| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691 |
- /**
- ******************************************************************************
- * 版 本 :V1.0.0
- * 作 者 :liuyanbin,helomgxiang
- * 版权所有,盗版必究。
- * Copyright(C) All rights reserved
- ******************************************************************************
- * 历史记录
- * 序号 版本 变更内容 作者 日期
- * 1 V0.0.1 实现数据发送功能 何龙翔 2023/12/10
- * 2 V0.0.2 实现NB数据发送功能 刘艳斌 2024/1/10
- * 3 V0.0.3 整合4g和nb 刘艳斌 2024/1/24
- *
- ******************************************************************************
- */
- #include "stm32f10x.h"
- #include <stdio.h>
- #include <stdarg.h>
- #include <string.h>
- #include <stdlib.h>
- #include "BC260_UDP_Client5.h"
- #include "CoAP.h"
- #include "mbedtls_util.h"
- #include "cJSON.h"
- #include "sys.h"
- #include "bc260.h"
- #include "pump_dicts.h"
- #include "INflash.h"
- #if NBFLAG
- // 流程
- enum Step{
- STEP_NONE, // 空闲状态,无操作
- 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_SET_QISDE_0, // 关闭发送回显
- STEP_SEND, // 发送
- STEP_RECV, // 等待发送结果
-
- 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, // 流程结束
- };
- // 当前
- static enum Step step = STEP_NONE;
- // 下一步
- static enum Step next_step = STEP_NONE;
- // 客户端5
- struct BC260Y_Client_Struct UDP_Client5 = {
- .status = Client_Status_None,
- };
- // 注册后的参数
- extern Coefficient_Data flashdata;
- // socket ID
- static uint8_t connectID = 1;
- /** 阿里云连接参数 **/
- static char ProductKey[20] = "a1t3qlUNDcP";
- static char DeviceName[20] = "LTEcat1ceshi001";
- static char DeviceSecret[40] = "4929a78860f663ec72e2c313a4eee7ac";
- static char ClientID[60];
- static char Seq[10] = "666";
- static uint16_t Port = 5682;
- static char Host[60];
- static uint32_t SeqOffset;
- static char Random[20];
- static char Token[50];
- // payload缓存
- //static uint8_t payload[256];
- //static uint16_t payload_length;
- // coap报文
- static uint8_t coap_message[512];
- static uint16_t coap_message_length = 0;
- // aes cbc
- static uint8_t aes_key[16] = {0};
- static char iv[] = "543yhjy97ae7fyfg";
- // 泵参数
- static struct Pump_Params pump_params;
- // 待发送数据的地址和长度
- static uint8_t data[128];
- static uint16_t data_length;
- static uint8_t test_flag=0;
- // 计时相关的变量
- uint8_t Client5_time_flag = 0;
- uint32_t Client5_timer_ms = 0;
- uint32_t Client5_wait_time = 10;
- // 信号值
- static struct Signal
- {
- int RSRP;
- int RSRQ;
- int RSSI;
- int SINR;
- } signal = {
- .RSRP = 99,
- .RSRQ = 99,
- .RSSI = 99,
- .SINR = 99,
- };
- void Query_Signal(int * RSRP, int * RSRQ, int * RSSI, int * SINR)
- {
- *RSRP = signal.RSRP;
- *RSRQ = signal.RSRQ;
- *RSSI = signal.RSSI;
- *SINR = signal.SINR;
- }
- // 初始化
- void UDP_Client5_Init(void)
- {
- // 赋值三元组
- strcpy(ProductKey, flashdata.productKey);
- strcpy(DeviceName, flashdata.deviceName);
- strcpy(DeviceSecret, flashdata.deviceSecret);
-
- // 设置host
- memset(Host, '\0', sizeof(Host));
- strcat(Host, ProductKey);
- strcat(Host, ".coap.cn-shanghai.link.aliyuncs.com");
- // 设置clientid
- memset(ClientID, '\0', sizeof(ClientID));
- strcat(ClientID, ProductKey);
- strcat(ClientID, "&");
- strcat(ClientID, DeviceName);
- }
- // 声明函数。步骤跳转
- void goto_step(enum Step ns);
- // 发送流程
- void UDP_Client5_Handle(void);
- // 发送数据
- void UDP_Client5_Send(struct Pump_Params params,uint8_t test_switch)
- {
- test_flag=test_switch;
- if(step == STEP_NONE)
- {
- // 待发送数据的地址和长度
- pump_params = params;
- // 初始化
- UDP_Client5_Init();
- // 正在发送
- UDP_Client5.status = Client_Status_Sending;
- // 流程开始
- goto_step(STEP_START);
- }
- }
- // 获取状态
- enum Client_Status UDP_Client5_Status(void)
- {
- if(UDP_Client5.status == Client_Status_None)
- {
- return UDP_Client5.status;
- }
- else if(step == STEP_FINISH)
- {
- return UDP_Client5.status;
- }
- else
- {
- return Client_Status_Sending;
- }
- }
- // 清除
- void UDP_Client5_Clear(void)
- {
- // 流程置空
- goto_step(STEP_NONE);
- // 空闲
- UDP_Client5.status = Client_Status_None;
- }
- // 直接跳转到下一步
- static void goto_step(enum Step ns)
- {
- // 重置bc260y状态
- bc260y.reset();
- step = ns;
- }
- // 先等待再跳转到下一步
- static void goto_step_wait(enum Step ns, uint32_t t)
- {
- goto_step(STEP_WAIT); // 等待
- Client5_wait_time = t;
- next_step = ns; // 等待之后跳转
- }
- // 只等待,等待之后返回原来的步骤
- static void goto_wait(uint32_t t)
- {
- goto_step_wait(step, t);
- }
- // 失败
- static void goto_failure(char * info)
- {
- Log_Printf_Debug("STEP: 数据发送失败,%s\r\n", info);
- UDP_Client5.status = Client_Status_Failure;
- strcpy(UDP_Client5.info, info);
- goto_step(STEP_FAILURE);
- }
- // 成功
- static void goto_success(char * info)
- {
- Log_Printf_Debug("STEP: 数据发送成功,%s\r\n", info);
- UDP_Client5.status = Client_Status_Success;
- strcpy(UDP_Client5.info, info);
- goto_step(STEP_SUCCESS);
- }
- // 等待
- static void wait(void)
- {
- if(Client5_time_flag == 0)
- {
- Client5_timer_ms = 0;
- Client5_time_flag = 1;
- }
- else if(Client5_timer_ms > Client5_wait_time)
- {
- goto_step(next_step); // 进入下一步
- Client5_time_flag = 0;
- }
- }
- // 判断认证还是发送
- static uint8_t judge_auth_or_data(void)
- {
- if(strlen(Token) > 0) // 已认证
- {
- return 1;
- }
- else
- {
- return 0;
- }
- }
- // 拼接认证报文
- static void join_auth_message(uint8_t * coap_message, uint16_t * coap_message_length)
- {
- SeqOffset=65535;
- Log_Printf_Debug("STEP: 拼接认证报文,seqOffset=%d\r\n", SeqOffset);
- // 先清除
- // memset(coap_message, 0, sizeof(coap_message));
- // coap_message_length = 0;
-
- // CoAP协议
- CoAP_Init();
- CoAP_Set_T(0);
- CoAP_Set_Code(2);
- CoAP_Set_MessageID(SeqOffset);
- // option
- // host
- CoAP_Set_Option_Str(3, Host);
- // port
- CoAP_Set_Option_Short(7, Port);
- // path
- CoAP_Set_Option_Str(11, "auth");
- // content-format
- CoAP_Set_Option_Short(12, 50);
- // accept
- CoAP_Set_Option_Short(17, 50);
-
- // 待签名数据
- // 签名相关
- static char StrForSignature[100];
- static char sign[50];
- memset(StrForSignature, '\0', sizeof(StrForSignature));
- sprintf((char * )StrForSignature, "clientId%sdeviceName%sproductKey%sseq%s", ClientID, DeviceName, ProductKey, Seq);
- // 签名
- memset(sign, '\0', sizeof(sign));
- utils_hmac_sha1_str(StrForSignature, strlen((char * )StrForSignature), sign, DeviceSecret, strlen(DeviceSecret));
- // payload
- // memset(payload, '\0', sizeof(payload));
- char payload[256] = {0};
- sprintf((char * )payload, "{\"clientId\":\"%s\",\"signmethod\":\"hmacsha1\",\"sign\":\"%s\",\"productKey\":\"%s\",\"deviceName\":\"%s\",\"seq\":\"%s\"}", ClientID, sign, ProductKey, DeviceName, Seq);
- // 设置payload
- CoAP_Set_Payload_Str(payload);
-
- // 生成报文
- * coap_message_length = CoAP_Get_Length();
- memcpy(coap_message, CoAP_Get_Message(), * coap_message_length);
- }
- // 拼接数据报文
- static void join_data_message(uint8_t * data, uint8_t data_length, uint8_t * coap_message, uint16_t * coap_message_length)
- {
- SeqOffset++;
- Log_Printf_Debug("STEP: 拼接数据报文,seqOffset=%d\r\n", SeqOffset);
-
- // 先清除
- // memset(coap_message, 0, sizeof(coap_message));
- // coap_message_length = 0;
-
- char out[80]={0};
- char sha256_source[100] = {0};
- snprintf(sha256_source, sizeof(sha256_source), "%s,%s" ,DeviceSecret ,Random);
- Log_Printf_Debug("sha256_source: %s\r\n", sha256_source);
- utils_sha256(sha256_source, strlen(sha256_source), out);
- memset(aes_key, 0, sizeof(aes_key));
- memcpy(aes_key, out+8, 16); //获取key
-
- // CoAP协议
- CoAP_Init();
- CoAP_Set_T(0);
- CoAP_Set_Code(2);
- CoAP_Set_MessageID(SeqOffset);
- // option
- // host
- CoAP_Set_Option_Str(3, Host);
- // port
- CoAP_Set_Option_Short(7, Port);
- // path
- CoAP_Set_Option_Str(11, "topic");
- CoAP_Set_Option_Str(11, "sys");
- CoAP_Set_Option_Str(11, ProductKey);
- CoAP_Set_Option_Str(11, DeviceName);
- CoAP_Set_Option_Str(11, "thing");
- CoAP_Set_Option_Str(11, "model");
- CoAP_Set_Option_Str(11, "up_raw");
- // content-format
- CoAP_Set_Option_Short(12, 50);
- // accept
- CoAP_Set_Option_Short(17, 50);
- // 2088
- CoAP_Set_Option_Str(2088, Token);
- // 2089
- char Rand2089[10] = {'\0'};
- char Opt2089[20] = {'\0'};
- my_itoa(SeqOffset, Rand2089, 10);
- int Opt2089_Length = utils_aes128_cbc_enc((char * )aes_key, iv, Rand2089, Opt2089);
- CoAP_Set_Option_Str(2089, Opt2089);
-
- // payload
- // memset(payload, '\0', sizeof(payload));
- uint8_t payload[256] = {0};
-
- //
- int payload_length = utils_aes128_cbc_enc_with_length((char * )aes_key, iv, data, data_length, payload);
- // payload_length = utils_aes128_cbc_enc((char * )aes_key, iv, (char * )Data_Buffer, (char * )payload);
- Log_Printf_Debug("payload_length: %d\r\n", payload_length);
-
- CoAP_Set_Payload(payload, payload_length);
-
- // 生成报文
- * coap_message_length = CoAP_Get_Length();
- memcpy(coap_message, CoAP_Get_Message(), * coap_message_length);
- }
- // 等待数据返回
- static uint8_t recv_data_handle(uint8_t * coap_message, uint16_t coap_message_length)
- {
- uint16_t payload_length = CoAP_Get_Payload_Length(coap_message, coap_message_length);
- uint8_t payload[256] = {0};
- CoAP_Get_Payload(coap_message, coap_message_length, payload);
-
- Log_Printf_Debug("payload长度: %d\r\n", payload_length);
-
- // 判断是认证返回,还是数据发送返回
- if(payload_length == 0) // 无返回
- {
- // 清空Token,重新认证
- memset(Token, '\0', sizeof(Token));
- return 0;
- }
- else if(payload[0] == '{' && payload[payload_length-1] == '}') // 认证返回
- {
- // 解析json
- cJSON * cjson = cJSON_Parse((char * )payload);
- Log_Printf_Debug("plaintext(%d): %s\r\n",payload_length, payload);
- memset(Random, '\0', sizeof(Random));
- memset(Token, '\0', sizeof(Token));
- if(cJSON_HasObjectItem(cjson, "random"))
- {
- char * random = cJSON_GetObjectItem(cjson, "random")->valuestring;
- strcpy(Random, random);
- }
- if(cJSON_HasObjectItem(cjson, "seqOffset"))
- {
- uint16_t seqOffset = cJSON_GetObjectItem(cjson, "seqOffset")->valueint;
- SeqOffset = seqOffset;
- }
- if(cJSON_HasObjectItem(cjson, "token"))
- {
- char * token = cJSON_GetObjectItem(cjson, "token")->valuestring;
- strcpy(Token, token);
- }
- Log_Printf_Debug("\r\n(%s, %s, %d)\r\n", Random, Token, SeqOffset);
- cJSON_Delete(cjson);//清除结构体
- return 1;
- }
- else
- {
- // 数据发送成功返回
- uint8_t plaintext[256] = {0}; // 明文
- uint16_t plaintext_length = utils_aes128_cbc_dec((char * )aes_key, iv, (char * )payload, payload_length, (char * )plaintext);
- Log_Printf_Debug("\r\nplaintext(%d): %s\r\n",plaintext_length, (char *)plaintext);
- return 2;
- }
- }
- // 发送数据的逻辑
- 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 uint8_t auth_times = 0; // 认证次数
- static uint16_t socket_err = 0;
- static uint8_t auth_or_data = 0;
- void UDP_Client5_Handle(void)
- {
- // 流程
- switch(step)
- {
- case STEP_NONE: // 空闲
- break;
- case STEP_START: // 开始
- query_cgreg_times = 0; // 查询网络状态的次数
- auth_times = 0; // 认证次数
- goto_step(STEP_EXIT_SLEEP);
- break;
- case STEP_EXIT_SLEEP: // 退出休眠
- result = bc260y.exit_sleep();
- if(result == Result_Success)
- {
- goto_step_wait(STEP_SET_CFUN_1, 5);
- }
- else if(result == Result_Failed)
- {
- goto_step_wait(STEP_SET_CFUN_1, 100);
- }
- break;
- case STEP_SET_CFUN_1: // 设置全功能模式
- result = bc260y.set_cfun(1);
- if(result == Result_Success)
- {
- goto_step(STEP_SET_CGREG_2);
- }
- else if(result == Result_Failed)
- {
- goto_failure("设置全功能模式失败");
- }
- break;
- case STEP_SET_CGREG_2: // 设置ps域
- result = bc260y.set_cgreg(2);
- if(result == Result_Success)
- {
- goto_step(STEP_SET_QISDE_0);
- }
- else if(result == Result_Failed)
- {
- goto_failure("设置ps域失败");
- }
- break;
- case STEP_SET_QISDE_0: // 关闭回显
- result = bc260y.set_qisde(0);
- if(result == Result_Success)
- {
- goto_step(STEP_QUERY_CGREG);
- }
- else if(result == Result_Failed)
- {
- goto_failure("关闭回显失败");
- }
- break;
- case STEP_QUERY_CGREG: // 查询ps域
- result = bc260y.query_cgreg(&cgreg_n, &cgreg_stat, &cgreg_lac, &cgreg_ci);
- if(result == Result_Success)
- {
- if(cgreg_stat == 1)
- {
- // 参数赋值
- pump_params.lac = cgreg_lac;
- pump_params.ci = cgreg_ci;
- // 编码
- business_protocol_encode(pump_params, data, &data_length);
- // 下一步
- if(test_flag == 0)
- {
- goto_step(STEP_CLOSE);
- }
- else
- {
- goto_step(STEP_QUERY_QENG_SERVINGCELL);
- }
- }
- else if(query_cgreg_times > 10) // 最多查询20次
- {
- goto_failure("查询ps域次数过多");
- }
- else
- {
- goto_wait(400);
- query_cgreg_times++;
- }
- }
- 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)
- {
- goto_step(STEP_CLOSE);
- }
- else if(result == Result_Failed)
- {
- goto_failure("查询信号质量失败");
- }
- break;
- case STEP_CLOSE: // 关闭连接
- result = bc260y.close_socket(connectID);
- if(result == Result_Success)
- {
- goto_step(STEP_DATAFORMAT);
- }
- else if(result == Result_Failed)
- {
- goto_failure("关闭连接失败");
- }
- break;
- case STEP_DATAFORMAT:
- result = bc260y.dataformat(1);
- if(result == Result_Success)
- {
- goto_step(STEP_OPEN);
- }
- else if(result == Result_Failed)
- {
- goto_failure("配置发送格式失败");
- }
- break;
- case STEP_OPEN: // 打开客户端
- result = bc260y.open_socket(connectID, "UDP", Host, Port, 1, &socket_err);
- if(result == Result_Success)
- {
- if(socket_err == 0)
- {
- goto_step(STEP_JUDGE_AUTH_OR_DATA);
- }
- else
- {
- goto_failure("客户端打开错误");
- }
- }
- else if(result == Result_Failed)
- {
- goto_failure("打开客户端失败");
- }
- break;
- case STEP_JUDGE_AUTH_OR_DATA: // 判断认证还是发送
- auth_or_data = judge_auth_or_data();
- if(auth_or_data == 1) // 已认证
- {
- goto_step(STEP_JOIN_DATA_MESSAGE);
- }
- else
- {
- goto_step(STEP_JOIN_AUTH_MESSAGE);
- }
- break;
- case STEP_JOIN_AUTH_MESSAGE: // 拼接认证报文
- if(auth_times > 0) // 最多重新认证一次
- {
- goto_failure("认证次数过多");
- }
- else
- {
- join_auth_message(coap_message, &coap_message_length);
- goto_step(STEP_SEND);
- auth_times++;
- }
- break;
- case STEP_JOIN_DATA_MESSAGE: // 拼接数据报文
- join_data_message(data, data_length, coap_message, &coap_message_length);
- goto_step(STEP_SEND);
- break;
- case STEP_SEND: // 发送send
- result = bc260y.send_rai(connectID, coap_message, coap_message_length,2);
- if(result == Result_Success)
- {
- goto_step(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 = recv_data_handle(coap_message, coap_message_length);
- if(res == 0) // 发送失败
- {
- goto_step(STEP_JUDGE_AUTH_OR_DATA); // 重新认证
- }
- else if(res == 1) // 认证成功
- {
- goto_step(STEP_JOIN_DATA_MESSAGE);
- }
- else if(res == 2) // 发送成功
- {
- goto_success("发送成功");
- }
- }
- else if(result == Result_Failed)
- {
- goto_failure("等待结果失败");
- }
- break;
- case STEP_WAIT: // 等待
- wait();
- break;
- case STEP_SUCCESS: // 成功
- goto_step(STEP_SET_SLEEP);
- break;
- case STEP_FAILURE: // 失败
- goto_step(STEP_SET_SLEEP);
- break;
- case STEP_SET_SLEEP: // 设置休眠模式
- result = bc260y.set_sleep(1);
- if(result != Result_None)
- {
- goto_step(STEP_ENTER_SLEEP);
- }
- break;
- case STEP_ENTER_SLEEP: // 进入睡眠
- //bc260y.enter_sleep();
- goto_step(STEP_FINISH);
- break;
- case STEP_FINISH: // 结束流程
- break;
- default:
- break;
- }
-
- }
- #endif
|