diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/client_adapter.c b/APP_Framework/Applications/app_test/test_lora_p2p/client_adapter.c new file mode 100644 index 000000000..444b419b2 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_lora_p2p/client_adapter.c @@ -0,0 +1,561 @@ +// +// Created by 18363 on 2023/9/17. +// + +#include + +#ifdef ADAPTER_SX1278 +extern AdapterProductInfoType Sx1278Attach(struct Adapter *adapter); +#endif + +#ifdef ADAPTER_E220 +extern AdapterProductInfoType E220Attach(struct Adapter *adapter); +#endif + +#ifdef ADAPTER_E22 +extern AdapterProductInfoType E22Attach(struct Adapter *adapter); +#endif + +/*******************报文宏********************/ +#define ADAPTER_LORA_DATA_LENGTH 112 +#define ADAPTER_LORA_TRANSFER_DATA_LENGTH ADAPTER_LORA_DATA_LENGTH + 16 + +#define ADAPTER_LORA_DATA_HEAD 0x3C +#define ADAPTER_LORA_NET_PANID 0x0102 +#define ADAPTER_LORA_DATA_TYPE_JOIN 0x0A +#define ADAPTER_LORA_DATA_TYPE_QUIT 0x0B +#define ADAPTER_LORA_DATA_TYPE_JOIN_REPLY 0x0C +#define ADAPTER_LORA_DATA_TYPE_QUIT_REPLY 0x0D +#define ADAPTER_LORA_DATA_TYPE_USERDATA 0x0E +#define ADAPTER_LORA_DATA_END 0x5A +/*******************枚举_客户端状态********************/ +enum ClientState +{ + CLIENT_DISCONNECT = 0, + CLIENT_CONNECT, +}; + +/*******************全局变量********************/ +//报文定义 +struct LoraDataFormat +{ + uint16_t flame_head; + uint32_t length; + uint8_t src_id; + uint8_t tar_id; + uint16_t panid; + + uint16_t data_type; + uint8_t data[ADAPTER_LORA_DATA_LENGTH]; + uint16_t crc_data; + + uint16_t flame_end; +}; + +struct ClientParam +{ + uint8_t client_id; + uint16_t panid; + enum ClientState client_state; + + uint8_t gateway_id; +}; + +static sem_t recv_sem; +static pthread_t receive_task; +static pthread_t client_task; +uint8_t recv_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH]; +uint8_t send_buf[ADAPTER_LORA_DATA_LENGTH]; +struct LoraDataFormat recv_data_format; + +/*******************CRC16校验********************/ +static uint16_t Crc16Compute(uint8_t *data, uint16_t length) +{ + int j; + uint16_t crc_data = 0xFFFF; + + while (length--) { + crc_data ^= *data++; + for( j = 0 ; j < 8 ; j ++) { + if(crc_data & 0x01) + crc_data = crc_data >> 1 ^ 0xA001; + else + crc_data = crc_data >> 1; + } + } + + return crc_data; +} + +static int Crc16Check(uint8_t *data, uint16_t length, uint16_t crc_data){ + uint16_t re_crc_data = Crc16Compute(data, length); + if (crc_data == re_crc_data) + return 0; + else + return -1; +} + +/*******************Gateway进程********************/ +//更新连接状态 +static int LoraClientUpdate(struct Adapter *adapter, struct LoraDataFormat *client_recv_data) +{ + struct ClientParam *client = (struct ClientParam *)adapter->adapter_param; + + if (ADAPTER_LORA_DATA_TYPE_JOIN_REPLY == client_recv_data->data_type) { + client->gateway_id = client_recv_data->src_id; + //client->panid = client_recv_data->panid; + client->client_state = CLIENT_CONNECT; + printf("LoraClientUpdate client join panid 0x%x successfully\n", client->panid); + } else if (ADAPTER_LORA_DATA_TYPE_QUIT_REPLY == client_recv_data->data_type) { + client->gateway_id = 0; + //client->panid = 0; + client->client_state = CLIENT_DISCONNECT; + printf("LoraClientUpdate client quit panid 0x%x successfully\n", client->panid); + } + + return 0; +} + +//发送用户数据 +//客户端发送数据,数据类型为UserDate +static int ClientSendData(struct Adapter *adapter, void *send_buf, int length) +{ + struct ClientParam *client = (struct ClientParam *)adapter->adapter_param; + + if (client->client_state != CLIENT_CONNECT) { + printf("Lora client %d does not connect to Lora gateway\n", client->client_id); + return 0; + } + if (length > ADAPTER_LORA_DATA_LENGTH) { + printf("Lora client %d send data %d is larger than max %d \n", client->client_id, length, ADAPTER_LORA_DATA_LENGTH); + return 0; + } + uint16_t client_user_type; + uint32_t client_user_length = ADAPTER_LORA_TRANSFER_DATA_LENGTH; + uint8_t client_user_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH]; + uint16_t crc16=Crc16Compute((uint8_t *)send_buf, ADAPTER_LORA_DATA_LENGTH); + memset(client_user_data, 0, ADAPTER_LORA_TRANSFER_DATA_LENGTH); + client_user_type = ADAPTER_LORA_DATA_TYPE_USERDATA; + + client_user_data[0] = ADAPTER_LORA_DATA_HEAD; + client_user_data[1] = ADAPTER_LORA_DATA_HEAD; + client_user_data[2] = (client_user_length >> 24) & 0xFF; + client_user_data[3] = (client_user_length >> 16) & 0xFF; + client_user_data[4] = (client_user_length >> 8) & 0xFF; + client_user_data[5] = client_user_length & 0xFF; + client_user_data[6] = adapter->net_role_id & 0xFF; + client_user_data[7] = client->gateway_id; + client_user_data[8] = (client->panid>>8) & 0xFF; + client_user_data[9] = client->panid & 0xFF; + client_user_data[10] = ( client_user_type >> 8) & 0xFF; + client_user_data[11] = client_user_type & 0xFF; + memcpy((uint8_t *)(client_user_data + 12), (uint8_t *)send_buf, length); + client_user_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 4] = (crc16>>8)& 0xFF; + client_user_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 3] = crc16& 0xFF; + client_user_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 2] = ADAPTER_LORA_DATA_END; + client_user_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 1] = ADAPTER_LORA_DATA_END; + if (AdapterDeviceSend(adapter, client_user_data, ADAPTER_LORA_TRANSFER_DATA_LENGTH) < 0) { + printf("sending user data fails\n"); + return -1; + } + printf("sending user data is done\n"); + return 0; +} + +//连接或中止请求 +static int ClientJoinNet() +{ + printf("client join starts"); + struct AdapterData priv_lora_net; + struct Adapter *adapter= AdapterDeviceFindByName(ADAPTER_LORA_NAME); + struct ClientParam * client_param=(struct ClientParam * )adapter->adapter_param; + + uint16_t client_join_type; + uint32_t client_join_length = ADAPTER_LORA_TRANSFER_DATA_LENGTH; + uint8_t client_join_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH]; + memset(send_buf, 0, ADAPTER_LORA_DATA_LENGTH); + uint16_t crc16=Crc16Compute((uint8_t *)send_buf, ADAPTER_LORA_DATA_LENGTH); + memset(client_join_data, 0, ADAPTER_LORA_TRANSFER_DATA_LENGTH); + + client_join_type = ADAPTER_LORA_DATA_TYPE_JOIN; + + client_join_data[0] = ADAPTER_LORA_DATA_HEAD; + client_join_data[1] = ADAPTER_LORA_DATA_HEAD; + client_join_data[2] = (client_join_length >> 24) & 0xFF; + client_join_data[3] = (client_join_length >> 16) & 0xFF; + client_join_data[4] = (client_join_length >> 8) & 0xFF; + client_join_data[5] = client_join_length & 0xFF; + client_join_data[6] = adapter->net_role_id & 0xFF; + client_join_data[7] = 0; + client_join_data[8] = (client_param->panid>>8) & 0xFF; + client_join_data[9] = client_param->panid & 0xFF; + client_join_data[10] = ( client_join_type >> 8) & 0xFF; + client_join_data[11] = client_join_type & 0xFF; + + client_join_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 4] = (crc16>>8)& 0xFF; + client_join_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 3] = crc16& 0xFF; + client_join_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 2] = ADAPTER_LORA_DATA_END; + client_join_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 1] = ADAPTER_LORA_DATA_END; + + priv_lora_net.len = ADAPTER_LORA_TRANSFER_DATA_LENGTH; + priv_lora_net.buffer = client_join_data; + + if (AdapterDeviceJoin(adapter, (uint8_t *)&priv_lora_net) < 0) { + printf("sending join message fails\n"); + return -1; + } + + printf("%s:client_join_data panid 0x%x client_id 0x%x\n", __func__, client_param->panid, adapter->net_role_id); + printf("sending join message is done\n"); + return 0; +} + +//终端与目标网关的连接 +static int ClientQuitNet() +{ + printf("client quit starts"); + struct AdapterData priv_lora_net; + struct Adapter *adapter= AdapterDeviceFindByName(ADAPTER_LORA_NAME); + struct ClientParam * client_param=(struct ClientParam * )adapter->adapter_param; + + uint16_t client_quit_type; + uint32_t client_quit_length = ADAPTER_LORA_TRANSFER_DATA_LENGTH; + uint8_t client_quit_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH]; + memset(send_buf, 0, ADAPTER_LORA_DATA_LENGTH); + uint16_t crc16=Crc16Compute((uint8_t *)send_buf, ADAPTER_LORA_DATA_LENGTH); + + memset(client_quit_data, 0, ADAPTER_LORA_TRANSFER_DATA_LENGTH); + + client_quit_type = ADAPTER_LORA_DATA_TYPE_QUIT; + + client_quit_data[0] = ADAPTER_LORA_DATA_HEAD; + client_quit_data[1] = ADAPTER_LORA_DATA_HEAD; + client_quit_data[2] = (client_quit_length >> 24) & 0xFF; + client_quit_data[3] = (client_quit_length >> 16) & 0xFF; + client_quit_data[4] = (client_quit_length >> 8) & 0xFF; + client_quit_data[5] = client_quit_length & 0xFF; + client_quit_data[6] = adapter->net_role_id & 0xFF; + client_quit_data[7] = client_param->gateway_id; + client_quit_data[8] = (client_param->panid>>8) & 0xFF; + client_quit_data[9] = client_param->panid & 0xFF; + client_quit_data[10] = ( client_quit_type >> 8) & 0xFF; + client_quit_data[11] = client_quit_type & 0xFF; + + client_quit_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 4] = (crc16>>8)& 0xFF; + client_quit_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 3] = crc16& 0xFF; + client_quit_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 2] = ADAPTER_LORA_DATA_END; + client_quit_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 1] = ADAPTER_LORA_DATA_END; + + priv_lora_net.len = ADAPTER_LORA_TRANSFER_DATA_LENGTH; + priv_lora_net.buffer = client_quit_data; + + if (AdapterDeviceDisconnect(adapter, (uint8_t *)&priv_lora_net) < 0) { + printf("sending quit message is fails"); + return -1; + } + + printf("%s:client_quit_data panid 0x%x client_id 0x%x\n", __func__, client_param->panid, adapter->net_role_id); + printf("sending quit message is done\n"); + return 0; +} +//打印格式化数据 +static int PrintFormattedData(struct LoraDataFormat formatData){ + printf("HEAD: 0x%x\n",formatData.flame_head); + printf("LENGTH: 0x%x\n",formatData.length); + printf("SRC_ID: 0x%x\n", formatData.src_id); + printf("TAR_ID: 0x%x\n", formatData.tar_id); + printf("PANID: 0x%x", formatData.panid); + printf("DATA_TYPE: 0x%x\n", formatData.data_type); + printf("CRC_DATA: 0x%x\n", formatData.crc_data); + printf("END: 0x%x\n", formatData.flame_end); +} + +//接收数据分析 +static int AnalyzeClientReceiveData(struct Adapter *adapter) +{ + printf("analyze the receivedata\n"); + int ret = 0; + + if (ADAPTER_LORA_NET_PANID == recv_data_format.panid&&adapter->net_role_id==recv_data_format.tar_id) { + + // printf("%s: gateway_recv_data\n", __func__); + + PrintFormattedData(recv_data_format); + + switch (recv_data_format.data_type) + { + //如果从gateway接收的是连接或中止回复 + case ADAPTER_LORA_DATA_TYPE_JOIN_REPLY : + case ADAPTER_LORA_DATA_TYPE_QUIT_REPLY : + printf("The data type is JOIN or REPLY"); + ret = LoraClientUpdate(adapter, &recv_data_format); + break; + default: + break; + } + + //清空 + memset(&recv_data_format, 0 , sizeof(struct LoraDataFormat)); + } else { + printf("target client does not match\n"); + ret = -1; + } + printf("analysis is done\n"); + return ret; +} +//接收数据格式化 +static int FormatReceiveData(struct Adapter *adapter, uint8_t *recv_data, uint16_t length) +{ + printf("Format receive data starts\n"); + if ((ADAPTER_LORA_DATA_HEAD == recv_data[0]) && (ADAPTER_LORA_DATA_HEAD == recv_data[1]) && + (ADAPTER_LORA_DATA_END == recv_data[length - 1]) && (ADAPTER_LORA_DATA_END == recv_data[length - 2])){ + + recv_data_format.flame_head = ((recv_data[0] << 8) & 0xFF00) | recv_data[1]; + recv_data_format.length = ((recv_data[2] << 24) & 0xFF000000) | ((recv_data[3] << 16) & 0xFF0000) | + ((recv_data[4] << 8) & 0xFF00) | (recv_data[5] & 0xFF); + recv_data_format.src_id = recv_data[6]; + recv_data_format.tar_id = recv_data[7]; + recv_data_format.panid = ((recv_data[8] << 8) & 0xFF00) | recv_data[9]; + recv_data_format.data_type = ((recv_data[10] << 8) & 0xFF00) | recv_data[11]; + + recv_data_format.crc_data=((recv_data[length - 4] << 8) & 0xFF00) | recv_data[length - 3]; + recv_data_format.flame_end = ((recv_data[length - 2] << 8) & 0xFF00) | recv_data[length - 1]; + + memcpy(recv_data_format.data, (uint8_t *)(recv_data + 12), ADAPTER_LORA_DATA_LENGTH); + + if(Crc16Check(recv_data_format.data, ADAPTER_LORA_DATA_LENGTH, recv_data_format.crc_data)<0){ + printf("crc16check is fail\n"); + return -1; + } + else return 0; + } + printf("the head or end of the data is wrong\n"); + return -1; +} + +static void *ClientReceiveTask(void *parameter){ + printf("client receive task starts\n"); + int ret = 0; + struct Adapter *lora_adapter = (struct Adapter *)parameter; + + while (1) { + memset(recv_data, 0, ADAPTER_LORA_TRANSFER_DATA_LENGTH); + + ret = AdapterDeviceRecv(lora_adapter, recv_data, ADAPTER_LORA_TRANSFER_DATA_LENGTH); + if (ret <= 0) { + // printf("AdapterDeviceRecv error.Just return\n"); + continue; + } + printf("AdapterDeviceRecv success\n"); + + if(FormatReceiveData(lora_adapter, recv_data, ADAPTER_LORA_TRANSFER_DATA_LENGTH)<0){ + continue; + } + if(AnalyzeClientReceiveData(lora_adapter)){ + continue; + } + } + + return 0; +} + +static void *ClientDataTask(void *parameter) +{ + printf("client data task starts\n"); + //printf("checkpoint10\n"); + //PrivTaskDelay(10000); + + //获取clientparam参数引用 + int i, ret = 0; + struct Adapter *lora_adapter = (struct Adapter *)parameter; + struct ClientParam *client = (struct ClientParam *)lora_adapter->adapter_param; + + //设置发送缓存 + memset(send_buf, 0, ADAPTER_LORA_DATA_LENGTH); + sprintf(send_buf, "Lora client %d adapter test\n", client->client_id); + //printf("checkpoint11\n"); + // PrivTaskDelay(10000); + while (1) { + if (send_buf) { + PrivTaskDelay(2000); + // printf("client is sending test data\n"); + ClientSendData(lora_adapter, (void *)send_buf, strlen(send_buf)); + // printf("sending data is done"); + } + } + + return 0; +} + +static int SendMessageTask(int arg, char* args[]) +{ + printf("client data task starts\n"); + int i, ret = 0; + struct Adapter *lora_adapter= AdapterDeviceFindByName(ADAPTER_LORA_NAME); + struct ClientParam *client = (struct ClientParam *)lora_adapter->adapter_param; + + //设置发送缓存 + memset(send_buf, 0, ADAPTER_LORA_DATA_LENGTH); + sprintf(send_buf, args[1]); + //printf("checkpoint11\n"); + // PrivTaskDelay(10000); + if (send_buf) { + printf("client is sending test data\n"); + ClientSendData(lora_adapter, (void *)send_buf, strlen(send_buf)); + printf("sending data is done"); + } + + return 0; +} + + +int ClientLoraLaunch(void){ + + printf("client is launching\n"); + //获取适配器 + struct Adapter *adapter= AdapterDeviceFindByName(ADAPTER_LORA_NAME); + AdapterDeviceOpen(adapter); + //printf("checkpoint1\n"); + //PrivTaskDelay(10000); + + //配置 +#ifdef ADD_NUTTX_FEATURES + pthread_attr_t lora_client_attr = PTHREAD_ATTR_INITIALIZER; + lora_client_attr.priority = 20; + lora_client_attr.stacksize = 2048; +#else + pthread_attr_t lora_client_attr; + lora_client_attr.schedparam.sched_priority = 20; + lora_client_attr.stacksize = 2048; +#endif + + //启动客户端接收Task:LoraClientDataTask + PrivTaskCreate(&receive_task, &lora_client_attr, &ClientReceiveTask, (void *)adapter); + PrivTaskStartup(&receive_task); + +//#ifdef ADD_NUTTX_FEATURES +// lora_client_attr.priority = 19; +//#else +// lora_client_attr.schedparam.sched_priority = 19; +//#endif +// //printf("checkpoint2\n"); +// //PrivTaskDelay(10000); +// //printf("checkpoint3"); +// //启动客户端Task:LoraClientDataTask +// //create lora client task +// PrivTaskCreate(&client_task, &lora_client_attr, &ClientDataTask, (void *)adapter); +// PrivTaskStartup(&client_task); +// //printf("checkpoint4"); +// //PrivTaskDelay(10000); + return 0; + +} +/*******************设备的初始化和注册********************/ +////注册 +static int ClientAdapterRegister(struct Adapter *adapter){ + int ret = 0; + struct ClientParam *lora_client; + + strncpy(adapter->name, ADAPTER_LORA_NAME, NAME_NUM_MAX); + + adapter->net_protocol = PRIVATE_PROTOCOL; + + + lora_client = PrivMalloc(sizeof(struct ClientParam)); + if (!lora_client) { + printf("creating clientparems is failed\n"); + PrivFree(lora_client); + return -1; + } + + memset(lora_client, 0, sizeof(struct ClientParam)); + + lora_client->client_id = ADAPTER_LORA_NET_ROLE_ID; + lora_client->client_state = CLIENT_DISCONNECT; + lora_client->panid = ADAPTER_LORA_NET_PANID; + lora_client->gateway_id = 0; + printf("creating clientparams is successful\n"); + + memset(&recv_data_format, 0, sizeof(struct LoraDataFormat)); + printf("memestting clientparams is successful\n"); + + adapter->net_role = CLIENT; + adapter->adapter_param = (void *)lora_client; + + adapter->net_role_id = ADAPTER_LORA_NET_ROLE_ID; + + adapter->adapter_status = UNREGISTERED; + + ret = AdapterDeviceRegister(adapter); + printf("setting up the adpater is successful\n"); + if (ret < 0) { + printf("Adapter4G register error\n"); + if (lora_client) + PrivFree(lora_client); + return -1; + } + return ret; +} +//初始化 +int AdapterLoraInit(void){ + printf("init adapter starts\n"); + int ret=0; + struct Adapter *adapter= PrivMalloc(sizeof(struct Adapter)); + if (!adapter) { + PrivFree(adapter); + return -1; + } + memset(adapter, 0, sizeof(struct Adapter)); + //注册adapter + ret=ClientAdapterRegister(adapter); + //根据产品型号进行配置 +#ifdef ADAPTER_SX1278 + AdapterProductInfoType product_info = Sx1278Attach(adapter); + if (!product_info) { + printf("AdapterLoraInit sx1278 attach error\n"); + PrivFree(adapter); + return -1; + } + + adapter->product_info_flag = 1; + adapter->info = product_info; + adapter->done = product_info->model_done; + +#endif + +#ifdef ADAPTER_E220 + AdapterProductInfoType product_info = E220Attach(adapter); + if (!product_info) { + printf("AdapterLoraInit e220 attach error\n"); + PrivFree(adapter); + return -1; + } + + adapter->product_info_flag = 1; + adapter->info = product_info; + adapter->done = product_info->model_done; +#endif + +#ifdef ADAPTER_E22 + AdapterProductInfoType product_info = E22Attach(adapter); + if (!product_info) { + printf("AdapterLoraInit e22 attach error\n"); + PrivFree(adapter); + return -1; + } + + adapter->product_info_flag = 1; + adapter->info = product_info; + adapter->done = product_info->model_done; +#endif + PrivSemaphoreCreate(&adapter->sem, 0 ,0); + PrivSemaphoreCreate(&recv_sem, 0, 0); + PrivMutexCreate(&adapter->lock, 0); + printf("init adapter is completed\n"); + return ret; +} +PRIV_SHELL_CMD_FUNCTION(ClientLoraLaunch, a lora test sample, PRIV_SHELL_CMD_MAIN_ATTR); +PRIV_SHELL_CMD_FUNCTION(ClientJoinNet, a lora test sample, PRIV_SHELL_CMD_MAIN_ATTR); +PRIV_SHELL_CMD_FUNCTION(ClientQuitNet, a lora test sample, PRIV_SHELL_CMD_MAIN_ATTR); +PRIV_SHELL_CMD_FUNCTION(SendMessageTask, a lora test sample, PRIV_SHELL_CMD_MAIN_ATTR); + diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/gateway_adpater.c b/APP_Framework/Applications/app_test/test_lora_p2p/gateway_adpater.c new file mode 100644 index 000000000..c5affd233 --- /dev/null +++ b/APP_Framework/Applications/app_test/test_lora_p2p/gateway_adpater.c @@ -0,0 +1,434 @@ +// +// Created by 18363 on 2023/9/17. +// + +#include + +#ifdef ADAPTER_SX1278 +extern AdapterProductInfoType Sx1278Attach(struct Adapter *adapter); +#endif + +#ifdef ADAPTER_E220 +extern AdapterProductInfoType E220Attach(struct Adapter *adapter); +#endif + +#ifdef ADAPTER_E22 +extern AdapterProductInfoType E22Attach(struct Adapter *adapter); +#endif + +/*******************报文宏********************/ +#define ADAPTER_LORA_DATA_LENGTH 112 +#define ADAPTER_LORA_TRANSFER_DATA_LENGTH ADAPTER_LORA_DATA_LENGTH + 16 + +#define ADAPTER_LORA_DATA_HEAD 0x3C +#define ADAPTER_LORA_NET_PANID 0x0102 +#define ADAPTER_LORA_DATA_TYPE_JOIN 0x0A +#define ADAPTER_LORA_DATA_TYPE_QUIT 0x0B +#define ADAPTER_LORA_DATA_TYPE_JOIN_REPLY 0x0C +#define ADAPTER_LORA_DATA_TYPE_QUIT_REPLY 0x0D +#define ADAPTER_LORA_DATA_TYPE_USERDATA 0x0E +#define ADAPTER_LORA_DATA_END 0x5A + +/*******************枚举_客户端状态********************/ +enum ClientState +{ + CLIENT_DISCONNECT = 0, + CLIENT_CONNECT, +}; + +/*******************全局变量********************/ +//报文定义 +struct LoraDataFormat +{ + uint16_t flame_head; + uint32_t length; + uint8_t src_id; + uint8_t tar_id; + uint16_t panid; + + uint16_t data_type; + uint8_t data[ADAPTER_LORA_DATA_LENGTH]; + uint16_t crc_data; + + uint16_t flame_end; +}; + +struct GatewayParam{ + uint8_t gateway_id; + uint16_t panid; + uint8_t client_id[ADAPTER_LORA_CLIENT_NUM]; + int client_num; +}; + + + +static sem_t recv_sem; +static pthread_t receive_task; +static pthread_t gateway_task; +uint8_t gateway_reply_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH]; +uint8_t send_buff[ADAPTER_LORA_DATA_LENGTH]; +uint8_t recv_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH]; +struct LoraDataFormat recv_data_format; + + +/*******************CRC16校验********************/ +static uint16_t Crc16Compute(uint8_t *data, uint16_t length) +{ + int j; + uint16_t crc_data = 0xFFFF; + + while (length--) { + crc_data ^= *data++; + for( j = 0 ; j < 8 ; j ++) { + if(crc_data & 0x01) + crc_data = crc_data >> 1 ^ 0xA001; + else + crc_data = crc_data >> 1; + } + } + + return crc_data; +} + +static int Crc16Check(uint8_t *data, uint16_t length, uint16_t crc_data){ + uint16_t re_crc_data = Crc16Compute(data, length); + if (crc_data == re_crc_data) + return 0; + else + return -1; +} + +/*******************Gateway进程********************/ +//接收用户数据 +static int GatewayHandleData(struct Adapter *adapter, struct LoraDataFormat *recv_data){ + + /*User needs to handle client data depends on the requirement*/ + printf("Lora Gateway receive Client %d data:\n", recv_data->src_id); + printf("%s\n", recv_data->data); + printf("handling data is done\n"); + return 0; +} +//回复中止或连接请求 +static int GatewayReplyJoin(struct Adapter *adapter, struct LoraDataFormat *recv_data) +{ + printf("reply join\n"); + int i; + int client_join_flag = 0; + uint16_t gateway_data_type; + struct GatewayParam *gateway = (struct GatewayParam *)adapter->adapter_param; + uint32_t gateway_reply_length = ADAPTER_LORA_TRANSFER_DATA_LENGTH; + memset(send_buff, 0, ADAPTER_LORA_DATA_LENGTH); + uint16_t crc16=Crc16Compute((uint8_t *)send_buff, ADAPTER_LORA_DATA_LENGTH); + + memset(gateway_reply_data, 0, ADAPTER_LORA_TRANSFER_DATA_LENGTH); + + for (i = 0; i < gateway->client_num; i ++) { + if (recv_data->src_id == gateway->client_id[i]) { + printf("Lora client_%d 0x%x has already join net 0x%x\n", i, recv_data->src_id, gateway->gateway_id); + client_join_flag = 1; + break; + } + } + if (!client_join_flag) { + if (gateway->client_num > ADAPTER_LORA_CLIENT_NUM) { + printf("Lora gateway only support %u(max) client\n", ADAPTER_LORA_CLIENT_NUM); + gateway->client_num = 0; + } + gateway->client_id[gateway->client_num] = recv_data->src_id; + gateway->client_num++; + } + + + gateway_data_type = ADAPTER_LORA_DATA_TYPE_JOIN_REPLY; + + gateway_reply_data[0] = ADAPTER_LORA_DATA_HEAD; + gateway_reply_data[1] = ADAPTER_LORA_DATA_HEAD; + gateway_reply_data[2] = (gateway_reply_length >> 24) & 0xFF; + gateway_reply_data[3] = (gateway_reply_length >> 16) & 0xFF; + gateway_reply_data[4] = (gateway_reply_length >> 8) & 0xFF; + gateway_reply_data[5] = gateway_reply_length & 0xFF; + gateway_reply_data[6] = recv_data->tar_id; + gateway_reply_data[7] = recv_data->src_id; + gateway_reply_data[8] = (gateway->panid>>8) & 0xFF; + gateway_reply_data[9] = gateway->panid & 0xFF; + gateway_reply_data[10] = (gateway_data_type >> 8) & 0xFF; + gateway_reply_data[11] = gateway_data_type & 0xFF; + + gateway_reply_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 4] = (crc16>>8)& 0xFF; + gateway_reply_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 3] = crc16& 0xFF; + gateway_reply_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 2] = ADAPTER_LORA_DATA_END; + gateway_reply_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 1] = ADAPTER_LORA_DATA_END; + + if (AdapterDeviceSend(adapter, gateway_reply_data, ADAPTER_LORA_TRANSFER_DATA_LENGTH) < 0) { + return -1; + } + printf("Lora gateway 0x%x accept client 0x%x \n", gateway->gateway_id, recv_data->src_id); + printf("replying join is done"); + return 0; +} + +static int GatewayReplyQuit(struct Adapter *adapter, struct LoraDataFormat *recv_data){ + printf("reply quit\n"); + int i; + uint16_t gateway_data_type; + struct GatewayParam *gateway = (struct GatewayParam *)adapter->adapter_param; + uint32_t gateway_reply_length = ADAPTER_LORA_TRANSFER_DATA_LENGTH; + memset(send_buff, 0, ADAPTER_LORA_DATA_LENGTH); + uint16_t crc16=Crc16Compute((uint8_t *)send_buff, ADAPTER_LORA_DATA_LENGTH); + + memset(gateway_reply_data, 0, ADAPTER_LORA_TRANSFER_DATA_LENGTH); + + for (i = 0; i < gateway->client_num; i ++) { + if (gateway->client_id[i] == recv_data->src_id) { + for(int j=i+1;jclient_num;++j){ + gateway->client_id[j-1] = gateway->client_id[j]; + } + gateway->client_num --; + break; + } + } + + gateway_data_type = ADAPTER_LORA_DATA_TYPE_QUIT_REPLY; + + gateway_reply_data[0] = ADAPTER_LORA_DATA_HEAD; + gateway_reply_data[1] = ADAPTER_LORA_DATA_HEAD; + gateway_reply_data[2] = (gateway_reply_length >> 24) & 0xFF; + gateway_reply_data[3] = (gateway_reply_length >> 16) & 0xFF; + gateway_reply_data[4] = (gateway_reply_length >> 8) & 0xFF; + gateway_reply_data[5] = gateway_reply_length & 0xFF; + gateway_reply_data[6] = recv_data->tar_id; + gateway_reply_data[7] = recv_data->src_id; + gateway_reply_data[8] = (gateway->panid>>8) & 0xFF; + gateway_reply_data[9] = gateway->panid & 0xFF; + gateway_reply_data[10] = (gateway_data_type >> 8) & 0xFF; + gateway_reply_data[11] = gateway_data_type & 0xFF; + + gateway_reply_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 4] = (crc16>>8)& 0xFF; + gateway_reply_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 3] = crc16& 0xFF; + gateway_reply_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 2] = ADAPTER_LORA_DATA_END; + gateway_reply_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 1] = ADAPTER_LORA_DATA_END; + if (AdapterDeviceSend(adapter, gateway_reply_data, ADAPTER_LORA_TRANSFER_DATA_LENGTH) < 0) { + return -1; + } + printf("Lora gateway 0x%x accept client 0x%x \n", gateway->gateway_id, recv_data->src_id); + printf("replying quit is done"); + return 0; +} +// +//打印格式化数据 +static int PrintFormattedData(struct LoraDataFormat formatData){ + printf("HEAD: 0x%x\n",formatData.flame_head); + printf("LENGTH: 0x%x\n",formatData.length); + printf("SRC_ID: 0x%x\n", formatData.src_id); + printf("TAR_ID: 0x%x\n", formatData.tar_id); + printf("PANID: 0x%x", formatData.panid); + printf("DATA_TYPE: 0x%x\n", formatData.data_type); + printf("CRC_DATA: 0x%x\n", formatData.crc_data); + printf("END: 0x%x\n", formatData.flame_end); +} + +//接收数据分析 +static int AnalyzeGateWayReceiveData(struct Adapter *adapter) +{ + int ret = 0; + + if (ADAPTER_LORA_NET_PANID == recv_data_format.panid) { + + //printf("%s: gateway_recv_data\n", __func__); + PrintFormattedData(recv_data_format); + + switch (recv_data_format.data_type) + { + //如果是连接或中止请求 + case ADAPTER_LORA_DATA_TYPE_JOIN : + ret = GatewayReplyJoin(adapter, &recv_data_format); + break; + case ADAPTER_LORA_DATA_TYPE_QUIT : + ret = GatewayReplyQuit(adapter, &recv_data_format); + break; + //如果是用户数据 + case ADAPTER_LORA_DATA_TYPE_USERDATA : + ret = GatewayHandleData(adapter, &recv_data_format); + break; + default: + break; + } + } else { + ret = -1; + } + + return ret; +} + + + +//接收数据格式化 +static int FormatReceiveData(struct Adapter *adapter, uint8_t *recv_data, uint16_t length) +{ + if ((ADAPTER_LORA_DATA_HEAD == recv_data[0]) && (ADAPTER_LORA_DATA_HEAD == recv_data[1]) && + (ADAPTER_LORA_DATA_END == recv_data[length - 1]) && (ADAPTER_LORA_DATA_END == recv_data[length - 2])){ + + recv_data_format.flame_head = ((recv_data[0] << 8) & 0xFF00) | recv_data[1]; + recv_data_format.length = ((recv_data[2] << 24) & 0xFF000000) | ((recv_data[3] << 16) & 0xFF0000) | + ((recv_data[4] << 8) & 0xFF00) | (recv_data[5] & 0xFF); + recv_data_format.src_id = recv_data[6]; + recv_data_format.tar_id = recv_data[7]; + recv_data_format.panid = ((recv_data[8] << 8) & 0xFF00) | recv_data[9]; + recv_data_format.data_type = ((recv_data[10] << 8) & 0xFF00) | recv_data[11]; + + recv_data_format.crc_data=((recv_data[length - 4] << 8) & 0xFF00) | recv_data[length - 3]; + recv_data_format.flame_end = ((recv_data[length - 2] << 8) & 0xFF00) | recv_data[length - 1]; + + memcpy(recv_data_format.data, (uint8_t *)(recv_data + 12), ADAPTER_LORA_DATA_LENGTH); + + if(Crc16Check(recv_data_format.data, ADAPTER_LORA_DATA_LENGTH, recv_data_format.crc_data)<0){ + printf("crc16check is fail\n"); + return -1; + } + else return 0; + } + return -1; +} + +static void *GatewayReceiveTask(void *parameter){ + int ret = 0; + struct Adapter *lora_adapter = (struct Adapter *)parameter; + + while (1) { + memset(recv_data, 0, ADAPTER_LORA_TRANSFER_DATA_LENGTH); + + ret = AdapterDeviceRecv(lora_adapter, recv_data, ADAPTER_LORA_TRANSFER_DATA_LENGTH); + if (ret <= 0) { + printf("AdapterDeviceRecv error.Just return\n"); + continue; + } + printf("AdapterDeviceRecv success\n"); + if(FormatReceiveData(lora_adapter, recv_data, ADAPTER_LORA_TRANSFER_DATA_LENGTH)<0){ + continue; + } + if(AnalyzeGateWayReceiveData(lora_adapter)){ + continue; + } + } + + return 0; +} + +int GatewayLoraLaunch(void){ + + //获取适配器 + struct Adapter *adapter= AdapterDeviceFindByName(ADAPTER_LORA_NAME); + AdapterDeviceOpen(adapter); + //配置 +#ifdef ADD_NUTTX_FEATURES + pthread_attr_t lora_gateway_attr = PTHREAD_ATTR_INITIALIZER; + lora_gateway_attr.priority = 20; + lora_gateway_attr.stacksize = 2048; +#else + pthread_attr_t lora_gateway_attr; + lora_gateway_attr.schedparam.sched_priority = 20; + lora_gateway_attr.stacksize = 2048; +#endif + //启动网关接收Task:LoraReceiveTask,第四个为传入参数 + PrivTaskCreate(&receive_task, &lora_gateway_attr, &GatewayReceiveTask, (void *)adapter); + PrivTaskStartup(&receive_task); + +} +/*******************设备的初始化和注册********************/ +//注册 +int GatewayAdapterRegister(struct Adapter *adapter){ + int ret = 0; + struct GatewayParam *lora_gateway; + + strncpy(adapter->name, ADAPTER_LORA_NAME, NAME_NUM_MAX); + + adapter->net_protocol = PRIVATE_PROTOCOL; + + + lora_gateway = PrivMalloc(sizeof(struct GatewayParam)); + if (!lora_gateway) { + PrivFree(lora_gateway); + return -1; + } + + memset(lora_gateway, 0, sizeof(struct GatewayParam)); + + lora_gateway->gateway_id = ADAPTER_LORA_NET_ROLE_ID; + lora_gateway->panid = ADAPTER_LORA_NET_PANID; + lora_gateway->client_num=0; + + memset(&recv_data_format, 0, sizeof(struct LoraDataFormat)); + + adapter->net_role = GATEWAY; + adapter->adapter_param = (void *)lora_gateway; + + adapter->net_role_id = ADAPTER_LORA_NET_ROLE_ID; + + adapter->adapter_status = UNREGISTERED; + + ret = AdapterDeviceRegister(adapter); + if (ret < 0) { + printf("Adapter4G register error\n"); + if (lora_gateway) + PrivFree(lora_gateway); + return -1; + } + + return ret; +} +//初始化 +int AdapterLoraInit(void){ + printf("init adapter starts\n"); + int ret=0; + struct Adapter *adapter= PrivMalloc(sizeof(struct Adapter)); + memset(adapter, 0, sizeof(struct Adapter)); + //注册adapter + ret=GatewayAdapterRegister(adapter); + //根据产品型号进行配置 +#ifdef ADAPTER_SX1278 + AdapterProductInfoType product_info = Sx1278Attach(adapter); + if (!product_info) { + printf("AdapterLoraInit sx1278 attach error\n"); + PrivFree(adapter); + return -1; + } + + adapter->product_info_flag = 1; + adapter->info = product_info; + adapter->done = product_info->model_done; + +#endif + +#ifdef ADAPTER_E220 + AdapterProductInfoType product_info = E220Attach(adapter); + if (!product_info) { + printf("AdapterLoraInit e220 attach error\n"); + PrivFree(adapter); + return -1; + } + + adapter->product_info_flag = 1; + adapter->info = product_info; + adapter->done = product_info->model_done; +#endif + +#ifdef ADAPTER_E22 + AdapterProductInfoType product_info = E22Attach(adapter); + if (!product_info) { + printf("AdapterLoraInit e22 attach error\n"); + PrivFree(adapter); + return -1; + } + + adapter->product_info_flag = 1; + adapter->info = product_info; + adapter->done = product_info->model_done; +#endif + PrivSemaphoreCreate(&adapter->sem, 0 ,0); + PrivSemaphoreCreate(&recv_sem, 0, 0); + PrivMutexCreate(&adapter->lock, 0); + printf("init adapter is completed\n"); + return ret; +} + +PRIV_SHELL_CMD_FUNCTION(GatewayLoraLaunch, a lora test sample, PRIV_SHELL_CMD_MAIN_ATTR); \ No newline at end of file diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/readme.md b/APP_Framework/Applications/app_test/test_lora_p2p/readme.md new file mode 100644 index 000000000..452bf86bd --- /dev/null +++ b/APP_Framework/Applications/app_test/test_lora_p2p/readme.md @@ -0,0 +1,21 @@ +通信报文定义: +struct LoraDataFormat +{ + uint16_t flame_head;//报文头0x3C3C + uint32_t length;//报文长度 + uint8_t src_id;//源地址 + uint8_t tar_id;//目的地址 + uint16_t panid;//域id 0x0102 + uint16_t data_type;//数据类型join、quit、userdata、join_reply、quit_reply + uint8_t data[ADAPTER_LORA_DATA_LENGTH];//裸数据 + uint16_t crc_data; + +​ uint16_t flame_end;0x5A5A + +}; +通信类型: +JOIN 0x0A +QUIT 0x0B +JOIN_REPLY 0x0C +QUIT_REPLY 0x0D +USERDATA 0x0E diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/0client启动.png b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/0client启动.png new file mode 100644 index 000000000..4cee795c0 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/0client启动.png differ diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/10client在断开连接下发送数据.png b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/10client在断开连接下发送数据.png new file mode 100644 index 000000000..60606a03b Binary files /dev/null and b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/10client在断开连接下发送数据.png differ diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/114514client多次发送数据.png b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/114514client多次发送数据.png new file mode 100644 index 000000000..dadf4b1ba Binary files /dev/null and b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/114514client多次发送数据.png differ diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/1919810Gateway多次接受数据.png b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/1919810Gateway多次接受数据.png new file mode 100644 index 000000000..255aae3ca Binary files /dev/null and b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/1919810Gateway多次接受数据.png differ diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/1启动网关.png b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/1启动网关.png new file mode 100644 index 000000000..2f5fa5a35 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/1启动网关.png differ diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/2client发送连接请求.png b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/2client发送连接请求.png new file mode 100644 index 000000000..e0df27cbb Binary files /dev/null and b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/2client发送连接请求.png differ diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/3gateway接受并回复join请求.png b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/3gateway接受并回复join请求.png new file mode 100644 index 000000000..f0ff7d317 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/3gateway接受并回复join请求.png differ diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/4client接受gateway-reply,成功连接.png b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/4client接受gateway-reply,成功连接.png new file mode 100644 index 000000000..ed21ef53b Binary files /dev/null and b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/4client接受gateway-reply,成功连接.png differ diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/5client发送数据.png b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/5client发送数据.png new file mode 100644 index 000000000..88dd2f486 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/5client发送数据.png differ diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/6gateway接受数据.png b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/6gateway接受数据.png new file mode 100644 index 000000000..5ce8577b7 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/6gateway接受数据.png differ diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/7client发送quit请求.png b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/7client发送quit请求.png new file mode 100644 index 000000000..f69c26d6e Binary files /dev/null and b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/7client发送quit请求.png differ diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/8gateway接受并回复quit请求.png b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/8gateway接受并回复quit请求.png new file mode 100644 index 000000000..661ae00f6 Binary files /dev/null and b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/8gateway接受并回复quit请求.png differ diff --git a/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/9client接收gateway-reply并终止连接.png b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/9client接收gateway-reply并终止连接.png new file mode 100644 index 000000000..d1f3de45a Binary files /dev/null and b/APP_Framework/Applications/app_test/test_lora_p2p/连接、断开、发送数据、打开连接下发送数据/9client接收gateway-reply并终止连接.png differ