Source Code Cross Referenced for Protocol.java in  » 6.0-JDK-Modules » j2me » com » sun » midp » io » j2me » sms » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » com.sun.midp.io.j2me.sms 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *
0003:         *
0004:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
0005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006:         * 
0007:         * This program is free software; you can redistribute it and/or
0008:         * modify it under the terms of the GNU General Public License version
0009:         * 2 only, as published by the Free Software Foundation.
0010:         * 
0011:         * This program is distributed in the hope that it will be useful, but
0012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014:         * General Public License version 2 for more details (a copy is
0015:         * included at /legal/license.txt).
0016:         * 
0017:         * You should have received a copy of the GNU General Public License
0018:         * version 2 along with this work; if not, write to the Free Software
0019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020:         * 02110-1301 USA
0021:         * 
0022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023:         * Clara, CA 95054 or visit www.sun.com if you need additional
0024:         * information or have any questions.
0025:         */
0026:
0027:        package com.sun.midp.io.j2me.sms;
0028:
0029:        import com.sun.midp.io.j2me.ProtocolBase;
0030:
0031:        import com.sun.midp.io.HttpUrl;
0032:        import com.sun.midp.security.Permissions;
0033:        import java.io.DataInputStream;
0034:        import java.io.DataOutputStream;
0035:        import java.io.InputStream;
0036:        import java.io.OutputStream;
0037:        import java.util.Vector;
0038:        import javax.microedition.io.Connector;
0039:        import javax.microedition.io.Connection;
0040:        import javax.wireless.messaging.Message;
0041:        import javax.wireless.messaging.MessageConnection;
0042:
0043:        // Exceptions
0044:        import java.io.IOException;
0045:        import java.io.InterruptedIOException;
0046:
0047:        /**
0048:         * SMS message connection implementation.
0049:         *
0050:         * <code>Protocol</code> itself is not instantiated. Instead, the application
0051:         * calls <code>Connector.open</code> with an SMS URL string and obtains a
0052:         * {@link javax.wireless.messaging.MessageConnection MessageConnection}
0053:         *  object. It is an instance of <code>MessageConnection</code>
0054:         * that is instantiated. The Generic Connection Framework mechanism
0055:         * in CLDC will return a <code>Protocol</code> object, which is the
0056:         * implementation of <code>MessageConnection</code>. The
0057:         * <code>Protocol</code> object represents a connection to a low-level transport
0058:         * mechanism.
0059:         * <p>
0060:         * Optional packages, such as <code>Protocol</code>, cannot reside in
0061:         * small devices.
0062:         * The Generic Connection Framework allows an application to reach the
0063:         * optional packages and classes indirectly. For example, an application
0064:         * can be written with a string that is used to open a connection. Inside
0065:         * the implementation of <code>Connector</code>, the string is mapped to a
0066:         * particular implementation: <code>Protocol</code>, in this case. This allows
0067:         * the implementation to be optional even though
0068:         * the interface, <code>MessageConnection</code>, is required.
0069:         * <p>
0070:         * Closing the connection frees an instance of <code>MessageConnection</code>.
0071:         * <p>
0072:         * The <code>Protocol</code> class contains methods
0073:         * to open and close the connection to the low-level transport mechanism. The
0074:         * messages passed on the transport mechanism are defined by the
0075:         * {@link MessageObject MessageObject}
0076:         * class.
0077:         * Connections can be made in either client mode or server mode.
0078:         * <ul>
0079:         * <li>Client mode connections are for sending messages only. They are
0080:         * created by passing a string identifying a destination address to the
0081:         * <code>Connector.open()</code> method.</li>
0082:         * <li>Server mode connections are for receiving and sending messages. They
0083:         * are created by passing a string that identifies a port, or equivalent,
0084:         * on the local host to the <code>Connector.open()</code> method.</li>
0085:         * </ul>
0086:         * The class also contains methods to send, receive, and construct
0087:         * <code>Message</code> objects.
0088:         * <p>
0089:         * <p>
0090:         * This class declares that it implements <code>StreamConnection</code>
0091:         * so it can intercept calls to <code>Connector.open*Stream()</code>
0092:         * to throw an <code>IllegalArgumentException</code>.
0093:         * </p>
0094:         *
0095:         */
0096:        public class Protocol extends ProtocolBase {
0097:
0098:            /** Connection mode. */
0099:            private final int connectionMode = 0;
0100:
0101:            /** Currently opened connections. */
0102:            static protected Vector openconnections = new Vector();
0103:
0104:            /** Name of current connection. */
0105:            protected String url;
0106:
0107:            /** Local handle for port number. */
0108:            private int m_iport = 0;
0109:
0110:            /** Count of simultaneous opened conenctions. */
0111:            protected static int open_count = 0;
0112:
0113:            /** Ports barred from use int the specification. */
0114:            int restrictedPorts[] = { 2805, // WAP WTA secure connection-less session service
0115:                    2923, // WAP WTA secure session service
0116:                    2948, // WAP Push connectionless session service (client side)
0117:                    2949, // WAP Push secure connectionless session service (client side)
0118:                    5502, // Service Card reader
0119:                    5503, // Internet access configuration reader
0120:                    5508, // Dynamic Menu Control Protocol
0121:                    5511, // Message Access Protocol
0122:                    5512, // Simple Email Notification
0123:                    9200, // WAP connectionless session service
0124:                    9201, // WAP session service
0125:                    9202, // WAP secure connectionless session service
0126:                    9203, // WAP secure session service
0127:                    9207, // WAP vCal Secure
0128:                    49996, // SyncML OTA configuration
0129:                    49999 // WAP OTA configuration
0130:            };
0131:
0132:            /**	 DCS: GSM Alphabet  */
0133:            protected static final int GSM_TEXT = 0;
0134:
0135:            /**	 DCS: Binary */
0136:            protected static final int GSM_BINARY = 1;
0137:
0138:            /**	 DCS: Unicode UCS-2 */
0139:            protected static final int GSM_UCS2 = 2;
0140:
0141:            /** Creates a message connection protocol handler. */
0142:            public Protocol() {
0143:                super ();
0144:                ADDRESS_PREFIX = "sms://";
0145:            }
0146:
0147:            /**
0148:             * Gets the connection parameter in string mode.
0149:             * @return string that contains a parameter 
0150:             */
0151:            protected String getAppID() {
0152:                if (m_iport > 0) {
0153:                    return new String(Integer.toString(m_iport));
0154:                } else {
0155:                    return null;
0156:                }
0157:            }
0158:
0159:            /**
0160:             * Sets the connection parameter in string mode.
0161:             * @param newValue new value of connection parameter 
0162:             */
0163:            protected void setAppID(String newValue) {
0164:                try {
0165:                    m_iport = Integer.parseInt(newValue);
0166:                } catch (NumberFormatException exc) {
0167:                    m_iport = 0;
0168:                }
0169:            }
0170:
0171:            /**
0172:             * Private class to encapsulate SMSPacket data structure
0173:             *
0174:             */
0175:            private class SMSPacket {
0176:                /** Message buffer */
0177:                public byte[] message;
0178:                /** Buffer with sender's address */
0179:                public byte[] address;
0180:                /** port number */
0181:                public int port;
0182:                /** sent at */
0183:                public long sentAt;
0184:                /** Type of message */
0185:                public int messageType;
0186:            };
0187:
0188:            /*
0189:             * MessageConnection Interface
0190:             */
0191:
0192:            /**
0193:             * Constructs a new message object of a text or binary type.
0194:             * If the <code>TEXT_MESSAGE</code> constant is passed in, the
0195:             * <code>TextMessage</code> interface is implemented by the created object.
0196:             * If the <code>BINARY_MESSAGE</code> constant is passed in, the
0197:             * <code>BinaryMessage</code> interface is implemented by the created
0198:             * object.
0199:             * <p>
0200:             * If this method is called in a sending mode, a new <code>Message</code>
0201:             * object is requested from the connection. For example:
0202:             * <p>
0203:             * <code>Message msg = conn.newMessage(TEXT_MESSAGE);</code>
0204:             * <p>
0205:             * The <code>Message</code> object that was created doesn't have the
0206:             * destination address set. It's the application's responsibility to set it
0207:             * before the message is sent.
0208:             * <p>
0209:             * If this method is called in receiving mode, the
0210:             * <code>Message</code> object does have
0211:             * its address set. The application can act on the object to extract
0212:             * the address and message data.
0213:             * <p>
0214:             * <!-- The <code>type</code> parameter indicates the number of bytes
0215:             * that should be
0216:             * allocated for the message. No restrictions are placed on the application
0217:             * for the value of <code>size</code>.
0218:             * A value of <code>null</code> is permitted and creates a
0219:             * <code>Message</code> object
0220:             * with a 0-length message. -->
0221:             *
0222:             * @param type <code>TEXT_MESSAGE</code> or
0223:             *     <code>BINARY_MESSAGE</code>.
0224:             * @return a new message.
0225:             */
0226:            public Message newMessage(String type) {
0227:                String address = null;
0228:
0229:                /*
0230:                 * Provide the default address from the original open.
0231:                 */
0232:
0233:                if (((m_mode & Connector.WRITE) > 0) && (host != null)) {
0234:                    address = ADDRESS_PREFIX + host;
0235:                    if (m_iport != 0) {
0236:                        address = address + ":" + String.valueOf(m_iport);
0237:                    }
0238:                }
0239:
0240:                return newMessage(type, address);
0241:            }
0242:
0243:            /**
0244:             * Constructs a new message object of a text or binary type and specifies
0245:             * a destination address.
0246:             * If the <code>TEXT_MESSAGE</code> constant is passed in, the
0247:             * <code>TextMessage</code> interface is implemented by the created object.
0248:             * If the <code>BINARY_MESSAGE</code> constant is passed in, the
0249:             * <code>BinaryMessage</code> interface is implemented by the created
0250:             * object.
0251:             * <p>
0252:             * The destination address <code>addr</code> has the following format:
0253:             * </p>
0254:             * <p>
0255:             * <code>sms://</code><em>phone_number</em>:<em>port</em>
0256:             * </p>
0257:             *
0258:             * @param type <code>TEXT_MESSAGE</code> or
0259:             *     <code>BINARY_MESSAGE</code>.
0260:             * @param addr the destination address of the message.
0261:             * @return a new <code>Message</code> object.
0262:             */
0263:            public Message newMessage(String type, String addr) {
0264:                Message message = null;
0265:
0266:                if (type.equals(MessageConnection.TEXT_MESSAGE)) {
0267:
0268:                    message = new TextObject(addr);
0269:                } else {
0270:                    if (type.equals(MessageConnection.BINARY_MESSAGE)) {
0271:
0272:                        message = new BinaryObject(addr);
0273:                    } else {
0274:                        throw new IllegalArgumentException(
0275:                                "Message type not supported");
0276:                    }
0277:                }
0278:
0279:                return message;
0280:            }
0281:
0282:            /**
0283:             * Receives the bytes that have been sent over the connection, constructs a
0284:             * <code>Message</code> object, and returns it.
0285:             * <p>
0286:             * If there are no <code>Message</code>s waiting on the connection, this
0287:             * method will block until a message is received, or the
0288:             * <code>MessageConnection</code> is closed.
0289:             *
0290:             * @return a <code>Message</code> object.
0291:             * @exception java.io.IOException if an error occurs while receiving a
0292:             *     message.
0293:             * @exception java.io.InterruptedIOException if this
0294:             *     <code>MessageConnection</code> object is closed during this receive
0295:             *     method call.
0296:             * @exception java.lang.SecurityException if the application does not have
0297:             *      permission to receive messages using the given port number.
0298:             */
0299:            public synchronized Message receive() throws IOException {
0300:
0301:                /* Check if we have permission to recieve. */
0302:                checkReceivePermission();
0303:
0304:                /* Make sure the connection is still open. */
0305:                ensureOpen();
0306:
0307:                if (((m_mode & Connector.READ) == 0) || (host != null)) {
0308:
0309:                    throw new IOException("Invalid connection mode");
0310:                }
0311:
0312:                Message message = null;
0313:                int length = 0;
0314:                try {
0315:
0316:                    SMSPacket smsPacket = new SMSPacket();
0317:
0318:                    /*
0319:                     * Packet has been received and deleted from inbox.
0320:                     * Time to wake up receive thread.
0321:                     */
0322:                    // Pick up the SMS message from the message pool.
0323:                    length = receive0(m_iport, midletSuite.getID(), connHandle,
0324:                            smsPacket);
0325:
0326:                    if (length >= 0) {
0327:                        String type;
0328:                        boolean isTextMessage = true;
0329:                        if (smsPacket.messageType == GSM_BINARY) {
0330:                            type = MessageConnection.BINARY_MESSAGE;
0331:                            isTextMessage = false;
0332:                        } else {
0333:                            type = MessageConnection.TEXT_MESSAGE;
0334:                            isTextMessage = true;
0335:                        }
0336:                        message = newMessage(type, new String(ADDRESS_PREFIX
0337:                                + new String(smsPacket.address) + ":"
0338:                                + smsPacket.port));
0339:                        String messg = null;
0340:                        if (isTextMessage) {
0341:                            if (length > 0) {
0342:                                if (smsPacket.messageType == GSM_TEXT) {
0343:                                    messg = new String(TextEncoder
0344:                                            .toString(TextEncoder
0345:                                                    .decode(smsPacket.message)));
0346:                                } else {
0347:                                    messg = new String(TextEncoder
0348:                                            .toString(smsPacket.message));
0349:
0350:                                }
0351:                            } else {
0352:                                messg = new String("");
0353:                            }
0354:                            ((TextObject) message).setPayloadText(messg);
0355:                        } else {
0356:                            if (length > 0) {
0357:                                ((BinaryObject) message)
0358:                                        .setPayloadData(smsPacket.message);
0359:                            } else {
0360:                                ((BinaryObject) message)
0361:                                        .setPayloadData(new byte[0]);
0362:                            }
0363:                        }
0364:                        ((MessageObject) message)
0365:                                .setTimeStamp(smsPacket.sentAt);
0366:                    }
0367:                } catch (InterruptedIOException ex) {
0368:                    length = 0;
0369:                    throw new InterruptedIOException(
0370:                            "MessageConnection is closed");
0371:                } catch (IOException ex) {
0372:                    io2InterruptedIOExc(ex, "receiving");
0373:                } finally {
0374:                    if (length < 0) {
0375:                        throw new InterruptedIOException(
0376:                                "Connection closed error");
0377:                    }
0378:                }
0379:
0380:                return message;
0381:            }
0382:
0383:            /**
0384:             * Sends a message over the connection. This method extracts the data
0385:             * payload from the <code>Message</code> object so that it can be sent as a
0386:             * datagram.
0387:             *
0388:             * @param     dmsg a <code>Message</code> object
0389:             * @exception java.io.IOException if the message could not be sent or
0390:             *     because of network failure
0391:             * @exception java.lang.IllegalArgumentException if the message is
0392:             *     incomplete or contains invalid information. This exception is also
0393:             *     thrown if the payload of the message exceeds the maximum length for
0394:             *     the given messaging protocol.
0395:             * @exception java.io.InterruptedIOException if a timeout occurs while
0396:             *     either trying to send the message or if this <code>Connection</code>
0397:             *     object is closed during this <code>send</code> operation.
0398:             * @exception java.lang.NullPointerException if the parameter is
0399:             *     <code>null</code>.
0400:             * @exception java.lang.SecurityException if the application does not have
0401:             *      permission to send the message.
0402:             */
0403:            public void send(Message dmsg) throws IOException {
0404:                String phoneNumber = null;
0405:                String address = null;
0406:
0407:                if (dmsg == null) {
0408:                    throw new NullPointerException();
0409:                }
0410:
0411:                if (dmsg.getAddress() == null) {
0412:                    throw new IllegalArgumentException();
0413:                }
0414:
0415:                /*
0416:                 * parse name into host and port
0417:                 */
0418:                String addr = dmsg.getAddress();
0419:                HttpUrl url = new HttpUrl(addr);
0420:                if (url.port == -1) {
0421:                    /* no port supplied */
0422:                    url.port = 0;
0423:                }
0424:
0425:                /* Can not send to cbs address. */
0426:                if (addr.startsWith("cbs:")) {
0427:                    // Can't send a CBS message.
0428:                    throw new IllegalArgumentException("Can't send CBS msg.");
0429:                }
0430:
0431:                int numSeg = numberOfSegments(dmsg);
0432:                if ((numSeg <= 0) || (numSeg > 3)) {
0433:                    throw new IOException("Error: message is too large");
0434:                }
0435:
0436:                try {
0437:                    midletSuite.checkForPermission(Permissions.SMS_SEND,
0438:                            url.host, Integer.toString(numSeg));
0439:                } catch (InterruptedException ie) {
0440:                    throw new InterruptedIOException(
0441:                            "Interrupted while trying "
0442:                                    + "to ask the user permission");
0443:                }
0444:
0445:                ensureOpen();
0446:
0447:                if ((m_mode & Connector.WRITE) == 0) {
0448:
0449:                    throw new IOException("Invalid mode");
0450:                }
0451:
0452:                int sourcePort = 0;
0453:                if ((m_mode & Connector.READ) != 0 && host == null) {
0454:                    sourcePort = m_iport;
0455:                }
0456:
0457:                for (int restrictedPortIndex = 0; restrictedPortIndex < restrictedPorts.length; restrictedPortIndex++) {
0458:                    if (url.port == restrictedPorts[restrictedPortIndex]) {
0459:                        throw new SecurityException(
0460:                                "not allowed to send SMS messages to the restricted ports");
0461:                    }
0462:                }
0463:
0464:                int messageType = GSM_BINARY;
0465:                byte[] msgBuffer = null;
0466:
0467:                if (dmsg instanceof  TextObject) {
0468:                    byte[] gsm7bytes;
0469:                    msgBuffer = ((TextObject) dmsg).getBytes();
0470:                    if (msgBuffer != null) {
0471:                        /*
0472:                         * Attempt to encode the UCS2 bytes as GSM 7-bit.
0473:                         */
0474:                        gsm7bytes = TextEncoder.encode(msgBuffer);
0475:                        if (gsm7bytes != null) {
0476:                            msgBuffer = gsm7bytes;
0477:                            messageType = GSM_TEXT;
0478:                        } else {
0479:                            /*
0480:                             * Encoding attempt failed. Send UCS2 bytes.
0481:                             */
0482:                            messageType = GSM_UCS2;
0483:                        }
0484:                    }
0485:
0486:                } else if (dmsg instanceof  BinaryObject) {
0487:                    msgBuffer = ((BinaryObject) dmsg).getPayloadData();
0488:                } else {
0489:                    throw new IllegalArgumentException(
0490:                            "Message type not supported");
0491:                }
0492:
0493:                try {
0494:                    send0(connHandle, messageType, url.host, url.port,
0495:                            sourcePort, msgBuffer);
0496:                } catch (IOException ex) {
0497:                    io2InterruptedIOExc(ex, "sending");
0498:                }
0499:            }
0500:
0501:            /**
0502:             * Returns how many segments in the underlying protocol would
0503:             * be needed for sending the <code>Message</code> given as the parameter.
0504:             *
0505:             * <p>Note that this method does not actually send the message;
0506:             * it will only calculate the number of protocol segments
0507:             * needed for sending it.
0508:             * </p>
0509:             * <p>This method calculates the number of segments required
0510:             * when this message is split into the protocol segments
0511:             * utilizing the underlying protocol's features.
0512:             * Possible implementation's limitations that may limit the number of
0513:             * segments that can be sent using it are not taken into account. These
0514:             * limitations are protocol specific. They are documented
0515:             * with that protocol's adapter definition.
0516:             * </p>
0517:             * @param msg the message to be used for the calculation
0518:             * @return number of protocol segments required to send the message.
0519:             *     If the <code>Message</code> object can't be sent using
0520:             *     the underlying protocol, <code>0</code> is returned.
0521:             */
0522:            public int numberOfSegments(Message msg) {
0523:
0524:                /** The number of segments required to send the message. */
0525:                int segments = 0;
0526:
0527:                /* Generate the proper buffer contents and message type. */
0528:                byte[] msgBuffer = null;
0529:                int messageType = GSM_TEXT;
0530:                if (msg instanceof  TextObject) {
0531:                    msgBuffer = ((TextObject) msg).getBytes();
0532:                    if (msgBuffer != null) {
0533:                        /*
0534:                         * Attempt to encode the UCS2 bytes as GSM 7-bit.
0535:                         */
0536:                        byte[] gsm7bytes = TextEncoder.encode(msgBuffer);
0537:                        if (gsm7bytes != null) {
0538:                            msgBuffer = gsm7bytes;
0539:                        } else {
0540:                            /*
0541:                             * Encoding attempt failed. Use UCS2 bytes.
0542:                             */
0543:                            messageType = GSM_UCS2;
0544:                        }
0545:                    }
0546:                } else if (msg instanceof  BinaryObject) {
0547:                    msgBuffer = ((BinaryObject) msg).getPayloadData();
0548:                    messageType = GSM_BINARY;
0549:                } else {
0550:                    throw new IllegalArgumentException(
0551:                            "Message type not supported.");
0552:                }
0553:
0554:                // Pick up the message length.
0555:                if (msgBuffer != null) {
0556:
0557:                    // Parse address to see if there's a port value.
0558:                    boolean hasPort = false;
0559:                    String addr = msg.getAddress();
0560:                    if (addr != null) {
0561:                        // workaround. HttpUrl can throw IAE on zero port.
0562:                        try {
0563:                            HttpUrl url = new HttpUrl(addr);
0564:                            if (url.port != -1) {
0565:                                /* No port supplied. */
0566:                                hasPort = true;
0567:                            }
0568:                        } catch (IllegalArgumentException iae) {
0569:                            hasPort = false;
0570:                        }
0571:
0572:                        if (addr.startsWith("cbs:")) {
0573:                            // Can't send a CBS message.
0574:                            return 0;
0575:                        }
0576:                    }
0577:                    // Other protocols can receive the message.
0578:                    segments = numberOfSegments0(msgBuffer, msgBuffer.length,
0579:                            messageType, hasPort);
0580:                }
0581:
0582:                return segments;
0583:            }
0584:
0585:            /**
0586:             * Closes the connection. Resets the connection <code>open</code> flag
0587:             * to <code>false</code>. Subsequent operations on a
0588:             * closed connection should throw an appropriate exception.
0589:             *
0590:             *
0591:             * @exception IOException  if an I/O error occurs
0592:             */
0593:            public void close() throws IOException {
0594:                /*
0595:                 * Set m_iport to 0, in order to quit out of the while loop
0596:                 * in the receiver thread.
0597:                 */
0598:                int save_iport = m_iport;
0599:
0600:                m_iport = 0;
0601:
0602:                synchronized (closeLock) {
0603:                    if (open) {
0604:                        /*
0605:                         * Reset open flag early to prevent receive0 executed by
0606:                         * concurrent thread to operate on partially closed
0607:                         * connection
0608:                         */
0609:                        open = false;
0610:
0611:                        close0(save_iport, connHandle, 1);
0612:
0613:                        setMessageListener(null);
0614:
0615:                        /*
0616:                         * Reset handle and other params to default
0617:                         * values. Multiple calls to close() are allowed
0618:                         * by the spec and the resetting would prevent any
0619:                         * strange behaviour.
0620:                         */
0621:                        connHandle = 0;
0622:                        host = null;
0623:                        m_mode = 0;
0624:
0625:                        /*
0626:                         * Remove this connection from the list of open
0627:                         * connections.
0628:                         */
0629:                        int len = openconnections.size();
0630:                        for (int i = 0; i < len; i++) {
0631:                            if (openconnections.elementAt(i) == this ) {
0632:                                openconnections.removeElementAt(i);
0633:                                break;
0634:                            }
0635:                        }
0636:
0637:                        open_count--;
0638:                    }
0639:                }
0640:            }
0641:
0642:            /*
0643:             * ConnectionBaseInterface Interface
0644:             */
0645:
0646:            /**
0647:             * Opens a connection. This method is called from the
0648:             * <code>Connector.open()</code> method to obtain the destination
0649:             * address given in the <code>name</code> parameter.
0650:             * <p>
0651:             * The format for the <code>name</code> string for this method is:
0652:             * </p>
0653:             * <p>
0654:             * <code>sms://<em>[phone_number</em>:<em>][port_number]</em></code>
0655:             * </p>
0656:             * <p>
0657:             * where the <em>phone_number:</em> is optional.
0658:             * If the <em>phone_number</em>
0659:             * parameter is present, the connection is being opened in
0660:             * client mode. This means that messages can be sent.
0661:             * If the parameter is absent, the connection is being opened in
0662:             * server mode. This means that messages can be sent and received.
0663:             * <p>
0664:             * The connection that is opened is to a low-level transport mechanism
0665:             * which can be any of the following:
0666:             * <ul>
0667:             * <li>a datagram Short Message Peer-to-Peer (SMPP)
0668:             * to a service center </li>
0669:             * <li>a <code>comm</code> connection to a phone device with
0670:             *   AT-commands</li>
0671:             * <li>a native SMS stack</li>
0672:             *  </ul>
0673:             * Currently, the <code>mode</code> and <code>timeouts</code> parameters are
0674:             * ignored.
0675:             *
0676:             * @param name the target of the connection
0677:             * @param mode indicates whether the caller
0678:             *             intends to write to the connection. Currently,
0679:             *             this parameter is ignored.
0680:             * @param timeouts indicates whether the caller
0681:             *                 wants timeout exceptions. Currently,
0682:             *             this parameter is ignored.
0683:             * @return this connection
0684:             * @exception IOException if the connection is closed or unavailable
0685:             */
0686:            public Connection openPrim(String name, int mode, boolean timeouts)
0687:                    throws IOException {
0688:
0689:                return openPrimInternal(name, mode, timeouts);
0690:            }
0691:
0692:            /*
0693:             * StreamConnection Interface
0694:             */
0695:
0696:            /**
0697:             * Open and return an input stream for a connection.
0698:             * This method always throw
0699:             * <code>IllegalArgumentException</code>.
0700:             *
0701:             * @return                 An input stream
0702:             * @exception IOException  If an I/O error occurs
0703:             * @exception IllegalArgumentException  is thrown for all requests
0704:             */
0705:            public InputStream openInputStream() throws IOException {
0706:
0707:                throw new IllegalArgumentException("Not supported");
0708:            }
0709:
0710:            /**
0711:             * Open and return a data input stream for a connection.
0712:             * This method always throw
0713:             * <code>IllegalArgumentException</code>.
0714:             *
0715:             * @return                 An input stream
0716:             * @exception IOException  If an I/O error occurs
0717:             * @exception IllegalArgumentException  is thrown for all requests
0718:             */
0719:            public DataInputStream openDataInputStream() throws IOException {
0720:
0721:                throw new IllegalArgumentException("Not supported");
0722:            }
0723:
0724:            /**
0725:             * Open and return an output stream for a connection.
0726:             * This method always throw
0727:             * <code>IllegalArgumentException</code>.
0728:             *
0729:             * @return                 An output stream
0730:             * @exception IOException  If an I/O error occurs
0731:             * @exception IllegalArgumentException  is thrown for all requests
0732:             */
0733:            public OutputStream openOutputStream() throws IOException {
0734:
0735:                throw new IllegalArgumentException("Not supported");
0736:            }
0737:
0738:            /**
0739:             * Open and return a data output stream for a connection.
0740:             * This method always throw
0741:             * <code>IllegalArgumentException</code>.
0742:             *
0743:             * @return                 an output stream
0744:             * @exception IOException  if an I/O error occurs
0745:             * @exception IllegalArgumentException  is thrown for all requests
0746:             */
0747:            public DataOutputStream openDataOutputStream() throws IOException {
0748:
0749:                throw new IllegalArgumentException("Not supported");
0750:            }
0751:
0752:            /*
0753:             * Protocol members
0754:             */
0755:
0756:            /**
0757:             * Opens a connection. This is the internal entry point that
0758:             * allows the CBS protocol handler to use the reserved port for
0759:             * CBS emulated messages.
0760:             *
0761:             * @param name the target of the connection
0762:             * @param mode indicates whether the caller
0763:             *             intends to write to the connection. Currently,
0764:             *             this parameter is ignored.
0765:             * @param timeouts indicates whether the caller
0766:             *                 wants timeout exceptions. Currently,
0767:             *             this parameter is ignored.
0768:             * @return this connection
0769:             * @exception IOException if the connection is closed or unavailable
0770:             */
0771:            public synchronized Connection openPrimInternal(String name,
0772:                    int mode, boolean timeouts) throws IOException {
0773:
0774:                /*
0775:                 * If <code>host == null</code>, then we are a server endpoint at
0776:                 * the supplied <code>port</code>.
0777:                 *
0778:                 * If <code>host != null</code> we are a client endpoint at a port
0779:                 * decided by the system and the default address for
0780:                 * SMS messages to be sent is <code>sms://host:port</code>.
0781:                 */
0782:
0783:                String portName = null;
0784:
0785:                if ((name == null) || (name.length() <= 2)
0786:                        || (name.charAt(0) != '/') || (name.charAt(1) != '/')) {
0787:                    throw new IllegalArgumentException(
0788:                            "Missing protocol separator");
0789:                }
0790:
0791:                int colon = name.indexOf(':');
0792:                if (colon > 0) {
0793:                    if (colon != 2) {
0794:                        host = name.substring(2, colon);
0795:                    }
0796:                    portName = name.substring(colon + 1);
0797:                } else {
0798:                    if (name.length() > 2) {
0799:                        host = name.substring(2);
0800:                    }
0801:                }
0802:
0803:                if (host != null) {
0804:                    int offset = 0;
0805:                    int len = host.length();
0806:                    char c = '\0';
0807:                    /* Only '+' followed by 0-9 are allowed in the host field. */
0808:                    if (len > 0) {
0809:                        c = host.charAt(0);
0810:                        if (c == '+') {
0811:                            offset = 1;
0812:                        }
0813:                        for (int i = offset; i < host.length(); i++) {
0814:                            c = host.charAt(i);
0815:                            if ('0' <= c && c <= '9') {
0816:
0817:                                continue;
0818:                            } else {
0819:                                throw new IllegalArgumentException(
0820:                                        "Host format");
0821:                            }
0822:                        }
0823:                    }
0824:                }
0825:
0826:                int portNumber = 0;
0827:                m_iport = 0;
0828:                if (portName != null) {
0829:                    int len = portName.length();
0830:                    if (len == 0) {
0831:                        throw new IllegalArgumentException("Port length");
0832:                    }
0833:                    /*
0834:                     * Add a numeric check hat the port is less than the
0835:                     * GSM maximum port number.
0836:                     */
0837:                    try {
0838:                        portNumber = Integer.parseInt(portName);
0839:                        m_iport = portNumber;
0840:                        if ((portNumber > 65535) || (portNumber < 0)) {
0841:                            throw new IllegalArgumentException("Port range");
0842:                        }
0843:                    } catch (NumberFormatException nfe) {
0844:                        throw new IllegalArgumentException("Port Number"
0845:                                + " formatted badly.");
0846:                    }
0847:
0848:                }
0849:
0850:                if (mode == Connector.READ && host != null && host.length() > 0) {
0851:                    throw new IllegalArgumentException("Cannot read on "
0852:                            + "client connection");
0853:                }
0854:
0855:                if ((mode == Connector.WRITE) && (host == null)) {
0856:                    /*
0857:                     * avoid throwing the following exception for compliance
0858:                     * throw new IllegalArgumentException("Missing host name");
0859:                     */
0860:                }
0861:
0862:                if ((mode != Connector.READ) && (mode != Connector.WRITE)
0863:                        && (mode != Connector.READ_WRITE)) {
0864:
0865:                    throw new IllegalArgumentException("Invalid mode");
0866:                }
0867:
0868:                /*
0869:                 * Check to see if the application has the permision to
0870:                 * use this connection type.
0871:                 */
0872:                if (!openPermission) {
0873:                    try {
0874:                        midletSuite.checkForPermission(Permissions.SMS_SERVER,
0875:                                "sms:open");
0876:                        openPermission = true;
0877:                    } catch (InterruptedException ie) {
0878:                        throw new InterruptedIOException(
0879:                                "Interrupted while trying "
0880:                                        + "to ask the user permission");
0881:                    }
0882:                }
0883:                /*
0884:                 * Check to see if this connection is already opened.
0885:                 */
0886:                int len = openconnections.size();
0887:                for (int i = 0; i < len; i++) {
0888:                    if (!(openconnections.elementAt(i) instanceof  com.sun.midp.io.j2me.sms.Protocol)
0889:                            || ((Protocol) openconnections.elementAt(i)).url
0890:                                    .equals(name)) {
0891:                        throw new IOException("Already opened");
0892:                    }
0893:                }
0894:
0895:                openconnections.addElement(this );
0896:                url = name;
0897:
0898:                try {
0899:                    connHandle = open0(host, midletSuite.getID(), m_iport);
0900:                } catch (IOException ioexcep) {
0901:                    m_mode = 0;
0902:                    throw new IOException("SMS connection cannot be opened");
0903:                } catch (OutOfMemoryError oomexcep) {
0904:                    m_mode = 0;
0905:                    throw new IOException("SMS connection cannot be opened");
0906:                }
0907:
0908:                open_count++;
0909:                m_mode = mode;
0910:                open = true;
0911:
0912:                return this ;
0913:            }
0914:
0915:            /**
0916:             * Checks internal setting of receive permission.
0917:             * Called from receive and setMessageListener methods.
0918:             * @exception InterruptedIOException if permission dialog
0919:             * was preempted
0920:             */
0921:            protected void checkReceivePermission()
0922:                    throws InterruptedIOException {
0923:                /* Check if we have permission to recieve. */
0924:                if (!readPermission) {
0925:                    try {
0926:                        midletSuite.checkForPermission(Permissions.SMS_RECEIVE,
0927:                                "sms:receive");
0928:                        readPermission = true;
0929:                    } catch (InterruptedException ie) {
0930:                        throw new InterruptedIOException(
0931:                                "Interrupted while trying "
0932:                                        + "to ask the user permission");
0933:                    }
0934:                }
0935:            }
0936:
0937:            /**
0938:             * Native finalizer
0939:             */
0940:            private native void finalize();
0941:
0942:            /**
0943:             * Native function to open sms connection
0944:             *
0945:             * @param host The name of the host for this connection. Can be
0946:             *	   <code>null</code>.
0947:             * @param msid Midlet suite ID, Cannot be <code>null</code>.
0948:             * @param port port to open
0949:             * @return    returns handle to SMS connection.
0950:             */
0951:            private native int open0(String host, int msid, int port)
0952:                    throws IOException;
0953:
0954:            /**
0955:             * Unblock the receive thread.
0956:             *
0957:             * @param msid The MIDlet suite ID.
0958:             *
0959:             * @return  returns handle to the connection.
0960:             */
0961:            protected int unblock00(int msid) throws IOException {
0962:                return open0(null, msid, 0);
0963:            }
0964:
0965:            /**
0966:             * Native function to close sms connection
0967:             *
0968:             * @param port port number to close
0969:             * @param handle sms handle returned by open0
0970:             * @param deRegister Deregistration appID when parameter is 1.
0971:             * @return    0 on success, -1 on failure
0972:             */
0973:            private native int close0(int port, int handle, int deRegister);
0974:
0975:            /**
0976:             * Close connection.
0977:             *
0978:             * @param connHandle handle returned by open0
0979:             * @param deRegister Deregistration appID when parameter is 1.
0980:             * @return    0 on success, -1 on failure
0981:             */
0982:            protected int close00(int connHandle, int deRegister) {
0983:                return close0(m_iport, connHandle, deRegister);
0984:            }
0985:
0986:            /**
0987:             * Sends SMS message
0988:             *
0989:             * @param handle handle to SMS connection.
0990:             * @param type message type, binary or text.
0991:             * @param host URL of host sending message
0992:             * @param destPort destination port
0993:             * @param sourcePort source port
0994:             * @param message message buffer
0995:             * @return number of bytes sent
0996:             * @exception IOException  if an I/O error occurs
0997:             */
0998:            private native int send0(int handle, int type, String host,
0999:                    int destPort, int sourcePort, byte[] message)
1000:                    throws IOException;
1001:
1002:            /**
1003:             * Receives SMS message
1004:             *
1005:             * @param port incoming port
1006:             * @param msid Midlet suite ID
1007:             * @param handle handle to open SMS connection
1008:             * @param smsPacket received packet
1009:             * @return number of bytes received
1010:             * @exception IOException  if an I/O error occurs
1011:             */
1012:            private native int receive0(int port, int msid, int handle,
1013:                    SMSPacket smsPacket) throws IOException;
1014:
1015:            /**
1016:             * Waits until message available
1017:             *
1018:             * @param port incoming port
1019:             * @param handle handle to SMS connection
1020:             * @return 0 on success, -1 on failure
1021:             * @exception IOException  if an I/O error occurs
1022:             */
1023:            private native int waitUntilMessageAvailable0(int port, int handle)
1024:                    throws IOException;
1025:
1026:            /**
1027:             * Waits until message available
1028:             *
1029:             * @param handle handle to connection
1030:             * @return 0 on success, -1 on failure
1031:             * @exception IOException  if an I/O error occurs
1032:             */
1033:            protected int waitUntilMessageAvailable00(int handle)
1034:                    throws IOException {
1035:                return waitUntilMessageAvailable0(m_iport, handle);
1036:            }
1037:
1038:            /**
1039:             * Computes the number of transport-layer segments that would be required to
1040:             * send the given message.
1041:             *
1042:             * @param msgBuffer The message to be sent.
1043:             * @param msgLen The length of the message.
1044:             * @param msgType The message type: binary or text.
1045:             * @param hasPort Indicates if the message includes a source or destination
1046:             *	   port number.
1047:             *
1048:             * @return The number of transport-layer segments required to send the
1049:             *	   message.
1050:             */
1051:            private native int numberOfSegments0(byte msgBuffer[], int msgLen,
1052:                    int msgType, boolean hasPort);
1053:
1054:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.