SMS Commands

This section applies primarily to Android(APK) phones that have been provisioned, go mobile and expect to receive commands. Android pads typically do not have a cell radio built in, so while pads can be provisioned and have a cell phone number, they cannot send/receive phone calls or SMS messages unless they have cellular capability, as some do.

Nebula sends commands to mobile devices via SMS. The mobile device typically receives the message within a few seconds of sending. Mobile devices send commands to home devices via HTTP -> hub(public IP address) -> any home Nebula device. Mobile devices receive command responses from home devices via the open HTTP pipe the command was sent on.

SMS messages have a size limit of 140 bytes for messages. If an SMS message is greater than the limit it is truncated by the service provider to 140 bytes. A truncated message will fail the test Nebula imposes to insure received commands conform to a GalixiPcol. This becomes even more problematic because SMS commands are prepended with SMS_CMD_CODE to identify them as coming from Nebula. The default code is GLX. When encryption is used the message also contains a 26 byte Initialization Vector(IV key), similar to a public key, used to decrypt the message.

Example: Using Ping which has no command payload.

Send Ping plain text SMS message is 23 bytes:
GLX00200002000100000000
Send Ping encrypted SMS message is 73 bytes:
GLX^525n2YfsqV3Se+J4rdjmnA==^Aks/5NGvoRIfZ96N3exqWgssgQv7KNcLOWR6DOLR1lw=

With a 140 byte limit on SMS messages, there are very few bytes left to include a payload with the command. Nebula uses Device 1 to hold SMS commands greater than 140 bytes and instructs the mobile device, with a no payload SMS command (73 bytes), to retrieve the message from Device 1 via HTTP.

Nebula Send SMS Commands

When sending a command Nebula first checks if the command is going to a mobile device. If it is the command is directed to SendCommand.smsOp(). The APK smsOp method first checks that permission to send SMS has been granted. It then encrypts the command if required. Next it checks if the command exceeds 140 bytes. If it’s less than 140 bytes the command is sent as an SMS message. If it’s greater than 140 bytes the command is sent to and saved on Device 1 with the SmsPutOn1 command. This is followed by sending SmsGetOn1 as an SMS message to the intended receiver. When the receiver gets the message it will send a SmsGetFrom1 command to Device 1. The receiver will retrieve, execute the command and reply with an SmsCmdReply command to the sender.

There is a “gotcha” if multiple devices are mobile AND the command is sent in a loop AND the command is greater than 140 bytes. This is the case for the commands Add, Modify or Delete device. The command may be wrong due to Device1.StaticValues.bigSms getting updated, via HTTP, before the (SMS) receiving device retrieves the command. For Nebula, the Add, Modify and Delete device commands always contains the same payload(a CSV of the device). Only the toDevice changes. SmsProcessorActivity checks for the Nebula loop commands and will run them regardless of the toDevice. Note that the toDevice received the command on its unique phone number, so it gets the looped command only once. If you send a command in a loop it’s OK for HTTP because SendCommand.clientOp() blocks, delaying the loop, until a reply or timeout occurs. This is on the Nebula TODO list to address.

Nebula Reply to SMS Commands

Nebula is notified of an incoming SMS by SmsBroadcastReceiver. The BroadcastReceiver verifies the SMS and checks if the message starts with the SMS_CMD_CODE indicating that the message is a Nebula command. If not the message is ignored. If it is a Nebula command the BroadcastReceiver passes the command to SmsProcessorActivity where it is decrypted if necessary. SmsProcessorActivity contains the logic for retrieving the command from Device 1, executing the command and responding to it by either HTTP if sent by a home device or by SMS if the sender is mobile as well.

A response is returned to the sender for all commands received whether the command arrives via HTTP or SMS. Replies have a payload from the server that is used by the command’s clientPostAction method. In the case of SMS the SmsProcessorActivity determines if the incoming SMS is a command or an SmsCmdReply(also a command). If it’s a command, it gets run and replied to. SmsProcessorActivity only runs on mobile devices. If it receives an SmsCmdReply, it knows that the other device is mobile too. If both devices are mobile they can end up in an endless situation of replying to an SmsCmdReply with an SmsCmdReply. SmsProcessorActivity will send an SmsEndReply command instead of SmsCmdReply if the other device is mobile too. The other device, also processing commands with SmsProcessorActivity, will know not to reply to an SmsEndReply command.