CHAPTER 5 ■ COMMUNICATION 178 It is also possible to use the mobile as a display device by using setlogo to control the text and/or graphic used in the phone’s logo. This might report basic status information about your e-mail, weather, or RSS feeds. You could also use the voice-dialing capabilities to call another phone so that you’re able to listen in to the sound of the house (like a high-tech, remote, baby monitor) through this: gnokii dialvoice 12345678 For this to work, you’d need to keep the phone’s microphone accessible (that is, not in a cupboard inside Node0) or wire an external mic to the phone. This can be extended as a personal “dial-a-disc” service, where the audio output of your computer is wired to the microphone in the mobile, and you can request music through a text message, which is then played back in the form of a voice call. It’s not practical, however, unless you have free (or very cheap) voice calls. The use of mobile for SMS is declining since newer phones contain broadband and usable web browsers as standard. The web interface has more control and flexibility than an SMS message could ever hope to have. But to equip all members of the family with one is a costly rollout, and you have no fallback method should your shiny new phone get sat on by an elephant! However, as a consequence, fewer new phones are likely to have SMS drivers since the development work would be appreciated by a comparatively smaller demographic. That is where the next solution comes in Custom Numbers and APIs Having one (or more) mobile phones attached to your PC isn’t the most cost-efficient way of handling messages. After all, all messages are entered into a phone, processed by the mobile networks’ computer systems, and converted back for display on a phone. It stands to reason there must be a way of connecting to these computer systems directly to send and receive messages. There is! A number of companies, such as IntelliSoftware (http://www.intellisoftware.co.uk) and Txtlocal (http://www.txtlocal.co.uk), offer an SMS gateway service that provides access to the mobile network through an API that lets you send and receive messages from any computer with Internet access. Their cost structure is that of a pay-as-you-go phone, with a setup charge (usually zero) and a per-message fee. This is usually cheaper than a pay-as-you-go phone since you don’t need to have a custom number (which is the expensive bit!), and it eliminates the cost of your initial phone purchase. And because it’s a web service, you can have as many different ones (for high- and low-priority messages, for example) as you like without running out of USB ports. There is still the problem of running out of credit during hectic periods, but you can usually provide a credit card number that will automatically top off your balance in these situations (which is dangerous, in my opinion!), or you can sign up (often with free trials) to many SMS gateway services to provide separate channels of communication, providing built-in redundancy to reduce failover. Sending Messages This is the easiest part to get working, because both of the services mentioned (which I’ll use as an example) provide an API that takes a basic HTTP request and translates it into a text message. My code for mxsms-intelli, for example, is as follows: CHAPTER 5 ■ COMMUNICATION 179 #!/usr/bin/php <?php include 'IntelliSMS.php'; array_shift($argv); // ignore program name $type = array_shift($argv); $toAddr = array_shift($argv); $message = implode(" ", $argv); $fromAddr = "MinervaHome"; $objIntelliSMS = new IntelliSMS(); $objIntelliSMS->Username = 'MyUserName'; $objIntelliSMS->Password = 'MyPassword'; $objIntelliSMS->MaxConCatMsgs = 1; $result = $objIntelliSMS->SendMessage($toAddr, $message, $fromAddr); ?> And that, believe it or not, is all the code that’s necessary! You invoke it as suspected with the following: mxsms-intelli sms 012345678 This stuff really works Although text messages can be extended over several packets, I have limited the maximum here to 1, in case of excessive output from a runaway application. Naturally, the clever formatting is hidden inside the library, which is similar to that use in the Txtlocal version, exposed here: #!/usr/bin/php <?php array_shift($argv); // ignore program name $type = array_shift($argv); $toAddr = array_shift($argv); $message = implode(" ", $argv); $fromAddr = "MinervaHome"; # Things get different now $uname = ' MyUserName'; $pword = 'MyPassword'; $message = urlencode($message); $data = "uname=".$uname."&pword=".$pword."&message=".$message."&from=". $fromAddr."&selectednums=".$toAddr."&info=1&test=0"; $ch = curl_init('http://www.txtlocal.com/sendsmspost.php'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); CHAPTER 5 ■ COMMUNICATION 180 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($ch); curl_close($ch); ?> The prologue to each piece of code is intentionally identical. This allows you to use either service interchangeably, maybe on a round-robin basis, according to whether you have credit or are sending a high- or low-priority message. By writing two differently named scripts, you can then either switch between them manually by issuing the following or have a separate script called mxsms that determines which transport to use: ln -s mxsms-intelli mxsms I have passed a $type parameter into this code so that SMS, for example, can become sms-high, as mentioned earlier. This can also be used to change the $fromAddr, which appears on your phone when you receive the message. It is limited to 11 characters, but since it is customizable, it could become part of your message, maybe to indicate the following: • The priority of the message • The service provider used • The number of credits left • The first 11 letters of the message Each provider has a slightly different API, with different functionality, but as far as the end result is concerned, they can all be used the same way. Some of the applications of SMS include sending daily weather reports, news feeds, or lottery results to your phone—or reporting when other house dwellers have arrived or left for work (so you can phone and encourage them otherwise). ■ Note The SMS protocol, as available to consumers, does not guarantee that the message will arrive or that it will arrive promptly. Most do, but it is possible (as most of us have experienced firsthand) for them to be delayed by hours, or even days, and sometimes they never appear at all. You should therefore have nothing critical—such as life-support machines—reliant on these messages. There are two other types of message you may want to send, WAP and binary. A WAP message is a single-credit SMS message that includes a piece of text and a URL, which can be opened using the phone itself (which may incur a cost on that device). This can be used for more complex statistical information, where the executive summary is in the text, with the URL linking to a prebuilt graph that is uploaded to your WAP server at the same time. The binary message is 140 octets of geeky goodness but because of its size is limited to sending small logos (which can also represent server performance graphs!) or ringtones. Sending multiple messages to a group of users is possible through most, if not all, SMS gateway APIs, but their administration is usually through the Web. And since you have a fully empowered Linux box controlling your environment, you might as well store the addresses on your machine and send CHAPTER 5 ■ COMMUNICATION 181 multiple messages that way. The cost is the same, and the time difference is generally negligible. I’ll expand the mxsms script in Chapter 7. Receiving Messages This is no more difficult than sending messages, but it does require some extra steps—and, if you’d like your own custom number, more cost. In either case, the SMS gateway company receives a message on your behalf and then passes it onto you via an alternate commonly agreed protocol so that you can do something specific with it. Depending on the company, service level, and API, you might be able to do the following: • Forward the text message as an e-mail • Request a web page with the sender and message as arguments • Send an autoresponse • Forward to another (mobile) number The two of interest here are the e-mail and web page handlers. In either case, the text-based format of SMS means that parsers are generally trivial to write. Sending the message from a phone can happen in a couple of ways. The cheapest way is to share a number with other users. In this case, you will send a message, which includes your username, to the number supplied by your SMS gateway. The gateway then looks up the given user with a target machine and issues a request. The format of this message might be as follows: username+your message here or as follows: username your message here or even as follows: null your message here In the latter case (as adopted by Txtlocal), the gateway looks up the phone number from which you’re sending the request and ties it to your account information, before passing the message on. It is also up to the gateway whether this username (or null) is included in the message. ■ Tip Choose a short username if possible to save SMS characters! You can save repeatedly writing your username if you save a version in your drafts folder and copy it out each time. Alternatively, you can purchase a specific number for our own use. In that case, you don’t have to include the username in the message anymore. This route usually incurs a setup fee. For those with even more money, you can buy a special short code (between four to six digits) that is an alias to the longer form of the number. These are usually used for businesses, however, and are priced accordingly. They CHAPTER 5 ■ COMMUNICATION 182 might be easier to remember, but you only really need them when your phone has died, making your address book inaccessible. In which case, carrying a written copy of the number is cheaper! So, once the message has arrived, you must process it. In the case of e-mail, you can use Procmail as you saw earlier to process the following into something useful with a simple regular expression: ##You have a new message from 012345678 saying Null This is my test. Note that the word Null is a symptom of the free protocol and the specific provider, as mentioned earlier. The web page request is the easier method, because the SMS gateway invokes a predetermined URL containing all the necessary parameters. Each company has a different format, so it is a good idea to create a script called echo.php for testing purposes. <?php $rt.= "Get:\n"; $rt.= print_r($_GET, TRUE); $rt.= "Post:\n"; $rt.= print_r($_POST, TRUE); file_put_contents( 'log.txt', file_get_contents( 'log.txt' ) . $rt ); ?> Since the SMS gateway ignores all output from the web pages it requests, you’ll never see this data, which is why you’ve redirected its output into a log file. You can have a rolling update of this file with the following: tail -f log.txt Then send a text message and have it redirected to echo.php, and you’ll see exactly what arguments are supplied. Using the earlier examples, IntelliSoftware provides the following: Get: Array ( ) Post: Array ( [from] => 012345678 [text] => This is my last test tonight [msgid] => 50011005000001624552 [type] => 1 ) Txtlocal gives this: Get: Array ( ) . computer with Internet access. Their cost structure is that of a pay-as-you-go phone, with a setup charge (usually zero) and a per-message fee. This is usually cheaper than a pay-as-you-go phone. "MinervaHome"; $objIntelliSMS = new IntelliSMS(); $objIntelliSMS->Username = 'MyUserName'; $objIntelliSMS->Password = 'MyPassword'; $objIntelliSMS->MaxConCatMsgs. because it’s a web service, you can have as many different ones (for high- and low-priority messages, for example) as you like without running out of USB ports. There is still the problem of running