SDK Script sms-control.are

For further information on how to configure see SMS Control.

sms-control.are
/* DESC: This script will execute commands received by SMS.
 * Copyright (C) 2012 NetModule AG, Switzerland
 */
 
INTERVAL        = 10;                           /* only run every 10 seconds                    */
MAXMSG          = 5;                            /* process max. 5 msgs                          */
MAXAGE          = 300;                          /* message mustn't be older than 5 mins         */
MAXLINES	= 32;				/* max. number of lines in msg (incl. header)   */
AUTH            = 1;                            /* perform authentication                       */
ADMPWD          = "";                           /* password used for authentication             */
IGNORECASE      = 1;                            /* ignore upper-/lower-case                     */
SENDERS         = mkarray(/* "+123456789" */);  /* allowed senders                              */
 
/* check if we should perform authentication */
if (argc == 2 && argv[1] == "noauth") {
    AUTH = 0;
}
 
/* retrieve password */
if (AUTH) {
    if (strlen(ADMPWD) == 0) {
        /* use configured admin password */
        ADMPWD = nb_config_get("admin.password");
        if (strlen(ADMPWD) > 0) {
            nb_syslog("using admin password for authentication");
        } else {
            /* not there -> use a default password instead */
            nb_syslog("using default password for authentication");
            ADMPWD = "admin01";
        }
    }
    if (IGNORECASE) ADMPWD = tolower(ADMPWD);
}
 
/* parse message */
string parse (string msg)
{
    /* read by line */
    lnr = 0;
    ishdr = 1;
    tlnr = 0;
    allowed = (length(SENDERS) == 0) ? 1 : 0;
 
    lp = msg;
    for (lnr = 0; lnr < MAXLINES && strlen(lp) > 0; lnr++) {
        pos = strchr(lp, "\n");
    	if (is_void(pos)) pos = strlen(lp);
 
        line = left(lp, pos);
	lp = substr(lp, pos + 1);
 
        if (strlen(line) == 0) {
            /* saw header separator */
            ishdr = 0;
            continue;
        }
        if (ishdr) {
            /* saw header line */
            if (left(line, 5) == "Sent:") {
                /* check age of message */
                sentdate = trim(substr(line, 5));
                sent = strptime(sentdate, "%Y-%m-%d %H:%M:%S");
 
                if (!is_void(sent)) {
                    /* got a valid sent date */
                    now = localtime(time());
                    age = mktime(now) - mktime(sent);
                    nb_syslog("message has been sent %ds ago", age);
                    if (age > MAXAGE) {
                    	nb_syslog("rejecting too old message");
                        return "";
                    }
                } else {
                    nb_syslog("time check has been omitted");
                }
            } else if (left(line, 5) == "From:") {
                from = substr(line, 6);
                if (length(SENDERS) > 0) {
                    for (s = 0; s < length(SENDERS); s++) {
                        sender = SENDERS[s]; 
                        if (left(from, strlen(sender)) == sender) {
                            allowed = 1;
                            break;
                        }
                    }
                }
                if (allowed == 0) {
                    nb_syslog("rejecting message from unknown sender %s", from);
                    return "";
                } else {
                    nb_syslog("sender %s can pass", from);
                }
            }
        } else {
            /* saw text line */
            if (IGNORECASE) line = tolower(line);
 
            if (AUTH && tlnr == 0) {
                /* first line of message must contain the password */
                if (left(line, strlen(ADMPWD)) != ADMPWD) {
                    nb_syslog("authentication failed");
                    return "";
                } else {
                    nb_syslog("authentication succeeded");
                }
            } else if ((AUTH && tlnr == 1) || (!AUTH && tlnr == 0)) {
                /* this line must contain the command */
                if (left(line, 6) == "reboot") {
                    return "reboot";
                } else if (left(line, 7) == "connect") {
                    return "connect";
                } else if (left(line, 10) == "disconnect") {
                    return "disconnect";
                } else if (left(line, 6) == "status") {
                    return "status";
                } else if (left(line, 6) == "output") {
                    return left(line, 13);
                }
            } else {
                break;
            }
            tlnr++;
        }
    }
 
    nb_syslog("no command detected");
 
    return "";
}
 
int setdio (string cmd) 
{
    newstate = substr(cmd, 9, 3);
    port = substr(cmd, 7, 1);
 
    if (port != "1" && port != "2") {
        nb_syslog("invalid DIO port %s\n", port);        
        return -1;
    }     
    if (newstate == "on") { 
        st = 1;
    } else if (newstate == "off") { 
        st = 0;
    } else  {         
        nb_syslog("invalid new DIO state %s\n", newstate);
        return -1;
    }        
 
    rc = nb_dio_set(sprintf("out%s", port), st);
    if (rc) {
        nb_syslog("Unable to set state %s for DIO output port %s\n", newstate, port);
        return -1;
    } else {            
        nb_syslog("Setting state %s for DIO output port %s\n", newstate, port);
        return 0; 
    }
}
 
/* check if we got stressed */
LASTFILE = "/tmp/sms-control.last";
last = 0;
 
fp = fopen(LASTFILE, "r");
if (fp) {
    /* we have been run at least one time */
    str = fread(fp, 32);
    if (str) last = (int) str;
    fclose(fp);
}
 
now = mktime(localtime(time()));
elapsed = now - last;
if (elapsed > 0 && elapsed < INTERVAL) {
    nb_syslog("we have ben run %d seconds ago. skipping.", elapsed);
    exit(0);
}
 
/* record timestamp */
fp = fopen(LASTFILE, "w+");
if (fp) {
    str = sprintf("%d", now);
    fwrite(fp, str);
    fclose(fp);
}
 
/* read inbox */
msgs = nb_sms_list();
nr_msgs = length(msgs);
 
if (nr_msgs == 0) {
    nb_syslog("there are no messages in your inbox");
    exit(0);
}
 
nb_syslog("you have %d message(s) in your inbox", nr_msgs);
 
/* track states */
reboot = 0;
connecting = 0;
disconnecting = 0;
 
 
/* only process latest messages */
start = nr_msgs - MAXMSG;
if (start < 0) start = 0;
 
for (i=start; i<nr_msgs; i++) {
    msg = nb_sms_retrieve(msgs[i]);
    if (!msg) continue;
 
    nb_syslog("processing message %d of %d (ID %s)", 
               i, nr_msgs, msgs[i]);
 
    cmd = parse(msg);
    if (cmd == "reboot") {   
        nb_syslog("reboot command received");
        reboot = 1;
    } else if (cmd == "connect") {
        nb_syslog("connect command received");
        if (connecting) {
            nb_syslog("already connecting");
        } else {
            /* enable first wanlink */
            nb_config_set("wanlink.0.mode=1");
            connecting = 1;
        }
    } else if (cmd == "disconnect") {
        nb_syslog("disconnect command received");
        if (disconnecting) {
            nb_syslog("already disconnecting");
        } else {
            /* disable first wanlink */
            nb_config_set("wanlink.0.mode=0");
            disconnecting = 1;
        }
    } else if (cmd == "status") {
        nb_syslog("status command received");
        rcpt = nb_sms_header(msgs[i], "From");
        if (rcpt) {
            id = nb_sms_send(rcpt, nb_status_summary());
            if (!id) {
                nb_syslog("unable to send status message to %s", rcpt);
            } else {
                nb_syslog("successfully queued status message to %s (ID %s)", rcpt, id);
            }
        }
    } else if (left(cmd,6) == "output") {
        nb_syslog("dio out command received");
        setdio(cmd);
    } else {
        nb_syslog("ignoring invalid message");
    }
 
    /* delete message  */
    ret = nb_sms_delete(msgs[i]);
    if (ret == 0) nb_syslog("deleted message %s", msgs[i]);
}
 
if (reboot == 1) {
    /* trigger reboot  */
    nb_syslog("rebooting system");
    nb_reboot();
}
 
exit(0);