#include "task.h" #include "malloc.h" #include "cjson.h" #include "myFile.h" #include "gateway_message.h" #include "log.h" #include "sx1276.h" #include "radio.h" void processHTTPjson(cJSON *json); void processDevice(cJSON *json, const char *readString); void master_task(char *string); void slave_task(); tRadioDriver *Radio = NULL; uint16_t BufferSize ; uint8_t Buffer[256]; uint32_t rx_num = 0; uint8_t PingMsg[] = "PING\0"; uint8_t PongMsg[] = "PONG\0"; /** * @brief 从输入字符串匹配对应的key并将value中的string返回 * @param cJSON *data_obj json对象, const char *key key关键字 * @retval 解析出的string */ char *processStringData(cJSON *data_obj, const char *key) { cJSON *json_data = cJSON_GetObjectItemCaseSensitive(data_obj, key); if (cJSON_IsString(json_data) && (json_data->valuestring != NULL)) { return json_data->valuestring; } else { // gateway.data_valid_flag = 0; // 如果任意数据为NULL则此次数据为无效 return NULL; } } // json解析int int processIntData(cJSON *data_obj, const char *key) { cJSON *json_data = cJSON_GetObjectItemCaseSensitive(data_obj, key); // if (cJSON_IsNumber(json_data) && (json_data->valueint != NULL)) 解决寄存器地址为0问题 if (cJSON_IsNumber(json_data)) { return json_data->valueint; } else { // gateway.data_valid_flag = 0; // 如果任意数据为NULL则此次数据为无效 return -1; } } // 解析json中包含的节点数量,已经节点的id void processNodeListData(cJSON *data_obj, GATEWAY_PARAMS *gateway) { cJSON *nodeList = cJSON_GetObjectItemCaseSensitive(data_obj, "nodeList"); if (nodeList == NULL || !cJSON_IsArray(nodeList)) { cJSON_Delete(nodeList); } int nodeListSize = cJSON_GetArraySize(nodeList); for (int i = 0; i < nodeListSize; i++) { cJSON *node = cJSON_GetArrayItem(nodeList, i); if (cJSON_IsString(node)) { addNode(gateway, node->valuestring); // 往链表中不断加入新的节点 } } } /* ********************************************************************************************************* * 函 数 名: void data_task(void *pdata) * 功能说明: 主要是data_task处理线程,优先级高。其运行逻辑是将nandflash中的数据解析出来轮询发送数据 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ void data_task(void *pdata) { OS_CPU_SR cpu_sr; pdata = pdata; char *lora_config_json = malloc(15 * 1024); read_file("lora_json.txt", lora_config_json); cJSON *json = cJSON_Parse(lora_config_json); if (json != NULL) { OS_ENTER_CRITICAL(); // 进入临界区确保同一时间只有一个线程访问gatewayMessage processHTTPjson(json); OS_EXIT_CRITICAL(); } else { LogPrint(LOG_INFO, __func__, __LINE__, "json is to long"); } cJSON_Delete(json); free(lora_config_json); Radio = RadioDriverInit(); Radio->Init(); #ifdef MASTER Radio->SetTxPacket(PingMsg, strlen((const char *)PingMsg)); printf("MASTER"); #else Radio->StartRx(); printf("SLAVE"); #endif while (1) { #ifdef MASTER master_task("a"); #else slave_task(); #endif } } /* ********************************************************************************************************* * 函 数 名: void processHTTPjson(cJSON *json) * 功能说明: 解析http下载json文件数据转换为结构体信息保存在内部结构体 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ void processHTTPjson(cJSON *json) { GATEWAY_PARAMS *gateway = get_gateway_config_params(); // 解析必须的网关信息 strcpy(gateway->host, processStringData(json, "host")); gateway->port = processIntData(json, "port"); strcpy(gateway->messageTopic, processStringData(json, "messageTopic")); strcpy(gateway->commandTopic, processStringData(json, "commandTopic")); // 解析节点lodelist内包含的nodelist的设备序列号并扩充整个设备链表 processNodeListData(json, gateway); NODE_PARAMS *current = gateway->node_params; // 拿到节点的名称后去解析json的相关内容 while (current != NULL) { char *processNodeRead = malloc(20); sprintf(processNodeRead, "read_%s", current->node_address); cJSON *readArrayItem = cJSON_GetObjectItem(json, processNodeRead); if (cJSON_IsArray(readArrayItem)) { uint8_t read_data_num = cJSON_GetArraySize(readArrayItem); for (int i = 0; i < read_data_num; i++) { cJSON *read_data_obj = cJSON_GetArrayItem(readArrayItem, i); // 解析到节点内部的内容 if (cJSON_IsObject(read_data_obj)) { DEVICE_PARAMS *currentDevice; } else { } } } free(processNodeRead); current = current->nextNode; } } /* ********************************************************************************************************* * 函 数 名: void master_task(char *string) * 功能说明: 主网关sx1278轮询发送调用接口,发送结束后就将状态切换到接收状态,等待从机的响应值,当从机超时或接收到数据进行后续数据处理的流程 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ volatile uint32_t startTime; //记录开始的时间 void master_task(char *string) { switch (Radio->Process()) { case RF_RX_DONE: Radio->GetRxPacket(Buffer, &BufferSize); printf("Master_Task:RX_____%s,Rx_num:%d\n", Buffer, rx_num); rx_num++; if (strncmp((const char *)Buffer, (const char *)PongMsg, strlen((const char *)PongMsg)) == 0) { Radio->SetTxPacket(PingMsg, strlen((const char *)PingMsg)); startTime=OSTimeGet(); delay_ms(1000); } break; case RF_TX_DONE: startTime=OSTimeGet(); Radio->StartRx(); case RF_BUSY: case RF_IDLE: if(OSTimeGet()-startTime>10000) //每次发送信号时记录上一次发送的时间如果超过一段时间没有响应则进行下一次发送 { Radio->SetTxPacket(PingMsg, strlen((const char *)PingMsg)); startTime=OSTimeGet(); delay_ms(1000); } default: OSTimeDlyHMSM(0, 0, 0, 500); break; } } /* ********************************************************************************************************* * 函 数 名: void slave_task(char *string) * 功能说明: 负责从站数据处理 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ volatile bool rxflag=false; void slave_task() { switch (Radio->Process()) { case RF_RX_DONE: Radio->GetRxPacket(Buffer, &BufferSize); printf("Slave_Task:RX_____%s,Rx_num:%d\n", Buffer, rx_num); rx_num++; if (strncmp((const char *)Buffer, (const char *)PingMsg, strlen((const char *)PingMsg)) == 0) { Radio->SetTxPacket(PongMsg, strlen((const char *)PongMsg)); delay_ms(1000); } break; case RF_TX_DONE: Radio->StartRx(); break; case RF_IDLE: case RF_BUSY: default: OSTimeDlyHMSM(0, 0, 0, 500); } }