PageRenderTime 58ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/packages/sms/gateway/smscommon.lua

http://luasms.googlecode.com/
Lua | 431 lines | 382 code | 23 blank | 26 comment | 73 complexity | d67e2256705b178db2f74db2bd7cdad7 MD5 | raw file
  1. socket = require("socket")
  2. json = require("json")
  3. require("smscompress")
  4. require("smsrs232")
  5. require("smsdb")
  6. DEBUG = 2
  7. function printDL(level, ...)
  8. if level == 0 then return end
  9. local lista = {...}
  10. local level = level or 99
  11. local ttipo = {"ERROR", "ERROR", "WARNING", "INFO"}
  12. local stipo = "DEBUG-INFO"
  13. if level < 5 then
  14. stipo = ttipo[level]
  15. end
  16. if level <= DEBUG then
  17. -- io.write(string.format("%s %s:%s %s ",os.date("%x %X",socket.gettime()), PROGRAM, FUNCTION,stipo))
  18. if level < 5 then
  19. io.write(string.format("%s %s",os.date("%x %X", socket.gettime()), stipo))
  20. else
  21. io.write("\t")
  22. end
  23. if lista then
  24. for i=1, #lista do
  25. io.write(" "..tostring(lista[i]))
  26. end
  27. end
  28. io.write("\n")
  29. end
  30. end
  31. --[[
  32. SMS Functions
  33. ]]
  34. function leer(dev)
  35. local t1 = socket.gettime()
  36. local str = ""
  37. local status = ""
  38. local serr = nil
  39. local text = ""
  40. while true do
  41. local e, rspta = dev:read(1,100)
  42. if socket.gettime() - t1 > 5 then
  43. return {text=str, status="ERROR TimeOut", rawdata=text}, text, status, str, "timeout"
  44. end
  45. if rspta==nil then
  46. if str:match("ERROR: %d+\r\n$") then
  47. status = trim(str:match("ERROR: %d+\r\n$"))
  48. break
  49. end
  50. if str:sub(-7) == "ERROR\r\n" then
  51. status = trim(str:sub(-7))
  52. break
  53. end
  54. if str:sub(-4) == "OK\r\n" then
  55. status = trim(str:sub(-4))
  56. break
  57. end
  58. else
  59. t1 = socket.gettime()
  60. str = str .. rspta
  61. end
  62. end
  63. text = trim(str:gsub(status,""))
  64. return {text=text, status=status, rawdata=str}, text, status, str, serr
  65. end
  66. function leersend(dev)
  67. local str = ""
  68. local serr = nil
  69. local esta = false
  70. while true do
  71. local e, rspta = dev:read(1,100)
  72. if rspta==nil then
  73. if str:sub(-7) == "ERROR\r\n" then break end
  74. if str:sub(-4) == "OK\r\n" then break end
  75. if esta == true then break end
  76. else
  77. if str:sub(-1) == ">" then esta = true end
  78. -- print(string.byte(rspta),rspta)
  79. str = str .. rspta
  80. end
  81. end
  82. return str, serr
  83. end
  84. function command(dev,cmd)
  85. local cmd = cmd or ""
  86. cmd = string.format("AT%s\r\n",cmd)
  87. -- print(cmd)
  88. dev:write(cmd)
  89. -- socket.sleep(.5)
  90. local tmsg, str, serr = leer(dev)
  91. if DEBUG > 4 then
  92. print("cmd: "..tostring(cmd),"msg: "..tostring(str),"status: "..tostring(serr))
  93. end
  94. return tmsg, str, serr
  95. end
  96. function checkMsgs(dev)
  97. local rspta, text, status, fullmsg, serr = command(dev,"+CPMS?") -- Obtiene los valores de las distintas memorias y cantidad de mensajes en cada una
  98. local tmsgs = {}
  99. for mem, i, e in string.gfind(rspta.text,'"(%a+)",(%d+),(%d+)') do
  100. tmsgs[mem] = {cnt=i, of=e}
  101. end
  102. return tmsgs
  103. end
  104. function readAllMessages(modem)
  105. local dev = modem.dev
  106. local trspta = {}
  107. if dev == nil then return trspta end
  108. rspta, text, status, str, serr =command(dev,"+CMGF=1") -- Setea Modo Texto
  109. if rspta.status == "OK" then
  110. local rspta, serr = command(dev,"+CPMS?") -- Obtiene los valores de las distintas memorias y cantidad de mensajes en cada una
  111. local tmsgs = {}
  112. for mem, i, e in string.gfind(rspta.text,'"(%a+)",(%d+),(%d+)',2) do
  113. tmsgs[mem] = {cnt=i, of=e}
  114. end
  115. for k, t in pairs(tmsgs) do -- Procesa cada Memoria
  116. if tonumber(t.cnt) > 0 then
  117. rspta, str, serr = command(dev,string.format('+CPMS="%s"',k))
  118. rspta, str, serr = command(dev,'+CMGL="ALL"')
  119. local j = split(rspta.text, "+CMGL: ")
  120. for i, line in ipairs(j) do
  121. local s, e, status = string.find(line,"\r\n\r\n(%w+)")
  122. if s and e and status then
  123. line = line:sub(1,s-1)
  124. end
  125. print (line)
  126. for idx, status, callerId, nada, fecha, msg in string.gfind(line, '(%d+),"([^"]*)","([^",]*)",([^,]*),"([^"]*)"\r\n(.+)') do
  127. trspta[#trspta+1] = {}
  128. trspta[#trspta].mem = k
  129. trspta[#trspta].dev = modem.dev
  130. trspta[#trspta].cmd = "+CMGL: "
  131. trspta[#trspta].msg = msg or ""
  132. trspta[#trspta].fecha = fecha or ""
  133. trspta[#trspta].fecha = "20"..fecha:gsub("/","-")
  134. trspta[#trspta].fecha = trspta[#trspta].fecha:gsub(","," ")
  135. trspta[#trspta].nose = nada or ""
  136. trspta[#trspta].callerId = callerId or ""
  137. trspta[#trspta].status = status or ""
  138. trspta[#trspta].idx = idx or ""
  139. trspta[#trspta].rawdata = "+CMGL: "..line
  140. end
  141. --[[
  142. for idx, status, callerId, nada, msg in string.gfind(line, '(%d+),"([^"]*)","([^",]*)",([^,]*),\r\n(.+)') do
  143. msg = msg or ""
  144. fecha = fecha or ""
  145. nada = nada or ""
  146. callerId = callerId or ""
  147. status = status or ""
  148. idx = idx or ""
  149. print(string.format("idx:'%s'\n\tst:'%s',\n\ttoNum:'%s',\n\tnada:'%s',\n\tfecha:'%s',\n\tmsg:'%s'",idx, status, callerId, nada, fecha, msg))
  150. end
  151. ]]
  152. end
  153. end
  154. end
  155. else -- Modo texto no soportado
  156. print("Modo Texto no Soportado")
  157. end
  158. return trspta
  159. end
  160. function readMessage(dev,mem,idx)
  161. local tmsg = {}
  162. tmsg, text, status, str, serr =command(dev,"+CMGF=0") -- Setea Modo Hexadecimal
  163. tmsg, text, status, str, serr = command(dev,string.format('+CPMS="%s"',mem)) -- Setea Memoria a leer
  164. if tmsg.status == "OK" then
  165. return command(dev,string.format('+CMGR=%s',idx)) -- Lee mensage en la posicion idx
  166. end
  167. return nil
  168. end
  169. function sendMessage(dev, nro, msg)
  170. local str, serr = command(dev,"+CMGF=1")
  171. str, serr = command(dev,"+CSMS=1")
  172. str, serr = command(dev,'+CPMS="SM"')
  173. str, serr = command(dev,"+CMGF=1")
  174. str, serr = command(dev,'+CSCS="GSM"')
  175. str, serr = command(dev,'+CMEE=1')
  176. local tosend = string.format('AT+CMGS="%s",129\r',nro)
  177. -- local tosend = string.format('AT+CMGS="%s"\r\n',nro)
  178. print("------------------------------------------")
  179. print(tosend)
  180. print("------------------------------------------")
  181. dev:write(tosend)
  182. rspta = leersend(dev)
  183. print("R Msg2", rspta)
  184. msg=msg:sub(1,110)
  185. tosend = string.format('%s%s',msg,string.char(26))
  186. print("------------------------------------------")
  187. print(tosend)
  188. print("------------------------------------------")
  189. dev:write(tosend)
  190. return leer(dev)
  191. end
  192. function proccess(dev)
  193. if dev then
  194. local msgs;
  195. local tmsg, rspta , serr = command(devs[a],"")
  196. -- if rspta and rspta:match("OK") then
  197. if tmsg.status == "OK" then
  198. tmsg = command(devs[a],"+CPIN?")
  199. if tmsg.status == "OK" then
  200. print("/dev/ttyUSB"..a)
  201. tmsgs = readMessages(devs[a])
  202. else
  203. print("/dev/ttyUSB"..a)
  204. print(tmsg.text, tmsg.status)
  205. end
  206. end
  207. if msgs then
  208. if #msgs > 0 then
  209. for i, t in ipairs(msgs) do
  210. print(t.fecha,t.callerId,t.msg)
  211. print("")
  212. if t.status=="REC UNREAD" then
  213. -- if #msgs == i then
  214. -- sendMessage(devs[a],t.callerId,"Mensaje SMS Recibido: "..t.msg)
  215. end
  216. end
  217. end
  218. end
  219. else
  220. print(info)
  221. end
  222. end
  223. function setModem(ldevs, gateway)
  224. modem = {}
  225. IMSI = {}
  226. for _, a in ipairs(ldevs) do
  227. print("Abriendo port "..a.port)
  228. local topen = socket.gettime()
  229. dev , info = openPort(a.port)
  230. print(info)
  231. if dev then
  232. topen = socket.gettime() - topen
  233. local tmsg = command(dev,"")
  234. if tmsg.status == "OK" then
  235. IMSIdentity = command(dev,'+CIMI') -- InternationalMobileSubscriberIdentity
  236. modem[a.port] = {}
  237. modem[a.port].port = a.port or "undefined"
  238. modem[a.port].gateway = gateway or "undefined"
  239. modem[a.port].number = a.number or "undefined"
  240. modem[a.port].timeopen = topen
  241. modem[a.port].IMSIdentity = IMSIdentity.text
  242. _, modem[a.port].smsGateWay = command(dev,"+CSCA?") -- obtiene el gateway y el modo
  243. _, modem[a.port].operator = command(dev,"+COPS?") -- Nombre del proveedor
  244. modem[a.port].dev = dev -- handle port
  245. _, modem[a.port].marca = command(dev,'+CGMI') -- Marca
  246. _, modem[a.port].modelo = command(dev,'+CGMM') -- Modelo
  247. _, modem[a.port].revision = command(dev,'+CGMR') -- Revision
  248. _, modem[a.port].serialNumber = command(dev,'+CGSN') -- Serial Number
  249. _, modem[a.port].signalLevel = command(dev,"+CSQ") --Signal level
  250. modem[a.port].enabled = true
  251. if IMSIdentity.status == "OK" then
  252. if IMSI[IMSIdentity.text] then
  253. print(IMSIdentity.text,modem[IMSI[IMSIdentity.text]].timeopen,topen)
  254. if modem[IMSI[IMSIdentity.text]].timeopen > topen then
  255. modem[IMSI[IMSIdentity.text]].dev:close()
  256. modem[IMSI[IMSIdentity.text]] = nil
  257. IMSI[IMSIdentity.text] = a.port
  258. else
  259. modem[a.port].dev:close()
  260. modem[a.port] = nil
  261. end
  262. else
  263. IMSI[IMSIdentity.text] = a.port
  264. end
  265. else
  266. print(a.port.." No tiene SIM o SIM no funciona")
  267. modem[a.port].enabled = false
  268. modem[a.port].dev:close()
  269. modem[a.port].dev = nil
  270. end
  271. else
  272. print(a.." no es modem")
  273. dev:close()
  274. end
  275. end
  276. end
  277. return modem
  278. end
  279. function checkModem(ldevs)
  280. devs = {}
  281. modem = {}
  282. IMSI = {}
  283. for _, a in ipairs(ldevs) do
  284. print("Abriendo port "..a)
  285. local topen = socket.gettime()
  286. dev , info = openPort(a)
  287. print(info)
  288. if dev then
  289. topen = socket.gettime() - topen
  290. local tmsg = command(dev,"")
  291. if tmsg.status == "OK" then
  292. IMSIdentity = command(dev,'+CIMI') -- InternationalMobileSubscriberIdentity
  293. modem[a] = {}
  294. modem[a].timeopen = topen
  295. modem[a].IMSIdentity = IMSIdentity
  296. modem[a].smsGateWay = command(dev,"+CSCA?") -- obtiene el gateway y el modo
  297. modem[a].operator = command(dev,"+COPS?") -- Nombre del proveedor
  298. modem[a].dev = dev -- handle port
  299. modem[a].marca = command(dev,'+CGMI') -- Marca
  300. modem[a].modelo = command(dev,'+CGMM') -- Modelo
  301. modem[a].revision = command(dev,'+CGMR') -- Revision
  302. modem[a].serialNumber = command(dev,'+CGSN') -- Serial Number
  303. modem[a].signalLevel = command(dev,"+CSQ") --Signal level
  304. modem[a].enabled = true
  305. if modem[a].IMSIdentity.status == "OK" then
  306. if IMSI[IMSIdentity.text] then
  307. print(IMSIdentity.text,modem[IMSI[IMSIdentity.text]].timeopen,topen)
  308. if modem[IMSI[IMSIdentity.text]].timeopen > topen then
  309. modem[IMSI[IMSIdentity.text]].dev:close()
  310. modem[IMSI[IMSIdentity.text]] = nil
  311. IMSI[IMSIdentity.text] = a
  312. else
  313. modem[a].dev:close()
  314. modem[a] = nil
  315. end
  316. else
  317. IMSI[IMSIdentity.text] = a
  318. end
  319. else
  320. print(a.." No tiene SIM o SIM no funciona")
  321. modem[a].enabled = false
  322. modem[a].dev:close()
  323. modem[a].dev = nil
  324. end
  325. else
  326. print(a.." no es modem")
  327. dev:close()
  328. end
  329. end
  330. end
  331. return modem
  332. end
  333. function findModem()
  334. ldevs = {}
  335. fdevs = io.popen("ls /dev/ttyUSB*")
  336. for line in fdevs:lines() do
  337. ldevs[#ldevs+1]=line
  338. end
  339. fdevs:close()
  340. fdevs = io.popen("ls /dev/ttyS*")
  341. for line in fdevs:lines() do
  342. ldevs[#ldevs+1]=line
  343. end
  344. fdevs:close()
  345. return checkModem(ldevs)
  346. end
  347. function isVoto(t,dbCon)
  348. local _, _, mesa, votos, fpv_presi, fpv_sena, fpv_dip, b_presi, b_sena, b_dip = t.msg:gmatch("(%d+)%.(%d+)%.(%d+)%.(%d+)%.(%d+)%.(%d+)%.(%d+)%.(%d+)")
  349. if mesa then
  350. print(mesa, votos, fpv_presi, fpv_sena, fpv_dip, b_presi, b_sena, b_dip)
  351. return 1
  352. end
  353. return 0
  354. end
  355. function showRspta(t,dbCon)
  356. print(k, t)
  357. -- print (t.fecha, t.callerId, t.msg)
  358. end
  359. function decompress(str)
  360. local hc = 0
  361. local comp = ""
  362. str = string.gsub(str, "(%x%x)", function (h)
  363. hc = hc + 1
  364. local bin = hex2bin(h)
  365. local subin = bin:sub(hc+1)
  366. local toconv = "0"..subin..comp
  367. local rslt = string.char(bin2dec(toconv:sub(1,8)))
  368. -- print(rslt, h, hc, bin, subin, comp, toconv)
  369. comp = bin:sub(1,hc)
  370. if hc == 8 then
  371. hc = 0
  372. comp = ""
  373. end
  374. return rslt
  375. end)
  376. return str
  377. end
  378. function decompress1(str)
  379. local hc = 0
  380. local comp = ""
  381. -- print("Resto",str:len() % 16)
  382. if (str:len() % 16) > 0 then
  383. str = str.."00"
  384. end
  385. str = string.gsub(str, "(%x%x)", function (h)
  386. hc = hc + 1
  387. local bin = hex2bin(h)
  388. local subin = bin:sub(hc+1)
  389. local toconv = "0"..subin..comp
  390. local rslt = string.char(bin2dec(toconv:sub(1,8)))
  391. -- print(rslt, h, hc, bin, subin, comp, toconv)
  392. comp = bin:sub(1,hc)
  393. if hc == 8 then
  394. hc = 1
  395. comp = ""
  396. bin = hex2bin(h)
  397. subin = bin:sub(hc+1)
  398. toconv = "0"..subin..comp
  399. rslt = rslt .. string.char(bin2dec(toconv:sub(1,8)))
  400. comp = bin:sub(1,hc)
  401. end
  402. return rslt
  403. end)
  404. return str
  405. end
  406. function getReg(str,len)
  407. return str:sub(1,len), str:sub(len+1)
  408. end