初赛二级赛题目,Lora网关

This commit is contained in:
windyyuan 2023-10-06 00:00:01 +08:00
parent c6b88ef9a7
commit 0573d641c6
16 changed files with 1016 additions and 0 deletions

View File

@ -0,0 +1,561 @@
//
// Created by 18363 on 2023/9/17.
//
#include<adapter.h>
#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
//启动客户端接收TaskLoraClientDataTask
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");
// //启动客户端TaskLoraClientDataTask
// //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);

View File

@ -0,0 +1,434 @@
//
// Created by 18363 on 2023/9/17.
//
#include<adapter.h>
#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 <join request>\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;j<gateway->client_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 <quit request>\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
//启动网关接收TaskLoraReceiveTask第四个为传入参数
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);

View File

@ -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