EC800M_UDP_Client5.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. #include "stm32f10x.h"
  2. #include <stdio.h>
  3. #include <stdarg.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include "EC800M_UDP_Client5.h"
  7. #include "CoAP.h"
  8. #include "mbedtls_util.h"
  9. #include "cJSON.h"
  10. #include "sys.h"
  11. #include "ec800m.h"
  12. #include "pump_dicts.h"
  13. #include "INflash.h"
  14. #if _4GFLAG
  15. // 流程
  16. enum Step{
  17. STEP_NONE, // 空闲状态,无操作
  18. STEP_START, // 开始
  19. STEP_EXIT_SLEEP, // 退出睡眠
  20. STEP_ENTER_SLEEP, // 进入睡眠
  21. STEP_WAIT, // 等待
  22. STEP_STATE, // 查询状态
  23. STEP_OPEN, // 打开
  24. STEP_OPEN_WAIT_RESULT, // 等待打开结果
  25. STEP_JUDGE_AUTH_OR_DATA, // 判断认证还是发送
  26. STEP_JOIN_AUTH_MESSAGE, // 拼接认证报文
  27. STEP_JOIN_DATA_MESSAGE, // 拼接数据报文
  28. STEP_QUERY_SLEEP, // 查询休眠
  29. STEP_SET_SLEEP, // 开启休眠
  30. STEP_QUERY_QENG_SERVINGCELL, // 查询信号质量
  31. STEP_SET_QISDE_0, // 关闭发送回显
  32. STEP_SEND, // 发送
  33. STEP_RECV, // 等待发送结果
  34. STEP_SET_CFUN_0, // 设置最小功能模式
  35. STEP_WAIT_SET_CFUN_0, // 等待设置最小功能模式
  36. STEP_SET_CFUN_1, // 设置全功能模式
  37. STEP_WAIT_SET_CFUN_1, // 等待设置全功能模式结果
  38. STEP_SET_CGREG_2, // 设置ps域允许上报网络注册和位置信息
  39. STEP_QUERY_CGREG, // 查询网络注册状态
  40. STEP_CLOSE, // 关闭
  41. STEP_SUCCESS, // 成功
  42. STEP_FAILURE, // 失败
  43. STEP_FINISH, // 流程结束
  44. };
  45. // 当前
  46. static enum Step step = STEP_NONE;
  47. // 下一步
  48. static enum Step next_step = STEP_NONE;
  49. // 客户端5
  50. struct EC800M_Client_Struct UDP_Client5 = {
  51. .status = Client_Status_None,
  52. };
  53. // 注册后的参数
  54. extern Coefficient_Data flashdata;
  55. // socket ID
  56. static uint8_t connectID = 5;
  57. /** 阿里云连接参数 **/
  58. static char ProductKey[20] = "a1t3qlUNDcP";
  59. static char DeviceName[20] = "LTEcat1ceshi001";
  60. static char DeviceSecret[40] = "4929a78860f663ec72e2c313a4eee7ac";
  61. static char ClientID[60];
  62. static char Seq[10] = "666";
  63. static uint16_t Port = 5682;
  64. static char Host[60];
  65. static uint32_t SeqOffset;
  66. static char Random[20];
  67. static char Token[50];
  68. // payload缓存
  69. //static uint8_t payload[256];
  70. //static uint16_t payload_length;
  71. // coap报文
  72. static uint8_t coap_message[512];
  73. static uint16_t coap_message_length = 0;
  74. // aes cbc
  75. static uint8_t aes_key[16] = {0};
  76. static char iv[] = "543yhjy97ae7fyfg";
  77. // 泵参数
  78. static struct Pump_Params pump_params;
  79. // 待发送数据的地址和长度
  80. static uint8_t data[128];
  81. static uint16_t data_length;
  82. static uint8_t test_flag=0;
  83. // 计时相关的变量
  84. uint8_t Client5_time_flag = 0;
  85. uint32_t Client5_timer_ms = 0;
  86. uint32_t Client5_wait_time = 10;
  87. // 信号值
  88. static struct Signal
  89. {
  90. int RSRP;
  91. int RSRQ;
  92. int RSSI;
  93. int SINR;
  94. } signal = {
  95. .RSRP = 99,
  96. .RSRQ = 99,
  97. .RSSI = 99,
  98. .SINR = 99,
  99. };
  100. void Query_Signal(int * RSRP, int * RSRQ, int * RSSI, int * SINR)
  101. {
  102. *RSRP = signal.RSRP;
  103. *RSRQ = signal.RSRQ;
  104. *RSSI = signal.RSSI;
  105. *SINR = signal.SINR;
  106. }
  107. // 初始化
  108. void UDP_Client5_Init(void)
  109. {
  110. // 赋值三元组
  111. strcpy(ProductKey, flashdata.productKey);
  112. strcpy(DeviceName, flashdata.deviceName);
  113. strcpy(DeviceSecret, flashdata.deviceSecret);
  114. // 设置host
  115. memset(Host, '\0', sizeof(Host));
  116. strcat(Host, ProductKey);
  117. strcat(Host, ".coap.cn-shanghai.link.aliyuncs.com");
  118. // 设置clientid
  119. memset(ClientID, '\0', sizeof(ClientID));
  120. strcat(ClientID, ProductKey);
  121. strcat(ClientID, "&");
  122. strcat(ClientID, DeviceName);
  123. }
  124. // 声明函数。步骤跳转
  125. void goto_step(enum Step ns);
  126. // 发送流程
  127. void UDP_Client5_Handle(void);
  128. // 发送数据
  129. void UDP_Client5_Send(struct Pump_Params params,uint8_t test_switch)
  130. {
  131. test_flag=test_switch;
  132. if(step == STEP_NONE)
  133. {
  134. // 待发送数据的地址和长度
  135. pump_params = params;
  136. // 初始化
  137. UDP_Client5_Init();
  138. // 正在发送
  139. UDP_Client5.status = Client_Status_Sending;
  140. // 流程开始
  141. goto_step(STEP_START);
  142. }
  143. }
  144. // 获取状态
  145. enum Client_Status UDP_Client5_Status(void)
  146. {
  147. if(UDP_Client5.status == Client_Status_None)
  148. {
  149. return UDP_Client5.status;
  150. }
  151. else if(step == STEP_FINISH)
  152. {
  153. return UDP_Client5.status;
  154. }
  155. else
  156. {
  157. return Client_Status_Sending;
  158. }
  159. }
  160. // 清除
  161. void UDP_Client5_Clear(void)
  162. {
  163. // 流程置空
  164. goto_step(STEP_NONE);
  165. // 空闲
  166. UDP_Client5.status = Client_Status_None;
  167. }
  168. // 直接跳转到下一步
  169. static void goto_step(enum Step ns)
  170. {
  171. // 重置ec800m状态
  172. ec800m.reset();
  173. step = ns;
  174. }
  175. // 先等待再跳转到下一步
  176. static void goto_step_wait(enum Step ns, uint32_t t)
  177. {
  178. goto_step(STEP_WAIT); // 等待
  179. Client5_wait_time = t;
  180. next_step = ns; // 等待之后跳转
  181. }
  182. // 只等待,等待之后返回原来的步骤
  183. static void goto_wait(uint32_t t)
  184. {
  185. goto_step_wait(step, t);
  186. }
  187. // 失败
  188. static void goto_failure(char * info)
  189. {
  190. Log_Printf_Debug("STEP: 数据发送失败,%s\r\n", info);
  191. UDP_Client5.status = Client_Status_Failure;
  192. strcpy(UDP_Client5.info, info);
  193. goto_step(STEP_FAILURE);
  194. }
  195. // 成功
  196. static void goto_success(char * info)
  197. {
  198. Log_Printf_Debug("STEP: 数据发送成功,%s\r\n", info);
  199. UDP_Client5.status = Client_Status_Success;
  200. strcpy(UDP_Client5.info, info);
  201. goto_step(STEP_SUCCESS);
  202. }
  203. // 等待
  204. static void wait(void)
  205. {
  206. if(Client5_time_flag == 0)
  207. {
  208. Client5_timer_ms = 0;
  209. Client5_time_flag = 1;
  210. }
  211. else if(Client5_timer_ms > Client5_wait_time)
  212. {
  213. goto_step(next_step); // 进入下一步
  214. Client5_time_flag = 0;
  215. }
  216. }
  217. // 判断认证还是发送
  218. static uint8_t judge_auth_or_data(void)
  219. {
  220. if(strlen(Token) > 0) // 已认证
  221. {
  222. return 1;
  223. }
  224. else
  225. {
  226. return 0;
  227. }
  228. }
  229. // 拼接认证报文
  230. static void join_auth_message(uint8_t * coap_message, uint16_t * coap_message_length)
  231. {
  232. SeqOffset=65535;
  233. Log_Printf_Debug("STEP: 拼接认证报文,seqOffset=%d\r\n", SeqOffset);
  234. // 先清除
  235. // memset(coap_message, 0, sizeof(coap_message));
  236. // coap_message_length = 0;
  237. // CoAP协议
  238. CoAP_Init();
  239. CoAP_Set_T(0);
  240. CoAP_Set_Code(2);
  241. CoAP_Set_MessageID(SeqOffset);
  242. // option
  243. // host
  244. CoAP_Set_Option_Str(3, Host);
  245. // port
  246. CoAP_Set_Option_Short(7, Port);
  247. // path
  248. CoAP_Set_Option_Str(11, "auth");
  249. // content-format
  250. CoAP_Set_Option_Short(12, 50);
  251. // accept
  252. CoAP_Set_Option_Short(17, 50);
  253. // 待签名数据
  254. // 签名相关
  255. static char StrForSignature[100];
  256. static char sign[50];
  257. memset(StrForSignature, '\0', sizeof(StrForSignature));
  258. sprintf((char * )StrForSignature, "clientId%sdeviceName%sproductKey%sseq%s", ClientID, DeviceName, ProductKey, Seq);
  259. // 签名
  260. memset(sign, '\0', sizeof(sign));
  261. utils_hmac_sha1_str(StrForSignature, strlen((char * )StrForSignature), sign, DeviceSecret, strlen(DeviceSecret));
  262. // payload
  263. // memset(payload, '\0', sizeof(payload));
  264. char payload[256] = {0};
  265. sprintf((char * )payload, "{\"clientId\":\"%s\",\"signmethod\":\"hmacsha1\",\"sign\":\"%s\",\"productKey\":\"%s\",\"deviceName\":\"%s\",\"seq\":\"%s\"}", ClientID, sign, ProductKey, DeviceName, Seq);
  266. // 设置payload
  267. CoAP_Set_Payload_Str(payload);
  268. // 生成报文
  269. * coap_message_length = CoAP_Get_Length();
  270. memcpy(coap_message, CoAP_Get_Message(), * coap_message_length);
  271. }
  272. // 拼接数据报文
  273. static void join_data_message(uint8_t * data, uint8_t data_length, uint8_t * coap_message, uint16_t * coap_message_length)
  274. {
  275. SeqOffset++;
  276. Log_Printf_Debug("STEP: 拼接数据报文,seqOffset=%d\r\n", SeqOffset);
  277. // 先清除
  278. // memset(coap_message, 0, sizeof(coap_message));
  279. // coap_message_length = 0;
  280. char out[80]={0};
  281. char sha256_source[100] = {0};
  282. snprintf(sha256_source, sizeof(sha256_source), "%s,%s" ,DeviceSecret ,Random);
  283. Log_Printf_Debug("sha256_source: %s\r\n", sha256_source);
  284. utils_sha256(sha256_source, strlen(sha256_source), out);
  285. memset(aes_key, 0, sizeof(aes_key));
  286. memcpy(aes_key, out+8, 16); //获取key
  287. // CoAP协议
  288. CoAP_Init();
  289. CoAP_Set_T(0);
  290. CoAP_Set_Code(2);
  291. CoAP_Set_MessageID(SeqOffset);
  292. // option
  293. // host
  294. CoAP_Set_Option_Str(3, Host);
  295. // port
  296. CoAP_Set_Option_Short(7, Port);
  297. // path
  298. CoAP_Set_Option_Str(11, "topic");
  299. CoAP_Set_Option_Str(11, "sys");
  300. CoAP_Set_Option_Str(11, ProductKey);
  301. CoAP_Set_Option_Str(11, DeviceName);
  302. CoAP_Set_Option_Str(11, "thing");
  303. CoAP_Set_Option_Str(11, "model");
  304. CoAP_Set_Option_Str(11, "up_raw");
  305. // content-format
  306. CoAP_Set_Option_Short(12, 50);
  307. // accept
  308. CoAP_Set_Option_Short(17, 50);
  309. // 2088
  310. CoAP_Set_Option_Str(2088, Token);
  311. // 2089
  312. char Rand2089[10] = {'\0'};
  313. char Opt2089[20] = {'\0'};
  314. my_itoa(SeqOffset, Rand2089, 10);
  315. int Opt2089_Length = utils_aes128_cbc_enc((char * )aes_key, iv, Rand2089, Opt2089);
  316. CoAP_Set_Option_Str(2089, Opt2089);
  317. // payload
  318. // memset(payload, '\0', sizeof(payload));
  319. uint8_t payload[256] = {0};
  320. //
  321. int payload_length = utils_aes128_cbc_enc_with_length((char * )aes_key, iv, data, data_length, payload);
  322. // payload_length = utils_aes128_cbc_enc((char * )aes_key, iv, (char * )Data_Buffer, (char * )payload);
  323. Log_Printf_Debug("payload_length: %d\r\n", payload_length);
  324. CoAP_Set_Payload(payload, payload_length);
  325. // 生成报文
  326. * coap_message_length = CoAP_Get_Length();
  327. memcpy(coap_message, CoAP_Get_Message(), * coap_message_length);
  328. }
  329. // 等待数据返回
  330. static uint8_t recv_data_handle(uint8_t * coap_message, uint16_t coap_message_length)
  331. {
  332. uint16_t payload_length = CoAP_Get_Payload_Length(coap_message, coap_message_length);
  333. uint8_t payload[256] = {0};
  334. CoAP_Get_Payload(coap_message, coap_message_length, payload);
  335. Log_Printf_Debug("payload长度: %d\r\n", payload_length);
  336. // 判断是认证返回,还是数据发送返回
  337. if(payload_length == 0) // 无返回
  338. {
  339. // 清空Token,重新认证
  340. memset(Token, '\0', sizeof(Token));
  341. return 0;
  342. }
  343. else if(payload[0] == '{' && payload[payload_length-1] == '}') // 认证返回
  344. {
  345. // 解析json
  346. cJSON * cjson = cJSON_Parse((char * )payload);
  347. Log_Printf_Debug("plaintext(%d): %s\r\n",payload_length, payload);
  348. memset(Random, '\0', sizeof(Random));
  349. memset(Token, '\0', sizeof(Token));
  350. if(cJSON_HasObjectItem(cjson, "random"))
  351. {
  352. char * random = cJSON_GetObjectItem(cjson, "random")->valuestring;
  353. strcpy(Random, random);
  354. }
  355. if(cJSON_HasObjectItem(cjson, "seqOffset"))
  356. {
  357. uint16_t seqOffset = cJSON_GetObjectItem(cjson, "seqOffset")->valueint;
  358. SeqOffset = seqOffset;
  359. }
  360. if(cJSON_HasObjectItem(cjson, "token"))
  361. {
  362. char * token = cJSON_GetObjectItem(cjson, "token")->valuestring;
  363. strcpy(Token, token);
  364. }
  365. Log_Printf_Debug("\r\n(%s, %s, %d)\r\n", Random, Token, SeqOffset);
  366. cJSON_Delete(cjson);//清除结构体
  367. return 1;
  368. }
  369. else
  370. {
  371. // 数据发送成功返回
  372. uint8_t plaintext[256] = {0}; // 明文
  373. uint16_t plaintext_length = utils_aes128_cbc_dec((char * )aes_key, iv, (char * )payload, payload_length, (char * )plaintext);
  374. Log_Printf_Debug("\r\nplaintext(%d): %s\r\n",plaintext_length, (char *)plaintext);
  375. return 2;
  376. }
  377. }
  378. // 发送数据的逻辑
  379. static enum Result result = Result_None;
  380. static uint8_t cgreg_n;
  381. static uint8_t cgreg_stat;
  382. static uint16_t cgreg_lac;
  383. static uint32_t cgreg_ci;
  384. static uint8_t query_cgreg_times = 0; // 查询网络状态的次数
  385. static uint8_t auth_times = 0; // 认证次数
  386. static uint16_t socket_err = 0;
  387. static uint8_t auth_or_data = 0;
  388. void UDP_Client5_Handle(void)
  389. {
  390. // 流程
  391. switch(step)
  392. {
  393. case STEP_NONE: // 空闲
  394. break;
  395. case STEP_START: // 开始
  396. query_cgreg_times = 0; // 查询网络状态的次数
  397. auth_times = 0; // 认证次数
  398. goto_step(STEP_EXIT_SLEEP);
  399. break;
  400. case STEP_EXIT_SLEEP: // 退出休眠
  401. ec800m.exit_sleep();
  402. goto_step_wait(STEP_SET_CFUN_1, 3);
  403. break;
  404. case STEP_SET_CFUN_1: // 设置全功能模式
  405. result = ec800m.set_cfun(1);
  406. if(result == Result_Success)
  407. {
  408. goto_step(STEP_SET_CGREG_2);
  409. }
  410. else if(result == Result_Failed)
  411. {
  412. goto_failure("设置全功能模式失败");
  413. }
  414. break;
  415. case STEP_SET_CGREG_2: // 设置ps域
  416. result = ec800m.set_cgreg(2);
  417. if(result == Result_Success)
  418. {
  419. goto_step(STEP_QUERY_CGREG);
  420. }
  421. else if(result == Result_Failed)
  422. {
  423. goto_failure("设置ps域失败");
  424. }
  425. break;
  426. case STEP_QUERY_CGREG: // 查询ps域
  427. result = ec800m.query_cgreg(&cgreg_n, &cgreg_stat, &cgreg_lac, &cgreg_ci);
  428. if(result == Result_Success)
  429. {
  430. if(cgreg_stat == 1)
  431. {
  432. // 参数赋值
  433. pump_params.lac = cgreg_lac;
  434. pump_params.ci = cgreg_ci;
  435. // 编码
  436. business_protocol_encode(pump_params, data, &data_length);
  437. // 下一步
  438. if(test_flag == 0)
  439. {
  440. goto_step(STEP_CLOSE);
  441. }
  442. else
  443. {
  444. goto_step(STEP_QUERY_QENG_SERVINGCELL);
  445. }
  446. }
  447. else if(query_cgreg_times > 10) // 最多查询20次
  448. {
  449. goto_failure("查询ps域次数过多");
  450. }
  451. else
  452. {
  453. goto_wait(400);
  454. query_cgreg_times++;
  455. }
  456. }
  457. else if(result == Result_Failed)
  458. {
  459. goto_failure("查询ps域失败");
  460. }
  461. break;
  462. case STEP_QUERY_QENG_SERVINGCELL: // 查询信号质量
  463. result = ec800m.qeng_servingcell(&signal.RSRP, &signal.RSRQ, &signal.RSSI, &signal.SINR);
  464. if(result == Result_Success)
  465. {
  466. goto_step(STEP_CLOSE);
  467. }
  468. else if(result == Result_Failed)
  469. {
  470. goto_failure("查询信号质量失败");
  471. }
  472. break;
  473. case STEP_CLOSE: // 关闭连接
  474. result = ec800m.close_socket(connectID);
  475. if(result == Result_Success)
  476. {
  477. goto_step(STEP_OPEN);
  478. }
  479. else if(result == Result_Failed)
  480. {
  481. goto_failure("关闭连接失败");
  482. }
  483. break;
  484. case STEP_OPEN: // 打开客户端
  485. result = ec800m.open_socket(connectID, "UDP", Host, Port, 1, &socket_err);
  486. if(result == Result_Success)
  487. {
  488. if(socket_err == 0)
  489. {
  490. goto_step(STEP_JUDGE_AUTH_OR_DATA);
  491. }
  492. else
  493. {
  494. goto_failure("客户端打开错误");
  495. }
  496. }
  497. else if(result == Result_Failed)
  498. {
  499. goto_failure("打开客户端失败");
  500. }
  501. break;
  502. case STEP_JUDGE_AUTH_OR_DATA: // 判断认证还是发送
  503. auth_or_data = judge_auth_or_data();
  504. if(auth_or_data == 1) // 已认证
  505. {
  506. goto_step(STEP_JOIN_DATA_MESSAGE);
  507. }
  508. else
  509. {
  510. goto_step(STEP_JOIN_AUTH_MESSAGE);
  511. }
  512. break;
  513. case STEP_JOIN_AUTH_MESSAGE: // 拼接认证报文
  514. if(auth_times > 0) // 最多重新认证一次
  515. {
  516. goto_failure("认证次数过多");
  517. }
  518. else
  519. {
  520. join_auth_message(coap_message, &coap_message_length);
  521. goto_step(STEP_SET_QISDE_0);
  522. auth_times++;
  523. }
  524. break;
  525. case STEP_JOIN_DATA_MESSAGE: // 拼接数据报文
  526. join_data_message(data, data_length, coap_message, &coap_message_length);
  527. goto_step(STEP_SET_QISDE_0);
  528. break;
  529. case STEP_SET_QISDE_0: // 关闭发送回显
  530. result = ec800m.set_qisde(0);
  531. if(result == Result_Success)
  532. {
  533. goto_step(STEP_SEND);
  534. }
  535. else if(result == Result_Failed)
  536. {
  537. goto_failure("关闭发送回显失败");
  538. }
  539. break;
  540. case STEP_SEND: // 发送send
  541. result = ec800m.send(connectID, coap_message, coap_message_length);
  542. if(result == Result_Success)
  543. {
  544. goto_step(STEP_RECV);
  545. }
  546. else if(result == Result_Failed)
  547. {
  548. goto_failure("发送send失败");
  549. }
  550. break;
  551. case STEP_RECV: // 等待结果
  552. result = ec800m.recv_with_time(connectID, coap_message, &coap_message_length, 10000);
  553. if(result == Result_Success)
  554. {
  555. uint8_t res = recv_data_handle(coap_message, coap_message_length);
  556. if(res == 0) // 发送失败
  557. {
  558. goto_step(STEP_JUDGE_AUTH_OR_DATA); // 重新认证
  559. }
  560. else if(res == 1) // 认证成功
  561. {
  562. goto_step(STEP_JOIN_DATA_MESSAGE);
  563. }
  564. else if(res == 2) // 发送成功
  565. {
  566. goto_success("发送成功");
  567. }
  568. }
  569. else if(result == Result_Failed)
  570. {
  571. goto_failure("等待结果失败");
  572. }
  573. break;
  574. case STEP_WAIT: // 等待
  575. wait();
  576. break;
  577. case STEP_SUCCESS: // 成功
  578. goto_step(STEP_SET_SLEEP);
  579. break;
  580. case STEP_FAILURE: // 失败
  581. goto_step(STEP_SET_SLEEP);
  582. break;
  583. case STEP_SET_SLEEP: // 设置休眠模式
  584. result = ec800m.set_sleep(1);
  585. if(result != Result_None)
  586. {
  587. goto_step(STEP_SET_CFUN_0);
  588. }
  589. break;
  590. case STEP_SET_CFUN_0: // 设置最小功能模式
  591. result = ec800m.set_cfun(0);
  592. if(result != Result_None)
  593. {
  594. goto_step(STEP_ENTER_SLEEP);
  595. }
  596. break;
  597. case STEP_ENTER_SLEEP: // 进入睡眠
  598. ec800m.enter_sleep();
  599. goto_step(STEP_FINISH);
  600. break;
  601. case STEP_FINISH: // 结束流程
  602. break;
  603. default:
  604. break;
  605. }
  606. }
  607. #endif