ESP32_WROOM_32D.c 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660
  1. #include "ESP32_WROOM_32D.h"
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <stdarg.h>
  6. extern int Flag3S;
  7. #define g_uMsgCmdFrameLen (6)
  8. extern uint8_t Devicenum;
  9. extern uint8_t g_wifi_rx_buf[WIFI_RX_BUF_SIZE];
  10. extern uint32_t g_wifi_rx_last;
  11. extern uint32_t g_wifi_rx_head;
  12. extern uint32_t g_wifi_rx_last_tick; /* 最近一次收到ESP数据的时间戳(10ms单位) */
  13. uint8_t wifi_tx_buf[WIFI_TX_BUF_SIZE];
  14. uint16_t wifi_tx_len;
  15. static int wifi_state = 0; //WiFi模块当前状态
  16. static int wifi_ack_delay = 0; //WiFi应答等待
  17. static int wifi_set_ssid = 0; //WiFi应答SSID设置
  18. uint32_t unlink_time = 0;
  19. extern uint32_t pc_link_timeout;
  20. char TCP_IP_PORT[8] = {"8001"};
  21. char MAC_ADDR[20] = {0};
  22. uint32_t broadDevFlag = 0;
  23. extern uint8_t pc_channel_recv;
  24. static int resendtime = 0;
  25. uint16_t WriteComm2(char *data, uint16_t len)
  26. {
  27. //return UART_Write(UART2, data, len);
  28. HAL_UART_Transmit((UART_HandleTypeDef *)sysinf.ESPUart,(const uint8_t *)data, len,1000);
  29. // HAL_UART_Transmit_DMA((UART_HandleTypeDef *)sysinf.ESPUart,(const uint8_t *)data, len);
  30. return 0;
  31. }
  32. /*WIFI单次发送指令*/
  33. void ESP32_Send_AT_Cmd(char *cmd,uint32_t time)
  34. {
  35. char buff[128] = {0};
  36. strcpy(buff, cmd);
  37. strcat(buff, "\r\n");
  38. Van_Device_Printf(VAN_LOG_WIFI,"\nW--> %s", buff);
  39. WriteComm2(buff, strlen(buff));
  40. wifi_ack_delay = time;
  41. }
  42. void ESP32_AT(void)
  43. {
  44. ESP32_Send_AT_Cmd("AT",5000);
  45. }
  46. /*恢复出厂设置*/
  47. void ESP32_AT_Restore(void)
  48. {
  49. ESP32_Send_AT_Cmd("AT+RESTORE",500);
  50. }
  51. /*复位*/
  52. void ESP32_AT_RST(void)
  53. {
  54. ESP32_Send_AT_Cmd("AT+RST",8000);
  55. }
  56. /*上电自动连接AP*/
  57. void ESP32_AT_AUTOCONN(void)
  58. {
  59. ESP32_Send_AT_Cmd("AT+CWAUTOCONN=0",5000);
  60. }
  61. /*WIFI AP/STA/AP+STA模式选择*/
  62. void ESP32_Net_Mode_Choose(ENUM_Net_ModeTypeDef enumMode)
  63. {
  64. switch ( enumMode )
  65. {
  66. case STA:
  67. ESP32_Send_AT_Cmd ( "AT+CWMODE=1", 5000 );
  68. break;
  69. case AP:
  70. ESP32_Send_AT_Cmd ( "AT+CWMODE=2", 5000 );
  71. break;
  72. case STA_AP:
  73. ESP32_Send_AT_Cmd ( "AT+CWMODE=3", 5000 );
  74. break;
  75. default:
  76. break;
  77. }
  78. }
  79. /*WIFI加入AP*/
  80. void ESP32_JoinAP( char * pSSID, char * pPassWord, char * pMacAddr)
  81. {
  82. char cCmd [128];
  83. my_sprintf ( cCmd, sizeof(cCmd), "AT+CWJAP=\"%s\",\"%s\",\"%s\"", pSSID, pPassWord,pMacAddr);
  84. ESP32_Send_AT_Cmd( cCmd,5000 );
  85. }
  86. /*WIFI建立AP*/
  87. void ESP32_SetupAP( char * pSSID, char * pPassWord)
  88. {
  89. char cCmd [40];
  90. my_sprintf ( cCmd,sizeof(cCmd), "AT+CWSAP=\"%s\",\"%s\"", pSSID, pPassWord );
  91. ESP32_Send_AT_Cmd( cCmd, 5000 );
  92. }
  93. /*WIFI查询IP*/
  94. void ESP32_GetIp(void)
  95. {
  96. ESP32_Send_AT_Cmd( "AT+CIPSTA?", 5000 );
  97. }
  98. /*WIFI禁止自动连接*/
  99. void ESP32_DisAutoLink(void)
  100. {
  101. ESP32_Send_AT_Cmd( "AT+CWAUTOCONN=0", 5000 );
  102. }
  103. void ESP32_CWLAP(char * pSSID)
  104. {
  105. char cCmd [80];
  106. my_sprintf ( cCmd, sizeof(cCmd), "AT+CWLAP=\"%s\"", pSSID);
  107. ESP32_Send_AT_Cmd( cCmd, 5000 );
  108. }
  109. /*WIFI关闭回显*/
  110. void ESP32_EchoOff(void)
  111. {
  112. ESP32_Send_AT_Cmd( "ATE0", 5000 );
  113. }
  114. /*WIFI初始化*/
  115. void ESP32_Init(void)
  116. {
  117. ESP32_Send_AT_Cmd( "+++", 5000 );
  118. }
  119. /*WIFI 单/多连接*/
  120. void ESP32_Enable_MultipleId (uint8_t enumEnUnvarnishTx )
  121. {
  122. char cCmd [20];
  123. my_sprintf ( cCmd, sizeof(cCmd), "AT+CIPMUX=%d", ( enumEnUnvarnishTx ? 1 : 0 ) );
  124. ESP32_Send_AT_Cmd ( cCmd, 5000 );
  125. }
  126. /*WIFI AP作为服务端开启或关闭,1---开启服务:0---关闭服务*/
  127. void ESP32_AP_Server (uint8_t open)
  128. {
  129. char cCmd [40];
  130. my_sprintf ( cCmd,sizeof(cCmd), "AT+CIPSERVER=%d", open);
  131. ESP32_Send_AT_Cmd( cCmd, 5000 );
  132. }
  133. /*WIFI STA选择TCP或UDP协议*/
  134. void ESP32_Link_Server(ENUM_NetPro_TypeDef enumE, char * ip, char * ComNum, ENUM_ID_NO_TypeDef id)
  135. {
  136. char cStr [100] = { 0 }, cCmd [60];
  137. switch ( enumE )
  138. {
  139. case enumTCP:
  140. my_sprintf ( cStr, sizeof(cCmd), "\"%s\",\"%s\",%s,6", "TCP", ip, ComNum );
  141. break;
  142. case enumUDP:
  143. my_sprintf ( cStr,sizeof(cCmd), "\"%s\",\"%s\",%s,9090,0", "UDP", ip, ComNum );
  144. break;
  145. default:
  146. break;
  147. }
  148. if ( id < 5 )
  149. my_sprintf ( cCmd,sizeof(cCmd), "AT+CIPSTART=%d,%s", id, cStr);
  150. else
  151. my_sprintf ( cCmd, sizeof(cCmd), "AT+CIPSTART=%s", cStr );
  152. ESP32_Send_AT_Cmd ( cCmd,5000 );
  153. }
  154. /*WIFI透传*/
  155. void ESP32_UnvarnishSend ( void )
  156. {
  157. ESP32_Send_AT_Cmd( "AT+CIPMODE=1", 5000 );//设置透传模式
  158. }
  159. /*WIFI停止TCP*/
  160. void ESP32_STOPTCP ( ENUM_ID_NO_TypeDef id )
  161. {
  162. char cCmd [60];
  163. my_sprintf ( cCmd,sizeof(cCmd), "AT+CIPCLOSE=%d", id);
  164. ESP32_Send_AT_Cmd ( cCmd, 20000 );
  165. }
  166. /*退出透传*/
  167. void ESP32_ExitUnvarnishSend( void )
  168. {
  169. ESP32_Send_AT_Cmd("+++", 5000);
  170. }
  171. ///*设置默认波特率为460800*/
  172. //void ESP32_SET_BUAR(void)
  173. //{
  174. // ESP32_Send_AT_Cmd("AT+UART_DEF=460800,8,1,0,0","OK",NULL,500);
  175. //}
  176. /********************************************************************
  177. * int WIFI_Send_Data(uint8_t *data, uint8_t len, uint8_t flag)
  178. *
  179. *描述:通过WIFI发送数据,异步
  180. *参数:data:数据
  181. *参数:len:数据长度
  182. *参数:flag:1:立即发送,0:暂存
  183. *返回:无
  184. *其他:无
  185. *--------------------------------------------------------------------
  186. *记录:
  187. ********************************************************************/
  188. int WIFI_Send_Data(uint8_t *data, uint16_t len, uint8_t flag)
  189. {
  190. char cStr [40] = {0};
  191. if (wifi_state < WIFI_TRANS)
  192. return -1;
  193. if(wifi_ack_delay > 0)
  194. return -2;
  195. if(wifi_tx_len)
  196. return -3;
  197. if(len > WIFI_TX_BUF_SIZE){
  198. Van_Device_Printf(VAN_LOG_WIFI,"WIFI_Send len:%d error ", len);
  199. return -1;
  200. }
  201. memcpy(&wifi_tx_buf[wifi_tx_len], data, len);
  202. wifi_tx_len += len;
  203. if(flag)
  204. {
  205. wifi_ack_delay = 3000;
  206. my_sprintf ( cStr, sizeof(cStr),"AT+CIPSEND=0,%d", wifi_tx_len );
  207. ESP32_Send_AT_Cmd ( cStr, 3000 );
  208. return wifi_tx_len;
  209. }
  210. return 0;
  211. }
  212. int WIFI_Send_MSG(uint8_t*msgHead,uint8_t *data, uint8_t * crc, uint16_t len)
  213. {
  214. char cStr [40] = {0};
  215. if (wifi_state != WIFI_TRANS)
  216. return -1;
  217. if(wifi_ack_delay > 0)
  218. return -2;
  219. if(wifi_tx_len > 0)
  220. return -3;
  221. memcpy(&wifi_tx_buf[0], msgHead, g_uMsgCmdFrameLen);
  222. memcpy(&wifi_tx_buf[g_uMsgCmdFrameLen], data, len);
  223. memcpy(&wifi_tx_buf[g_uMsgCmdFrameLen+len], crc, 2);
  224. wifi_tx_len = g_uMsgCmdFrameLen+len+2;
  225. wifi_ack_delay = 3000;
  226. my_sprintf ( cStr, sizeof(cStr),"AT+CIPSEND=0,%d", wifi_tx_len );
  227. ESP32_Send_AT_Cmd ( cStr, 3000 );
  228. return wifi_tx_len;
  229. }
  230. int WIFI_SendIlde(void){
  231. if(wifi_tx_len == 0)
  232. return 0;
  233. if (wifi_state < WIFI_TRANS)
  234. return 0;
  235. if(wifi_ack_delay > 0)
  236. return 0;
  237. return 1;
  238. }
  239. int WIFI_ReSend(void)
  240. {
  241. char cStr [40] = {0};
  242. if(wifi_tx_len == 0)
  243. return 0;
  244. if (wifi_state < WIFI_TRANS)
  245. return -1;
  246. if(wifi_ack_delay > 0)
  247. return -2;
  248. wifi_ack_delay = 3000;
  249. my_sprintf ( cStr, sizeof(cStr),"AT+CIPSEND=0,%d", wifi_tx_len );
  250. ESP32_Send_AT_Cmd ( cStr, 3000 );
  251. return 0;
  252. }
  253. //wifi修改SSID
  254. void WIFI_set_ssid(void)
  255. {
  256. wifi_ack_delay = 0;
  257. wifi_state = WIFI_POWEROFF;
  258. wifi_set_ssid = 1;
  259. if(wifi_tx_len > 0)
  260. {
  261. WriteComm2((char *)wifi_tx_buf, wifi_tx_len);
  262. wifi_tx_len = 0;
  263. }
  264. }
  265. //wifi修改SSID
  266. void WIFI_set_CloseConnect(void)
  267. {
  268. wifi_state = WIFI_CLOSE;
  269. }
  270. // //在内存中查找字符串
  271. // char* find_str(void *src, int size, char *str)
  272. // {
  273. // char *p = (char*)src;
  274. // int len = strlen((const char *)str);
  275. // if(len < 1)
  276. // return p;
  277. // for(int i = 0; i < size; i++)
  278. // {
  279. // if(p[i] == *str)
  280. // {
  281. // if( 0 == memcmp(&p[i], str, len))
  282. // {
  283. // return &p[i];
  284. // }
  285. // }
  286. // }
  287. // return NULL;
  288. // }
  289. //在内存中查找字符串
  290. char* find_str_loop(void *src, int size, uint32_t *start, uint32_t end, char *str) {
  291. if (src == NULL || start == NULL || str == NULL || size <= 0)
  292. return NULL;
  293. unsigned char *buf = (unsigned char*)src;
  294. int head = *start;
  295. int len = strlen(str);
  296. // 空串直接返回当前位置(不移动头指针)
  297. if (len == 0) {
  298. return (char*)(buf + head);
  299. }
  300. // 计算有效数据长度
  301. int valid_len;
  302. if (end >= head)
  303. valid_len = end - head;
  304. else
  305. valid_len = (size - head) + end;
  306. // 若有效数据长度小于目标串长度,不可能匹配
  307. if (valid_len < len)
  308. return NULL;
  309. // 从 head 开始遍历所有可能的起始位置(不包括 end)
  310. int pos = head;
  311. while (pos != end) {
  312. // 检查从 pos 开始的 len 个字节是否与 str 匹配
  313. int i;
  314. for (i = 0; i < len; i++) {
  315. int idx = (pos + i) % size;
  316. if (buf[idx] != (unsigned char)str[i])
  317. break;
  318. }
  319. if (i == len) { // 完全匹配
  320. // 更新头指针为匹配串之后的位置
  321. *start = (pos + len) % size;
  322. return (char*)(buf + pos);
  323. }
  324. // 移动到下一个起始位置
  325. pos = (pos + 1) % size;
  326. // 如果移动后到达 end,提前终止(有效数据遍历完毕)
  327. // 但 while 条件会处理,可省略
  328. }
  329. // 未找到
  330. return NULL;
  331. }
  332. /********************************************************************
  333. * WIFI_recv_deal()
  334. *
  335. *描述:接收帧解析
  336. *参数:无
  337. *返回:无
  338. *其他:无
  339. *--------------------------------------------------------------------
  340. *记录:
  341. ********************************************************************/
  342. void WIFI_recv_deal(void)
  343. {
  344. char *p;
  345. int data_len = g_wifi_rx_last>g_wifi_rx_head?(g_wifi_rx_last-g_wifi_rx_head):(WIFI_RX_BUF_SIZE+g_wifi_rx_last-g_wifi_rx_head);
  346. // int udp_data_len = 0;
  347. char* data = (char*)g_wifi_rx_buf;
  348. if((data_len < 5)&&(wifi_state != WIFI_TRANS))
  349. return;
  350. //判断是否接收完成
  351. if(wifi_state > WIFI_LISTEN)
  352. {
  353. if(data[g_wifi_rx_last-1] != '\n' && data[g_wifi_rx_last-2] != '\n')
  354. {
  355. return;
  356. }
  357. }
  358. switch (wifi_state)
  359. {
  360. //指令模式
  361. case WIFI_POWEROFF:
  362. case WIFI_ERROR:
  363. if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last,"ready") ||
  364. NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last,"boot"))
  365. {
  366. wifi_state = WIFI_POWERON;
  367. wifi_ack_delay = 0;
  368. memset(wifi_tx_buf,0,sizeof(wifi_tx_buf));
  369. wifi_tx_len = 0;
  370. // wifi_receive_clear();
  371. }
  372. break;
  373. case WIFI_POWERON:
  374. case WIFI_INIT:
  375. case WIFI_STATION:
  376. case WIFI_DISAUTO:
  377. case WIFI_LINK_AP:
  378. case WIFI_GET_IP:
  379. case WIFI_SETMUX:
  380. case WIFI_LISTEN:
  381. if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "OK\r\n"))
  382. {
  383. Van_Device_Printf(VAN_LOG_WIFI,"\nW<-- %s", data);
  384. wifi_ack_delay = 0;
  385. if(WIFI_LISTEN == wifi_state){
  386. /*上电需要广播地址*/
  387. broadDevFlag = 1;
  388. sysinf.s10_flag = 1;
  389. resendtime = 0;
  390. memset(wifi_tx_buf, 0, sizeof(wifi_tx_buf));
  391. wifi_tx_len = 0;
  392. // if(sysinf.connectTcpFlag == 1){
  393. // if(wifi_tx_len){
  394. // char cStr [40] = {0};
  395. // my_sprintf ( cStr,sizeof(cStr), "AT+CIPSEND=0,%d", wifi_tx_len );
  396. // ESP32_Send_AT_Cmd ( cStr, 3000 );
  397. // }
  398. // // sysinf.pc_link_timeout = 0;
  399. // // sysinf.pc_channel_recv = PC_CONNECT_TYPE_WIFI;
  400. // }
  401. // wifi_receive_clear();
  402. }
  403. wifi_state++;
  404. resendtime = 0;
  405. HAL_Delay(1000);
  406. //
  407. }
  408. break;
  409. case WIFI_CWLAP:{
  410. char* strStart = find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last,sysinf.wifiname);
  411. uint32_t apHeader = g_wifi_rx_head;
  412. if(NULL != strStart)
  413. {
  414. if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "OK\r\n")){
  415. /*循环始终需要OK,找到OK后,恢复APhead位置,重新搜寻mac*/
  416. g_wifi_rx_head = apHeader;
  417. Van_Device_Printf(VAN_LOG_WIFI,"\nW<-- %s", data);
  418. wifi_ack_delay = 0;
  419. strStart+=strlen(sysinf.wifiname);
  420. strStart =find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last,",\"");
  421. unsigned int startPos = ((unsigned int)strStart-(unsigned int)g_wifi_rx_buf + 2)%WIFI_RX_BUF_SIZE;/*跳过,\*/
  422. for(unsigned i=0;i<17;i++){
  423. MAC_ADDR[i] = g_wifi_rx_buf[(i+startPos)%WIFI_RX_BUF_SIZE];
  424. }
  425. MAC_ADDR[18] = 0;
  426. wifi_state++;
  427. }
  428. // wifi_receive_clear();
  429. }
  430. }
  431. break;
  432. //数据模式
  433. case WIFI_TRANS:
  434. //收到AT+CIPSEND回应,可发送数据
  435. if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "CLOSED"))
  436. {
  437. Van_Device_Printf(VAN_LOG_WIFI,"\nW<-- %d %s", data_len,data);
  438. wifi_state = WIFI_LISTEN;
  439. wifi_ack_delay = 0;//从发送写指令,到此才算发送完成
  440. broadDevFlag = 0;
  441. }
  442. else if ((NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "ERROR"))||
  443. (NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last,"SEND FAIL")))
  444. {
  445. if(resendtime < MAX_RESEND_TIME){
  446. char cStr [40] = {0};
  447. my_sprintf ( cStr,sizeof(cStr), "AT+CIPSEND=0,%d", wifi_tx_len );
  448. ESP32_Send_AT_Cmd ( cStr, 3000 );
  449. resendtime ++;
  450. }else{
  451. wifi_state = WIFI_POWEROFF;
  452. wifi_ack_delay = 0;
  453. }
  454. // wifi_receive_clear();
  455. } else if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "SEND OK"))
  456. {
  457. //收到AT+CIPSEND回应,可发送数据
  458. Van_Device_Printf(VAN_LOG_WIFI,"\n--> SEND OK", wifi_tx_len);
  459. wifi_ack_delay = 0;//从发送写指令,到此才算发送完成
  460. resendtime = 0;
  461. memset(wifi_tx_buf, 0, sizeof(wifi_tx_buf));
  462. wifi_tx_len = 0;
  463. // wifi_receive_clear();
  464. }
  465. else if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "OK\r\n"))
  466. {
  467. wifi_receive_clear();
  468. Van_Device_Printf(VAN_LOG_WIFI,"\n--> OK W %d", wifi_tx_len);
  469. WriteComm2((char *)wifi_tx_buf, wifi_tx_len+1);
  470. wifi_ack_delay = 3000;
  471. }
  472. // else if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, ">"))
  473. // {
  474. // wifi_receive_clear();
  475. // Van_Device_Printf(VAN_LOG_WIFI,"\n--> > W %d", wifi_tx_len);
  476. // WriteComm2((char *)wifi_tx_buf, wifi_tx_len+1);
  477. // wifi_ack_delay = 3000;
  478. // }
  479. if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "DISCONNECT"))
  480. {
  481. Van_Device_Printf(VAN_LOG_WIFI,"\nW--> %s", data);
  482. wifi_state = WIFI_POWEROFF;
  483. wifi_ack_delay = 0;
  484. }
  485. //收到PC数据
  486. p = find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "+IPD,0,");
  487. if(NULL != p)
  488. {
  489. int iProcLen = DecodeNew(&uart0_massage,uart0_data,g_wifi_rx_buf, &g_wifi_rx_head,g_wifi_rx_last,WIFI_RX_BUF_SIZE);
  490. if (iProcLen > 0) {
  491. sysinf.pc_channel_recv = PC_CONNECT_TYPE_WIFI;
  492. sysinf.pc_link_timeout = 0;
  493. uart0_massage.data = (char *)uart0_data;
  494. query_pc_cmd(&uart0_massage);
  495. wifi_receive_clear();
  496. }
  497. // wifi_receive_clear();
  498. // set_pc_chanel_recv(1);
  499. // b2b_recv_data(p, udp_data_len);
  500. }
  501. break;
  502. case WIFI_CLOSE:{
  503. if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "CLOSED\r\n"))
  504. {
  505. wifi_state = WIFI_LISTEN;
  506. wifi_ack_delay = 0;
  507. }
  508. }
  509. break;
  510. default:
  511. break;
  512. }
  513. if(WIFI_TRANS != wifi_state){
  514. wifi_receive_clear();
  515. }
  516. }
  517. void WIFI_send_deal(void)
  518. {
  519. static uint8_t try_count = 0;
  520. static uint8_t try_con = 0;
  521. static uint32_t wifi_start_delay = 0;
  522. static uint8_t res_count = 0;
  523. uint8_t wifi_result = 0;
  524. //启动超时
  525. if(wifi_state < WIFI_LISTEN && wifi_start_delay++ > 120*10)
  526. {
  527. wifi_start_delay = 0;
  528. wifi_state = WIFI_POWEROFF;
  529. wifi_ack_delay = 0;
  530. }
  531. //等待模块应答
  532. if(wifi_ack_delay > 0)
  533. {
  534. wifi_ack_delay -= 100;
  535. return;
  536. }
  537. if(resendtime >= MAX_RESEND_TIME){
  538. wifi_state = WIFI_POWEROFF;
  539. }
  540. if((WIFI_TRANS != wifi_state )|| ((WIFI_TRANS == wifi_state)&& wifi_tx_len )){
  541. resendtime++;
  542. }
  543. switch (wifi_state)
  544. {
  545. case WIFI_POWEROFF:
  546. case WIFI_ERROR:
  547. ESP32_AT_RST();
  548. wifi_start_delay = 0;
  549. resendtime = 0;
  550. try_count = 0;
  551. if(sysinf.connectTcpFlag){
  552. /*持续5次均不能链接到tcp,状态回退,重启链接udp*/
  553. res_count++;
  554. if(res_count > 5){
  555. sysinf.connectTcpFlag = 0;
  556. }
  557. }
  558. break;
  559. case WIFI_POWERON:
  560. ESP32_AT();
  561. break;
  562. case WIFI_INIT:
  563. ESP32_EchoOff();
  564. break;
  565. case WIFI_STATION:
  566. ESP32_Net_Mode_Choose(STA);
  567. break;
  568. case WIFI_DISAUTO:
  569. ESP32_DisAutoLink();
  570. try_count = 0;
  571. resendtime = 0;
  572. break;
  573. case WIFI_CWLAP:
  574. ESP32_CWLAP(sysinf.wifiname);
  575. try_count++;
  576. if(try_count == MAX_RESEND_TIME)
  577. {
  578. wifi_state = WIFI_POWEROFF;
  579. if(wifi_set_ssid == 1)
  580. {
  581. wifi_set_ssid = 0;
  582. wifi_result = 0xff;
  583. data_send_to_pc(PC_CMD_SETWIFI, (char *)&wifi_result, 1);
  584. }
  585. Van_Device_Printf(VAN_LOG_ERROR, "no wifi AP:%s\n\r",sysinf.wifiname);
  586. }
  587. try_con = 0;
  588. resendtime = 0;
  589. break;
  590. case WIFI_LINK_AP:
  591. ESP32_JoinAP(sysinf.wifiname, sysinf.password,MAC_ADDR);
  592. try_con++ ;
  593. if(try_con == MAX_RESEND_TIME)
  594. {
  595. wifi_state = WIFI_POWEROFF;
  596. if(wifi_set_ssid == 1)
  597. {
  598. wifi_set_ssid = 0;
  599. wifi_result = 0xfe;
  600. data_send_to_pc(PC_CMD_SETWIFI, (char *)&wifi_result, 1);
  601. }
  602. Van_Device_Printf(VAN_LOG_ERROR, "can't jonn AP:%s %s\n\r",sysinf.wifiname,sysinf.password);
  603. }
  604. break;
  605. case WIFI_GET_IP:
  606. ESP32_GetIp();
  607. if(wifi_set_ssid == 1)
  608. {
  609. wifi_set_ssid = 0;
  610. wifi_result = 1;
  611. data_send_to_pc(PC_CMD_SETWIFI, (char *)&wifi_result, 1);
  612. }
  613. break;
  614. case WIFI_SETMUX:
  615. ESP32_Enable_MultipleId(1);
  616. break;
  617. case WIFI_LISTEN:
  618. if(sysinf.connectTcpFlag){
  619. if(resendtime < MAX_RESEND_TIME)
  620. {
  621. ESP32_Link_Server(enumTCP,sysinf.TCP_IP_Addr, sysinf.TCP_IP_PORT, Multiple_ID_0);
  622. }else{
  623. /*多次TCP未链接,链接UDP*/
  624. // connectTcpFlag = 0;
  625. // resendtime = 0;
  626. memset(wifi_tx_buf, 0, sizeof(wifi_tx_buf));
  627. wifi_tx_len = 0;
  628. }
  629. }else{
  630. if(resendtime < MAX_RESEND_TIME)
  631. {
  632. ESP32_Link_Server(enumUDP,User_ESP32_UDPServer_IP, User_ESP32_UDPServer_PORT, Multiple_ID_0);
  633. }
  634. }
  635. break;
  636. case WIFI_TRANS:
  637. if(resendtime < MAX_RESEND_TIME)
  638. {
  639. if(wifi_tx_len){
  640. char cStr [40] = {0};
  641. Van_Device_Printf(VAN_LOG_WIFI,"\nbuflen:%d %d %s",g_wifi_rx_head,g_wifi_rx_last, g_wifi_rx_buf);
  642. my_sprintf ( cStr,sizeof(cStr),"AT+CIPSEND=0,%d", wifi_tx_len );
  643. ESP32_Send_AT_Cmd ( cStr, 3000 );
  644. }
  645. }
  646. if(sysinf.connectTcpFlag){
  647. /*tcp链接上,复位计数清零*/
  648. res_count = 0;
  649. }
  650. break;
  651. case WIFI_CLOSE:
  652. ESP32_STOPTCP(Single_ID_0);
  653. break;
  654. default:
  655. wifi_state = WIFI_ERROR;
  656. break;
  657. }
  658. }
  659. /* ========================================================================
  660. * 热点配网(SoftAP WiFi配网)状态机
  661. * 触发 : 按键长按30s -> WIFI_provision_request() (usr_motor.c)
  662. * 流程 : 复位ESP32 -> AP模式(AT+CWMODE=2) -> 建热点
  663. * OneChip_Mini7 / test1234 (192.168.4.1/255.255.255.0)
  664. * -> AT+CIPAP? 查询热点IP -> AT+CWDHCP? 查询DHCP状态
  665. * -> AT+CIPMUX=1 -> AT+CIPSERVER=1,8002 启动TCP服务
  666. * -> 手机连接热点,经TCP 8002下发:
  667. * {"ssid":"Onechip_602","password":"onchip1003"}
  668. * -> 解析JSON, ssid->sysinf.wifiname, password->sysinf.password
  669. * -> cfg_save_cfg_param() 保存到Flash
  670. * -> 复位ESP32进入正常STA模式(按新配置自动连接)
  671. * 说明 : 热点地址192.168.4.1/255.255.255.0为ESP32 SoftAP默认值,无需配置
  672. * ===================================================================== */
  673. #define WIFI_PROV_AP_SSID "OneChip_Mini7" /* 热点名称 */
  674. #define WIFI_PROV_AP_PWD "test1234" /* 热点密码 */
  675. #define WIFI_PROV_AP_CHANNEL 6 /* 信道 */
  676. #define WIFI_PROV_AP_ECN 3 /* 加密:3=WPA2_PSK */
  677. #define WIFI_PROV_TCP_PORT 8002 /* TCP服务端口 */
  678. #define WIFI_PROV_CMD_TIMEOUT 500 /* 单条AT指令超时:5s(10ms) */
  679. #define WIFI_PROV_RST_TIMEOUT 1000 /* AT+RST等待ready:10s */
  680. #define WIFI_PROV_LISTEN_TIMEOUT 30000 /* 等待配网数据总超时:300s */
  681. #define WIFI_PROV_MAX_RETRY 3 /* 指令失败重试次数 */
  682. #define WIFI_PROV_RX_IDLE_TIMEOUT 100 /* 无有效IPD残留数据清空时限:1s(10ms) */
  683. typedef enum
  684. {
  685. WIFI_PROV_IDLE = 0, /* 空闲 */
  686. WIFI_PROV_START, /* 启动初始化 */
  687. WIFI_PROV_RST, /* 复位ESP32,重启进入AP主机模式 */
  688. WIFI_PROV_WAIT_READY, /* 等待模块重启完成 */
  689. WIFI_PROV_MODE, /* AT+CWMODE=2 设置AP模式 */
  690. WIFI_PROV_SAP, /* AT+CWSAP 建立热点 */
  691. WIFI_PROV_IP_Q, /* AT+CIPAP? 查询SoftAP接口IP(默认192.168.4.1) */
  692. WIFI_PROV_DHCP_Q, /* AT+CWDHCP? 查询DHCP使能状态 */
  693. WIFI_PROV_MUX, /* AT+CIPMUX=1 打开多连接 */
  694. WIFI_PROV_SERVER, /* AT+CIPSERVER=1,8002 启动TCP服务 */
  695. WIFI_PROV_LISTEN, /* 等待手机下发配网JSON */
  696. WIFI_PROV_ACK_SEND, /* AT+CIPSEND 向手机应答 */
  697. WIFI_PROV_ACK_DATA, /* 等待'>'并发送应答数据 */
  698. WIFI_PROV_SAVE, /* 保存配置到Flash */
  699. WIFI_PROV_DONE, /* 配网完成,复位进入正常模式 */
  700. } wifi_prov_state_t;
  701. static volatile uint8_t wifi_prov_request = 0; /* 配网请求标志(可被ISR置位) */
  702. static uint8_t wifi_prov_active = 0; /* 配网进行中 */
  703. static uint8_t wifi_prov_state = WIFI_PROV_IDLE;
  704. static uint8_t wifi_prov_retry = 0;
  705. static uint8_t wifi_prov_wait = 0; /* 1=正在等待应答 */
  706. static uint8_t wifi_prov_json_ok = 0; /* 解析到的配置是否有效 */
  707. static uint8_t wifi_prov_linkid = 0; /* TCP链路ID */
  708. static uint32_t wifi_prov_tick = 0; /* 起始时间戳(10ms单位) */
  709. static uint32_t wifi_prov_timeout = 0; /* 等待超时(10ms单位) */
  710. static char wifi_prov_ipd[WIFI_RX_BUF_SIZE];/* +IPD载荷累积缓存(JSON) */
  711. static uint16_t wifi_prov_ipd_len = 0;
  712. static char wifi_prov_ack[WIFI_RX_BUF_SIZE];/* 应答JSON */
  713. static void wifi_prov_enter(void);
  714. static void wifi_prov_exit(void);
  715. static void wifi_prov_abort(void);
  716. /* 配网进行中? */
  717. uint8_t WIFI_provision_active(void)
  718. {
  719. return wifi_prov_active;
  720. }
  721. /* 请求进入热点配网模式(按键长按30s调用,允许在中断中调用) */
  722. uint8_t WIFI_provision_request(void)
  723. {
  724. if (wifi_prov_active != 0)
  725. return 0; /* 已在配网中 */
  726. wifi_prov_request = 1;
  727. return 1;
  728. }
  729. /* 配网状态机内部发送AT指令 */
  730. static void wifi_prov_send_cmd(const char *cmd, uint32_t timeout10ms)
  731. {
  732. char buff[128] = {0};
  733. strcpy(buff, cmd);
  734. strcat(buff, "\r\n");
  735. Van_Device_Printf(VAN_LOG_WIFI, "\nP--> %s", buff);
  736. WriteComm2(buff, strlen(buff));
  737. wifi_prov_wait = 1;
  738. wifi_prov_tick = sysinf.conter10ms;
  739. wifi_prov_timeout = timeout10ms;
  740. }
  741. /* 从ESP接收环中提取一个完整的+IPD报文载荷并追加到累积缓存
  742. * 返回: 1=取到完整报文; 0=暂无完整报文(继续等待);
  743. * -1=帧头/载荷异常(不打印、不清空、不消费,继续等待直到总超时退出) */
  744. static int wifi_prov_capture_ipd(void)
  745. {
  746. uint32_t head = g_wifi_rx_head;
  747. uint32_t last = g_wifi_rx_last;
  748. uint32_t avail = (last + WIFI_RX_BUF_SIZE - head) % WIFI_RX_BUF_SIZE;
  749. int pos = -1;
  750. uint32_t i;
  751. if (avail == 0)
  752. return 0;
  753. /* 查找"+IPD,"头 */
  754. for (i = 0; (i + 5) <= avail; i++)
  755. {
  756. uint32_t p = (head + i) % WIFI_RX_BUF_SIZE;
  757. if (g_wifi_rx_buf[p] == '+' &&
  758. g_wifi_rx_buf[(p + 1) % WIFI_RX_BUF_SIZE] == 'I' &&
  759. g_wifi_rx_buf[(p + 2) % WIFI_RX_BUF_SIZE] == 'P' &&
  760. g_wifi_rx_buf[(p + 3) % WIFI_RX_BUF_SIZE] == 'D' &&
  761. g_wifi_rx_buf[(p + 4) % WIFI_RX_BUF_SIZE] == ',')
  762. {
  763. pos = (int)i;
  764. break;
  765. }
  766. }
  767. if (pos < 0)
  768. return 0; /* 缓冲内无+IPD报文 */
  769. i = (uint32_t)(pos + 5);
  770. if (i >= avail)
  771. return 0; /* 帧头不完整,继续等待 */
  772. /* 解析头: +IPD,<linkID>,<len>: */
  773. if (g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] < '0' ||
  774. g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] > '9')
  775. return -1; /* linkid非数字,帧损坏 */
  776. {
  777. uint32_t linkid = 0;
  778. while (i < avail &&
  779. g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] >= '0' &&
  780. g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] <= '9')
  781. {
  782. linkid = linkid * 10 + (uint32_t)(g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] - '0');
  783. i++;
  784. }
  785. if (i >= avail)
  786. return 0; /* linkid未完,继续等待 */
  787. if (g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] != ',')
  788. return -1; /* 缺少逗号分隔,帧损坏 */
  789. wifi_prov_linkid = (uint8_t)linkid;
  790. i++;
  791. if (i >= avail)
  792. return 0;
  793. if (g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] < '0' ||
  794. g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] > '9')
  795. return -1; /* 长度非数字,帧损坏 */
  796. {
  797. uint32_t pktlen = 0;
  798. while (i < avail &&
  799. g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] >= '0' &&
  800. g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] <= '9')
  801. {
  802. pktlen = pktlen * 10 + (uint32_t)(g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] - '0');
  803. i++;
  804. }
  805. if (i >= avail)
  806. return 0; /* len未完,继续等待 */
  807. if (g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] != ':')
  808. return -1; /* 缺少冒号分隔,帧损坏 */
  809. i++; /* 跳过 ':' */
  810. if (pktlen == 0)
  811. return -1; /* 空载荷异常 */
  812. if (avail < i + pktlen)
  813. return 0; /* 载荷尚未收完,继续等待 */
  814. if ((uint16_t)(wifi_prov_ipd_len + pktlen) < sizeof(wifi_prov_ipd))
  815. {
  816. uint32_t k;
  817. for (k = 0; k < pktlen; k++)
  818. {
  819. char c = (char)g_wifi_rx_buf[(head + i + k) % WIFI_RX_BUF_SIZE];
  820. if (c == '\r' || c == '\n') /* 去掉行结束符 */
  821. continue;
  822. wifi_prov_ipd[wifi_prov_ipd_len++] = c;
  823. }
  824. wifi_prov_ipd[wifi_prov_ipd_len] = '\0';
  825. }
  826. else
  827. {
  828. /* 载荷超限无法累积: 丢弃该帧载荷,重新接收 */
  829. wifi_prov_ipd_len = 0;
  830. wifi_prov_ipd[0] = '\0';
  831. }
  832. /* 消费该报文 */
  833. g_wifi_rx_head = (head + i + pktlen) % WIFI_RX_BUF_SIZE;
  834. return 1;
  835. }
  836. }
  837. }
  838. /* 解析配网JSON: {"ssid":"xxx","password":"xxx"}
  839. * 返回: 0=成功; -1=失败 */
  840. static int wifi_prov_parse_json(const char *json, char *ssid, uint16_t ssidCap,
  841. char *pwd, uint16_t pwdCap)
  842. {
  843. cJSON *root = NULL;
  844. cJSON *it = NULL;
  845. int rlt = -1;
  846. if (json == NULL || json[0] != '{' || ssid == NULL || pwd == NULL)
  847. return -1;
  848. ssid[0] = '\0';
  849. pwd[0] = '\0';
  850. root = cJSON_Parse(json);
  851. if (root == NULL)
  852. return -1;
  853. it = cJSON_GetObjectItem(root, "ssid");
  854. if (it == NULL || !cJSON_IsString(it) || it->valuestring == NULL ||
  855. it->valuestring[0] == '\0')
  856. goto out; /* 必须包含非空ssid */
  857. if (strlen(it->valuestring) >= (size_t)ssidCap)
  858. goto out; /* ssid超长 */
  859. strcpy(ssid, it->valuestring);
  860. it = cJSON_GetObjectItem(root, "password");
  861. if (it != NULL && cJSON_IsString(it) && it->valuestring != NULL)
  862. {
  863. if (strlen(it->valuestring) >= (size_t)pwdCap)
  864. goto out; /* 密码超长 */
  865. strcpy(pwd, it->valuestring); /* 允许开放网络密码为空 */
  866. }
  867. rlt = 0;
  868. out:
  869. cJSON_Delete(root);
  870. return rlt;
  871. }
  872. /* 生成应答JSON */
  873. static void wifi_prov_build_ack(uint8_t accepted, const char *reason)
  874. {
  875. if (accepted)
  876. {
  877. my_sprintf(wifi_prov_ack, sizeof(wifi_prov_ack),
  878. "{\"v\":1,\"status\":\"accepted\",\"sn\":\"%s\"}\r\n",
  879. sysinf.SN);
  880. }
  881. else
  882. {
  883. if (reason == NULL)
  884. reason = "invalid";
  885. my_sprintf(wifi_prov_ack, sizeof(wifi_prov_ack),
  886. "{\"v\":1,\"status\":\"rejected\",\"reason\":\"%s\"}\r\n",
  887. reason);
  888. }
  889. }
  890. /* 进入热点配网模式 */
  891. static void wifi_prov_enter(void)
  892. {
  893. wifi_prov_active = 1;
  894. wifi_prov_state = WIFI_PROV_START;
  895. wifi_prov_retry = 0;
  896. wifi_prov_wait = 0;
  897. wifi_prov_linkid = 0;
  898. wifi_prov_json_ok = 0;
  899. wifi_prov_ipd_len = 0;
  900. wifi_prov_ipd[0] = '\0';
  901. memset(wifi_tx_buf, 0, sizeof(wifi_tx_buf));
  902. wifi_tx_len = 0;
  903. wifi_ack_delay = 0;
  904. wifi_state = WIFI_POWEROFF; /* 暂停正常wifi流程 */
  905. wifi_receive_clear();
  906. Van_Device_Printf(VAN_LOG_WIFI,
  907. "\r\n[Provision] enter, AP=%s pwd=%s port=%d",
  908. WIFI_PROV_AP_SSID, WIFI_PROV_AP_PWD, WIFI_PROV_TCP_PORT);
  909. beep_set(BEEP_SCANOK); /* 提示进入配网 */
  910. }
  911. /* 退出热点配网,回到正常STA流程 */
  912. static void wifi_prov_exit(void)
  913. {
  914. wifi_prov_active = 0;
  915. wifi_prov_request = 0;
  916. wifi_prov_state = WIFI_PROV_IDLE;
  917. wifi_prov_wait = 0;
  918. wifi_prov_ipd_len = 0;
  919. wifi_prov_ipd[0] = '\0';
  920. memset(wifi_tx_buf, 0, sizeof(wifi_tx_buf));
  921. wifi_tx_len = 0;
  922. wifi_ack_delay = 0;
  923. wifi_receive_clear();
  924. /* 交给正常流程:WIFI_POWEROFF会先AT+RST复位模块,再按新配置重连 */
  925. WIFI_set_ssid();
  926. Van_Device_Printf(VAN_LOG_WIFI, "\r\n[Provision] exit to normal STA");
  927. }
  928. /* 配网失败,恢复到正常STA模式 */
  929. static void wifi_prov_abort(void)
  930. {
  931. Van_Device_Printf(VAN_LOG_WIFI, "\r\n[Provision] abort, exit to normal STA");
  932. wifi_prov_exit();
  933. }
  934. /* 检查AT指令应答;收到OK后切到okState;出错则重试,超过次数退出配网
  935. * 返回: 1=收到OK并已切状态; 0=仍在等待; -1=失败(已重发或已中止) */
  936. static int wifi_prov_check_cmd_resp(uint8_t okState)
  937. {
  938. if (NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  939. g_wifi_rx_last, "OK\r\n"))
  940. {
  941. wifi_receive_clear();
  942. wifi_prov_wait = 0;
  943. wifi_prov_retry = 0;
  944. wifi_prov_state = okState;
  945. return 1;
  946. }
  947. if (NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  948. g_wifi_rx_last, "ERROR") ||
  949. (uint32_t)(sysinf.conter10ms - wifi_prov_tick) >= wifi_prov_timeout)
  950. {
  951. wifi_receive_clear();
  952. wifi_prov_wait = 0;
  953. if (++wifi_prov_retry < WIFI_PROV_MAX_RETRY)
  954. return -1; /* 由状态机重发指令 */
  955. wifi_prov_abort();
  956. return -1;
  957. }
  958. return 0;
  959. }
  960. /* 查询类AT指令处理: 发送AT+CIPAP?/AT+CWDHCP?后等待回复,收到OK(或超时)后
  961. * 将完整应答打印到调试日志并切到okState状态
  962. * 返回: 0=仍在等待; 1=已收到回复并切状态 */
  963. static uint8_t wifi_prov_query_done(uint8_t okState)
  964. {
  965. char tmp[WIFI_RX_BUF_SIZE];
  966. uint32_t head = g_wifi_rx_head;
  967. uint32_t last = g_wifi_rx_last;
  968. uint32_t n = 0;
  969. if (wifi_prov_wait == 0)
  970. return 0;
  971. /* 线性化接收缓冲,便于查找与打印 */
  972. while (head != last && n < (uint32_t)(WIFI_RX_BUF_SIZE - 1))
  973. {
  974. tmp[n++] = (char)g_wifi_rx_buf[head];
  975. head = (head + 1) % WIFI_RX_BUF_SIZE;
  976. }
  977. tmp[n] = '\0';
  978. if (strstr(tmp, "OK") != NULL ||
  979. (uint32_t)(sysinf.conter10ms - wifi_prov_tick) >= wifi_prov_timeout)
  980. {
  981. /* 打印查询结果(含OK结尾),确认热点IP与DHCP状态 */
  982. Van_Device_Printf(VAN_LOG_WIFI, "\r\n[Provision] <-%s", tmp);
  983. wifi_receive_clear();
  984. wifi_prov_wait = 0;
  985. wifi_prov_retry = 0;
  986. wifi_prov_state = okState;
  987. return 1;
  988. }
  989. return 0;
  990. }
  991. /* 热点配网状态机主处理(每次进入WIFI_process调用) */
  992. static void wifi_prov_process(void)
  993. {
  994. switch (wifi_prov_state)
  995. {
  996. case WIFI_PROV_IDLE:
  997. default:
  998. break;
  999. /* 启动初始化 */
  1000. case WIFI_PROV_START:
  1001. wifi_receive_clear();
  1002. wifi_prov_ipd_len = 0;
  1003. wifi_prov_ipd[0] = '\0';
  1004. wifi_prov_wait = 0;
  1005. wifi_prov_state = WIFI_PROV_RST;
  1006. break;
  1007. /* 1. 复位ESP32,重启进入AP主机模式 */
  1008. case WIFI_PROV_RST:
  1009. wifi_prov_send_cmd("AT+RST", WIFI_PROV_RST_TIMEOUT);
  1010. wifi_prov_state = WIFI_PROV_WAIT_READY;
  1011. wifi_prov_retry = 0;
  1012. break;
  1013. case WIFI_PROV_WAIT_READY:
  1014. if (NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  1015. g_wifi_rx_last, "ready") ||
  1016. NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  1017. g_wifi_rx_last, "boot"))
  1018. {
  1019. wifi_receive_clear();
  1020. wifi_prov_state = WIFI_PROV_MODE;
  1021. }
  1022. else if ((uint32_t)(sysinf.conter10ms - wifi_prov_tick) >= wifi_prov_timeout)
  1023. {
  1024. wifi_receive_clear();
  1025. if (++wifi_prov_retry < WIFI_PROV_MAX_RETRY)
  1026. wifi_prov_state = WIFI_PROV_RST; /* 重试复位 */
  1027. else
  1028. wifi_prov_abort();
  1029. }
  1030. break;
  1031. /* 2. 设置AP模式 */
  1032. case WIFI_PROV_MODE:
  1033. if (wifi_prov_wait != 0)
  1034. wifi_prov_check_cmd_resp(WIFI_PROV_SAP);
  1035. else
  1036. wifi_prov_send_cmd("AT+CWMODE=2", WIFI_PROV_CMD_TIMEOUT);
  1037. break;
  1038. /* 3. 建立热点: 名称OneChip_Mini7, 密码test1234 */
  1039. case WIFI_PROV_SAP:
  1040. {
  1041. char cStr[128] = {0};
  1042. if (wifi_prov_wait != 0)
  1043. wifi_prov_check_cmd_resp(WIFI_PROV_IP_Q);
  1044. else
  1045. {
  1046. my_sprintf(cStr, sizeof(cStr), "AT+CWSAP=\"%s\",\"%s\",%d,%d",
  1047. WIFI_PROV_AP_SSID, WIFI_PROV_AP_PWD,
  1048. WIFI_PROV_AP_CHANNEL, WIFI_PROV_AP_ECN);
  1049. wifi_prov_send_cmd(cStr, WIFI_PROV_CMD_TIMEOUT);
  1050. }
  1051. break;
  1052. }
  1053. /* 4. 查询SoftAP接口IP(默认192.168.4.1),确认热点地址 */
  1054. case WIFI_PROV_IP_Q:
  1055. if (wifi_prov_wait != 0)
  1056. wifi_prov_query_done(WIFI_PROV_DHCP_Q);
  1057. else
  1058. wifi_prov_send_cmd("AT+CIPAP?", WIFI_PROV_CMD_TIMEOUT);
  1059. break;
  1060. /* 5. 查询DHCP使能状态(确认AP侧能分配192.168.4.x) */
  1061. case WIFI_PROV_DHCP_Q:
  1062. if (wifi_prov_wait != 0)
  1063. wifi_prov_query_done(WIFI_PROV_MUX);
  1064. else
  1065. wifi_prov_send_cmd("AT+CWDHCP?", WIFI_PROV_CMD_TIMEOUT);
  1066. break;
  1067. /* 6. 打开多连接 */
  1068. case WIFI_PROV_MUX:
  1069. if (wifi_prov_wait != 0)
  1070. wifi_prov_check_cmd_resp(WIFI_PROV_SERVER);
  1071. else
  1072. wifi_prov_send_cmd("AT+CIPMUX=1", WIFI_PROV_CMD_TIMEOUT);
  1073. break;
  1074. /* 7. 启动TCP服务端: 端口8002 */
  1075. case WIFI_PROV_SERVER:
  1076. {
  1077. char cStr[48] = {0};
  1078. if (wifi_prov_wait != 0)
  1079. {
  1080. if (wifi_prov_check_cmd_resp(WIFI_PROV_LISTEN) == 1)
  1081. wifi_prov_tick = sysinf.conter10ms; /* 记录开始等待配网的时间 */
  1082. }
  1083. else
  1084. {
  1085. my_sprintf(cStr, sizeof(cStr), "AT+CIPSERVER=1,%d", WIFI_PROV_TCP_PORT);
  1086. wifi_prov_send_cmd(cStr, WIFI_PROV_CMD_TIMEOUT);
  1087. }
  1088. break;
  1089. }
  1090. /* 8. 等待手机经TCP下发配网JSON(总超时300s) */
  1091. case WIFI_PROV_LISTEN:
  1092. if ((uint32_t)(sysinf.conter10ms - wifi_prov_tick) >= WIFI_PROV_LISTEN_TIMEOUT)
  1093. {
  1094. Van_Device_Printf(VAN_LOG_WIFI, "\r\n[Provision] wait cfg timeout");
  1095. wifi_prov_wait = 0;
  1096. wifi_prov_state = WIFI_PROV_DONE; /* 超时未收到配置,直接退出 */
  1097. break;
  1098. }
  1099. /* 接收并解析+IPD报文 */
  1100. {
  1101. int ipdRlt = wifi_prov_capture_ipd();
  1102. if (ipdRlt > 0)
  1103. {
  1104. if (wifi_prov_ipd_len >= (uint16_t)(sizeof(wifi_prov_ipd) - 2))
  1105. {
  1106. /* 累积超限,丢弃重收 */
  1107. wifi_receive_clear();
  1108. wifi_prov_ipd_len = 0;
  1109. wifi_prov_ipd[0] = '\0';
  1110. }
  1111. }
  1112. else
  1113. {
  1114. /* 存在接收数据但未解析出有效+IPD,且距最近接收超1s: 打印残留并清空 */
  1115. if (g_wifi_rx_head != g_wifi_rx_last &&
  1116. (uint32_t)(sysinf.conter10ms - g_wifi_rx_last_tick) >= WIFI_PROV_RX_IDLE_TIMEOUT)
  1117. {
  1118. Van_Device_Printf(VAN_LOG_WIFI, "\r\n%s", g_wifi_rx_buf);
  1119. wifi_receive_clear();
  1120. wifi_prov_ipd_len = 0;
  1121. wifi_prov_ipd[0] = '\0';
  1122. }
  1123. }
  1124. }
  1125. /* 累积到完整JSON后解析 */
  1126. if (wifi_prov_ipd_len > 0 &&
  1127. wifi_prov_ipd[0] == '{' &&
  1128. wifi_prov_ipd[wifi_prov_ipd_len - 1] == '}')
  1129. {
  1130. char ssid[sizeof(sysinf.wifiname)];
  1131. char pwd[sizeof(sysinf.password)];
  1132. if (wifi_prov_parse_json(wifi_prov_ipd, ssid, (uint16_t)sizeof(ssid),
  1133. pwd, (uint16_t)sizeof(pwd)) == 0)
  1134. {
  1135. memset(sysinf.wifiname, 0, sizeof(sysinf.wifiname));
  1136. memset(sysinf.password, 0, sizeof(sysinf.password));
  1137. strcpy(sysinf.wifiname, ssid);
  1138. strcpy(sysinf.password, pwd);
  1139. wifi_prov_json_ok = 1;
  1140. Van_Device_Printf(VAN_LOG_WIFI, "\r\n[Provision] got cfg: ssid=%s pwd=%s",
  1141. sysinf.wifiname, sysinf.password);
  1142. }
  1143. else
  1144. {
  1145. wifi_prov_json_ok = 0;
  1146. Van_Device_Printf(VAN_LOG_WIFI, "\r\n[Provision] bad json: %s",
  1147. wifi_prov_ipd);
  1148. }
  1149. wifi_prov_build_ack(wifi_prov_json_ok, "invalid");
  1150. wifi_prov_state = WIFI_PROV_ACK_SEND;
  1151. }
  1152. break;
  1153. /* 9. 向手机应答(accepted/rejected) */
  1154. case WIFI_PROV_ACK_SEND:
  1155. {
  1156. char cStr[48] = {0};
  1157. Van_Device_Printf(VAN_LOG_WIFI, "\r\nack json: %s",
  1158. wifi_prov_ack);
  1159. wifi_receive_clear();
  1160. my_sprintf(cStr, sizeof(cStr), "AT+CIPSEND=%d,%d",
  1161. wifi_prov_linkid, (int)strlen(wifi_prov_ack));
  1162. wifi_prov_send_cmd(cStr, WIFI_PROV_CMD_TIMEOUT);
  1163. /* CIPSEND属非透传"先握手后发数": 复位wait,由ACK_DATA收到OK后真正发载荷 */
  1164. wifi_prov_wait = 0;
  1165. wifi_prov_state = WIFI_PROV_ACK_DATA;
  1166. break;
  1167. }
  1168. case WIFI_PROV_ACK_DATA:
  1169. if (wifi_prov_wait == 0)
  1170. {
  1171. /* 等待 'OK\r\n' 提示符后发送应答数据 */
  1172. if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "OK\r\n"))
  1173. {
  1174. wifi_receive_clear();
  1175. wifi_prov_wait = 1;
  1176. wifi_prov_tick = sysinf.conter10ms;
  1177. wifi_prov_timeout = WIFI_PROV_CMD_TIMEOUT;
  1178. WriteComm2(wifi_prov_ack, strlen(wifi_prov_ack));
  1179. }
  1180. else if (NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  1181. g_wifi_rx_last, "ERROR") ||
  1182. NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  1183. g_wifi_rx_last, "CLOSED") ||
  1184. (uint32_t)(sysinf.conter10ms - wifi_prov_tick) >= wifi_prov_timeout)
  1185. {
  1186. /* 应答失败或超时,继续后续流程 */
  1187. Van_Device_Printf(VAN_LOG_WIFI, "\r\n%s", g_wifi_rx_buf);
  1188. wifi_receive_clear();
  1189. wifi_prov_wait = 0;
  1190. wifi_prov_state = (wifi_prov_json_ok != 0) ? WIFI_PROV_SAVE : WIFI_PROV_LISTEN;
  1191. wifi_prov_ipd_len = 0;
  1192. wifi_prov_ipd[0] = '\0';
  1193. if (wifi_prov_json_ok == 0)
  1194. wifi_prov_tick = sysinf.conter10ms; /* 重新计时 */
  1195. }
  1196. }
  1197. else
  1198. {
  1199. /* 等待SEND OK */
  1200. if (NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  1201. g_wifi_rx_last, "SEND OK") ||
  1202. NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  1203. g_wifi_rx_last, "ERROR") ||
  1204. NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  1205. g_wifi_rx_last, "CLOSED") ||
  1206. (uint32_t)(sysinf.conter10ms - wifi_prov_tick) >= wifi_prov_timeout)
  1207. {
  1208. Van_Device_Printf(VAN_LOG_WIFI, "\r\n%s", g_wifi_rx_buf);
  1209. wifi_receive_clear();
  1210. wifi_prov_wait = 0;
  1211. wifi_prov_state = (wifi_prov_json_ok != 0) ? WIFI_PROV_SAVE : WIFI_PROV_LISTEN;
  1212. wifi_prov_ipd_len = 0; /* 无效配置则清空缓存重新等待 */
  1213. wifi_prov_ipd[0] = '\0';
  1214. if (wifi_prov_json_ok == 0)
  1215. wifi_prov_tick = sysinf.conter10ms; /* 重新计时 */
  1216. }
  1217. }
  1218. break;
  1219. /* 10. 保存配网参数到Flash */
  1220. case WIFI_PROV_SAVE:
  1221. {
  1222. uint8_t saveRlt = cfg_save_cfg_param();
  1223. Van_Device_Printf(VAN_LOG_WIFI, "\r\n[Provision] cfg_save_cfg_param=%d", saveRlt);
  1224. wifi_prov_state = WIFI_PROV_DONE;
  1225. break;
  1226. }
  1227. /* 11. 配网完成: 复位ESP32进入正常模式 */
  1228. case WIFI_PROV_DONE:
  1229. wifi_prov_exit();
  1230. break;
  1231. }
  1232. }
  1233. //wifi任务
  1234. void WIFI_process()
  1235. {
  1236. /* 热点配网模式优先处理 */
  1237. if (wifi_prov_request != 0 || wifi_prov_active != 0)
  1238. {
  1239. if (wifi_prov_request != 0)
  1240. {
  1241. wifi_prov_request = 0;
  1242. wifi_prov_enter();
  1243. }
  1244. wifi_prov_process();
  1245. return;
  1246. }
  1247. if(sysinf.pc_channel_recv == 2 && wifi_state > WIFI_SETMUX){
  1248. /*串口状态下,不走wifi处理*/
  1249. return;
  1250. }
  1251. WIFI_recv_deal();
  1252. WIFI_send_deal();
  1253. }
  1254. static uint32_t m_pow_n(uint32_t m, int32_t n)
  1255. {
  1256. uint32_t i = 0, ret = 1;
  1257. if (n < 0) return 0;
  1258. for (i = 0; i < n; i++)
  1259. {
  1260. ret *= m;
  1261. }
  1262. return ret;
  1263. }
  1264. // 返回值为打印字符的个数
  1265. // 支持%d,%o, %x,%s,%c,%f(只打印6位数字)
  1266. int my_sprintf(char *pdes,unsigned int len, const char* str, ...)
  1267. {
  1268. if (str == NULL) return -1;
  1269. uint32_t ret_num = 0;// 返回打印字符的个数
  1270. char* pStr = (char*)str;// 指向str
  1271. int ArgIntVal = 0; // 接收整型
  1272. uint32_t ArgHexVal = 0;// 接十六进制
  1273. char* ArgStrVal = NULL; // 接收字符型
  1274. double ArgFloVal = 0.0; // 接受浮点型
  1275. uint32_t val_seg = 0; // 数据切分
  1276. uint32_t val_temp = 0; // 临时保存数据
  1277. int cnt = 0; // 数据长度计数
  1278. int cnt_float = 0; // 数据长度计数
  1279. va_list pArgs; // 定义va_list类型指针,用于存储参数的地址
  1280. va_start(pArgs, str); // 初始化pArgs
  1281. while (*pStr != '\0')
  1282. {
  1283. switch (*pStr)
  1284. {
  1285. case ' ':
  1286. case '\r':
  1287. case '\n':
  1288. *pdes++ = (*pStr); ret_num++; break;
  1289. case '\t':
  1290. *pdes++ =(*pStr); ret_num += 4; break;
  1291. case '%':
  1292. pStr++;
  1293. // % 格式解析
  1294. if('.' == *pStr)
  1295. {
  1296. pStr++;
  1297. cnt_float = *pStr - '0';// %.Nf,输出指定位数小数
  1298. pStr++;
  1299. }
  1300. switch (*pStr)
  1301. {
  1302. case '%':
  1303. *pdes++ =('%');// %%,输出%
  1304. ret_num++;
  1305. pStr++;
  1306. continue;
  1307. case 'c':
  1308. ArgIntVal = va_arg(pArgs, int);// %c,输出char
  1309. *pdes++ =((char)ArgIntVal);
  1310. ret_num++;
  1311. pStr++;
  1312. continue;
  1313. case 'd':
  1314. // 接收整型
  1315. ArgIntVal = va_arg(pArgs, int);
  1316. if (ArgIntVal < 0)// 如果为负数打印,负号
  1317. {
  1318. ArgIntVal = -ArgIntVal;// 取相反数
  1319. *pdes++ =('-');
  1320. ret_num++;
  1321. }
  1322. val_seg = ArgIntVal;// 赋值给 val_seg处理数据
  1323. // 计算ArgIntVal长度
  1324. if (ArgIntVal)
  1325. {
  1326. while (val_seg) {
  1327. cnt++;
  1328. val_seg /= 10;
  1329. }
  1330. }
  1331. else cnt = 1;// 数字0的长度为1
  1332. ret_num += cnt;// 字符个数加上整数的长度
  1333. // 将整数转为单个字符打印
  1334. while (cnt)
  1335. {
  1336. val_seg = ArgIntVal / m_pow_n(10, cnt - 1);
  1337. ArgIntVal %= m_pow_n(10, cnt - 1);
  1338. *pdes++ =((char)val_seg + '0');
  1339. cnt--;
  1340. }
  1341. pStr++;
  1342. continue;
  1343. case 'o':
  1344. // 接收整型
  1345. ArgIntVal = va_arg(pArgs, int);
  1346. if (ArgIntVal < 0)// 如果为负数打印,负号
  1347. {
  1348. ArgIntVal = -ArgIntVal;// 取相反数
  1349. *pdes++ =('-');
  1350. ret_num++;
  1351. }
  1352. val_seg = ArgIntVal;// 赋值给 val_seg处理数据
  1353. // 计算ArgIntVal长度
  1354. if (ArgIntVal)
  1355. {
  1356. while (val_seg) {
  1357. cnt++;
  1358. val_seg /= 8;
  1359. }
  1360. }
  1361. else cnt = 1;// 数字0的长度为1
  1362. ret_num += cnt;// 字符个数加上整数的长度
  1363. // 将整数转为单个字符打印
  1364. while (cnt)
  1365. {
  1366. val_seg = ArgIntVal / m_pow_n(8, cnt - 1);
  1367. ArgIntVal %= m_pow_n(8, cnt - 1);
  1368. *pdes++ =((char)val_seg + '0');
  1369. cnt--;
  1370. }
  1371. pStr++;
  1372. continue;
  1373. case 'x':
  1374. // 接收16进制
  1375. ArgHexVal = va_arg(pArgs, uint32_t);
  1376. val_seg = ArgHexVal;
  1377. // 计算ArgIntVal长度
  1378. if (ArgHexVal)
  1379. {
  1380. while (val_seg) {
  1381. cnt++;
  1382. val_seg /= 16;
  1383. }
  1384. }
  1385. else cnt = 1;// 数字0的长度为1
  1386. ret_num += cnt;// 字符个数加上整数的长度
  1387. // 将整数转为单个字符打印
  1388. while (cnt)
  1389. {
  1390. val_seg = ArgHexVal / m_pow_n(16, cnt - 1);
  1391. ArgHexVal %= m_pow_n(16, cnt - 1);
  1392. if (val_seg <= 9)
  1393. *pdes++ =((char)val_seg + '0');
  1394. else
  1395. {
  1396. //*pdes++ =((char)val_seg - 10 + 'a'); //小写字母
  1397. *pdes++ =((char)val_seg - 10 + 'A');
  1398. }
  1399. cnt--;
  1400. }
  1401. pStr++;
  1402. continue;
  1403. case 'b':
  1404. // 接收整型
  1405. ArgIntVal = va_arg(pArgs, int);
  1406. val_seg = ArgIntVal;
  1407. // 计算ArgIntVal长度
  1408. if (ArgIntVal)
  1409. {
  1410. while (val_seg) {
  1411. cnt++;
  1412. val_seg /= 2;
  1413. }
  1414. }
  1415. else cnt = 1;// 数字0的长度为1
  1416. ret_num += cnt;// 字符个数加上整数的长度
  1417. // 将整数转为单个字符打印
  1418. while (cnt)
  1419. {
  1420. val_seg = ArgIntVal / m_pow_n(2, cnt - 1);
  1421. ArgIntVal %= m_pow_n(2, cnt - 1);
  1422. *pdes++ =((char)val_seg + '0');
  1423. cnt--;
  1424. }
  1425. pStr++;
  1426. continue;
  1427. case 's':
  1428. // 接收字符
  1429. ArgStrVal = va_arg(pArgs, char*);
  1430. ret_num += (uint32_t)strlen(ArgStrVal);
  1431. while (*ArgStrVal)
  1432. {
  1433. *pdes++ =(*ArgStrVal);
  1434. ArgStrVal++;
  1435. }
  1436. pStr++;
  1437. continue;
  1438. case 'f':
  1439. // 接收浮点型 保留6为小数,不采取四舍五入
  1440. ArgFloVal = va_arg(pArgs, double);
  1441. val_seg = (uint32_t)ArgFloVal;// 取整数部分
  1442. val_temp = val_seg; // 临时保存整数部分数据
  1443. ArgFloVal = ArgFloVal - val_seg;// 得出余下的小数部分
  1444. // 计算整数部分长度
  1445. if (val_seg)
  1446. {
  1447. while (val_seg) {
  1448. cnt++;
  1449. val_seg /= 10;
  1450. }
  1451. }
  1452. else cnt = 1;// 数字0的长度为1
  1453. ret_num += cnt;// 字符个数加上整数的长度
  1454. // 将整数转为单个字符打印
  1455. while (cnt)
  1456. {
  1457. val_seg = val_temp / m_pow_n(10, cnt - 1);
  1458. val_temp %= m_pow_n(10, cnt - 1);
  1459. *pdes++ =((char)val_seg + '0');
  1460. cnt--;
  1461. }
  1462. // 打印小数点
  1463. *pdes++ =('.');
  1464. ret_num++;
  1465. // printf("\r\n %f\r\n", ArgFloVal);
  1466. if(cnt_float == 0)
  1467. cnt_float = 6;
  1468. // 开始输出小数部分
  1469. //ArgFloVal *= 1000000;
  1470. ArgFloVal *= m_pow_n(10, cnt_float);
  1471. val_temp = (int)ArgFloVal;// 取整数部分
  1472. while (cnt_float)
  1473. {
  1474. val_seg = val_temp / m_pow_n(10, cnt_float - 1);
  1475. val_temp %= m_pow_n(10, cnt_float - 1);
  1476. *pdes++ =((char)val_seg + '0');
  1477. cnt_float--;
  1478. }
  1479. ret_num += 6;
  1480. pStr++;
  1481. continue;
  1482. default:// % 匹配错误,暂输出空格
  1483. *pdes++ =(' '); ret_num++;
  1484. break;
  1485. }
  1486. break;
  1487. default:
  1488. *pdes++ =(*pStr); ret_num++;
  1489. break;
  1490. }
  1491. pStr++;
  1492. if(ret_num > len){
  1493. break;
  1494. }
  1495. }
  1496. va_end(pArgs);// 结束取参数
  1497. *pdes++ = 0;
  1498. return ret_num;
  1499. }