forked from xuos/xiuos
Add LoRa module
This commit is contained in:
@@ -1,7 +1,13 @@
|
||||
menuconfig CONNECTION_COMMUNICATION_WIFI
|
||||
bool "Enable Wifi"
|
||||
default n
|
||||
|
||||
|
||||
menuconfig CONNECTION_COMMUNICATION_LORA
|
||||
bool "Enable LORA"
|
||||
default n
|
||||
if CONNECTION_COMMUNICATION_LORA
|
||||
source "$KERNEL_DIR/framework/connection/Adapter/lora/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig CONNECTION_COMMUNICATION_ETHERNET
|
||||
bool "Enable Ethernet"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
SRC_DIR := src
|
||||
|
||||
# ifeq ($(CONFIG_CONNECTION_COMMUNICATION_LORA), y)
|
||||
# SRC_DIR += lora
|
||||
# endif
|
||||
ifeq ($(CONFIG_CONNECTION_COMMUNICATION_LORA), y)
|
||||
SRC_DIR += lora
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CONNECTION_COMMUNICATION_ETHERNET), y)
|
||||
SRC_DIR += ethernet
|
||||
|
||||
184
framework/connection/Adapter/include/xs_adapter_lora.h
Normal file
184
framework/connection/Adapter/include/xs_adapter_lora.h
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file xs_adapterLora.h
|
||||
* @brief lora adhoc logic
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.04.22
|
||||
*/
|
||||
|
||||
#ifndef XS_ADAPTER_LORA_H
|
||||
#define XS_ADAPTER_LORA_H
|
||||
|
||||
#include "xs_adapter.h"
|
||||
|
||||
#define DEVNAME_LEN_MAX 32
|
||||
#define NETNAME_LEN_MAX 32
|
||||
#define CONNECTED_CLIENTS_MAX 512
|
||||
|
||||
#define CLIENT_SEND_CELL_LEN 120
|
||||
|
||||
|
||||
struct AdapterLora {
|
||||
struct Adapter parent; /* inherit from Adapter */
|
||||
const char * name; /* name of the adapter instance */
|
||||
|
||||
const char *deve_ui; /* Lora specific value */
|
||||
const char *app_key; /* Lora specific value */
|
||||
|
||||
int spi_lora_fd;
|
||||
};
|
||||
typedef struct AdapterLora *AdapterLoraT;
|
||||
|
||||
int LoraAdapterOpen(adapter_t padapter);
|
||||
void LoraAdapterCose(struct Adapter *padapter);
|
||||
int LoraAdapterSend(struct Adapter *padapter, const char* data, int len, bool block, int time_out, int delay, void *p);
|
||||
int LoraAdapterReceive(adapter_t padapter, char* rev_buffer, int buffer_len,int time_out, bool block, void *p);
|
||||
int LoraAdapterJoin(adapter_t sadapter, int dev_type, char* net_id);
|
||||
int LoraAdapterSendc2g(adapter_t padapter, const char *data, int len, bool block, int time_out, int delay, send_success cb, void* param, void *p);
|
||||
|
||||
// Client state machine
|
||||
enum LoraClientStatus
|
||||
{
|
||||
LORA_CLIENT_IDLE = 0,
|
||||
LORA_CLIENT_LOOKING4GATEWAY,
|
||||
LORA_CLIENT_CONNECTING2GATEWAY,
|
||||
LORA_CLIENT_CONNECTED,
|
||||
LORA_CLIENT_WAITTING_FOR_DISCONNECTED,
|
||||
LORA_CLIENT_DISCONNECTED,
|
||||
};
|
||||
|
||||
struct LoraClientStatusInfo
|
||||
{
|
||||
enum LoraClientStatus status;
|
||||
int user_id;
|
||||
char gateway_name[DEVNAME_LEN_MAX];
|
||||
char client_name[DEVNAME_LEN_MAX];
|
||||
};
|
||||
|
||||
enum LoraOpcode
|
||||
{
|
||||
LORA_OPCODE_START = 0xFFF0,
|
||||
LORA_JOIN_REQ = 0xFFF1,
|
||||
LORA_JOIN_RSP = 0xFFF2,
|
||||
LORA_HANDSHAKE_REQ = 0xFFF3,
|
||||
LORA_HANDSHAKE_RSP = 0xFFF4,
|
||||
LORA_C2G_DATA_REQ = 0xFFF5,
|
||||
LORA_C2G_DATA_RSP = 0xFFF6,
|
||||
LORA_CLOSE_REQ = 0xFFF7,
|
||||
LORA_CLOSE_RSP = 0xFFF8,
|
||||
LORA_OPCODE_END,
|
||||
};
|
||||
|
||||
enum WorkThreadStatus
|
||||
{
|
||||
WORK_THREAD_RX = 1,
|
||||
WORK_THREAD_TX,
|
||||
};
|
||||
|
||||
// pkg header
|
||||
typedef struct
|
||||
{
|
||||
int op_code;
|
||||
int length;
|
||||
}LoraHeader;
|
||||
|
||||
// Network access, handshake function protocol
|
||||
typedef struct
|
||||
{
|
||||
char net_id[NETNAME_LEN_MAX];
|
||||
}LoraProtoJoinReq;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char net_id[NETNAME_LEN_MAX];
|
||||
char gateway_name[DEVNAME_LEN_MAX];
|
||||
int signal_strength;
|
||||
int error_code;
|
||||
}LoraProtoJoinRsp;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char client_name[DEVNAME_LEN_MAX];
|
||||
char gateway_name[DEVNAME_LEN_MAX];
|
||||
}LoraProtoHandshakeReq;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char client_name[DEVNAME_LEN_MAX];
|
||||
char gateway_name[DEVNAME_LEN_MAX];
|
||||
int user_id;
|
||||
int error_code;
|
||||
}LoraProtoHandshakeRsp;
|
||||
|
||||
|
||||
// Data transmission protocol
|
||||
typedef struct
|
||||
{
|
||||
int user_id;
|
||||
int pkg_id;
|
||||
int data_len;
|
||||
int crc;
|
||||
}LoraProtoC2GDataReq;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int user_id;
|
||||
int ack_id;
|
||||
int data_len;
|
||||
int crc;
|
||||
}LoraProtoC2GDataRsp;
|
||||
|
||||
// Client active disconnect
|
||||
typedef struct
|
||||
{
|
||||
int user_id;
|
||||
}LoraProtoCloseReq;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int user_id;
|
||||
int error_code;
|
||||
}LoraProtoCloseRsp;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* data;
|
||||
int len;
|
||||
bool* prsp_flag;
|
||||
adapter_t padapter;
|
||||
}CheckRspParam;
|
||||
|
||||
typedef void(*send_success)(void* param);
|
||||
typedef struct
|
||||
{
|
||||
bool has_data;
|
||||
int crc;
|
||||
int pkg_id;
|
||||
char data[CLIENT_SEND_CELL_LEN];
|
||||
int data_len;
|
||||
send_success callback;
|
||||
void* param;
|
||||
}ClientSendCell;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char user_name[DEVNAME_LEN_MAX];
|
||||
int user_id;
|
||||
DoubleLinklistType link;
|
||||
}OnlineUser;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
30
framework/connection/Adapter/lora/Kconfig
Normal file
30
framework/connection/Adapter/lora/Kconfig
Normal file
@@ -0,0 +1,30 @@
|
||||
#LORA adhoc configuration
|
||||
#Set same netID, and then join one adhoc net.
|
||||
|
||||
menuconfig CONNECTION_COMMUNICATION_BOOTSTART_LORA_NET_SAMPLE
|
||||
bool "use bootstart lora net sample"
|
||||
default n
|
||||
|
||||
if CONNECTION_COMMUNICATION_BOOTSTART_LORA_NET_SAMPLE
|
||||
menuconfig CONNECTION_COMMUNICATION_SET_AS_LORA_CLIENT
|
||||
bool "set this as lora client "
|
||||
default n
|
||||
|
||||
if CONNECTION_COMMUNICATION_SET_AS_LORA_CLIENT
|
||||
config CONNECTION_COMMUNICATION_LORA_CLIENT_NAME
|
||||
string "config lora net client name"
|
||||
default "lora_client_name0"
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_CLIENT_PKG_COUNT
|
||||
int "config lora send pkg count"
|
||||
default 1000
|
||||
endif
|
||||
|
||||
menuconfig CONNECTION_COMMUNICATION_SET_AS_LORA_GATEWAY
|
||||
bool "set this as lora gateway"
|
||||
default n
|
||||
|
||||
config CONNECTION_COMMUNICATION_LORA_NET_ID
|
||||
string "config lora net ID"
|
||||
default "intelligence grain"
|
||||
endif
|
||||
3
framework/connection/Adapter/lora/Makefile
Normal file
3
framework/connection/Adapter/lora/Makefile
Normal file
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := xs_adapter_lora.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
849
framework/connection/Adapter/lora/xs_adapter_lora.c
Normal file
849
framework/connection/Adapter/lora/xs_adapter_lora.c
Normal file
@@ -0,0 +1,849 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file xs_AdapterLora.c
|
||||
* @brief lora adhoc logic
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021.04.22
|
||||
*/
|
||||
|
||||
#include <xs_adapter_lora.h>
|
||||
#include "spi_lora_sx12xx.h"
|
||||
#include "radio.h"
|
||||
#include "sx1276-LoRa.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <user_api.h>
|
||||
|
||||
#define SLEEP_MS 50
|
||||
|
||||
enum NetRoleType _role_type = ROLE_TYPE_NONE;
|
||||
|
||||
bool gateway_listening = false;
|
||||
bool client_work_thread_running = false;
|
||||
|
||||
char gateway_net_id[NETNAME_LEN_MAX];
|
||||
char client_net_id[NETNAME_LEN_MAX];
|
||||
|
||||
struct LoraClientStatusInfo g_client_status_info;
|
||||
int pkg_id_c2g;
|
||||
|
||||
#define BUFFER_LEN_MAX 120
|
||||
char rec_buffer[BUFFER_LEN_MAX] = {0};
|
||||
char client_rec_buffer[BUFFER_LEN_MAX] = {0};
|
||||
|
||||
char send_buffer[BUFFER_LEN_MAX] = {0};
|
||||
|
||||
DoubleLinklistType online_user_head = {&online_user_head, &online_user_head};
|
||||
|
||||
// Client send buffer. Only one element is set temporarily
|
||||
ClientSendCell client_send_buffer;
|
||||
int pclient_send_buffer_mutex = -1;
|
||||
enum WorkThreadStatus g_work_thread_status;
|
||||
bool need_send_data = false;
|
||||
|
||||
int32 ServerTask = NONE;
|
||||
int32 ClientTask = NONE;
|
||||
|
||||
static int spi_lora_fd_intern = -1;
|
||||
|
||||
extern tRadioDriver *Radio;
|
||||
|
||||
/**
|
||||
* @description: open lora adapter
|
||||
* @param padapter - lora adapter pointer
|
||||
*/
|
||||
int LoraAdapterOpen(adapter_t padapter)
|
||||
{
|
||||
int fd = ((AdapterLoraT)padapter)->spi_lora_fd;
|
||||
if (fd < 0){
|
||||
fd = open(LORA_SPI_NAME,O_RDWR);
|
||||
}
|
||||
|
||||
if(fd < 0){
|
||||
printf("LoRa check failed!\n!");
|
||||
return ERROR;
|
||||
} else {
|
||||
((AdapterLoraT)padapter)->spi_lora_fd = fd;
|
||||
spi_lora_fd_intern = fd;
|
||||
|
||||
memset(&g_client_status_info, 0, sizeof(g_client_status_info));
|
||||
g_client_status_info.status = LORA_CLIENT_IDLE;
|
||||
pkg_id_c2g = 1;
|
||||
_role_type = ROLE_TYPE_NONE;
|
||||
printf("LoRa check ok!\nNote: The length of the message that can be sent in a single time is 120 characters\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: close lora adapter
|
||||
* @param padapter - lora adapter pointer
|
||||
*/
|
||||
void LoraAdapterCose(struct Adapter *padapter)
|
||||
{
|
||||
if (((AdapterLoraT)padapter)->spi_lora_fd < 0){
|
||||
printf("LoRa device not found! close failed!\n");
|
||||
} else {
|
||||
// Disconnect
|
||||
int count = 10;
|
||||
g_client_status_info.status = LORA_CLIENT_WAITTING_FOR_DISCONNECTED;
|
||||
need_send_data = true;
|
||||
while (count > 0 && g_client_status_info.status == LORA_CLIENT_WAITTING_FOR_DISCONNECTED)
|
||||
{
|
||||
printf("lora client waitting for rsp, count(%d)\n", count);
|
||||
UserTaskDelay(1000);
|
||||
count--;
|
||||
}
|
||||
if (g_client_status_info.status != LORA_CLIENT_DISCONNECTED){
|
||||
printf("lora send close pkg failed!\n");
|
||||
}
|
||||
|
||||
gateway_listening = false;
|
||||
client_work_thread_running = false;
|
||||
|
||||
// Release thread
|
||||
if (NONE != ServerTask){
|
||||
UserTaskDelete(ServerTask);
|
||||
ServerTask = NONE;
|
||||
}
|
||||
|
||||
if (NONE != ClientTask){
|
||||
UserTaskDelete(ClientTask);
|
||||
ClientTask = NONE;
|
||||
}
|
||||
|
||||
// Release the lock
|
||||
if (pclient_send_buffer_mutex != NONE) {
|
||||
UserMutexDelete(pclient_send_buffer_mutex);
|
||||
pclient_send_buffer_mutex = NONE;
|
||||
}
|
||||
|
||||
// Driver
|
||||
((AdapterLoraT)padapter)->spi_lora_fd = NONE;
|
||||
}
|
||||
}
|
||||
|
||||
bool lora_channel_avtive()
|
||||
{
|
||||
return Radio->ChannelEmpty() == 0;
|
||||
}
|
||||
|
||||
int LoraAdapterSend(struct Adapter *padapter, const char *data, int len, bool block, int time_out, int delay, void *p)
|
||||
{
|
||||
if (len > 120){
|
||||
printf("ERROR:The message is too long!\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (((AdapterLoraT)padapter)->spi_lora_fd == NONE){
|
||||
printf("LoRa device not found!\n");
|
||||
return ERROR;
|
||||
} else {
|
||||
int time_counter = 0;
|
||||
int time_sleep_gap = 500;
|
||||
while (false == lora_channel_avtive()) {
|
||||
|
||||
if (time_counter * time_sleep_gap > time_out) {
|
||||
printf("LoRa_adapter_send failed! time_out!\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
|
||||
UserTaskDelay(time_sleep_gap);
|
||||
time_counter++;
|
||||
}
|
||||
|
||||
char Msg[120] = {0};
|
||||
memcpy(Msg, data, len);
|
||||
|
||||
Radio->SetTxPacket(Msg, len);
|
||||
while (Radio->Process() != RF_TX_DONE)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
int lora_send(const char *data, int len)
|
||||
{
|
||||
if (len > 120) {
|
||||
printf("ERROR:The message is too long!\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
int time_counter = 0;
|
||||
int time_sleep_gap = 500;
|
||||
int time_out = 10000;
|
||||
while (false == lora_channel_avtive()) {
|
||||
if (time_counter * time_sleep_gap > time_out) {
|
||||
printf("LoRa send failed! time_out!\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
UserTaskDelay(time_sleep_gap);
|
||||
time_counter++;
|
||||
}
|
||||
|
||||
char Msg[120] = {0};
|
||||
memcpy(Msg, data, len);
|
||||
|
||||
Radio->SetTxPacket(Msg, len);
|
||||
while (Radio->Process() != RF_TX_DONE)
|
||||
;
|
||||
}
|
||||
|
||||
int LoraAdapterSendc2g(adapter_t padapter, const char *data, int len, bool block, int time_out, int delay, send_success cb, void *param, void *p)
|
||||
{
|
||||
if (_role_type == ROLE_TYPE_SLAVE && g_client_status_info.status == LORA_CLIENT_CONNECTED) {
|
||||
LoraHeader header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
header.op_code = LORA_C2G_DATA_REQ;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoC2GDataReq) + len;
|
||||
|
||||
if (header.length > 120) {
|
||||
printf("Send failed, LoRa send max length is 120.\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (client_send_buffer.has_data == true){
|
||||
printf("Send failed, last pakage is resending\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
LoraProtoC2GDataReq req;
|
||||
req.user_id = g_client_status_info.user_id;
|
||||
req.pkg_id = pkg_id_c2g;
|
||||
req.data_len = len;
|
||||
req.crc = 0xFFFF;
|
||||
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &req, sizeof(req));
|
||||
memcpy(send_buffer + sizeof(header) + sizeof(req), data, len);
|
||||
|
||||
// Write data to buffer (lock)
|
||||
UserMutexObtain(pclient_send_buffer_mutex, WAITING_FOREVER);
|
||||
client_send_buffer.has_data = true;
|
||||
client_send_buffer.pkg_id = pkg_id_c2g;
|
||||
client_send_buffer.crc = 0xFFFF;
|
||||
memcpy(client_send_buffer.data, send_buffer, header.length);
|
||||
client_send_buffer.data_len = header.length;
|
||||
client_send_buffer.callback = cb;
|
||||
client_send_buffer.param = param;
|
||||
|
||||
UserMutexAbandon(pclient_send_buffer_mutex);
|
||||
// printf("copy to send buffer. len = %d\n", header.length);
|
||||
|
||||
// Switch worker thread state
|
||||
need_send_data = true;
|
||||
return ERROR;
|
||||
} else {
|
||||
printf("LoRa client is unconnected! can not send data!\n");
|
||||
}
|
||||
}
|
||||
|
||||
OnlineUser *find_user_by_name(char *name)
|
||||
{
|
||||
DoubleLinklistType *pLink;
|
||||
DOUBLE_LINKLIST_FOR_EACH(pLink, &online_user_head)
|
||||
{
|
||||
OnlineUser *pUer =CONTAINER_OF(pLink, OnlineUser, link);
|
||||
if (strcmp(pUer->user_name, name) == 0) {
|
||||
return pUer;
|
||||
}
|
||||
}
|
||||
return NONE;
|
||||
}
|
||||
|
||||
OnlineUser *find_user_by_id(int id)
|
||||
{
|
||||
DoubleLinklistType *pLink;
|
||||
DOUBLE_LINKLIST_FOR_EACH(pLink, &online_user_head)
|
||||
{
|
||||
OnlineUser *pUer =CONTAINER_OF(pLink, OnlineUser, link);
|
||||
if (pUer->user_id == id) {
|
||||
return pUer;
|
||||
}
|
||||
}
|
||||
return NONE;
|
||||
}
|
||||
|
||||
int insert_connected_clients(char *name, int user_id)
|
||||
{
|
||||
OnlineUser *pUser = malloc(sizeof(OnlineUser));
|
||||
if (NONE == pUser)
|
||||
return ERROR;
|
||||
|
||||
pUser->user_id = user_id;
|
||||
strcpy(pUser->user_name, name);
|
||||
DoubleLinkListInsertNodeAfter(&online_user_head, &pUser->link);
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void CheckSendBuffer()
|
||||
{
|
||||
UserMutexObtain(pclient_send_buffer_mutex, WAITING_FOREVER);
|
||||
if (client_send_buffer.has_data == true)
|
||||
{
|
||||
//Sending or packet loss retransmission
|
||||
lora_send(client_send_buffer.data, client_send_buffer.data_len);
|
||||
// printf("client check and send. len = %d\n", client_send_buffer.data_len);
|
||||
}
|
||||
UserMutexAbandon(pclient_send_buffer_mutex);
|
||||
}
|
||||
|
||||
int LoraAdapterReceive(adapter_t padapter, char *rev_buffer, int buffer_len, int time_out, bool block, void *p)
|
||||
{
|
||||
uint16 BufferSize = buffer_len;
|
||||
|
||||
memset(rev_buffer, 0, buffer_len);
|
||||
|
||||
if (((AdapterLoraT)padapter)->spi_lora_fd == NONE)
|
||||
{
|
||||
printf("LoRa device not found!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Radio->StartRx();
|
||||
printf("Ready!\n");
|
||||
|
||||
while (Radio->Process() != RF_RX_DONE)
|
||||
{
|
||||
// if (time_out < 0)
|
||||
// {
|
||||
// printf("LoRa device receive failed! Timeout!\n");
|
||||
// return ERROR;
|
||||
// }
|
||||
// UserTaskDelay(SLEEP_MS);
|
||||
// time_out -= SLEEP_MS;
|
||||
}
|
||||
|
||||
Radio->GetRxPacket(rev_buffer, (uint16 *)&BufferSize);
|
||||
if (BufferSize == buffer_len)
|
||||
{
|
||||
printf("rev_buffer is too small!\n");
|
||||
}
|
||||
|
||||
printf("RX : %s\n", rev_buffer);
|
||||
return BufferSize;
|
||||
}
|
||||
}
|
||||
|
||||
int LoraGatewayProcess(adapter_t padapter, char *pkg, int rec_len)
|
||||
{
|
||||
struct AdapterLora* lora_adapter = (struct AdapterLora*)padapter;
|
||||
|
||||
if (rec_len > 0)
|
||||
{
|
||||
LoraHeader header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
char *start = (char *)pkg;
|
||||
LoraHeader *pheader = (LoraHeader *)start;
|
||||
|
||||
char *req = start + sizeof(LoraHeader);
|
||||
|
||||
if (pheader->op_code < LORA_OPCODE_START || pheader->op_code > LORA_OPCODE_END)
|
||||
{
|
||||
printf("Illegal opcode, discard data!\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if (rec_len != pheader->length)
|
||||
{
|
||||
printf("pkg is not complete!, discard data!\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
printf("gateway receive pkg opcode(%4x)\n", pheader->op_code);
|
||||
switch (pheader->op_code)
|
||||
{
|
||||
case LORA_JOIN_REQ: // There is a client request to join the network segment
|
||||
if (strcmp(((LoraProtoJoinReq *)req)->net_id, gateway_net_id) == 0) // The request is really this network segment
|
||||
{
|
||||
LoraProtoJoinReq *req = (LoraProtoJoinReq *)(start + sizeof(LoraHeader));
|
||||
|
||||
header.op_code = LORA_JOIN_RSP;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoJoinRsp);
|
||||
|
||||
LoraProtoJoinRsp rsp;
|
||||
memset(&rsp, 0, sizeof(rsp));
|
||||
rsp.error_code = 0;
|
||||
rsp.signal_strength = 0; // signal intensity
|
||||
|
||||
printf(" 11aa strlen(lora_adapter->name) = %d\n", strlen(lora_adapter->name));
|
||||
printf(" 11aa lora_adapter->name = %s\n", lora_adapter->name);
|
||||
|
||||
strcpy(rsp.gateway_name, lora_adapter->name);
|
||||
strcpy(rsp.net_id, gateway_net_id);
|
||||
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &rsp, sizeof(rsp));
|
||||
|
||||
printf("LoraProtoJoinRsp rsp.gateway_name = %s rsp.net_id = %s\n", rsp.gateway_name, rsp.net_id);
|
||||
lora_send(send_buffer, header.length);
|
||||
printf("gateway send pkg opcode(%4x)\n", header.op_code);
|
||||
}
|
||||
break;
|
||||
case LORA_HANDSHAKE_REQ:
|
||||
if (strcmp(((LoraProtoHandshakeReq *)req)->gateway_name, lora_adapter->name) == 0) //The other party really wants to connect themselves
|
||||
{
|
||||
// Construction reply, connection confirmation
|
||||
LoraProtoHandshakeReq *req = (LoraProtoHandshakeReq *)(start + sizeof(LoraHeader));
|
||||
int user_id = 0;
|
||||
// If it can be found, it will prove that it is connected. It may be packet loss, so normal retransmission is good
|
||||
OnlineUser *pUser = find_user_by_name(req->client_name);
|
||||
if (NONE == pUser)
|
||||
{
|
||||
// New virtual connection
|
||||
user_id = rand() % UINT32_SIZE_MAX;
|
||||
if (ERROR == insert_connected_clients(req->client_name, user_id))
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Packet loss
|
||||
user_id = pUser->user_id;
|
||||
}
|
||||
|
||||
header.op_code = LORA_HANDSHAKE_RSP;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoHandshakeRsp);
|
||||
|
||||
LoraProtoHandshakeRsp rsp;
|
||||
memset(&rsp, 0, sizeof(rsp));
|
||||
strcpy(rsp.client_name, req->client_name);
|
||||
strcpy(rsp.gateway_name, req->gateway_name);
|
||||
rsp.user_id = user_id;
|
||||
rsp.error_code = 0;
|
||||
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &rsp, sizeof(rsp));
|
||||
|
||||
printf("LoraProtoHandshakeRsp, rsp.client_name = %s, rsp.gateway_name = %s\n", rsp.client_name, rsp.gateway_name);
|
||||
lora_send(send_buffer, header.length);
|
||||
printf("gateway send pkg opcode(%4x)\n", header.op_code);
|
||||
}
|
||||
break;
|
||||
case LORA_C2G_DATA_REQ:
|
||||
{
|
||||
OnlineUser *pUser = find_user_by_id(((LoraProtoC2GDataReq *)req)->user_id);
|
||||
if (pUser) //What the other party wants to send is really himself
|
||||
{
|
||||
LoraProtoC2GDataReq *req = (LoraProtoC2GDataReq *)(start + sizeof(LoraHeader));
|
||||
|
||||
char *data = start + sizeof(LoraHeader) + sizeof(LoraProtoC2GDataReq);
|
||||
// printf("receive data from client(%s), content(%s)", pUser->user_name, data);
|
||||
printf(" receive data from \033[0;31m client(%s)\033[0m \n, content(%s). ", pUser->user_name, data);
|
||||
// Logic layer to deal with
|
||||
|
||||
// CRC calculation for data and reply to client
|
||||
header.op_code = LORA_C2G_DATA_RSP;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoC2GDataRsp);
|
||||
|
||||
LoraProtoC2GDataRsp rsp;
|
||||
memset(&rsp, 0, sizeof(rsp));
|
||||
rsp.user_id = req->user_id;
|
||||
rsp.crc = 0xFFFF;
|
||||
rsp.data_len = rec_len;
|
||||
rsp.ack_id = req->pkg_id;
|
||||
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &rsp, sizeof(rsp));
|
||||
|
||||
lora_send(send_buffer, header.length);
|
||||
printf("gateway send pkg opcode(%4x), ack_id(%d)\n", header.op_code, rsp.ack_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("user unconnected, discard data.\n");
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case LORA_CLOSE_REQ:
|
||||
{
|
||||
LoraProtoCloseReq *req = (LoraProtoCloseReq *)(start + sizeof(LoraHeader));
|
||||
|
||||
//log
|
||||
DoubleLinklistType *pNode;
|
||||
printf("******** connected users *********\n");
|
||||
DOUBLE_LINKLIST_FOR_EACH(pNode, &online_user_head)
|
||||
{
|
||||
OnlineUser *pUser =CONTAINER_OF(pNode, OnlineUser, link);
|
||||
printf("pUser->user_name %s\n", pUser->user_name);
|
||||
printf("pUser->user_id %d\n", pUser->user_id);
|
||||
}
|
||||
printf("*********************************\n");
|
||||
|
||||
printf("req->user_id = %d\n", req->user_id);
|
||||
|
||||
OnlineUser *pUser = find_user_by_id(req->user_id);
|
||||
if (pUser)
|
||||
{
|
||||
DoubleLinkListRmNode(&pUser->link);
|
||||
|
||||
header.op_code = LORA_CLOSE_RSP;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoCloseRsp);
|
||||
LoraProtoCloseRsp rsp;
|
||||
rsp.error_code = 0;
|
||||
rsp.user_id = req->user_id;
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &rsp, sizeof(rsp));
|
||||
|
||||
lora_send(send_buffer, header.length);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("find user failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gateway receives requests from clients in a loop
|
||||
static void LoraGateWayListen(void *parameter)
|
||||
{
|
||||
// adapter_t padapter = (adapter_t)malloc(sizeof(struct Adapter));
|
||||
adapter_t padapter = parameter;
|
||||
|
||||
while (gateway_listening)
|
||||
{
|
||||
printf("444x(0x%x), %d, %d \n", ((AdapterLoraT)padapter)->spi_lora_fd, sizeof(rec_buffer), BUFFER_LEN_MAX);
|
||||
|
||||
int rec_len = LoraAdapterReceive(padapter, rec_buffer, BUFFER_LEN_MAX, 10000, true, NULL);
|
||||
UserTaskDelay(50); //Afraid the other party hasn't entered reception mode yet
|
||||
LoraGatewayProcess(padapter, rec_buffer, rec_len);
|
||||
}
|
||||
}
|
||||
|
||||
// All client packets received are processed here
|
||||
int LoraClientProcess(adapter_t padapter, char *pkg, int pkg_len)
|
||||
{
|
||||
struct AdapterLora* lora_adapter = (struct AdapterLora*)padapter;
|
||||
|
||||
LoraHeader *pheader = (LoraHeader *)pkg;
|
||||
|
||||
LoraHeader header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
|
||||
char *data_start = pkg + sizeof(LoraHeader);
|
||||
|
||||
switch (pheader->op_code)
|
||||
{
|
||||
case LORA_JOIN_RSP:
|
||||
if (g_client_status_info.status == LORA_CLIENT_LOOKING4GATEWAY)
|
||||
{
|
||||
LoraProtoJoinRsp *data = (LoraProtoJoinRsp *)data_start;
|
||||
|
||||
if (strcmp(data->net_id, client_net_id) != 0)
|
||||
break;
|
||||
|
||||
strcpy(g_client_status_info.gateway_name, data->gateway_name);
|
||||
strcpy(g_client_status_info.client_name, lora_adapter->name);
|
||||
g_client_status_info.status = LORA_CLIENT_CONNECTING2GATEWAY;
|
||||
break;
|
||||
}
|
||||
case LORA_HANDSHAKE_RSP:
|
||||
if (strcmp(((LoraProtoHandshakeRsp *)data_start)->client_name, lora_adapter->name) == 0) // Confirm that it was sent to yourself
|
||||
{
|
||||
LoraProtoHandshakeRsp *data = (LoraProtoHandshakeRsp *)data_start;
|
||||
printf("get LoraProtoHandshakeRsp data->client_name = %s, data->gateway_name = %s\n", data->client_name, data->gateway_name);
|
||||
// Confirm the connection and record the status information
|
||||
g_client_status_info.status = LORA_CLIENT_CONNECTED;
|
||||
g_client_status_info.user_id = data->user_id;
|
||||
|
||||
strcpy(g_client_status_info.gateway_name, data->gateway_name);
|
||||
|
||||
printf("client is connected to gateway(%s)\n", g_client_status_info.gateway_name);
|
||||
}
|
||||
break;
|
||||
|
||||
case LORA_C2G_DATA_RSP:
|
||||
if (((LoraProtoC2GDataRsp *)data_start)->user_id == g_client_status_info.user_id) // Confirm that it was sent to yourself
|
||||
{
|
||||
LoraProtoC2GDataRsp *data = (LoraProtoC2GDataRsp *)data_start;
|
||||
|
||||
UserMutexObtain(pclient_send_buffer_mutex, WAITING_FOREVER);
|
||||
if (data->ack_id == client_send_buffer.pkg_id)
|
||||
{
|
||||
if (data->crc == client_send_buffer.crc)
|
||||
{
|
||||
// Send successfully, execute external callback
|
||||
if (client_send_buffer.callback)
|
||||
{
|
||||
client_send_buffer.callback(client_send_buffer.param);
|
||||
}
|
||||
|
||||
//Reset buffer
|
||||
memset(&client_send_buffer, 0, sizeof(client_send_buffer));
|
||||
client_send_buffer.has_data = false;
|
||||
// printf("pkg_id(%d) get ack. send success. send buffer clear.\n", data->ack_id);
|
||||
|
||||
pkg_id_c2g++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Then do nothing and wait for the retransmission
|
||||
printf("client send failed.crc check failed.\n");
|
||||
}
|
||||
}
|
||||
UserMutexAbandon(pclient_send_buffer_mutex);
|
||||
}
|
||||
break;
|
||||
|
||||
case LORA_CLOSE_RSP:
|
||||
{
|
||||
LoraProtoCloseRsp *rsp = (LoraProtoCloseRsp *)data_start;
|
||||
printf("case LORA_CLOSE_RSP rsp->user_id(%d)\n", rsp->user_id);
|
||||
printf("case LORA_CLOSE_RSP g_client_status_info.user_id(%d)\n", g_client_status_info.user_id);
|
||||
|
||||
if (rsp->user_id == g_client_status_info.user_id)
|
||||
{
|
||||
g_client_status_info.status = LORA_CLIENT_DISCONNECTED;
|
||||
printf("client close success.\n");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// The client requests the gateway to disconnect
|
||||
int SendCloseReq()
|
||||
{
|
||||
LoraHeader header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
header.op_code = LORA_CLOSE_REQ;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoCloseReq);
|
||||
|
||||
LoraProtoCloseReq req;
|
||||
req.user_id = g_client_status_info.user_id;
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &req, sizeof(req));
|
||||
printf("client send close req");
|
||||
lora_send(send_buffer, header.length);
|
||||
}
|
||||
|
||||
// The client broadcasts the name of the network segment that it wants to join
|
||||
int SendJoinReq(char *net_id)
|
||||
{
|
||||
LoraHeader header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
header.op_code = LORA_JOIN_REQ;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoJoinReq);
|
||||
|
||||
LoraProtoJoinReq req;
|
||||
memcpy(req.net_id, net_id, strlen(net_id) + 1);
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &req, sizeof(req));
|
||||
|
||||
lora_send(send_buffer, header.length);
|
||||
}
|
||||
|
||||
// Client requests connection from gateway
|
||||
int SendHandShakeReq(char *client_name, char *gateway_name)
|
||||
{
|
||||
LoraHeader header;
|
||||
header.op_code = LORA_HANDSHAKE_REQ;
|
||||
header.length = sizeof(LoraHeader) + sizeof(LoraProtoHandshakeReq);
|
||||
|
||||
LoraProtoHandshakeReq req;
|
||||
memset(&req, 0, sizeof(req));
|
||||
strcpy(req.client_name, client_name);
|
||||
strcpy(req.gateway_name, gateway_name);
|
||||
|
||||
memcpy(send_buffer, &header, sizeof(header));
|
||||
memcpy(send_buffer + sizeof(header), &req, sizeof(req));
|
||||
|
||||
printf("LoraProtoHandshakeReq, req.client_name = %s req.gateway_name = %s\n", req.client_name, req.gateway_name);
|
||||
lora_send(send_buffer, header.length);
|
||||
}
|
||||
|
||||
void work_thread_process(adapter_t padapter)
|
||||
{
|
||||
if (g_work_thread_status == WORK_THREAD_RX)
|
||||
{
|
||||
// printf("client start receiving \n");
|
||||
uint16 len;
|
||||
int counter = 0;
|
||||
Radio->StartRx();
|
||||
while (Radio->Process() != RF_RX_DONE)
|
||||
{
|
||||
// Receive external signal, check buffer
|
||||
if (need_send_data)
|
||||
{
|
||||
g_work_thread_status = WORK_THREAD_TX;
|
||||
need_send_data = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//Jump out of the monitoring cycle regularly to see if there is anything that needs to be retransmitted
|
||||
if (counter > 100000)
|
||||
{
|
||||
if (g_client_status_info.status == LORA_CLIENT_CONNECTED)
|
||||
{
|
||||
//printf("check send buffer.\n");
|
||||
}
|
||||
if (g_client_status_info.status >= LORA_CLIENT_LOOKING4GATEWAY &&
|
||||
g_client_status_info.status <= LORA_CLIENT_CONNECTING2GATEWAY)
|
||||
{
|
||||
printf("retry to handshake.\n");
|
||||
}
|
||||
g_work_thread_status = WORK_THREAD_TX;
|
||||
// printf("client end receiving.\n");
|
||||
return;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
enum LoraClientStatus old = g_client_status_info.status;
|
||||
Radio->GetRxPacket(rec_buffer, (uint16 *)&len);
|
||||
LoraClientProcess(padapter, rec_buffer, len);
|
||||
|
||||
//If the client state machine changes, there is something to send to the other party, and it will be switched to the sending mode immediately
|
||||
if (old != g_client_status_info.status)
|
||||
{
|
||||
g_work_thread_status = WORK_THREAD_TX;
|
||||
UserTaskDelay(50); //Afraid the other party hasn't entered reception mode yet
|
||||
}
|
||||
}
|
||||
else if (g_work_thread_status == WORK_THREAD_TX)
|
||||
{
|
||||
// Temporarily designed not to be interrupted
|
||||
switch (g_client_status_info.status)
|
||||
{
|
||||
case LORA_CLIENT_LOOKING4GATEWAY:
|
||||
SendJoinReq(client_net_id);
|
||||
break;
|
||||
case LORA_CLIENT_CONNECTING2GATEWAY:
|
||||
SendHandShakeReq(g_client_status_info.client_name, g_client_status_info.gateway_name);
|
||||
break;
|
||||
case LORA_CLIENT_CONNECTED:
|
||||
CheckSendBuffer();
|
||||
break;
|
||||
case LORA_CLIENT_WAITTING_FOR_DISCONNECTED:
|
||||
SendCloseReq(g_client_status_info.user_id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
g_work_thread_status = WORK_THREAD_RX;
|
||||
}
|
||||
}
|
||||
|
||||
void static work_thread_func(void *parameter)
|
||||
{
|
||||
adapter_t padapter = (adapter_t)parameter;
|
||||
while (client_work_thread_running)
|
||||
{
|
||||
work_thread_process(padapter);
|
||||
}
|
||||
}
|
||||
int LoraAdapterJoin(adapter_t padapter, int net_role_type, char *net_id)
|
||||
{
|
||||
UtaskType lora_utask_master;
|
||||
UtaskType lora_utask_slave;
|
||||
do
|
||||
{
|
||||
_role_type = net_role_type;
|
||||
x_err_t err;
|
||||
if (_role_type == ROLE_TYPE_MASTER)
|
||||
{
|
||||
strcpy(gateway_net_id, net_id);
|
||||
|
||||
//Single child thread gateway loop monitoring req
|
||||
gateway_listening = true;
|
||||
printf("GateWayListen thread create...");
|
||||
|
||||
strncpy(lora_utask_master.name,"GateWayListen",strlen("GateWayListen"));
|
||||
lora_utask_master.func_entry = LoraGateWayListen;
|
||||
lora_utask_master.func_param = padapter;
|
||||
lora_utask_master.prio = 10;
|
||||
lora_utask_master.stack_size = 2048;
|
||||
|
||||
ServerTask = UserTaskCreate(lora_utask_master);
|
||||
err = UserTaskStartup(ServerTask);
|
||||
if (err != EOK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (_role_type == ROLE_TYPE_SLAVE)
|
||||
{
|
||||
strcpy(client_net_id, net_id);
|
||||
|
||||
// Create lock
|
||||
if (pclient_send_buffer_mutex < 0)
|
||||
{
|
||||
pclient_send_buffer_mutex = UserMutexCreate();
|
||||
}
|
||||
|
||||
// Update state machine
|
||||
g_client_status_info.status = LORA_CLIENT_LOOKING4GATEWAY;
|
||||
|
||||
// Start single child thread client loop to listen for RSP
|
||||
client_send_buffer.has_data = false;
|
||||
memset(&client_send_buffer, 0, sizeof(client_send_buffer));
|
||||
client_work_thread_running = true;
|
||||
g_work_thread_status = WORK_THREAD_TX;
|
||||
|
||||
strncpy(lora_utask_slave.name,"ClientWorkThread",strlen("ClientWorkThread"));
|
||||
lora_utask_slave.func_entry = work_thread_func;
|
||||
lora_utask_slave.func_param = padapter;
|
||||
lora_utask_slave.prio = 10;
|
||||
lora_utask_slave.stack_size = 2048;
|
||||
|
||||
ClientTask = UserTaskCreate(lora_utask_slave);
|
||||
|
||||
err = UserTaskStartup(ClientTask);
|
||||
if (err != EOK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
// Block detection for a period of time
|
||||
int counter = 100;
|
||||
while (counter > 0)
|
||||
{
|
||||
if (g_client_status_info.status == LORA_CLIENT_CONNECTED)
|
||||
{
|
||||
break; // Successful connection
|
||||
}
|
||||
else
|
||||
{
|
||||
UserTaskDelay(300);
|
||||
}
|
||||
counter--;
|
||||
}
|
||||
return (counter > 0) ? 0 : ERROR;
|
||||
}
|
||||
return EOK;
|
||||
} while (false);
|
||||
|
||||
// Exception handling, releasing resources
|
||||
LoraAdapterCose(padapter);
|
||||
return ERROR;
|
||||
}
|
||||
@@ -26,6 +26,9 @@
|
||||
#ifdef CONNECTION_COMMUNICATION_ZIGBEE
|
||||
#include <xs_adapter_zigbee.h>
|
||||
#endif
|
||||
#ifdef CONNECTION_COMMUNICATION_LORA
|
||||
#include <xs_adapter_lora.h>
|
||||
#endif
|
||||
|
||||
|
||||
// Zigbee Adapter List
|
||||
@@ -48,8 +51,7 @@ void* ZigbeeAdapterFind(char* name)
|
||||
DoubleLinklistType* phead = &zigbee_adapter_list;
|
||||
struct AdapterZigbee* padapter = NONE;
|
||||
|
||||
for(pnode = phead->node_next; pnode != phead; pnode = pnode->node_next)
|
||||
{
|
||||
for(pnode = phead->node_next; pnode != phead; pnode = pnode->node_next) {
|
||||
padapter = (struct AdapterZigbee*)SYS_DOUBLE_LINKLIST_ENTRY(pnode, struct Adapter, link);
|
||||
// KPrintf("ZigbeeReceiveDemo bbb\n");
|
||||
if (0 == strcmp(padapter->name, name)){
|
||||
@@ -61,7 +63,37 @@ void* ZigbeeAdapterFind(char* name)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Lora Adapter List
|
||||
#ifdef CONNECTION_COMMUNICATION_LORA
|
||||
static DoubleLinklistType lora_adapter_list;
|
||||
|
||||
void LoraAdapterInit()
|
||||
{
|
||||
InitDoubleLinkList(&lora_adapter_list);
|
||||
}
|
||||
|
||||
void LoraAdapterRegister(adapter_t padapter)
|
||||
{
|
||||
DoubleLinkListInsertNodeAfter(&lora_adapter_list, &(padapter->link));
|
||||
}
|
||||
|
||||
void* LoraAdapterFind(char* name)
|
||||
{
|
||||
DoubleLinklistType* pnode = NONE;
|
||||
DoubleLinklistType* phead = &lora_adapter_list;
|
||||
struct AdapterLora* padapter = NONE;
|
||||
|
||||
for(pnode = phead->node_next; pnode != phead; pnode = pnode->node_next) {
|
||||
padapter = (struct AdapterLora*)SYS_DOUBLE_LINKLIST_ENTRY(pnode, struct Adapter, link);
|
||||
|
||||
if (0 == strcmp(padapter->name, name)) {
|
||||
return padapter;
|
||||
}
|
||||
}
|
||||
|
||||
return padapter;
|
||||
}
|
||||
#endif
|
||||
|
||||
// AT Adapter List
|
||||
static DoubleLinklistType at_adapter_list;
|
||||
@@ -86,8 +118,7 @@ void* ATAdapterFind(uint32 adapter_id)
|
||||
struct AdapterAT* padapter = NONE;
|
||||
|
||||
|
||||
for(pnode = phead->node_next; pnode != phead; pnode = pnode->node_next)
|
||||
{
|
||||
for(pnode = phead->node_next; pnode != phead; pnode = pnode->node_next) {
|
||||
padapter = (struct AdapterAT*)SYS_DOUBLE_LINKLIST_ENTRY(pnode, struct AdapterAT, link);
|
||||
|
||||
if (padapter->at_adapter_id == adapter_id){
|
||||
|
||||
Reference in New Issue
Block a user