luat_lib_socket.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312
  1. /*
  2. @module socket
  3. @summary 网络接口
  4. @version 1.0
  5. @date 2022.11.13
  6. @demo socket
  7. @tag LUAT_USE_NETWORK
  8. */
  9. #include "luat_base.h"
  10. #include "luat_mem.h"
  11. // #ifdef LUAT_USE_NETWORK
  12. #include "luat_network_adapter.h"
  13. #include "luat_rtos.h"
  14. #include "luat_zbuff.h"
  15. #define LUAT_LOG_TAG "socket"
  16. #include "luat_log.h"
  17. //static const char NW_TYPE[] = "NWA*";
  18. #define LUAT_NW_CTRL_TYPE "NWCTRL*"
  19. typedef struct
  20. {
  21. network_ctrl_t *netc;
  22. int cb_ref; //回调函数
  23. char *task_name;
  24. uint8_t adapter_index;
  25. }luat_socket_ctrl_t;
  26. #define L_CTRL_CHECK do {if (!l_ctrl){return 0;}}while(0)
  27. network_adapter_info* network_adapter_fetch(int id, void** userdata);
  28. /*
  29. 获取本地ip
  30. @api socket.localIP(adapter)
  31. @int 适配器序号, 只能是socket.ETH0(外置以太网),socket.LWIP_ETH(内置以太网),socket.LWIP_STA(内置WIFI的STA),socket.LWIP_AP(内置WIFI的AP),socket.LWIP_GP(内置蜂窝网络的GPRS),socket.USB(外置USB网卡),如果不填,优先选择soc平台自带能上外网的适配器,若仍然没有,选择最后一个注册的适配器
  32. @return string 通常是内网ip, 也可能是外网ip, 取决于运营商的分配
  33. @return string 网络掩码
  34. @return string 网关IP
  35. @usage
  36. sys.taskInit(function()
  37. while 1 do
  38. sys.wait(3000)
  39. log.info("socket", "ip", socket.localIP())
  40. -- 输出示例
  41. -- 62.39.244.10 255.255.255.255 0.0.0.0
  42. end
  43. end)
  44. */
  45. static int l_socket_local_ip(lua_State *L)
  46. {
  47. luat_ip_addr_t local_ip, net_mask, gate_way, ipv6;
  48. int adapter_index = luaL_optinteger(L, 1, network_get_last_register_adapter());
  49. if (adapter_index < 0 || adapter_index >= NW_ADAPTER_QTY)
  50. {
  51. return 0;
  52. }
  53. #ifdef LUAT_USE_LWIP
  54. network_set_ip_invaild(&ipv6);
  55. int ret = network_get_full_local_ip_info(NULL, adapter_index, &local_ip, &net_mask, &gate_way, &ipv6);
  56. #else
  57. void* userdata = NULL;
  58. network_adapter_info* info = network_adapter_fetch(adapter_index, &userdata);
  59. if (info == NULL)
  60. return 0;
  61. int ret = info->get_local_ip_info(&local_ip, &net_mask, &gate_way, userdata);
  62. #endif
  63. if (ret == 0) {
  64. #ifdef LUAT_USE_LWIP
  65. lua_pushfstring(L, "%s", ipaddr_ntoa(&local_ip));
  66. lua_pushfstring(L, "%s", ipaddr_ntoa(&net_mask));
  67. lua_pushfstring(L, "%s", ipaddr_ntoa(&gate_way));
  68. #if LWIP_IPV6
  69. if (IPADDR_TYPE_V6 == ipv6.type)
  70. {
  71. char *ipv6_string = ip6addr_ntoa(&ipv6.u_addr.ip6);
  72. lua_pushfstring(L, "%s", ipv6_string);
  73. }
  74. else
  75. #endif
  76. {
  77. lua_pushnil(L);
  78. }
  79. return 4;
  80. #else
  81. lua_pushfstring(L, "%d.%d.%d.%d", (local_ip.ipv4 >> 0) & 0xFF, (local_ip.ipv4 >> 8) & 0xFF, (local_ip.ipv4 >> 16) & 0xFF, (local_ip.ipv4 >> 24) & 0xFF);
  82. lua_pushfstring(L, "%d.%d.%d.%d", (net_mask.ipv4 >> 0) & 0xFF, (net_mask.ipv4 >> 8) & 0xFF, (net_mask.ipv4 >> 16) & 0xFF, (net_mask.ipv4 >> 24) & 0xFF);
  83. lua_pushfstring(L, "%d.%d.%d.%d", (gate_way.ipv4 >> 0) & 0xFF, (gate_way.ipv4 >> 8) & 0xFF, (gate_way.ipv4 >> 16) & 0xFF, (gate_way.ipv4 >> 24) & 0xFF);
  84. return 3;
  85. #endif
  86. }
  87. return 0;
  88. }
  89. static int32_t l_socket_callback(lua_State *L, void* ptr)
  90. {
  91. rtos_msg_t* msg = (rtos_msg_t*)lua_topointer(L, -1);
  92. luat_socket_ctrl_t *l_ctrl =(luat_socket_ctrl_t *)msg->ptr;
  93. if (l_ctrl->netc)
  94. {
  95. if (l_ctrl->cb_ref)
  96. {
  97. lua_geti(L, LUA_REGISTRYINDEX, l_ctrl->cb_ref);
  98. if (lua_isfunction(L, -1)) {
  99. lua_pushlightuserdata(L, l_ctrl);
  100. lua_pushinteger(L, msg->arg1);
  101. lua_pushinteger(L, msg->arg2);
  102. lua_call(L, 3, 0);
  103. }
  104. }
  105. else if (l_ctrl->task_name)
  106. {
  107. lua_getglobal(L, "sys_send");
  108. if (lua_isfunction(L, -1)) {
  109. lua_pushstring(L, l_ctrl->task_name);
  110. lua_pushinteger(L, msg->arg1);
  111. lua_pushinteger(L, msg->arg2);
  112. lua_call(L, 3, 0);
  113. }
  114. }
  115. else
  116. {
  117. lua_getglobal(L, "sys_pub");
  118. if (lua_isfunction(L, -1)) {
  119. lua_pushstring(L, LUAT_NW_CTRL_TYPE);
  120. lua_pushinteger(L, l_ctrl->netc->adapter_index);
  121. lua_pushinteger(L, l_ctrl->netc->socket_id);
  122. lua_pushinteger(L, msg->arg1);
  123. lua_pushinteger(L, msg->arg2);
  124. lua_call(L, 5, 0);
  125. }
  126. }
  127. }
  128. lua_pushinteger(L, 0);
  129. return 1;
  130. }
  131. static int32_t luat_lib_socket_callback(void *data, void *param)
  132. {
  133. OS_EVENT *event = (OS_EVENT *)data;
  134. rtos_msg_t msg;
  135. msg.handler = l_socket_callback;
  136. msg.ptr = param;
  137. msg.arg1 = event->ID & 0x0fffffff;
  138. msg.arg2 = event->Param1;
  139. luat_msgbus_put(&msg, 0);
  140. return 0;
  141. }
  142. static luat_socket_ctrl_t * l_get_ctrl(lua_State *L, int index)
  143. {
  144. if (luaL_testudata(L, 1, LUAT_NW_CTRL_TYPE))
  145. {
  146. return ((luat_socket_ctrl_t *)luaL_checkudata(L, 1, LUAT_NW_CTRL_TYPE));
  147. }
  148. else
  149. {
  150. return ((luat_socket_ctrl_t *)lua_touserdata(L, 1));
  151. }
  152. }
  153. // __gc
  154. static int l_socket_gc(lua_State *L)
  155. {
  156. luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
  157. L_CTRL_CHECK;
  158. if (l_ctrl->netc)
  159. {
  160. network_force_close_socket(l_ctrl->netc);
  161. network_release_ctrl(l_ctrl->netc);
  162. l_ctrl->netc = NULL;
  163. }
  164. if (l_ctrl->cb_ref)
  165. {
  166. luaL_unref(L, LUA_REGISTRYINDEX, l_ctrl->cb_ref);
  167. l_ctrl->cb_ref = 0;
  168. }
  169. if (l_ctrl->task_name)
  170. {
  171. luat_heap_free(l_ctrl->task_name);
  172. l_ctrl->task_name = 0;
  173. }
  174. return 0;
  175. }
  176. /*
  177. 在某个适配的网卡上申请一个socket_ctrl
  178. @api socket.create(adapter, cb)
  179. @int 适配器序号, 只能是socket.ETH0(外置以太网),socket.LWIP_ETH(内置以太网),socket.LWIP_STA(内置WIFI的STA),socket.LWIP_AP(内置WIFI的AP),socket.LWIP_GP(内置蜂窝网络的GPRS),socket.USB(外置USB网卡),如果不填,优先选择soc平台自带能上外网的适配器,若仍然没有,选择最后一个注册的适配器
  180. @string or function string为消息通知的taskName,function则为回调函数,如果固件没有内置sys_wait,则必须是function
  181. 当通过回调函数回调消息时,输入给function一共3个参数:
  182. param1为申请的network_ctrl
  183. param2为具体的消息,只能是socket.RESET, socket.LINK, socket.ON_LINE, socket.TX_OK, socket.RX_NEW, socket.CLOSED等等
  184. param3为消息对应的参数
  185. @return userdata 成功返回network_ctrl,失败返回nil
  186. @usage
  187. --以太网网卡上申请一个network_ctrl,通过socket_cb_fun回调相关消息
  188. local netc = socket.create(socket.ETH0, socket_cb_fun)
  189. --以太网网卡上申请一个network_ctrl,通过sendMsg方式通知taskName为"IOT_TASK"回调相关消息
  190. local netc = socket.create(socket.ETH0, "IOT_TASK")
  191. -- 在默认网络适配器上创建一个network_ctrl
  192. local netc = socket.create(nil, "MySocket")
  193. */
  194. static int l_socket_create(lua_State *L)
  195. {
  196. int adapter_index = luaL_optinteger(L, 1, network_get_last_register_adapter());
  197. if (adapter_index < 0 || adapter_index >= NW_ADAPTER_QTY)
  198. {
  199. lua_pushnil(L);
  200. return 1;
  201. }
  202. luat_socket_ctrl_t *l_ctrl = (luat_socket_ctrl_t *)lua_newuserdata(L, sizeof(luat_socket_ctrl_t));
  203. if (!l_ctrl)
  204. {
  205. lua_pushnil(L);
  206. return 1;
  207. }
  208. l_ctrl->adapter_index = adapter_index;
  209. l_ctrl->netc = network_alloc_ctrl(adapter_index);
  210. if (!l_ctrl->netc)
  211. {
  212. LLOGD("create fail");
  213. lua_pushnil(L);
  214. return 1;
  215. }
  216. network_init_ctrl(l_ctrl->netc, NULL, luat_lib_socket_callback, l_ctrl);
  217. if (lua_isfunction(L, 2))
  218. {
  219. lua_pushvalue(L, 2);
  220. l_ctrl->cb_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  221. l_ctrl->task_name = NULL;
  222. }
  223. else if (lua_isstring(L, 2))
  224. {
  225. l_ctrl->cb_ref = 0;
  226. size_t len;
  227. const char *buf;
  228. buf = lua_tolstring(L, 2, &len);//取出字符串数据
  229. l_ctrl->task_name = luat_heap_malloc(len + 1);
  230. memset(l_ctrl->task_name, 0, len + 1);
  231. memcpy(l_ctrl->task_name, buf, len);
  232. }
  233. luaL_setmetatable(L, LUAT_NW_CTRL_TYPE);
  234. return 1;
  235. }
  236. /*
  237. 配置是否打开debug信息
  238. @api socket.debug(ctrl, onoff)
  239. @user_data socket.create得到的ctrl
  240. @boolean true 打开debug开关
  241. @return nil 无返回值
  242. @usage
  243. -- 打开调试信息,默认是关闭状态
  244. socket.debug(ctrl, true)
  245. */
  246. static int l_socket_set_debug(lua_State *L)
  247. {
  248. luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
  249. L_CTRL_CHECK;
  250. if (lua_isboolean(L, 2))
  251. {
  252. l_ctrl->netc->is_debug = lua_toboolean(L, 2);
  253. }
  254. return 0;
  255. }
  256. /*
  257. 配置network一些信息,
  258. @api socket.config(ctrl, local_port, is_udp, is_tls, keep_idle, keep_interval, keep_cnt, server_cert, client_cert, client_key, client_password)
  259. @user_data socket.create得到的ctrl
  260. @int 本地端口号,小端格式,如果不写,则自动分配一个,如果用户填了端口号则需要小于60000, 默认不写
  261. @boolean 是否是UDP,默认false
  262. @boolean 是否是加密传输,默认false
  263. @int tcp keep live模式下的idle时间(秒),如果留空则表示不启用,如果是不支持标准posix接口的网卡(比如W5500),则为心跳间隔
  264. @int tcp keep live模式下的探测间隔时间(秒)
  265. @int tcp keep live模式下的探测次数
  266. @string TCP模式下的服务器ca证书数据,UDP模式下的PSK,不需要加密传输写nil,后续参数也全部nil
  267. @string TCP模式下的客户端ca证书数据,UDP模式下的PSK-ID,TCP模式下如果不需要验证客户端证书时,忽略,一般不需要验证客户端证书
  268. @string TCP模式下的客户端私钥加密数据
  269. @string TCP模式下的客户端私钥口令数据
  270. @return boolean 成功返回true,失败返回false
  271. @usage
  272. --最普通的TCP传输
  273. socket.config(ctrl)
  274. --最普通的加密TCP传输,证书都不用验证的那种
  275. socket.config(ctrl, nil, nil ,true)
  276. */
  277. static int l_socket_config(lua_State *L)
  278. {
  279. luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
  280. L_CTRL_CHECK;
  281. uint8_t is_udp = 0;
  282. uint8_t is_tls = 0;
  283. int param_pos = 1;
  284. uint32_t keep_idle, keep_interval, keep_cnt;
  285. const char *server_cert = NULL;
  286. const char *client_cert = NULL;
  287. const char *client_key = NULL;
  288. const char *client_password = NULL;
  289. size_t server_cert_len, client_cert_len, client_key_len, client_password_len;
  290. uint16_t local_port = luaL_optinteger(L, ++param_pos, 0);
  291. if (lua_isboolean(L, ++param_pos))
  292. {
  293. is_udp = lua_toboolean(L, param_pos);
  294. }
  295. if (lua_isboolean(L, ++param_pos))
  296. {
  297. is_tls = lua_toboolean(L, param_pos);
  298. }
  299. #ifndef LUAT_USE_TLS
  300. if (is_tls){
  301. LLOGE("NOT SUPPORT TLS");
  302. lua_pushboolean(L, 0);
  303. return 1;
  304. }
  305. #endif
  306. keep_idle = luaL_optinteger(L, ++param_pos, 0);
  307. keep_interval = luaL_optinteger(L, ++param_pos, 0);
  308. keep_cnt = luaL_optinteger(L, ++param_pos, 0);
  309. if (lua_isstring(L, ++param_pos))
  310. {
  311. server_cert_len = 0;
  312. server_cert = luaL_checklstring(L, param_pos, &server_cert_len);
  313. }
  314. if (lua_isstring(L, ++param_pos))
  315. {
  316. client_cert_len = 0;
  317. client_cert = luaL_checklstring(L, param_pos, &client_cert_len);
  318. }
  319. if (lua_isstring(L, ++param_pos))
  320. {
  321. client_key_len = 0;
  322. client_key = luaL_checklstring(L, param_pos, &client_key_len);
  323. }
  324. if (lua_isstring(L, ++param_pos))
  325. {
  326. client_password_len = 0;
  327. client_password = luaL_checklstring(L, param_pos, &client_password_len);
  328. }
  329. network_set_base_mode(l_ctrl->netc, !is_udp, 10000, keep_idle, keep_idle, keep_interval, keep_cnt);
  330. network_set_local_port(l_ctrl->netc, local_port);
  331. if (is_tls)
  332. {
  333. network_init_tls(l_ctrl->netc, (server_cert || client_cert)?2:0);
  334. if (is_udp)
  335. {
  336. network_set_psk_info(l_ctrl->netc, (const unsigned char *)server_cert, server_cert_len, (const unsigned char *)client_key, client_key_len);
  337. }
  338. else
  339. {
  340. if (server_cert)
  341. {
  342. network_set_server_cert(l_ctrl->netc, (const unsigned char *)server_cert, server_cert_len + 1);
  343. }
  344. if (client_cert)
  345. {
  346. network_set_client_cert(l_ctrl->netc, (const unsigned char *)client_cert, client_cert_len + 1,
  347. (const unsigned char *)client_key, client_key_len + 1,
  348. (const unsigned char *)client_password, client_password_len + 1);
  349. }
  350. }
  351. }
  352. else
  353. {
  354. network_deinit_tls(l_ctrl->netc);
  355. }
  356. lua_pushboolean(L, 1);
  357. return 1;
  358. }
  359. /*
  360. 等待网卡linkup
  361. @api socket.linkup(ctrl)
  362. @user_data socket.create得到的ctrl
  363. @return boolean true没有异常发生,false失败了,如果false则不需要看下一个返回值了
  364. @return boolean true已经linkup,false没有linkup,之后需要接收socket.LINK消息
  365. @usage
  366. -- 判断一下是否已经联网
  367. local succ, result = socket.linkup(ctrl)
  368. */
  369. static int l_socket_linkup(lua_State *L)
  370. {
  371. luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
  372. L_CTRL_CHECK;
  373. int result = network_wait_link_up(l_ctrl->netc, 0);
  374. lua_pushboolean(L, (result < 0)?0:1);
  375. lua_pushboolean(L, result == 0);
  376. return 2;
  377. }
  378. /*
  379. 作为客户端连接服务器
  380. @api socket.connect(ctrl, ip, remote_port, need_ipv6_dns)
  381. @user_data socket.create得到的ctrl
  382. @string or int ip或者域名,如果是IPV4,可以是大端格式的int值
  383. @int 服务器端口号,小端格式
  384. @boolean 域名解析是否要IPV6,true要,false不要,默认false不要,只有支持IPV6的协议栈才有效果
  385. @return boolean true没有异常发生,false失败了,如果false则不需要看下一个返回值了,如果有异常,后续要close
  386. @return boolean true已经connect,false没有connect,之后需要接收socket.ON_LINE消息
  387. @usage
  388. local succ, result = socket.connect(ctrl, "netlab.luatos.com", 40123)
  389. --[[
  390. 常见的连接失败的code值, 会在日志中显示
  391. -1 底层内存不足
  392. -3 超时
  393. -8 端口已经被占用
  394. -11 链接未建立
  395. -13 模块主动断开连接
  396. -14 服务器主动断开连接
  397. ]]
  398. */
  399. static int l_socket_connect(lua_State *L)
  400. {
  401. #ifdef LUAT_USE_LWIP
  402. luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
  403. L_CTRL_CHECK;
  404. luat_ip_addr_t ip_addr;
  405. const char *ip = NULL;
  406. size_t ip_len;
  407. network_set_ip_invaild(&ip_addr);
  408. if (lua_isinteger(L, 2))
  409. {
  410. network_set_ip_ipv4(&ip_addr, lua_tointeger(L, 2));
  411. ip = NULL;
  412. ip_len = 0;
  413. }
  414. else
  415. {
  416. ip_len = 0;
  417. ip = luaL_checklstring(L, 2, &ip_len);
  418. }
  419. uint16_t remote_port = luaL_checkinteger(L, 3);
  420. LLOGD("connect to %s,%d", ip, remote_port);
  421. if (!network_ip_is_vaild_ipv4(&ip_addr))
  422. {
  423. if (LUA_TBOOLEAN == lua_type(L, 4))
  424. {
  425. network_connect_ipv6_domain(l_ctrl->netc, lua_toboolean(L, 4));
  426. }
  427. else
  428. {
  429. network_connect_ipv6_domain(l_ctrl->netc, 0);
  430. }
  431. }
  432. int result = network_connect(l_ctrl->netc, ip, ip_len, (!network_ip_is_vaild_ipv4(&ip_addr))?NULL:&ip_addr, remote_port, 0);
  433. lua_pushboolean(L, (result < 0)?0:1);
  434. lua_pushboolean(L, result == 0);
  435. return 2;
  436. #else
  437. luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
  438. L_CTRL_CHECK;
  439. luat_ip_addr_t ip_addr;
  440. const char *ip = NULL;
  441. size_t ip_len;
  442. ip_addr.is_ipv6 = 0xff;
  443. if (lua_isinteger(L, 2))
  444. {
  445. ip_addr.is_ipv6 = 0;
  446. ip_addr.ipv4 = lua_tointeger(L, 2);
  447. ip = NULL;
  448. ip_len = 0;
  449. }
  450. else
  451. {
  452. ip_len = 0;
  453. ip = luaL_checklstring(L, 2, &ip_len);
  454. }
  455. uint16_t remote_port = luaL_checkinteger(L, 3);
  456. LLOGD("connect to %s,%d", ip, remote_port);
  457. int result = network_connect(l_ctrl->netc, ip, ip_len, ip_addr.is_ipv6?NULL:&ip_addr, remote_port, 0);
  458. lua_pushboolean(L, (result < 0)?0:1);
  459. lua_pushboolean(L, result == 0);
  460. return 2;
  461. #endif
  462. }
  463. /*
  464. 作为客户端断开连接
  465. @api socket.discon(ctrl)
  466. @user_data socket.create得到的ctrl
  467. @return boolean true没有异常发生,false失败了,如果false则不需要看下一个返回值了
  468. @return boolean true已经断开,false没有断开,之后需要接收socket.CLOSED消息
  469. @usage
  470. local succ, result = socket.discon(ctrl)
  471. */
  472. static int l_socket_disconnect(lua_State *L)
  473. {
  474. luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
  475. L_CTRL_CHECK;
  476. int result = network_close(l_ctrl->netc, 0);
  477. lua_pushboolean(L, (result < 0)?0:1);
  478. lua_pushboolean(L, result == 0);
  479. return 2;
  480. }
  481. /*
  482. 强制关闭socket
  483. @api socket.close(ctrl)
  484. @user_data socket.create得到的ctrl
  485. @return nil 无返回值
  486. */
  487. static int l_socket_close(lua_State *L)
  488. {
  489. luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
  490. L_CTRL_CHECK;
  491. network_force_close_socket(l_ctrl->netc);
  492. return 0;
  493. }
  494. /*
  495. 发送数据给对端,UDP单次发送不要超过1460字节,否则很容易失败
  496. @api socket.tx(ctrl, data, ip, port, flag)
  497. @user_data socket.create得到的ctrl
  498. @string or user_data zbuff 要发送的数据
  499. @string or int 对端IP,如果是TCP应用则忽略,如果是UDP,如果留空则用connect时候的参数,如果是IPV4,可以是大端格式的int值
  500. @int 对端端口号,小端格式,如果是TCP应用则忽略,如果是UDP,如果留空则用connect时候的参数
  501. @int 发送参数,目前预留,不起作用
  502. @return boolean true没有异常发生,false失败了,如果false则不需要看下一个返回值了,如果false,后续要close
  503. @return boolean true缓冲区满了,false没有满,如果true,则需要等待一段时间或者等到socket.TX_OK消息后再尝试发送,同时忽略下一个返回值
  504. @return boolean true已经收到应答,false没有收到应答,之后需要接收socket.TX_OK消息, 也可以忽略继续发送,直到full==true
  505. @usage
  506. local succ, full, result = socket.tx(ctrl, "123456", "xxx.xxx.xxx.xxx", xxxx)
  507. */
  508. static int l_socket_tx(lua_State *L)
  509. {
  510. #ifdef LUAT_USE_LWIP
  511. char ip_buf[68] = {0};
  512. luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
  513. L_CTRL_CHECK;
  514. luat_ip_addr_t ip_addr = {0};
  515. luat_zbuff_t *buff = NULL;
  516. const char *ip = NULL;
  517. const char *data = NULL;
  518. size_t ip_len = 0, data_len = 0;
  519. network_set_ip_invaild(&ip_addr);
  520. if (lua_isstring(L, 2))
  521. {
  522. data_len = 0;
  523. data = luaL_checklstring(L, 2, &data_len);
  524. }
  525. else
  526. {
  527. buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
  528. data = (const char*)buff->addr;
  529. data_len = buff->used;
  530. }
  531. if (lua_isinteger(L, 3))
  532. {
  533. network_set_ip_ipv4(&ip_addr, lua_tointeger(L, 3));
  534. }
  535. else if (lua_isstring(L, 3))
  536. {
  537. ip_len = 0;
  538. ip = luaL_checklstring(L, 3, &ip_len);
  539. memcpy(ip_buf, ip, ip_len);
  540. ip_buf[ip_len] = 0;
  541. ipaddr_aton(ip_buf, &ip_addr);
  542. }
  543. uint32_t tx_len;
  544. int result = network_tx(l_ctrl->netc, (const uint8_t *)data, data_len, luaL_optinteger(L, 5, 0), network_ip_is_vaild(&ip_addr)?&ip_addr:NULL, luaL_optinteger(L, 4, 0), &tx_len, 0);
  545. #else
  546. luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
  547. L_CTRL_CHECK;
  548. luat_ip_addr_t ip_addr = {0};
  549. luat_zbuff_t *buff = NULL;
  550. const char *ip = NULL;
  551. const char *data = NULL;
  552. size_t ip_len = 0, data_len = 0;
  553. ip_addr.is_ipv6 = 0xff;
  554. if (lua_isstring(L, 2))
  555. {
  556. data_len = 0;
  557. data = luaL_checklstring(L, 2, &data_len);
  558. }
  559. else
  560. {
  561. buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
  562. data = (const char *)buff->addr;
  563. data_len = buff->used;
  564. }
  565. if (lua_isinteger(L, 3))
  566. {
  567. ip_addr.is_ipv6 = 0;
  568. ip_addr.ipv4 = lua_tointeger(L, 3);
  569. }
  570. else if (lua_isstring(L, 3))
  571. {
  572. ip_len = 0;
  573. ip = luaL_checklstring(L, 3, &ip_len);
  574. if (network_string_is_ipv4(ip, ip_len))
  575. {
  576. ip_addr.is_ipv6 = 0;
  577. ip_addr.ipv4 = network_string_to_ipv4(ip, ip_len);
  578. }
  579. else
  580. {
  581. char *name = luat_heap_malloc(ip_len + 1);
  582. memcpy(name, ip, ip_len);
  583. name[ip_len] = 0;
  584. network_string_to_ipv6(name, &ip_addr);
  585. free(name);
  586. }
  587. }
  588. uint32_t tx_len;
  589. int result = network_tx(l_ctrl->netc, (const uint8_t *)data, data_len, luaL_optinteger(L, 5, 0), (ip_addr.is_ipv6 != 0xff)?&ip_addr:NULL, luaL_optinteger(L, 4, 0), &tx_len, 0);
  590. #endif
  591. lua_pushboolean(L, (result < 0)?0:1);
  592. lua_pushboolean(L, tx_len != data_len);
  593. lua_pushboolean(L, result == 0);
  594. return 3;
  595. }
  596. /*
  597. 接收对端发出的数据,注意数据已经缓存在底层,使用本函数只是提取出来,UDP模式下一次只会取出一个数据包
  598. @api socket.rx(ctrl, buff, flag, limit)
  599. @user_data socket.create得到的ctrl
  600. @user_data zbuff 存放接收的数据,如果缓冲区不够大会自动扩容
  601. @int 接收参数,目前预留,不起作用
  602. @int 接收数据长度限制,如果指定了,则只取前N个字节. 2024.1.5 新增
  603. @return boolean true没有异常发生,false失败了,如果false则不需要看下一个返回值了,如果false,后续要close
  604. @return int 本次接收到数据长度
  605. @return string 对端IP,只有UDP模式下才有意义,TCP模式返回nil,注意返回的格式,如果是IPV4,1byte 0x00 + 4byte地址 如果是IPV6,1byte 0x01 + 16byte地址
  606. @return int 对端port,只有UDP模式下才有意义,TCP模式返回0
  607. @usage
  608. -- 从socket中读取数据, ctrl是socket.create返回的, 请查阅demo/socket
  609. local buff = zbuff.create(2048)
  610. local succ, data_len, remote_ip, remote_port = socket.rx(ctrl, buff)
  611. -- 限制读取长度, 2024.1.5 新增
  612. -- 注意
  613. -- 如果是UDP数据, 如果limit小于UDP数据包长度, 只会取前limit个字节, 剩余数据会丢弃
  614. -- 如果是TCP数据, 如果有剩余数据, 不会丢弃, 可继续读取.
  615. -- 有新的数据到来才会有新的EVENT数据, 未读取完成的数据不会触发新EVENT事件
  616. local succ, data_len, remote_ip, remote_port = socket.rx(ctrl, buff, 1500)
  617. -- 读取缓冲区大小, 2024.1.5 新增, 注意,老版本固件不传buff参数会报错的
  618. -- 对于TCP数据, 这里返回的是待读取的数据的总长度
  619. -- 对于UDP数据, 这里返回的是单个UDP数据包的长度
  620. local succ, data_len = socket.rx(ctrl)
  621. if succ then
  622. log.info("待收取数据长度", data_len)
  623. end
  624. */
  625. static int l_socket_rx(lua_State *L)
  626. {
  627. luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
  628. L_CTRL_CHECK;
  629. luat_zbuff_t *buff = NULL;
  630. luat_ip_addr_t ip_addr = {0};
  631. uint8_t ip[17] = {0};
  632. uint16_t port = 0;
  633. // uint8_t new_flag = 0;
  634. uint32_t rx_len = 0;
  635. uint32_t total_len = 0;
  636. int result = network_rx(l_ctrl->netc, NULL, 0, 0, NULL, NULL, &total_len);
  637. if (result < 0)
  638. {
  639. lua_pushboolean(L, 0);
  640. lua_pushinteger(L, 0);
  641. return 2;
  642. }
  643. if (!total_len)
  644. {
  645. lua_pushboolean(L, 1);
  646. lua_pushinteger(L, 0);
  647. return 2;
  648. }
  649. // 是否传入的zbuff呢? 没有的话就返回值长度
  650. if (lua_isuserdata(L, 2)) {
  651. buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
  652. }
  653. else {
  654. // 仅返回长度
  655. lua_pushboolean(L, 1);
  656. lua_pushinteger(L, total_len);
  657. return 2;
  658. }
  659. // 是否限制接收数据长度
  660. if (lua_gettop(L) >= 4 && lua_isinteger(L, 4)) {
  661. uint32_t limit = lua_tointeger(L, 4);
  662. if (total_len > limit)
  663. {
  664. LLOGD("待数据数据长度 %d 限制读取长度 %d", total_len, limit);
  665. total_len = limit;
  666. }
  667. }
  668. if (1)
  669. {
  670. if ((buff->len - buff->used) < total_len)
  671. {
  672. result = __zbuff_resize(buff, total_len + buff->used);
  673. if (result < 0) {
  674. if (buff->len > buff->used) {
  675. LLOGW("zbuff自动扩容失败, 减少接收到数据长度 %d -> %d", total_len, buff->len - buff->used);
  676. total_len = buff->len - buff->used;
  677. }
  678. else {
  679. LLOGE("zbuff自动扩容失败, 且zbuff没有剩余空间,无法读取剩余数据");
  680. lua_pushboolean(L, 0);
  681. lua_pushinteger(L, 0);
  682. return 2;
  683. }
  684. }
  685. }
  686. result = network_rx(l_ctrl->netc, buff->addr + buff->used, total_len, 0, &ip_addr, &port, &rx_len);
  687. if (result < 0)
  688. {
  689. lua_pushboolean(L, 0);
  690. lua_pushinteger(L, 0);
  691. return 2;
  692. }
  693. else if (!rx_len)
  694. {
  695. lua_pushboolean(L, 1);
  696. lua_pushinteger(L, 0);
  697. return 2;
  698. }
  699. else
  700. {
  701. buff->used += rx_len;
  702. lua_pushboolean(L, 1);
  703. lua_pushinteger(L, rx_len);
  704. if (l_ctrl->netc->is_tcp)
  705. {
  706. lua_pushnil(L);
  707. lua_pushnil(L);
  708. }
  709. else
  710. {
  711. #ifdef LUAT_USE_LWIP
  712. #if LWIP_IPV6
  713. if (IPADDR_TYPE_V4 == ip_addr.type)
  714. {
  715. ip[0] = 0;
  716. memcpy(ip + 1, &ip_addr.u_addr.ip4.addr, 4);
  717. lua_pushlstring(L, (const char*)ip, 5);
  718. }
  719. else
  720. {
  721. ip[0] = 1;
  722. memcpy(ip + 1, ip_addr.u_addr.ip6.addr, 16);
  723. lua_pushlstring(L, (const char*)ip, 17);
  724. }
  725. #else
  726. ip[0] = 0;
  727. memcpy(ip + 1, &ip_addr.addr, 4);
  728. lua_pushlstring(L, (const char*)ip, 5);
  729. #endif
  730. #else
  731. if (!ip_addr.is_ipv6)
  732. {
  733. ip[0] = 0;
  734. memcpy(ip + 1, &ip_addr.ipv4, 4);
  735. lua_pushlstring(L, (const char*)ip, 5);
  736. }
  737. else
  738. {
  739. ip[0] = 1;
  740. memcpy(ip + 1, &ip_addr.ipv6_u8_addr, 16);
  741. lua_pushlstring(L, (const char*)ip, 17);
  742. }
  743. #endif
  744. lua_pushinteger(L, port);
  745. }
  746. }
  747. }
  748. return 4;
  749. }
  750. /*
  751. 读取数据(非zbuff版本)
  752. @api socket.read(netc, len)
  753. @userdata socket.create得到的ctrl
  754. @int 限制读取数据长度,可选,不传就是读出全部
  755. @return boolean 读取成功与否
  756. @return string 读取的数据,仅当读取成功时有效
  757. @return string 对方IP地址,仅当读取成功且UDP通信时有效
  758. @return int 对方端口,仅当读取成功且UDP通信时有效
  759. @usage
  760. -- 本函数于2024.4.8添加, 用于简易读取不大的数据
  761. -- 请优先使用socket.rx函数, 本函数主要用于固件不含zbuff库时的变通调用
  762. local ok, data = socket.read(netc, 1500)
  763. if ok and #data > 0 then
  764. log.info("读取到的数据", data)
  765. end
  766. */
  767. static int l_socket_read(lua_State *L) {
  768. luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
  769. L_CTRL_CHECK;
  770. luat_ip_addr_t ip_addr = {0};
  771. uint8_t ip[17] = {0};
  772. uint16_t port = 0;
  773. // uint8_t new_flag = 0;
  774. uint32_t rx_len = 0;
  775. uint32_t total_len = 0;
  776. int result = network_rx(l_ctrl->netc, NULL, 0, 0, NULL, NULL, &total_len);
  777. if (result < 0)
  778. {
  779. lua_pushboolean(L, 0);
  780. return 1;
  781. }
  782. if (!total_len)
  783. {
  784. lua_pushboolean(L, 1);
  785. lua_pushstring(L, "");
  786. return 2;
  787. }
  788. // 是否限制接收数据长度
  789. if (lua_gettop(L) >= 2 && lua_isinteger(L, 2)) {
  790. uint32_t limit = lua_tointeger(L, 2);
  791. if (limit > 0 && total_len > limit)
  792. {
  793. LLOGD("待数据数据长度 %d 限制读取长度 %d", total_len, limit);
  794. total_len = limit;
  795. }
  796. }
  797. luaL_Buffer bf = {0};
  798. char* buff = luaL_buffinitsize(L, &bf, total_len);
  799. result = network_rx(l_ctrl->netc, (uint8_t*)buff, total_len, 0, &ip_addr, &port, &rx_len);
  800. if (result < 0)
  801. {
  802. lua_pushboolean(L, 0);
  803. return 1;
  804. }
  805. else if (!rx_len)
  806. {
  807. lua_pushboolean(L, 1);
  808. lua_pushstring(L, "");
  809. return 2;
  810. }
  811. else
  812. {
  813. lua_pushboolean(L, 1);
  814. luaL_pushresultsize(&bf, rx_len);
  815. if (l_ctrl->netc->is_tcp)
  816. {
  817. return 2;
  818. }
  819. else
  820. {
  821. #ifdef LUAT_USE_LWIP
  822. #if LWIP_IPV6
  823. if (IPADDR_TYPE_V4 == ip_addr.type)
  824. {
  825. ip[0] = 0;
  826. memcpy(ip + 1, &ip_addr.u_addr.ip4.addr, 4);
  827. lua_pushlstring(L, (const char*)ip, 5);
  828. }
  829. else
  830. {
  831. ip[0] = 1;
  832. memcpy(ip + 1, ip_addr.u_addr.ip6.addr, 16);
  833. lua_pushlstring(L, (const char*)ip, 17);
  834. }
  835. #else
  836. ip[0] = 0;
  837. memcpy(ip + 1, &ip_addr.addr, 4);
  838. lua_pushlstring(L, (const char*)ip, 5);
  839. #endif
  840. #else
  841. if (!ip_addr.is_ipv6)
  842. {
  843. ip[0] = 0;
  844. memcpy(ip + 1, &ip_addr.ipv4, 4);
  845. lua_pushlstring(L, (const char*)ip, 5);
  846. }
  847. else
  848. {
  849. ip[0] = 1;
  850. memcpy(ip + 1, &ip_addr.ipv6_u8_addr, 16);
  851. lua_pushlstring(L, (const char*)ip, 17);
  852. }
  853. #endif
  854. lua_pushinteger(L, port);
  855. return 4;
  856. }
  857. }
  858. }
  859. /*
  860. 等待新的socket消息,在连接成功和发送数据成功后,使用一次将network状态转换到接收新数据
  861. @api socket.wait(ctrl)
  862. @user_data socket.create得到的ctrl
  863. @return boolean true没有异常发生,false失败了,如果false则不需要看下一个返回值了,如果false,后续要close
  864. @return boolean true有新的数据需要接收,false没有数据,之后需要接收socket.EVENT消息
  865. @usage
  866. local succ, result = socket.wait(ctrl)
  867. */
  868. static int l_socket_wait(lua_State *L)
  869. {
  870. luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
  871. L_CTRL_CHECK;
  872. int result = network_wait_event(l_ctrl->netc, NULL, 0, NULL);
  873. lua_pushboolean(L, (result < 0)?0:1);
  874. lua_pushboolean(L, result == 0);
  875. return 2;
  876. }
  877. /*
  878. 作为服务端开始监听
  879. @api socket.listen(ctrl)
  880. @user_data socket.create得到的ctrl
  881. @return boolean true没有异常发生,false失败了,如果false则不需要看下一个返回值了,如果false,后续要close
  882. @return boolean true已经connect,false没有connect,之后需要接收socket.ON_LINE消息
  883. @usage
  884. local succ, result = socket.listen(ctrl)
  885. */
  886. static int l_socket_listen(lua_State *L)
  887. {
  888. luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
  889. L_CTRL_CHECK;
  890. int result = network_listen(l_ctrl->netc, 0);
  891. lua_pushboolean(L, (result < 0)?0:1);
  892. lua_pushboolean(L, result == 0);
  893. return 2;
  894. }
  895. /*
  896. 作为服务端接收到一个新的客户端,注意,如果是类似W5500的硬件协议栈不支持1对多,则不需要第二个参数
  897. @api socket.accept(ctrl)
  898. @user_data socket.create得到的ctrl,这里是服务器端
  899. @string or function or nil string为消息通知的taskName,function则为回调函数,和socket.create参数一致
  900. @return boolean true没有异常发生,false失败了,如果false则不需要看下一个返回值了,如果false,后续要close
  901. @return user_data or nil 如果支持1对多,则会返回新的ctrl,自动create,如果不支持则返回nil
  902. @usage
  903. local succ, new_netc = socket.listen(ctrl, cb)
  904. */
  905. static int l_socket_accept(lua_State *L)
  906. {
  907. luat_socket_ctrl_t *old_ctrl = l_get_ctrl(L, 1);
  908. if (!old_ctrl) return 0;
  909. if (network_accept_enable(old_ctrl->netc))
  910. {
  911. luat_socket_ctrl_t *new_ctrl = (luat_socket_ctrl_t *)lua_newuserdata(L, sizeof(luat_socket_ctrl_t));
  912. if (!new_ctrl)
  913. {
  914. lua_pushboolean(L, 0);
  915. lua_pushnil(L);
  916. return 2;
  917. }
  918. new_ctrl->adapter_index = old_ctrl->adapter_index;
  919. new_ctrl->netc = network_alloc_ctrl(old_ctrl->adapter_index);
  920. if (!new_ctrl->netc)
  921. {
  922. LLOGD("create fail");
  923. lua_pushboolean(L, 0);
  924. lua_pushnil(L);
  925. return 2;
  926. }
  927. network_init_ctrl(new_ctrl->netc, NULL, luat_lib_socket_callback, new_ctrl);
  928. if (lua_isfunction(L, 2))
  929. {
  930. lua_pushvalue(L, 2);
  931. new_ctrl->cb_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  932. new_ctrl->task_name = NULL;
  933. }
  934. else if (lua_isstring(L, 2))
  935. {
  936. new_ctrl->cb_ref = 0;
  937. size_t len;
  938. const char *buf;
  939. buf = lua_tolstring(L, 2, &len);//取出字符串数据
  940. new_ctrl->task_name = luat_heap_malloc(len + 1);
  941. memset(new_ctrl->task_name, 0, len + 1);
  942. memcpy(new_ctrl->task_name, buf, len);
  943. }
  944. if (network_socket_accept(old_ctrl, new_ctrl))
  945. {
  946. lua_pushboolean(L, 0);
  947. lua_pushnil(L);
  948. return 2;
  949. }
  950. else
  951. {
  952. lua_pushboolean(L, 1);
  953. luaL_setmetatable(L, LUAT_NW_CTRL_TYPE);
  954. return 2;
  955. }
  956. }
  957. else
  958. {
  959. lua_pushboolean(L, !network_socket_accept(old_ctrl->netc, NULL));
  960. lua_pushnil(L);
  961. return 2;
  962. }
  963. }
  964. /*
  965. 获取socket当前状态
  966. @api socket.state(ctrl)
  967. @user_data socket.create得到的ctrl
  968. @return int or nil,输入参数正确的情况下,返回状态的数值,否则返回nil
  969. @return string or nil,输入参数正确的情况下,返回状态的中文描述,否则返回nil
  970. @usage
  971. local state, str = socket.state(ctrl)
  972. log.info("state", state, str)
  973. state 0 "硬件离线",
  974. 1 "离线",
  975. 2 "等待DNS",
  976. 3 "正在连接",
  977. 4 "正在TLS握手",
  978. 5 "在线",
  979. 6 "在监听",
  980. 7 "正在离线",
  981. 8 "未知"
  982. */
  983. static int l_socket_state(lua_State *L)
  984. {
  985. luat_socket_ctrl_t *l_ctrl = l_get_ctrl(L, 1);
  986. L_CTRL_CHECK;
  987. lua_pushinteger(L, l_ctrl->netc->state);
  988. lua_pushstring(L, network_ctrl_state_string(l_ctrl->netc->state));
  989. return 2;
  990. }
  991. /*
  992. 主动释放掉network_ctrl
  993. @api socket.release(ctrl)
  994. @user_data socket.create得到的ctrl
  995. @usage
  996. -- 释放后就不能再使用了
  997. socket.release(ctrl)
  998. */
  999. static int l_socket_release(lua_State *L)
  1000. {
  1001. return l_socket_gc(L);
  1002. }
  1003. /*
  1004. 设置DNS服务器
  1005. @api socket.setDNS(adapter_index, dns_index, ip)
  1006. @int 适配器序号, 只能是socket.ETH0,socket.STA,socket.AP,如果不填,会选择最后一个注册的适配器
  1007. @int dns服务器序号,从1开始
  1008. @string or int dns,如果是IPV4,可以是大端格式的int值
  1009. @return boolean 成功返回true,失败返回false
  1010. @usage
  1011. -- 设置默认网络适配器的DNS配置
  1012. socket.setDNS(nil, 1, "114.114.114.114")
  1013. -- 设置制定网络适配器的DNS配置
  1014. socket.setDNS(socket.ETH0, 1, "114.114.114.114")
  1015. */
  1016. static int l_socket_set_dns(lua_State *L)
  1017. {
  1018. #ifdef LUAT_USE_LWIP
  1019. char ip_buf[68];
  1020. int adapter_index = luaL_optinteger(L, 1, network_get_last_register_adapter());
  1021. if (adapter_index < 0 || adapter_index >= NW_ADAPTER_QTY)
  1022. {
  1023. lua_pushboolean(L, 0);
  1024. return 1;
  1025. }
  1026. int dns_index = luaL_optinteger(L, 2, 1);
  1027. luat_ip_addr_t ip_addr;
  1028. const char *ip;
  1029. size_t ip_len;
  1030. network_set_ip_invaild(&ip_addr);
  1031. if (lua_isinteger(L, 3))
  1032. {
  1033. network_set_ip_ipv4(&ip_addr, lua_tointeger(L, 3));
  1034. ip = NULL;
  1035. ip_len = 0;
  1036. }
  1037. else
  1038. {
  1039. ip_len = 0;
  1040. ip = luaL_checklstring(L, 3, &ip_len);
  1041. memcpy(ip_buf, ip, ip_len);
  1042. ip_buf[ip_len] = 0;
  1043. ipaddr_aton(ip_buf, &ip_addr);
  1044. }
  1045. #else
  1046. int adapter_index = luaL_optinteger(L, 1, network_get_last_register_adapter());
  1047. if (adapter_index < 0 || adapter_index >= NW_ADAPTER_QTY)
  1048. {
  1049. lua_pushboolean(L, 0);
  1050. return 1;
  1051. }
  1052. int dns_index = luaL_optinteger(L, 2, 1);
  1053. luat_ip_addr_t ip_addr;
  1054. const char *ip;
  1055. size_t ip_len;
  1056. ip_addr.is_ipv6 = 0xff;
  1057. if (lua_isinteger(L, 3))
  1058. {
  1059. ip_addr.is_ipv6 = 0;
  1060. ip_addr.ipv4 = lua_tointeger(L, 3);
  1061. ip = NULL;
  1062. ip_len = 0;
  1063. }
  1064. else
  1065. {
  1066. ip_len = 0;
  1067. ip = luaL_checklstring(L, 3, &ip_len);
  1068. ip_addr.is_ipv6 = !network_string_is_ipv4(ip, ip_len);
  1069. if (ip_addr.is_ipv6)
  1070. {
  1071. char *temp = luat_heap_malloc(ip_len + 1);
  1072. memcpy(temp, ip, ip_len);
  1073. temp[ip_len] = 0;
  1074. network_string_to_ipv6(temp, &ip_addr);
  1075. luat_heap_free(temp);
  1076. }
  1077. else
  1078. {
  1079. ip_addr.ipv4 = network_string_to_ipv4(ip, ip_len);
  1080. }
  1081. }
  1082. #endif
  1083. network_set_dns_server(adapter_index, dns_index - 1, &ip_addr);
  1084. lua_pushboolean(L, 1);
  1085. return 1;
  1086. }
  1087. /*
  1088. 设置SSL的log登记
  1089. @api socket.sslLog(log_level)
  1090. @int mbedtls log等级
  1091. @return nil 无返回值
  1092. @usage
  1093. --[[
  1094. SSL/TLS log级别说明
  1095. 0不打印
  1096. 1只打印错误和警
  1097. 2大部分info
  1098. 3及3以上详细的debug
  1099. 过多的信息可能会造成内存碎片化
  1100. ]]
  1101. -- 打印大部分info日志
  1102. socket.sslLog(2)
  1103. */
  1104. static int l_socket_set_ssl_log(lua_State *L)
  1105. {
  1106. #if defined(MBEDTLS_DEBUG_C)
  1107. mbedtls_debug_set_threshold(luaL_optinteger(L, 1, 1));
  1108. #endif
  1109. return 0;
  1110. }
  1111. #ifdef LUAT_USE_SNTP
  1112. #include "luat_sntp.h"
  1113. #endif
  1114. /*
  1115. 查看网卡适配器的联网状态
  1116. @api socket.adapter(index)
  1117. @int 需要查看的适配器序号,可以留空会查看全部网卡,直到遇到IP READY的,如果指定网卡,只能是socket.ETH0(外置以太网),socket.LWIP_ETH(内置以太网),socket.LWIP_STA(内置WIFI的STA),socket.LWIP_AP(内置WIFI的AP),socket.LWIP_GP(内置蜂窝网络的GPRS),socket.USB(外置USB网卡)
  1118. @return boolean 被查看的适配器是否IP READY,true表示已经准备好可以联网了,false暂时不可以联网
  1119. @return int 最后一个被查看的适配器序号
  1120. @usage
  1121. -- 查看全部网卡,直到找到一个是IP READY的
  1122. local isReady,index = socket.adapter() --如果isReady为true,则index为IP READY的网卡适配器序号
  1123. --查看外置以太网(比如W5500)是否IP READY
  1124. local isReady,default = socket.adapter(socket.ETH0)
  1125. */
  1126. static int l_socket_adapter(lua_State *L)
  1127. {
  1128. int adapter_index = luaL_optinteger(L, 1, -1);
  1129. if (adapter_index > NW_ADAPTER_INDEX_LWIP_NONE && adapter_index < NW_ADAPTER_QTY)
  1130. {
  1131. lua_pushboolean(L, network_check_ready(NULL, adapter_index));
  1132. lua_pushinteger(L, adapter_index);
  1133. }
  1134. else
  1135. {
  1136. for(int i = NW_ADAPTER_INDEX_LWIP_GPRS; i < NW_ADAPTER_QTY; i++)
  1137. {
  1138. if (network_check_ready(NULL, i))
  1139. {
  1140. lua_pushboolean(L, 1);
  1141. lua_pushinteger(L, i);
  1142. return 2;
  1143. }
  1144. }
  1145. lua_pushboolean(L, 0);
  1146. lua_pushinteger(L, NW_ADAPTER_QTY - 1);
  1147. }
  1148. return 2;
  1149. }
  1150. /*
  1151. 获取对端ip
  1152. @api socket.remoteIP(ctrl)
  1153. @user_data socket.create得到的ctrl
  1154. @return string IP1,如果为nil,则表示没有获取到IP地址
  1155. @return string IP2,如果为nil,则表示没有IP2
  1156. @return string IP3,如果为nil,则表示没有IP3
  1157. @return string IP4,如果为nil,则表示没有IP4
  1158. @usage
  1159. -- 注意: ,必须在接收到socket.ON_LINE消息之后才可能获取到,最多返回4个IP。
  1160. -- socket.connect里如果remote_port设置成0,则当DNS完成时就返回socket.ON_LINE消息
  1161. local ip1,ip2,ip3,ip4 = socket.remoteIP(ctrl)
  1162. */
  1163. static int l_socket_remote_ip(lua_State *L)
  1164. {
  1165. luat_socket_ctrl_t *ctrl = l_get_ctrl(L, 1);
  1166. PV_Union uPV;
  1167. uint8_t i;
  1168. uint8_t total;
  1169. if (!ctrl)
  1170. {
  1171. goto NO_REMOTE_IP;
  1172. }
  1173. if (!ctrl->netc->dns_ip_nums || !ctrl->netc->dns_ip)
  1174. {
  1175. goto NO_REMOTE_IP;
  1176. }
  1177. total = (ctrl->netc->dns_ip_nums > 4)?4:ctrl->netc->dns_ip_nums;
  1178. for(i = 0; i < total; i++)
  1179. {
  1180. #ifdef LUAT_USE_LWIP
  1181. lua_pushfstring(L, "%s", ipaddr_ntoa(&ctrl->netc->dns_ip[i].ip));
  1182. #else
  1183. uPV.u32 = &ctrl->netc->dns_ip[i].ip.ipv4;
  1184. lua_pushfstring(L, "%d.%d.%d.%d", uPV.u8[0], uPV.u8[1], uPV.u8[2], uPV.u8[3]);
  1185. #endif
  1186. }
  1187. if (total < 4)
  1188. {
  1189. for(i = total; i < 4; i++)
  1190. {
  1191. lua_pushnil(L);
  1192. }
  1193. }
  1194. return 4;
  1195. NO_REMOTE_IP:
  1196. lua_pushnil(L);
  1197. lua_pushnil(L);
  1198. lua_pushnil(L);
  1199. lua_pushnil(L);
  1200. return 4;
  1201. }
  1202. #include "rotable2.h"
  1203. static const rotable_Reg_t reg_socket_adapter[] =
  1204. {
  1205. {"create", ROREG_FUNC(l_socket_create)},
  1206. {"debug", ROREG_FUNC(l_socket_set_debug)},
  1207. {"config", ROREG_FUNC(l_socket_config)},
  1208. {"linkup", ROREG_FUNC(l_socket_linkup)},
  1209. {"connect", ROREG_FUNC(l_socket_connect)},
  1210. {"listen", ROREG_FUNC(l_socket_listen)},
  1211. {"accept", ROREG_FUNC(l_socket_accept)},
  1212. {"discon", ROREG_FUNC(l_socket_disconnect)},
  1213. {"close", ROREG_FUNC(l_socket_close)},
  1214. {"tx", ROREG_FUNC(l_socket_tx)},
  1215. {"rx", ROREG_FUNC(l_socket_rx)},
  1216. {"read", ROREG_FUNC(l_socket_read)},
  1217. {"wait", ROREG_FUNC(l_socket_wait)},
  1218. {"state", ROREG_FUNC(l_socket_state)},
  1219. {"release", ROREG_FUNC(l_socket_release)},
  1220. { "setDNS", ROREG_FUNC(l_socket_set_dns)},
  1221. { "sslLog", ROREG_FUNC(l_socket_set_ssl_log)},
  1222. {"localIP", ROREG_FUNC(l_socket_local_ip)},
  1223. {"remoteIP", ROREG_FUNC(l_socket_remote_ip)},
  1224. {"adapter", ROREG_FUNC(l_socket_adapter)},
  1225. #ifdef LUAT_USE_SNTP
  1226. {"sntp", ROREG_FUNC(l_sntp_get)},
  1227. {"ntptm", ROREG_FUNC(l_sntp_tm)},
  1228. #endif
  1229. //@const ETH0 number 带硬件协议栈的ETH0,值为5
  1230. { "ETH0", ROREG_INT(NW_ADAPTER_INDEX_ETH0)},
  1231. //@const LWIP_ETH number 使用LWIP协议栈的以太网卡,值为4
  1232. { "LWIP_ETH", ROREG_INT(NW_ADAPTER_INDEX_LWIP_ETH)},
  1233. //@const LWIP_STA number 使用LWIP协议栈的WIFI STA,值为2
  1234. { "LWIP_STA", ROREG_INT(NW_ADAPTER_INDEX_LWIP_WIFI_STA)},
  1235. //@const LWIP_AP number 使用LWIP协议栈的WIFI AP,值为3
  1236. { "LWIP_AP", ROREG_INT(NW_ADAPTER_INDEX_LWIP_WIFI_AP)},
  1237. //@const LWIP_GP number 使用LWIP协议栈的移动蜂窝模块,值为1
  1238. { "LWIP_GP", ROREG_INT(NW_ADAPTER_INDEX_LWIP_GPRS)},
  1239. //@const USB number 使用LWIP协议栈的USB网卡,值为6
  1240. { "USB", ROREG_INT(NW_ADAPTER_INDEX_USB)},
  1241. //@const LINK number LINK事件
  1242. { "LINK", ROREG_INT(EV_NW_RESULT_LINK & 0x0fffffff)},
  1243. //@const ON_LINE number ON_LINE事件
  1244. { "ON_LINE", ROREG_INT(EV_NW_RESULT_CONNECT & 0x0fffffff)},
  1245. //@const EVENT number EVENT事件
  1246. { "EVENT", ROREG_INT(EV_NW_RESULT_EVENT & 0x0fffffff)},
  1247. //@const TX_OK number TX_OK事件
  1248. { "TX_OK", ROREG_INT(EV_NW_RESULT_TX & 0x0fffffff)},
  1249. //@const CLOSED number CLOSED事件
  1250. { "CLOSED", ROREG_INT(EV_NW_RESULT_CLOSE & 0x0fffffff)},
  1251. { NULL, ROREG_INT(0)}
  1252. };
  1253. LUAMOD_API int luaopen_socket_adapter( lua_State *L ) {
  1254. luat_newlib2(L, reg_socket_adapter);
  1255. luaL_newmetatable(L, LUAT_NW_CTRL_TYPE); /* create metatable for file handles */
  1256. lua_pushcfunction(L, l_socket_gc);
  1257. lua_setfield(L, -2, "__gc");
  1258. lua_pop(L, 1); /* pop new metatable */
  1259. return 1;
  1260. }
  1261. // #endif