Methods Summary |
---|
protected void | checkReceivePermission()Checks internal setting of receive permission.
Called from receive and setMessageListener methods.
/* Check if we have permission to recieve. */
if (!readPermission) {
try {
midletSuite.checkForPermission(Permissions.SMS_RECEIVE,
"sms:receive");
readPermission = true;
} catch (InterruptedException ie) {
throw new InterruptedIOException("Interrupted while trying " +
"to ask the user permission");
}
}
|
public void | close()Closes the connection. Resets the connection open flag
to false . Subsequent operations on a
closed connection should throw an appropriate exception.
/*
* Set m_iport to 0, in order to quit out of the while loop
* in the receiver thread.
*/
int save_iport = m_iport;
m_iport = 0;
synchronized (closeLock) {
if (open) {
/*
* Reset open flag early to prevent receive0 executed by
* concurrent thread to operate on partially closed
* connection
*/
open = false;
close0(save_iport, connHandle, 1);
setMessageListener(null);
/*
* Reset handle and other params to default
* values. Multiple calls to close() are allowed
* by the spec and the resetting would prevent any
* strange behaviour.
*/
connHandle = 0;
host = null;
m_mode = 0;
/*
* Remove this connection from the list of open
* connections.
*/
int len = openconnections.size();
for (int i = 0; i < len; i++) {
if (openconnections.elementAt(i) == this) {
openconnections.removeElementAt(i);
break;
}
}
open_count--;
}
}
|
private native int | close0(int port, int handle, int deRegister)Native function to close sms connection
|
protected int | close00(int connHandle, int deRegister)Close connection.
return close0(m_iport, connHandle, deRegister);
|
private native void | finalize()Native finalizer
|
protected java.lang.String | getAppID()Gets the connection parameter in string mode.
if (m_iport > 0) {
return new String(Integer.toString(m_iport));
} else {
return null;
}
|
public javax.wireless.messaging.Message | newMessage(java.lang.String type)Constructs a new message object of a text or binary type.
If the TEXT_MESSAGE constant is passed in, the
TextMessage interface is implemented by the created object.
If the BINARY_MESSAGE constant is passed in, the
BinaryMessage interface is implemented by the created
object.
If this method is called in a sending mode, a new Message
object is requested from the connection. For example:
Message msg = conn.newMessage(TEXT_MESSAGE);
The Message object that was created doesn't have the
destination address set. It's the application's responsibility to set it
before the message is sent.
If this method is called in receiving mode, the
Message object does have
its address set. The application can act on the object to extract
the address and message data.
String address = null;
/*
* Provide the default address from the original open.
*/
if (((m_mode & Connector.WRITE) > 0) && (host != null)) {
address = ADDRESS_PREFIX + host;
if (m_iport != 0) {
address = address + ":" + String.valueOf(m_iport);
}
}
return newMessage(type, address);
|
public javax.wireless.messaging.Message | newMessage(java.lang.String type, java.lang.String addr)Constructs a new message object of a text or binary type and specifies
a destination address.
If the TEXT_MESSAGE constant is passed in, the
TextMessage interface is implemented by the created object.
If the BINARY_MESSAGE constant is passed in, the
BinaryMessage interface is implemented by the created
object.
The destination address addr has the following format:
sms:// phone_number:port
Message message = null;
if (type.equals(MessageConnection.TEXT_MESSAGE)) {
message = new TextObject(addr);
} else {
if (type.equals(MessageConnection.BINARY_MESSAGE)) {
message = new BinaryObject(addr);
} else {
throw new IllegalArgumentException(
"Message type not supported");
}
}
return message;
|
public int | numberOfSegments(javax.wireless.messaging.Message msg)Returns how many segments in the underlying protocol would
be needed for sending the Message given as the parameter.
Note that this method does not actually send the message;
it will only calculate the number of protocol segments
needed for sending it.
This method calculates the number of segments required
when this message is split into the protocol segments
utilizing the underlying protocol's features.
Possible implementation's limitations that may limit the number of
segments that can be sent using it are not taken into account. These
limitations are protocol specific. They are documented
with that protocol's adapter definition.
/** The number of segments required to send the message. */
int segments = 0;
/* Generate the proper buffer contents and message type. */
byte[] msgBuffer = null;
int messageType = GSM_TEXT;
if (msg instanceof TextObject) {
msgBuffer = ((TextObject)msg).getBytes();
if (msgBuffer != null) {
/*
* Attempt to encode the UCS2 bytes as GSM 7-bit.
*/
byte[] gsm7bytes = TextEncoder.encode(msgBuffer);
if (gsm7bytes != null) {
msgBuffer = gsm7bytes;
} else {
/*
* Encoding attempt failed. Use UCS2 bytes.
*/
messageType = GSM_UCS2;
}
}
} else if (msg instanceof BinaryObject) {
msgBuffer = ((BinaryObject)msg).getPayloadData();
messageType = GSM_BINARY;
} else {
throw new IllegalArgumentException("Message type not supported.");
}
// Pick up the message length.
if (msgBuffer != null) {
// Parse address to see if there's a port value.
boolean hasPort = false;
String addr = msg.getAddress();
if (addr != null) {
// workaround. HttpUrl can throw IAE on zero port.
try {
HttpUrl url = new HttpUrl(addr);
if (url.port != -1) {
/* No port supplied. */
hasPort = true;
}
} catch (IllegalArgumentException iae) {
hasPort = false;
}
if (addr.startsWith("cbs:")) {
// Can't send a CBS message.
return 0;
}
}
// Other protocols can receive the message.
segments = numberOfSegments0(msgBuffer, msgBuffer.length,
messageType, hasPort);
}
return segments;
|
private native int | numberOfSegments0(byte[] msgBuffer, int msgLen, int msgType, boolean hasPort)Computes the number of transport-layer segments that would be required to
send the given message.
|
private native int | open0(java.lang.String host, int msid, int port)Native function to open sms connection
|
public java.io.DataInputStream | openDataInputStream()Open and return a data input stream for a connection.
This method always throw
IllegalArgumentException .
throw new IllegalArgumentException("Not supported");
|
public java.io.DataOutputStream | openDataOutputStream()Open and return a data output stream for a connection.
This method always throw
IllegalArgumentException .
throw new IllegalArgumentException("Not supported");
|
public java.io.InputStream | openInputStream()Open and return an input stream for a connection.
This method always throw
IllegalArgumentException .
throw new IllegalArgumentException("Not supported");
|
public java.io.OutputStream | openOutputStream()Open and return an output stream for a connection.
This method always throw
IllegalArgumentException .
throw new IllegalArgumentException("Not supported");
|
public javax.microedition.io.Connection | openPrim(java.lang.String name, int mode, boolean timeouts)Opens a connection. This method is called from the
Connector.open() method to obtain the destination
address given in the name parameter.
The format for the name string for this method is:
sms://[phone_number:][port_number]
where the phone_number: is optional.
If the phone_number
parameter is present, the connection is being opened in
client mode. This means that messages can be sent.
If the parameter is absent, the connection is being opened in
server mode. This means that messages can be sent and received.
The connection that is opened is to a low-level transport mechanism
which can be any of the following:
- a datagram Short Message Peer-to-Peer (SMPP)
to a service center
- a
comm connection to a phone device with
AT-commands
- a native SMS stack
Currently, the mode and timeouts parameters are
ignored.
return openPrimInternal(name, mode, timeouts);
|
public synchronized javax.microedition.io.Connection | openPrimInternal(java.lang.String name, int mode, boolean timeouts)Opens a connection. This is the internal entry point that
allows the CBS protocol handler to use the reserved port for
CBS emulated messages.
/*
* If <code>host == null</code>, then we are a server endpoint at
* the supplied <code>port</code>.
*
* If <code>host != null</code> we are a client endpoint at a port
* decided by the system and the default address for
* SMS messages to be sent is <code>sms://host:port</code>.
*/
String portName = null;
if ((name == null) || (name.length() <= 2) ||
(name.charAt(0) != '/") ||
(name.charAt(1) != '/")) {
throw new IllegalArgumentException("Missing protocol separator");
}
int colon = name.indexOf(':");
if (colon > 0) {
if (colon != 2) {
host = name.substring(2, colon);
}
portName = name.substring(colon + 1);
} else {
if (name.length() > 2) {
host = name.substring(2);
}
}
if (host != null) {
int offset = 0;
int len = host.length();
char c = '\0";
/* Only '+' followed by 0-9 are allowed in the host field. */
if (len > 0) {
c = host.charAt(0);
if (c == '+") {
offset = 1;
}
for (int i = offset; i < host.length(); i++) {
c = host.charAt(i);
if ('0" <= c && c <= '9") {
continue;
} else {
throw new IllegalArgumentException("Host format");
}
}
}
}
int portNumber = 0;
m_iport = 0;
if (portName != null) {
int len = portName.length();
if (len == 0) {
throw new IllegalArgumentException("Port length");
}
/*
* Add a numeric check hat the port is less than the
* GSM maximum port number.
*/
try {
portNumber = Integer.parseInt(portName);
m_iport = portNumber;
if ((portNumber > 65535) || (portNumber < 0)) {
throw new IllegalArgumentException("Port range");
}
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException("Port Number" +
" formatted badly.");
}
}
if (mode == Connector.READ && host != null && host.length() > 0) {
throw new IllegalArgumentException("Cannot read on " +
"client connection");
}
if ((mode == Connector.WRITE) && (host == null)) {
/*
* avoid throwing the following exception for compliance
* throw new IllegalArgumentException("Missing host name");
*/
}
if ((mode != Connector.READ) &&
(mode != Connector.WRITE) &&
(mode != Connector.READ_WRITE)) {
throw new IllegalArgumentException("Invalid mode");
}
/*
* Check to see if the application has the permision to
* use this connection type.
*/
if (!openPermission) {
try {
midletSuite.checkForPermission(Permissions.SMS_SERVER,
"sms:open");
openPermission = true;
} catch (InterruptedException ie) {
throw new InterruptedIOException("Interrupted while trying " +
"to ask the user permission");
}
}
/*
* Check to see if this connection is already opened.
*/
int len = openconnections.size();
for (int i = 0; i < len; i++) {
if (!(openconnections.elementAt(i)
instanceof com.sun.midp.io.j2me.sms.Protocol)
|| ((Protocol) openconnections.elementAt(i)).url.equals(name)) {
throw new IOException("Already opened");
}
}
openconnections.addElement(this);
url = name;
try {
connHandle = open0(host, midletSuite.getID(), m_iport);
} catch (IOException ioexcep) {
m_mode = 0;
throw new IOException("SMS connection cannot be opened");
} catch (OutOfMemoryError oomexcep) {
m_mode = 0;
throw new IOException("SMS connection cannot be opened");
}
open_count++;
m_mode = mode;
open = true;
return this;
|
public synchronized javax.wireless.messaging.Message | receive()Receives the bytes that have been sent over the connection, constructs a
Message object, and returns it.
If there are no Message s waiting on the connection, this
method will block until a message is received, or the
MessageConnection is closed.
/* Check if we have permission to recieve. */
checkReceivePermission();
/* Make sure the connection is still open. */
ensureOpen();
if (((m_mode & Connector.READ) == 0) || (host != null)) {
throw new IOException("Invalid connection mode");
}
Message message = null;
int length = 0;
try {
SMSPacket smsPacket = new SMSPacket();
/*
* Packet has been received and deleted from inbox.
* Time to wake up receive thread.
*/
// Pick up the SMS message from the message pool.
length = receive0(m_iport, midletSuite.getID(),
connHandle, smsPacket);
if (length >= 0) {
String type;
boolean isTextMessage = true;
if (smsPacket.messageType == GSM_BINARY) {
type = MessageConnection.BINARY_MESSAGE;
isTextMessage = false;
} else {
type = MessageConnection.TEXT_MESSAGE;
isTextMessage = true;
}
message = newMessage(type,
new String(ADDRESS_PREFIX
+ new String(smsPacket.address)
+ ":" + smsPacket.port));
String messg = null;
if (isTextMessage) {
if (length > 0) {
if (smsPacket.messageType == GSM_TEXT) {
messg = new String(TextEncoder.toString(
TextEncoder.decode(smsPacket.message)));
} else {
messg = new String(TextEncoder.toString(
smsPacket.message));
}
} else {
messg = new String("");
}
((TextObject)message).setPayloadText(messg);
} else {
if (length > 0) {
((BinaryObject)message).setPayloadData(
smsPacket.message);
} else {
((BinaryObject)message).setPayloadData(new byte[0]);
}
}
((MessageObject)message).setTimeStamp(smsPacket.sentAt);
}
} catch (InterruptedIOException ex) {
length = 0;
throw new InterruptedIOException("MessageConnection is closed");
} catch (IOException ex) {
io2InterruptedIOExc(ex, "receiving");
} finally {
if (length < 0) {
throw new InterruptedIOException("Connection closed error");
}
}
return message;
|
private native int | receive0(int port, int msid, int handle, com.sun.midp.io.j2me.sms.Protocol$SMSPacket smsPacket)Receives SMS message
|
public void | send(javax.wireless.messaging.Message dmsg)Sends a message over the connection. This method extracts the data
payload from the Message object so that it can be sent as a
datagram.
String phoneNumber = null;
String address = null;
if (dmsg == null) {
throw new NullPointerException();
}
if (dmsg.getAddress() == null) {
throw new IllegalArgumentException();
}
/*
* parse name into host and port
*/
String addr = dmsg.getAddress();
HttpUrl url = new HttpUrl(addr);
if (url.port == -1) {
/* no port supplied */
url.port = 0;
}
/* Can not send to cbs address. */
if (addr.startsWith("cbs:")) {
// Can't send a CBS message.
throw new IllegalArgumentException("Can't send CBS msg.");
}
int numSeg = numberOfSegments(dmsg);
if ((numSeg <= 0) || (numSeg > 3)) {
throw new IOException("Error: message is too large");
}
try {
midletSuite.checkForPermission(Permissions.SMS_SEND,
url.host,
Integer.toString(numSeg));
} catch (InterruptedException ie) {
throw new InterruptedIOException("Interrupted while trying " +
"to ask the user permission");
}
ensureOpen();
if ((m_mode & Connector.WRITE) == 0) {
throw new IOException("Invalid mode");
}
int sourcePort = 0;
if ((m_mode & Connector.READ) != 0 && host == null) {
sourcePort = m_iport;
}
for (int restrictedPortIndex = 0;
restrictedPortIndex < restrictedPorts.length;
restrictedPortIndex++) {
if (url.port == restrictedPorts[restrictedPortIndex]) {
throw new SecurityException(
"not allowed to send SMS messages to the restricted ports");
}
}
int messageType = GSM_BINARY;
byte[] msgBuffer = null;
if (dmsg instanceof TextObject) {
byte[] gsm7bytes;
msgBuffer = ((TextObject)dmsg).getBytes();
if (msgBuffer != null) {
/*
* Attempt to encode the UCS2 bytes as GSM 7-bit.
*/
gsm7bytes = TextEncoder.encode(msgBuffer);
if (gsm7bytes != null) {
msgBuffer = gsm7bytes;
messageType = GSM_TEXT;
} else {
/*
* Encoding attempt failed. Send UCS2 bytes.
*/
messageType = GSM_UCS2;
}
}
} else if (dmsg instanceof BinaryObject) {
msgBuffer = ((BinaryObject)dmsg).getPayloadData();
} else {
throw new IllegalArgumentException("Message type not supported");
}
try {
send0(connHandle, messageType,
url.host,
url.port,
sourcePort,
msgBuffer);
} catch (IOException ex) {
io2InterruptedIOExc(ex, "sending");
}
|
private native int | send0(int handle, int type, java.lang.String host, int destPort, int sourcePort, byte[] message)Sends SMS message
|
protected void | setAppID(java.lang.String newValue)Sets the connection parameter in string mode.
try {
m_iport = Integer.parseInt(newValue);
} catch (NumberFormatException exc) {
m_iport = 0;
}
|
protected int | unblock00(int msid)Unblock the receive thread.
return open0(null, msid, 0);
|
private native int | waitUntilMessageAvailable0(int port, int handle)Waits until message available
|
protected int | waitUntilMessageAvailable00(int handle)Waits until message available
return waitUntilMessageAvailable0(m_iport, handle);
|