ESP32_WROOM_32D.c 52 KB

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