iot_netcfg.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*
  2. * Copyright (c) 2021 Huawei Device Co., Ltd.
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #include <unistd.h>
  16. #include "errno.h"
  17. #include "cmsis_os2.h"
  18. #include "sys/time.h"
  19. #include "sys/socket.h"
  20. #include "netinet/in.h"
  21. #include "lwip/inet.h"
  22. #include "lwip/netdb.h"
  23. #include "cJSON.h"
  24. #include "ohos_types.h"
  25. #include "iot_softap.h"
  26. #include "iot_netcfg.h"
  27. #include "iot_demo_def.h"
  28. #define SSID_MAX_LEN 32
  29. #define PWD_MAX_LEN 32
  30. #define NET_PORT 8686
  31. #define RETRY_TIMES 5
  32. #define CONNECT_TIMEOUT 20
  33. #define CMD_KEY "cmd"
  34. #define PAR_KEY "param"
  35. #define SID_KEY "wifiName"
  36. #define PWD_KEY "wifiPassword"
  37. #define CMD_CONFIG 0x20
  38. #define REQUEST_STR "{\"cmd\":32,\"code\":200,\"msg\":\"\"}"
  39. static int ParseWifiInfo(const char *psr, char *ssid, int sl, char *pwd, int pl)
  40. {
  41. cJSON *json;
  42. cJSON *sub;
  43. cJSON *obj;
  44. int cmd;
  45. char *ps = NULL;
  46. char *pw = NULL;
  47. json = cJSON_Parse(psr);
  48. RaiseLog(LOG_LEVEL_ERR, "parse_json: %s\n", psr);
  49. if (json == NULL) {
  50. RaiseLog(LOG_LEVEL_ERR, "parse_json: %s\n", psr);
  51. return -1;
  52. }
  53. sub = cJSON_GetObjectItem(json, CMD_KEY);
  54. cmd = cJSON_GetNumberValue(sub);
  55. if (cmd != CMD_CONFIG) {
  56. RaiseLog(LOG_LEVEL_ERR, "CMD TYPE FAILED! cmd=%d \n", cmd);
  57. cJSON_Delete(json);
  58. return -1;
  59. }
  60. sub = cJSON_GetObjectItem(json, PAR_KEY);
  61. if (sub == NULL) {
  62. RaiseLog(LOG_LEVEL_ERR, "get param obj failed! \n");
  63. cJSON_Delete(json);
  64. return -1;
  65. }
  66. obj = cJSON_GetObjectItem(sub, SID_KEY);
  67. ps = cJSON_GetStringValue(obj);
  68. if (ps == NULL) {
  69. RaiseLog(LOG_LEVEL_ERR, "get ssid failed! \n");
  70. cJSON_Delete(json);
  71. return -1;
  72. }
  73. if (strncpy_s(ssid, sl, ps, strlen(ps)) < 0) {
  74. RaiseLog(LOG_LEVEL_ERR, "strncpy_s failed! \n");
  75. cJSON_Delete(json);
  76. return -1;
  77. }
  78. obj = cJSON_GetObjectItem(sub, PWD_KEY);
  79. pw = cJSON_GetStringValue(obj);
  80. if (pw != NULL) {
  81. RaiseLog(LOG_LEVEL_INFO, "pw=%s\n", pw);
  82. if (strncpy_s(pwd, pl, pw, strlen(pw)) < 0) {
  83. RaiseLog(LOG_LEVEL_ERR, "strncpy_s failed! \n");
  84. cJSON_Delete(json);
  85. return -1;
  86. }
  87. }
  88. cJSON_Delete(json);
  89. return 0;
  90. }
  91. static int NetCfgGetSocketValue(int sockfd, char *ssid, int sLen, char *pwd, int pLen)
  92. {
  93. int result = -1;
  94. if (sockfd < 0) {
  95. RaiseLog(LOG_LEVEL_ERR, "sockfd invalid!\n");
  96. return -1;
  97. }
  98. if (ssid == NULL || sLen < SSID_MAX_LEN || pwd == NULL || pLen < PWD_MAX_LEN) {
  99. RaiseLog(LOG_LEVEL_ERR, "NULL POINT!\n");
  100. return -1;
  101. }
  102. while (1) {
  103. int readbytes;
  104. struct sockaddr_in addr;
  105. char recvbuf[BUFF_SIZE] = {0};
  106. socklen_t len = sizeof(addr);
  107. readbytes = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&addr, &len);
  108. if (readbytes <= 0) {
  109. RaiseLog(LOG_LEVEL_ERR, "socket disconnect! \n");
  110. break;
  111. }
  112. if (ParseWifiInfo((const char *)recvbuf, ssid, sLen, pwd, pLen) == 0) {
  113. sendto(sockfd, REQUEST_STR, strlen(REQUEST_STR), 0, (struct sockaddr *)&addr, &len);
  114. result = 0;
  115. break;
  116. }
  117. }
  118. return result;
  119. }
  120. static int NetCfgGetWifiInfo(char *ssid, int sLen, char *pwd, int pLen)
  121. {
  122. int sockfd;
  123. struct sockaddr_in servaddr;
  124. if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
  125. RaiseLog(LOG_LEVEL_ERR, "socket error! \n");
  126. return -1;
  127. }
  128. memset_s(&servaddr, sizeof(servaddr), 0, sizeof(servaddr));
  129. servaddr.sin_family = AF_INET;
  130. servaddr.sin_port = htons(NET_PORT);
  131. servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  132. RaiseLog(LOG_LEVEL_INFO, "listen port %d\n", NET_PORT);
  133. if (bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
  134. RaiseLog(LOG_LEVEL_ERR, "bind socket! \n");
  135. close(sockfd);
  136. return -1;
  137. }
  138. if (listen(sockfd, 1) < 0) {
  139. RaiseLog(LOG_LEVEL_ERR,"listen failed! errno = %d \n", errno);
  140. close(sockfd);
  141. return -1;
  142. }
  143. while (1) {
  144. int newfd, retval;
  145. struct sockaddr_in client_addr;
  146. socklen_t length = sizeof(client_addr);
  147. newfd = accept(sockfd, (struct sockaddr *)&client_addr, &length);
  148. RaiseLog(LOG_LEVEL_INFO, "new socket connect!\n");
  149. retval = NetCfgGetSocketValue(newfd, ssid, sLen, pwd, pLen);
  150. close(newfd);
  151. if (retval == 0) {
  152. RaiseLog(LOG_LEVEL_INFO, "config network success! \n");
  153. break;
  154. }
  155. }
  156. close(sockfd);
  157. return 0;
  158. }
  159. int BOARD_NetCfgStartConfig(const char *appName, char *ssid, int sLen, char *pwd, int pLen)
  160. {
  161. int retval = 0;
  162. if (BOARD_SoftApStart(appName) < 0) {
  163. RaiseLog(LOG_LEVEL_ERR, "start softap failed! \n");
  164. return -1;
  165. }
  166. if (NetCfgGetWifiInfo(ssid, sLen, pwd, pLen) < 0) {
  167. RaiseLog(LOG_LEVEL_ERR, "start softap failed! \n");
  168. retval = -1;
  169. }
  170. BOARD_SoftApStop();
  171. return retval;
  172. }