|
|
@ -28,9 +28,15 @@ extern AdapterProductInfoType Sx1278Attach(struct Adapter *adapter); |
|
|
|
extern AdapterProductInfoType E220Attach(struct Adapter *adapter); |
|
|
|
#endif |
|
|
|
|
|
|
|
#define ADAPTER_LORA_CLIENT_NUM 255 |
|
|
|
#define ADAPTER_LORA_DATA_LENGTH 256 |
|
|
|
#define ADAPTER_LORA_RECV_DATA_LENGTH ADAPTER_LORA_DATA_LENGTH + 16 |
|
|
|
//#define CLIENT_UPDATE_MODE
|
|
|
|
#define GATEWAY_CMD_MODE |
|
|
|
|
|
|
|
//Client num index 1-ADAPTER_LORA_CLIENT_NUM
|
|
|
|
//#define ADAPTER_LORA_CLIENT_NUM 20
|
|
|
|
|
|
|
|
//LORA single transfer data max size 128 bytes: data format 16 bytes and user data 112 bytes
|
|
|
|
#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 |
|
|
@ -40,6 +46,9 @@ extern AdapterProductInfoType E220Attach(struct Adapter *adapter); |
|
|
|
#define ADAPTER_LORA_DATA_TYPE_QUIT_REPLY 0x0D |
|
|
|
#define ADAPTER_LORA_DATA_TYPE_USERDATA 0x0E |
|
|
|
#define ADAPTER_LORA_DATA_TYPE_CMD 0x0F |
|
|
|
#define ADAPTER_LORA_DATA_END 0x5A |
|
|
|
|
|
|
|
#define ADAPTER_LORA_RECEIVE_ERROR_CNT 1 |
|
|
|
|
|
|
|
//need to change status if the lora client wants to quit the net when timeout or a certain event
|
|
|
|
//eg.can also use sem to trigger quit function
|
|
|
@ -66,28 +75,26 @@ enum LoraGatewayState { |
|
|
|
LORA_RECV_DATA, |
|
|
|
}; |
|
|
|
|
|
|
|
static uint8 LoraGatewayState = LORA_STATE_IDLE; |
|
|
|
|
|
|
|
struct LoraGatewayParam |
|
|
|
{ |
|
|
|
uint8 gateway_id; |
|
|
|
uint16 panid; |
|
|
|
uint8 client_id[ADAPTER_LORA_CLIENT_NUM]; |
|
|
|
uint8_t gateway_id; |
|
|
|
uint16_t panid; |
|
|
|
uint8_t client_id[ADAPTER_LORA_CLIENT_NUM]; |
|
|
|
int client_num; |
|
|
|
int receive_data_sem; |
|
|
|
}; |
|
|
|
|
|
|
|
struct LoraClientParam |
|
|
|
{ |
|
|
|
uint8 client_id; |
|
|
|
uint16 panid; |
|
|
|
uint8_t client_id; |
|
|
|
uint16_t panid; |
|
|
|
enum ClientState client_state; |
|
|
|
|
|
|
|
uint8 gateway_id; |
|
|
|
uint8_t gateway_id; |
|
|
|
}; |
|
|
|
|
|
|
|
/*LoraDataFormat:
|
|
|
|
**flame_head : 0x3C |
|
|
|
**flame_head : 0x3C3C |
|
|
|
**length : sizeof(struct LoraDataFormat) |
|
|
|
**panid : 0x0102 |
|
|
|
**client_id : 0x01、0x02、0x03... |
|
|
@ -95,23 +102,31 @@ struct LoraClientParam |
|
|
|
**data_type : 0x0A(join net, client->gateway)、0x0B(join net reply, gateway->client)、 |
|
|
|
0x0C(user data, client->gateway)、0x0D(user data cmd, gateway->client) |
|
|
|
**data : user data |
|
|
|
**crc16 : CRC 16 check data |
|
|
|
**flame_end : 0x5A5A |
|
|
|
*/ |
|
|
|
struct LoraDataFormat |
|
|
|
{ |
|
|
|
uint8 flame_head; |
|
|
|
uint8 reserved[3]; |
|
|
|
uint32 length; |
|
|
|
uint16 panid; |
|
|
|
uint8 client_id; |
|
|
|
uint8 gateway_id; |
|
|
|
uint16_t flame_head; |
|
|
|
uint16_t flame_index; |
|
|
|
uint32_t length; |
|
|
|
uint16_t panid; |
|
|
|
uint8_t client_id; |
|
|
|
uint8_t gateway_id; |
|
|
|
|
|
|
|
uint16 data_type; |
|
|
|
uint8 data[ADAPTER_LORA_DATA_LENGTH]; |
|
|
|
uint16_t data_type; |
|
|
|
uint8_t data[ADAPTER_LORA_DATA_LENGTH]; |
|
|
|
|
|
|
|
uint16 crc16; |
|
|
|
uint16_t flame_end; |
|
|
|
}; |
|
|
|
|
|
|
|
uint8_t lora_recv_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH]; |
|
|
|
struct LoraDataFormat client_recv_data_format[ADAPTER_LORA_CLIENT_NUM]; |
|
|
|
|
|
|
|
static sem_t gateway_recv_data_sem; |
|
|
|
struct LoraDataFormat gateway_recv_data_format; |
|
|
|
|
|
|
|
static int recv_error_cnt = 0; |
|
|
|
|
|
|
|
/*******************LORA MESH FUNCTION***********************/ |
|
|
|
|
|
|
|
/**
|
|
|
@ -119,10 +134,10 @@ struct LoraDataFormat |
|
|
|
* @param data input data buffer |
|
|
|
* @param length input data buffer minus check code |
|
|
|
*/ |
|
|
|
static uint16 LoraCrc16(uint8 *data, uint16 length) |
|
|
|
static uint16_t LoraCrc16(uint8_t *data, uint16_t length) |
|
|
|
{ |
|
|
|
int j; |
|
|
|
uint16 crc_data = 0xFFFF; |
|
|
|
uint16_t crc_data = 0xFFFF; |
|
|
|
|
|
|
|
while (length--) { |
|
|
|
crc_data ^= *data++; |
|
|
@ -142,10 +157,10 @@ static uint16 LoraCrc16(uint8 *data, uint16 length) |
|
|
|
* @param data input data buffer |
|
|
|
* @param length input data buffer minus check code |
|
|
|
*/ |
|
|
|
static int LoraCrc16Check(uint8 *data, uint16 length) |
|
|
|
static int LoraCrc16Check(uint8_t *data, uint16_t length) |
|
|
|
{ |
|
|
|
uint16 crc_data; |
|
|
|
uint16 input_data = (((uint16)data[length - 1] << 8) & 0xFF00) | ((uint16)data[length - 2] & 0x00FF); |
|
|
|
uint16_t crc_data; |
|
|
|
uint16_t input_data = (((uint16_t)data[length - 1] << 8) & 0xFF00) | ((uint16_t)data[length - 2] & 0x00FF); |
|
|
|
|
|
|
|
crc_data = LoraCrc16(data, length - 2); |
|
|
|
|
|
|
@ -155,29 +170,6 @@ static int LoraCrc16Check(uint8 *data, uint16 length) |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* @description: Lora receive data check |
|
|
|
* @param data receive data buffer |
|
|
|
* @param length receive data length |
|
|
|
* @param recv_data LoraDataFormat data |
|
|
|
*/ |
|
|
|
static int LoraReceiveDataCheck(uint8 *data, uint16 length, struct LoraDataFormat *recv_data) |
|
|
|
{ |
|
|
|
int i; |
|
|
|
uint32 recv_data_length = 0; |
|
|
|
for ( i = 0; i < length; i ++) { |
|
|
|
if (ADAPTER_LORA_DATA_HEAD == data[i]) { |
|
|
|
recv_data_length = (data[i + 4] & 0xFF) | ((data[i + 5] & 0xFF) << 8) | ((data[i + 6] & 0xFF) << 16) | ((data[i + 7] & 0xFF) << 24); |
|
|
|
if (sizeof(struct LoraDataFormat) == recv_data_length) { |
|
|
|
memcpy(recv_data, (uint8 *)(data + i), sizeof(struct LoraDataFormat)); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* @description: Lora Gateway reply connect request to Client |
|
|
|
* @param adapter Lora adapter pointer |
|
|
@ -187,10 +179,13 @@ static int LoraGatewayReply(struct Adapter *adapter, struct LoraDataFormat *gate |
|
|
|
{ |
|
|
|
int i; |
|
|
|
int client_join_flag = 0; |
|
|
|
uint16_t gateway_data_type; |
|
|
|
uint32_t gateway_reply_length = ADAPTER_LORA_TRANSFER_DATA_LENGTH; |
|
|
|
struct LoraGatewayParam *gateway = (struct LoraGatewayParam *)adapter->adapter_param; |
|
|
|
struct LoraDataFormat gateway_reply_data; |
|
|
|
|
|
|
|
memset(&gateway_reply_data, 0, sizeof(struct LoraDataFormat)); |
|
|
|
uint8_t gateway_reply_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH]; |
|
|
|
|
|
|
|
memset(gateway_reply_data, 0, ADAPTER_LORA_TRANSFER_DATA_LENGTH); |
|
|
|
|
|
|
|
if (ADAPTER_LORA_DATA_TYPE_JOIN == gateway_recv_data->data_type) { |
|
|
|
|
|
|
@ -203,23 +198,35 @@ static int LoraGatewayReply(struct Adapter *adapter, struct LoraDataFormat *gate |
|
|
|
} |
|
|
|
|
|
|
|
if (!client_join_flag) { |
|
|
|
if (gateway->client_num > 6) { |
|
|
|
printf("Lora gateway only support 6(max) client\n"); |
|
|
|
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] = gateway_recv_data->client_id; |
|
|
|
gateway->client_num ++; |
|
|
|
} |
|
|
|
|
|
|
|
gateway_reply_data.flame_head = ADAPTER_LORA_DATA_HEAD; |
|
|
|
gateway_reply_data.length = sizeof(struct LoraDataFormat); |
|
|
|
gateway_reply_data.panid = gateway->panid; |
|
|
|
gateway_reply_data.data_type = ADAPTER_LORA_DATA_TYPE_JOIN_REPLY; |
|
|
|
gateway_reply_data.client_id = gateway_recv_data->client_id; |
|
|
|
gateway_reply_data.gateway_id = gateway->gateway_id; |
|
|
|
gateway_reply_data.crc16 = LoraCrc16((uint8 *)&gateway_reply_data, sizeof(struct LoraDataFormat) - 2); |
|
|
|
|
|
|
|
if (AdapterDeviceSend(adapter, (uint8 *)&gateway_reply_data, gateway_reply_data.length) < 0) { |
|
|
|
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] = 0; |
|
|
|
gateway_reply_data[3] = 0; |
|
|
|
gateway_reply_data[4] = (gateway_reply_length >> 24) & 0xFF; |
|
|
|
gateway_reply_data[5] = (gateway_reply_length >> 16) & 0xFF; |
|
|
|
gateway_reply_data[6] = (gateway_reply_length >> 8) & 0xFF; |
|
|
|
gateway_reply_data[7] = gateway_reply_length & 0xFF; |
|
|
|
gateway_reply_data[8] = (gateway->panid >> 8) & 0xFF; |
|
|
|
gateway_reply_data[9] = gateway->panid & 0xFF; |
|
|
|
gateway_reply_data[10] = gateway_recv_data->client_id; |
|
|
|
gateway_reply_data[11] = gateway->gateway_id; |
|
|
|
gateway_reply_data[12] = (gateway_data_type >> 8) & 0xFF; |
|
|
|
gateway_reply_data[13] = gateway_data_type & 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; |
|
|
|
} |
|
|
|
|
|
|
@ -233,15 +240,27 @@ static int LoraGatewayReply(struct Adapter *adapter, struct LoraDataFormat *gate |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
gateway_reply_data.flame_head = ADAPTER_LORA_DATA_HEAD; |
|
|
|
gateway_reply_data.length = sizeof(struct LoraDataFormat); |
|
|
|
gateway_reply_data.panid = gateway->panid; |
|
|
|
gateway_reply_data.data_type = ADAPTER_LORA_DATA_TYPE_QUIT_REPLY; |
|
|
|
gateway_reply_data.client_id = gateway_recv_data->client_id; |
|
|
|
gateway_reply_data.gateway_id = gateway->gateway_id; |
|
|
|
gateway_reply_data.crc16 = LoraCrc16((uint8 *)&gateway_reply_data, sizeof(struct LoraDataFormat) - 2); |
|
|
|
|
|
|
|
if (AdapterDeviceSend(adapter, (uint8 *)&gateway_reply_data, gateway_reply_data.length) < 0) { |
|
|
|
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] = 0; |
|
|
|
gateway_reply_data[3] = 0; |
|
|
|
gateway_reply_data[4] = (gateway_reply_length >> 24) & 0xFF; |
|
|
|
gateway_reply_data[5] = (gateway_reply_length >> 16) & 0xFF; |
|
|
|
gateway_reply_data[6] = (gateway_reply_length >> 8) & 0xFF; |
|
|
|
gateway_reply_data[7] = gateway_reply_length & 0xFF; |
|
|
|
gateway_reply_data[8] = (gateway->panid >> 8) & 0xFF; |
|
|
|
gateway_reply_data[9] = gateway->panid & 0xFF; |
|
|
|
gateway_reply_data[10] = gateway_recv_data->client_id; |
|
|
|
gateway_reply_data[11] = gateway->gateway_id; |
|
|
|
gateway_reply_data[12] = (gateway_data_type >> 8) & 0xFF; |
|
|
|
gateway_reply_data[13] = gateway_data_type & 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; |
|
|
|
} |
|
|
|
|
|
|
@ -257,22 +276,36 @@ static int LoraGatewayReply(struct Adapter *adapter, struct LoraDataFormat *gate |
|
|
|
* @param client_id Lora Client id |
|
|
|
* @param cmd Lora cmd |
|
|
|
*/ |
|
|
|
static int LoraGatewaySendCmd(struct Adapter *adapter, unsigned char client_id, int cmd) |
|
|
|
static int LoraGatewaySendCmd(struct Adapter *adapter, uint8_t client_id, uint16_t cmd) |
|
|
|
{ |
|
|
|
struct LoraGatewayParam *gateway = (struct LoraGatewayParam *)adapter->adapter_param; |
|
|
|
struct LoraDataFormat gateway_cmd_data; |
|
|
|
|
|
|
|
memset(&gateway_cmd_data, 0, sizeof(struct LoraDataFormat)); |
|
|
|
|
|
|
|
gateway_cmd_data.flame_head = ADAPTER_LORA_DATA_HEAD; |
|
|
|
gateway_cmd_data.length = sizeof(struct LoraDataFormat); |
|
|
|
gateway_cmd_data.panid = gateway->panid; |
|
|
|
gateway_cmd_data.data_type = cmd; |
|
|
|
gateway_cmd_data.client_id = client_id; |
|
|
|
gateway_cmd_data.gateway_id = gateway->gateway_id; |
|
|
|
gateway_cmd_data.crc16 = LoraCrc16((uint8 *)&gateway_cmd_data, sizeof(struct LoraDataFormat) - 2); |
|
|
|
uint16_t gateway_cmd_type; |
|
|
|
uint32_t gateway_cmd_length = ADAPTER_LORA_TRANSFER_DATA_LENGTH; |
|
|
|
uint8_t gateway_cmd_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH]; |
|
|
|
|
|
|
|
memset(gateway_cmd_data, 0, sizeof(struct LoraDataFormat)); |
|
|
|
|
|
|
|
gateway_cmd_type = cmd; |
|
|
|
|
|
|
|
gateway_cmd_data[0] = ADAPTER_LORA_DATA_HEAD; |
|
|
|
gateway_cmd_data[1] = ADAPTER_LORA_DATA_HEAD; |
|
|
|
gateway_cmd_data[2] = 0; |
|
|
|
gateway_cmd_data[3] = 0; |
|
|
|
gateway_cmd_data[4] = (gateway_cmd_length >> 24) & 0xFF; |
|
|
|
gateway_cmd_data[5] = (gateway_cmd_length >> 16) & 0xFF; |
|
|
|
gateway_cmd_data[6] = (gateway_cmd_length >> 8) & 0xFF; |
|
|
|
gateway_cmd_data[7] = gateway_cmd_length & 0xFF; |
|
|
|
gateway_cmd_data[8] = (gateway->panid >> 8) & 0xFF; |
|
|
|
gateway_cmd_data[9] = gateway->panid & 0xFF; |
|
|
|
gateway_cmd_data[10] = client_id; |
|
|
|
gateway_cmd_data[11] = gateway->gateway_id; |
|
|
|
gateway_cmd_data[12] = (gateway_cmd_type >> 8) & 0xFF; |
|
|
|
gateway_cmd_data[13] = gateway_cmd_type & 0xFF; |
|
|
|
|
|
|
|
gateway_cmd_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 2] = ADAPTER_LORA_DATA_END; |
|
|
|
gateway_cmd_data[ADAPTER_LORA_TRANSFER_DATA_LENGTH - 1] = ADAPTER_LORA_DATA_END; |
|
|
|
|
|
|
|
if (AdapterDeviceSend(adapter, (uint8 *)&gateway_cmd_data, gateway_cmd_data.length) < 0) { |
|
|
|
if (AdapterDeviceSend(adapter, gateway_cmd_data, ADAPTER_LORA_TRANSFER_DATA_LENGTH) < 0) { |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
@ -289,6 +322,8 @@ static int LoraGatewayHandleData(struct Adapter *adapter, struct LoraDataFormat |
|
|
|
/*User needs to handle client data depends on the requirement*/ |
|
|
|
printf("Lora Gateway receive Client %d data:\n", gateway_recv_data->client_id); |
|
|
|
printf("%s\n", gateway_recv_data->data); |
|
|
|
|
|
|
|
PrivSemaphoreAbandon(&gateway_recv_data_sem); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
@ -321,8 +356,9 @@ static int LoraClientUpdate(struct Adapter *adapter, struct LoraDataFormat *clie |
|
|
|
* @param adapter Lora adapter pointer |
|
|
|
* @param send_buf Lora Client send user data buf |
|
|
|
* @param length user data length (max size is ADAPTER_LORA_DATA_LENGTH) |
|
|
|
* @param send_index user data index, max size ADAPTER_LORA_DATA_LENGTH single index |
|
|
|
*/ |
|
|
|
static int LoraClientSendData(struct Adapter *adapter, void *send_buf, int length) |
|
|
|
static int LoraClientSendData(struct Adapter *adapter, void *send_buf, int length, uint16_t send_index) |
|
|
|
{ |
|
|
|
struct LoraClientParam *client = (struct LoraClientParam *)adapter->adapter_param; |
|
|
|
|
|
|
@ -336,22 +372,35 @@ static int LoraClientSendData(struct Adapter *adapter, void *send_buf, int lengt |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
struct LoraDataFormat client_user_data; |
|
|
|
|
|
|
|
memset(&client_user_data, 0, sizeof(struct LoraDataFormat)); |
|
|
|
|
|
|
|
client_user_data.flame_head = ADAPTER_LORA_DATA_HEAD; |
|
|
|
client_user_data.length = sizeof(struct LoraDataFormat); |
|
|
|
client_user_data.panid = client->panid; |
|
|
|
client_user_data.data_type = ADAPTER_LORA_DATA_TYPE_USERDATA; |
|
|
|
client_user_data.client_id = client->client_id; |
|
|
|
client_user_data.gateway_id = client->gateway_id; |
|
|
|
|
|
|
|
memcpy(client_user_data.data, (uint8 *)send_buf, length); |
|
|
|
|
|
|
|
client_user_data.crc16 = LoraCrc16((uint8 *)&client_user_data, sizeof(struct LoraDataFormat) - 2); |
|
|
|
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]; |
|
|
|
|
|
|
|
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] = (send_index >> 8) & 0xFF; |
|
|
|
client_user_data[3] = send_index & 0xFF; |
|
|
|
client_user_data[4] = (client_user_length >> 24) & 0xFF; |
|
|
|
client_user_data[5] = (client_user_length >> 16) & 0xFF; |
|
|
|
client_user_data[6] = (client_user_length >> 8) & 0xFF; |
|
|
|
client_user_data[7] = client_user_length & 0xFF; |
|
|
|
client_user_data[8] = (client->panid >> 8) & 0xFF; |
|
|
|
client_user_data[9] = client->panid & 0xFF; |
|
|
|
client_user_data[10] = client->client_id; |
|
|
|
client_user_data[11] = client->gateway_id; |
|
|
|
client_user_data[12] = (client_user_type >> 8) & 0xFF; |
|
|
|
client_user_data[13] = client_user_type & 0xFF; |
|
|
|
|
|
|
|
memcpy((uint8_t *)(client_user_data + 14), (uint8_t *)send_buf, length); |
|
|
|
|
|
|
|
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, (uint8 *)&client_user_data, client_user_data.length) < 0) { |
|
|
|
if (AdapterDeviceSend(adapter, client_user_data, ADAPTER_LORA_TRANSFER_DATA_LENGTH) < 0) { |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
@ -361,35 +410,32 @@ static int LoraClientSendData(struct Adapter *adapter, void *send_buf, int lengt |
|
|
|
/**
|
|
|
|
* @description: Lora Gateway receive data analyzing |
|
|
|
* @param adapter Lora adapter pointer |
|
|
|
* @param gateway_recv_data Lora gateway receive data pointer |
|
|
|
*/ |
|
|
|
static int LoraGateWayDataAnalyze(struct Adapter *adapter, struct LoraDataFormat *gateway_recv_data) |
|
|
|
static int LoraGateWayDataAnalyze(struct Adapter *adapter) |
|
|
|
{ |
|
|
|
int ret = 0; |
|
|
|
printf("%s:gateway_recv_data\n",__func__); |
|
|
|
printf("head 0x%x length %d panid 0x%x data_type 0x%x client_id 0x%x gateway_id 0x%x crc 0x%x\n", |
|
|
|
gateway_recv_data->flame_head, gateway_recv_data->length, gateway_recv_data->panid, gateway_recv_data->data_type, |
|
|
|
gateway_recv_data->client_id, gateway_recv_data->gateway_id, gateway_recv_data->crc16); |
|
|
|
|
|
|
|
if (LoraCrc16Check((uint8 *)gateway_recv_data, sizeof(struct LoraDataFormat)) < 0) { |
|
|
|
printf("LoraGateWayDataAnalyze CRC check error\n"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
if (ADAPTER_LORA_NET_PANID == gateway_recv_data_format.panid) { |
|
|
|
|
|
|
|
if ((ADAPTER_LORA_DATA_HEAD == gateway_recv_data->flame_head) && |
|
|
|
(ADAPTER_LORA_NET_PANID == gateway_recv_data->panid)) { |
|
|
|
switch (gateway_recv_data->data_type) |
|
|
|
printf("%s: gateway_recv_data\n", __func__); |
|
|
|
printf("head 0x%x length %d panid 0x%x data_type 0x%x client_id 0x%x gateway_id 0x%x end 0x%x\n", |
|
|
|
gateway_recv_data_format.flame_head, gateway_recv_data_format.length, gateway_recv_data_format.panid, gateway_recv_data_format.data_type, |
|
|
|
gateway_recv_data_format.client_id, gateway_recv_data_format.gateway_id, gateway_recv_data_format.flame_end); |
|
|
|
|
|
|
|
switch (gateway_recv_data_format.data_type) |
|
|
|
{ |
|
|
|
case ADAPTER_LORA_DATA_TYPE_JOIN : |
|
|
|
case ADAPTER_LORA_DATA_TYPE_QUIT : |
|
|
|
ret = LoraGatewayReply(adapter, gateway_recv_data); |
|
|
|
ret = LoraGatewayReply(adapter, &gateway_recv_data_format); |
|
|
|
break; |
|
|
|
case ADAPTER_LORA_DATA_TYPE_USERDATA : |
|
|
|
ret = LoraGatewayHandleData(adapter, gateway_recv_data); |
|
|
|
ret = LoraGatewayHandleData(adapter, &gateway_recv_data_format); |
|
|
|
break; |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
} else { |
|
|
|
ret = -1; |
|
|
|
} |
|
|
|
|
|
|
|
return ret; |
|
|
@ -400,58 +446,44 @@ static int LoraGateWayDataAnalyze(struct Adapter *adapter, struct LoraDataFormat |
|
|
|
* @param adapter Lora adapter pointer |
|
|
|
* @param send_buf Lora Client send user data buf |
|
|
|
* @param length user data length (max size is ADAPTER_LORA_DATA_LENGTH) |
|
|
|
* @param index user data index, max size ADAPTER_LORA_DATA_LENGTH single index |
|
|
|
*/ |
|
|
|
static int LoraClientDataAnalyze(struct Adapter *adapter, void *send_buf, int length) |
|
|
|
static int LoraClientDataAnalyze(struct Adapter *adapter, void *send_buf, int length, uint16_t index) |
|
|
|
{ |
|
|
|
int ret = 0; |
|
|
|
uint8 lora_recv_data[ADAPTER_LORA_RECV_DATA_LENGTH] = {0}; |
|
|
|
|
|
|
|
struct LoraDataFormat *client_recv_data = PrivMalloc(sizeof(struct LoraDataFormat)); |
|
|
|
|
|
|
|
memset(client_recv_data, 0, sizeof(struct LoraDataFormat)); |
|
|
|
|
|
|
|
ret = AdapterDeviceRecv(adapter, lora_recv_data, ADAPTER_LORA_RECV_DATA_LENGTH); |
|
|
|
if (ret <= 0) { |
|
|
|
printf("LoraClientDataAnalyze recv error.Just return\n"); |
|
|
|
PrivFree(client_recv_data); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
LoraReceiveDataCheck(lora_recv_data, ADAPTER_LORA_RECV_DATA_LENGTH, client_recv_data); |
|
|
|
uint8_t client_id = adapter->net_role_id; |
|
|
|
|
|
|
|
printf("%s:client_recv_data\n", __func__); |
|
|
|
printf("head 0x%x length %d panid 0x%x data_type 0x%x client_id 0x%x gateway_id 0x%x crc 0x%x\n", |
|
|
|
client_recv_data->flame_head, client_recv_data->length, client_recv_data->panid, client_recv_data->data_type, |
|
|
|
client_recv_data->client_id, client_recv_data->gateway_id, client_recv_data->crc16); |
|
|
|
ret = PrivSemaphoreObtainWait(&adapter->sem, NULL); |
|
|
|
if (0 == ret) { |
|
|
|
//only handle this client_id information from gateway
|
|
|
|
if ((client_recv_data_format[client_id - 1].client_id == adapter->net_role_id) && |
|
|
|
(ADAPTER_LORA_NET_PANID == client_recv_data_format[client_id - 1].panid)) { |
|
|
|
|
|
|
|
if ((ADAPTER_LORA_DATA_HEAD == client_recv_data->flame_head) && |
|
|
|
(ADAPTER_LORA_NET_PANID == client_recv_data->panid)) { |
|
|
|
if (LoraCrc16Check((uint8 *)client_recv_data, sizeof(struct LoraDataFormat)) < 0) { |
|
|
|
printf("LoraClientDataAnalyze CRC check error\n"); |
|
|
|
PrivFree(client_recv_data); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
printf("%s: 0x%x client_recv_data\n", __func__, client_recv_data_format[client_id - 1].client_id); |
|
|
|
printf("head 0x%x length %d panid 0x%x data_type 0x%x client_id 0x%x gateway_id 0x%x end 0x%x\n", |
|
|
|
client_recv_data_format[client_id - 1].flame_head, client_recv_data_format[client_id - 1].length, client_recv_data_format[client_id - 1].panid, client_recv_data_format[client_id - 1].data_type, |
|
|
|
client_recv_data_format[client_id - 1].client_id, client_recv_data_format[client_id - 1].gateway_id, client_recv_data_format[client_id - 1].flame_end); |
|
|
|
|
|
|
|
//only handle this client_id information from gateway
|
|
|
|
if (client_recv_data->client_id == adapter->net_role_id) { |
|
|
|
switch (client_recv_data->data_type) |
|
|
|
switch (client_recv_data_format[client_id - 1].data_type) |
|
|
|
{ |
|
|
|
case ADAPTER_LORA_DATA_TYPE_JOIN_REPLY : |
|
|
|
case ADAPTER_LORA_DATA_TYPE_QUIT_REPLY : |
|
|
|
ret = LoraClientUpdate(adapter, client_recv_data); |
|
|
|
ret = LoraClientUpdate(adapter, &client_recv_data_format[client_id - 1]); |
|
|
|
break; |
|
|
|
case ADAPTER_LORA_DATA_TYPE_CMD : |
|
|
|
if (send_buf) { |
|
|
|
ret = LoraClientSendData(adapter, send_buf, length); |
|
|
|
ret = LoraClientSendData(adapter, send_buf, length, index); |
|
|
|
} |
|
|
|
break; |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
//Client operation done
|
|
|
|
memset(&client_recv_data_format[client_id - 1], 0 , sizeof(struct LoraDataFormat)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
PrivFree(client_recv_data); |
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
@ -462,30 +494,43 @@ static int LoraClientDataAnalyze(struct Adapter *adapter, void *send_buf, int le |
|
|
|
*/ |
|
|
|
static int LoraClientJoinNet(struct Adapter *adapter, unsigned short panid) |
|
|
|
{ |
|
|
|
struct LoraDataFormat client_join_data; |
|
|
|
struct AdapterData priv_lora_net; |
|
|
|
|
|
|
|
memset(&client_join_data, 0, sizeof(struct LoraDataFormat)); |
|
|
|
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]; |
|
|
|
|
|
|
|
client_join_data.flame_head = ADAPTER_LORA_DATA_HEAD; |
|
|
|
client_join_data.length = sizeof(struct LoraDataFormat); |
|
|
|
client_join_data.panid = panid; |
|
|
|
client_join_data.data_type = ADAPTER_LORA_DATA_TYPE_JOIN; |
|
|
|
client_join_data.client_id = adapter->net_role_id; |
|
|
|
client_join_data.crc16 = LoraCrc16((uint8 *)&client_join_data, sizeof(struct LoraDataFormat) - 2); |
|
|
|
memset(client_join_data, 0, ADAPTER_LORA_TRANSFER_DATA_LENGTH); |
|
|
|
|
|
|
|
printf("%s:client_join_data\n", __func__); |
|
|
|
printf("head 0x%x length %d panid 0x%x data_type 0x%x client_id 0x%x gateway_id 0x%x crc 0x%x\n", |
|
|
|
client_join_data.flame_head, client_join_data.length, client_join_data.panid, client_join_data.data_type, |
|
|
|
client_join_data.client_id, client_join_data.gateway_id, client_join_data.crc16); |
|
|
|
|
|
|
|
priv_lora_net.len = sizeof(struct LoraDataFormat); |
|
|
|
priv_lora_net.buffer = (uint8 *)&client_join_data; |
|
|
|
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] = 0; |
|
|
|
client_join_data[3] = 0; |
|
|
|
client_join_data[4] = (client_join_length >> 24) & 0xFF; |
|
|
|
client_join_data[5] = (client_join_length >> 16) & 0xFF; |
|
|
|
client_join_data[6] = (client_join_length >> 8) & 0xFF; |
|
|
|
client_join_data[7] = client_join_length & 0xFF; |
|
|
|
client_join_data[8] = (panid >> 8) & 0xFF; |
|
|
|
client_join_data[9] = panid & 0xFF; |
|
|
|
client_join_data[10] = adapter->net_role_id & 0xFF; |
|
|
|
client_join_data[11] = 0; |
|
|
|
client_join_data[12] = (client_join_type >> 8) & 0xFF; |
|
|
|
client_join_data[13] = client_join_type & 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 *)&priv_lora_net) < 0) { |
|
|
|
if (AdapterDeviceJoin(adapter, (uint8_t *)&priv_lora_net) < 0) { |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
printf("%s:client_join_data panid 0x%x client_id 0x%x\n", __func__, panid, adapter->net_role_id); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
@ -496,107 +541,166 @@ static int LoraClientJoinNet(struct Adapter *adapter, unsigned short panid) |
|
|
|
*/ |
|
|
|
static int LoraClientQuitNet(struct Adapter *adapter, unsigned short panid) |
|
|
|
{ |
|
|
|
struct LoraDataFormat client_quit_data; |
|
|
|
struct AdapterData priv_lora_net; |
|
|
|
|
|
|
|
memset(&client_quit_data, 0, sizeof(struct LoraDataFormat)); |
|
|
|
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]; |
|
|
|
|
|
|
|
client_quit_data.flame_head = ADAPTER_LORA_DATA_HEAD; |
|
|
|
client_quit_data.length = sizeof(struct LoraDataFormat); |
|
|
|
client_quit_data.panid = panid; |
|
|
|
client_quit_data.data_type = ADAPTER_LORA_DATA_TYPE_QUIT; |
|
|
|
client_quit_data.client_id = adapter->net_role_id; |
|
|
|
client_quit_data.crc16 = LoraCrc16((uint8 *)&client_quit_data, sizeof(struct LoraDataFormat) - 2); |
|
|
|
|
|
|
|
priv_lora_net.len = sizeof(struct LoraDataFormat); |
|
|
|
priv_lora_net.buffer = (uint8 *)&client_quit_data; |
|
|
|
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] = 0; |
|
|
|
client_quit_data[3] = 0; |
|
|
|
client_quit_data[4] = (client_quit_length >> 24) & 0xFF; |
|
|
|
client_quit_data[5] = (client_quit_length >> 16) & 0xFF; |
|
|
|
client_quit_data[6] = (client_quit_length >> 8) & 0xFF; |
|
|
|
client_quit_data[7] = client_quit_length & 0xFF; |
|
|
|
client_quit_data[8] = (panid >> 8) & 0xFF; |
|
|
|
client_quit_data[9] = panid & 0xFF; |
|
|
|
client_quit_data[10] = adapter->net_role_id & 0xFF; |
|
|
|
client_quit_data[11] = 0; |
|
|
|
client_quit_data[12] = (client_quit_type >> 8) & 0xFF; |
|
|
|
client_quit_data[13] = client_quit_type & 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; |
|
|
|
|
|
|
|
if (AdapterDeviceDisconnect(adapter, (uint8 *)&priv_lora_net) < 0) { |
|
|
|
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) { |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
printf("%s:client_quit_data panid 0x%x client_id 0x%x\n", __func__, panid, adapter->net_role_id); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* @description: Lora Gateway Process function |
|
|
|
* @param lora_adapter Lora adapter pointer |
|
|
|
* @param gateway Lora gateway pointer |
|
|
|
* @param gateway_recv_data Lora gateway receive data pointer |
|
|
|
* @description: Lora receive data check |
|
|
|
* @param adapter Lora adapter pointer |
|
|
|
* @param recv_data receive data buffer |
|
|
|
* @param length receive data length |
|
|
|
*/ |
|
|
|
int LoraGatewayProcess(struct Adapter *lora_adapter, struct LoraGatewayParam *gateway, struct LoraDataFormat *gateway_recv_data) |
|
|
|
static int LoraReceiveDataCheck(struct Adapter *adapter, uint8_t *recv_data, uint16_t length) |
|
|
|
{ |
|
|
|
int i, ret = 0; |
|
|
|
uint8 lora_recv_data[ADAPTER_LORA_RECV_DATA_LENGTH]; |
|
|
|
switch (LoraGatewayState) |
|
|
|
{ |
|
|
|
case LORA_STATE_IDLE: |
|
|
|
memset(lora_recv_data, 0, ADAPTER_LORA_RECV_DATA_LENGTH); |
|
|
|
|
|
|
|
ret = AdapterDeviceRecv(lora_adapter, lora_recv_data, ADAPTER_LORA_RECV_DATA_LENGTH); |
|
|
|
if (ret <= 0) { |
|
|
|
printf("LoraGatewayProcess IDLE recv error.Just return\n"); |
|
|
|
break; |
|
|
|
int ret; |
|
|
|
uint8_t client_id; |
|
|
|
|
|
|
|
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])) { |
|
|
|
|
|
|
|
#ifdef AS_LORA_GATEWAY_ROLE |
|
|
|
gateway_recv_data_format.flame_head = ((recv_data[0] << 8) & 0xFF00) | recv_data[1]; |
|
|
|
gateway_recv_data_format.flame_index = ((recv_data[2] << 8) & 0xFF00) | recv_data[3]; |
|
|
|
gateway_recv_data_format.length = ((recv_data[4] << 24) & 0xFF000000) | ((recv_data[5] << 16) & 0xFF0000) | |
|
|
|
((recv_data[6] << 8) & 0xFF00) | (recv_data[7] & 0xFF); |
|
|
|
gateway_recv_data_format.panid = ((recv_data[8] << 8) & 0xFF00) | recv_data[9]; |
|
|
|
gateway_recv_data_format.client_id = recv_data[10]; |
|
|
|
gateway_recv_data_format.gateway_id = recv_data[11]; |
|
|
|
gateway_recv_data_format.data_type = ((recv_data[12] << 8) & 0xFF00) | recv_data[13]; |
|
|
|
|
|
|
|
gateway_recv_data_format.flame_end = ((recv_data[length - 2] << 8) & 0xFF00) | recv_data[length - 1]; |
|
|
|
|
|
|
|
memcpy(gateway_recv_data_format.data, (uint8_t *)(recv_data + 14), ADAPTER_LORA_DATA_LENGTH); |
|
|
|
|
|
|
|
ret = LoraGateWayDataAnalyze(adapter); |
|
|
|
|
|
|
|
return ret; |
|
|
|
#else |
|
|
|
client_id = recv_data[10]; |
|
|
|
|
|
|
|
if (client_id == adapter->net_role_id) { |
|
|
|
printf("client_id 0x%x recv data\n", client_id); |
|
|
|
client_recv_data_format[client_id - 1].flame_head = ((recv_data[0] << 8) & 0xFF00) | recv_data[1]; |
|
|
|
client_recv_data_format[client_id - 1].flame_index = ((recv_data[2] << 8) & 0xFF00) | recv_data[3]; |
|
|
|
client_recv_data_format[client_id - 1].length = ((recv_data[4] << 24) & 0xFF000000) | ((recv_data[5] << 16) & 0xFF0000) | |
|
|
|
((recv_data[6] << 8) & 0xFF00) | (recv_data[7] & 0xFF); |
|
|
|
client_recv_data_format[client_id - 1].panid = ((recv_data[8] << 8) & 0xFF00) | recv_data[9]; |
|
|
|
client_recv_data_format[client_id - 1].client_id = recv_data[10]; |
|
|
|
client_recv_data_format[client_id - 1].gateway_id = recv_data[11]; |
|
|
|
client_recv_data_format[client_id - 1].data_type = ((recv_data[12] << 8) & 0xFF00) | recv_data[13]; |
|
|
|
|
|
|
|
client_recv_data_format[client_id - 1].flame_end = ((recv_data[length - 2] << 8) & 0xFF00) | recv_data[length - 1]; |
|
|
|
|
|
|
|
memcpy(client_recv_data_format[client_id - 1].data, (uint8_t *)(recv_data + 14), ADAPTER_LORA_DATA_LENGTH); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
LoraReceiveDataCheck(lora_recv_data, ADAPTER_LORA_RECV_DATA_LENGTH, gateway_recv_data); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* @description: Lora data receive task |
|
|
|
* @param parameter - Lora adapter pointer |
|
|
|
*/ |
|
|
|
static void *LoraReceiveTask(void *parameter) |
|
|
|
{ |
|
|
|
int ret = 0; |
|
|
|
struct Adapter *lora_adapter = (struct Adapter *)parameter; |
|
|
|
|
|
|
|
if (ADAPTER_LORA_DATA_TYPE_JOIN == gateway_recv_data->data_type) { |
|
|
|
LoraGatewayState = LORA_JOIN_NET; |
|
|
|
} else if (ADAPTER_LORA_DATA_TYPE_QUIT == gateway_recv_data->data_type) { |
|
|
|
LoraGatewayState = LORA_QUIT_NET; |
|
|
|
} else { |
|
|
|
LoraGatewayState = LORA_STATE_IDLE; |
|
|
|
while (1) { |
|
|
|
memset(lora_recv_data, 0, ADAPTER_LORA_TRANSFER_DATA_LENGTH); |
|
|
|
|
|
|
|
ret = AdapterDeviceRecv(lora_adapter, lora_recv_data, ADAPTER_LORA_TRANSFER_DATA_LENGTH); |
|
|
|
if (ret <= 0) { |
|
|
|
printf("AdapterDeviceRecv error.Just return\n"); |
|
|
|
recv_error_cnt++; |
|
|
|
if (recv_error_cnt > ADAPTER_LORA_RECEIVE_ERROR_CNT) { |
|
|
|
recv_error_cnt = 0; |
|
|
|
#ifdef AS_LORA_GATEWAY_ROLE |
|
|
|
PrivSemaphoreAbandon(&gateway_recv_data_sem); |
|
|
|
#endif |
|
|
|
} |
|
|
|
continue; |
|
|
|
} |
|
|
|
break; |
|
|
|
case LORA_JOIN_NET: |
|
|
|
case LORA_QUIT_NET: |
|
|
|
ret = LoraGateWayDataAnalyze(lora_adapter, gateway_recv_data); |
|
|
|
|
|
|
|
ret = LoraReceiveDataCheck(lora_adapter, lora_recv_data, ADAPTER_LORA_TRANSFER_DATA_LENGTH); |
|
|
|
if (ret < 0) { |
|
|
|
printf("LoraGateWayDataAnalyze state %d error, re-send data cmd to client\n", LoraGatewayState); |
|
|
|
PrivTaskDelay(500); |
|
|
|
continue; |
|
|
|
} |
|
|
|
LoraGatewayState = LORA_RECV_DATA; |
|
|
|
break; |
|
|
|
case LORA_RECV_DATA: |
|
|
|
for (i = 0; i < gateway->client_num; i ++) { |
|
|
|
if (gateway->client_id[i]) { |
|
|
|
printf("LoraGatewayProcess send to client %d for data\n", gateway->client_id[i]); |
|
|
|
ret = LoraGatewaySendCmd(lora_adapter, gateway->client_id[i], ADAPTER_LORA_DATA_TYPE_CMD); |
|
|
|
if (ret < 0) { |
|
|
|
printf("LoraGatewaySendCmd client ID %d error\n", gateway->client_id[i]); |
|
|
|
PrivTaskDelay(500); |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
memset(lora_recv_data, 0, ADAPTER_LORA_RECV_DATA_LENGTH); |
|
|
|
ret = AdapterDeviceRecv(lora_adapter, lora_recv_data, ADAPTER_LORA_RECV_DATA_LENGTH); |
|
|
|
if (ret <= 0) { |
|
|
|
printf("LoraGatewayProcess recv error.Just return\n"); |
|
|
|
continue; |
|
|
|
} |
|
|
|
PrivSemaphoreAbandon(&lora_adapter->sem); |
|
|
|
} |
|
|
|
|
|
|
|
LoraReceiveDataCheck(lora_recv_data, ADAPTER_LORA_RECV_DATA_LENGTH, gateway_recv_data); |
|
|
|
|
|
|
|
if (ADAPTER_LORA_DATA_TYPE_JOIN == gateway_recv_data->data_type) { |
|
|
|
LoraGatewayState = LORA_JOIN_NET; |
|
|
|
} else if (ADAPTER_LORA_DATA_TYPE_QUIT == gateway_recv_data->data_type) { |
|
|
|
LoraGatewayState = LORA_QUIT_NET; |
|
|
|
} else { |
|
|
|
ret = LoraGateWayDataAnalyze(lora_adapter, gateway_recv_data); |
|
|
|
if (ret < 0) { |
|
|
|
printf("LoraGateWayDataAnalyze error, re-send data cmd to client\n"); |
|
|
|
PrivTaskDelay(500); |
|
|
|
} |
|
|
|
} |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* @description: Lora Gateway Process function |
|
|
|
* @param lora_adapter Lora adapter pointer |
|
|
|
* @param gateway Lora gateway pointer |
|
|
|
*/ |
|
|
|
void LoraGatewayProcess(struct Adapter *lora_adapter, struct LoraGatewayParam *gateway) |
|
|
|
{ |
|
|
|
int i, ret = 0; |
|
|
|
|
|
|
|
#ifdef GATEWAY_CMD_MODE |
|
|
|
for (i = 0; i < gateway->client_num; i ++) { |
|
|
|
if (gateway->client_id[i]) { |
|
|
|
printf("LoraGatewayProcess send to client %d for data\n", gateway->client_id[i]); |
|
|
|
ret = LoraGatewaySendCmd(lora_adapter, gateway->client_id[i], ADAPTER_LORA_DATA_TYPE_CMD); |
|
|
|
if (ret < 0) { |
|
|
|
printf("LoraGatewaySendCmd client ID %d error\n", gateway->client_id[i]); |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
ret = PrivSemaphoreObtainWait(&gateway_recv_data_sem, NULL); |
|
|
|
if (0 == ret) { |
|
|
|
printf("LoraGatewayProcess receive client %d data done\n", gateway->client_id[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
return 0; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
@ -609,10 +713,16 @@ static void *LoraGatewayTask(void *parameter) |
|
|
|
int ret = 0; |
|
|
|
struct Adapter *lora_adapter = (struct Adapter *)parameter; |
|
|
|
struct LoraGatewayParam *gateway = (struct LoraGatewayParam *)lora_adapter->adapter_param; |
|
|
|
struct LoraDataFormat gateway_recv_data; |
|
|
|
|
|
|
|
memset(&gateway_recv_data_format, 0, sizeof(struct LoraDataFormat)); |
|
|
|
|
|
|
|
gateway->client_num = ADAPTER_LORA_CLIENT_NUM; |
|
|
|
for (i = 0; i < ADAPTER_LORA_CLIENT_NUM;i ++) { |
|
|
|
gateway->client_id[i] = i + 1; |
|
|
|
} |
|
|
|
|
|
|
|
while (1) { |
|
|
|
LoraGatewayProcess(lora_adapter, gateway, &gateway_recv_data); |
|
|
|
LoraGatewayProcess(lora_adapter, gateway); |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
@ -628,69 +738,36 @@ static void *LoraClientDataTask(void *parameter) |
|
|
|
struct Adapter *lora_adapter = (struct Adapter *)parameter; |
|
|
|
struct LoraClientParam *client = (struct LoraClientParam *)lora_adapter->adapter_param; |
|
|
|
|
|
|
|
for (i = 0; i < ADAPTER_LORA_CLIENT_NUM; i ++) { |
|
|
|
memset(&client_recv_data_format[i], 0, sizeof(struct LoraDataFormat)); |
|
|
|
} |
|
|
|
|
|
|
|
client->gateway_id = 0xFF; |
|
|
|
client->panid = ADAPTER_LORA_NET_PANID; |
|
|
|
client->client_state = CLIENT_CONNECT; |
|
|
|
|
|
|
|
//set lora_send_buf for test
|
|
|
|
uint8 lora_send_buf[ADAPTER_LORA_DATA_LENGTH]; |
|
|
|
uint8_t lora_send_buf[ADAPTER_LORA_DATA_LENGTH]; |
|
|
|
memset(lora_send_buf, 0, ADAPTER_LORA_DATA_LENGTH); |
|
|
|
sprintf(lora_send_buf, "Lora client %d adapter test\n", client->client_id); |
|
|
|
|
|
|
|
while (1) { |
|
|
|
|
|
|
|
PrivTaskDelay(100); |
|
|
|
|
|
|
|
if ((CLIENT_DISCONNECT == client->client_state) && (!g_adapter_lora_quit_flag)) { |
|
|
|
ret = LoraClientJoinNet(lora_adapter, client->panid); |
|
|
|
if (ret < 0) { |
|
|
|
printf("LoraClientJoinNet error panid 0x%x\n", client->panid); |
|
|
|
} |
|
|
|
|
|
|
|
ret = LoraClientDataAnalyze(lora_adapter, NULL, 0); |
|
|
|
if (ret < 0) { |
|
|
|
printf("LoraClientDataAnalyze error, reconnect to gateway\n"); |
|
|
|
PrivTaskDelay(500); |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (CLIENT_CONNECT == client->client_state) { |
|
|
|
ret = LoraClientDataAnalyze(lora_adapter, (void *)lora_send_buf, strlen(lora_send_buf)); |
|
|
|
if (ret < 0) { |
|
|
|
printf("LoraClientDataAnalyze error, wait for next data cmd\n"); |
|
|
|
PrivTaskDelay(500); |
|
|
|
continue; |
|
|
|
} |
|
|
|
//Condition 1: Gateway send user_data cmd, client send user_data after receiving user_data cmd
|
|
|
|
#ifdef GATEWAY_CMD_MODE |
|
|
|
ret = LoraClientDataAnalyze(lora_adapter, (void *)lora_send_buf, strlen(lora_send_buf), 0); |
|
|
|
if (ret < 0) { |
|
|
|
printf("LoraClientDataAnalyze error, wait for next data cmd\n"); |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* @description: Lora Client quit task |
|
|
|
* @param parameter - Lora adapter pointer |
|
|
|
*/ |
|
|
|
static void *LoraClientQuitTask(void *parameter) |
|
|
|
{ |
|
|
|
int ret = 0; |
|
|
|
struct Adapter *lora_adapter = (struct Adapter *)parameter; |
|
|
|
struct LoraClientParam *client = (struct LoraClientParam *)lora_adapter->adapter_param; |
|
|
|
|
|
|
|
while (1) { |
|
|
|
PrivTaskDelay(100); |
|
|
|
|
|
|
|
if ((CLIENT_CONNECT == client->client_state) && (g_adapter_lora_quit_flag)) { |
|
|
|
ret = LoraClientQuitNet(lora_adapter, client->panid); |
|
|
|
if (ret < 0) { |
|
|
|
printf("LoraClientQuitNet error panid 0x%x, re-quit net\n", client->panid); |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
ret = LoraClientDataAnalyze(lora_adapter, NULL, 0); |
|
|
|
if (ret < 0) { |
|
|
|
printf("LoraClientQuitTask LoraClientDataAnalyze error\n"); |
|
|
|
PrivTaskDelay(500); |
|
|
|
continue; |
|
|
|
} |
|
|
|
#endif |
|
|
|
//Condition 2: client send user_data automatically
|
|
|
|
#ifdef CLIENT_UPDATE_MODE |
|
|
|
if (lora_send_buf) { |
|
|
|
PrivTaskDelay(2000); |
|
|
|
printf("LoraClientSendData\n"); |
|
|
|
LoraClientSendData(lora_adapter, (void *)lora_send_buf, strlen(lora_send_buf), 0); |
|
|
|
} |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
@ -803,15 +880,22 @@ int AdapterLoraInit(void) |
|
|
|
adapter->done = product_info->model_done; |
|
|
|
#endif |
|
|
|
|
|
|
|
PrivSemaphoreCreate(&adapter->sem, 0, 0); |
|
|
|
|
|
|
|
PrivSemaphoreCreate(&gateway_recv_data_sem, 0, 0); |
|
|
|
|
|
|
|
PrivMutexCreate(&adapter->lock, 0); |
|
|
|
|
|
|
|
return ret; |
|
|
|
} |
|
|
|
|
|
|
|
/******************Lora TEST*********************/ |
|
|
|
static pthread_t lora_recv_data_task; |
|
|
|
|
|
|
|
#ifdef AS_LORA_GATEWAY_ROLE |
|
|
|
static pthread_t lora_gateway_task; |
|
|
|
#else //AS_LORA_CLIENT_ROLE
|
|
|
|
static pthread_t lora_client_data_task; |
|
|
|
static pthread_t lora_client_quit_task; |
|
|
|
#endif |
|
|
|
|
|
|
|
int AdapterLoraTest(void) |
|
|
@ -832,6 +916,15 @@ int AdapterLoraTest(void) |
|
|
|
lora_gateway_attr.stacksize = 2048; |
|
|
|
#endif |
|
|
|
|
|
|
|
PrivTaskCreate(&lora_recv_data_task, &lora_gateway_attr, &LoraReceiveTask, (void *)adapter); |
|
|
|
PrivTaskStartup(&lora_recv_data_task); |
|
|
|
|
|
|
|
#ifdef ADD_NUTTX_FETURES |
|
|
|
lora_gateway_attr.priority = 19; |
|
|
|
#else |
|
|
|
lora_gateway_attr.schedparam.sched_priority = 19; |
|
|
|
#endif |
|
|
|
|
|
|
|
PrivTaskCreate(&lora_gateway_task, &lora_gateway_attr, &LoraGatewayTask, (void *)adapter); |
|
|
|
PrivTaskStartup(&lora_gateway_task); |
|
|
|
|
|