One important thing as far as network monitoring solutions for a CWN is concerned, involves setting up a system by which the administrators are informed in case one of our services goes down. We may use email or a messaging client like Jabber, but in the event that something goes wrong with the core switch or the gateway, and the internet and/or the intranet is out, this will be useless. In such a situation, the solution would be to use a media which doesn't involve the local area network or the internet for that matter, one of them being, SMSes. So this is where we choose to deploy Zabbix with a GSM modem on my netmon machine. Rohit, the technician who the Genus people (the company which provided us the modem) had sent over to demonstrate the modem, only knew how to operate it via hyper terminal which is an interface for Windows by which you can communicate with your serial port. He was supposed to show me how to use the AT commands and all that. But since we ITR folk at MNIT kick ass, we don't use Windows see? All our servers run on Debian, Gentoo, FreeBSD, Deeproot etc. No Windows! Now this dude had never used Linux before and even went to the extent of typing AT on my linux terminal. And since I was new to the whole idea of AT commands then, I didn't know how to talk with the serial port in linux, which is done using minicom, by the way. My immediate aim was to just test the modem and a quick look up on google told me that there's this thing called gsm-utils, which is a package used to send SMSes using a GSM modem (duh?) in linux. With apt-get install gsm-utils, I got the binaries installed in a jiffy and a quick browse through the man pages gave me all the info I needed to use this tool. So I insert my SIM into the device, and I try to send a message to Rohit's cell phone by typing the following into the console,
$: gsmsendsms -d /dev/ttyS0 XXXXXXXXXX “testing”

Then came the moment of truth, as me and Rohit stood there; waiting for some form of output to appear on the screen while the cursor kept blinking, when the welcome sound of the message-received tone on Rohit's handset sounded. I leaped in joy and punched the air with my signature style. Rohit shook hands with me and told me that it seems he isn't needed anymore. :P


When I met Gaur sir a few minutes later with the good news, he told me to test the modem from Zabbix. I didn't see why that could make any difference because as far as linux supported the modem (which I'd just tested and seen for myself) , Zabbix wouldn't complain as well. But hell was I wrong!


Now while I still could make Zabbix use the gsmsendsms command (a remote command) for the alerts, it came with it's own set of problems. First of all, Zabbix won't log the remote commands and second, it won't know if the command really executed or not. This wasn't really an issue because there's no way the command could NOT work see? But the main problem was the loss in flexibility of setting up the triggers themselves. If I use the gsmsendsms command, I'd have to write the same code over and over again for different phone numbers (for the different admins) and for different triggers. This seemed very sloppy and I'm the kind of guy who likes to keep things... well... beautiful :). This meant having to get the AT commands working at all costs.


So I made a very stupid trigger which would alert me in case the hostname on the netmon machine was changed. And since Zabbix sends an alert everytime the trigger changes values, I just had to change the condition a little bit and it kept equating to true and false. Hence, I kept switching the trigger between,

{zabbix_server: system.hostname.str(netmon)}

and

{zabbix_server: system.hostname.str(X)}

As soon as I saved the trigger, Zabbix tried to send an SMS. And as I'd expected, it didn't work! It gave me the following error,

“Expected [OK], received [ERROR]”

So to figure out what the problem was, I thought I'd install minicom and try sending an SMS manually using the darned AT commands myself. It was then that I figured out the problem. Zabbix seems to use the serial port with a default baud rate. And this didn't seem to match with the baud rate of the modem itself. Although I was able to send an SMS through minicom at a baud rate of 9600 baud, I couldnt get the same to work from Zabbix, even after setting the serial port speed to 9600 baud. At that point, I got an error like this,

“Expected [OK], received [*AT+CMEE=2\rERROR]”

(The * here, was some symbol my browser couldn't identify because of lack of unicode support)

So finally I decided enough is enough and I thought I'd give the source code a little tweak. And tucked away in a little corner of the source tree for Zabbix was a file named sms.c :).

And here are the relevant contents of the code,

#: vim ~zabbix-1.4.4/src/libs/zbxsms/sms.c

typedef struct {

char *message;

const char *result;

int timeout_sec;

} zbx_sms_scenario;


zbx_sms_scenario scenario[] = {

/* 0 */ {ZBX_AT_ESC , NULL , 0 }, /* Send */

/* 1 */ {"AT+CMEE=2\r" , "OK" , 5 }, /* verbose error values */

/* 1 */ {"ATE0\r" , "OK" , 5 }, /* Turn off echo */

/* 2 */ {"AT\r" , "OK" , 5 }, /* Init modem */

/* 3 */ {"AT+CMGF=1\r" , "OK" , 5 }, /* Switch to text mode */

/* 4 */ {"AT+CMGS=\"" , NULL ,0 }, /* Set phone number */

/* 5 */ {number , NULL , 0 }, /* Write phone number */

/* 6 */ {"\"\r" , "> " , 5 }, /* Set phone number */

/* 7 */ {message , NULL, 0 }, /* Write message */

/* 8 */ {ZBX_AT_CTRL_Z ,"+CMGS: ", 40 }, /* Send message */

/* 9 */ {NULL , "OK" , 1 }, /* ^Z */

/* EOS */ {NULL , NULL , 0 }

};

Hmmmm, AT+CMEE=2\r eh? Verbose error values? Doesn't look to important to me. Why not turn the OK beside it into ERROR and hence, trick Zabbix into sending an SMS even if it is an ERROR? Its worth a shot. So I change,

/* 1 */ {"AT+CMEE=2\r" , "OK" , 5 }, /* verbose error values */

into

/* 1 */ {"AT+CMEE=2\r" , "ERROR" , 5 }, /* verbose error values */

I exit vim and then type the following into the console,

#~zabbix-1.4.4: make && make install

And would you believe it? It actually worked! Ha! Talk about luck. It's kind of strange that inspite of receiving an ERROR, Zabbix proceeded to send the message. Strange. Oh well, there's one case where having the source code helped.