luat_lib_sms.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. /*
  2. @module sms
  3. @summary 短信
  4. @version 1.0
  5. @date 2022.12.08
  6. @demo sms
  7. @tag LUAT_USE_SMS
  8. @usage
  9. -- 注意, Air780E/Air600E/Air780EG/Air780EG均不支持电信卡的短信!!
  10. -- 意思是, 当上述模块搭配电信SIM卡, 无法从模块发出短信, 也无法在模块接收短信
  11. -- 如果是联通卡或者移动卡, 均可收取短信, 但实名制的卡才能发送短信
  12. */
  13. #include "luat_base.h"
  14. #include "luat_msgbus.h"
  15. #include "luat_mem.h"
  16. #include "luat_mobile.h"
  17. #include "luat_timer.h"
  18. #include "luat_rtos.h"
  19. #include "luat_str.h"
  20. #include "luat_sms.h"
  21. #ifndef bool
  22. #define bool uint8_t
  23. #endif
  24. #define LUAT_LOG_TAG "sms"
  25. #include "luat_log.h"
  26. static int lua_sms_ref = 0;
  27. static int lua_sms_recv_long = 1;
  28. typedef struct long_sms
  29. {
  30. uint8_t refNum;
  31. uint8_t maxNum;
  32. uint8_t seqNum;
  33. char buff[1];
  34. }long_sms_t;
  35. typedef struct long_sms_send
  36. {
  37. size_t payload_len;
  38. uint8_t *payload;
  39. }long_sms_send_t;
  40. #define LONG_SMS_CMAX (128)
  41. static long_sms_t* lngbuffs[LONG_SMS_CMAX];
  42. static luat_sms_pdu_packet_t g_s_sms_pdu_packet = {0};
  43. static long_sms_send_t g_s_sms_send = {0};
  44. static uint8_t ref_idx = 254;
  45. static uint64_t long_sms_send_idp = 0;
  46. static int l_long_sms_send_callback(lua_State *L, void* ptr){
  47. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  48. if (long_sms_send_idp)
  49. {
  50. lua_pushboolean(L, msg->arg1 == 0 ? 0 : 1);
  51. luat_cbcwait(L, long_sms_send_idp, 1);
  52. long_sms_send_idp = 0;
  53. }
  54. /*
  55. @sys_pub sms
  56. 短信发送结果
  57. SMS_SENT
  58. @result boolean 发送结果,成功为true, 失败为false
  59. @usage
  60. sys.subscribe("SMS_SENT", function(result)
  61. log.info("sms send result", result)
  62. end)
  63. */
  64. lua_getglobal(L, "sys_pub");
  65. lua_pushliteral(L, "SMS_SENT");
  66. lua_pushboolean(L, msg->arg1 == 0 ? 0 : 1);
  67. lua_call(L, 2, 0);
  68. g_s_sms_pdu_packet.maxNum = 0;
  69. return 0;
  70. }
  71. static void push_sms_args(lua_State* L, luat_sms_recv_msg_t* sms, char* dst, size_t dstlen) {
  72. char phone[strlen(sms->phone_address) * 3 + 1];
  73. memset(phone, 0, strlen(sms->phone_address) * 3 + 1);
  74. size_t outlen = 0;
  75. memcpy(phone, sms->phone_address, strlen(sms->phone_address));
  76. if (strlen(phone) > 4 && phone[0] == '0' && phone[1] == '0' && strlen(phone) % 2 == 0) {
  77. // 看来是ucs编码了
  78. luat_str_ucs2_to_char(sms->phone_address, strlen(sms->phone_address), phone, &outlen);
  79. phone[outlen] = 0x00;
  80. }
  81. lua_pushstring(L, phone);
  82. if (dst == NULL) {
  83. luaL_Buffer buff;
  84. luaL_buffinit(L, &buff);
  85. for (size_t j = 0; j < sms->maxNum; j++)
  86. {
  87. for (size_t i = 0; i < LONG_SMS_CMAX; i++)
  88. {
  89. if (lngbuffs[i] && lngbuffs[i]->refNum == dstlen && lngbuffs[i]->seqNum == j + 1) {
  90. luaL_addstring(&buff, lngbuffs[i]->buff);
  91. }
  92. }
  93. }
  94. luaL_pushresult(&buff);
  95. }
  96. else {
  97. lua_pushlstring(L, dst, dstlen);
  98. }
  99. // 添加元数据
  100. lua_newtable(L);
  101. // 长短信总数
  102. lua_pushinteger(L, sms->refNum);
  103. lua_setfield(L, -2, "refNum");
  104. // 当前序号
  105. lua_pushinteger(L, sms->seqNum);
  106. lua_setfield(L, -2, "seqNum");
  107. // 当前序号
  108. lua_pushinteger(L, sms->maxNum);
  109. lua_setfield(L, -2, "maxNum");
  110. // 时间信息
  111. lua_pushinteger(L, sms->time.year);
  112. lua_setfield(L, -2, "year");
  113. lua_pushinteger(L, sms->time.month);
  114. lua_setfield(L, -2, "mon");
  115. lua_pushinteger(L, sms->time.day);
  116. lua_setfield(L, -2, "day");
  117. lua_pushinteger(L, sms->time.hour);
  118. lua_setfield(L, -2, "hour");
  119. lua_pushinteger(L, sms->time.minute);
  120. lua_setfield(L, -2, "min");
  121. lua_pushinteger(L, sms->time.second);
  122. lua_setfield(L, -2, "sec");
  123. lua_pushinteger(L, sms->time.tz_sign == '+' ? sms->time.tz : - sms->time.tz);
  124. lua_setfield(L, -2, "tz");
  125. }
  126. static int l_sms_recv_handler(lua_State* L, void* ptr) {
  127. luat_sms_recv_msg_t* sms = ((luat_sms_recv_msg_t*)ptr);
  128. // char buff[280+2] = {0};
  129. size_t dstlen = strlen(sms->sms_buffer);
  130. char tmpbuff[140*3+2] = {0};
  131. char *dst = tmpbuff;
  132. LLOGD("dcs %d | %d | %d | %d", sms->dcs_info.alpha_bet, sms->dcs_info.dcs, sms->dcs_info.msg_class, sms->dcs_info.type);
  133. if (sms->dcs_info.alpha_bet == 0) {
  134. memcpy(dst, sms->sms_buffer, strlen(sms->sms_buffer));
  135. }
  136. else {
  137. luat_str_ucs2_to_char(sms->sms_buffer, strlen(sms->sms_buffer), dst, &dstlen);
  138. dst[dstlen] = 0;
  139. }
  140. if (sms->maxNum > 0 && lua_sms_recv_long) {
  141. int index = -1;
  142. for (size_t i = 0; i < LONG_SMS_CMAX; i++)
  143. {
  144. if (lngbuffs[i] == NULL) {
  145. index = i;
  146. break;
  147. }
  148. }
  149. if (index < 0) {
  150. LLOGE("too many long-sms!!");
  151. goto exit;
  152. }
  153. lngbuffs[index] = luat_heap_malloc(sizeof(long_sms_t) + dstlen);
  154. if (lngbuffs[index] == NULL) {
  155. LLOGE("out of memory when malloc long sms buff");
  156. goto exit;
  157. }
  158. lngbuffs[index]->maxNum = sms->maxNum;
  159. lngbuffs[index]->seqNum = sms->seqNum;
  160. lngbuffs[index]->refNum = sms->refNum;
  161. memcpy(lngbuffs[index]->buff, dst, dstlen);
  162. lngbuffs[index]->buff[dstlen] = 0x00;
  163. size_t counter = (sms->maxNum + 1) * sms->maxNum / 2;
  164. for (size_t i = 0; i < LONG_SMS_CMAX; i++)
  165. {
  166. if (lngbuffs[i] == NULL || lngbuffs[i]->refNum != sms->refNum) {
  167. continue;
  168. }
  169. counter -= lngbuffs[i]->seqNum;
  170. }
  171. if (counter != 0) {
  172. LLOGI("long-sms, wait more frags %d/%d", sms->seqNum, sms->maxNum);
  173. goto exit;
  174. }
  175. LLOGI("long-sms is ok");
  176. dst = NULL;
  177. dstlen = sms->refNum;
  178. }
  179. // 先发系统消息
  180. lua_getglobal(L, "sys_pub");
  181. if (lua_isnil(L, -1)) {
  182. luat_heap_free(sms);
  183. return 0;
  184. }
  185. /*
  186. @sys_pub sms
  187. 收到短信
  188. SMS_INC
  189. @string 手机号
  190. @string 短信内容,UTF8编码
  191. @usage
  192. --使用的例子,可多行
  193. -- 接收短信, 支持多种方式, 选一种就可以了
  194. -- 1. 设置回调函数
  195. --sms.setNewSmsCb( function(phone,sms)
  196. log.info("sms",phone,sms)
  197. end)
  198. -- 2. 订阅系统消息
  199. --sys.subscribe("SMS_INC", function(phone,sms)
  200. log.info("sms",phone,sms)
  201. end)
  202. */
  203. lua_pushliteral(L, "SMS_INC");
  204. push_sms_args(L, sms, dst, dstlen);
  205. lua_call(L, 4, 0);
  206. // 如果有回调函数, 就调用
  207. if (lua_sms_ref) {
  208. lua_geti(L, LUA_REGISTRYINDEX, lua_sms_ref);
  209. if (lua_isfunction(L, -1)) {
  210. push_sms_args(L, sms, dst, dstlen);
  211. lua_call(L, 3, 0);
  212. }
  213. }
  214. // 清理长短信的缓冲,如果有的话
  215. for (size_t i = 0; i < 16; i++)
  216. {
  217. if (lngbuffs[i] && lngbuffs[i]->refNum == sms->refNum) {
  218. luat_heap_free(lngbuffs[i]);
  219. lngbuffs[i] = NULL;
  220. }
  221. }
  222. exit:
  223. luat_heap_free(sms);
  224. return 0;
  225. }
  226. void luat_sms_recv_cb(uint32_t event, void *param)
  227. {
  228. luat_sms_recv_msg_t* sms = ((luat_sms_recv_msg_t*)param);
  229. rtos_msg_t msg = {0};
  230. if (event != 0) {
  231. return;
  232. }
  233. luat_sms_recv_msg_t* tmp = luat_heap_malloc(sizeof(luat_sms_recv_msg_t));
  234. if (tmp == NULL) {
  235. LLOGE("out of memory when malloc sms content");
  236. return;
  237. }
  238. memcpy(tmp, sms, sizeof(luat_sms_recv_msg_t));
  239. msg.handler = l_sms_recv_handler;
  240. msg.ptr = tmp;
  241. luat_msgbus_put(&msg, 0);
  242. }
  243. static void luat_sms_send_done(uint8_t is_success)
  244. {
  245. rtos_msg_t msg = {
  246. .handler = l_long_sms_send_callback,
  247. .arg1 = is_success,
  248. .arg2 = 0
  249. };
  250. luat_msgbus_put(&msg, 0);
  251. if (g_s_sms_send.payload != NULL) {
  252. luat_heap_free(g_s_sms_send.payload);
  253. g_s_sms_send.payload = NULL;
  254. }
  255. }
  256. void luat_sms_send_cb(int ret)
  257. {
  258. // 当前没有短信在发送,应该不会产生这个回调吧?
  259. if (!g_s_sms_pdu_packet.maxNum) {
  260. return;
  261. }
  262. // 发送失败
  263. if (ret) {
  264. luat_sms_send_done(0);
  265. return;
  266. }
  267. LLOGD("long sms callback seqNum = %d", g_s_sms_pdu_packet.seqNum);
  268. // 全部短信发送完成
  269. if (g_s_sms_pdu_packet.seqNum == g_s_sms_pdu_packet.maxNum) {
  270. luat_sms_send_done(1);
  271. return;
  272. }
  273. // 长短信继续发送
  274. g_s_sms_pdu_packet.seqNum++;
  275. uint8_t packet_len = g_s_sms_send.payload_len - (g_s_sms_pdu_packet.seqNum - 1) * LUAT_SMS_LONG_MSG_PDU_SIZE;
  276. uint32_t addr = g_s_sms_send.payload + (g_s_sms_pdu_packet.seqNum - 1) * LUAT_SMS_LONG_MSG_PDU_SIZE;
  277. // 最后一包
  278. if (packet_len <= LUAT_SMS_LONG_MSG_PDU_SIZE) {
  279. memcpy(g_s_sms_pdu_packet.payload_buf, (void *)addr, packet_len);
  280. g_s_sms_pdu_packet.payload_len = packet_len;
  281. } else {
  282. // 继续发送
  283. memcpy(g_s_sms_pdu_packet.payload_buf, (void *)addr, LUAT_SMS_LONG_MSG_PDU_SIZE);
  284. g_s_sms_pdu_packet.payload_len = LUAT_SMS_LONG_MSG_PDU_SIZE;
  285. }
  286. int len = luat_sms_pdu_packet(&g_s_sms_pdu_packet);
  287. ret = luat_sms_send_msg_v2(g_s_sms_pdu_packet.pdu_buf, len);
  288. // 发送失败
  289. if (ret) {
  290. luat_sms_send_done(0);
  291. }
  292. return;
  293. }
  294. /*
  295. 异步发送短信
  296. @api sms.send(phone, msg, auto_phone_fix)
  297. @string 电话号码,必填
  298. @string 短信内容,必填
  299. @bool 是否自动处理电话号号码的格式,默认是按短信内容和号码格式进行自动判断, 设置为false可禁用
  300. @return bool 成功返回true,否则返回false或nil
  301. @usgae
  302. -- 短信号码支持2种形式
  303. -- +XXYYYYYYY 其中XX代表国家代码, 中国是86, 推荐使用这种
  304. -- YYYYYYYYY 直接填目标号码, 例如10010, 10086, 或者国内的手机号码
  305. log.info("sms", sms.send("+8613416121234", "Hi, LuatOS - " .. os.date()))
  306. -- 直接使用目标号码, 不做任何自动化处理. 2023.09.21新增
  307. log.info("sms", sms.send("85513416121234", "Hi, LuatOS - " .. os.date()), false)
  308. */
  309. static int l_sms_send(lua_State *L) {
  310. size_t phone_len = 0;
  311. size_t payload_len = 0;
  312. const char* phone = luaL_checklstring(L, 1, &phone_len);
  313. const char* payload = luaL_checklstring(L, 2, &payload_len);
  314. int auto_phone = 1;
  315. if (lua_isboolean(L, 3) && !lua_toboolean(L, 3)) {
  316. auto_phone = 0;
  317. }
  318. int ret = 0;
  319. // 当前有其他地方在发送短信
  320. if (g_s_sms_pdu_packet.maxNum) {
  321. LLOGE("sms is busy");
  322. return 0;
  323. }
  324. if (payload_len == 0) {
  325. LLOGE("sms is empty");
  326. return 0;
  327. }
  328. if (phone_len < 3 || phone_len > 29) {
  329. LLOGE("phone is too short or too long!! %d", phone_len);
  330. return 0;
  331. }
  332. size_t outlen = 0;
  333. uint8_t *ucs2_buf = NULL;
  334. ucs2_buf = (uint8_t *)luat_heap_malloc(payload_len * 3);
  335. if (ucs2_buf == NULL)
  336. {
  337. LLOGE("out of memory");
  338. return 0;
  339. }
  340. memset(ucs2_buf, 0x00, payload_len * 3);
  341. ret = luat_str_utf8_to_ucs2(payload, payload_len, ucs2_buf, payload_len * 3, &outlen);
  342. if (ret) {
  343. LLOGE("utf82ucs2 encode fail");
  344. goto SMS_FAIL;
  345. }
  346. memset(&g_s_sms_send, 0x00, sizeof(long_sms_send_t));
  347. memset(&g_s_sms_pdu_packet, 0x00, sizeof(luat_sms_pdu_packet_t));
  348. // 短短信
  349. if (outlen <= LUAT_SMS_SHORT_MSG_PDU_SIZE) {
  350. g_s_sms_pdu_packet.maxNum = 1;
  351. memcpy(g_s_sms_pdu_packet.payload_buf, ucs2_buf , outlen);
  352. g_s_sms_pdu_packet.payload_len = outlen;
  353. } else {
  354. // 长短信
  355. ref_idx = (ref_idx + 1) % 255;
  356. g_s_sms_pdu_packet.maxNum = (outlen + LUAT_SMS_LONG_MSG_PDU_SIZE - 1) / LUAT_SMS_LONG_MSG_PDU_SIZE;
  357. g_s_sms_pdu_packet.refNum = ref_idx;
  358. memcpy(g_s_sms_pdu_packet.payload_buf, ucs2_buf , LUAT_SMS_LONG_MSG_PDU_SIZE);
  359. g_s_sms_pdu_packet.payload_len = LUAT_SMS_LONG_MSG_PDU_SIZE;
  360. }
  361. g_s_sms_pdu_packet.auto_phone = auto_phone;
  362. g_s_sms_pdu_packet.phone_len = phone_len;
  363. g_s_sms_pdu_packet.phone = phone;
  364. g_s_sms_pdu_packet.seqNum = 1;
  365. g_s_sms_send.payload = ucs2_buf;
  366. g_s_sms_send.payload_len = outlen;
  367. int len = luat_sms_pdu_packet(&g_s_sms_pdu_packet);
  368. LLOGD("pdu len %d", len);
  369. ret = luat_sms_send_msg_v2(g_s_sms_pdu_packet.pdu_buf, len);
  370. if (!ret) {
  371. lua_pushboolean(L, ret == 0);
  372. return 1;
  373. }
  374. SMS_FAIL:
  375. g_s_sms_pdu_packet.maxNum = 0;
  376. g_s_sms_send.payload = NULL;
  377. if(ucs2_buf != NULL) {
  378. luat_heap_free(ucs2_buf);
  379. }
  380. lua_pushboolean(L, ret == 0);
  381. return 1;
  382. }
  383. /*
  384. 同步发送短信
  385. @api sms.sendLong(phone, msg, auto_phone_fix).wait()
  386. @string 电话号码,必填
  387. @string 短信内容,必填
  388. @bool 是否自动处理电话号号码的格式,默认是按短信内容和号码格式进行自动判断, 设置为false可禁用
  389. @return bool 异步等待结果 成功返回true, 否则返回false或nil
  390. @usgae
  391. sys.taskInit(function()
  392. local str = string.rep("1234567890", 50)
  393. sys.waitUntil("IP_READY")
  394. -- 发送500bytes的短信
  395. sms.sendLong("+8613416121234", str).wait()
  396. end)
  397. */
  398. static int l_long_sms_send(lua_State *L) {
  399. size_t phone_len = 0;
  400. size_t payload_len = 0;
  401. uint8_t *ucs2_buf = NULL;
  402. const char* phone = luaL_checklstring(L, 1, &phone_len);
  403. const char* payload = luaL_checklstring(L, 2, &payload_len);
  404. int auto_phone = 1;
  405. if (lua_isboolean(L, 3) && !lua_toboolean(L, 3)) {
  406. auto_phone = 0;
  407. }
  408. // 当前有其他地方在发送短信
  409. if (g_s_sms_pdu_packet.maxNum) {
  410. LLOGE("sms is busy");
  411. lua_pushboolean(L, 0);
  412. luat_pushcwait_error(L,1);
  413. return 1;
  414. }
  415. // 当前有其他地方在用sms.sendLong发送短信
  416. if (long_sms_send_idp) {
  417. lua_pushboolean(L, 0);
  418. luat_pushcwait_error(L,1);
  419. return 1;
  420. }
  421. if (payload_len == 0) {
  422. LLOGE("sms is empty");
  423. goto SMS_FAIL;
  424. }
  425. if (phone_len < 3 || phone_len > 29) {
  426. LLOGE("phone is too short or too long!! %d", phone_len);
  427. goto SMS_FAIL;
  428. }
  429. size_t outlen = 0;
  430. ucs2_buf = (uint8_t *)luat_heap_malloc(payload_len * 3);
  431. if (ucs2_buf == NULL)
  432. {
  433. LLOGE("out of memory");
  434. goto SMS_FAIL;
  435. }
  436. memset(ucs2_buf, 0x00, payload_len * 3);
  437. int ret = luat_str_utf8_to_ucs2(payload, payload_len, ucs2_buf, payload_len * 3, &outlen);
  438. if (ret) {
  439. LLOGE("utf8 to ucs2 fail ret");
  440. goto SMS_FAIL;
  441. }
  442. memset(&g_s_sms_send, 0x00, sizeof(long_sms_send_t));
  443. memset(&g_s_sms_pdu_packet, 0x00, sizeof(luat_sms_pdu_packet_t));
  444. // 短短信
  445. if (outlen <= LUAT_SMS_SHORT_MSG_PDU_SIZE) {
  446. g_s_sms_pdu_packet.maxNum = 1;
  447. memcpy(g_s_sms_pdu_packet.payload_buf, ucs2_buf , outlen);
  448. g_s_sms_pdu_packet.payload_len = outlen;
  449. } else {
  450. // 长短信
  451. ref_idx = (ref_idx + 1) % 255;
  452. g_s_sms_pdu_packet.maxNum = (outlen + LUAT_SMS_LONG_MSG_PDU_SIZE - 1) / LUAT_SMS_LONG_MSG_PDU_SIZE;
  453. g_s_sms_pdu_packet.refNum = ref_idx;
  454. memcpy(g_s_sms_pdu_packet.payload_buf, ucs2_buf , LUAT_SMS_LONG_MSG_PDU_SIZE);
  455. g_s_sms_pdu_packet.payload_len = LUAT_SMS_LONG_MSG_PDU_SIZE;
  456. }
  457. long_sms_send_idp = luat_pushcwait(L);
  458. g_s_sms_pdu_packet.auto_phone = auto_phone;
  459. g_s_sms_pdu_packet.phone_len = phone_len;
  460. g_s_sms_pdu_packet.phone = phone;
  461. g_s_sms_pdu_packet.seqNum = 1;
  462. g_s_sms_send.payload = ucs2_buf;
  463. g_s_sms_send.payload_len = outlen;
  464. char buf[400] = {0};
  465. char tmp[3] = {0};
  466. int len = luat_sms_pdu_packet(&g_s_sms_pdu_packet);
  467. LLOGE("pdu len %d", len);
  468. for (int i = 0; i < len; i++)
  469. {
  470. sprintf(tmp, "%02X", g_s_sms_pdu_packet.pdu_buf[i]);
  471. strcat(buf, tmp);
  472. }
  473. LLOGE("pdu buf %s", buf);
  474. ret = luat_sms_send_msg_v2(g_s_sms_pdu_packet.pdu_buf, len);
  475. if (!ret) {
  476. return 1;
  477. }
  478. SMS_FAIL:
  479. long_sms_send_idp = 0;
  480. g_s_sms_pdu_packet.maxNum = 0;
  481. g_s_sms_send.payload = NULL;
  482. if(ucs2_buf != NULL) {
  483. luat_heap_free(ucs2_buf);
  484. }
  485. lua_pushboolean(L, 0);
  486. luat_pushcwait_error(L, 1);
  487. return 1;
  488. }
  489. /**
  490. 设置新SMS的回调函数
  491. @api sms.setNewSmsCb(func)
  492. @function 回调函数, 3个参数, num, txt, metas
  493. @return nil 传入是函数就能成功,无返回值
  494. @usage
  495. sms.setNewSmsCb(function(num, txt, metas)
  496. -- num 手机号码
  497. -- txt 文本内容
  498. -- metas 短信的元数据,例如发送的时间,长短信编号
  499. -- 注意, 长短信会自动合并成一条txt
  500. log.info("sms", num, txt, metas and json.encode(metas) or "")
  501. end)
  502. */
  503. static int l_sms_cb(lua_State *L) {
  504. if (lua_sms_ref) {
  505. luaL_unref(L, LUA_REGISTRYINDEX, lua_sms_ref);
  506. lua_sms_ref = 0;
  507. }
  508. if (lua_isfunction(L, 1)) {
  509. lua_sms_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  510. }
  511. return 0;
  512. }
  513. /**
  514. 设置长短信的自动合并功能
  515. @api sms.autoLong(mode)
  516. @bool 是否自动合并,true为自动合并,为默认值
  517. @return bool 设置后的值
  518. @usage
  519. -- 禁用长短信的自动合并, 一般不需要禁用
  520. sms.autoLong(false)
  521. */
  522. static int l_sms_auto_long(lua_State *L) {
  523. if (lua_isboolean(L, 1)) {
  524. lua_sms_recv_long = lua_toboolean(L, 1);
  525. }
  526. else if (lua_isinteger(L, 1))
  527. {
  528. lua_sms_recv_long = lua_toboolean(L, 1);
  529. }
  530. lua_pushboolean(L, lua_sms_recv_long == 0 ? 0 : 1);
  531. return 1;
  532. }
  533. /**
  534. 清除长短信缓存
  535. @api sms.clearLong()
  536. @return int 清理掉的片段数量
  537. @usage
  538. sms.clearLong()
  539. */
  540. static int l_sms_clear_long(lua_State *L) {
  541. int counter = 0;
  542. for (size_t i = 0; i < LONG_SMS_CMAX; i++)
  543. {
  544. if (lngbuffs[i]) {
  545. counter ++;
  546. luat_heap_free(lngbuffs[i]);
  547. lngbuffs[i] = NULL;
  548. }
  549. }
  550. lua_pushinteger(L, counter);
  551. return 1;
  552. }
  553. #include "rotable2.h"
  554. static const rotable_Reg_t reg_sms[] =
  555. {
  556. { "send", ROREG_FUNC(l_sms_send)},
  557. { "setNewSmsCb", ROREG_FUNC(l_sms_cb)},
  558. { "autoLong", ROREG_FUNC(l_sms_auto_long)},
  559. { "clearLong", ROREG_FUNC(l_sms_clear_long)},
  560. { "sendLong", ROREG_FUNC(l_long_sms_send)},
  561. { NULL, ROREG_INT(0)}
  562. };
  563. LUAMOD_API int luaopen_sms( lua_State *L ) {
  564. luat_newlib2(L, reg_sms);
  565. return 1;
  566. }