luat_lib_mobile.c 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324
  1. /*
  2. @module mobile
  3. @summary 蜂窝网络
  4. @version 1.0
  5. @date 2022.8.9
  6. @demo mobile
  7. @tag LUAT_USE_MOBILE
  8. @usage
  9. -- 简单演示
  10. log.info("imei", mobile.imei())
  11. log.info("imsi", mobile.imsi())
  12. local sn = mobile.sn()
  13. if sn then
  14. log.info("sn", sn:toHex())
  15. end
  16. log.info("muid", mobile.muid())
  17. log.info("iccid", mobile.iccid())
  18. log.info("csq", mobile.csq())
  19. log.info("rssi", mobile.rssi())
  20. log.info("rsrq", mobile.rsrq())
  21. log.info("rsrp", mobile.rsrp())
  22. log.info("snr", mobile.snr())
  23. log.info("simid", mobile.simid())
  24. */
  25. #include "luat_base.h"
  26. #include "luat_mem.h"
  27. #include "luat_rtos.h"
  28. #include "luat_msgbus.h"
  29. #include "luat_mobile.h"
  30. #include "luat_network_adapter.h"
  31. #define LUAT_LOG_TAG "mobile"
  32. #include "luat_log.h"
  33. extern void luat_cc_start_speech(uint32_t param);
  34. extern void luat_cc_play_tone(uint32_t param);
  35. /**
  36. 获取IMEI
  37. @api mobile.imei(index)
  38. @int 编号,默认0. 在支持双卡的模块上才会出现0或1的情况
  39. @return string 当前的IMEI值,若失败返回nil
  40. @usgae
  41. -- 注意, 当前所有模块只支持单待,所以IMEI总是同一个
  42. */
  43. static int l_mobile_imei(lua_State* L) {
  44. char buff[24] = {0};
  45. // size_t len = 0;
  46. // size_t wlen = 0;
  47. int ret = 0;
  48. int index = luaL_optinteger(L, 1, 0);
  49. ret = luat_mobile_get_imei(index, buff, 24);
  50. // if (lua_isstring(L, 2)) {
  51. // const char* wbuff = luaL_checklstring(L, 2, &wlen);
  52. // if (wlen >= 15) {
  53. // ret = luat_mobile_set_imei(index, wbuff, wlen);
  54. // LLOGI("IMEI write %d %s ret %d", index, wbuff, ret);
  55. // }
  56. // }
  57. if (ret > 0) {
  58. buff[23] = 0x00; // 确保能结束
  59. lua_pushlstring(L, buff, strlen(buff));
  60. }
  61. else
  62. lua_pushnil(L);
  63. return 1;
  64. }
  65. /**
  66. 获取IMSI
  67. @api mobile.imsi(index)
  68. @int 编号,默认0. 在支持双卡的模块上才会出现0或1的情况
  69. @return string 当前的IMSI值,若失败返回nil
  70. @usgae
  71. -- 注意, 当前所有模块只支持单待,所以IMSI总是同一个
  72. */
  73. static int l_mobile_imsi(lua_State* L) {
  74. char buff[24] = {0};
  75. // size_t len = 0;
  76. // size_t wlen = 0;
  77. int ret = 0;
  78. int index = luaL_optinteger(L, 1, 0);
  79. ret = luat_mobile_get_imsi(index, buff, 24);
  80. // if (lua_isstring(L, 2)) {
  81. // const char* wbuff = luaL_checklstring(L, 2, &wlen);
  82. // if (wlen >= 1) {
  83. // ret = luat_mobile_set_imsi(index, wbuff, wlen);
  84. // LLOGI("IMSI write %d %s ret %d", index, wbuff, ret);
  85. // }
  86. // }
  87. if (ret > 0){
  88. buff[23] = 0x00; // 确保能结束
  89. lua_pushlstring(L, buff, strlen(buff));
  90. }
  91. else
  92. lua_pushnil(L);
  93. return 1;
  94. }
  95. /**
  96. 获取SN
  97. @api mobile.sn()
  98. @return string 当前的SN值,若失败返回nil. 注意, SN可能包含不可见字符
  99. @usage
  100. -- 注意, 出厂未必有写SN
  101. -- 一般用途的唯一id, 可以用mobile.imei()代替
  102. -- 如需要真正的唯一ID, 使用 mcu.unique_id()
  103. */
  104. static int l_mobile_sn(lua_State* L) {
  105. char buff[32] = {0};
  106. // size_t len = 0;
  107. // size_t wlen = 0;
  108. int ret = 0;
  109. ret = luat_mobile_get_sn(buff, 32);
  110. // if (lua_isstring(L, 1)) {
  111. // const char* wbuff = luaL_checklstring(L, 1, &wlen);
  112. // if (wlen >= 1) {
  113. // ret = luat_mobile_set_sn(wbuff, wlen);
  114. // LLOGI("SN write %d %s ret %d", index, wbuff, ret);
  115. // }
  116. // }
  117. if (ret > 0) {
  118. //buff[63] = 0x00; // 确保能结束
  119. lua_pushlstring(L, buff, ret);
  120. }
  121. else
  122. lua_pushnil(L);
  123. return 1;
  124. }
  125. /**
  126. 获取MUID
  127. @api mobile.muid()
  128. @return string 当前的MUID值,若失败返回nil
  129. */
  130. static int l_mobile_muid(lua_State* L) {
  131. char buff[33] = {0};
  132. // size_t len = 0;
  133. // size_t wlen = 0;
  134. int ret = 0;
  135. ret = luat_mobile_get_muid(buff, 32);
  136. if (lua_isstring(L, 1)) {
  137. // const char* wbuff = luaL_checklstring(L, 1, &wlen);
  138. // if (wlen >= 15) {
  139. // ret = luat_mobile_set_muid(index, wbuff, wlen);
  140. // LLOGI("SN write %d %s ret %d", index, wbuff, ret);
  141. // }
  142. }
  143. if (ret > 0) {
  144. lua_pushlstring(L, buff, strlen(buff));
  145. }
  146. else
  147. lua_pushnil(L);
  148. return 1;
  149. }
  150. /**
  151. 获取或设置ICCID
  152. @api mobile.iccid(id)
  153. @int SIM卡的编号, 例如0, 1, 默认0
  154. @return string ICCID值,若失败返回nil
  155. */
  156. static int l_mobile_iccid(lua_State* L) {
  157. char buff[24] = {0};
  158. // size_t len = 0;
  159. // size_t wlen = 0;
  160. int ret = 0;
  161. int index = luaL_optinteger(L, 1, 0);
  162. ret = luat_mobile_get_iccid(index, buff, 24);
  163. if (ret > 0) {
  164. buff[23] = 0x00; // 确保能结束
  165. lua_pushlstring(L, buff, strlen(buff));
  166. }
  167. else
  168. lua_pushnil(L);
  169. return 1;
  170. }
  171. /**
  172. 获取手机卡号,注意,只有写入了手机号才能读出,因此有可能读出来是空的
  173. @api mobile.number(id)
  174. @int SIM卡的编号, 例如0, 1, 默认0
  175. @return string number值,若失败返回nil
  176. */
  177. static int l_mobile_number(lua_State* L) {
  178. char buff[24] = {0};
  179. // size_t len = 0;
  180. // size_t wlen = 0;
  181. int ret = 0;
  182. int index = luaL_optinteger(L, 1, 0);
  183. ret = luat_mobile_get_sim_number(index, buff, 24);
  184. if (ret > 0) {
  185. buff[23] = 0x00; // 确保能结束
  186. lua_pushlstring(L, buff, strlen(buff));
  187. }
  188. else
  189. lua_pushnil(L);
  190. return 1;
  191. }
  192. /**
  193. 获取当前SIM卡槽,或者切换卡槽
  194. @api mobile.simid(id)
  195. @int SIM卡的编号, 例如0, 1, 如果支持双卡,比如EC618,可以填2来自适应,但是会占用掉4个IO(gpio4/5/6/23)。如果不填就直接读取当前卡槽
  196. @boolean 是否优先用SIM0,只有SIM卡编号写2自适应才有用!!!。true优先用SIM0,false则由具体平台决定,支持双卡双待SIM0优先,不支持的是上一次检测到的优先,默认是false,必须在开机就配置,否则就无效了
  197. @return int 当前sim卡槽编号,若失败返回-1
  198. @usage
  199. mobile.simid(0) -- 固定使用SIM0
  200. mobile.simid(1) -- 固件使用SIM1
  201. mobile.simid(2) -- 自动识别SIM0, SIM1, 优先级看具体平台
  202. mobile.simid(2, true) -- -- 自动识别SIM0, SIM1, 且SIM0优先
  203. -- 提醒, 自动识别是会增加时间的
  204. */
  205. static int l_mobile_simid(lua_State* L) {
  206. // char buff[24] = {0};
  207. int ret = 0;
  208. int id = 0;
  209. if (lua_isinteger(L, 1)) {
  210. ret = luat_mobile_set_sim_id(lua_tointeger(L, 1));
  211. LLOGI("sim set to %d , ret %d", lua_tointeger(L, 1), ret);
  212. }
  213. if (LUA_TBOOLEAN == lua_type(L, 2)) {
  214. if (lua_toboolean(L, 2)) {
  215. luat_mobile_set_sim_detect_sim0_first();
  216. }
  217. }
  218. ret = luat_mobile_get_sim_id(&id);
  219. if (ret == 0) {
  220. lua_pushinteger(L, id);
  221. }
  222. else {
  223. lua_pushinteger(L, -1);
  224. }
  225. return 1;
  226. }
  227. /**
  228. 检测当前SIM卡是否准备好,对SIM卡的PIN码做相关操作
  229. @api mobile.simPin(id,operation,pin1,pin2)
  230. @int SIM卡的编号, 例如0, 1, 支持双卡双待的才需要选择
  231. @int PIN码操作类型,只能是mobile.PIN_XXXX,不操作就留空
  232. @string 更换pin时操作的pin码,或者验证操作的pin码,或者解锁pin码时的PUK,4~8字节
  233. @string 更换pin码操作时的新的pin码,解锁pin码时的新PIN,4~8字节
  234. @return boolean 当无PIN操作时,返回SIM卡是否准备好,有PIN操作时,返回是否成功
  235. @usage
  236. local cpin_is_ready = mobile.simPin() -- 当前sim卡是否准备好,一般返回false就是没卡
  237. local succ = mobile.simPin(0, mobile.PIN_VERIFY, "1234") -- 输入pin码验证
  238. */
  239. static int l_mobile_sim_pin(lua_State* L) {
  240. char old[9] = {0};
  241. char new[9] = {0};
  242. int id = luaL_optinteger(L, 1, 0);
  243. int operation = luaL_optinteger(L, 2, -1);
  244. size_t old_len, new_len;
  245. if (lua_isstring(L, 3))
  246. {
  247. const char *old_pin = lua_tolstring(L, 3, &old_len);
  248. memcpy(old, old_pin, (old_len > 8)?8:old_len);
  249. }
  250. if (lua_isstring(L, 4))
  251. {
  252. const char *new_pin = lua_tolstring(L, 4, &new_len);
  253. memcpy(new, new_pin, (new_len > 8)?8:new_len);
  254. }
  255. if (operation != -1)
  256. {
  257. lua_pushboolean(L, (luat_mobile_set_sim_pin(id, operation, old, new) == 0));
  258. }
  259. else
  260. {
  261. lua_pushboolean(L, (luat_mobile_get_sim_ready(id) == 1));
  262. }
  263. return 1;
  264. }
  265. /**
  266. 设置RRC自动释放时间间隔,当开启时后,遇到极弱信号+频繁数据操作可能会引起网络严重故障,因此需要额外设置自动重启协议栈
  267. @api mobile.rtime(time, auto_reset_stack)
  268. @int RRC自动释放时间,等同于Air724的AT+RTIME,单位秒,写0或者不写则是停用,不要超过20秒,没有意义
  269. @boolean 网络遇到严重故障时尝试自动恢复,和飞行模式/SIM卡切换冲突,true开启,false关闭,留空时,如果设置了时间则自动开启。原厂优化过协议栈后不需要了。本参数废弃
  270. @return nil 无返回值
  271. */
  272. static int l_mobile_set_rrc_auto_release_time(lua_State* L) {
  273. luat_mobile_set_rrc_auto_release_time(luaL_optinteger(L, 1, 0));
  274. // if (LUA_TBOOLEAN == lua_type(L, 2)) {
  275. // luat_mobile_fatal_error_auto_reset_stack(lua_toboolean(L, 2));
  276. // }
  277. // else
  278. // {
  279. // if (luaL_optinteger(L, 1, 0))
  280. // {
  281. // luat_mobile_fatal_error_auto_reset_stack(1);
  282. // }
  283. // }
  284. return 0;
  285. }
  286. /**
  287. 设置一些辅助周期性或者自动功能,目前支持SIM卡暂时脱离后恢复,周期性获取小区信息,网络遇到严重故障时尝试自动恢复
  288. @api mobile.setAuto(check_sim_period, get_cell_period, search_cell_time, auto_reset_stack, network_check_period)
  289. @int SIM卡自动恢复时间,单位毫秒,建议5000~10000,和飞行模式/SIM卡切换冲突,不能再同一时间使用,必须错开执行。写0或者不写则是关闭功能
  290. @int 周期性获取小区信息的时间间隔,单位毫秒。获取小区信息会增加部分功耗。写0或者不写则是关闭功能
  291. @int 每次搜索小区时最大搜索时间,单位秒。不要超过8秒
  292. @boolean 网络遇到严重故障时尝试自动恢复,和飞行模式/SIM卡切换冲突,true开启,false关闭,开始状态是false,留空则不做改变
  293. @int 设置定时检测网络是否正常并且在检测到长时间无网时通过重启协议栈来恢复,无网恢复时长,单位ms,建议60000以上,为网络搜索网络保留足够的时间,留空则不做更改
  294. @return nil 无返回值
  295. */
  296. static int l_mobile_set_auto_work(lua_State* L) {
  297. luat_mobile_set_period_work(luaL_optinteger(L, 2, 0), luaL_optinteger(L, 1, 0), luaL_optinteger(L, 3, 0));
  298. if (LUA_TBOOLEAN == lua_type(L, 4)) {
  299. luat_mobile_fatal_error_auto_reset_stack(lua_toboolean(L, 4));
  300. }
  301. if (lua_isinteger(L, 5)) {
  302. luat_mobile_set_check_network_period(luaL_optinteger(L, 5, 0));
  303. }
  304. return 0;
  305. }
  306. /**
  307. 获取或设置APN,设置APN必须在入网前就设置好,比如在SIM卡识别完成前就设置好
  308. @api mobile.apn(index, cid, new_apn_name, user_name, password, ip_type, protocol)
  309. @int 编号,默认0. 在支持双卡的模块上才会出现0或1的情况
  310. @int cid, 默认0,如果要用非默认APN来激活,必须>0
  311. @string 新的APN,不填就是获取APN, 填了就是设置APN, 是否支持设置取决于底层实现
  312. @string 新的APN的username,如果APN不是空,那必须填写,如果没有留个空字符串""。如果APN是空的,那可以nil
  313. @string 新的APN的password,如果APN不是空,那必须填写,如果没有留个空字符串""。如果APN是空的,那可以nil
  314. @int 激活APN时的IP TYPE,1=IPV4 2=IPV6 3=IPV4V6,默认是1
  315. @int 激活APN时,如果需要username和password,就要写鉴权协议类型,1~3,默认3,代表1和2都尝试一下。不需要鉴权的写0
  316. @boolean 是否删除APN,true是,其他都否,只有参数3新的APN不是string的时候才有效果
  317. @return string 获取到的默认APN值,失败返回nil
  318. @usage
  319. mobile.apn(0,1,"cmiot","","",nil,0) -- 移动公网卡设置APN为cmiot,一般不用设置
  320. mobile.apn(0,1,"name","user","password",nil,3) -- 专网卡设置的demo,name,user,password联系卡商获取
  321. */
  322. static int l_mobile_apn(lua_State* L) {
  323. char buff[64] = {0};
  324. size_t len = 0;
  325. size_t wlen = 0;
  326. int ret = 0;
  327. int index = luaL_optinteger(L, 1, 0);
  328. int cid = luaL_optinteger(L, 2, 0);
  329. ret = luat_mobile_get_apn(index, cid, buff, sizeof(buff) - 1);
  330. if (lua_isstring(L, 3)) {
  331. const char* wbuff = luaL_checklstring(L, 3, &wlen);
  332. size_t user_name_len = 0;
  333. size_t password_len = 0;
  334. const char* user_name = luaL_checklstring(L, 4, &user_name_len);
  335. const char* password = luaL_checklstring(L, 5, &password_len);
  336. uint8_t ip_type = luaL_optinteger(L, 6, 1);
  337. uint8_t protocol = luaL_optinteger(L, 7, 3);
  338. if (!user_name_len && !password_len)
  339. {
  340. protocol = 0;
  341. }
  342. if (wlen) {
  343. luat_mobile_user_apn_auto_active(index, cid, ip_type, protocol, wbuff, wlen, user_name, user_name_len, password, password_len);
  344. }
  345. else
  346. {
  347. luat_mobile_user_apn_auto_active(index, cid, ip_type, 0xff, NULL, 0, NULL, 0, NULL, 0);
  348. }
  349. }
  350. else
  351. {
  352. if (lua_isboolean(L, 8) && lua_toboolean(L, 8))
  353. {
  354. luat_mobile_del_apn(index, cid, 0);
  355. }
  356. }
  357. if (ret > 0) {
  358. lua_pushlstring(L, buff, strlen(buff));
  359. }
  360. else
  361. lua_pushnil(L);
  362. return 1;
  363. }
  364. /**
  365. 是否默认开启IPV6功能,必须在LTE网络连接前就设置好
  366. @api mobile.ipv6(onff)
  367. @boolean 开关 true开启 false 关闭
  368. @return boolean true 当前是开启的,false 当前是关闭的
  369. @usage
  370. -- 注意, 开启ipv6后, 开机联网会慢2~3秒
  371. */
  372. static int l_mobile_ipv6(lua_State* L) {
  373. // char buff[24] = {0};
  374. // uint8_t onoff;
  375. if (LUA_TBOOLEAN == lua_type(L, 1)) {
  376. luat_mobile_set_default_pdn_ipv6(lua_toboolean(L, 1));
  377. }
  378. lua_pushboolean(L, luat_mobile_get_default_pdn_ipv6());
  379. return 1;
  380. }
  381. /**
  382. 获取csq
  383. @api mobile.csq()
  384. @return int 当前CSQ值, 若失败返回0. 范围 0 - 31, 越大越好
  385. @usage
  386. -- 注意, 4G模块的CSQ值仅供参考, rsrp/rsrq才是真正的信号强度指标
  387. */
  388. static int l_mobile_csq(lua_State* L) {
  389. // luat_mobile_signal_strength_info_t info = {0};
  390. uint8_t csq = 0;
  391. if (luat_mobile_get_signal_strength(&csq) == 0) {
  392. lua_pushinteger(L, (int)csq);
  393. }
  394. else {
  395. lua_pushinteger(L, 0);
  396. }
  397. return 1;
  398. }
  399. /**
  400. 获取rssi
  401. @api mobile.rssi()
  402. @return int 当前rssi值,若失败返回0. 范围 0 到 -114, 越小越好
  403. */
  404. static int l_mobile_rssi(lua_State* L) {
  405. luat_mobile_signal_strength_info_t info = {0};
  406. if (luat_mobile_get_signal_strength_info(&info) == 0) {
  407. lua_pushinteger(L, info.lte_signal_strength.rssi);
  408. }
  409. else {
  410. lua_pushinteger(L, 0);
  411. }
  412. return 1;
  413. }
  414. /**
  415. 获取rsrp,参考信号接收功率
  416. @api mobile.rsrp()
  417. @return int 当前rsrp值,若失败返回0. 取值范围: -44 ~ -140 ,值越大越好
  418. */
  419. static int l_mobile_rsrp(lua_State* L) {
  420. luat_mobile_signal_strength_info_t info = {0};
  421. if (luat_mobile_get_signal_strength_info(&info) == 0) {
  422. lua_pushinteger(L, info.lte_signal_strength.rsrp);
  423. }
  424. else {
  425. lua_pushinteger(L, 0);
  426. }
  427. return 1;
  428. }
  429. /**
  430. 获取rsrq,参考信号发送功率
  431. @api mobile.rsrq()
  432. @return int 当前rsrq值,若失败返回0. 取值范围: -3 ~ -19.5 ,值越大越好
  433. */
  434. static int l_mobile_rsrq(lua_State* L) {
  435. luat_mobile_signal_strength_info_t info = {0};
  436. if (luat_mobile_get_signal_strength_info(&info) == 0) {
  437. lua_pushinteger(L, info.lte_signal_strength.rsrq);
  438. }
  439. else {
  440. lua_pushinteger(L, 0);
  441. }
  442. return 1;
  443. }
  444. /**
  445. 获取snr,信噪比
  446. @api mobile.snr()
  447. @return int 当前snq值,若失败返回0.范围 0 - 30, 越大越好
  448. */
  449. static int l_mobile_snr(lua_State* L) {
  450. luat_mobile_signal_strength_info_t info = {0};
  451. if (luat_mobile_get_signal_strength_info(&info) == 0) {
  452. lua_pushinteger(L, info.lte_signal_strength.snr);
  453. }
  454. else {
  455. lua_pushinteger(L, 0);
  456. }
  457. return 1;
  458. }
  459. /**
  460. 获取当前服务小区的ECI(E-UTRAN Cell Identifier)
  461. @api mobile.eci()
  462. @return int 当前eci值,若失败返回-1
  463. */
  464. static int l_mobile_eci(lua_State* L) {
  465. uint32_t eci;
  466. if (luat_mobile_get_service_cell_identifier(&eci) == 0) {
  467. lua_pushinteger(L, eci);
  468. }
  469. else {
  470. lua_pushinteger(L, -1);
  471. }
  472. return 1;
  473. }
  474. /**
  475. 获取当前服务小区的TAC或者LAC
  476. @api mobile.tac()
  477. @return int 当前eci值,若失败返回-1. 如果尚未注册到网络,会返回0
  478. @usage
  479. -- 本API于 2023.7.9 新增
  480. */
  481. static int l_mobile_tac(lua_State* L) {
  482. uint32_t tac;
  483. if (luat_mobile_get_service_tac_or_lac(&tac) == 0) {
  484. lua_pushinteger(L, tac);
  485. }
  486. else {
  487. lua_pushinteger(L, -1);
  488. }
  489. return 1;
  490. }
  491. /**
  492. 获取当前服务小区的eNBID(eNodeB Identifier)
  493. @api mobile.enbid()
  494. @return int 当前enbid值,若失败返回-1
  495. */
  496. static int l_mobile_enbid(lua_State* L) {
  497. uint32_t eci;
  498. if (luat_mobile_get_service_cell_identifier(&eci) == 0) {
  499. lua_pushinteger(L, eci>>8);
  500. }
  501. else {
  502. lua_pushinteger(L, -1);
  503. }
  504. return 1;
  505. }
  506. /**
  507. 进出飞行模式
  508. @api mobile.flymode(index, enable)
  509. @int 编号,默认0. 在支持双卡的模块上才会出现0或1的情况
  510. @bool 是否设置为飞行模式,true为设置, false为退出,可选
  511. @return bool 原飞行模式的状态
  512. */
  513. static int l_mobile_flymode(lua_State* L) {
  514. int index = luaL_optinteger(L, 1, 0);
  515. int flymode = luat_mobile_get_flymode(index);
  516. if (lua_isboolean(L, 2)) {
  517. luat_mobile_set_flymode(index, lua_toboolean(L, 2));
  518. }
  519. lua_pushboolean(L, flymode == 0 ? 0 : 1);
  520. return 1;
  521. }
  522. /**
  523. 获取网络状态
  524. @api mobile.status()
  525. @return int 当前网络状态,0:网络未注册;1:网络已注册;2:正在搜网中;3:网络注册被拒绝
  526. */
  527. static int l_mobile_status(lua_State* L) {
  528. int LUAT_MOBILE_REGISTER_STATUS_E = luat_mobile_get_register_status();
  529. lua_pushinteger(L, LUAT_MOBILE_REGISTER_STATUS_E);
  530. return 1;
  531. }
  532. static inline uint16_t u162bcd(uint16_t src) {
  533. uint8_t high = (src >> 8) & 0xFF;
  534. uint8_t low = src & 0xFF;
  535. uint16_t dst = 0;
  536. dst += (low & 0x0F) + (low >> 4) * 10;
  537. dst += ((high & 0x0F) + (high >> 4) * 10) * 100;
  538. //LLOGD("src %04X dst %d", src, dst);
  539. return dst;
  540. }
  541. /**
  542. 获取机制信息
  543. @api mobile.getCellInfo()
  544. @return table 包含基站数据的数组
  545. @usage
  546. -- 注意: 从2023.06.20开始, 需要主动请求一次reqCellInfo才会有基站数据.
  547. --示例输出
  548. --[[
  549. [
  550. {"rsrq":-10,"rssi":-55,"cid":124045360,"mnc":17,"pci":115,"earfcn":1850,"snr":15,"rsrp":-85,"mcc":1120,"tdd":0},
  551. {"pci":388,"rsrq":-11,"mnc":17,"earfcn":2452,"snr":5,"rsrp":-67,"mcc":1120,"cid":124045331},
  552. {"pci":100,"rsrq":-9,"mnc":17,"earfcn":75,"snr":17,"rsrp":-109,"mcc":1120,"cid":227096712}
  553. ]
  554. ]]
  555. mobile.reqCellInfo(60)
  556. -- 订阅
  557. sys.subscribe("CELL_INFO_UPDATE", function()
  558. log.info("cell", json.encode(mobile.getCellInfo()))
  559. end)
  560. -- 定期轮训式
  561. sys.taskInit(function()
  562. sys.wait(3000)
  563. while 1 do
  564. mobile.reqCellInfo(15)
  565. sys.waitUntil("CELL_INFO_UPDATE", 15000)
  566. log.info("cell", json.encode(mobile.getCellInfo()))
  567. end
  568. end)
  569. */
  570. static int l_mobile_get_cell_info(lua_State* L) {
  571. lua_newtable(L);
  572. luat_mobile_cell_info_t* info = luat_heap_malloc(sizeof(luat_mobile_cell_info_t));
  573. if (info == NULL) {
  574. LLOGE("out of memory when malloc cell_info");
  575. return 1;
  576. }
  577. int ret = luat_mobile_get_last_notify_cell_info(info);
  578. if (ret != 0) {
  579. LLOGI("none cell info found %d", ret);
  580. goto exit;
  581. }
  582. //LLOGD("cid %d neighbor %d", info->lte_service_info.cid, info->lte_neighbor_info_num);
  583. // 当前仅返回lte信息
  584. if (info->lte_info_valid == 0 || info->lte_service_info.cid == 0) {
  585. if (0 == luat_mobile_get_service_cell_identifier(&info->lte_service_info.cid) && info->lte_service_info.cid) {
  586. LLOGW("请先调用 mobile.reqCellInfo()!!");
  587. }
  588. else {
  589. LLOGI("lte cell info not found");
  590. }
  591. goto exit;
  592. }
  593. lua_newtable(L);
  594. lua_pushinteger(L, info->lte_service_info.pci);
  595. lua_setfield(L, -2, "pci");
  596. lua_pushinteger(L, info->lte_service_info.cid);
  597. lua_setfield(L, -2, "cid");
  598. lua_pushinteger(L, info->lte_service_info.earfcn);
  599. lua_setfield(L, -2, "earfcn");
  600. lua_pushinteger(L, info->lte_service_info.rsrp);
  601. lua_setfield(L, -2, "rsrp");
  602. lua_pushinteger(L, info->lte_service_info.rsrq);
  603. lua_setfield(L, -2, "rsrq");
  604. lua_pushinteger(L, info->lte_service_info.rssi);
  605. lua_setfield(L, -2, "rssi");
  606. lua_pushinteger(L, info->lte_service_info.is_tdd);
  607. lua_setfield(L, -2, "tdd");
  608. lua_pushinteger(L, info->lte_service_info.snr);
  609. lua_setfield(L, -2, "snr");
  610. lua_pushinteger(L, u162bcd(info->lte_service_info.mcc));
  611. lua_setfield(L, -2, "mcc");
  612. lua_pushinteger(L, u162bcd(info->lte_service_info.mnc));
  613. lua_setfield(L, -2, "mnc");
  614. lua_pushinteger(L, info->lte_service_info.tac);
  615. lua_setfield(L, -2, "tac");
  616. lua_pushinteger(L, info->lte_service_info.band);
  617. lua_setfield(L, -2, "band");
  618. lua_pushinteger(L, info->lte_service_info.ulbandwidth);
  619. lua_setfield(L, -2, "ulbandwidth");
  620. lua_pushinteger(L, info->lte_service_info.dlbandwidth);
  621. lua_setfield(L, -2, "dlbandwidth");
  622. lua_seti(L, -2, 1);
  623. if (info->lte_neighbor_info_num > 0) {
  624. for (size_t i = 0; i < info->lte_neighbor_info_num; i++)
  625. {
  626. lua_settop(L, 1);
  627. //LLOGD("add neighbor %d", i);
  628. lua_newtable(L);
  629. lua_pushinteger(L, info->lte_info[i].pci);
  630. lua_setfield(L, -2, "pci");
  631. lua_pushinteger(L, info->lte_info[i].cid);
  632. lua_setfield(L, -2, "cid");
  633. if (0x8850 == info->version)
  634. {
  635. lua_pushinteger(L, info->lte_info[i].rssi);
  636. lua_setfield(L, -2, "rssi");
  637. lua_pushinteger(L, info->lte_info[i].celltype);
  638. lua_setfield(L, -2, "celltype");
  639. lua_pushinteger(L, info->lte_info[i].bandwidth);
  640. lua_setfield(L, -2, "bandwidth");
  641. }
  642. lua_pushinteger(L, info->lte_info[i].earfcn);
  643. lua_setfield(L, -2, "earfcn");
  644. lua_pushinteger(L, info->lte_info[i].rsrp);
  645. lua_setfield(L, -2, "rsrp");
  646. lua_pushinteger(L, info->lte_info[i].rsrq);
  647. lua_setfield(L, -2, "rsrq");
  648. lua_pushinteger(L, u162bcd(info->lte_info[i].mcc));
  649. lua_setfield(L, -2, "mcc");
  650. lua_pushinteger(L, u162bcd(info->lte_info[i].mnc));
  651. lua_setfield(L, -2, "mnc");
  652. lua_pushinteger(L, info->lte_info[i].snr);
  653. lua_setfield(L, -2, "snr");
  654. lua_pushinteger(L, info->lte_info[i].tac);
  655. lua_setfield(L, -2, "tac");
  656. lua_seti(L, -2, i + 2);
  657. }
  658. }
  659. lua_settop(L, 1);
  660. exit:
  661. luat_heap_free(info);
  662. return 1;
  663. }
  664. /**
  665. 发起基站信息查询,含临近小区
  666. @api mobile.reqCellInfo(timeout)
  667. @int 超时时长,单位秒,默认15. 最少5, 最高60
  668. @return nil 无返回值
  669. @usage
  670. -- 参考 mobile.getCellInfo 函数
  671. */
  672. static int l_mobile_request_cell_info(lua_State* L) {
  673. int timeout = luaL_optinteger(L, 1, 15);
  674. if (timeout > 60)
  675. timeout = 60;
  676. else if (timeout < 5)
  677. timeout = 5;
  678. luat_mobile_get_cell_info_async(timeout);
  679. return 0;
  680. }
  681. /**
  682. 重启协议栈
  683. @api mobile.reset()
  684. @usage
  685. -- 重启LTE协议栈
  686. mobile.reset()
  687. */
  688. static int l_mobile_reset(lua_State* L) {
  689. luat_mobile_reset_stack();
  690. return 0;
  691. }
  692. /**
  693. 数据量流量处理
  694. @api mobile.dataTraffic(clearUplink, clearDownlink)
  695. @boolean 清空上行流量累计值,true清空,其他忽略
  696. @boolean 清空下行流量累计值,true清空,其他忽略
  697. @return int 上行流量GB
  698. @return int 上行流量B
  699. @return int 下行流量GB
  700. @return int 下行流量B
  701. @usage
  702. -- 获取上下行流量累计值
  703. -- 上行流量值Byte = uplinkGB * 1024 * 1024 * 1024 + uplinkB
  704. -- 下行流量值Byte = downlinkGB * 1024 * 1024 * 1024 + downlinkB
  705. local uplinkGB, uplinkB, downlinkGB, downlinkB = mobile.dataTraffic()
  706. -- 清空上下行流量累计值
  707. mobile.dataTraffic(true, true)
  708. */
  709. static int l_mobile_data_traffic(lua_State* L) {
  710. uint64_t uplink;
  711. uint64_t downlink;
  712. uint8_t clear_uplink = 0;
  713. uint8_t clear_downlink = 0;
  714. volatile uint32_t temp;
  715. if (LUA_TBOOLEAN == lua_type(L, 1)) {
  716. clear_uplink = lua_toboolean(L, 1);
  717. }
  718. if (LUA_TBOOLEAN == lua_type(L, 2)) {
  719. clear_downlink = lua_toboolean(L, 2);
  720. }
  721. luat_mobile_get_ip_data_traffic(&uplink, &downlink);
  722. if (clear_uplink || clear_downlink) {
  723. luat_mobile_clear_ip_data_traffic(clear_uplink, clear_downlink);
  724. }
  725. temp = (uint32_t)(uplink >> 30);
  726. lua_pushinteger(L, temp);
  727. temp = (((uint32_t)uplink) & 0x3FFFFFFF);
  728. lua_pushinteger(L, temp);
  729. temp = (uint32_t)(downlink >> 30);
  730. lua_pushinteger(L, temp);
  731. temp = (((uint32_t)downlink) & 0x3FFFFFFF);
  732. lua_pushinteger(L, temp);
  733. return 4;
  734. }
  735. /**
  736. 网络特殊配置,针对不同平台有不同的配置,谨慎使用,目前只有EC618
  737. @api mobile.config(item, value)
  738. @int 配置项目,看mobile.CONF_XXX
  739. @int 配置值
  740. @return boolean 是否成功
  741. @usage
  742. -- EC618配置小区重选信号差值门限,不能大于15dbm,必须在飞行模式下才能用
  743. mobile.flymode(0,true)
  744. mobile.config(mobile.CONF_RESELTOWEAKNCELL, 15)
  745. mobile.config(mobile.CONF_STATICCONFIG, 1) --开启网络静态优化
  746. mobile.flymode(0,false)
  747. -- EC618设置SIM写入次数的统计
  748. -- 关闭统计
  749. mobile.config(mobile.CONF_SIM_WC_MODE, 0)
  750. -- 开启统计, 默认也是开启的.
  751. mobile.config(mobile.CONF_SIM_WC_MODE, 1)
  752. -- 读取统计值,异步, 需要通过系统消息SIM_IND获取
  753. sys.subscribe("SIM_IND", function(stats, value)
  754. log.info("SIM_IND", stats)
  755. if stats == "SIM_WC" then
  756. log.info("sim", "write counter", value)
  757. end
  758. end)
  759. mobile.config(mobile.CONF_SIM_WC_MODE, 2)
  760. -- 清空统计值
  761. mobile.config(mobile.CONF_SIM_WC_MODE, 3)
  762. */
  763. static int l_mobile_config(lua_State* L) {
  764. uint8_t item = luaL_optinteger(L, 1, 0);
  765. uint32_t value = luaL_optinteger(L, 2, 0);
  766. if (!item)
  767. {
  768. lua_pushboolean(L, 0);
  769. }
  770. else
  771. {
  772. lua_pushboolean(L, !luat_mobile_config(item, value));
  773. }
  774. return 1;
  775. }
  776. #include "luat_uart.h"
  777. #include "luat_zbuff.h"
  778. /**
  779. 获取当前使用/支持的band
  780. @api mobile.getBand(band, is_default)
  781. @zbuff 输出band
  782. @boolean true默认支持,false当前支持的,默认是false,当前是预留功能,不要写true
  783. @return boolean 成功返回true,失败放回false
  784. @usage
  785. local buff = zbuff.create(40)
  786. mobile.getBand(buff) --输出当前使用的band,band号放在buff内,buff[0],buff[1],buff[2] .. buff[buff:used() - 1]
  787. */
  788. static int l_mobile_get_band(lua_State* L) {
  789. luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 1, LUAT_ZBUFF_TYPE));
  790. uint8_t total_num;
  791. int re;
  792. if (buff->len < 40)
  793. {
  794. __zbuff_resize(buff, 40);
  795. }
  796. if (lua_isboolean(L, 2) && lua_toboolean(L, 2))
  797. {
  798. re = luat_mobile_get_support_band(buff->addr, &total_num);
  799. }
  800. else
  801. {
  802. re = luat_mobile_get_band(buff->addr, &total_num);
  803. }
  804. buff->used = total_num;
  805. lua_pushboolean(L, !re);
  806. return 1;
  807. }
  808. /**
  809. 设置使用的band
  810. @api mobile.setBand(band, num)
  811. @zbuff 输入使用的band
  812. @int band数量
  813. @return boolean 成功返回true,失败放回false
  814. @usage
  815. local buff = zbuff.create(40)
  816. buff[0] = 3
  817. buff[1] = 5
  818. buff[2] = 8
  819. buff[3] = 40
  820. mobile.setBand(buff, 4) --设置使用的band一共4个,为3,5,8,40
  821. */
  822. static int l_mobile_set_band(lua_State* L) {
  823. luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 1, LUAT_ZBUFF_TYPE));
  824. int num = luaL_optinteger(L, 2, 1);
  825. lua_pushboolean(L, !luat_mobile_set_band(buff->addr, num));
  826. return 1;
  827. }
  828. /**
  829. RF测试开关和配置
  830. @api mobile.nstOnOff(onoff, uart_id)
  831. @boolean true开启测试模式,false关闭
  832. @int 串口号
  833. @return nil 无返回值
  834. @usage
  835. mobile.nstOnOff(true, uart.VUART_0) --打开测试模式,并且用虚拟串口发送结果
  836. mobile.nstOnOff(false) --关闭测试模式
  837. */
  838. static int l_mobile_nst_test_onoff(lua_State* L) {
  839. luat_mobile_rf_test_mode(luaL_optinteger(L, 2, LUAT_VUART_ID_0), lua_toboolean(L, 1));
  840. return 0;
  841. }
  842. /**
  843. RF测试数据输入
  844. @api mobile.nstInput(data)
  845. @string or zbuff 用户从串口获取的数据,注意,当获取完所有数据后,需要再传一个nil来作为传输结束
  846. @return nil 无返回值
  847. @usage
  848. mobile.nstInput(uart_data)
  849. mobile.nstInput(nil)
  850. */
  851. static int l_mobile_nst_data_input(lua_State* L) {
  852. size_t len = 0;
  853. const char *buf = NULL;
  854. if(lua_isuserdata(L, 1))
  855. {
  856. luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 1, LUAT_ZBUFF_TYPE));
  857. len = buff->used;
  858. buf = buff->addr;
  859. }
  860. else if (lua_isstring(L, 1))
  861. {
  862. buf = lua_tolstring(L, 1, &len);//取出字符串数据
  863. }
  864. luat_mobile_rf_test_input(buf, len);
  865. return 0;
  866. }
  867. #include "rotable2.h"
  868. static const rotable_Reg_t reg_mobile[] = {
  869. {"status", ROREG_FUNC(l_mobile_status)},
  870. {"imei", ROREG_FUNC(l_mobile_imei)},
  871. {"imsi", ROREG_FUNC(l_mobile_imsi)},
  872. {"sn", ROREG_FUNC(l_mobile_sn)},
  873. {"iccid", ROREG_FUNC(l_mobile_iccid)},
  874. {"number", ROREG_FUNC(l_mobile_number)},
  875. {"muid", ROREG_FUNC(l_mobile_muid)},
  876. {"apn", ROREG_FUNC(l_mobile_apn)},
  877. {"ipv6", ROREG_FUNC(l_mobile_ipv6)},
  878. {"csq", ROREG_FUNC(l_mobile_csq)},
  879. {"rssi", ROREG_FUNC(l_mobile_rssi)},
  880. {"rsrq", ROREG_FUNC(l_mobile_rsrq)},
  881. {"rsrp", ROREG_FUNC(l_mobile_rsrp)},
  882. {"snr", ROREG_FUNC(l_mobile_snr)},
  883. {"eci", ROREG_FUNC(l_mobile_eci)},
  884. {"tac", ROREG_FUNC(l_mobile_tac)},
  885. {"enbid", ROREG_FUNC(l_mobile_enbid)},
  886. {"flymode", ROREG_FUNC(l_mobile_flymode)},
  887. {"simid", ROREG_FUNC(l_mobile_simid)},
  888. {"simPin", ROREG_FUNC(l_mobile_sim_pin)},
  889. {"rtime", ROREG_FUNC(l_mobile_set_rrc_auto_release_time)},
  890. {"setAuto", ROREG_FUNC(l_mobile_set_auto_work)},
  891. {"getCellInfo", ROREG_FUNC(l_mobile_get_cell_info)},
  892. {"reqCellInfo", ROREG_FUNC(l_mobile_request_cell_info)},
  893. {"reset", ROREG_FUNC(l_mobile_reset)},
  894. {"dataTraffic", ROREG_FUNC(l_mobile_data_traffic)},
  895. {"config", ROREG_FUNC(l_mobile_config)},
  896. {"getBand", ROREG_FUNC(l_mobile_get_band)},
  897. {"setBand", ROREG_FUNC(l_mobile_set_band)},
  898. {"nstOnOff", ROREG_FUNC(l_mobile_nst_test_onoff)},
  899. {"nstInput", ROREG_FUNC(l_mobile_nst_data_input)},
  900. //@const UNREGISTER number 未注册
  901. {"UNREGISTER", ROREG_INT(LUAT_MOBILE_STATUS_UNREGISTER)},
  902. //@const REGISTERED number 已注册
  903. {"REGISTERED", ROREG_INT(LUAT_MOBILE_STATUS_REGISTERED)},
  904. //@const SEARCH number 正在搜索中
  905. {"SEARCH", ROREG_INT(LUAT_MOBILE_STATUS_SEARCHING)},
  906. //@const DENIED number 注册被拒绝
  907. {"DENIED", ROREG_INT(LUAT_MOBILE_STATUS_DENIED)},
  908. //@const UNKNOW number 未知
  909. {"UNKNOW", ROREG_INT(LUAT_MOBILE_STATUS_UNKNOW)},
  910. //@const REGISTERED_ROAMING number 已注册,漫游
  911. {"REGISTERED_ROAMING", ROREG_INT(LUAT_MOBILE_STATUS_REGISTERED_ROAMING)},
  912. //@const SMS_ONLY_REGISTERED number 已注册,仅SMS
  913. {"SMS_ONLY_REGISTERED", ROREG_INT(LUAT_MOBILE_STATUS_SMS_ONLY_REGISTERED)},
  914. //@const SMS_ONLY_REGISTERED_ROAMING number 已注册,漫游,仅SMS
  915. {"SMS_ONLY_REGISTERED_ROAMING", ROREG_INT(LUAT_MOBILE_STATUS_SMS_ONLY_REGISTERED_ROAMING)},
  916. //@const EMERGENCY_REGISTERED number 已注册,紧急服务
  917. {"EMERGENCY_REGISTERED", ROREG_INT(LUAT_MOBILE_STATUS_EMERGENCY_REGISTERED)},
  918. //@const CSFB_NOT_PREFERRED_REGISTERED number 已注册,非主要服务
  919. {"CSFB_NOT_PREFERRED_REGISTERED", ROREG_INT(LUAT_MOBILE_STATUS_CSFB_NOT_PREFERRED_REGISTERED)},
  920. //@const CSFB_NOT_PREFERRED_REGISTERED_ROAMING number 已注册,非主要服务,漫游
  921. {"CSFB_NOT_PREFERRED_REGISTERED_ROAMING", ROREG_INT(LUAT_MOBILE_STATUS_CSFB_NOT_PREFERRED_REGISTERED_ROAMING)},
  922. //@const CONF_RESELTOWEAKNCELL number 小区重选信号差值门限,需要飞行模式设置
  923. {"CONF_RESELTOWEAKNCELL", ROREG_INT(MOBILE_CONF_RESELTOWEAKNCELL)},
  924. //@const CONF_STATICCONFIG number 网络静态模式优化,需要飞行模式设置
  925. {"CONF_STATICCONFIG", ROREG_INT(MOBILE_CONF_STATICCONFIG)},
  926. //@const CONF_QUALITYFIRST number 网络切换以信号质量优先,需要飞行模式设置,0不开,1开启,2开启并加速切换,功耗会增加
  927. {"CONF_QUALITYFIRST", ROREG_INT(MOBILE_CONF_QUALITYFIRST)},
  928. //@const CONF_USERDRXCYCLE number LTE跳paging,需要飞行模式设置,谨慎使用,0是不设置,1~7增大或减小DrxCycle周期倍数,1:1/8倍 2:1/4倍 3:1/2倍 4:2倍 5:4倍 6:8倍 7:16倍,8~12配置固定的DrxCycle周期,仅当该周期大于网络分配的DrxCycle周期时该配置才会生效,8:320ms 9:640ms 10:1280ms 11:2560ms 12:5120ms
  929. {"CONF_USERDRXCYCLE", ROREG_INT(MOBILE_CONF_USERDRXCYCLE)},
  930. //@const CONF_T3324MAXVALUE number PSM模式中的T3324时间,单位S
  931. {"CONF_T3324MAXVALUE", ROREG_INT(MOBILE_CONF_T3324MAXVALUE)},
  932. //@const CONF_PSM_MODE number PSM模式开关,0关,1开
  933. {"CONF_PSM_MODE", ROREG_INT(MOBILE_CONF_PSM_MODE)},
  934. //@const CONF_CE_MODE number attach模式,0为EPS ONLY 2为混合,遇到IMSI detach脱网问题,设置为0,注意设置为EPS ONLY时会取消短信功能
  935. {"CONF_CE_MODE", ROREG_INT(MOBILE_CONF_CE_MODE)},
  936. //@const CONF_SIM_WC_MODE number SIM写入次数的配置和读取
  937. {"CONF_SIM_WC_MODE", ROREG_INT(MOBILE_CONF_SIM_WC_MODE)},
  938. //@const PIN_VERIFY number 验证PIN码操作
  939. {"PIN_VERIFY", ROREG_INT(LUAT_SIM_PIN_VERIFY)},
  940. //@const PIN_CHANGE number 更换PIN码操作
  941. {"PIN_CHANGE", ROREG_INT(LUAT_SIM_PIN_CHANGE)},
  942. //@const PIN_ENABLE number 使能PIN码验证
  943. {"PIN_ENABLE", ROREG_INT(LUAT_SIM_PIN_ENABLE)},
  944. //@const PIN_DISABLE number 关闭PIN码验证
  945. {"PIN_DISABLE", ROREG_INT(LUAT_SIM_PIN_DISABLE)},
  946. //@const PIN_UNBLOCK number 解锁PIN码
  947. {"PIN_UNBLOCK", ROREG_INT(LUAT_SIM_PIN_UNBLOCK)},
  948. {NULL, ROREG_INT(0)}
  949. };
  950. LUAMOD_API int luaopen_mobile( lua_State *L ) {
  951. luat_newlib2(L, reg_mobile);
  952. return 1;
  953. }
  954. static int l_mobile_event_handle(lua_State* L, void* ptr) {
  955. LUAT_MOBILE_EVENT_E event;
  956. uint8_t index;
  957. uint8_t status;
  958. int ret;
  959. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  960. event = msg->arg1;
  961. index = msg->arg2 >> 8;
  962. status = msg->arg2 & 0xFF;
  963. // luat_mobile_cell_info_t cell_info;
  964. // luat_mobile_signal_strength_info_t signal_info;
  965. // uint8_t csq, i;
  966. // char imsi[20];
  967. // char iccid[24] = {0};
  968. if (lua_getglobal(L, "sys_pub") != LUA_TFUNCTION) {
  969. return 0;
  970. };
  971. switch(event)
  972. {
  973. case LUAT_MOBILE_EVENT_CFUN:
  974. break;
  975. case LUAT_MOBILE_EVENT_SIM:
  976. /*
  977. @sys_pub mobile
  978. sim卡状态变化
  979. SIM_IND
  980. @usage
  981. sys.subscribe("SIM_IND", function(status, value)
  982. -- status的取值有:
  983. -- RDY SIM卡就绪, value为nil
  984. -- NORDY 无SIM卡, value为nil
  985. -- SIM_PIN 需要输入PIN, value为nil
  986. -- GET_NUMBER 获取到电话号码(不一定有值), value为nil
  987. -- SIM_WC SIM卡的写入次数统计,掉电归0, value为统计值
  988. log.info("sim status", status, value)
  989. end)
  990. */
  991. switch (status)
  992. {
  993. case LUAT_MOBILE_SIM_READY:
  994. lua_pushstring(L, "SIM_IND");
  995. lua_pushstring(L, "RDY");
  996. lua_call(L, 2, 0);
  997. break;
  998. case LUAT_MOBILE_NO_SIM:
  999. lua_pushstring(L, "SIM_IND");
  1000. lua_pushstring(L, "NORDY");
  1001. lua_call(L, 2, 0);
  1002. break;
  1003. case LUAT_MOBILE_SIM_NEED_PIN:
  1004. lua_pushstring(L, "SIM_IND");
  1005. lua_pushstring(L, "SIM_PIN");
  1006. lua_call(L, 2, 0);
  1007. break;
  1008. case LUAT_MOBILE_SIM_NUMBER:
  1009. lua_pushstring(L, "SIM_IND");
  1010. lua_pushstring(L, "GET_NUMBER");
  1011. lua_call(L, 2, 0);
  1012. break;
  1013. case LUAT_MOBILE_SIM_WC:
  1014. lua_pushstring(L, "SIM_IND");
  1015. lua_pushstring(L, "SIM_WC");
  1016. uint32_t tmp = (uint32_t)ptr;
  1017. lua_pushinteger(L, tmp);
  1018. lua_call(L, 3, 0);
  1019. break;
  1020. default:
  1021. break;
  1022. }
  1023. break;
  1024. case LUAT_MOBILE_EVENT_REGISTER_STATUS:
  1025. break;
  1026. case LUAT_MOBILE_EVENT_CELL_INFO:
  1027. switch (status)
  1028. {
  1029. case LUAT_MOBILE_CELL_INFO_UPDATE:
  1030. /*
  1031. @sys_pub mobile
  1032. 基站数据已更新
  1033. CELL_INFO_UPDATE
  1034. @usage
  1035. -- 订阅式
  1036. sys.subscribe("CELL_INFO_UPDATE", function()
  1037. log.info("cell", json.encode(mobile.getCellInfo()))
  1038. end)
  1039. */
  1040. lua_pushstring(L, "CELL_INFO_UPDATE");
  1041. lua_call(L, 1, 0);
  1042. break;
  1043. default:
  1044. break;
  1045. }
  1046. break;
  1047. case LUAT_MOBILE_EVENT_PDP:
  1048. LLOGD("cid%d, state%d", index, status);
  1049. break;
  1050. case LUAT_MOBILE_EVENT_NETIF:
  1051. switch (status)
  1052. {
  1053. case LUAT_MOBILE_NETIF_LINK_ON:
  1054. LLOGD("NETIF_LINK_ON -> IP_READY");
  1055. /*
  1056. @sys_pub mobile
  1057. 已联网
  1058. IP_READY
  1059. @usage
  1060. -- 联网后会发一次这个消息
  1061. sys.subscribe("IP_READY", function(ip, adapter)
  1062. log.info("mobile", "IP_READY", ip, (adapter or -1) == socket.LWIP_GP)
  1063. end)
  1064. */
  1065. lua_pushstring(L, "IP_READY");
  1066. luat_ip_addr_t local_ip, net_mask, gate_way, ipv6;
  1067. #ifdef LUAT_USE_LWIP
  1068. ipv6.type = 0xff;
  1069. int ret = network_get_full_local_ip_info(NULL, NW_ADAPTER_INDEX_LWIP_GPRS, &local_ip, &net_mask, &gate_way, &ipv6);
  1070. #else
  1071. void* userdata = NULL;
  1072. network_adapter_info* info = network_adapter_fetch(NW_ADAPTER_INDEX_LWIP_GPRS, &userdata);
  1073. if (info == NULL)
  1074. ret = -1;
  1075. else
  1076. ret = info->get_local_ip_info(&local_ip, &net_mask, &gate_way, userdata);
  1077. #endif
  1078. if (ret == 0) {
  1079. #ifdef LUAT_USE_LWIP
  1080. lua_pushfstring(L, "%s", ipaddr_ntoa(&local_ip));
  1081. #else
  1082. lua_pushfstring(L, "%d.%d.%d.%d", (local_ip.ipv4 >> 24) & 0xFF, (local_ip.ipv4 >> 16) & 0xFF, (local_ip.ipv4 >> 8) & 0xFF, (local_ip.ipv4 >> 0) & 0xFF);
  1083. #endif
  1084. }
  1085. else {
  1086. lua_pushliteral(L, "0.0.0.0");
  1087. }
  1088. lua_pushinteger(L, NW_ADAPTER_INDEX_LWIP_GPRS);
  1089. lua_call(L, 3, 0);
  1090. break;
  1091. case LUAT_MOBILE_NETIF_LINK_OFF:
  1092. LLOGD("NETIF_LINK_OFF -> IP_LOSE");
  1093. /*
  1094. @sys_pub mobile
  1095. 已断网
  1096. IP_LOSE
  1097. @usage
  1098. -- 断网后会发一次这个消息
  1099. sys.subscribe("IP_LOSE", function(adapter)
  1100. log.info("mobile", "IP_LOSE", (adapter or -1) == socket.LWIP_GP)
  1101. end)
  1102. */
  1103. lua_pushstring(L, "IP_LOSE");
  1104. lua_pushinteger(L, NW_ADAPTER_INDEX_LWIP_GPRS);
  1105. lua_call(L, 2, 0);
  1106. break;
  1107. default:
  1108. break;
  1109. }
  1110. break;
  1111. case LUAT_MOBILE_EVENT_TIME_SYNC:
  1112. /*
  1113. @sys_pub mobile
  1114. 时间已经同步
  1115. NTP_UPDATE
  1116. @usage
  1117. -- 对于电信/移动的卡, 联网后,基站会下发时间,但联通卡不会,务必留意
  1118. sys.subscribe("NTP_UPDATE", function()
  1119. log.info("mobile", "time", os.date())
  1120. end)
  1121. */
  1122. LLOGD("TIME_SYNC %d", status);
  1123. lua_pushstring(L, "NTP_UPDATE");
  1124. lua_call(L, 1, 0);
  1125. break;
  1126. case LUAT_MOBILE_EVENT_CSCON:
  1127. // LLOGD("CSCON %d", status);
  1128. break;
  1129. case LUAT_MOBILE_EVENT_BEARER:
  1130. LLOGD("bearer act %d, result %d",status, index);
  1131. break;
  1132. case LUAT_MOBILE_EVENT_SMS:
  1133. switch(status)
  1134. {
  1135. case LUAT_MOBILE_SMS_READY:
  1136. LLOGI("sim%d sms ready", index);
  1137. break;
  1138. case LUAT_MOBILE_NEW_SMS:
  1139. break;
  1140. case LUAT_MOBILE_SMS_SEND_DONE:
  1141. break;
  1142. case LUAT_MOBILE_SMS_ACK:
  1143. break;
  1144. }
  1145. break;
  1146. case LUAT_MOBILE_EVENT_IMS_REGISTER_STATUS:
  1147. LLOGD("ims reg state %d", status);
  1148. break;
  1149. case LUAT_MOBILE_EVENT_CC:
  1150. LLOGD("LUAT_MOBILE_EVENT_CC status %d",status);
  1151. /*
  1152. @sys_pub mobile
  1153. 通话状态变化
  1154. CC_IND
  1155. @usage
  1156. sys.subscribe("CC_IND", function(status, value)
  1157. log.info("cc status", status, value)
  1158. end)
  1159. */
  1160. switch(status){
  1161. case LUAT_MOBILE_CC_READY:
  1162. LLOGD("LUAT_MOBILE_CC_READY");
  1163. lua_pushstring(L, "CC_IND");
  1164. lua_pushstring(L, "READY");
  1165. lua_call(L, 2, 0);
  1166. break;
  1167. case LUAT_MOBILE_CC_INCOMINGCALL:
  1168. lua_pushstring(L, "CC_IND");
  1169. lua_pushstring(L, "INCOMINGCALL");
  1170. lua_call(L, 2, 0);
  1171. break;
  1172. case LUAT_MOBILE_CC_CALL_NUMBER:
  1173. // lua_pushstring(L, "CC_IND");
  1174. // lua_pushstring(L, "CALL_NUMBER");
  1175. // lua_call(L, 2, 0);
  1176. break;
  1177. case LUAT_MOBILE_CC_CONNECTED_NUMBER:
  1178. // lua_pushstring(L, "CC_IND");
  1179. // lua_pushstring(L, "CONNECTED_NUMBER");
  1180. // lua_call(L, 2, 0);
  1181. break;
  1182. case LUAT_MOBILE_CC_CONNECTED:
  1183. lua_pushstring(L, "CC_IND");
  1184. lua_pushstring(L, "CONNECTED");
  1185. lua_call(L, 2, 0);
  1186. break;
  1187. case LUAT_MOBILE_CC_DISCONNECTED:
  1188. lua_pushstring(L, "CC_IND");
  1189. lua_pushstring(L, "DISCONNECTED");
  1190. lua_call(L, 2, 0);
  1191. break;
  1192. case LUAT_MOBILE_CC_SPEECH_START:
  1193. lua_pushstring(L, "CC_IND");
  1194. lua_pushstring(L, "SPEECH_START");
  1195. lua_call(L, 2, 0);
  1196. break;
  1197. case LUAT_MOBILE_CC_MAKE_CALL_OK:
  1198. lua_pushstring(L, "CC_IND");
  1199. lua_pushstring(L, "MAKE_CALL_OK");
  1200. lua_call(L, 2, 0);
  1201. break;
  1202. case LUAT_MOBILE_CC_MAKE_CALL_FAILED:
  1203. lua_pushstring(L, "CC_IND");
  1204. lua_pushstring(L, "MAKE_CALL_FAILED");
  1205. lua_call(L, 2, 0);
  1206. break;
  1207. case LUAT_MOBILE_CC_ANSWER_CALL_DONE:
  1208. lua_pushstring(L, "CC_IND");
  1209. lua_pushstring(L, "ANSWER_CALL_DONE");
  1210. lua_call(L, 2, 0);
  1211. break;
  1212. case LUAT_MOBILE_CC_HANGUP_CALL_DONE:
  1213. lua_pushstring(L, "CC_IND");
  1214. lua_pushstring(L, "HANGUP_CALL_DONE");
  1215. lua_call(L, 2, 0);
  1216. break;
  1217. case LUAT_MOBILE_CC_LIST_CALL_RESULT:
  1218. lua_pushstring(L, "CC_IND");
  1219. lua_pushstring(L, "LIST_CALL_RESULT");
  1220. lua_call(L, 2, 0);
  1221. break;
  1222. case LUAT_MOBILE_CC_PLAY:// 最先
  1223. lua_pushstring(L, "CC_IND");
  1224. lua_pushstring(L, "PLAY");
  1225. lua_call(L, 2, 0);
  1226. break;
  1227. }
  1228. break;
  1229. default:
  1230. break;
  1231. }
  1232. return 0;
  1233. }
  1234. void luat_mobile_event_cb(LUAT_MOBILE_EVENT_E event, uint8_t index, uint8_t status, void* ptr) {
  1235. #if defined LUAT_USE_VOLTE
  1236. switch (event){
  1237. case LUAT_MOBILE_EVENT_CC:
  1238. switch(status){
  1239. case LUAT_MOBILE_CC_SPEECH_START:
  1240. luat_cc_start_speech(index+1);
  1241. break;
  1242. case LUAT_MOBILE_CC_PLAY:
  1243. luat_cc_play_tone(index);
  1244. break;
  1245. }
  1246. break;
  1247. default:
  1248. break;
  1249. }
  1250. #endif
  1251. rtos_msg_t msg = {
  1252. .handler = l_mobile_event_handle,
  1253. .arg1 = event,
  1254. .arg2 = (index << 8) + status ,
  1255. .ptr = ptr
  1256. };
  1257. luat_msgbus_put(&msg, 0);
  1258. }