ESP32_WROOM_32D.c 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669
  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. /* 过滤其他设备的UDP广播: 命令为PC_CMD_SETIP且数据以"Mini7"开头(本机send_Devinf_pc广播的设备信息),
  491. 说明是同类设备发出的广播而非上位机下发的SETIP,丢弃不做后续处理 */
  492. if(iProcLen > 0 && PC_CMD_SETIP == uart0_massage.cmd &&
  493. strncmp((const char *)uart0_data, "Mini7", 5) == 0)
  494. {
  495. Van_Device_Printf(VAN_LOG_WIFI, "\n[WiFi] filter peer device broadcast");
  496. wifi_receive_clear();
  497. iProcLen = 0; /* 标记为已过滤,跳过后续PC命令处理 */
  498. }
  499. if (iProcLen > 0) {
  500. sysinf.pc_channel_recv = PC_CONNECT_TYPE_WIFI;
  501. sysinf.pc_link_timeout = 0;
  502. uart0_massage.data = (char *)uart0_data;
  503. query_pc_cmd(&uart0_massage);
  504. wifi_receive_clear();
  505. }
  506. // wifi_receive_clear();
  507. // set_pc_chanel_recv(1);
  508. // b2b_recv_data(p, udp_data_len);
  509. }
  510. break;
  511. case WIFI_CLOSE:{
  512. if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "CLOSED\r\n"))
  513. {
  514. wifi_state = WIFI_LISTEN;
  515. wifi_ack_delay = 0;
  516. }
  517. }
  518. break;
  519. default:
  520. break;
  521. }
  522. if(WIFI_TRANS != wifi_state){
  523. wifi_receive_clear();
  524. }
  525. }
  526. void WIFI_send_deal(void)
  527. {
  528. static uint8_t try_count = 0;
  529. static uint8_t try_con = 0;
  530. static uint32_t wifi_start_delay = 0;
  531. static uint8_t res_count = 0;
  532. uint8_t wifi_result = 0;
  533. //启动超时
  534. if(wifi_state < WIFI_LISTEN && wifi_start_delay++ > 120*10)
  535. {
  536. wifi_start_delay = 0;
  537. wifi_state = WIFI_POWEROFF;
  538. wifi_ack_delay = 0;
  539. }
  540. //等待模块应答
  541. if(wifi_ack_delay > 0)
  542. {
  543. wifi_ack_delay -= 100;
  544. return;
  545. }
  546. if(resendtime >= MAX_RESEND_TIME){
  547. wifi_state = WIFI_POWEROFF;
  548. }
  549. if((WIFI_TRANS != wifi_state )|| ((WIFI_TRANS == wifi_state)&& wifi_tx_len )){
  550. resendtime++;
  551. }
  552. switch (wifi_state)
  553. {
  554. case WIFI_POWEROFF:
  555. case WIFI_ERROR:
  556. ESP32_AT_RST();
  557. wifi_start_delay = 0;
  558. resendtime = 0;
  559. try_count = 0;
  560. if(sysinf.connectTcpFlag){
  561. /*持续5次均不能链接到tcp,状态回退,重启链接udp*/
  562. res_count++;
  563. if(res_count > 5){
  564. sysinf.connectTcpFlag = 0;
  565. }
  566. }
  567. break;
  568. case WIFI_POWERON:
  569. ESP32_AT();
  570. break;
  571. case WIFI_INIT:
  572. ESP32_EchoOff();
  573. break;
  574. case WIFI_STATION:
  575. ESP32_Net_Mode_Choose(STA);
  576. break;
  577. case WIFI_DISAUTO:
  578. ESP32_DisAutoLink();
  579. try_count = 0;
  580. resendtime = 0;
  581. break;
  582. case WIFI_CWLAP:
  583. ESP32_CWLAP(sysinf.wifiname);
  584. try_count++;
  585. if(try_count == MAX_RESEND_TIME)
  586. {
  587. wifi_state = WIFI_POWEROFF;
  588. if(wifi_set_ssid == 1)
  589. {
  590. wifi_set_ssid = 0;
  591. wifi_result = 0xff;
  592. data_send_to_pc(PC_CMD_SETWIFI, (char *)&wifi_result, 1);
  593. }
  594. Van_Device_Printf(VAN_LOG_ERROR, "no wifi AP:%s\n\r",sysinf.wifiname);
  595. }
  596. try_con = 0;
  597. resendtime = 0;
  598. break;
  599. case WIFI_LINK_AP:
  600. ESP32_JoinAP(sysinf.wifiname, sysinf.password,MAC_ADDR);
  601. try_con++ ;
  602. if(try_con == MAX_RESEND_TIME)
  603. {
  604. wifi_state = WIFI_POWEROFF;
  605. if(wifi_set_ssid == 1)
  606. {
  607. wifi_set_ssid = 0;
  608. wifi_result = 0xfe;
  609. data_send_to_pc(PC_CMD_SETWIFI, (char *)&wifi_result, 1);
  610. }
  611. Van_Device_Printf(VAN_LOG_ERROR, "can't jonn AP:%s %s\n\r",sysinf.wifiname,sysinf.password);
  612. }
  613. break;
  614. case WIFI_GET_IP:
  615. ESP32_GetIp();
  616. if(wifi_set_ssid == 1)
  617. {
  618. wifi_set_ssid = 0;
  619. wifi_result = 1;
  620. data_send_to_pc(PC_CMD_SETWIFI, (char *)&wifi_result, 1);
  621. }
  622. break;
  623. case WIFI_SETMUX:
  624. ESP32_Enable_MultipleId(1);
  625. break;
  626. case WIFI_LISTEN:
  627. if(sysinf.connectTcpFlag){
  628. if(resendtime < MAX_RESEND_TIME)
  629. {
  630. ESP32_Link_Server(enumTCP,sysinf.TCP_IP_Addr, sysinf.TCP_IP_PORT, Multiple_ID_0);
  631. }else{
  632. /*多次TCP未链接,链接UDP*/
  633. // connectTcpFlag = 0;
  634. // resendtime = 0;
  635. memset(wifi_tx_buf, 0, sizeof(wifi_tx_buf));
  636. wifi_tx_len = 0;
  637. }
  638. }else{
  639. if(resendtime < MAX_RESEND_TIME)
  640. {
  641. ESP32_Link_Server(enumUDP,User_ESP32_UDPServer_IP, User_ESP32_UDPServer_PORT, Multiple_ID_0);
  642. }
  643. }
  644. break;
  645. case WIFI_TRANS:
  646. if(resendtime < MAX_RESEND_TIME)
  647. {
  648. if(wifi_tx_len){
  649. char cStr [40] = {0};
  650. Van_Device_Printf(VAN_LOG_WIFI,"\nbuflen:%d %d %s",g_wifi_rx_head,g_wifi_rx_last, g_wifi_rx_buf);
  651. my_sprintf ( cStr,sizeof(cStr),"AT+CIPSEND=0,%d", wifi_tx_len );
  652. ESP32_Send_AT_Cmd ( cStr, 3000 );
  653. }
  654. }
  655. if(sysinf.connectTcpFlag){
  656. /*tcp链接上,复位计数清零*/
  657. res_count = 0;
  658. }
  659. break;
  660. case WIFI_CLOSE:
  661. ESP32_STOPTCP(Single_ID_0);
  662. break;
  663. default:
  664. wifi_state = WIFI_ERROR;
  665. break;
  666. }
  667. }
  668. /* ========================================================================
  669. * 热点配网(SoftAP WiFi配网)状态机
  670. * 触发 : 按键长按30s -> WIFI_provision_request() (usr_motor.c)
  671. * 流程 : 复位ESP32 -> AP模式(AT+CWMODE=2) -> 建热点
  672. * OneChip_Mini7 / test1234 (192.168.4.1/255.255.255.0)
  673. * -> AT+CIPAP? 查询热点IP -> AT+CWDHCP? 查询DHCP状态
  674. * -> AT+CIPMUX=1 -> AT+CIPSERVER=1,8002 启动TCP服务
  675. * -> 手机连接热点,经TCP 8002下发:
  676. * {"ssid":"Onechip_602","password":"onchip1003"}
  677. * -> 解析JSON, ssid->sysinf.wifiname, password->sysinf.password
  678. * -> cfg_save_cfg_param() 保存到Flash
  679. * -> 复位ESP32进入正常STA模式(按新配置自动连接)
  680. * 说明 : 热点地址192.168.4.1/255.255.255.0为ESP32 SoftAP默认值,无需配置
  681. * ===================================================================== */
  682. #define WIFI_PROV_AP_SSID "OneChip_Mini7" /* 热点名称 */
  683. #define WIFI_PROV_AP_PWD "test1234" /* 热点密码 */
  684. #define WIFI_PROV_AP_CHANNEL 6 /* 信道 */
  685. #define WIFI_PROV_AP_ECN 3 /* 加密:3=WPA2_PSK */
  686. #define WIFI_PROV_TCP_PORT 8002 /* TCP服务端口 */
  687. #define WIFI_PROV_CMD_TIMEOUT 500 /* 单条AT指令超时:5s(10ms) */
  688. #define WIFI_PROV_RST_TIMEOUT 1000 /* AT+RST等待ready:10s */
  689. #define WIFI_PROV_LISTEN_TIMEOUT 30000 /* 等待配网数据总超时:300s */
  690. #define WIFI_PROV_MAX_RETRY 3 /* 指令失败重试次数 */
  691. #define WIFI_PROV_RX_IDLE_TIMEOUT 100 /* 无有效IPD残留数据清空时限:1s(10ms) */
  692. typedef enum
  693. {
  694. WIFI_PROV_IDLE = 0, /* 空闲 */
  695. WIFI_PROV_START, /* 启动初始化 */
  696. WIFI_PROV_RST, /* 复位ESP32,重启进入AP主机模式 */
  697. WIFI_PROV_WAIT_READY, /* 等待模块重启完成 */
  698. WIFI_PROV_MODE, /* AT+CWMODE=2 设置AP模式 */
  699. WIFI_PROV_SAP, /* AT+CWSAP 建立热点 */
  700. WIFI_PROV_IP_Q, /* AT+CIPAP? 查询SoftAP接口IP(默认192.168.4.1) */
  701. WIFI_PROV_DHCP_Q, /* AT+CWDHCP? 查询DHCP使能状态 */
  702. WIFI_PROV_MUX, /* AT+CIPMUX=1 打开多连接 */
  703. WIFI_PROV_SERVER, /* AT+CIPSERVER=1,8002 启动TCP服务 */
  704. WIFI_PROV_LISTEN, /* 等待手机下发配网JSON */
  705. WIFI_PROV_ACK_SEND, /* AT+CIPSEND 向手机应答 */
  706. WIFI_PROV_ACK_DATA, /* 等待'>'并发送应答数据 */
  707. WIFI_PROV_SAVE, /* 保存配置到Flash */
  708. WIFI_PROV_DONE, /* 配网完成,复位进入正常模式 */
  709. } wifi_prov_state_t;
  710. static volatile uint8_t wifi_prov_request = 0; /* 配网请求标志(可被ISR置位) */
  711. static uint8_t wifi_prov_active = 0; /* 配网进行中 */
  712. static uint8_t wifi_prov_state = WIFI_PROV_IDLE;
  713. static uint8_t wifi_prov_retry = 0;
  714. static uint8_t wifi_prov_wait = 0; /* 1=正在等待应答 */
  715. static uint8_t wifi_prov_json_ok = 0; /* 解析到的配置是否有效 */
  716. static uint8_t wifi_prov_linkid = 0; /* TCP链路ID */
  717. static uint32_t wifi_prov_tick = 0; /* 起始时间戳(10ms单位) */
  718. static uint32_t wifi_prov_timeout = 0; /* 等待超时(10ms单位) */
  719. static char wifi_prov_ipd[WIFI_RX_BUF_SIZE];/* +IPD载荷累积缓存(JSON) */
  720. static uint16_t wifi_prov_ipd_len = 0;
  721. static char wifi_prov_ack[WIFI_RX_BUF_SIZE];/* 应答JSON */
  722. static void wifi_prov_enter(void);
  723. static void wifi_prov_exit(void);
  724. static void wifi_prov_abort(void);
  725. /* 配网进行中? */
  726. uint8_t WIFI_provision_active(void)
  727. {
  728. return wifi_prov_active;
  729. }
  730. /* 请求进入热点配网模式(按键长按30s调用,允许在中断中调用) */
  731. uint8_t WIFI_provision_request(void)
  732. {
  733. if (wifi_prov_active != 0)
  734. return 0; /* 已在配网中 */
  735. wifi_prov_request = 1;
  736. return 1;
  737. }
  738. /* 配网状态机内部发送AT指令 */
  739. static void wifi_prov_send_cmd(const char *cmd, uint32_t timeout10ms)
  740. {
  741. char buff[128] = {0};
  742. strcpy(buff, cmd);
  743. strcat(buff, "\r\n");
  744. Van_Device_Printf(VAN_LOG_WIFI, "\nP--> %s", buff);
  745. WriteComm2(buff, strlen(buff));
  746. wifi_prov_wait = 1;
  747. wifi_prov_tick = sysinf.conter10ms;
  748. wifi_prov_timeout = timeout10ms;
  749. }
  750. /* 从ESP接收环中提取一个完整的+IPD报文载荷并追加到累积缓存
  751. * 返回: 1=取到完整报文; 0=暂无完整报文(继续等待);
  752. * -1=帧头/载荷异常(不打印、不清空、不消费,继续等待直到总超时退出) */
  753. static int wifi_prov_capture_ipd(void)
  754. {
  755. uint32_t head = g_wifi_rx_head;
  756. uint32_t last = g_wifi_rx_last;
  757. uint32_t avail = (last + WIFI_RX_BUF_SIZE - head) % WIFI_RX_BUF_SIZE;
  758. int pos = -1;
  759. uint32_t i;
  760. if (avail == 0)
  761. return 0;
  762. /* 查找"+IPD,"头 */
  763. for (i = 0; (i + 5) <= avail; i++)
  764. {
  765. uint32_t p = (head + i) % WIFI_RX_BUF_SIZE;
  766. if (g_wifi_rx_buf[p] == '+' &&
  767. g_wifi_rx_buf[(p + 1) % WIFI_RX_BUF_SIZE] == 'I' &&
  768. g_wifi_rx_buf[(p + 2) % WIFI_RX_BUF_SIZE] == 'P' &&
  769. g_wifi_rx_buf[(p + 3) % WIFI_RX_BUF_SIZE] == 'D' &&
  770. g_wifi_rx_buf[(p + 4) % WIFI_RX_BUF_SIZE] == ',')
  771. {
  772. pos = (int)i;
  773. break;
  774. }
  775. }
  776. if (pos < 0)
  777. return 0; /* 缓冲内无+IPD报文 */
  778. i = (uint32_t)(pos + 5);
  779. if (i >= avail)
  780. return 0; /* 帧头不完整,继续等待 */
  781. /* 解析头: +IPD,<linkID>,<len>: */
  782. if (g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] < '0' ||
  783. g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] > '9')
  784. return -1; /* linkid非数字,帧损坏 */
  785. {
  786. uint32_t linkid = 0;
  787. while (i < avail &&
  788. g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] >= '0' &&
  789. g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] <= '9')
  790. {
  791. linkid = linkid * 10 + (uint32_t)(g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] - '0');
  792. i++;
  793. }
  794. if (i >= avail)
  795. return 0; /* linkid未完,继续等待 */
  796. if (g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] != ',')
  797. return -1; /* 缺少逗号分隔,帧损坏 */
  798. wifi_prov_linkid = (uint8_t)linkid;
  799. i++;
  800. if (i >= avail)
  801. return 0;
  802. if (g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] < '0' ||
  803. g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] > '9')
  804. return -1; /* 长度非数字,帧损坏 */
  805. {
  806. uint32_t pktlen = 0;
  807. while (i < avail &&
  808. g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] >= '0' &&
  809. g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] <= '9')
  810. {
  811. pktlen = pktlen * 10 + (uint32_t)(g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] - '0');
  812. i++;
  813. }
  814. if (i >= avail)
  815. return 0; /* len未完,继续等待 */
  816. if (g_wifi_rx_buf[(head + i) % WIFI_RX_BUF_SIZE] != ':')
  817. return -1; /* 缺少冒号分隔,帧损坏 */
  818. i++; /* 跳过 ':' */
  819. if (pktlen == 0)
  820. return -1; /* 空载荷异常 */
  821. if (avail < i + pktlen)
  822. return 0; /* 载荷尚未收完,继续等待 */
  823. if ((uint16_t)(wifi_prov_ipd_len + pktlen) < sizeof(wifi_prov_ipd))
  824. {
  825. uint32_t k;
  826. for (k = 0; k < pktlen; k++)
  827. {
  828. char c = (char)g_wifi_rx_buf[(head + i + k) % WIFI_RX_BUF_SIZE];
  829. if (c == '\r' || c == '\n') /* 去掉行结束符 */
  830. continue;
  831. wifi_prov_ipd[wifi_prov_ipd_len++] = c;
  832. }
  833. wifi_prov_ipd[wifi_prov_ipd_len] = '\0';
  834. }
  835. else
  836. {
  837. /* 载荷超限无法累积: 丢弃该帧载荷,重新接收 */
  838. wifi_prov_ipd_len = 0;
  839. wifi_prov_ipd[0] = '\0';
  840. }
  841. /* 消费该报文 */
  842. g_wifi_rx_head = (head + i + pktlen) % WIFI_RX_BUF_SIZE;
  843. return 1;
  844. }
  845. }
  846. }
  847. /* 解析配网JSON: {"ssid":"xxx","password":"xxx"}
  848. * 返回: 0=成功; -1=失败 */
  849. static int wifi_prov_parse_json(const char *json, char *ssid, uint16_t ssidCap,
  850. char *pwd, uint16_t pwdCap)
  851. {
  852. cJSON *root = NULL;
  853. cJSON *it = NULL;
  854. int rlt = -1;
  855. if (json == NULL || json[0] != '{' || ssid == NULL || pwd == NULL)
  856. return -1;
  857. ssid[0] = '\0';
  858. pwd[0] = '\0';
  859. root = cJSON_Parse(json);
  860. if (root == NULL)
  861. return -1;
  862. it = cJSON_GetObjectItem(root, "ssid");
  863. if (it == NULL || !cJSON_IsString(it) || it->valuestring == NULL ||
  864. it->valuestring[0] == '\0')
  865. goto out; /* 必须包含非空ssid */
  866. if (strlen(it->valuestring) >= (size_t)ssidCap)
  867. goto out; /* ssid超长 */
  868. strcpy(ssid, it->valuestring);
  869. it = cJSON_GetObjectItem(root, "password");
  870. if (it != NULL && cJSON_IsString(it) && it->valuestring != NULL)
  871. {
  872. if (strlen(it->valuestring) >= (size_t)pwdCap)
  873. goto out; /* 密码超长 */
  874. strcpy(pwd, it->valuestring); /* 允许开放网络密码为空 */
  875. }
  876. rlt = 0;
  877. out:
  878. cJSON_Delete(root);
  879. return rlt;
  880. }
  881. /* 生成应答JSON */
  882. static void wifi_prov_build_ack(uint8_t accepted, const char *reason)
  883. {
  884. if (accepted)
  885. {
  886. my_sprintf(wifi_prov_ack, sizeof(wifi_prov_ack),
  887. "{\"v\":1,\"status\":\"accepted\",\"sn\":\"%s\"}\r\n",
  888. sysinf.SN);
  889. }
  890. else
  891. {
  892. if (reason == NULL)
  893. reason = "invalid";
  894. my_sprintf(wifi_prov_ack, sizeof(wifi_prov_ack),
  895. "{\"v\":1,\"status\":\"rejected\",\"reason\":\"%s\"}\r\n",
  896. reason);
  897. }
  898. }
  899. /* 进入热点配网模式 */
  900. static void wifi_prov_enter(void)
  901. {
  902. wifi_prov_active = 1;
  903. wifi_prov_state = WIFI_PROV_START;
  904. wifi_prov_retry = 0;
  905. wifi_prov_wait = 0;
  906. wifi_prov_linkid = 0;
  907. wifi_prov_json_ok = 0;
  908. wifi_prov_ipd_len = 0;
  909. wifi_prov_ipd[0] = '\0';
  910. memset(wifi_tx_buf, 0, sizeof(wifi_tx_buf));
  911. wifi_tx_len = 0;
  912. wifi_ack_delay = 0;
  913. wifi_state = WIFI_POWEROFF; /* 暂停正常wifi流程 */
  914. wifi_receive_clear();
  915. Van_Device_Printf(VAN_LOG_WIFI,
  916. "\r\n[Provision] enter, AP=%s pwd=%s port=%d",
  917. WIFI_PROV_AP_SSID, WIFI_PROV_AP_PWD, WIFI_PROV_TCP_PORT);
  918. beep_set(BEEP_SCANOK); /* 提示进入配网 */
  919. }
  920. /* 退出热点配网,回到正常STA流程 */
  921. static void wifi_prov_exit(void)
  922. {
  923. wifi_prov_active = 0;
  924. wifi_prov_request = 0;
  925. wifi_prov_state = WIFI_PROV_IDLE;
  926. wifi_prov_wait = 0;
  927. wifi_prov_ipd_len = 0;
  928. wifi_prov_ipd[0] = '\0';
  929. memset(wifi_tx_buf, 0, sizeof(wifi_tx_buf));
  930. wifi_tx_len = 0;
  931. wifi_ack_delay = 0;
  932. wifi_receive_clear();
  933. /* 交给正常流程:WIFI_POWEROFF会先AT+RST复位模块,再按新配置重连 */
  934. WIFI_set_ssid();
  935. Van_Device_Printf(VAN_LOG_WIFI, "\r\n[Provision] exit to normal STA");
  936. }
  937. /* 配网失败,恢复到正常STA模式 */
  938. static void wifi_prov_abort(void)
  939. {
  940. Van_Device_Printf(VAN_LOG_WIFI, "\r\n[Provision] abort, exit to normal STA");
  941. wifi_prov_exit();
  942. }
  943. /* 检查AT指令应答;收到OK后切到okState;出错则重试,超过次数退出配网
  944. * 返回: 1=收到OK并已切状态; 0=仍在等待; -1=失败(已重发或已中止) */
  945. static int wifi_prov_check_cmd_resp(uint8_t okState)
  946. {
  947. if (NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  948. g_wifi_rx_last, "OK\r\n"))
  949. {
  950. wifi_receive_clear();
  951. wifi_prov_wait = 0;
  952. wifi_prov_retry = 0;
  953. wifi_prov_state = okState;
  954. return 1;
  955. }
  956. if (NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  957. g_wifi_rx_last, "ERROR") ||
  958. (uint32_t)(sysinf.conter10ms - wifi_prov_tick) >= wifi_prov_timeout)
  959. {
  960. wifi_receive_clear();
  961. wifi_prov_wait = 0;
  962. if (++wifi_prov_retry < WIFI_PROV_MAX_RETRY)
  963. return -1; /* 由状态机重发指令 */
  964. wifi_prov_abort();
  965. return -1;
  966. }
  967. return 0;
  968. }
  969. /* 查询类AT指令处理: 发送AT+CIPAP?/AT+CWDHCP?后等待回复,收到OK(或超时)后
  970. * 将完整应答打印到调试日志并切到okState状态
  971. * 返回: 0=仍在等待; 1=已收到回复并切状态 */
  972. static uint8_t wifi_prov_query_done(uint8_t okState)
  973. {
  974. char tmp[WIFI_RX_BUF_SIZE];
  975. uint32_t head = g_wifi_rx_head;
  976. uint32_t last = g_wifi_rx_last;
  977. uint32_t n = 0;
  978. if (wifi_prov_wait == 0)
  979. return 0;
  980. /* 线性化接收缓冲,便于查找与打印 */
  981. while (head != last && n < (uint32_t)(WIFI_RX_BUF_SIZE - 1))
  982. {
  983. tmp[n++] = (char)g_wifi_rx_buf[head];
  984. head = (head + 1) % WIFI_RX_BUF_SIZE;
  985. }
  986. tmp[n] = '\0';
  987. if (strstr(tmp, "OK") != NULL ||
  988. (uint32_t)(sysinf.conter10ms - wifi_prov_tick) >= wifi_prov_timeout)
  989. {
  990. /* 打印查询结果(含OK结尾),确认热点IP与DHCP状态 */
  991. Van_Device_Printf(VAN_LOG_WIFI, "\r\n[Provision] <-%s", tmp);
  992. wifi_receive_clear();
  993. wifi_prov_wait = 0;
  994. wifi_prov_retry = 0;
  995. wifi_prov_state = okState;
  996. return 1;
  997. }
  998. return 0;
  999. }
  1000. /* 热点配网状态机主处理(每次进入WIFI_process调用) */
  1001. static void wifi_prov_process(void)
  1002. {
  1003. switch (wifi_prov_state)
  1004. {
  1005. case WIFI_PROV_IDLE:
  1006. default:
  1007. break;
  1008. /* 启动初始化 */
  1009. case WIFI_PROV_START:
  1010. wifi_receive_clear();
  1011. wifi_prov_ipd_len = 0;
  1012. wifi_prov_ipd[0] = '\0';
  1013. wifi_prov_wait = 0;
  1014. wifi_prov_state = WIFI_PROV_RST;
  1015. break;
  1016. /* 1. 复位ESP32,重启进入AP主机模式 */
  1017. case WIFI_PROV_RST:
  1018. wifi_prov_send_cmd("AT+RST", WIFI_PROV_RST_TIMEOUT);
  1019. wifi_prov_state = WIFI_PROV_WAIT_READY;
  1020. wifi_prov_retry = 0;
  1021. break;
  1022. case WIFI_PROV_WAIT_READY:
  1023. if (NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  1024. g_wifi_rx_last, "ready") ||
  1025. NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  1026. g_wifi_rx_last, "boot"))
  1027. {
  1028. wifi_receive_clear();
  1029. wifi_prov_state = WIFI_PROV_MODE;
  1030. }
  1031. else if ((uint32_t)(sysinf.conter10ms - wifi_prov_tick) >= wifi_prov_timeout)
  1032. {
  1033. wifi_receive_clear();
  1034. if (++wifi_prov_retry < WIFI_PROV_MAX_RETRY)
  1035. wifi_prov_state = WIFI_PROV_RST; /* 重试复位 */
  1036. else
  1037. wifi_prov_abort();
  1038. }
  1039. break;
  1040. /* 2. 设置AP模式 */
  1041. case WIFI_PROV_MODE:
  1042. if (wifi_prov_wait != 0)
  1043. wifi_prov_check_cmd_resp(WIFI_PROV_SAP);
  1044. else
  1045. wifi_prov_send_cmd("AT+CWMODE=2", WIFI_PROV_CMD_TIMEOUT);
  1046. break;
  1047. /* 3. 建立热点: 名称OneChip_Mini7, 密码test1234 */
  1048. case WIFI_PROV_SAP:
  1049. {
  1050. char cStr[128] = {0};
  1051. if (wifi_prov_wait != 0)
  1052. wifi_prov_check_cmd_resp(WIFI_PROV_IP_Q);
  1053. else
  1054. {
  1055. my_sprintf(cStr, sizeof(cStr), "AT+CWSAP=\"%s\",\"%s\",%d,%d",
  1056. WIFI_PROV_AP_SSID, WIFI_PROV_AP_PWD,
  1057. WIFI_PROV_AP_CHANNEL, WIFI_PROV_AP_ECN);
  1058. wifi_prov_send_cmd(cStr, WIFI_PROV_CMD_TIMEOUT);
  1059. }
  1060. break;
  1061. }
  1062. /* 4. 查询SoftAP接口IP(默认192.168.4.1),确认热点地址 */
  1063. case WIFI_PROV_IP_Q:
  1064. if (wifi_prov_wait != 0)
  1065. wifi_prov_query_done(WIFI_PROV_DHCP_Q);
  1066. else
  1067. wifi_prov_send_cmd("AT+CIPAP?", WIFI_PROV_CMD_TIMEOUT);
  1068. break;
  1069. /* 5. 查询DHCP使能状态(确认AP侧能分配192.168.4.x) */
  1070. case WIFI_PROV_DHCP_Q:
  1071. if (wifi_prov_wait != 0)
  1072. wifi_prov_query_done(WIFI_PROV_MUX);
  1073. else
  1074. wifi_prov_send_cmd("AT+CWDHCP?", WIFI_PROV_CMD_TIMEOUT);
  1075. break;
  1076. /* 6. 打开多连接 */
  1077. case WIFI_PROV_MUX:
  1078. if (wifi_prov_wait != 0)
  1079. wifi_prov_check_cmd_resp(WIFI_PROV_SERVER);
  1080. else
  1081. wifi_prov_send_cmd("AT+CIPMUX=1", WIFI_PROV_CMD_TIMEOUT);
  1082. break;
  1083. /* 7. 启动TCP服务端: 端口8002 */
  1084. case WIFI_PROV_SERVER:
  1085. {
  1086. char cStr[48] = {0};
  1087. if (wifi_prov_wait != 0)
  1088. {
  1089. if (wifi_prov_check_cmd_resp(WIFI_PROV_LISTEN) == 1)
  1090. wifi_prov_tick = sysinf.conter10ms; /* 记录开始等待配网的时间 */
  1091. }
  1092. else
  1093. {
  1094. my_sprintf(cStr, sizeof(cStr), "AT+CIPSERVER=1,%d", WIFI_PROV_TCP_PORT);
  1095. wifi_prov_send_cmd(cStr, WIFI_PROV_CMD_TIMEOUT);
  1096. }
  1097. break;
  1098. }
  1099. /* 8. 等待手机经TCP下发配网JSON(总超时300s) */
  1100. case WIFI_PROV_LISTEN:
  1101. if ((uint32_t)(sysinf.conter10ms - wifi_prov_tick) >= WIFI_PROV_LISTEN_TIMEOUT)
  1102. {
  1103. Van_Device_Printf(VAN_LOG_WIFI, "\r\n[Provision] wait cfg timeout");
  1104. wifi_prov_wait = 0;
  1105. wifi_prov_state = WIFI_PROV_DONE; /* 超时未收到配置,直接退出 */
  1106. break;
  1107. }
  1108. /* 接收并解析+IPD报文 */
  1109. {
  1110. int ipdRlt = wifi_prov_capture_ipd();
  1111. if (ipdRlt > 0)
  1112. {
  1113. if (wifi_prov_ipd_len >= (uint16_t)(sizeof(wifi_prov_ipd) - 2))
  1114. {
  1115. /* 累积超限,丢弃重收 */
  1116. wifi_receive_clear();
  1117. wifi_prov_ipd_len = 0;
  1118. wifi_prov_ipd[0] = '\0';
  1119. }
  1120. }
  1121. else
  1122. {
  1123. /* 存在接收数据但未解析出有效+IPD,且距最近接收超1s: 打印残留并清空 */
  1124. if (g_wifi_rx_head != g_wifi_rx_last &&
  1125. (uint32_t)(sysinf.conter10ms - g_wifi_rx_last_tick) >= WIFI_PROV_RX_IDLE_TIMEOUT)
  1126. {
  1127. Van_Device_Printf(VAN_LOG_WIFI, "\r\n%s", g_wifi_rx_buf);
  1128. wifi_receive_clear();
  1129. wifi_prov_ipd_len = 0;
  1130. wifi_prov_ipd[0] = '\0';
  1131. }
  1132. }
  1133. }
  1134. /* 累积到完整JSON后解析 */
  1135. if (wifi_prov_ipd_len > 0 &&
  1136. wifi_prov_ipd[0] == '{' &&
  1137. wifi_prov_ipd[wifi_prov_ipd_len - 1] == '}')
  1138. {
  1139. char ssid[sizeof(sysinf.wifiname)];
  1140. char pwd[sizeof(sysinf.password)];
  1141. if (wifi_prov_parse_json(wifi_prov_ipd, ssid, (uint16_t)sizeof(ssid),
  1142. pwd, (uint16_t)sizeof(pwd)) == 0)
  1143. {
  1144. memset(sysinf.wifiname, 0, sizeof(sysinf.wifiname));
  1145. memset(sysinf.password, 0, sizeof(sysinf.password));
  1146. strcpy(sysinf.wifiname, ssid);
  1147. strcpy(sysinf.password, pwd);
  1148. wifi_prov_json_ok = 1;
  1149. Van_Device_Printf(VAN_LOG_WIFI, "\r\n[Provision] got cfg: ssid=%s pwd=%s",
  1150. sysinf.wifiname, sysinf.password);
  1151. }
  1152. else
  1153. {
  1154. wifi_prov_json_ok = 0;
  1155. Van_Device_Printf(VAN_LOG_WIFI, "\r\n[Provision] bad json: %s",
  1156. wifi_prov_ipd);
  1157. }
  1158. wifi_prov_build_ack(wifi_prov_json_ok, "invalid");
  1159. wifi_prov_state = WIFI_PROV_ACK_SEND;
  1160. }
  1161. break;
  1162. /* 9. 向手机应答(accepted/rejected) */
  1163. case WIFI_PROV_ACK_SEND:
  1164. {
  1165. char cStr[48] = {0};
  1166. Van_Device_Printf(VAN_LOG_WIFI, "\r\nack json: %s",
  1167. wifi_prov_ack);
  1168. wifi_receive_clear();
  1169. my_sprintf(cStr, sizeof(cStr), "AT+CIPSEND=%d,%d",
  1170. wifi_prov_linkid, (int)strlen(wifi_prov_ack));
  1171. wifi_prov_send_cmd(cStr, WIFI_PROV_CMD_TIMEOUT);
  1172. /* CIPSEND属非透传"先握手后发数": 复位wait,由ACK_DATA收到OK后真正发载荷 */
  1173. wifi_prov_wait = 0;
  1174. wifi_prov_state = WIFI_PROV_ACK_DATA;
  1175. break;
  1176. }
  1177. case WIFI_PROV_ACK_DATA:
  1178. if (wifi_prov_wait == 0)
  1179. {
  1180. /* 等待 'OK\r\n' 提示符后发送应答数据 */
  1181. if(NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE ,&g_wifi_rx_head, g_wifi_rx_last, "OK\r\n"))
  1182. {
  1183. wifi_receive_clear();
  1184. wifi_prov_wait = 1;
  1185. wifi_prov_tick = sysinf.conter10ms;
  1186. wifi_prov_timeout = WIFI_PROV_CMD_TIMEOUT;
  1187. WriteComm2(wifi_prov_ack, strlen(wifi_prov_ack));
  1188. }
  1189. else if (NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  1190. g_wifi_rx_last, "ERROR") ||
  1191. NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  1192. g_wifi_rx_last, "CLOSED") ||
  1193. (uint32_t)(sysinf.conter10ms - wifi_prov_tick) >= wifi_prov_timeout)
  1194. {
  1195. /* 应答失败或超时,继续后续流程 */
  1196. Van_Device_Printf(VAN_LOG_WIFI, "\r\n%s", g_wifi_rx_buf);
  1197. wifi_receive_clear();
  1198. wifi_prov_wait = 0;
  1199. wifi_prov_state = (wifi_prov_json_ok != 0) ? WIFI_PROV_SAVE : WIFI_PROV_LISTEN;
  1200. wifi_prov_ipd_len = 0;
  1201. wifi_prov_ipd[0] = '\0';
  1202. if (wifi_prov_json_ok == 0)
  1203. wifi_prov_tick = sysinf.conter10ms; /* 重新计时 */
  1204. }
  1205. }
  1206. else
  1207. {
  1208. /* 等待SEND OK */
  1209. if (NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  1210. g_wifi_rx_last, "SEND OK") ||
  1211. NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  1212. g_wifi_rx_last, "ERROR") ||
  1213. NULL != find_str_loop(g_wifi_rx_buf, WIFI_RX_BUF_SIZE, &g_wifi_rx_head,
  1214. g_wifi_rx_last, "CLOSED") ||
  1215. (uint32_t)(sysinf.conter10ms - wifi_prov_tick) >= wifi_prov_timeout)
  1216. {
  1217. Van_Device_Printf(VAN_LOG_WIFI, "\r\n%s", g_wifi_rx_buf);
  1218. wifi_receive_clear();
  1219. wifi_prov_wait = 0;
  1220. wifi_prov_state = (wifi_prov_json_ok != 0) ? WIFI_PROV_SAVE : WIFI_PROV_LISTEN;
  1221. wifi_prov_ipd_len = 0; /* 无效配置则清空缓存重新等待 */
  1222. wifi_prov_ipd[0] = '\0';
  1223. if (wifi_prov_json_ok == 0)
  1224. wifi_prov_tick = sysinf.conter10ms; /* 重新计时 */
  1225. }
  1226. }
  1227. break;
  1228. /* 10. 保存配网参数到Flash */
  1229. case WIFI_PROV_SAVE:
  1230. {
  1231. uint8_t saveRlt = cfg_save_cfg_param();
  1232. Van_Device_Printf(VAN_LOG_WIFI, "\r\n[Provision] cfg_save_cfg_param=%d", saveRlt);
  1233. wifi_prov_state = WIFI_PROV_DONE;
  1234. break;
  1235. }
  1236. /* 11. 配网完成: 复位ESP32进入正常模式 */
  1237. case WIFI_PROV_DONE:
  1238. wifi_prov_exit();
  1239. break;
  1240. }
  1241. }
  1242. //wifi任务
  1243. void WIFI_process()
  1244. {
  1245. /* 热点配网模式优先处理 */
  1246. if (wifi_prov_request != 0 || wifi_prov_active != 0)
  1247. {
  1248. if (wifi_prov_request != 0)
  1249. {
  1250. wifi_prov_request = 0;
  1251. wifi_prov_enter();
  1252. }
  1253. wifi_prov_process();
  1254. return;
  1255. }
  1256. if(sysinf.pc_channel_recv == 2 && wifi_state > WIFI_SETMUX){
  1257. /*串口状态下,不走wifi处理*/
  1258. return;
  1259. }
  1260. WIFI_recv_deal();
  1261. WIFI_send_deal();
  1262. }
  1263. static uint32_t m_pow_n(uint32_t m, int32_t n)
  1264. {
  1265. uint32_t i = 0, ret = 1;
  1266. if (n < 0) return 0;
  1267. for (i = 0; i < n; i++)
  1268. {
  1269. ret *= m;
  1270. }
  1271. return ret;
  1272. }
  1273. // 返回值为打印字符的个数
  1274. // 支持%d,%o, %x,%s,%c,%f(只打印6位数字)
  1275. int my_sprintf(char *pdes,unsigned int len, const char* str, ...)
  1276. {
  1277. if (str == NULL) return -1;
  1278. uint32_t ret_num = 0;// 返回打印字符的个数
  1279. char* pStr = (char*)str;// 指向str
  1280. int ArgIntVal = 0; // 接收整型
  1281. uint32_t ArgHexVal = 0;// 接十六进制
  1282. char* ArgStrVal = NULL; // 接收字符型
  1283. double ArgFloVal = 0.0; // 接受浮点型
  1284. uint32_t val_seg = 0; // 数据切分
  1285. uint32_t val_temp = 0; // 临时保存数据
  1286. int cnt = 0; // 数据长度计数
  1287. int cnt_float = 0; // 数据长度计数
  1288. va_list pArgs; // 定义va_list类型指针,用于存储参数的地址
  1289. va_start(pArgs, str); // 初始化pArgs
  1290. while (*pStr != '\0')
  1291. {
  1292. switch (*pStr)
  1293. {
  1294. case ' ':
  1295. case '\r':
  1296. case '\n':
  1297. *pdes++ = (*pStr); ret_num++; break;
  1298. case '\t':
  1299. *pdes++ =(*pStr); ret_num += 4; break;
  1300. case '%':
  1301. pStr++;
  1302. // % 格式解析
  1303. if('.' == *pStr)
  1304. {
  1305. pStr++;
  1306. cnt_float = *pStr - '0';// %.Nf,输出指定位数小数
  1307. pStr++;
  1308. }
  1309. switch (*pStr)
  1310. {
  1311. case '%':
  1312. *pdes++ =('%');// %%,输出%
  1313. ret_num++;
  1314. pStr++;
  1315. continue;
  1316. case 'c':
  1317. ArgIntVal = va_arg(pArgs, int);// %c,输出char
  1318. *pdes++ =((char)ArgIntVal);
  1319. ret_num++;
  1320. pStr++;
  1321. continue;
  1322. case 'd':
  1323. // 接收整型
  1324. ArgIntVal = va_arg(pArgs, int);
  1325. if (ArgIntVal < 0)// 如果为负数打印,负号
  1326. {
  1327. ArgIntVal = -ArgIntVal;// 取相反数
  1328. *pdes++ =('-');
  1329. ret_num++;
  1330. }
  1331. val_seg = ArgIntVal;// 赋值给 val_seg处理数据
  1332. // 计算ArgIntVal长度
  1333. if (ArgIntVal)
  1334. {
  1335. while (val_seg) {
  1336. cnt++;
  1337. val_seg /= 10;
  1338. }
  1339. }
  1340. else cnt = 1;// 数字0的长度为1
  1341. ret_num += cnt;// 字符个数加上整数的长度
  1342. // 将整数转为单个字符打印
  1343. while (cnt)
  1344. {
  1345. val_seg = ArgIntVal / m_pow_n(10, cnt - 1);
  1346. ArgIntVal %= m_pow_n(10, cnt - 1);
  1347. *pdes++ =((char)val_seg + '0');
  1348. cnt--;
  1349. }
  1350. pStr++;
  1351. continue;
  1352. case 'o':
  1353. // 接收整型
  1354. ArgIntVal = va_arg(pArgs, int);
  1355. if (ArgIntVal < 0)// 如果为负数打印,负号
  1356. {
  1357. ArgIntVal = -ArgIntVal;// 取相反数
  1358. *pdes++ =('-');
  1359. ret_num++;
  1360. }
  1361. val_seg = ArgIntVal;// 赋值给 val_seg处理数据
  1362. // 计算ArgIntVal长度
  1363. if (ArgIntVal)
  1364. {
  1365. while (val_seg) {
  1366. cnt++;
  1367. val_seg /= 8;
  1368. }
  1369. }
  1370. else cnt = 1;// 数字0的长度为1
  1371. ret_num += cnt;// 字符个数加上整数的长度
  1372. // 将整数转为单个字符打印
  1373. while (cnt)
  1374. {
  1375. val_seg = ArgIntVal / m_pow_n(8, cnt - 1);
  1376. ArgIntVal %= m_pow_n(8, cnt - 1);
  1377. *pdes++ =((char)val_seg + '0');
  1378. cnt--;
  1379. }
  1380. pStr++;
  1381. continue;
  1382. case 'x':
  1383. // 接收16进制
  1384. ArgHexVal = va_arg(pArgs, uint32_t);
  1385. val_seg = ArgHexVal;
  1386. // 计算ArgIntVal长度
  1387. if (ArgHexVal)
  1388. {
  1389. while (val_seg) {
  1390. cnt++;
  1391. val_seg /= 16;
  1392. }
  1393. }
  1394. else cnt = 1;// 数字0的长度为1
  1395. ret_num += cnt;// 字符个数加上整数的长度
  1396. // 将整数转为单个字符打印
  1397. while (cnt)
  1398. {
  1399. val_seg = ArgHexVal / m_pow_n(16, cnt - 1);
  1400. ArgHexVal %= m_pow_n(16, cnt - 1);
  1401. if (val_seg <= 9)
  1402. *pdes++ =((char)val_seg + '0');
  1403. else
  1404. {
  1405. //*pdes++ =((char)val_seg - 10 + 'a'); //小写字母
  1406. *pdes++ =((char)val_seg - 10 + 'A');
  1407. }
  1408. cnt--;
  1409. }
  1410. pStr++;
  1411. continue;
  1412. case 'b':
  1413. // 接收整型
  1414. ArgIntVal = va_arg(pArgs, int);
  1415. val_seg = ArgIntVal;
  1416. // 计算ArgIntVal长度
  1417. if (ArgIntVal)
  1418. {
  1419. while (val_seg) {
  1420. cnt++;
  1421. val_seg /= 2;
  1422. }
  1423. }
  1424. else cnt = 1;// 数字0的长度为1
  1425. ret_num += cnt;// 字符个数加上整数的长度
  1426. // 将整数转为单个字符打印
  1427. while (cnt)
  1428. {
  1429. val_seg = ArgIntVal / m_pow_n(2, cnt - 1);
  1430. ArgIntVal %= m_pow_n(2, cnt - 1);
  1431. *pdes++ =((char)val_seg + '0');
  1432. cnt--;
  1433. }
  1434. pStr++;
  1435. continue;
  1436. case 's':
  1437. // 接收字符
  1438. ArgStrVal = va_arg(pArgs, char*);
  1439. ret_num += (uint32_t)strlen(ArgStrVal);
  1440. while (*ArgStrVal)
  1441. {
  1442. *pdes++ =(*ArgStrVal);
  1443. ArgStrVal++;
  1444. }
  1445. pStr++;
  1446. continue;
  1447. case 'f':
  1448. // 接收浮点型 保留6为小数,不采取四舍五入
  1449. ArgFloVal = va_arg(pArgs, double);
  1450. val_seg = (uint32_t)ArgFloVal;// 取整数部分
  1451. val_temp = val_seg; // 临时保存整数部分数据
  1452. ArgFloVal = ArgFloVal - val_seg;// 得出余下的小数部分
  1453. // 计算整数部分长度
  1454. if (val_seg)
  1455. {
  1456. while (val_seg) {
  1457. cnt++;
  1458. val_seg /= 10;
  1459. }
  1460. }
  1461. else cnt = 1;// 数字0的长度为1
  1462. ret_num += cnt;// 字符个数加上整数的长度
  1463. // 将整数转为单个字符打印
  1464. while (cnt)
  1465. {
  1466. val_seg = val_temp / m_pow_n(10, cnt - 1);
  1467. val_temp %= m_pow_n(10, cnt - 1);
  1468. *pdes++ =((char)val_seg + '0');
  1469. cnt--;
  1470. }
  1471. // 打印小数点
  1472. *pdes++ =('.');
  1473. ret_num++;
  1474. // printf("\r\n %f\r\n", ArgFloVal);
  1475. if(cnt_float == 0)
  1476. cnt_float = 6;
  1477. // 开始输出小数部分
  1478. //ArgFloVal *= 1000000;
  1479. ArgFloVal *= m_pow_n(10, cnt_float);
  1480. val_temp = (int)ArgFloVal;// 取整数部分
  1481. while (cnt_float)
  1482. {
  1483. val_seg = val_temp / m_pow_n(10, cnt_float - 1);
  1484. val_temp %= m_pow_n(10, cnt_float - 1);
  1485. *pdes++ =((char)val_seg + '0');
  1486. cnt_float--;
  1487. }
  1488. ret_num += 6;
  1489. pStr++;
  1490. continue;
  1491. default:// % 匹配错误,暂输出空格
  1492. *pdes++ =(' '); ret_num++;
  1493. break;
  1494. }
  1495. break;
  1496. default:
  1497. *pdes++ =(*pStr); ret_num++;
  1498. break;
  1499. }
  1500. pStr++;
  1501. if(ret_num > len){
  1502. break;
  1503. }
  1504. }
  1505. va_end(pArgs);// 结束取参数
  1506. *pdes++ = 0;
  1507. return ret_num;
  1508. }