#include "CONFIG.h" #if BC260Y #include "stm32f10x.h" #include #include #include #include #include "UDP_Client.h" #include "Timer_Module.h" #include "Log_Module.h" #include "mbedtls_util.h" #include "cJSON.h" #include "bc260y.h" #include "Pump_Dicts_Util.h" #include "Regist.h" #include "PumpBusiness.h" #include "Initialize.h" #include "Tuoreniot.h" // 测试模式 uint8_t UDPCLIENT_TestModeFlag = 0; // socket ID static uint8_t connectID = 1; // coap报文 static uint8_t coap_message[512]; static uint16_t coap_message_length = 0; // 待发送数据的地址和长度 static uint8_t data[128]; static uint16_t data_length; // 信号值 static struct Signal { int RSRP; int RSRQ; int RSSI; int SINR; } signal = { .RSRP = 99, .RSRQ = 99, .RSSI = 99, .SINR = 99, }; // 查询信号质量 void UDPCLIENT_QuerySignal(int * RSRP, int * RSRQ, int * RSSI, int * SINR) { *RSRP = signal.RSRP; *RSRQ = signal.RSRQ; *RSSI = signal.RSSI; *SINR = signal.SINR; } // 函数声明 static void UDPCLIENT_Process(void); // 流程 static void UDPCLIENT_SetStatus(enum UDPCLIENT_StatusEnum status); // 设置状态 static void UDPCLIENT_SetResult(enum UDPCLIENT_ResultEnum result); // 设置结果 static void goto_start(void); // 开始 static void goto_success(void); // 成功 static void goto_failure(char * _info); // 失败 static void goto_finish(void); // 结束 // 流程 enum Step{ STEP_START, // 开始 STEP_EXIT_SLEEP, // 退出睡眠 STEP_ENTER_SLEEP, // 进入睡眠 STEP_WAIT, // 等待 STEP_STATE, // 查询状态 STEP_OPEN, // 打开 STEP_OPEN_WAIT_RESULT, // 等待打开结果 STEP_JUDGE_AUTH_OR_DATA, // 判断认证还是发送 STEP_JOIN_AUTH_MESSAGE, // 拼接认证报文 STEP_JOIN_DATA_MESSAGE, // 拼接数据报文 STEP_QUERY_SLEEP, // 查询休眠 STEP_SET_SLEEP, // 开启休眠 STEP_QUERY_QENG_SERVINGCELL, // 查询信号质量 STEP_QUERY_ID, //查询SIM卡号 STEP_SET_QISDE_0, // 关闭发送回显 STEP_SET_QISDE_1, STEP_SEND, // 发送 STEP_RECV, // 等待发送结果 STEP_QUERY_CFUN, STEP_SET_CFUN_0, // 设置最小功能模式 STEP_WAIT_SET_CFUN_0, // 等待设置最小功能模式 STEP_SET_CFUN_1, // 设置全功能模式 STEP_WAIT_SET_CFUN_1, // 等待设置全功能模式结果 STEP_SET_CGREG_2, // 设置ps域允许上报网络注册和位置信息 STEP_QUERY_CGREG, // 查询网络注册状态 STEP_DATAFORMAT,//配置发送格式 STEP_CLOSE, // 关闭 STEP_SUCCESS, // 成功 STEP_FAILURE, // 失败 STEP_FINISH, // 流程结束 STEP_VERIFY_REGIST,//验证注册 STEP_VERIFY_INITIALIZE, // 验证初始化 STEP_QUERY_SOCKET, // 查询连接 STEP_QUERY_DNS, // 查询DNS STEP_SET_DNS, // 设置DNS STEP_QUERY_CFUN_DNS, // 设置完dns后,查询功能模式 STEP_SET_CFUN_0_DNS, // 设置完dns后,设置最小功能模式 }; // 步骤跳转时的监听 static uint8_t STEP_JOIN_AUTH_MESSAGE_times = 0; // 认证的次数 static uint8_t STEP_SET_CFUN_1_times = 0; // 全功能模式的次数 static void initialize() { STEP_JOIN_AUTH_MESSAGE_times = 0; STEP_SET_CFUN_1_times = 0; } static uint16_t goto_step_event(uint16_t ns) { // 重置bc260y状态 bc260y.reset(); // 流程控制 uint16_t step = ns; if(step == STEP_JOIN_AUTH_MESSAGE && STEP_JOIN_AUTH_MESSAGE_times++ >= 1) { goto_failure("认证次数过多"); step = STEP_FAILURE; } else if(step == STEP_SET_CFUN_1 && STEP_SET_CFUN_1_times++ >= 2) { goto_failure("重新联网次数过多"); step = STEP_FAILURE; } return step; } // 流程控制 static struct PCTRL_Struct pctrl = { .current_step = STEP_FINISH, .next_step = STEP_FINISH, .step_wait = STEP_WAIT, .goto_step_listener = goto_step_event, }; // 备注 static char info[40]; // 开始 static void goto_start(void) { initialize(); PCTRL_GotoStep(&pctrl, STEP_START, "开始"); } // 成功 static void goto_success(void) { UDPCLIENT_SetResult(UDPCLIENT_Result_Success); PCTRL_GotoStep(&pctrl, STEP_SUCCESS, "成功"); } // 失败 static void goto_failure(char * _info) { UDPCLIENT_SetResult(UDPCLIENT_Result_Failure); memset(info, 0, sizeof(info)); strcpy(info, _info); PCTRL_GotoStep(&pctrl, STEP_FAILURE, "失败"); Log_Printf_Debug("info:%s!\r\n", info); } // 结束 static void goto_finish(void) { UDPCLIENT_SetStatus(UDPCLIENT_Status_Done); PCTRL_GotoStep(&pctrl, STEP_FINISH, "结束"); } // 状态 static enum UDPCLIENT_StatusEnum udpclient_status = UDPCLIENT_Status_None; // 结果 static enum UDPCLIENT_ResultEnum udpclient_result = UDPCLIENT_Result_None; // 设置状态 static void UDPCLIENT_SetStatus(enum UDPCLIENT_StatusEnum status) { udpclient_status = status; } // 获取状态 enum UDPCLIENT_StatusEnum UDPCLIENT_GetStatus(void) { return udpclient_status; } // 设置结果 static void UDPCLIENT_SetResult(enum UDPCLIENT_ResultEnum result) { udpclient_result = result; } // 获取结果 enum UDPCLIENT_ResultEnum UDPCLIENT_GetResult(void) { return udpclient_result; } // 重置 enum EXECUTE_ResultEnum UDPCLIENT_Reset(void) { if(UDPCLIENT_GetStatus() == UDPCLIENT_Status_Being) { Log_Printf_Debug("发送流程重置错误!\r\n"); return EXECUTE_Result_Failure; } UDPCLIENT_SetStatus(UDPCLIENT_Status_None); UDPCLIENT_SetResult(UDPCLIENT_Result_None); return EXECUTE_Result_Success; } // 开始 enum EXECUTE_ResultEnum UDPCLIENT_Start(void) { UDPCLIENT_Reset(); if(UDPCLIENT_GetStatus() != UDPCLIENT_Status_None) { Log_Printf_Debug("发送流程启动错误!\r\n"); return EXECUTE_Result_Failure; } goto_start(); UDPCLIENT_SetStatus(UDPCLIENT_Status_Being); return EXECUTE_Result_Success; } // 流程处理,放到大循环里 void UDPCLIENT_ProcessHandle(void) { if(UDPCLIENT_GetStatus() == UDPCLIENT_Status_Being) { UDPCLIENT_Process(); } } //// 发送数据的逻辑 static enum Result result = Result_None; static uint8_t cgreg_n; static uint8_t cgreg_stat; static uint16_t cgreg_lac; static uint32_t cgreg_ci; //static uint8_t query_cgreg_times = 0; // 查询网络状态的次数 static uint16_t socket_err = 0; // dns static char pridnsaddr[20]; static uint8_t cfun_mode = 0; static uint8_t connectstate = 0; // 开启回显的标志 static void UDPCLIENT_Process(void) { // 流程 switch(pctrl.current_step) { case STEP_START: // 开始 PCTRL_GotoStep(&pctrl, STEP_EXIT_SLEEP, "退出休眠"); break; case STEP_EXIT_SLEEP: // 退出休眠 result = bc260y.exit_sleep_2(); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_SET_QISDE_1, "开启回显"); } else if(result == Result_Failed) { goto_failure("退出休眠失败"); } break; case STEP_SET_QISDE_1: // 开启回显 result = bc260y.set_qisde(1); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_SET_SLEEP, "设置休眠模式"); } else if(result == Result_Failed) { goto_failure("开启回显失败"); } break; case STEP_SET_SLEEP: // 设置休眠模式 result = bc260y.set_sleep(2); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_DATAFORMAT, "配置发送格式"); } else if(result == Result_Failed) { goto_failure("设置休眠模式失败"); } break; case STEP_DATAFORMAT: // 配置发送格式 result = bc260y.dataformat(1); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_QUERY_CFUN, "查询功能模式"); } else if(result == Result_Failed) { goto_failure("配置发送格式失败"); } break; case STEP_QUERY_CFUN: // 查询功能模式 result = bc260y.query_cfun(&cfun_mode); if(result == Result_Success) { if(cfun_mode == 0) { PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_1, "设置全功能模式"); } else { PCTRL_GotoStep(&pctrl, STEP_QUERY_DNS, "查询DNS"); memset(pridnsaddr, 0, sizeof(pridnsaddr)); } } else if(result == Result_Failed) { goto_failure("查询功能模式失败"); } break; case STEP_SET_CFUN_0: result=bc260y.set_cfun(0);//设置最小功能模式 if(result == Result_Success) { if(UDPCLIENT_GetResult() != UDPCLIENT_Result_None) { goto_finish(); } else { PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_1, "设置全功能模式"); } } else if(result == Result_Failed) { goto_failure("设置最小功能模式失败"); goto_finish(); } break; case STEP_SET_CFUN_1: // 设置全功能模式 result = bc260y.set_cfun(1); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_QUERY_DNS, "查询DNS"); memset(pridnsaddr, 0, sizeof(pridnsaddr)); } else if(result == Result_Failed) { goto_failure("设置全功能模式失败"); } break; case STEP_QUERY_DNS: // 查询DNS result = bc260y.query_dns(pridnsaddr); if(result == Result_Success) { if(strlen(pridnsaddr) <= 1) { PCTRL_GotoStep(&pctrl, STEP_SET_DNS, "设置DNS"); } else { PCTRL_GotoStep(&pctrl, STEP_SET_CGREG_2, "设置ps域"); } } else if(result == Result_Failed) { goto_failure("查询DNS失败"); } break; case STEP_SET_DNS: result = bc260y.set_dns("114.114.114.114", "8.8.8.8"); // 设置DNS if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_0, "设置完DNS,设置最小功能模式"); } else if(result == Result_Failed) { goto_failure("设置DNS失败"); } break; case STEP_SET_CGREG_2: // 设置ps域 result = bc260y.set_cereg(2); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_QUERY_ID, "查询SIM卡号"); } else if(result == Result_Failed) { goto_failure("设置ps域失败"); } break; case STEP_QUERY_ID: //查询SIM卡号 result = bc260y.query_qccid(pump_params.sim); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_QUERY_CGREG, "查询ps域"); } else if(result == Result_Failed) { goto_failure("查询SIM卡号失败"); } break; case STEP_QUERY_CGREG: // 查询ps域 result = bc260y.query_cereg(&cgreg_n, &cgreg_stat, &cgreg_lac, &cgreg_ci); if(result == Result_Success) { if(cgreg_stat == 1) { // 下一步 if(UDPCLIENT_TestModeFlag == 0) { PCTRL_GotoStep(&pctrl, STEP_QUERY_SOCKET, "查询连接"); } else { PCTRL_GotoStep(&pctrl, STEP_QUERY_QENG_SERVINGCELL, "查询信号质量"); } } else { goto_failure("网络注册失败"); } } else if(result == Result_Failed) { goto_failure("查询ps域失败"); } break; case STEP_QUERY_QENG_SERVINGCELL: // 查询信号质量 result = bc260y.qeng_servingcell(&signal.RSRP, &signal.RSRQ, &signal.RSSI, &signal.SINR); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_QUERY_SOCKET, "查询连接"); } else if(result == Result_Failed) { goto_failure("查询信号质量失败"); } break; case STEP_QUERY_SOCKET: // 查询连接 result =bc260y.query_socket_state(connectID,&connectstate); if(result == Result_Success) { if(connectstate==2) { PCTRL_GotoStep(&pctrl, STEP_JUDGE_AUTH_OR_DATA, "判断认证或发送"); } else { PCTRL_GotoStep(&pctrl, STEP_CLOSE, "关闭连接"); } } else if(result == Result_Failed) { goto_failure("查询UDP连接失败"); } break; case STEP_CLOSE: // 关闭连接 result = bc260y.close_socket(connectID); if(result == Result_Success) { PCTRL_GotoStep(&pctrl, STEP_OPEN, "打开客户端"); } else if(result == Result_Failed) { goto_failure("关闭连接失败"); } break; case STEP_OPEN: // 打开客户端 result = bc260y.open_socket(connectID, "UDP", regist_response.remoteAddress, regist_response.remotePort, 1, &socket_err); if(result == Result_Success) { if(socket_err == 0) { PCTRL_GotoStep(&pctrl, STEP_JUDGE_AUTH_OR_DATA, "判断认证或发送"); } else { PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_0, "打开客户端失败,设置最小功能模式"); } } else if(result == Result_Failed) { goto_failure("打开客户端失败"); } break; case STEP_JUDGE_AUTH_OR_DATA: // 判断认证或发送 if(TUORENIOT_IsAuthentication() == 1) // 已认证 { PCTRL_GotoStep(&pctrl, STEP_JOIN_DATA_MESSAGE, "拼接数据报文"); } else { PCTRL_GotoStep(&pctrl, STEP_JOIN_AUTH_MESSAGE, "拼接认证报文"); } break; case STEP_JOIN_AUTH_MESSAGE: // 拼接认证报文 memset(coap_message, 0, sizeof(coap_message)); TUORENIOT_PackAuthMessage(coap_message, &coap_message_length); // Log_Printf_Debug("认证报文:%d\r\n", coap_message_length); // Log_SendHex(coap_message, coap_message_length); // Log_Printf_Debug("\r\n"); PCTRL_GotoStep(&pctrl, STEP_SEND, "发送认证报文"); break; case STEP_JOIN_DATA_MESSAGE: // 拼接数据报文 pump_params.lac = cgreg_lac; pump_params.ci = cgreg_ci; PUMPBUSINESS_ParamsRefresh(); // 编码 memset(data, 0, sizeof(data)); PUMPDICTS_ProtocolEncode(&pump_params, data, &data_length); memset(coap_message, 0, sizeof(coap_message)); TUORENIOT_PackDataMessage(data, data_length, coap_message, &coap_message_length); // Log_Printf_Debug("数据报文:%d\r\n", coap_message_length); // Log_SendHex(coap_message, coap_message_length); // Log_Printf_Debug("\r\n"); PCTRL_GotoStep(&pctrl, STEP_SEND, "发送数据报文"); break; case STEP_SEND: // 发送send result = bc260y.send_rai(connectID, coap_message, coap_message_length, 2); if(result == Result_Success) { memset(coap_message, 0, sizeof(coap_message)); PCTRL_GotoStep(&pctrl, STEP_RECV, "等待接收数据"); } else if(result == Result_Failed) { goto_failure("发送send失败"); } break; case STEP_RECV: // 等待结果 result = bc260y.recv_with_time(connectID, coap_message, &coap_message_length, 10000); if(result == Result_Success) { uint8_t res = TUORENIOT_AnalysisMessage(coap_message, coap_message_length); if(res == 0) // 发送失败 { PCTRL_GotoStep(&pctrl, STEP_JUDGE_AUTH_OR_DATA, "重新认证"); // 重新认证 } else if(res == 1) // 认证成功 { PCTRL_GotoStep(&pctrl, STEP_JOIN_DATA_MESSAGE, "拼接数据报文"); } else if(res == 2) // 发送成功 { goto_success(); } } else if(result == Result_Failed) { PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_0, "重新发送,设置最小功能模式"); } break; case STEP_WAIT: // 等待 PCTRL_Wait(&pctrl); break; case STEP_SUCCESS: // 成功 goto_finish(); break; case STEP_FAILURE: // 失败 PCTRL_GotoStep(&pctrl, STEP_SET_CFUN_0, "失败,设置最小功能模式"); break; case STEP_FINISH: // 结束流程 break; default: goto_failure("步骤不存在"); break; } } #endif