Adjust directory structure

This commit is contained in:
Zhao_Jiasheng
2021-06-03 17:38:11 +08:00
parent 92301257f3
commit 89a2236b18
1993 changed files with 40 additions and 0 deletions
@@ -0,0 +1,31 @@
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"
default n
menuconfig CONNECTION_COMMUNICATION_ZIGBEE
bool "Enable Zigbee"
default n
menuconfig CONNECTION_COMMUNICATION_NB_IOT
bool "Enable NB-IOT"
default n
menuconfig CONNECTION_COMMUNICATION_4G
bool "Enable 4G"
default n
menuconfig CONNECTION_COMMUNICATION_BLUETOOTH
bool "Enable BlueTooth"
default n
@@ -0,0 +1,32 @@
SRC_DIR := src
ifeq ($(CONFIG_CONNECTION_COMMUNICATION_LORA), y)
SRC_DIR += lora
endif
ifeq ($(CONFIG_CONNECTION_COMMUNICATION_ETHERNET), y)
SRC_DIR += ethernet
endif
ifeq ($(CONFIG_CONNECTION_COMMUNICATION_WIFI), y)
SRC_DIR += wifi
endif
ifeq ($(CONFIG_CONNECTION_COMMUNICATION_ZIGBEE), y)
SRC_DIR += zigbee
endif
ifeq ($(CONFIG_CONNECTION_COMMUNICATION_NB_IOT), y)
SRC_DIR += nbiot
endif
# ifeq ($(CONFIG_CONNECTION_COMMUNICATION_4G), y)
# SRC_DIR += 4G
# endif
ifeq ($(CONFIG_CONNECTION_COMMUNICATION_BLUETOOTH), y)
SRC_DIR += bluetooth
endif
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,3 @@
SRC_FILES := xs_adapter_bluetooth.c xs_adaper_bluetooth_register.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,45 @@
/*
* 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_AdaperBluetooth_register.c
* @brief: register Bluetooth in initialization
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2021/4/30
*
*/
#include <xs_adapter_bluetooth.h>
#include <xs_adapter_manager.h>
#include <string.h>
/* initialize to the register list*/
int RegisterAdapterBluetooth(void)
{
static struct AdapterBluetooth bluetooth_adapter;
memset(&bluetooth_adapter, 0, sizeof(bluetooth_adapter));
static struct AdapterDone bluetooth_send_done = {
.NetAiitOpen = BluetoothOpen,
.NetAiitClose = BluetoothClose,
.NetAiitSend = BluetoothSend,
.NetAiitReceive = BluetoothReceive,
.NetAiitJoin = NULL,
.NetAiitIoctl = NULL,
};
bluetooth_adapter.parent.done = bluetooth_send_done;
bluetooth_adapter.name = "Bluetooth";
BluetoothAdapterInit();
BluetoothAdapterRegister((adapter_t)&bluetooth_adapter);
return EOK;
}
@@ -0,0 +1,155 @@
/*
* 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_Adapterxs_adapter_bluetooth.c
* @brief: bluetooth open close function
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2021/4/30
*
*/
#include <xs_adapter_manager.h>
#include "xs_adapter_bluetooth.h"
#include <user_api.h>
#include <bus_serial.h>
#include <dev_serial.h>
#include <string.h>
#ifdef BOARD_K210_EVB
#define SAMPLE_UART_NAME "/dev/uart3_dev3"
#endif
#ifdef BOARD_STM32F407_EVB
#define SAMPLE_UART_NAME "/dev/usart3_dev3"
#endif
static int serial_fd;
static int32_t bluetooth_receive;
static int rx_sem;
char bluetooth_buffer[NAME_NUM_MAX ]={0};
/* initialize srial port to open bluetooth*/
int BluetoothOpen(struct Adapter *padapter)
{
/* Open device in read-write mode */
serial_fd = open(SAMPLE_UART_NAME,O_RDWR);
/* set serial config, serial_baud_rate = 115200 */
struct SerialDataCfg cfg;
cfg.serial_baud_rate = BAUD_RATE_115200;
cfg.serial_data_bits = DATA_BITS_8;
cfg.serial_stop_bits = STOP_BITS_1;
cfg.serial_parity_mode = PARITY_NONE;
cfg.serial_bit_order = 0;
cfg.serial_invert_mode = 0;
cfg.serial_buffer_size = 128;
ioctl(serial_fd, 0, &cfg);
UserTaskDelay(1000);
printf("Bluetooth ready\n");
return 0;
}
/* send message to srial port*/
int BluetoothSend(struct Adapter *padapter, const char* data, int len, bool block, int time_out, int delay, send_success cb, void* param, void* reserved)
{
write(serial_fd,data,strlen(data));
return 0;
}
/*thread to read message from srial port*/
void SerialThreadEntry(void *parameter)
{
char ch;
int i = 0;
int n;
int run = 0;
while (1){
n = read(serial_fd,&ch,1);
if (n>0){
if (ch == '~'){
UserSemaphoreAbandon(rx_sem);
run = 1;
break;
}
bluetooth_buffer[i++] = ch;
}
if (run ==1)
break;
}
}
int BluetoothReceive(struct Adapter *padapter, char* rev_buffer, int buffer_len,int time_out, bool block, void* reserved)
{
x_err_t ret = EOK;
/* Set callback function */
/* Create thread serial */
UtaskType recv;
recv.name[0] = 'z';
recv.func_entry = SerialThreadEntry;
recv.func_param = NONE;
recv.stack_size = 1024;
recv.prio = 25;
memset(bluetooth_buffer, 0, sizeof(bluetooth_buffer));
/* Initialize semaphore */
rx_sem = UserSemaphoreCreate(0);
bluetooth_receive = UserTaskCreate(recv);
UserTaskStartup(bluetooth_receive);
/*copy to the receive buffer*/
UserSemaphoreObtain(rx_sem,-1);
memcpy(rev_buffer,bluetooth_buffer,strlen(bluetooth_buffer)+1 );
return ret;
}
void BluetoothSettingDemo(int argc, char *argv[])
{
adapter_t padapter = BluetoothAdapterFind("Bluetooth");
if (NONE == padapter){
KPrintf("adapter find failed!\n");
return;
}
/*Open adapter*/
if (0 != padapter->done.NetAiitOpen(padapter)){
KPrintf("adapter open failed!\n");
return;
}
BluetoothOpen(padapter);
/*Bluetooth communication settings*/
/*it can be changed if needed*/
char* set5 = "AT";
write(serial_fd,set5,strlen(set5));
UserTaskDelay(1000);
printf("bluetooth setting success!\n");
}
#ifndef SEPARATE_COMPILE
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
BluetoothSettingDemo, BluetoothSettingDemo, bluetooth send function );
#endif
void BluetoothClose(struct Adapter *padapter)
{
UserTaskDelete(bluetooth_receive);
close(serial_fd);
}
@@ -0,0 +1,5 @@
SRC_FILES += xs_adapterAT_ethernet.c \
xs_adapterAT_ethernet_register.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,409 @@
/*
* 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_AdapterAT_ethernet.c
* @brief Structure and function declarations of the connection ethernet
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#include <xs_adapter_at_ethernet.h>
#include <xs_adapter_manager.h>
#include <xs_adapter_at_agent.h>
#include <xs_adapter_def.h>
#include <user_api.h>
#include <string.h>
/**
* @description: Close ethernet
* @param padapter - ethernet device pointer
*/
void EthernetClose(struct Adapter *padapter)
{
}
/**
* @description: open ethernet
* @param padapter - ethernet device pointer
*/
int EthernetOpen(struct Adapter *padapter)
{
char *agent_name = "uart3_client";
const char *device_name = ETHERNET_UART_NAME;
uint32 result;
if (InitATAgent(agent_name, device_name, 512, NULL)){
printf("InitATAgent failed ! \n");
result = -ERROR;
return result;
}
ATAgentType at_agent = GetATAgent(agent_name);
if (NULL == at_agent){
printf("GetATAgent failed ! \n");
return -ERROR;
}
UserTaskDelay(5000);
struct AdapterAT *ethernetAT_adapter = (struct AdapterAT *)padapter;
ethernetAT_adapter->agent = at_agent;
return EOK;
}
int EthernetSend(struct Adapter *padapter, const char *data, int len, bool block, int time_out, int delay, send_success cb, void *param, void* p)
{
struct AdapterAT *ethernetAT_adapter = (struct AdapterAT *)padapter;
if (ethernetAT_adapter->agent){
EntmSend(ethernetAT_adapter->agent, data, len);
}
}
int EthernetReceive(struct Adapter *padapter, char *rev_buffer, int buffer_len, int time_out, bool block, void* p)
{
printf("ethernet receive waiting ... \n");
struct AdapterAT *ethernetAT_adapter = (struct AdapterAT *)padapter;
if (ethernetAT_adapter->agent){
if (EntmRecv(ethernetAT_adapter->agent, rev_buffer, buffer_len, 40000))
printf("EntmRecv failed ! \n");
}else{
printf("Can not find agent \n");
}
}
uint32 EthernetInitAtCmd(ATAgentType at_agent)
{
uint32 result;
ATReplyType reply = CreateATReply(64);
if (NULL == reply){
printf("CreateATReply failed ! \n");
result = -ERROR;
goto __exit;
}
ATOrderSend(at_agent, REPLY_TIME_OUT, NULL, "+++");
UserTaskDelay(100);
ATOrderSend(at_agent, REPLY_TIME_OUT, NULL, "a");
UserTaskDelay(500);
return result;
__exit:
if (reply)
DeleteATReply(reply);
return result;
}
static void EthernetSetUpAdapter(void *parameter)
{
#define INIT_RETRY 5
#define LEN_PARA_BUF 128
uint8 server_addr_wifi[LEN_PARA_BUF]="192.168.1.183";
uint8 server_port_wifi[LEN_PARA_BUF]="12345";
uint8 WIFI_ssid[LEN_PARA_BUF]="DDST 2";
uint8 WIFI_pwd[LEN_PARA_BUF]="passw0rd";
char cmd[LEN_PARA_BUF];
struct AdapterAT *adapterAT = (struct AdapterAT *) parameter;
//struct at_device_esp8266 *esp8266 = (struct at_device_esp8266 *) device->UserData;
struct ATAgent *agent = adapterAT->agent;
ATReplyType reply = NONE;
x_err_t result = EOK;
x_size_t retry_num = INIT_RETRY;
//DBG("%s device initialize start.", adapterAT->parent.);
/* wait hfa21 device startup finish */
UserTaskDelay(5000);
reply = CreateATReply(64);
if (reply == NONE){
printf("no memory for reply create.");
return;
}
while (retry_num--){
ATOrderSend(agent, REPLY_TIME_OUT, NULL, "+++");
UserTaskDelay(100);
ATOrderSend(agent, REPLY_TIME_OUT, NULL, "a");
UserTaskDelay(2500);
ATOrderSend(agent, REPLY_TIME_OUT, NULL, "AT+FCLR\r");
UserTaskDelay(30000);
ATOrderSend(agent, REPLY_TIME_OUT, NULL, "+++");
UserTaskDelay(100);
ATOrderSend(agent, REPLY_TIME_OUT, NULL, "a");
UserTaskDelay(2500);
memset(cmd,0,sizeof(cmd));
strcpy(cmd,"AT+WSSSID=");
strcat(cmd,WIFI_ssid);
strcat(cmd,"\r");
ATOrderSend(agent, REPLY_TIME_OUT, NULL, cmd);
UserTaskDelay(2500);
memset(cmd,0,sizeof(cmd));
strcpy(cmd,"AT+WSKEY=WPA2PSK,AES,");
strcat(cmd,WIFI_pwd);
strcat(cmd,"\r");
ATOrderSend(agent, REPLY_TIME_OUT, NULL, cmd);
UserTaskDelay(2500);
memset(cmd,0,sizeof(cmd));
strcpy(cmd,"AT+WMODE=sta\r");
ATOrderSend(agent, REPLY_TIME_OUT, NULL, cmd);
UserTaskDelay(2500);
memset(cmd,0,sizeof(cmd));
strcpy(cmd,"AT+NETP=TCP,CLIENT,");
strcat(cmd,server_port_wifi);
strcat(cmd,",");
strcat(cmd,server_addr_wifi);
strcat(cmd,"\r");
// strcpy(cmd,"AT+NETP\r");
ATOrderSend(agent, REPLY_TIME_OUT, NULL, cmd);
UserTaskDelay(2500);
memset(cmd,0,sizeof(cmd));
strcat(cmd,"AT+Z\r");
ATOrderSend(agent, REPLY_TIME_OUT, NULL, cmd);
UserTaskDelay(2500);
/* initialize successfully */
result = EOK;
break;
__exit:
if (result != EOK)
UserTaskDelay(1000);
}
if (reply)
DeleteATReply(reply);
}
int EthernetSetUp(struct AdapterAT *adapterAT)
{
EthernetSetUpAdapter(adapterAT);
return EOK;
}
int EthernetDHCP(struct AdapterAT *adapterAT, bool enable)
{
int result = EOK;
ATReplyType reply = NONE;
char dhcp_status[4];
memset(dhcp_status,0,sizeof(dhcp_status));
if(enable)
strcpy(dhcp_status,"on");
else
strcpy(dhcp_status,"off");
reply = CreateATReply(64);
if (reply == NONE){
printf("no memory for reply struct.");
return -ENOMEMORY;
}
/* send dhcp set commond "AT+CWDHCP_CUR=<mode>,<en>" and wait response */
if (ATOrderSend(adapterAT->agent, REPLY_TIME_OUT, reply, "AT+DHCPDEN=%s", dhcp_status) < 0){
result = -ERROR;
goto __exit;
}
__exit:
if (reply)
DeleteATReply(reply);
return result;
}
int EthernetPing(struct AdapterAT *adapterAT, const char *destination,struct PingResult *ping_resp)
{
char *ping_result = NONE;
ping_result = (char *) UserCalloc(1, 17);
EthernetInitAtCmd(adapterAT->agent);
uint32 result = EOK;
ATReplyType reply = CreateATReply(64);
if (NULL == reply){
printf("CreateATReply failed ! \n");
result = -ERROR;
goto __exit;
}
printf("\\r = 0x%x, \\n = 0x%x\n", '\r', '\n');
//ping baidu.com
uint32 err = ATOrderSend(adapterAT->agent, REPLY_TIME_OUT, reply, "AT+PING=%s", "192.168.250.240\r");
if (err){
printf("at_obj_exec_cmdAT+PINGfailed ! err = %d\n", err);
result = -ERROR;
goto __exit;
}
UserTaskDelay(2500);
ATOrderSend(adapterAT->agent, REPLY_TIME_OUT, NULL, "AT+Z\r");
UserTaskDelay(2000);
const char * result_buf = GetReplyText(reply);
if(!result_buf){
printf("send_dhcp_at_cmd AT+ result_buf = NULL");
result = -ERROR;
goto __exit;
}
char* str = strstr(result_buf, "+ok=");
printf("str is:%s\n",str);
ParseATReply(str, "+ok=%s\r", ping_result);
printf("ping result is:%s\n", ping_result);
__exit:
if (reply)
DeleteATReply(reply);
return result;
}
int EthernetNetstat(struct AdapterAT *adapterAT)
{
#define HFA21_NETSTAT_RESP_SIZE 320
#define HFA21_NETSTAT_TYPE_SIZE 10
#define HFA21_NETSTAT_IPADDR_SIZE 17
#define HFA21_NETP_EXPRESSION "+ok=%[^,],%[^,],%d,%s\r"
#define HFA21_WANN_EXPRESSION "+ok=%[^,],%[^,],%[^,],%[^,]\r"
#define HFA21_LANN_EXPRESSION "+ok=%[^,],%[^,]\r"
#define HFA21_WMODE_EXPRESSION "+ok=%s\r"
ATReplyType reply = NULL;
struct ATAgent *agent = adapterAT->agent;
uint32 result;
char * result_buf = NULL;
char * str = NULL;
/* sta/ap */
char *work_mode = NULL;
/* dhcp/static */
char *ip_mode = NULL;
char *local_ipaddr = NULL;
char *gateway = NULL;
char *netmask = NULL;
local_ipaddr = (char *) UserCalloc(1, HFA21_NETSTAT_IPADDR_SIZE);
gateway = (char *) UserCalloc(1, HFA21_NETSTAT_IPADDR_SIZE);
netmask = (char *) UserCalloc(1, HFA21_NETSTAT_IPADDR_SIZE);
work_mode = (char *) UserCalloc(1, HFA21_NETSTAT_IPADDR_SIZE);
ip_mode = (char *) UserCalloc(1, HFA21_NETSTAT_IPADDR_SIZE);
reply = CreateATReply(HFA21_NETSTAT_RESP_SIZE);
if (reply == NULL)
goto __exit;
ATOrderSend(agent, REPLY_TIME_OUT, NULL, "+++");
UserTaskDelay(100);
ATOrderSend(agent, REPLY_TIME_OUT, NULL, "a");
UserTaskDelay(2500);
if (ATOrderSend(agent, REPLY_TIME_OUT, reply, "AT+WMODE\r") < 0)
goto __exit;
UserTaskDelay(2500);
result_buf = GetReplyText(reply);
if(!result_buf){
printf("send_dhcp_at_cmd AT+ result_buf = NULL");
result = -ERROR;
goto __exit;
}
str = strstr(result_buf, "+ok=");
printf("str is:%s\n",str);
/* parse the third line of response data, get the network connection information */
ParseATReply(str, HFA21_WMODE_EXPRESSION, work_mode);
if(work_mode[0]=='S'){
if (ATOrderSend(agent, REPLY_TIME_OUT, reply, "AT+WANN\r") < 0)
goto __exit;
UserTaskDelay(2500);
result_buf = GetReplyText(reply);
if(!result_buf){
printf("send_dhcp_at_cmd AT+ result_buf = NULL");
result = -ERROR;
goto __exit;
}
str = strstr(result_buf, "+ok=");
printf("str is:%s\n",str);
/* parse the third line of response data, get the network connection information */
ParseATReply(str, HFA21_WANN_EXPRESSION, ip_mode, local_ipaddr, netmask, gateway);
}else{
if (ATOrderSend(agent, REPLY_TIME_OUT, reply, "AT+LANN\r") < 0)
goto __exit;
UserTaskDelay(2500);
result_buf = GetReplyText(reply);
if(!result_buf){
printf("send_dhcp_at_cmd AT+ result_buf = NULL");
result = -ERROR;
goto __exit;
}
str = strstr(result_buf, "+ok=");
printf("str is:%s\n",str);
/* parse the third line of response data, get the network connection information */
ParseATReply(str, HFA21_LANN_EXPRESSION, local_ipaddr, netmask);
}
ATOrderSend(adapterAT->agent, REPLY_TIME_OUT, NULL, "AT+Z\r");
UserTaskDelay(2500);
printf("work mode: %s\n", work_mode);
if(work_mode[0]=='S')
printf("ip mode: %s\nlocal ip: %s\nnetmask: %s\ngateway: %s\n", ip_mode, local_ipaddr, netmask, gateway);
else
printf("local ip: %s\nnetmask: %s\n", local_ipaddr, netmask);
return EOK;
__exit:
if (reply)
DeleteATReply(reply);
if (local_ipaddr)
UserFree(local_ipaddr);
if (netmask)
UserFree(netmask);
if (gateway)
UserFree(gateway);
if (work_mode)
UserFree(work_mode);
}
@@ -0,0 +1,70 @@
/*
* 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_AdapterAT_ethernet_register.c
* @brief Structure and function declarations of the ethernet register
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#include <xs_adapter_at_ethernet.h>
#include <xs_adapter_manager.h>
#include <xs_adapter_at_agent.h>
#include <user_api.h>
#include <stdlib.h>
const struct AdapterDone EthernetAdapterDone =
{
EthernetClose,
EthernetOpen,
NULL,
EthernetSend,
EthernetReceive,
NULL,
};
const struct ATDone EthernetATDone =
{
EthernetSetUp,
NULL,
NULL,
NULL,
EthernetDHCP,
EthernetPing,
EthernetNetstat,
NULL,
};
int RegisterAdapterEthernet(void)
{
struct AdapterEthernet *ethernet_adapter = malloc(sizeof(struct AdapterEthernet));
if (ethernet_adapter == NULL){
printf("out of memory\n");
return ERROR;
}
struct AdapterAT *ethernetAT_adapter = (struct AdapterAT *)ethernet_adapter;
struct Adapter *adapter = (struct Adapter *)ethernet_adapter;
ethernet_adapter->parent.atdone = EthernetATDone;
ethernet_adapter->parent.parent.done = EthernetAdapterDone;
ethernetAT_adapter->at_adapter_id = ETHERNET_ADAPTER_ID;
ATAdapterInit();
ATAdapterRegister(ethernetAT_adapter);
return EOK;
}
@@ -0,0 +1,72 @@
/*
* 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_adapter.h
* @brief Adapter interface
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#ifndef XS_ADAPTER_N
#define XS_ADAPTER_N
#include <stdbool.h>
#include <xs_klist.h>
#include <xs_adapter_def.h>
enum AdapterType {
ADAPTER_LORA = 0, /* Lora */
ADAPTER_4G , /* 4G */
ADAPTER_NBIOT , /* NBIot */
ADAPTER_WIFI , /* WIFI */
ADAPTER_ETHERNET , /* ETHERNET */
ADAPTER_BLUETOOTH , /* BLUETOOTH */
ADAPTER_ZIGBEE , /* ZIGBEE */
ADAPTER_5G , /* 5G */
};
enum MeshType{
NET_P2P = 0,
NET_ADHOC_SINGLE_GROUP,
NET_ADHOC_MULTI_GROUP,
};
enum NetRoleType{
ROLE_TYPE_SLAVE = 1,
ROLE_TYPE_MASTER,
ROLE_TYPE_NONE,
};
struct Adapter;
struct AdapterDone {
void (*NetAiitClose)(struct Adapter *padapter);
int (*NetAiitOpen)(struct Adapter *padapter);
int (*NetAiitJoin)(struct Adapter *padapter, int dev_type, char* net_id);
int (*NetAiitSend)(struct Adapter *padapter, const char* data, int len, bool block, int time_out, int delay, send_success cb, void* param, void* reserved);
int (*NetAiitReceive)(struct Adapter *padapter, char* rev_buffer, int buffer_len,int time_out, bool block, void* reserved);
int (*NetAiitIoctl)(struct Adapter *padapter, int cmd, void *arg);
};
struct Adapter
{
enum AdapterType type; /* type of adapter, such as lora adapter */
enum NetRoleType net_role_type;
enum MeshType mesh_type;
struct AdapterDone done; /* socket-like APIs for data transferring */
struct SysDoubleLinklistNode link; /* link list node */
};
typedef struct Adapter *adapter_t;
#endif
@@ -0,0 +1,94 @@
/*
* 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_adapter_at.h
* @brief AdapterAT interface
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#ifndef XS_ADAPTER_AT_H
#define XS_ADAPTER_AT_H
#include "xs_adapter.h"
#include <xs_adapter_at_agent.h>
#define SOCKET_STATUS_UNUSED (0)
#define SOCKET_STATUS_INIT (1)
#define SOCKET_STATUS_CONNECT (2)
#define SOCKET_TYPE_DGRAM (0)
#define SOCKET_TYPE_STREAM (1)
#define SOCKET_PROTOCOL_TCP (6)
#define SOCKET_PROTOCOL_UDP (17)
#define NET_TYPE_AF_INET (0)
#define NET_TYPE_AF_INET6 (1)
#define SOCKET_MAX 8
struct Socket
{
uint8_t fd;
uint8_t status ;
struct AddressIpv4 src_ip;
uint16_t src_port;
struct AddressIpv4 dst_ip;
uint16_t dst_port;
uint8_t type;
uint8_t af_type;
uint8_t protocal;
uint8 is_client;
};
struct AdapterAT;
struct ATDone
{
int (*ATOperateUp)(struct AdapterAT *adapterAT);
int (*ATOperateDown)(struct AdapterAT *adapterAT);
int (*ATOperateAddr)(struct AdapterAT *adapterAT, uint ip, uint gateway, uint netmask);
int (*ATOperateDns)(struct AdapterAT *adapterAT, struct AddressIpv4 *dns_addr, uint8 dns_count);
int (*ATOperateDHCP)(struct AdapterAT *adapterAT, bool enable);
int (*ATPing)(struct AdapterAT *adapterAT, const char *destination, struct PingResult *ping_resp);
int (*ATNetstat)(struct AdapterAT *adapterAT);
int (*ATOperateDefault)(struct AdapterAT *adapterAT);
int (*ATSocketCreate)(struct AdapterAT *adapterAT , uint8_t socket_fd , uint8_t type , uint8_t af_type );
int (*ATSocketConnect)(struct AdapterAT *adapterAT , uint8_t socket_fd , struct AddressIpv4 dst_ip , uint16_t dst_port, uint8 is_client);
int (*ATSocketClose)(struct AdapterAT *adapterAT , uint8_t socket_fd );
};
struct AdapterAT {
struct Adapter parent;
struct ATAgent *agent;
struct AddressIpv4 ip;
struct AddressIpv4 netmask;
struct AddressIpv4 gateway;
struct AddressIpv4 dns[DNS_COUNT];
uint32 at_adapter_id;
struct Socket socket[SOCKET_MAX];
uint8 hardware_address_len;
uint8 hardware_address[HW_MAX];
uint16 flags;
uint16 mtu;
void (*change_cb )(struct AdapterAT *adapterAT, enum CbType type, enum ChangeType ch_type_);
struct ATDone atdone;
struct SysDoubleLinklistNode link;
};
#endif
@@ -0,0 +1,81 @@
/*
* 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_adapter_at_agent.h
* @brief AT proxy, auto receive AT reply and transparency data
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#ifndef XS_ADAPTER_AT_CLIENT_H
#define XS_ADAPTER_AT_CLIENT_H
#include <stdarg.h>
#include <stddef.h>
#include <bus_serial.h>
enum ReceiveMode
{
ENTM_MODE = 1,
AT_MODE = 2,
};
struct ATReply
{
char *reply_buffer;
uint32 reply_max_len;
uint32 reply_len;
};
typedef struct ATReply *ATReplyType;
struct ATAgent
{
char agent_name[NAME_NUM_MAX];
int fd;
char *maintain_buffer;
uint32 maintain_len;
uint32 maintain_max;
int32 lock;
ATReplyType reply;
int rsp_sem;
int32 at_handler;
#define ENTM_RECV_MAX 256
char entm_recv_buf[ENTM_RECV_MAX];
uint32 entm_recv_len;
enum ReceiveMode receive_mode;
int entm_rx_notice;
};
typedef struct ATAgent *ATAgentType;
int EntmSend(ATAgentType agent, const char *data, int len);
int EntmRecv(ATAgentType agent, char *rev_buffer, int buffer_len, int time_out);
char *GetReplyText(ATReplyType reply);
ATReplyType CreateATReply(uint32 reply_max_len);
uint IpTint(char *ipstr);
void SwapStr(char *str, int begin, int end);
char* IpTstr(uint ipint);
ATAgentType GetATAgent(const char *agent_name);
int InitATAgent(const char *agent_name, const char *device_name, uint32 maintain_max, struct SerialCfgParam* pserial_cfg);
int ParseATReply(char* str, const char *format, ...);
void DeleteATReply(ATReplyType reply);
int ATOrderSend(ATAgentType agent, uint32 timeout, ATReplyType reply, const char *cmd_expr, ...);
#define REPLY_TIME_OUT 3000
#endif
@@ -0,0 +1,48 @@
/*
* 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_adapter_at_ethernet.h
* @brief Structure and function declarations of the connection ethernet
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#ifndef XS_ADAPTER_AT_ETHERNET_H
#define XS_ADAPTER_AT_ETHERNET_H
#include "xs_adapter.h"
#include "xs_adapter_at.h"
#include "xs_adapter_def.h"
#include "xs_klist.h"
struct AdapterEthernet {
struct AdapterAT parent; /* inherit from Adapter */
char vendor_name[NAME_LEN_MAX];
char product_ID_ethernet[NAME_LEN_MAX];
struct SingleLinklistNode link;
};
void EthernetClose(struct Adapter *padapter);
int EthernetOpen(struct Adapter *padapter);
int EthernetSend(struct Adapter *padapter, const char *data, int len, bool block, int time_out, int delay, send_success cb, void *param, void *p);
int EthernetReceive(struct Adapter *padapter, char *rev_buffer, int buffer_len, int time_out, bool block, void *p);
int EthernetSetUp(struct AdapterAT *adapterAT);
int EthernetDHCP(struct AdapterAT *adapterAT, bool enable);
int EthernetPing(struct AdapterAT *adapterAT, const char *destination, struct PingResult *ping_resp);
int EthernetNetstat(struct AdapterAT *adapterAT);
#endif
@@ -0,0 +1,57 @@
/*
* 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_adapter_at_nbiot.h
* @brief Structure and function declarations of the connection NBIoT
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#ifndef XS_ADAPTER_AT_NBIOT_H
#define XS_ADAPTER_AT_NBIOT_H
#include "xs_adapter.h"
#include "xs_adapter_at.h"
#include "xs_adapter_at_agent.h"
#include "xs_adapter_def.h"
#include <stdio.h>
#include <string.h>
#include <user_api.h>
#define MAX_SOCKET_NUM 8
#define SOCKET_STATUS_UNUSED (0)
#define SOCKET_STATUS_INIT (1)
#define SOCKET_STATUS_CONNECT (2)
struct AdapterNBIoT {
struct AdapterAT parent; /* inherit from Adapter */
char vendor_name[NAME_LEN_MAX];
char product_ID_ethernet[NAME_LEN_MAX];
struct SingleLinklistNode link;
};
int NbiotOpen(struct Adapter *padapter);
int NbiotSend(struct Adapter *padapter, const char* data, int len, bool block, int time_out, int delay, send_success cb, void* param, void* reserved);
int NBIotRecv(struct Adapter *padapter, char *rev_buffer, int buffer_len, int time_out, bool block);
int NBIoTSocketConnect(struct AdapterAT *adapterAT , uint8_t socket_fd , struct AddressIpv4 dst_ip , uint16_t dst_port, uint8 is_client);
int NBIoTSocketCreate(struct AdapterAT *adapterAT, uint8_t socket_fd, uint8_t type, uint8_t af_type );
int NBIoTSocketClose(struct AdapterAT *adapterAT, uint8_t socket_fd );
#endif
@@ -0,0 +1,50 @@
/*
* 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_adapter_at_wifi.h
* @brief Structure and function declarations of the connection wifi
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#ifndef XS_ADAPTER_AT_WIFI_H
#define XS_ADAPTER_AT_WIFI_H
#include "xs_adapter.h"
#include "xs_adapter_at.h"
#include "xs_adapter_def.h"
#include "xs_klist.h"
struct Adapterwifi {
struct AdapterAT parent; /* inherit from Adapter */
char vendor_name[NAME_LEN_MAX];
char product_id_wifi[NAME_LEN_MAX];
struct SingleLinklistNode link;
};
void WifiClose(struct Adapter *padapter);
int WifiOpen(struct Adapter *padapter);
int WifiSend(struct Adapter *padapter, const char *data, int len, bool block, int time_out, int delay, send_success cb, void *param, void *p);
int WifiReceive(struct Adapter *padapter, char *rev_buffer, int buffer_len, int time_out, bool block, void *p);
int WifiSetUp(struct AdapterAT *adapter_at);
int WifiSetDown(struct AdapterAT *adapter_at);
int WifiSetAddr(struct AdapterAT *adapter_at, uint ip, uint gateway, uint netmask);
int WifiDHCP(struct AdapterAT *adapter_at, bool enable);
int WifiPing(struct AdapterAT *adapter_at, const char *destination,struct PingResult *ping_resp);
int WifiNetstat(struct AdapterAT *adapter_at);
#endif
@@ -0,0 +1,41 @@
/*
* 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_adapter_bluetooth.h
* @brief: head file
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2021/4/25
*
*/
#ifndef XS_ADAPTER_BLUETOOTH_H
#define XS_ADAPTER_BLUETOOTH_H
#include "xs_adapter.h"
struct AdapterBluetooth {
struct Adapter parent; /* inherit from Adapter */
const char * name; /* name of the adapter instance */
const char * device_type; /* type of the adapter instance */
};
typedef struct AdapterBluetooth *AdapterBluetooth_t;
int BluetoothOpen(struct Adapter *padapter);
int BluetoothSend(struct Adapter *padapter, const char* data, int len, bool block, int time_out, int delay, send_success cb, void* param, void* reserved);
int BluetoothReceive(struct Adapter *padapter, char* rev_buffer, int buffer_len,int time_out, bool block, void* reserved);
void BluetoothClose(struct Adapter *padapter);
#endif
@@ -0,0 +1,77 @@
/*
* 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_adapter_def.h
* @brief defines about adapter
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#ifndef __XS_ADAPTER_DEF_H__
#define __XS_ADAPTER_DEF_H__
#include "stdbool.h"
typedef void(*send_success)(void* param);
#define NAME_LEN_MAX 32
#define IPV6__ADDRESS_COUNT 3U
#define DNS_COUNT 2U
#define HW_MAX 8U
enum CbType
{
CB_ADDR_IP, /* IP address */
CB_ADDR_NETMASK, /* subnet mask */
CB_ADDR_GATEWAY, /* netmask */
CB_ADDR_DNS_SERVER, /* dns server */
CB_STATUS_UP, /* changed to 'up' */
CB_STATUS_DOWN, /* changed to 'down' */
CB_STATUS_LINK_UP, /* changed to 'link up' */
CB_STATUS_LINK_DOWN, /* changed to 'link down' */
CB_STATUS_INTERNET_UP, /* changed to 'internet up' */
CB_STATUS_INTERNET_DOWN, /* changed to 'internet down' */
CB_STATUS_DHCP_ENABLE, /* enable DHCP capability */
CB_STATUS_DHCP_DISABLE, /* disable DHCP capability */
};
enum ChangeType
{
ADDR_CHANGE,
STATUS_CHANGE,
};
struct AddressIpv4
{
uint32 ipv4;
};
struct PingResult
{
struct AddressIpv4 ip_addr; /* response IP address */
uint16 data_len; /* response data length */
uint16 ttl; /* time to live */
uint32 ticks; /* response time, unit tick */
void *user_data; /* user-specific data */
};
#define NBIOT_ADAPTER_ID 0x02U
#define ETHERNET_ADAPTER_ID 0x03U
#define WIFI_ADAPTER_ID 0x04U
#define fourG_ADAPTER_ID 0x05U
#endif
@@ -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
@@ -0,0 +1,43 @@
/*
* 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_adapter_manager.h
* @brief manager adapter list
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#ifndef ADAPTER_MANAGER_H_
#define ADAPTER_MANAGER_H_
#include "xs_adapter.h"
#include <xs_adapter_at.h>
void LoraAdapterInit();
void LoraAdapterRegister(adapter_t padapter);
void* LoraAdapterFind(char* name);
void ATAdapterInit();
void ATAdapterRegister(struct AdapterAT* at_adapter);
void* ATAdapterFind(uint32 adapter_id);
void ZigbeeAdapterInit();
void ZigbeeAdapterRegister(adapter_t padapter);
void* ZigbeeAdapterFind(char* name);
void BluetoothAdapterInit();
void BluetoothAdapterRegister(adapter_t padapter);
void* BluetoothAdapterFind(char* name);
#endif
@@ -0,0 +1,41 @@
/*
* 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_adapter_zigbee.h
* @brief: head file
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2021/4/25
*
*/
#ifndef XS_ADAPTER_ZIGBEE_H
#define XS_ADAPTER_ZIGBEE_H
#include "xs_adapter.h"
struct AdapterZigbee {
struct Adapter parent; /* inherit from Adapter */
const char * name; /* name of the adapter instance */
const char * device_type; /* type of the adapter instance */
};
typedef struct AdapterZigbee *adapterZigbee_t;
int ZigbeeOpen(struct Adapter *padapter);
int ZigbeeSend(struct Adapter *padapter, const char* data, int len, bool block, int time_out, int delay, send_success cb, void* param, void* reserved);
int ZigbeeReceive(struct Adapter *padapter, char* rev_buffer, int buffer_len,int time_out, bool block, void* reserved);
void ZigbeeClose(struct Adapter *padapter);
#endif
@@ -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
@@ -0,0 +1,3 @@
SRC_FILES := xs_adapter_lora.c
include $(KERNEL_ROOT)/compiler.mk
@@ -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;
}
@@ -0,0 +1,3 @@
SRC_DIR := bc28
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,3 @@
SRC_FILES := xs_adapter_at_nbiot.c xs_adapter_at_nbiot_register.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,339 @@
/*
* 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_adapter_at_nbiot.c
* @brief BC28 NBIoT driver base connection framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#include <dev_serial.h>
#include <xs_adapter_at_nbiot.h>
#include <xs_adapter_manager.h>
#include <xs_adapter_def.h>
#define NBIOT_DEVICE_NAME "/dev/usart2_dev2"
#define SOCKET_TYPE_DGRAM (0)
#define SOCKET_TYPE_STREAM (1)
#define SOCKET_PROTOCOL_TCP (6)
#define SOCKET_PROTOCOL_UDP (17)
#define NET_TYPE_AF_INET (0)
#define NET_TYPE_AF_INET6 (1)
/**
* @description: Open NBIoT device
* @param padapter - NBIoT adapter
* @return success: EOK, failure: -ERROR
*/
int NbiotOpen(struct Adapter *padapter)
{
char *agent_name = "urat2_client";
const char *device_name = NBIOT_DEVICE_NAME;
struct SerialCfgParam cfg;
cfg.data_cfg.serial_baud_rate = BAUD_RATE_9600;
cfg.data_cfg.serial_bit_order = 0;
cfg.data_cfg.serial_buffer_size = SERIAL_RB_BUFSZ;
cfg.data_cfg.serial_data_bits = DATA_BITS_8;
cfg.data_cfg.serial_invert_mode = 0;
cfg.data_cfg.serial_parity_mode = PARITY_NONE;
cfg.data_cfg.serial_stop_bits = STOP_BITS_1;
if (InitATAgent(agent_name, device_name, 512, &cfg)) {
printf("NBIoT open failed!\n");
return -ERROR;
}
ATAgentType at_agent = GetATAgent(agent_name);
if (NULL == at_agent) {
printf("Get AT agent failed!\n");
return -ERROR;
}
UserTaskDelay(3000);
struct AdapterAT *nbiot = (struct AdapterAT *)padapter;
nbiot->agent = at_agent;
return EOK;
}
/**
* @description: NBIoT device create a socket connection
* @param adapterAT - NBIoT adapter AT
* @param socket_fd - socket file description
* @param type - socket type
* @param af_type - IPv4 or IPv6
* @return success: EOK, failure: -ERROR
*/
int NBIoTSocketCreate(struct AdapterAT *adapterAT, uint8_t socket_fd, uint8_t type, uint8_t af_type )
{
int32 result;
ATReplyType reply = CreateATReply(64);
if (NULL == reply) {
printf("at create failed ! \n");
result = -ERROR;
goto __exit;
}
if ( af_type == NET_TYPE_AF_INET6) {
printf("IPv6 not surport !\n");
return -1;
}
char *str_af_type = "AF_INET";
char *str_type;
char str_fd[3] = {0};
char *str_protocol ;
char at_cmd[64] = {0};
char *linsten_port = "0";
struct Socket socket = {0};
socket.status = SOCKET_STATUS_INIT;
socket.af_type = NET_TYPE_AF_INET;
if (type == SOCKET_TYPE_STREAM) { //tcp = AT+NSOCR=STREAM,6,0,1,AF_INET
socket.type = SOCKET_TYPE_STREAM;
socket.protocal = SOCKET_PROTOCOL_TCP;
str_type = "STREAM";
char *str_protocol = "6";
if (socket_fd > 0 && socket_fd < 8) {
str_fd[0] = socket_fd + '0';
} else
str_fd[0] = '0';
memcpy(at_cmd, "AT+NSOCR=", 9);
strcat(at_cmd, str_type);
strcat(at_cmd, ",");
strcat(at_cmd, str_protocol);
strcat(at_cmd, ",");
strcat(at_cmd, linsten_port);
strcat(at_cmd, ",");
strcat(at_cmd, str_fd);
strcat(at_cmd, ",");
strcat(at_cmd, str_af_type);
strcat(at_cmd, "\n");
}else if ( type == SOCKET_TYPE_DGRAM ){ //udp
socket.type = SOCKET_TYPE_DGRAM;
socket.protocal = SOCKET_PROTOCOL_UDP;
str_type = "DGRAM";
char *str_protocol = "17";
if (socket_fd > 0 && socket_fd < 8){
str_fd[0] = socket_fd + '0';
}else
str_fd[0] = '0';
memcpy(at_cmd, "AT+NSOCR=", 9);
strcat(at_cmd, str_type);
strcat(at_cmd, ",");
strcat(at_cmd, str_protocol);
strcat(at_cmd, ",");
strcat(at_cmd, linsten_port);
strcat(at_cmd, ",");
strcat(at_cmd, str_fd);
strcat(at_cmd, ",");
strcat(at_cmd, str_af_type);
strcat(at_cmd, "\n");
}else{
printf("error socket type \n");
return -1 ;
}
printf("cmd : %s\n", at_cmd);
ATOrderSend(adapterAT->agent, REPLY_TIME_OUT, reply, at_cmd);
UserTaskDelay(3000);
printf("bak : ");
for(int i = 0; i < strlen(reply->reply_buffer); i++)
printf(" 0x%02x", reply->reply_buffer[i]);
printf("\n");
struct Socket (*socketlist)[MAX_SOCKET_NUM] = &adapterAT->socket;
memset(socketlist[socket_fd], 0, sizeof(struct Socket));
memcpy(socketlist[socket_fd], &socket , sizeof(struct Socket));
__exit:
if (reply) {
DeleteATReply(reply);
}
return result;
}
/**
* @description: NBIoT device create a socket connection
* @param adapterAT - NBIoT adapter AT
* @param socket_fd - socket file description
* @param dst_ip - ip address
* @param dst_port - ip port
* @param is_client - whether it is a client
* @return success: EOK, failure: -ERROR
*/
int NBIoTSocketConnect(struct AdapterAT *adapterAT , uint8_t socket_fd , struct AddressIpv4 dst_ip , uint16_t dst_port, uint8 is_client)
{
int result;
ATReplyType reply = CreateATReply(64);
if (NULL == reply) {
printf("at create failed ! \n");
result = -ERROR;
goto __exit;
}
if (socket_fd < 1 || socket_fd > 8) {
printf("socket fd error \n");
return -1 ;
}
struct Socket (*socketlist)[SOCKET_MAX] = &adapterAT->socket;
if (socketlist[socket_fd]->status != SOCKET_STATUS_INIT || socketlist[socket_fd]->type != SOCKET_TYPE_STREAM) {
printf("socket type error \n");
}
char at_cmd[64] = {0};
char str_fd[2] = {0};
char str_port[6] = {0};
str_fd[0] = socket_fd + '0';
char *str_ip = IpTstr(dst_ip.ipv4) ;
sprintf(str_port, "%u", dst_port);
memcpy(at_cmd, "AT+NSOCO=", 9);
strcat(at_cmd, str_fd);
strcat(at_cmd, ",");
strcat(at_cmd, str_ip);
strcat(at_cmd, ",");
strcat(at_cmd, str_port);
strcat(at_cmd, "\n");
printf("cmd : %s\n", at_cmd);
ATOrderSend(adapterAT->agent, REPLY_TIME_OUT, reply, at_cmd);
UserTaskDelay(300);
socketlist[socket_fd]->dst_ip = dst_ip;
socketlist[socket_fd]->dst_port = dst_port;
socketlist[socket_fd]->status = SOCKET_STATUS_CONNECT;
__exit:
if (reply) {
DeleteATReply(reply);
}
return result;
}
/**
* @description: NBIoT device close a socket connection
* @param adapterAT - NBIoT adapter AT
* @param socket_fd - socket file description
* @return success: EOK, failure: -ERROR
*/
int NBIoTSocketClose(struct AdapterAT *adapterAT, uint8_t socket_fd )
{
int result;
ATReplyType reply = CreateATReply(64);
if (NULL == reply) {
printf("at create failed ! \n");
result = -ERROR;
goto __exit;
}
if (socket_fd < 1 || socket_fd > 7) {
printf("socket fd error \n");
return -1 ;
}
struct Socket (*socketlist)[SOCKET_MAX] = &adapterAT->socket;
char str_fd[2] = {0};
char at_cmd[16] = {0};
str_fd[0] = socket_fd + '0';
memcpy(at_cmd, "AT+NSOCL=", 9);
strcat(at_cmd, str_fd);
strcat(at_cmd, "\n");
printf("cmd : %s\n", at_cmd);
ATOrderSend(adapterAT->agent, REPLY_TIME_OUT, reply, at_cmd);
UserTaskDelay(300);
memset(socketlist[socket_fd], 0, sizeof(struct Socket));
__exit:
if (reply) {
DeleteATReply(reply);
}
return result;
}
/**
* @description: NBIoT socket send a message
* @param padapter - NBIoT adapter
* @param data - send data buffer
* @param len - send data length
* @param block - block
* @param time_out - timeout
* @param delay - delay time
* @param cb - send callback function
* @param param - send callback function parameter
* @param reserved - reserved parameter
* @return success: EOK, failure: -ERROR
*/
int NbiotSend(struct Adapter *padapter, const char* data, int len, bool block, int time_out, int delay, send_success cb, void* param, void* reserved)
{
uint32_t result;
ATReplyType reply = CreateATReply(64);
if (NULL == reply) {
printf("at create failed ! \n");
result = -ERROR;
goto __exit;
}
struct AdapterAT *adapterAT = (struct AdapterAT *)padapter;
int socket_fd = *(int*)reserved;
struct Socket (*socketlist)[SOCKET_MAX] = &adapterAT->socket;
char at_cmd[64] = {0};
char str_fd[2] = {0};
char size[2] = {0};
str_fd[0] = socket_fd + '0';
size[0] = len + '0';
memcpy(at_cmd, "AT+NSOSD=", 9);
strcat(at_cmd, str_fd);
strcat(at_cmd, ",");
strcat(at_cmd, size);
strcat(at_cmd, ",");
strcat(at_cmd, data);
strcat(at_cmd, "\n");
printf("cmd : %s\n", at_cmd);
ATOrderSend(adapterAT->agent, REPLY_TIME_OUT, reply, at_cmd);
UserTaskDelay(300);
__exit:
if (reply) {
DeleteATReply(reply);
}
return result;
}
@@ -0,0 +1,69 @@
/*
* 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_adapter_at_nbiot_register.c
* @brief BC28 nbiot driver register to connection framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#include <xs_adapter_manager.h>
#include <xs_adapter_at_nbiot.h>
const struct AdapterDone bc28_done =
{
NONE,
NbiotOpen,
NONE,
NbiotSend,
NONE,
NONE,
};
const struct ATDone bc28_at_done =
{
NONE,
NONE,
NONE,
NONE,
NONE,
NONE,
NONE,
NONE,
NBIoTSocketCreate,
NBIoTSocketConnect,
NBIoTSocketClose,
};
/**
* @description: Register nbiot device
* @return success: EOK, failure: ERROR
*/
int RegisterAdapterNBIoT(void)
{
static struct AdapterNBIoT nbiot_adapter;
struct AdapterAT *nbiot_at_adapter = (struct AdapterAT *)&nbiot_adapter;
struct Adapter *adapter = (struct Adapter *)&nbiot_adapter;
nbiot_adapter.parent.atdone = bc28_at_done;
nbiot_adapter.parent.parent.done = bc28_done;
nbiot_at_adapter->at_adapter_id = NBIOT_ADAPTER_ID;
ATAdapterInit();
ATAdapterRegister(nbiot_at_adapter);
return 0;
}
@@ -0,0 +1,4 @@
SRC_FILES := xs_adapter_manager.c \
xs_adapter_at_agent.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,485 @@
/*
* 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_adapterAT_client.c
* @brief AT proxy, auto receive AT reply and transparency data
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#include <xs_adapter_at_agent.h>
#include <stdbool.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <user_api.h>
#include <bus.h>
#define AT_CMD_MAX_LEN 128
#define AT_AGENT_MAX 2
static char send_buf[AT_CMD_MAX_LEN];
static uint32 last_cmd_len = 0;
static struct ATAgent at_agent_table[AT_AGENT_MAX] = {0};
uint IpTint(char *ipstr){
if (ipstr == NULL)
return 0;
char *token;
uint i = 3, total = 0, cur;
token = strtok(ipstr, ".");
while (token != NULL){
cur = atoi(token);
if (cur >= 0 && cur <= 255){
total += cur * pow(256, i);
}
i--;
token = strtok(NULL, ".");
}
return total;
}
void SwapStr(char *str, int begin, int end)
{
int i, j;
for (i = begin, j = end; i <= j; i++, j--){
if (str[i] != str[j]){
str[i] = str[i] ^ str[j];
str[j] = str[i] ^ str[j];
str[i] = str[i] ^ str[j];
}
}
}
char *IpTstr(uint ipint)
{
int LEN = 16;
char *new = (char *)malloc(LEN);
memset(new, '\0', LEN);
new[0] = '.';
char token[4];
int bt, ed, len, cur;
while (ipint){
cur = ipint % 256;
sprintf(token, "%d", cur);
strcat(new, token);
ipint /= 256;
if (ipint)
strcat(new, ".");
}
len = strlen(new);
SwapStr(new, 0, len - 1);
for (bt = ed = 0; ed < len;){
while (ed < len && new[ed] != '.'){
ed++;
}
SwapStr(new, bt, ed - 1);
ed += 1;
bt = ed;
}
new[len - 1] = '\0';
return new;
}
int ParseATReply(char *str, const char *format, ...)
{
va_list params;
int counts = 0;
va_start(params, format);
counts = vsscanf(str, format, params);
va_end(params);
return counts;
}
uint32 ATSprintf(int fd, const char *format, va_list params)
{
last_cmd_len = vsnprintf(send_buf, sizeof(send_buf), format, params);
return write(fd, send_buf, last_cmd_len);
}
int ATOrderSend(ATAgentType agent, uint32 timeout, ATReplyType reply, const char *cmd_expr, ...)
{
if (agent == NULL){
printf("ATAgent is null");
return -ERROR;
}
agent->receive_mode = AT_MODE;
memset(agent->maintain_buffer, 0x00, agent->maintain_max);
agent->maintain_len = 0;
memset(agent->entm_recv_buf, 0, ENTM_RECV_MAX);
agent->entm_recv_len = 0;
va_list params;
uint32 cmd_size = 0;
uint32 result = EOK;
const char *cmd = NULL;
UserMutexObtain(agent->lock, WAITING_FOREVER);
agent->reply = reply;
if(agent->reply != NULL){
reply->reply_len = 0;
va_start(params, cmd_expr);
ATSprintf(agent->fd, cmd_expr, params);
va_end(params);
if (UserSemaphoreObtain(agent->rsp_sem, timeout) != EOK){
result = -ETIMEOUT;
goto __out;
}
}else{
va_start(params, cmd_expr);
ATSprintf(agent->fd, cmd_expr, params);
va_end(params);
goto __out;
}
__out:
agent->reply = NULL;
UserMutexAbandon(agent->lock);
agent->receive_mode = ENTM_MODE;
return result;
}
char *GetReplyText(ATReplyType reply)
{
return reply->reply_buffer;
}
int EntmSend(ATAgentType agent, const char *data, int len)
{
char send_buf[128];
memset(send_buf, 0, 128);
agent->receive_mode = ENTM_MODE;
memcpy(send_buf, data, len);
memcpy(send_buf + len, "!@", 2);
write(agent->fd, send_buf, len + 2);
}
int EntmRecv(ATAgentType agent, char *rev_buffer, int buffer_len, int time_out)
{
UserTaskDelay(1000);
memset(agent->entm_recv_buf, 0, ENTM_RECV_MAX);
agent->entm_recv_len = 0;
UserSemaphoreSetValue(agent->entm_rx_notice, 0);
if (UserSemaphoreObtain(agent->entm_rx_notice, time_out)){
return ERROR;
}
if (buffer_len < agent->entm_recv_len){
return ERROR;
}
printf("EntmRecv once .\n");
agent->entm_recv_buf[agent->entm_recv_len - 2] = '\0';
memcpy(rev_buffer, agent->entm_recv_buf, agent->entm_recv_len - 2);
return EOK;
}
static int GetCompleteATReply(ATAgentType agent)
{
uint32 read_len = 0;
char ch = 0, last_ch = 0;
bool is_full = false;
memset(agent->maintain_buffer, 0x00, agent->maintain_max);
agent->maintain_len = 0;
while (1){
read(agent->fd, &ch, 1);
printf(" %c(0x%x)\n", ch, ch);
if (agent->receive_mode == ENTM_MODE){
if (agent->entm_recv_len < ENTM_RECV_MAX){
agent->entm_recv_buf[agent->entm_recv_len++] = ch;
if (last_ch == '!' && ch == '@'){
UserSemaphoreAbandon(agent->entm_rx_notice);
}
last_ch = ch;
}
else{
printf("entm_recv_buf is_full ...\n");
}
}
else if (agent->receive_mode == AT_MODE){
if (read_len < agent->maintain_max){
agent->maintain_buffer[read_len++] = ch;
agent->maintain_len = read_len;
}else{
printf("maintain_len is_full ...\n");
is_full = true;
}
if ((ch == '\n' && last_ch == '\r')){
if (is_full){
printf("read line failed. The line data length is out of buffer size(%d)!", agent->maintain_max);
memset(agent->maintain_buffer, 0x00, agent->maintain_max);
agent->maintain_len = 0;
return -ERROR;
}
printf("GetCompleteATReply get n r ...\n");
break;
}
last_ch = ch;
}
}
return read_len;
}
ATAgentType GetATAgent(const char *agent_name)
{
struct ATAgent* result = NULL;
for (int i = 0; i < AT_AGENT_MAX; i++){
if (strcmp(at_agent_table[i].agent_name, agent_name) == 0){
result = &at_agent_table[i];
}
}
return result;
}
static int DeleteATAgent(ATAgentType agent)
{
if (agent->lock){
UserMutexDelete(agent->lock);
}
if (agent->entm_rx_notice){
UserSemaphoreDelete(agent->entm_rx_notice);
}
if (agent->fd > 0){
close(agent->fd);
}
if (agent->rsp_sem){
UserSemaphoreDelete(agent->rsp_sem);
}
if (agent->maintain_buffer){
free(agent->maintain_buffer);
}
memset(agent, 0x00, sizeof(struct ATAgent));
}
static void ATAgentReceiveProcess(void *param)
{
ATAgentType agent = (ATAgentType)param;
const struct at_urc *urc;
while (1){
if (GetCompleteATReply(agent) > 0){
if (agent->reply != NULL){
ATReplyType reply = agent->reply;
agent->maintain_buffer[agent->maintain_len - 1] = '\0';
if (agent->maintain_len < reply->reply_max_len){
memcpy(reply->reply_buffer, agent->maintain_buffer, agent->maintain_len);
reply->reply_len = agent->maintain_len;
}
else{
printf("out of memory (%d)!", reply->reply_max_len);
}
agent->reply = NULL;
UserSemaphoreAbandon(agent->rsp_sem);
}
}
}
}
static int ATAgentInit(ATAgentType agent)
{
int result = EOK;
UtaskType at_utask;
do
{
agent->maintain_len = 0;
agent->maintain_buffer = (char *)malloc(agent->maintain_max);
if (agent->maintain_buffer == NONE){
break;
}
agent->entm_rx_notice = UserSemaphoreCreate(0);
if (agent->entm_rx_notice == 0){
break;
}
agent->rsp_sem = UserSemaphoreCreate(0);
if (agent->rsp_sem == 0){
break;
}
agent->lock = UserMutexCreate();
if (agent->lock == 0){
break;
}
agent->receive_mode = ENTM_MODE;
strncpy(at_utask.name, "recv_task", strlen("recv_task"));
at_utask.func_entry = ATAgentReceiveProcess;
at_utask.func_param = agent;
at_utask.stack_size = 1024;
at_utask.prio = 18;
agent->at_handler = UserTaskCreate(at_utask);
if (agent->at_handler == 0) {
break;
}
result = EOK;
return result;
} while (1);
DeleteATAgent(agent);
result = -ERROR;
return result;
}
static int SerialBusCheck(struct ATAgent *agent, const char *device_name, struct SerialCfgParam *pserial_cfg)
{
int ret = EOK;
agent->fd = open(device_name,O_RDWR);
if (!pserial_cfg) {
struct SerialDataCfg data_cfg;
memset(&data_cfg, 0, sizeof(struct SerialDataCfg));
data_cfg.serial_baud_rate = 57600;
ioctl(agent->fd, OPE_INT, &data_cfg);
return EOK;
}
ioctl(agent->fd, OPE_INT, &pserial_cfg->data_cfg);
return EOK;
}
int InitATAgent(const char *agent_name, const char *device_name, uint32 maintain_max, struct SerialCfgParam *pserial_cfg)
{
int i = 0;
int result = EOK;
int open_result = EOK;
struct ATAgent *agent = NONE;
if (GetATAgent(agent_name) != NULL) {
return result;
}
while (i < AT_AGENT_MAX && at_agent_table[i].fd > 0) {
i++;
}
if (i >= AT_AGENT_MAX) {
printf("agent buffer(%d) is full.", AT_AGENT_MAX);
result = -ERROR;
return result;
}
agent = &at_agent_table[i];
SerialBusCheck(agent, device_name, pserial_cfg);
strcpy(agent->agent_name, agent_name);
agent->maintain_max = maintain_max;
result = ATAgentInit(agent);
if (result == EOK)
{
UserTaskStartup(agent->at_handler);
}
return result;
}
ATReplyType CreateATReply(uint32 reply_max_len)
{
ATReplyType reply = NULL;
reply = (ATReplyType)malloc(sizeof(struct ATReply));
if (reply == NULL){
printf("no more memory\n");
return NULL;
}
reply->reply_max_len = reply_max_len;
reply->reply_buffer = (char *)malloc(reply_max_len);
if (reply->reply_buffer == NULL){
printf("no more memory\n");
free(reply);
return NULL;
}
return reply;
}
void DeleteATReply(ATReplyType reply)
{
if (reply){
if (reply->reply_buffer){
free(reply->reply_buffer);
reply->reply_buffer = NULL;
}
}
if (reply){
free(reply);
reply = NULL;
}
}
@@ -0,0 +1,169 @@
/*
* 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_adapter_manager.c
* @brief manage adapter list
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#include "xs_adapter_manager.h"
#include <xs_klist.h>
#include <string.h>
#include <xs_adapter_at.h>
#include <xs_adapter.h>
#ifdef CONNECTION_COMMUNICATION_ZIGBEE
#include <xs_adapter_zigbee.h>
#endif
#ifdef CONNECTION_COMMUNICATION_BLUETOOTH
#include <xs_adapter_bluetooth.h>
#endif
#ifdef CONNECTION_COMMUNICATION_LORA
#include <xs_adapter_lora.h>
#endif
// Zigbee Adapter List
#ifdef CONNECTION_COMMUNICATION_ZIGBEE
static DoubleLinklistType zigbee_adapter_list;
void ZigbeeAdapterInit()
{
InitDoubleLinkList(&zigbee_adapter_list);
}
void ZigbeeAdapterRegister(adapter_t padapter)
{
DoubleLinkListInsertNodeAfter(&zigbee_adapter_list, &(padapter->link));
}
void* ZigbeeAdapterFind(char* name)
{
DoubleLinklistType* pnode = NONE;
DoubleLinklistType* phead = &zigbee_adapter_list;
struct AdapterZigbee* padapter = NONE;
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)){
return padapter;
}
}
return padapter;
}
#endif
// Bluetooth Adapter List
#ifdef CONNECTION_COMMUNICATION_BLUETOOTH
static DoubleLinklistType bluetooth_adapter_list;
void BluetoothAdapterInit()
{
InitDoubleLinkList(&bluetooth_adapter_list);
}
void BluetoothAdapterRegister(adapter_t padapter)
{
DoubleLinkListInsertNodeAfter(&bluetooth_adapter_list, &(padapter->link));
}
void* BluetoothAdapterFind(char* name)
{
DoubleLinklistType* pnode = NONE;
DoubleLinklistType* phead = &bluetooth_adapter_list;
struct AdapterBluetooth* padapter = NONE;
for(pnode = phead->node_next; pnode != phead; pnode = pnode->node_next) {
padapter = (struct AdapterBluetooth*)SYS_DOUBLE_LINKLIST_ENTRY(pnode, struct Adapter, link);
// KPrintf("BluetoothReceiveDemo bbb\n");
if (0 == strcmp(padapter->name, name)){
return padapter;
}
}
return padapter;
}
#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;
static int at_adapter_list_inited = 0;
void ATAdapterInit()
{
if(!at_adapter_list_inited){
InitDoubleLinkList(&at_adapter_list);
at_adapter_list_inited = 1;
}
}
void ATAdapterRegister(struct AdapterAT* at_adapter)
{
DoubleLinkListInsertNodeAfter(&at_adapter_list, &(at_adapter->link));
}
void* ATAdapterFind(uint32 adapter_id)
{
DoubleLinklistType* pnode = NONE;
DoubleLinklistType* phead = &at_adapter_list;
struct AdapterAT* padapter = NONE;
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){
return padapter;
}
}
return NULL;
}
@@ -0,0 +1,4 @@
SRC_FILES += xs_adapter_at_wifi.c \
xs_adapter_at_wifi_register.c \
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,482 @@
/*
* 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_adapter_at_wifi.c
* @brief HFA21 wifi driver base connection framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#include <string.h>
#include <user_api.h>
#include <xs_adapter_at_wifi.h>
#include <xs_adapter_manager.h>
#include <xs_adapter_at_agent.h>
#include <xs_adapter_def.h>
int WifiSetDown(struct AdapterAT *adapter_at);
/**
* @description: Close wifi
* @param padapter - wifi device pointer
*/
void WifiClose(struct Adapter *padapter)
{
WifiSetDown((struct AdapterAT *)padapter);
}
/**
* @description: Open wifi
* @param padapter - wifi device pointer
* @return success: EOK, failure: -ERROR
*/
int WifiOpen(struct Adapter *padapter)
{
uint32 result;
char *agent_name = "uart3_client";
const char *device_name = WIFI_UART_NAME;
if (InitATAgent(agent_name, device_name, 512, NULL)) {
printf("at_client_init failed ! \n");
result = -ERROR;
return result;
}
ATAgentType at_agent = GetATAgent(agent_name);
if (NULL == at_agent) {
printf("GetATAgent failed ! \n");
return -ERROR;
}
UserTaskDelay(5000);
struct AdapterAT *wifi_at_adapter = (struct AdapterAT *)padapter;
wifi_at_adapter->agent = at_agent;
}
int WifiSend(struct Adapter *padapter, const char *data, int len, bool block, int time_out, int delay, send_success cb, void *param, void* p)
{
struct AdapterAT *wifi_at_adapter = (struct AdapterAT *)padapter;
if (wifi_at_adapter->agent) {
EntmSend(wifi_at_adapter->agent, data, len);
}
}
int WifiReceive(struct Adapter *padapter, char *rev_buffer, int buffer_len, int time_out, bool block, void* p)
{
printf("wifi receive waiting ... \n");
struct AdapterAT *wifi_at_adapter = (struct AdapterAT *)padapter;
if (wifi_at_adapter->agent) {
return EntmRecv(wifi_at_adapter->agent, rev_buffer, buffer_len, 40000);
} else {
printf("Can not find agent \n");
}
}
uint32 WifiInitAtCmd(ATAgentType at_agent)
{
uint32 result;
ATReplyType reply = CreateATReply(64);
if (NULL == reply) {
printf("at_create_resp failed ! \n");
result = -ERROR;
goto __exit;
}
ATOrderSend(at_agent, REPLY_TIME_OUT, NULL, "+++");
UserTaskDelay(100);
ATOrderSend(at_agent, REPLY_TIME_OUT, NULL, "a");
UserTaskDelay(500);
return result;
__exit:
if (reply) {
DeleteATReply(reply);
}
return result;
}
static void WifiSetUpAdapter(void *parameter)
{
#define INIT_RETRY 5
#define LEN_PARA_BUF 128
uint8 server_addr_wifi[LEN_PARA_BUF] = "192.168.1.183";
uint8 server_port_wifi[LEN_PARA_BUF] = "12345";
uint8 wifi_ssid[LEN_PARA_BUF] = "AIIT-Guest";
uint8 wifi_pwd[LEN_PARA_BUF] = "";
char cmd[LEN_PARA_BUF];
struct AdapterAT *adapter_at = (struct AdapterAT *) parameter;
//struct at_device_esp8266 *esp8266 = (struct at_device_esp8266 *) device->UserData;
struct ATAgent *agent = adapter_at->agent;
ATReplyType reply = NONE;
x_err_t result = EOK;
x_size_t retry_num = INIT_RETRY;
/* wait hfa21 device startup finish */
UserTaskDelay(5000);
reply = CreateATReply(64);
if (reply == NONE) {
printf("no memory for reply create.");
return;
}
while (retry_num--) {
WifiInitAtCmd(agent);
ATOrderSend(agent, REPLY_TIME_OUT, NULL, "AT+FCLR\r");
UserTaskDelay(20000);
WifiInitAtCmd(agent);
memset(cmd,0,sizeof(cmd));
strcpy(cmd,"AT+WANN\r");
ATOrderSend(agent, REPLY_TIME_OUT, NULL, cmd);
UserTaskDelay(2500);
memset(cmd,0,sizeof(cmd));
strcpy(cmd,"AT+WSSSID=");
strcat(cmd,wifi_ssid);
strcat(cmd,"\r");
ATOrderSend(agent, REPLY_TIME_OUT, NULL, cmd);
UserTaskDelay(2500);
memset(cmd,0,sizeof(cmd));
strcpy(cmd,"AT+WSKEY=WPA2PSK,AES,");
strcat(cmd,wifi_pwd);
strcat(cmd,"\r");
ATOrderSend(agent, REPLY_TIME_OUT, NULL, cmd);
UserTaskDelay(2500);
memset(cmd,0,sizeof(cmd));
strcpy(cmd,"AT+WMODE=sta\r");
ATOrderSend(agent, REPLY_TIME_OUT, NULL, cmd);
UserTaskDelay(2500);
memset(cmd,0,sizeof(cmd));
strcat(cmd,"AT+Z\r");
ATOrderSend(agent, REPLY_TIME_OUT, NULL, cmd);
UserTaskDelay(5000);
/* initialize successfully */
result = EOK;
break;
__exit:
if (result != EOK) {
UserTaskDelay(1000);
}
}
if (reply) {
DeleteATReply(reply);
}
}
int WifiSetDown(struct AdapterAT *adapter_at)
{
WifiInitAtCmd(adapter_at->agent);
ATOrderSend(adapter_at->agent, REPLY_TIME_OUT, NULL, "AT+FCLR\r");
UserTaskDelay(20000);
}
int WifiSetUp(struct AdapterAT *adapter_at)
{
WifiSetUpAdapter(adapter_at);
return EOK;
}
int WifiSetAddr(struct AdapterAT *adapter_at, uint ip, uint gateway, uint netmask)
{
#define HFA21_SET_ADDR_EXPRESSION "+ok=%[^,],%[^,],%[^,],%[^,]\r"
char *dhcp_mode =NULL;
char *ip_str = NULL;
/* role type(server/agent) */
char *gw_str = NULL;
char *mask_str = NULL;
dhcp_mode = (char *) UserCalloc(1, 8);
ip_str = (char *) UserCalloc(1, 17);
gw_str = (char *) UserCalloc(1, 17);
mask_str = (char *) UserCalloc(1, 17);
WifiInitAtCmd(adapter_at->agent);
uint32 result = EOK;
ATReplyType reply = CreateATReply(64);
if (NULL == reply) {
printf("at_create_resp failed ! \n");
result = -ERROR;
goto __exit;
}
uint32 err = ATOrderSend(adapter_at->agent, REPLY_TIME_OUT, NULL, "AT+WANN=%s,%s,%s,%s\r", "static", IpTstr(ip), IpTstr(netmask), IpTstr(gateway));
if (err) {
printf("ATOrderSendAT+PINGfailed ! err = %d\n", err);
result = -ERROR;
goto __exit;
}
UserTaskDelay(2500);
ATOrderSend(adapter_at->agent, REPLY_TIME_OUT, reply, "AT+WANN\r");
UserTaskDelay(2500);
ATOrderSend(adapter_at->agent, REPLY_TIME_OUT, NULL, "AT+Z\r");
UserTaskDelay(5000);
const char * result_buf = GetReplyText(reply);
if (!result_buf) {
printf("send_dhcp_at_cmd AT+ result_buf = NULL");
result = -ERROR;
goto __exit;
}
char* str = strstr(result_buf, "+ok=");
printf("str is:%s\n",str);
ParseATReply(str, HFA21_SET_ADDR_EXPRESSION, dhcp_mode,ip_str,mask_str,gw_str);
printf("after configure:\n mode:%s\n ip:%s\n netmask:%s\n gateway:%s\n", dhcp_mode, ip_str, mask_str, gw_str);
__exit:
if (reply) {
DeleteATReply(reply);
}
return result;
}
int WifiDHCP(struct AdapterAT *adapter_at, bool enable)
{
int result = EOK;
ATReplyType reply = NONE;
char dhcp_status[4];
memset(dhcp_status,0,sizeof(dhcp_status));
if(enable)
strcpy(dhcp_status,"on");
else
strcpy(dhcp_status,"off");
reply = CreateATReply(64);
if (reply == NONE) {
printf("no memory for reply struct.");
return -ENOMEMORY;
}
WifiInitAtCmd(adapter_at->agent);
char cmd[LEN_PARA_BUF];
memset(cmd, 0, sizeof(cmd));
strcpy(cmd, "AT+DHCPDEN=");
strcat(cmd, dhcp_status);
strcat(cmd, "\r");
ATOrderSend(adapter_at->agent, REPLY_TIME_OUT, reply, cmd);
UserTaskDelay(2500);
ATOrderSend(adapter_at->agent, REPLY_TIME_OUT, NULL, "AT+Z\r");
UserTaskDelay(2500);
__exit:
if (reply) {
DeleteATReply(reply);
}
return result;
}
int WifiPing(struct AdapterAT *adapter_at, const char *destination,struct PingResult *ping_resp)
{
char *ping_result = NONE;
char *dst = NONE;
ping_result = (char *) UserCalloc(1, 17);
dst = (char *) UserCalloc(1, 17);
strcpy(dst, destination);
strcat(dst, "\r");
WifiInitAtCmd(adapter_at->agent);
uint32 result = EOK;
ATReplyType reply = CreateATReply(64);
if (NULL == reply) {
printf("at_create_resp failed ! \n");
result = -ERROR;
goto __exit;
}
printf("\\r = 0x%x, \\n = 0x%x\n", '\r', '\n');
//ping baidu.com
uint32 err = ATOrderSend(adapter_at->agent, REPLY_TIME_OUT, reply, "AT+PING=%s", dst);
if (err) {
printf("ATOrderSendAT+PINGfailed ! err = %d\n", err);
result = -ERROR;
goto __exit;
}
UserTaskDelay(2500);
ATOrderSend(adapter_at->agent, REPLY_TIME_OUT, NULL, "AT+Z\r");
UserTaskDelay(2000);
const char * result_buf = GetReplyText(reply);
if (!result_buf) {
printf("send_dhcp_at_cmd AT+ result_buf = NULL");
result = -ERROR;
goto __exit;
}
char* str = strstr(result_buf, "+ok=");
printf("str is:%s\n",str);
ParseATReply(str, "+ok=%s\r", ping_result);
printf("ping www.baidu.com(36.152.44.95) result is:%s\n", ping_result);
__exit:
if (reply) {
DeleteATReply(reply);
}
return result;
}
int WifiNetstat(struct AdapterAT *adapter_at)
{
#define HFA21_NETSTAT_RESP_SIZE 320
#define HFA21_NETSTAT_TYPE_SIZE 10
#define HFA21_NETSTAT_IPADDR_SIZE 17
#define HFA21_WANN_EXPRESSION "+ok=%[^,],%[^,],%[^,],%[^,]\r"
#define HFA21_LANN_EXPRESSION "+ok=%[^,],%[^,]\r"
#define HFA21_WMODE_EXPRESSION "+ok=%s\r"
ATReplyType reply = NULL;
struct ATAgent *agent = adapter_at->agent;
uint32 result;
char * result_buf = NULL;
char * str = NULL;
/* sta/ap */
char *work_mode = NULL;
/* dhcp/static */
char *ip_mode = NULL;
char *local_ipaddr = NULL;
char *gateway = NULL;
char *netmask = NULL;
local_ipaddr = (char *) UserCalloc(1, HFA21_NETSTAT_IPADDR_SIZE);
gateway = (char *) UserCalloc(1, HFA21_NETSTAT_IPADDR_SIZE);
netmask = (char *) UserCalloc(1, HFA21_NETSTAT_IPADDR_SIZE);
work_mode = (char *) UserCalloc(1, HFA21_NETSTAT_IPADDR_SIZE);
ip_mode = (char *) UserCalloc(1, HFA21_NETSTAT_IPADDR_SIZE);
reply = CreateATReply(HFA21_NETSTAT_RESP_SIZE);
if (reply == NULL) {
//printf("no memory for reply create.", device->name);
goto __exit;
}
ATOrderSend(agent, REPLY_TIME_OUT, NULL, "+++");
UserTaskDelay(100);
ATOrderSend(agent, REPLY_TIME_OUT, NULL, "a");
UserTaskDelay(2500);
if (ATOrderSend(agent, REPLY_TIME_OUT, reply, "AT+WMODE\r") < 0) {
goto __exit;
}
UserTaskDelay(2500);
result_buf = GetReplyText(reply);
if(!result_buf) {
printf("send_dhcp_at_cmd AT+ result_buf = NULL");
result = -ERROR;
goto __exit;
}
str = strstr(result_buf, "+ok=");
printf("str is:%s\n",str);
/* parse the third line of response data, get the network connection information */
ParseATReply(str, HFA21_WMODE_EXPRESSION, work_mode);
if (work_mode[0]=='S') {
if (ATOrderSend(agent, REPLY_TIME_OUT, reply, "AT+WANN\r") < 0) {
goto __exit;
}
UserTaskDelay(2500);
result_buf = GetReplyText(reply);
if (!result_buf) {
printf("send_dhcp_at_cmd AT+ result_buf = NULL");
result = -ERROR;
goto __exit;
}
str = strstr(result_buf, "+ok=");
printf("str is:%s\n",str);
/* parse the third line of response data, get the network connection information */
ParseATReply(str, HFA21_WANN_EXPRESSION, ip_mode, local_ipaddr, netmask, gateway);
} else {
if (ATOrderSend(agent, REPLY_TIME_OUT, reply, "AT+LANN\r") < 0) {
goto __exit;
}
UserTaskDelay(2500);
result_buf = GetReplyText(reply);
if (!result_buf) {
printf("send_dhcp_at_cmd AT+ result_buf = NULL");
result = -ERROR;
goto __exit;
}
str = strstr(result_buf, "+ok=");
printf("str is:%s\n",str);
/* parse the third line of response data, get the network connection information */
ParseATReply(str, HFA21_LANN_EXPRESSION, local_ipaddr, netmask);
}
ATOrderSend(adapter_at->agent, REPLY_TIME_OUT, NULL, "AT+Z\r");
UserTaskDelay(2500);
printf("work mode: %s\n", work_mode);
if (work_mode[0]=='S')
printf("ip mode: %s\nlocal ip: %s\nnetmask: %s\ngateway: %s\n", ip_mode, local_ipaddr, netmask, gateway);
else
printf("local ip: %s\nnetmask: %s\n", local_ipaddr, netmask);
return EOK;
__exit:
if (reply)
DeleteATReply(reply);
if (local_ipaddr)
UserFree(local_ipaddr);
if (netmask)
UserFree(netmask);
if (gateway)
UserFree(gateway);
if (work_mode)
UserFree(work_mode);
}
@@ -0,0 +1,73 @@
/*
* 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_adapter_at_wifi_register.c
* @brief HFA21 wifi driver register to connection framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.04.22
*/
#include <stdlib.h>
#include <user_api.h>
#include <xs_adapter_at_wifi.h>
#include <xs_adapter_manager.h>
#include <xs_adapter_at_agent.h>
const struct AdapterDone wifi_adapter_done =
{
WifiClose,
WifiOpen,
NULL,
WifiSend,
WifiReceive,
NULL,
};
const struct ATDone wifi_at_done =
{
WifiSetUp,
WifiSetDown,
WifiSetAddr,
NULL,
WifiDHCP,
WifiPing,
WifiNetstat,
NULL,
};
/**
* @description: Register wifi device
* @return success: EOK, failure: ERROR
*/
int RegisterAdapterWifi(void)
{
struct Adapterwifi *wifi_adapter = malloc(sizeof(struct Adapterwifi));
if (wifi_adapter == NULL) {
printf("out of memory\n");
return ERROR;
}
struct AdapterAT *wifi_at_adapter = (struct AdapterAT *)wifi_adapter;
struct Adapter *adapter = (struct Adapter *)wifi_adapter;
wifi_adapter->parent.atdone = wifi_at_done;
wifi_adapter->parent.parent.done = wifi_adapter_done;
wifi_at_adapter->at_adapter_id = WIFI_ADAPTER_ID;
ATAdapterInit();
ATAdapterRegister(wifi_at_adapter);
return EOK;
}
@@ -0,0 +1,11 @@
menuconfig CONNECTION_COMMUNICATION_ZIGBEE_AIIT
bool "Enable zigbee for AIIT Board"
default n
menuconfig CONNECTION_COMMUNICATION_ZIGBEE_KD233
bool "Enable zigbee for kd233"
default n
menuconfig CONNECTION_COMMUNICATION_ZIGBEE_STM32
bool "Enable zigbee for STM32F407-DISCOVERY"
default n
@@ -0,0 +1,3 @@
SRC_FILES := xs_adapter_zigbee.c xs_adaper_zigbee_register.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,45 @@
/*
* 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_AdaperZigbee_register.c
* @brief: register zigbee in initialization
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2021/4/30
*
*/
#include <xs_adapter_zigbee.h>
#include <xs_adapter_manager.h>
#include <string.h>
/* initialize to the register list*/
int RegisterAdapterZigbee(void)
{
static struct AdapterZigbee zigbee_adapter;
memset(&zigbee_adapter, 0, sizeof(zigbee_adapter));
static struct AdapterDone zigbee_send_done = {
.NetAiitOpen = ZigbeeOpen,
.NetAiitClose = ZigbeeClose,
.NetAiitSend = ZigbeeSend,
.NetAiitReceive = ZigbeeReceive,
.NetAiitJoin = NULL,
.NetAiitIoctl = NULL,
};
zigbee_adapter.parent.done = zigbee_send_done;
zigbee_adapter.name = "zigbee";
ZigbeeAdapterInit();
ZigbeeAdapterRegister((adapter_t)&zigbee_adapter);
return EOK;
}
@@ -0,0 +1,190 @@
/*
* 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_AdapterZigbee.c
* @brief: zigbee open close function
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2021/4/30
*
*/
#include <xs_adapter_manager.h>
#include "xs_adapter_zigbee.h"
#include <user_api.h>
#include <bus_serial.h>
#include <dev_serial.h>
#include <string.h>
#ifdef CONNECTION_COMMUNICATION_ZIGBEE_AIIT
#define SAMPLE_UART_NAME "/dev/extuart_dev0"
int use_aiit = 1;
#endif
#ifdef CONNECTION_COMMUNICATION_ZIGBEE_KD233
#define SAMPLE_UART_NAME "/dev/uart3_dev3"
int use_aiit = 0;
#endif
#ifdef CONNECTION_COMMUNICATION_ZIGBEE_STM32
#define SAMPLE_UART_NAME "/dev/usart3_dev3"
int use_aiit = 0;
#endif
static int serial_fd;
static int32_t zigbeereceive;
static int rx_sem;
char zigbee_buffer[NAME_NUM_MAX ]={0};
/* initialize srial port to open zigbee*/
int ZigbeeOpen(struct Adapter *padapter)
{
/* Open device in read-write mode */
serial_fd = open(SAMPLE_UART_NAME,O_RDWR);
/* set serial config, serial_baud_rate = 115200 */
struct SerialDataCfg cfg;
cfg.serial_baud_rate = BAUD_RATE_115200;
cfg.serial_data_bits = DATA_BITS_8;
cfg.serial_stop_bits = STOP_BITS_1;
cfg.serial_parity_mode = PARITY_NONE;
cfg.serial_bit_order = 0;
cfg.serial_invert_mode = 0;
cfg.serial_buffer_size = 128;
/*aiit board use ch438, so it nees more serial configuration*/
if (use_aiit==1){
cfg.ext_uart_no = 0;
cfg.port_configure = 0;
}
ioctl(serial_fd, 0, &cfg);
UserTaskDelay(1000);
printf("Zigbee ready\n");
return 0;
}
/* send message to srial port*/
int ZigbeeSend(struct Adapter *padapter, const char* data, int len, bool block, int time_out, int delay, send_success cb, void* param, void* reserved)
{
write(serial_fd,data,strlen(data));
return 0;
}
/*thread to read message from srial port*/
void SerialThreadEntry(void *parameter)
{
char ch;
int i = 0;
int n;
int run = 0;
while (1){
n = read(serial_fd,&ch,1);
if (n>0){
if (ch == '~'){
UserSemaphoreAbandon(rx_sem);
run = 1;
break;
}
zigbee_buffer[i++] = ch;
}
if (run ==1)
break;
}
}
int ZigbeeReceive(struct Adapter *padapter, char* rev_buffer, int buffer_len,int time_out, bool block, void* reserved)
{
x_err_t ret = EOK;
/* Set callback function */
/* Create thread serial */
UtaskType recv;
recv.name[0] = 'z';
recv.func_entry = SerialThreadEntry;
recv.func_param = NONE;
recv.stack_size = 1024;
recv.prio = 25;
memset(zigbee_buffer, 0, sizeof(zigbee_buffer));
/* Initialize semaphore */
rx_sem = UserSemaphoreCreate(0);
zigbeereceive = UserTaskCreate(recv);
UserTaskStartup(zigbeereceive);
/*copy to the receive buffer*/
UserSemaphoreObtain(rx_sem,-1);
memcpy(rev_buffer,zigbee_buffer,strlen(zigbee_buffer)+1 );
return ret;
}
void ZigbeeSettingDemo(int argc, char *argv[])
{
adapter_t padapter = ZigbeeAdapterFind("zigbee");
if (NONE == padapter){
KPrintf("adapter find failed!\n");
return;
}
/*Open adapter*/
if (0 != padapter->done.NetAiitOpen(padapter)){
KPrintf("adapter open failed!\n");
return;
}
ZigbeeOpen(padapter);
/*zigbee communication settings*/
/*it can be changed if needed*/
char *set0 = "+++";
char *set1_1 = "AT+DEV=C"; /*set device type for coordinater*/
char *set1_2 = "AT+DEV=E"; /*set device type for end device*/
char *set2 = "AT+MODE=1"; /*device mode 1 : passthrough */
char *set3 = "AT+PANID=A1B2"; /* set PANID*/
char *set4 = "AT+CH=11"; /* set channel*/
char *set5 = "AT+EXIT"; /* exit AT mode*/
write(serial_fd,set0,strlen(set0));
UserTaskDelay(1000);
/*type something in the command line to set this zigbee as coordinater*/
/*otherwise it is an end device*/
if (argc == 2){
write(serial_fd,set1_1,strlen(set1_1));
UserTaskDelay(1000); /*zigbee needs some time to process input message*/
}else{
write(serial_fd,set1_2,strlen(set1_2));
UserTaskDelay(1000);
}
write(serial_fd,set2,strlen(set2));
UserTaskDelay(1000);
write(serial_fd,set3,strlen(set3));
UserTaskDelay(1000);
write(serial_fd,set4,strlen(set4));
UserTaskDelay(1000);
write(serial_fd,set5,strlen(set5));
UserTaskDelay(1000);
printf("zigbee setting success!\n");
}
#ifndef SEPARATE_COMPILE
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
ZigbeeSettingDemo, ZigbeeSettingDemo, zigbee send function );
#endif
void ZigbeeClose(struct Adapter *padapter)
{
UserTaskDelete(zigbeereceive);
close(serial_fd);
}
@@ -0,0 +1,11 @@
menu "connection"
menuconfig CONNECTION_ADAPTER
bool "Enable adapter"
default n
if CONNECTION_ADAPTER
source "$KERNEL_DIR/framework/connection/Adapter/Kconfig"
endif
endmenu
@@ -0,0 +1,5 @@
ifeq ($(CONFIG_CONNECTION_ADAPTER), y)
SRC_DIR += Adapter
endif
include $(KERNEL_ROOT)/compiler.mk