luat_lib_sms.c 18 KB

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