luat_network_posix.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. #include "luat_base.h"
  2. #include "luat_network_adapter.h"
  3. #include "luat_mem.h"
  4. #include "luat_msgbus.h"
  5. #include "luat_crypto.h"
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <errno.h>
  9. #include <netdb.h>
  10. #include <signal.h>
  11. #include <fcntl.h>
  12. #include <sys/select.h>
  13. #define LUAT_LOG_TAG "network"
  14. #include "luat_log.h"
  15. #include "luat_network_posix.h"
  16. CBFuncEx_t posix_network_cb;
  17. void * posix_network_param;
  18. uint8_t posix_network_ready;
  19. static luat_rtos_mutex_t* master_lock;
  20. static void posix_send_event(int id, int p1, int p2, int p3) {
  21. luat_network_cb_param_t params = {0};
  22. params.tag = 0;
  23. params.param = posix_network_param;
  24. // 触发一下回调
  25. // if (ready) {
  26. OS_EVENT event = {
  27. .ID = id,
  28. .Param1 = p1,
  29. .Param2 = p2,
  30. .Param3 = p3
  31. };
  32. LLOGD("posix event %d %d %d %d", id, p1, p2, p3);
  33. posix_network_cb(&event, &params);
  34. }
  35. void posix_network_client_thread_entry(posix_socket_t *ps) {
  36. luat_network_cb_param_t params = {0};
  37. params.tag = 0;
  38. params.param = posix_network_param;
  39. // 触发一下回调
  40. // if (ready) {
  41. OS_EVENT event = {0};
  42. struct sockaddr_in sockaddr = {0};
  43. sockaddr.sin_family = AF_INET;
  44. sockaddr.sin_port = htons(ps->remote_port);
  45. sockaddr.sin_addr.s_addr = ps->remote_ip.ipv4;
  46. luat_rtos_task_sleep(50);
  47. LLOGD("ready to connect %d", ps->socket_id);
  48. int ret = connect(ps->socket_id, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
  49. LLOGD("connect ret %d", ret);
  50. if (ret) {
  51. // 失败了
  52. LLOGD("connect FAIL ret %d", ret);
  53. posix_send_event(EV_NW_SOCKET_ERROR, ps->socket_id, 0, 0);
  54. luat_heap_free(ps);
  55. return;
  56. }
  57. // 发送系统消息, 通知连接成功
  58. posix_send_event(EV_NW_SOCKET_CONNECT_OK, ps->socket_id, 0, 0);
  59. LLOGD("wait data now");
  60. fd_set readfds;
  61. fd_set writefds;
  62. fd_set errorfds;
  63. int maxsock;
  64. struct timeval tv;
  65. maxsock = ps->socket_id;
  66. // timeout setting
  67. tv.tv_sec = 0;
  68. tv.tv_usec = 3000; //暂时3ms吧
  69. while (1) {
  70. // initialize file descriptor set
  71. FD_ZERO(&readfds);
  72. // FD_ZERO(&writefds);
  73. FD_ZERO(&errorfds);
  74. FD_SET(ps->socket_id, &readfds);
  75. // FD_SET(ps->socket_id, &writefds);
  76. FD_SET(ps->socket_id, &errorfds);
  77. if (master_lock)
  78. if (luat_rtos_mutex_lock(master_lock, 100))
  79. continue;
  80. ret = select(maxsock + 1, &readfds, NULL, &errorfds, &tv);
  81. if (master_lock)
  82. luat_rtos_mutex_unlock(master_lock);
  83. if (ret < 0) {
  84. LLOGE("select ret %d", ret);
  85. break;
  86. } else if (ret == 0) {
  87. //printf("select timeout\n");
  88. continue;
  89. }
  90. if (FD_ISSET(maxsock, &readfds)) {
  91. // 发消息,可读了
  92. }
  93. // if (FD_ISSET(maxsock, &writefds)) {
  94. // // 发消息,发送完成了??
  95. // }
  96. if (FD_ISSET(maxsock, &errorfds)) {
  97. // 发消息,出错了
  98. break;
  99. }
  100. }
  101. luat_heap_free(ps);
  102. LLOGI("socket thread exit");
  103. }
  104. void posix_network_set_ready(uint8_t ready) {
  105. LLOGD("CALL posix_network_set_ready");
  106. posix_network_ready = ready;
  107. luat_network_cb_param_t params = {0};
  108. params.tag = 0;
  109. params.param = posix_network_param;
  110. // 触发一下回调
  111. // if (ready) {
  112. OS_EVENT event = {
  113. .ID = EV_NW_STATE,
  114. .Param1 = 0,
  115. .Param2 = ready,
  116. .Param3 = 0
  117. };
  118. posix_network_cb(&event, &params);
  119. // }
  120. }
  121. //检查网络是否准备好,返回非0准备好,user_data是注册时的user_data,传入给底层api
  122. uint8_t (posix_check_ready)(void *user_data) {
  123. LLOGD("CALL posix_check_ready %d", posix_network_ready);
  124. return posix_network_ready;
  125. };
  126. //创建一个socket,并设置成非阻塞模式,user_data传入对应适配器, tag作为socket的合法依据,给check_socket_vaild比对用
  127. //成功返回socketid,失败 < 0
  128. int (posix_create_socket)(uint8_t is_tcp, uint64_t *tag, void *param, uint8_t is_ipv6, void *user_data) {
  129. // TODO 支持IPV6
  130. int s = socket(AF_INET, is_tcp ? SOCK_STREAM : SOCK_DGRAM, is_tcp ? IPPROTO_TCP : IPPROTO_UDP);
  131. LLOGD("CALL posix_create_socket %d %d", s, is_tcp);
  132. return s;
  133. }
  134. //作为client绑定一个port,并连接remote_ip和remote_port对应的server
  135. //成功返回0,失败 < 0
  136. int (posix_socket_connect)(int socket_id, uint64_t tag, uint16_t local_port, luat_ip_addr_t *remote_ip, uint16_t remote_port, void *user_data) {
  137. LLOGD("CALL posix_socket_connect %d", socket_id);
  138. posix_socket_t *ps = luat_heap_malloc(sizeof(posix_socket_t));
  139. if (ps == NULL) {
  140. LLOGE("out of memory when malloc posix_socket_t");
  141. return -1;
  142. }
  143. ps->socket_id = socket_id;
  144. ps->tag = tag;
  145. ps->local_port = local_port;
  146. memcpy(&ps->remote_ip, remote_ip, sizeof(luat_ip_addr_t));
  147. ps->remote_port = remote_port;
  148. ps->user_data = user_data;
  149. int ret = network_posix_client_thread_start(ps);
  150. LLOGD("socket thread start %d", ret);
  151. if (ret) {
  152. luat_heap_free(ps);
  153. }
  154. return ret;
  155. }
  156. //作为server绑定一个port,开始监听
  157. //成功返回0,失败 < 0
  158. int (posix_socket_listen)(int socket_id, uint64_t tag, uint16_t local_port, void *user_data) {
  159. // 尚未支持
  160. return -1;
  161. }
  162. //作为server接受一个client
  163. //成功返回0,失败 < 0
  164. int (posix_socket_accept)(int socket_id, uint64_t tag, luat_ip_addr_t *remote_ip, uint16_t *remote_port, void *user_data) {
  165. // 尚未支持
  166. return -1;
  167. }
  168. //主动断开一个tcp连接,需要走完整个tcp流程,用户需要接收到close ok回调才能确认彻底断开
  169. //成功返回0,失败 < 0
  170. int (posix_socket_disconnect)(int socket_id, uint64_t tag, void *user_data) {
  171. return close(socket_id);
  172. }
  173. //释放掉socket的控制权,除了tag异常外,必须立刻生效
  174. //成功返回0,失败 < 0
  175. int (posix_socket_close)(int socket_id, uint64_t tag, void *user_data) {
  176. return close(socket_id);
  177. }
  178. //强行释放掉socket的控制权,必须立刻生效
  179. //成功返回0,失败 < 0
  180. int (posix_socket_force_close)(int socket_id, void *user_data) {
  181. return close(socket_id);
  182. }
  183. //tcp时,不需要remote_ip和remote_port,如果buf为NULL,则返回当前缓存区的数据量,当返回值小于len时说明已经读完了
  184. //udp时,只返回1个block数据,需要多次读直到没有数据为止
  185. //成功返回实际读取的值,失败 < 0
  186. int (posix_socket_receive)(int socket_id, uint64_t tag, uint8_t *buf, uint32_t len, int flags, luat_ip_addr_t *remote_ip, uint16_t *remote_port, void *user_data) {
  187. struct timeval tv;
  188. tv.tv_sec = 0;
  189. tv.tv_usec = 1000; //暂时1ms吧
  190. setsockopt(socket_id, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
  191. if (master_lock)
  192. if (luat_rtos_mutex_lock(master_lock, 100))
  193. return -1;
  194. int ret = recv(socket_id, buf, len, flags);
  195. if (master_lock)
  196. luat_rtos_mutex_unlock(master_lock);
  197. return ret;
  198. }
  199. //tcp时,不需要remote_ip和remote_port
  200. //成功返回>0的len,缓冲区满了=0,失败 < 0,如果发送了len=0的空包,也是返回0,注意判断
  201. int (posix_socket_send)(int socket_id, uint64_t tag, const uint8_t *buf, uint32_t len, int flags, luat_ip_addr_t *remote_ip, uint16_t remote_port, void *user_data) {
  202. struct timeval tv;
  203. tv.tv_sec = 0;
  204. tv.tv_usec = 1000; //暂时1ms吧
  205. setsockopt(socket_id, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
  206. if (master_lock)
  207. if (luat_rtos_mutex_lock(master_lock, 100))
  208. return -1;
  209. int ret = send(socket_id, buf, len, flags);
  210. if (master_lock)
  211. luat_rtos_mutex_unlock(master_lock);
  212. return ret;
  213. }
  214. //检查socket合法性,成功返回0,失败 < 0
  215. int (posix_socket_check)(int socket_id, uint64_t tag, void *user_data) {
  216. // TODO 通过select errorfds?
  217. LLOGD("CALL posix_socket_check %d %lld", socket_id, tag);
  218. return 0;
  219. }
  220. //保留有效的socket,将无效的socket关闭
  221. void (posix_socket_clean)(int *vaild_socket_list, uint32_t num, void *user_data) {
  222. }
  223. int (posix_getsockopt)(int socket_id, uint64_t tag, int level, int optname, void *optval, uint32_t *optlen, void *user_data) {
  224. return getsockopt(socket_id, level, optname, optval, optlen);
  225. }
  226. int (posix_setsockopt)(int socket_id, uint64_t tag, int level, int optname, const void *optval, uint32_t optlen, void *user_data) {
  227. return setsockopt(socket_id, level, optname, optval, optlen);
  228. }
  229. //非posix的socket,用这个根据实际硬件设置参数
  230. int (posix_user_cmd)(int socket_id, uint64_t tag, uint32_t cmd, uint32_t value, void *user_data) {
  231. return 0; // 没有这些东西
  232. }
  233. int (posix_dns)(const char *domain_name, uint32_t len, void *param, void *user_data) {
  234. LLOGD("CALL posix_dns %.*s", len, domain_name);
  235. return -1; // 暂不支持DNS
  236. }
  237. int (posix_set_dns_server)(uint8_t server_index, luat_ip_addr_t *ip, void *user_data) {
  238. return 0; // 暂不支持设置DNS
  239. }
  240. #ifdef LUAT_USE_LWIP
  241. int (posix_set_mac)(uint8_t *mac, void *user_data);
  242. int (posix_set_static_ip)(luat_ip_addr_t *ip, luat_ip_addr_t *submask, luat_ip_addr_t *gateway, luat_ip_addr_t *ipv6, void *user_data);
  243. #endif
  244. int (posix_get_local_ip_info)(luat_ip_addr_t *ip, luat_ip_addr_t *submask, luat_ip_addr_t *gateway, void *user_data) {
  245. ip->ipv4 = 0;
  246. submask->ipv4 = 0;
  247. gateway->ipv4 = 0;
  248. return 0;
  249. }
  250. //所有网络消息都是通过cb_fun回调
  251. //cb_fun回调时第一个参数为OS_EVENT,包含了socket的必要信息,第二个是luat_network_cb_param_t,其中的param是这里传入的param(就是适配器序号)
  252. //OS_EVENT ID为EV_NW_XXX,param1是socket id param2是各自参数 param3是create_soceket传入的socket_param(就是network_ctrl *)
  253. //dns结果是特别的,ID为EV_NW_SOCKET_DNS_RESULT,param1是获取到的IP数据量,0就是失败了,param2是ip组,动态分配的, param3是dns传入的param(就是network_ctrl *)
  254. void (posix_socket_set_callback)(CBFuncEx_t cb_fun, void *param, void *user_data) {
  255. LLOGD("call posix_socket_set_callback %p %p", cb_fun, param);
  256. if (master_lock == NULL)
  257. luat_rtos_mutex_create(master_lock);
  258. posix_network_cb = cb_fun;
  259. posix_network_param = param;
  260. }
  261. network_adapter_info network_posix = {
  262. .check_ready = posix_check_ready,
  263. .create_soceket = posix_create_socket,
  264. .socket_connect = posix_socket_connect,
  265. .socket_accept = posix_socket_accept,
  266. .socket_disconnect = posix_socket_disconnect,
  267. .socket_close = posix_socket_close,
  268. .socket_force_close = posix_socket_force_close,
  269. .socket_receive = posix_socket_receive,
  270. .socket_send = posix_socket_send,
  271. .socket_clean = posix_socket_clean,
  272. .getsockopt = posix_getsockopt,
  273. .setsockopt = posix_setsockopt,
  274. .user_cmd = posix_user_cmd,
  275. .dns = posix_dns,
  276. .set_dns_server = posix_set_dns_server,
  277. .get_local_ip_info = posix_get_local_ip_info,
  278. .socket_set_callback = posix_socket_set_callback,
  279. .name = "posix",
  280. .max_socket_num = 4,
  281. .no_accept = 1, // 暂时不支持接收
  282. .is_posix = 1,
  283. };