(local fcntl (require "posix.fcntl")) (local posix (require "posix")) (local { : read : write } (require "posix.unistd")) (local {: tcgetattr : tcsetattr : tcdrain : CLOCAL : CREAD : ICANON : ECHO : ECHOE : ISIG : OPOST } (require "posix.termio")) (local { : nanosleep } (require "posix.time")) (local { : view } (require "fennel")) (local gsm-char (require :unicode-to-gsm)) (fn escape-for-logging [s] (s:gsub "%c" (fn [x] (.. "{" (string.byte x) "}")))) (fn tx [fd s] (write fd s) (print (.. ">>> " (escape-for-logging s))) (nanosleep {:tv_sec 0 :tv_nsec (* 10 1000 1000)})) (fn chars [i] (if (not i) "" (< i 256) (string.char i) (.. (string.char (rshift i 8)) (string.char (band i 0xff))))) (fn unicode-to-gsm [s] (s:gsub "." (fn [c] (chars (. gsm-char (string.byte c)))))) ;(print (escape-for-logging (unicode-to-gsm "hello"))) ;(print (escape-for-logging (unicode-to-gsm "{he@llo}€"))) (fn expect [fd pattern] (let [b (read fd 1024)] (if (> (# b) 0) (do (print (.. "<<< " (escape-for-logging b))) (if (string.find b pattern) (do (print "found" pattern) true) (expect fd pattern))) nil))) (fn send-sms [number body] (let [fd (fcntl.open "/dev/serial/by-id/usb-HUAWEI_HUAWEI_HiLink-if00-port0" posix.O_RDWR) termios (tcgetattr fd)] (tset termios :cflag (bor termios.cflag CLOCAL CREAD)) (tset termios :lflag (band termios.lflag (bnot ICANON) (bnot ECHO) (bnot ECHOE) (bnot ISIG))) (tset termios :oflag (band termios.oflag ( bnot OPOST))) (tcsetattr fd 0 termios) ;; opt->c_cc[VMIN] = 1; ;; opt->c_cc[VTIME] = 10; (tcdrain fd) (doto fd (tx "AT\r\n") (expect "OK") (tx "AT&F\r\n") (expect "OK") (tx "ATE0\r\n") ;disable command echo (expect "OK") (tx "AT+CMEE=1\r\n") ;print CME errors (expect "OK") (tx "AT+CMGF=1\r\n") ;SMS text mode (not PDU mode) (expect "OK") (tx "AT+CSCS=\"GSM\"\r\n") ; default character set (expect "OK") (tx "AT+CSMP=17,12,0,0\r\n") ; message valid for 12*5 minutes (expect "OK") (tx "AT+CSCA=\"+447958879879\",145\r\n") ;set SMSC (expect "OK") (tx (.. "AT+CMGS=\"" number "\"\r\n")) (expect ">") ;; (tx (unicode-to-gsm body)) (tx body) (tx "\026\r\n") (expect "OK")))) { :send send-sms }