solve the compile problem of tflite in xiuos

IT is  OK
This commit is contained in:
xuedongliang 2021-09-14 14:37:02 +08:00
commit cd9a3ee143
301 changed files with 150 additions and 68275 deletions

View File

@ -61,7 +61,7 @@ static struct InitDesc framework[] =
static struct InitDesc sensor_desc[] = static struct InitDesc sensor_desc[] =
{ {
#ifdef SENSOR_DEVICE_ZG09 #ifdef SENSOR_DEVICE_D124
{ "d124_voice", D124VoiceInit }, { "d124_voice", D124VoiceInit },
#endif #endif

View File

@ -1,7 +1,13 @@
menu "knowing app" menu "knowing app"
source "$APP_DIR/Applications/knowing_app/mnist/Kconfig" menuconfig APPLICATION_KNOWING
source "$APP_DIR/Applications/knowing_app/face_detect/Kconfig" bool "Using knowing apps"
source "$APP_DIR/Applications/knowing_app/instrusion_detect/Kconfig" default n
source "$APP_DIR/Applications/knowing_app/helmet_detect/Kconfig"
source "$APP_DIR/Applications/knowing_app/iris_ml_demo/Kconfig" if APPLICATION_KNOWING
source "$APP_DIR/Applications/knowing_app/mnist/Kconfig"
source "$APP_DIR/Applications/knowing_app/face_detect/Kconfig"
source "$APP_DIR/Applications/knowing_app/instrusion_detect/Kconfig"
source "$APP_DIR/Applications/knowing_app/helmet_detect/Kconfig"
source "$APP_DIR/Applications/knowing_app/iris_ml_demo/Kconfig"
endif
endmenu endmenu

View File

@ -0,0 +1,3 @@
SRC_DIR := mnist
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,7 @@
SRC_FILES := \
main.cpp \
mnistmain.c
CPPPATHS += -I.
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,3 +1,4 @@
#include <cstdio>
#include <transform.h> #include <transform.h>
#include <stdio.h> #include <stdio.h>

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiOS 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: mnistmain.c
* @brief: start mnist function
* @version: 1.0
* @author: AIIT XUOS Lab
* @date: 2021/4/30
*
*/
#include <transform.h>
void mnist_app(void);
int tfmnist(void) {
mnist_app();
}
// #ifndef SEPARATE_COMPILE
// SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0)|SHELL_CMD_DISABLE_RETURN, tfmnist, tfmnist, run mnist demo of tflite);
// #endif

View File

@ -22,6 +22,7 @@ menu "Framework"
source "$APP_DIR/Framework/connection/Kconfig" source "$APP_DIR/Framework/connection/Kconfig"
source "$APP_DIR/Framework/knowing/Kconfig" source "$APP_DIR/Framework/knowing/Kconfig"
source "$APP_DIR/Framework/control/Kconfig" source "$APP_DIR/Framework/control/Kconfig"
source "$APP_DIR/Framework/security/Kconfig"
endmenu endmenu

View File

@ -9,13 +9,16 @@ ifeq ($(CONFIG_SUPPORT_CONNECTION_FRAMEWORK),y)
endif endif
ifeq ($(CONFIG_SUPPORT_KNOWING_FRAMEWORK),y) ifeq ($(CONFIG_SUPPORT_KNOWING_FRAMEWORK),y)
SRC_DIR += know SRC_DIR += knowing
endif endif
ifeq ($(CONFIG_SUPPORT_CONTROL_FRAMEWORK),y) ifeq ($(CONFIG_SUPPORT_CONTROL_FRAMEWORK),y)
SRC_DIR += control SRC_DIR += control
endif endif
ifeq ($(CONFIG_CRYPTO),y)
SRC_DIR += security
endif
include $(KERNEL_ROOT)/compiler.mk include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,13 +1,4 @@
SRC_DIR := SRC_DIR := tensorflow-lite
ifeq ($(CONFIG_SUPPORT_KNOW_FRAMEWORK),y)
ifeq ($(CONFIG_USING_TFLITE_MNIST),y)
SRC_DIR += tflite_mnist
endif
ifeq ($(CONFIG_USING_TFLITE_SIN),y)
SRC_DIR += tflite_sin
endif
endif
include $(KERNEL_ROOT)/compiler.mk include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,6 +1,7 @@
menuconfig USING_TENSORFLOWLITEMICRO menuconfig USING_TENSORFLOWLITEMICRO
bool "Tensorflow Lite for Micro" bool "Tensorflow Lite for Micro"
select RT_USING_CPLUSPLUS select RT_USING_CPLUSPLUS
select LIB_CPLUSPLUS
default n default n
if USING_TENSORFLOWLITEMICRO if USING_TENSORFLOWLITEMICRO

View File

@ -1,3 +1,3 @@
SRC_DIR := tflite-mcu SRC_DIR := tensorflow-lite-for-mcu
include $(KERNEL_ROOT)/compiler.mk include $(KERNEL_ROOT)/compiler.mk

View File

@ -64,18 +64,19 @@ TFLITE_SRCS = \
source/tensorflow/lite/micro/kernels/tanh.cc \ source/tensorflow/lite/micro/kernels/tanh.cc \
source/tensorflow/lite/micro/kernels/transpose_conv.cc \ source/tensorflow/lite/micro/kernels/transpose_conv.cc \
source/tensorflow/lite/micro/kernels/unpack.cc \ source/tensorflow/lite/micro/kernels/unpack.cc \
source/tensorflow/lite/micro/kernels/add.cc \ source/tensorflow/lite/micro/kernels/normal/add.cc \
source/tensorflow/lite/micro/kernels/conv.cc \ source/tensorflow/lite/micro/kernels/normal/conv.cc \
source/tensorflow/lite/micro/kernels/depthwise_conv.cc \ source/tensorflow/lite/micro/kernels/normal/depthwise_conv.cc \
source/tensorflow/lite/micro/kernels/fully_connected.cc \ source/tensorflow/lite/micro/kernels/normal/fully_connected.cc \
source/tensorflow/lite/micro/kernels/mul.cc \ source/tensorflow/lite/micro/kernels/normal/mul.cc \
source/tensorflow/lite/micro/kernels/pooling.cc \ source/tensorflow/lite/micro/kernels/normal/pooling.cc \
source/tensorflow/lite/micro/kernels/softmax.cc \ source/tensorflow/lite/micro/kernels/normal/softmax.cc \
source/tensorflow/lite/micro/kernels/svdf.cc source/tensorflow/lite/micro/kernels/normal/svdf.cc
ifeq ($(CONFIG_INTELLIGENT_TFLITE),y) # ifeq ($(CONFIG_INTELLIGENT_TFLITE),y)
ifeq ($(CONFIG_USING_TENSORFLOWLITEMICRO),y)
SRC_FILES := $(TFLITE_SRCS) tf_fini_fix.c SRC_FILES := $(TFLITE_SRCS) tf_fini_fix.c
#CPPPATHS += \ CPPPATHS += \
-Isource \ -Isource \
-Isource/third_party/gemmlowp \ -Isource/third_party/gemmlowp \
-Isource/third_party/flatbuffers/include \ -Isource/third_party/flatbuffers/include \

View File

@ -27,7 +27,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <xiuos.h> #include <transform.h>
#define BIGNUMBER_SIZE_8WORD 8 #define BIGNUMBER_SIZE_8WORD 8
#define BIGNUMBER_SIZE_16WORD 16 #define BIGNUMBER_SIZE_16WORD 16

View File

@ -19,7 +19,7 @@
*/ */
#include <sm3.h> #include <sm3.h>
#include <xiuos.h> #include <transform.h>
void sm3_test_case(){ void sm3_test_case(){
uint8_t result[SM3_DIGEST_LENGTH] = { 0 }; uint8_t result[SM3_DIGEST_LENGTH] = { 0 };

View File

@ -19,7 +19,7 @@
*/ */
#include <sm4.h> #include <sm4.h>
#include <xiuos.h> #include <transform.h>
void sm4_test_case(){ void sm4_test_case(){
unsigned char ukey[16] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe ,0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }; unsigned char ukey[16] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe ,0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 };

View File

@ -40,4 +40,4 @@ void abort(void)
} }
while (1); while (1);
} }

View File

@ -242,7 +242,7 @@ static inline unsigned long KSwitch0(unsigned int knum)
{ {
uintptr_t param[1] = {0}; uintptr_t param[1] = {0};
uint8_t num = 0; uint8_t num = 0;
SERVICETABLE[knum].fun(knum, param, num); return SERVICETABLE[knum].fun(knum, param, num);
} }
static inline unsigned long KSwitch1(unsigned int knum, unsigned long arg1) static inline unsigned long KSwitch1(unsigned int knum, unsigned long arg1)
@ -250,7 +250,7 @@ static inline unsigned long KSwitch1(unsigned int knum, unsigned long arg1)
uintptr_t param[1] = {0}; uintptr_t param[1] = {0};
uint8_t num = 0; uint8_t num = 0;
param[0] = arg1; param[0] = arg1;
SERVICETABLE[knum].fun(knum, param, num ); return SERVICETABLE[knum].fun(knum, param, num );
} }
@ -261,7 +261,7 @@ static inline unsigned long KSwitch2(unsigned int knum, unsigned long arg1,
uint8_t num = 0; uint8_t num = 0;
param[0] = arg1; param[0] = arg1;
param[1] = arg2; param[1] = arg2;
SERVICETABLE[knum].fun(knum, param, num ); return SERVICETABLE[knum].fun(knum, param, num );
} }
@ -274,7 +274,7 @@ static inline unsigned long KSwitch3(unsigned int knum, unsigned long arg1,
param[1] = arg2; param[1] = arg2;
param[2] = arg3; param[2] = arg3;
SERVICETABLE[knum].fun(knum, param, num ); return SERVICETABLE[knum].fun(knum, param, num );
} }
static inline unsigned long KSwitch4(unsigned int knum, unsigned long arg1, static inline unsigned long KSwitch4(unsigned int knum, unsigned long arg1,
@ -287,7 +287,7 @@ static inline unsigned long KSwitch4(unsigned int knum, unsigned long arg1,
param[1] = arg2; param[1] = arg2;
param[2] = arg3; param[2] = arg3;
param[3] = arg4; param[3] = arg4;
SERVICETABLE[knum].fun(knum, param, num ); return SERVICETABLE[knum].fun(knum, param, num );
} }
static inline unsigned long KSwitch5(unsigned int knum, unsigned long arg1, static inline unsigned long KSwitch5(unsigned int knum, unsigned long arg1,
@ -301,7 +301,7 @@ static inline unsigned long KSwitch5(unsigned int knum, unsigned long arg1,
param[2] = arg3; param[2] = arg3;
param[3] = arg4; param[3] = arg4;
param[4] = arg5; param[4] = arg5;
SERVICETABLE[knum].fun(knum, param, num ); return SERVICETABLE[knum].fun(knum, param, num );
} }
static inline unsigned long KSwitch6(unsigned int knum, unsigned long arg1, static inline unsigned long KSwitch6(unsigned int knum, unsigned long arg1,
@ -317,7 +317,7 @@ static inline unsigned long KSwitch6(unsigned int knum, unsigned long arg1,
param[3] = arg4; param[3] = arg4;
param[4] = arg5; param[4] = arg5;
param[5] = arg6; param[5] = arg6;
SERVICETABLE[knum].fun(knum, param, num ); return SERVICETABLE[knum].fun(knum, param, num );
} }
#endif #endif

View File

@ -31,6 +31,12 @@ SECTIONS
*(.rodata .rodata*) *(.rodata .rodata*)
*(.glue_7) *(.glue_7)
*(.glue_7t) *(.glue_7t)
PROVIDE(__ctors_start__ = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE(__ctors_end__ = .);
PROVIDE(_uetext = ABSOLUTE(.)); PROVIDE(_uetext = ABSOLUTE(.));
} > usram } > usram

View File

@ -1,15 +0,0 @@
menu "APP Framework"
source "$KERNEL_DIR/framework/connection/Kconfig"
source "$KERNEL_DIR/framework/intelligent/Kconfig"
source "$KERNEL_DIR/framework/control/Kconfig"
source "$KERNEL_DIR/lib/Kconfig"
source "$KERNEL_DIR/framework/security/Kconfig"
endmenu

View File

@ -1,3 +0,0 @@
SRC_DIR := intelligent security
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,31 +0,0 @@
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

View File

@ -1,32 +0,0 @@
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

View File

@ -1,3 +0,0 @@
SRC_FILES := xs_adapter_bluetooth.c xs_adaper_bluetooth_register.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,45 +0,0 @@
/*
* 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;
}

View File

@ -1,155 +0,0 @@
/*
* 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);
}

View File

@ -1,5 +0,0 @@
SRC_FILES += xs_adapterAT_ethernet.c \
xs_adapterAT_ethernet_register.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,409 +0,0 @@
/*
* 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);
}

View File

@ -1,70 +0,0 @@
/*
* 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;
}

View File

@ -1,72 +0,0 @@
/*
* 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

View File

@ -1,94 +0,0 @@
/*
* 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

View File

@ -1,81 +0,0 @@
/*
* 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

View File

@ -1,48 +0,0 @@
/*
* 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

View File

@ -1,57 +0,0 @@
/*
* 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

View File

@ -1,50 +0,0 @@
/*
* 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

View File

@ -1,41 +0,0 @@
/*
* 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

View File

@ -1,77 +0,0 @@
/*
* 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

View File

@ -1,184 +0,0 @@
/*
* 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

View File

@ -1,43 +0,0 @@
/*
* 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

View File

@ -1,41 +0,0 @@
/*
* 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

View File

@ -1,30 +0,0 @@
#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

View File

@ -1,3 +0,0 @@
SRC_FILES := xs_adapter_lora.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,849 +0,0 @@
/*
* 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;
}

View File

@ -1,3 +0,0 @@
SRC_DIR := bc28
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,3 +0,0 @@
SRC_FILES := xs_adapter_at_nbiot.c xs_adapter_at_nbiot_register.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,339 +0,0 @@
/*
* 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;
}

View File

@ -1,69 +0,0 @@
/*
* 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;
}

View File

@ -1,4 +0,0 @@
SRC_FILES := xs_adapter_manager.c \
xs_adapter_at_agent.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,485 +0,0 @@
/*
* 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;
}
}

View File

@ -1,169 +0,0 @@
/*
* 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;
}

View File

@ -1,4 +0,0 @@
SRC_FILES += xs_adapter_at_wifi.c \
xs_adapter_at_wifi_register.c \
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,482 +0,0 @@
/*
* 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);
}

View File

@ -1,73 +0,0 @@
/*
* 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;
}

View File

@ -1,11 +0,0 @@
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

View File

@ -1,3 +0,0 @@
SRC_FILES := xs_adapter_zigbee.c xs_adaper_zigbee_register.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,45 +0,0 @@
/*
* 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;
}

View File

@ -1,190 +0,0 @@
/*
* 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);
}

View File

@ -1,11 +0,0 @@
menu "connection"
menuconfig CONNECTION_ADAPTER
bool "Enable adapter"
default n
if CONNECTION_ADAPTER
source "$KERNEL_DIR/framework/connection/Adapter/Kconfig"
endif
endmenu

View File

@ -1,5 +0,0 @@
ifeq ($(CONFIG_CONNECTION_ADAPTER), y)
SRC_DIR += Adapter
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,2 +0,0 @@
menu "Control"
endmenu

View File

@ -1,5 +0,0 @@
menu "Intelligence"
source "$KERNEL_DIR/framework/intelligent/tflite-mcu/Kconfig"
endmenu

View File

@ -1,4 +0,0 @@
config INTELLIGENT_TFLITE
bool "Tensorflow Lite for Micro"
select LIB_CPLUSPLUS
default n

View File

@ -1,203 +0,0 @@
Copyright 2019 The TensorFlow Authors. All rights reserved.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,139 +0,0 @@
/* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#ifndef TENSORFLOW_CORE_PUBLIC_VERSION_H_
#define TENSORFLOW_CORE_PUBLIC_VERSION_H_
// TensorFlow uses semantic versioning, see http://semver.org/.
// Also update tensorflow/tensorflow.bzl and
// tensorflow/tools/pip_package/setup.py
#define TF_MAJOR_VERSION 2
#define TF_MINOR_VERSION 5
#define TF_PATCH_VERSION 0
// TF_VERSION_SUFFIX is non-empty for pre-releases (e.g. "-alpha", "-alpha.1",
// "-beta", "-rc", "-rc.1")
#define TF_VERSION_SUFFIX ""
#define TF_STR_HELPER(x) #x
#define TF_STR(x) TF_STR_HELPER(x)
// e.g. "0.5.0" or "0.6.0-alpha".
#define TF_VERSION_STRING \
(TF_STR(TF_MAJOR_VERSION) "." TF_STR(TF_MINOR_VERSION) "." TF_STR( \
TF_PATCH_VERSION) TF_VERSION_SUFFIX)
// GraphDef compatibility versions (the versions field in graph.proto).
//
// Each graph has producer and min_consumer versions, and each
// consumer has its own version and a min_producer. In addition, graphs can
// mark specific consumer versions as bad (to prevent bugs from executing).
// A consumer will execute a graph if the consumer's version is at least the
// graph's min_consumer, the graph's producer version is at least the consumer's
// min_producer, and the consumer version isn't specifically disallowed by the
// graph.
//
// By default, newly created graphs have producer version TF_GRAPH_DEF_VERSION
// min_consumer TF_GRAPH_DEF_MIN_CONSUMER, and no other bad consumer versions.
//
// Version history:
//
// 0. Graphs created before GraphDef versioning
// 1. First real version (2dec2015)
// 2. adjust_contrast only takes float, doesn't perform clamping (11dec2015)
// 3. Remove TileGrad, since it was equivalent to reduce_sum (30dec2015)
// 4. When support for this version is removed, we can safely make AttrValue
// parsing more strict with respect to empty list values (see
// 111635679, 7jan2016).
// 5. Graphs are wholly-validated during Session::Create() (7jan2016).
// 6. TensorFlow is scalar strict within Google (27jan2016).
// 7. Remove TopK in favor of TopKV2 (5feb2016).
// 8. Replace RandomCrop from C++ with pure Python (5feb2016).
// 9. Deprecate batch_norm_with_global_normalization (16feb2016).
// 10. Deprecate conv3d_backprop_{filter,input} (10jun2016).
// 11. Deprecate {batch}_self_adjoint_eig (3aug2016).
// 12. Graph consumers understand the node_def field of FunctionDef (22aug2016).
// 13. Deprecate multiple batch linear algebra ops (9sep2016).
// 14. Deprecate batch_matrix_* ops. (10sep2016).
// 15. Deprecate batch_fft_* ops. (14sep2016).
// 16. Deprecate tensor_array (v1) ops in favor of v2 (10nov2016).
// 17. Deprecate inv (11nov2016).
// 17. Expose reverse_v2 (10nov2016)
// 18. Add VariableV2 (30nov2016)
// 19. Deprecated ops created by models moved out of core SkipGram, NegTrain.
// (08dec2016)
// 20. Catch all version 1.0 changes to Python API generation. SplitV is now
// used for tf.split, ReverseV2 is now used by tf.reverse, ConcatV2 is
// now used by tf.concat. Graphs use flooring
// division and mod semantics. TensorArrayV3. (12dec2016)
// Also considered the version for when it is required for reduction
// ops' indices to be scalar or vector, and not higher rank.
// Some earlier graph def versions allowed this.
// 21. Dropped FunctionDef.Node support, switched to node_def introduced
// in version 12. (11jan2017)
// 22. Placeholder now can specify and enforce scalar and partial
// shapes, particularly when restoring a graph from GraphDef
// produced at version 22 or later. (04/10/2016)
// 23. Remove NonMaxSuppression in favor of NonMaxSuppressionV2.
// 24. Deprecate lookup ops (v1) ops in favor of v2 (30may2017)
// 25. Deprecate stack (v1) ops in favor of v2 (2017/6/15).
// 25. Deprecate RandomPoisson (v1) ops in favor of v2 (2017/10/25).
// 26. Add a bool 'stripped_default_attrs' to MetaInfoDef indicating
// whether default-valued attrs have been stripped from the nodes in the
// GraphDef. (7dec2017)
// 27. Deprecate TensorArray ops v2 in favor of v3 and deprecated io_ops
// deprecated in favor of V2 ops. (2018/01/23)
// 28. Deprecate MatrixExponential op in favor of Python implementation.
// (2018/08/21).
// (2019/02/15). Added `control_ret` field to FunctionDef proto, and
// `control_output` field to OpDef proto.
// 29. Deprecate StatefulStandardNormal op in favor of StatefulStandardNormalV2.
// (2019/03/25).
// (2019/04/17). Added `arg_attr` field to FunctionDefProto.
// 30. (2019/05/09) First date based GraphDef version. GraphDef
// versions advance by 1 each day after this point.
#define TF_GRAPH_DEF_VERSION_MIN_PRODUCER 0
#define TF_GRAPH_DEF_VERSION_MIN_CONSUMER 0
#define TF_GRAPH_DEF_VERSION 639 // Updated: 2021/1/7
// Checkpoint compatibility versions (the versions field in SavedSliceMeta).
//
// The checkpoint versions have the same semantics as GraphDef versions, but the
// numbering scheme is separate. We have no plans to ever deprecate checkpoint
// versions, but it's good to have this in place in case we ever need to.
//
// Version history:
//
// 0. Checkpoints saved before checkpoint versioning.
// 1. First real version (10feb2015).
#define TF_CHECKPOINT_VERSION_MIN_PRODUCER 0
#define TF_CHECKPOINT_VERSION_MIN_CONSUMER 0
#define TF_CHECKPOINT_VERSION 1
/// Version query functions (defined in generated version_info.cc)
// Host compiler version (declared elsewhere to be __VERSION__)
extern const char* tf_compiler_version();
// The git commit designator when tensorflow was built
// If no git repository, this will be "internal".
extern const char* tf_git_version();
// Value of the _GLIBCXX_USE_CXX11_ABI flag, or 0 if it's not set.
extern int tf_cxx11_abi_flag();
// Returns 1 if build is monolithic, or 0 otherwise.
extern int tf_monolithic_build();
#endif // TENSORFLOW_CORE_PUBLIC_VERSION_H_

View File

@ -1,484 +0,0 @@
/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#ifndef TENSORFLOW_LITE_C_BUILTIN_OP_DATA_H_
#define TENSORFLOW_LITE_C_BUILTIN_OP_DATA_H_
#include <stdint.h>
#include "tensorflow/lite/c/common.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// TfLiteReshapeParams can't have dynamic data so we fix the maximum possible
// number of dimensions.
#define TFLITE_RESHAPE_PARAMS_MAX_DIMENSION_COUNT 8
// TODO(aselle): Consider using "if this then that" for testing.
// Useful placeholder to put in otherwise empty structs to avoid size warnings.
typedef struct {
char dummy;
} EmptyStructPlaceholder;
// IMPORTANT: All new members of structs must be added at the end to ensure
// backwards compatibility.
// Possible padding types (for convolutions)
typedef enum {
kTfLitePaddingUnknown = 0,
kTfLitePaddingSame,
kTfLitePaddingValid,
} TfLitePadding;
typedef enum {
kTfLiteMirrorPaddingUnknown = 0,
kTfLiteMirrorPaddingReflect,
kTfLiteMirrorPaddingSymmetric,
} TfLiteMirrorPaddingMode;
// TODO(b/130259536): We should move this out of builtin_op_data.
typedef struct {
int width;
int height;
int width_offset;
int height_offset;
} TfLitePaddingValues;
typedef struct {
TfLiteMirrorPaddingMode mode;
} TfLiteMirrorPaddingParams;
// Possible fused activation functions.
// TODO(aselle): rename to TfLiteActivation
typedef enum {
kTfLiteActNone = 0,
kTfLiteActRelu,
kTfLiteActReluN1To1, // min(max(-1, x), 1)
kTfLiteActRelu6, // min(max(0, x), 6)
kTfLiteActTanh,
kTfLiteActSignBit,
kTfLiteActSigmoid,
} TfLiteFusedActivation;
typedef struct {
// Parameters for CONV_2D version 1.
TfLitePadding padding;
int stride_width;
int stride_height;
TfLiteFusedActivation activation;
// Parameters for CONV_2D version 2.
// Note: Version 2 supports dilation values not equal to 1.
int dilation_width_factor;
int dilation_height_factor;
} TfLiteConvParams;
typedef struct {
TfLitePadding padding;
int stride_width;
int stride_height;
int filter_width;
int filter_height;
TfLiteFusedActivation activation;
struct {
TfLitePaddingValues padding;
} computed;
} TfLitePoolParams;
typedef struct {
// Parameters for DepthwiseConv version 1 or above.
TfLitePadding padding;
int stride_width;
int stride_height;
// `depth_multiplier` is redundant. It's used by CPU kernels in
// TensorFlow 2.0 or below, but ignored in versions above.
//
// The information can be deduced from the shape of input and the shape of
// weights. Since the TFLiteConverter toolchain doesn't support partially
// specified shapes, relying on `depth_multiplier` stops us from supporting
// graphs with dynamic shape tensors.
//
// Note: Some of the delegates (e.g. NNAPI, GPU) are still relying on this
// field.
int depth_multiplier;
TfLiteFusedActivation activation;
// Parameters for DepthwiseConv version 2 or above.
int dilation_width_factor;
int dilation_height_factor;
} TfLiteDepthwiseConvParams;
typedef struct {
int rank;
TfLiteFusedActivation activation;
// Parameter for SVDF version 4.
bool asymmetric_quantize_inputs;
} TfLiteSVDFParams;
typedef struct {
TfLiteFusedActivation activation;
// Parameter for RNN version 3.
bool asymmetric_quantize_inputs;
} TfLiteRNNParams;
typedef struct {
bool time_major;
TfLiteFusedActivation activation;
// Parameter for Sequence RNN version 3.
bool asymmetric_quantize_inputs;
} TfLiteSequenceRNNParams;
typedef struct {
bool time_major;
TfLiteFusedActivation activation;
bool merge_outputs;
// Parameter for Bidirectional RNN verison 3.
bool asymmetric_quantize_inputs;
} TfLiteBidirectionalSequenceRNNParams;
typedef enum {
kTfLiteFullyConnectedWeightsFormatDefault = 0,
kTfLiteFullyConnectedWeightsFormatShuffled4x16Int8 = 1,
} TfLiteFullyConnectedWeightsFormat;
typedef struct {
// Parameters for FullyConnected version 1 or above.
TfLiteFusedActivation activation;
// Parameters for FullyConnected version 2 or above.
TfLiteFullyConnectedWeightsFormat weights_format;
// Parameters for FullyConnected version 5 or above.
// If set to true, then the number of dimensions in the input and the output
// tensors are the same. Furthermore, all but the last dimension of the input
// and output shapes will be equal.
bool keep_num_dims;
// Parameters for FullyConnected version 7 or above.
// If set to true and the weights are quantized, then non constant inputs
// are quantized at evaluation time with asymmetric quantization.
bool asymmetric_quantize_inputs;
} TfLiteFullyConnectedParams;
typedef enum {
kTfLiteLshProjectionUnknown = 0,
kTfLiteLshProjectionSparse = 1,
kTfLiteLshProjectionDense = 2,
} TfLiteLSHProjectionType;
typedef struct {
TfLiteLSHProjectionType type;
} TfLiteLSHProjectionParams;
typedef struct {
float beta;
} TfLiteSoftmaxParams;
typedef struct {
int axis;
TfLiteFusedActivation activation;
} TfLiteConcatenationParams;
typedef struct {
TfLiteFusedActivation activation;
// Parameter added for the version 4.
bool pot_scale_int16;
} TfLiteAddParams;
typedef struct {
EmptyStructPlaceholder placeholder;
} TfLiteSpaceToBatchNDParams;
typedef struct {
EmptyStructPlaceholder placeholder;
} TfLiteBatchToSpaceNDParams;
typedef struct {
bool adj_x;
bool adj_y;
// Parameters for BatchMatMul version 4 or above.
// If set to true and the weights are quantized, then non constant inputs
// are quantized at evaluation time with asymmetric quantization.
bool asymmetric_quantize_inputs;
} TfLiteBatchMatMulParams;
typedef struct {
TfLiteFusedActivation activation;
} TfLiteMulParams;
typedef struct {
TfLiteFusedActivation activation;
// Parameter added for the version 5.
bool pot_scale_int16;
} TfLiteSubParams;
typedef struct {
TfLiteFusedActivation activation;
} TfLiteDivParams;
typedef struct {
TfLiteFusedActivation activation;
} TfLiteL2NormParams;
typedef struct {
int radius;
float bias;
float alpha;
float beta;
} TfLiteLocalResponseNormParams;
typedef enum {
kTfLiteLSTMFullKernel = 0,
kTfLiteLSTMBasicKernel
} TfLiteLSTMKernelType;
typedef struct {
// Parameters for LSTM version 1.
TfLiteFusedActivation activation;
float cell_clip;
float proj_clip;
// Parameters for LSTM version 2.
// kTfLiteLSTMBasicKernel is only supported in version 2 or above.
TfLiteLSTMKernelType kernel_type;
// Parameters for LSTM version 4.
bool asymmetric_quantize_inputs;
} TfLiteLSTMParams;
typedef struct {
// Parameters needed for the underlying LSTM.
TfLiteFusedActivation activation;
float cell_clip;
float proj_clip;
// If set to true then the first dimension is time, otherwise batch.
bool time_major;
// Parameter for unidirectional sequence RNN version 3.
bool asymmetric_quantize_inputs;
} TfLiteUnidirectionalSequenceLSTMParams;
typedef struct {
// Parameters supported by version 1:
// Parameters inherited for the LSTM kernel.
TfLiteFusedActivation activation;
float cell_clip;
float proj_clip;
// If true, store the outputs of both directions in the first output.
bool merge_outputs;
// Parameters supported by version 2:
// If set to true then the first dimension is time, otherwise batch.
bool time_major;
// Parameters supported by version 4:
// If set to true, then hybrid ops use asymmetric quantization for inputs.
bool asymmetric_quantize_inputs;
} TfLiteBidirectionalSequenceLSTMParams;
typedef struct {
bool align_corners;
// half_pixel_centers assumes pixels are of half the actual dimensions, and
// yields more accurate resizes. Corresponds to the same argument for the
// original TensorFlow op in TF2.0.
bool half_pixel_centers;
} TfLiteResizeBilinearParams;
typedef struct {
bool align_corners;
bool half_pixel_centers;
} TfLiteResizeNearestNeighborParams;
typedef struct {
EmptyStructPlaceholder placeholder;
} TfLitePadParams;
typedef struct {
EmptyStructPlaceholder placeholder;
} TfLitePadV2Params;
typedef struct {
// TODO(ahentz): We can't have dynamic data in this struct, at least not yet.
// For now we will fix the maximum possible number of dimensions.
int shape[TFLITE_RESHAPE_PARAMS_MAX_DIMENSION_COUNT];
int num_dimensions;
} TfLiteReshapeParams;
typedef struct {
int ngram_size;
int max_skip_size;
bool include_all_ngrams;
} TfLiteSkipGramParams;
typedef struct {
int block_size;
} TfLiteSpaceToDepthParams;
typedef struct {
int block_size;
} TfLiteDepthToSpaceParams;
typedef struct {
TfLiteType in_data_type;
TfLiteType out_data_type;
} TfLiteCastParams;
typedef enum {
kTfLiteCombinerTypeSum = 0,
kTfLiteCombinerTypeMean = 1,
kTfLiteCombinerTypeSqrtn = 2,
} TfLiteCombinerType;
typedef struct {
TfLiteCombinerType combiner;
} TfLiteEmbeddingLookupSparseParams;
typedef struct {
int axis;
} TfLiteGatherParams;
typedef struct {
EmptyStructPlaceholder placeholder;
} TfLiteTransposeParams;
typedef struct {
bool keep_dims;
} TfLiteReducerParams;
typedef struct {
int num_splits;
} TfLiteSplitParams;
typedef struct {
int num_splits;
} TfLiteSplitVParams;
typedef struct {
// TODO(ahentz): We can't have dynamic data in this struct, at least not yet.
// For now we will fix the maximum possible number of dimensions.
int squeeze_dims[8];
int num_squeeze_dims;
} TfLiteSqueezeParams;
typedef struct {
int begin_mask;
int end_mask;
int ellipsis_mask;
int new_axis_mask;
int shrink_axis_mask;
} TfLiteStridedSliceParams;
typedef struct {
TfLiteType output_type;
} TfLiteArgMaxParams;
typedef struct {
TfLiteType output_type;
} TfLiteArgMinParams;
typedef struct {
TfLitePadding padding;
int stride_width;
int stride_height;
} TfLiteTransposeConvParams;
typedef struct {
bool validate_indices;
} TfLiteSparseToDenseParams;
typedef struct {
TfLiteType out_type;
} TfLiteShapeParams;
typedef struct {
EmptyStructPlaceholder placeholder;
} TfLiteRankParams;
typedef struct {
// Parameters supported by version 1:
float min;
float max;
int num_bits;
// Parameters supported by version 2:
bool narrow_range;
} TfLiteFakeQuantParams;
typedef struct {
int values_count;
int axis;
} TfLitePackParams;
typedef struct {
int axis;
} TfLiteOneHotParams;
typedef struct {
int num;
int axis;
} TfLiteUnpackParams;
typedef struct {
float alpha;
} TfLiteLeakyReluParams;
typedef struct {
TfLiteType index_out_type;
} TfLiteUniqueParams;
typedef struct {
int seq_dim;
int batch_dim;
} TfLiteReverseSequenceParams;
typedef struct {
EmptyStructPlaceholder placeholder;
} TfLiteMatrixDiagParams;
typedef struct {
EmptyStructPlaceholder placeholder;
} TfLiteMatrixSetDiagParams;
typedef struct {
int then_subgraph_index;
int else_subgraph_index;
} TfLiteIfParams;
typedef struct {
int cond_subgraph_index;
int body_subgraph_index;
} TfLiteWhileParams;
typedef struct {
bool exclusive;
bool reverse;
} TfLiteCumsumParams;
typedef struct {
int init_subgraph_index;
} TfLiteCallOnceParams;
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // TENSORFLOW_LITE_C_BUILTIN_OP_DATA_H_

View File

@ -1,92 +0,0 @@
/* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
// This file declares types used by the pure C inference API defined in c_api.h,
// some of which are also used in the C++ and C kernel and interpreter APIs.
#ifndef TENSORFLOW_LITE_C_C_API_TYPES_H_
#define TENSORFLOW_LITE_C_C_API_TYPES_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// Define TFL_CAPI_EXPORT macro to export a function properly with a shared
// library.
#ifdef SWIG
#define TFL_CAPI_EXPORT
#else
#if defined(_WIN32)
#ifdef TFL_COMPILE_LIBRARY
#define TFL_CAPI_EXPORT __declspec(dllexport)
#else
#define TFL_CAPI_EXPORT __declspec(dllimport)
#endif // TFL_COMPILE_LIBRARY
#else
#define TFL_CAPI_EXPORT __attribute__((visibility("default")))
#endif // _WIN32
#endif // SWIG
typedef enum TfLiteStatus {
kTfLiteOk = 0,
// Generally referring to an error in the runtime (i.e. interpreter)
kTfLiteError = 1,
// Generally referring to an error from a TfLiteDelegate itself.
kTfLiteDelegateError = 2,
// Generally referring to an error in applying a delegate due to
// incompatibility between runtime and delegate, e.g., this error is returned
// when trying to apply a TfLite delegate onto a model graph that's already
// immutable.
kTfLiteApplicationError = 3
} TfLiteStatus;
// Types supported by tensor
typedef enum {
kTfLiteNoType = 0,
kTfLiteFloat32 = 1,
kTfLiteInt32 = 2,
kTfLiteUInt8 = 3,
kTfLiteInt64 = 4,
kTfLiteString = 5,
kTfLiteBool = 6,
kTfLiteInt16 = 7,
kTfLiteComplex64 = 8,
kTfLiteInt8 = 9,
kTfLiteFloat16 = 10,
kTfLiteFloat64 = 11,
kTfLiteComplex128 = 12,
kTfLiteUInt64 = 13,
} TfLiteType;
// Legacy. Will be deprecated in favor of TfLiteAffineQuantization.
// If per-layer quantization is specified this field will still be populated in
// addition to TfLiteAffineQuantization.
// Parameters for asymmetric quantization. Quantized values can be converted
// back to float using:
// real_value = scale * (quantized_value - zero_point)
typedef struct TfLiteQuantizationParams {
float scale;
int32_t zero_point;
} TfLiteQuantizationParams;
#ifdef __cplusplus
} // extern C
#endif
#endif // TENSORFLOW_LITE_C_C_API_TYPES_H_

View File

@ -1,236 +0,0 @@
/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/c/c_api_types.h"
#ifndef TF_LITE_STATIC_MEMORY
#include <stdlib.h>
#include <string.h>
#endif // TF_LITE_STATIC_MEMORY
int TfLiteIntArrayGetSizeInBytes(int size) {
static TfLiteIntArray dummy;
return sizeof(dummy) + sizeof(dummy.data[0]) * size;
}
int TfLiteIntArrayEqual(const TfLiteIntArray* a, const TfLiteIntArray* b) {
if (a == b) return 1;
if (a == NULL || b == NULL) return 0;
return TfLiteIntArrayEqualsArray(a, b->size, b->data);
}
int TfLiteIntArrayEqualsArray(const TfLiteIntArray* a, int b_size,
const int b_data[]) {
if (a == NULL) return (b_size == 0);
if (a->size != b_size) return 0;
int i = 0;
for (; i < a->size; i++)
if (a->data[i] != b_data[i]) return 0;
return 1;
}
#ifndef TF_LITE_STATIC_MEMORY
TfLiteIntArray* TfLiteIntArrayCreate(int size) {
TfLiteIntArray* ret =
(TfLiteIntArray*)malloc(TfLiteIntArrayGetSizeInBytes(size));
ret->size = size;
return ret;
}
TfLiteIntArray* TfLiteIntArrayCopy(const TfLiteIntArray* src) {
if (!src) return NULL;
TfLiteIntArray* ret = TfLiteIntArrayCreate(src->size);
if (ret) {
memcpy(ret->data, src->data, src->size * sizeof(int));
}
return ret;
}
void TfLiteIntArrayFree(TfLiteIntArray* a) { free(a); }
#endif // TF_LITE_STATIC_MEMORY
int TfLiteFloatArrayGetSizeInBytes(int size) {
static TfLiteFloatArray dummy;
return sizeof(dummy) + sizeof(dummy.data[0]) * size;
}
#ifndef TF_LITE_STATIC_MEMORY
TfLiteFloatArray* TfLiteFloatArrayCreate(int size) {
TfLiteFloatArray* ret =
(TfLiteFloatArray*)malloc(TfLiteFloatArrayGetSizeInBytes(size));
ret->size = size;
return ret;
}
void TfLiteFloatArrayFree(TfLiteFloatArray* a) { free(a); }
void TfLiteTensorDataFree(TfLiteTensor* t) {
if (t->allocation_type == kTfLiteDynamic ||
t->allocation_type == kTfLitePersistentRo) {
free(t->data.raw);
}
t->data.raw = NULL;
}
void TfLiteQuantizationFree(TfLiteQuantization* quantization) {
if (quantization->type == kTfLiteAffineQuantization) {
TfLiteAffineQuantization* q_params =
(TfLiteAffineQuantization*)(quantization->params);
if (q_params->scale) {
TfLiteFloatArrayFree(q_params->scale);
q_params->scale = NULL;
}
if (q_params->zero_point) {
TfLiteIntArrayFree(q_params->zero_point);
q_params->zero_point = NULL;
}
free(q_params);
}
quantization->params = NULL;
quantization->type = kTfLiteNoQuantization;
}
void TfLiteSparsityFree(TfLiteSparsity* sparsity) {
if (sparsity == NULL) {
return;
}
if (sparsity->traversal_order) {
TfLiteIntArrayFree(sparsity->traversal_order);
sparsity->traversal_order = NULL;
}
if (sparsity->block_map) {
TfLiteIntArrayFree(sparsity->block_map);
sparsity->block_map = NULL;
}
if (sparsity->dim_metadata) {
int i = 0;
for (; i < sparsity->dim_metadata_size; i++) {
TfLiteDimensionMetadata metadata = sparsity->dim_metadata[i];
if (metadata.format == kTfLiteDimSparseCSR) {
TfLiteIntArrayFree(metadata.array_segments);
metadata.array_segments = NULL;
TfLiteIntArrayFree(metadata.array_indices);
metadata.array_indices = NULL;
}
}
free(sparsity->dim_metadata);
sparsity->dim_metadata = NULL;
}
free(sparsity);
}
void TfLiteTensorFree(TfLiteTensor* t) {
TfLiteTensorDataFree(t);
if (t->dims) TfLiteIntArrayFree(t->dims);
t->dims = NULL;
if (t->dims_signature) {
TfLiteIntArrayFree((TfLiteIntArray *) t->dims_signature);
}
t->dims_signature = NULL;
TfLiteQuantizationFree(&t->quantization);
TfLiteSparsityFree(t->sparsity);
t->sparsity = NULL;
}
void TfLiteTensorReset(TfLiteType type, const char* name, TfLiteIntArray* dims,
TfLiteQuantizationParams quantization, char* buffer,
size_t size, TfLiteAllocationType allocation_type,
const void* allocation, bool is_variable,
TfLiteTensor* tensor) {
TfLiteTensorFree(tensor);
tensor->type = type;
tensor->name = name;
tensor->dims = dims;
tensor->params = quantization;
tensor->data.raw = buffer;
tensor->bytes = size;
tensor->allocation_type = allocation_type;
tensor->allocation = allocation;
tensor->is_variable = is_variable;
tensor->quantization.type = kTfLiteNoQuantization;
tensor->quantization.params = NULL;
}
void TfLiteTensorRealloc(size_t num_bytes, TfLiteTensor* tensor) {
if (tensor->allocation_type != kTfLiteDynamic &&
tensor->allocation_type != kTfLitePersistentRo) {
return;
}
// TODO(b/145340303): Tensor data should be aligned.
if (!tensor->data.raw) {
tensor->data.raw = malloc(num_bytes);
} else if (num_bytes > tensor->bytes) {
tensor->data.raw = realloc(tensor->data.raw, num_bytes);
}
tensor->bytes = num_bytes;
}
#endif // TF_LITE_STATIC_MEMORY
const char* TfLiteTypeGetName(TfLiteType type) {
switch (type) {
case kTfLiteNoType:
return "NOTYPE";
case kTfLiteFloat32:
return "FLOAT32";
case kTfLiteInt16:
return "INT16";
case kTfLiteInt32:
return "INT32";
case kTfLiteUInt8:
return "UINT8";
case kTfLiteInt8:
return "INT8";
case kTfLiteInt64:
return "INT64";
case kTfLiteUInt64:
return "UINT64";
case kTfLiteBool:
return "BOOL";
case kTfLiteComplex64:
return "COMPLEX64";
case kTfLiteComplex128:
return "COMPLEX128";
case kTfLiteString:
return "STRING";
case kTfLiteFloat16:
return "FLOAT16";
case kTfLiteFloat64:
return "FLOAT64";
}
return "Unknown type";
}
TfLiteDelegate TfLiteDelegateCreate() {
TfLiteDelegate d = {
.data_ = NULL,
.Prepare = NULL,
.CopyFromBufferHandle = NULL,
.CopyToBufferHandle = NULL,
.FreeBufferHandle = NULL,
.flags = kTfLiteDelegateFlagsNone,
};
return d;
}

View File

@ -1,913 +0,0 @@
/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
// This file defines common C types and APIs for implementing operations,
// delegates and other constructs in TensorFlow Lite. The actual operations and
// delegates can be defined using C++, but the interface between the interpreter
// and the operations are C.
//
// Summary of abstractions
// TF_LITE_ENSURE - Self-sufficient error checking
// TfLiteStatus - Status reporting
// TfLiteIntArray - stores tensor shapes (dims),
// TfLiteContext - allows an op to access the tensors
// TfLiteTensor - tensor (a multidimensional array)
// TfLiteNode - a single node or operation
// TfLiteRegistration - the implementation of a conceptual operation.
// TfLiteDelegate - allows delegation of nodes to alternative backends.
//
// Some abstractions in this file are created and managed by Interpreter.
//
// NOTE: The order of values in these structs are "semi-ABI stable". New values
// should be added only to the end of structs and never reordered.
#ifndef TENSORFLOW_LITE_C_COMMON_H_
#define TENSORFLOW_LITE_C_COMMON_H_
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "tensorflow/lite/c/c_api_types.h" // IWYU pragma: export
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// The list of external context types known to TF Lite. This list exists solely
// to avoid conflicts and to ensure ops can share the external contexts they
// need. Access to the external contexts is controlled by one of the
// corresponding support files.
typedef enum TfLiteExternalContextType {
kTfLiteEigenContext = 0, // include eigen_support.h to use.
kTfLiteGemmLowpContext = 1, // include gemm_support.h to use.
kTfLiteEdgeTpuContext = 2, // Placeholder for Edge TPU support.
kTfLiteCpuBackendContext = 3, // include cpu_backend_context.h to use.
kTfLiteMaxExternalContexts = 4
} TfLiteExternalContextType;
// Forward declare so dependent structs and methods can reference these types
// prior to the struct definitions.
struct TfLiteContext;
struct TfLiteDelegate;
struct TfLiteRegistration;
// An external context is a collection of information unrelated to the TF Lite
// framework, but useful to a subset of the ops. TF Lite knows very little
// about the actual contexts, but it keeps a list of them, and is able to
// refresh them if configurations like the number of recommended threads
// change.
typedef struct TfLiteExternalContext {
TfLiteExternalContextType type;
TfLiteStatus (*Refresh)(struct TfLiteContext* context);
} TfLiteExternalContext;
#define kTfLiteOptionalTensor (-1)
// Fixed size list of integers. Used for dimensions and inputs/outputs tensor
// indices
typedef struct TfLiteIntArray {
int size;
// gcc 6.1+ have a bug where flexible members aren't properly handled
// https://github.com/google/re2/commit/b94b7cd42e9f02673cd748c1ac1d16db4052514c
#if (!defined(__clang__) && defined(__GNUC__) && __GNUC__ == 6 && \
__GNUC_MINOR__ >= 1) || \
defined(HEXAGON) || (__clang_major__ == 7 && __clang_minor__ == 1)
int data[0];
#else
int data[];
#endif
} TfLiteIntArray;
// Given the size (number of elements) in a TfLiteIntArray, calculate its size
// in bytes.
int TfLiteIntArrayGetSizeInBytes(int size);
#ifndef TF_LITE_STATIC_MEMORY
// Create a array of a given `size` (uninitialized entries).
// This returns a pointer, that you must free using TfLiteIntArrayFree().
TfLiteIntArray* TfLiteIntArrayCreate(int size);
#endif
// Check if two intarrays are equal. Returns 1 if they are equal, 0 otherwise.
int TfLiteIntArrayEqual(const TfLiteIntArray* a, const TfLiteIntArray* b);
// Check if an intarray equals an array. Returns 1 if equals, 0 otherwise.
int TfLiteIntArrayEqualsArray(const TfLiteIntArray* a, int b_size,
const int b_data[]);
#ifndef TF_LITE_STATIC_MEMORY
// Create a copy of an array passed as `src`.
// You are expected to free memory with TfLiteIntArrayFree
TfLiteIntArray* TfLiteIntArrayCopy(const TfLiteIntArray* src);
// Free memory of array `a`.
void TfLiteIntArrayFree(TfLiteIntArray* a);
#endif // TF_LITE_STATIC_MEMORY
// Fixed size list of floats. Used for per-channel quantization.
typedef struct TfLiteFloatArray {
int size;
// gcc 6.1+ have a bug where flexible members aren't properly handled
// https://github.com/google/re2/commit/b94b7cd42e9f02673cd748c1ac1d16db4052514c
// This also applies to the toolchain used for Qualcomm Hexagon DSPs.
#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ == 6 && \
__GNUC_MINOR__ >= 1
float data[0];
#else
float data[];
#endif
} TfLiteFloatArray;
// Given the size (number of elements) in a TfLiteFloatArray, calculate its size
// in bytes.
int TfLiteFloatArrayGetSizeInBytes(int size);
#ifndef TF_LITE_STATIC_MEMORY
// Create a array of a given `size` (uninitialized entries).
// This returns a pointer, that you must free using TfLiteFloatArrayFree().
TfLiteFloatArray* TfLiteFloatArrayCreate(int size);
// Free memory of array `a`.
void TfLiteFloatArrayFree(TfLiteFloatArray* a);
#endif // TF_LITE_STATIC_MEMORY
// Since we must not depend on any libraries, define a minimal subset of
// error macros while avoiding names that have pre-conceived meanings like
// CHECK and check.
// Try to make all reporting calls through TF_LITE_KERNEL_LOG rather than
// calling the context->ReportError function directly, so that message strings
// can be stripped out if the binary size needs to be severely optimized.
#ifndef TF_LITE_STRIP_ERROR_STRINGS
#define TF_LITE_KERNEL_LOG(context, ...) \
do { \
(context)->ReportError((context), __VA_ARGS__); \
} while (false)
#define TF_LITE_MAYBE_KERNEL_LOG(context, ...) \
do { \
if ((context) != nullptr) { \
(context)->ReportError((context), __VA_ARGS__); \
} \
} while (false)
#else // TF_LITE_STRIP_ERROR_STRINGS
#define TF_LITE_KERNEL_LOG(context, ...)
#define TF_LITE_MAYBE_KERNEL_LOG(context, ...)
#endif // TF_LITE_STRIP_ERROR_STRINGS
// Check whether value is true, and if not return kTfLiteError from
// the current function (and report the error string msg).
#define TF_LITE_ENSURE_MSG(context, value, msg) \
do { \
if (!(value)) { \
TF_LITE_KERNEL_LOG((context), __FILE__ " " msg); \
return kTfLiteError; \
} \
} while (0)
// Check whether the value `a` is true, and if not return kTfLiteError from
// the current function, while also reporting the location of the error.
#define TF_LITE_ENSURE(context, a) \
do { \
if (!(a)) { \
TF_LITE_KERNEL_LOG((context), "%s:%d %s was not true.", __FILE__, \
__LINE__, #a); \
return kTfLiteError; \
} \
} while (0)
#define TF_LITE_ENSURE_STATUS(a) \
do { \
const TfLiteStatus s = (a); \
if (s != kTfLiteOk) { \
return s; \
} \
} while (0)
// Check whether the value `a == b` is true, and if not return kTfLiteError from
// the current function, while also reporting the location of the error.
// `a` and `b` may be evaluated more than once, so no side effects or
// extremely expensive computations should be done.
// NOTE: Use TF_LITE_ENSURE_TYPES_EQ if comparing TfLiteTypes.
#define TF_LITE_ENSURE_EQ(context, a, b) \
do { \
if ((a) != (b)) { \
TF_LITE_KERNEL_LOG((context), "%s:%d %s != %s (%d != %d)", __FILE__, \
__LINE__, #a, #b, (a), (b)); \
return kTfLiteError; \
} \
} while (0)
#define TF_LITE_ENSURE_TYPES_EQ(context, a, b) \
do { \
if ((a) != (b)) { \
TF_LITE_KERNEL_LOG((context), "%s:%d %s != %s (%s != %s)", __FILE__, \
__LINE__, #a, #b, TfLiteTypeGetName(a), \
TfLiteTypeGetName(b)); \
return kTfLiteError; \
} \
} while (0)
#define TF_LITE_ENSURE_NEAR(context, a, b, epsilon) \
do { \
auto delta = ((a) > (b)) ? ((a) - (b)) : ((b) - (a)); \
if (delta > epsilon) { \
TF_LITE_KERNEL_LOG((context), "%s:%d %s not near %s (%f != %f)", \
__FILE__, __LINE__, #a, #b, static_cast<double>(a), \
static_cast<double>(b)); \
return kTfLiteError; \
} \
} while (0)
#define TF_LITE_ENSURE_OK(context, status) \
do { \
const TfLiteStatus s = (status); \
if ((s) != kTfLiteOk) { \
return s; \
} \
} while (0)
// Single-precision complex data type compatible with the C99 definition.
typedef struct TfLiteComplex64 {
float re, im; // real and imaginary parts, respectively.
} TfLiteComplex64;
// Double-precision complex data type compatible with the C99 definition.
typedef struct TfLiteComplex128 {
double re, im; // real and imaginary parts, respectively.
} TfLiteComplex128;
// Half precision data type compatible with the C99 definition.
typedef struct TfLiteFloat16 {
uint16_t data;
} TfLiteFloat16;
// Return the name of a given type, for error reporting purposes.
const char* TfLiteTypeGetName(TfLiteType type);
// SupportedQuantizationTypes.
typedef enum TfLiteQuantizationType {
// No quantization.
kTfLiteNoQuantization = 0,
// Affine quantization (with support for per-channel quantization).
// Corresponds to TfLiteAffineQuantization.
kTfLiteAffineQuantization = 1,
} TfLiteQuantizationType;
// Structure specifying the quantization used by the tensor, if-any.
typedef struct TfLiteQuantization {
// The type of quantization held by params.
TfLiteQuantizationType type;
// Holds an optional reference to a quantization param structure. The actual
// type depends on the value of the `type` field (see the comment there for
// the values and corresponding types).
void* params;
} TfLiteQuantization;
// Parameters for asymmetric quantization across a dimension (i.e per output
// channel quantization).
// quantized_dimension specifies which dimension the scales and zero_points
// correspond to.
// For a particular value in quantized_dimension, quantized values can be
// converted back to float using:
// real_value = scale * (quantized_value - zero_point)
typedef struct TfLiteAffineQuantization {
TfLiteFloatArray* scale;
TfLiteIntArray* zero_point;
int32_t quantized_dimension;
} TfLiteAffineQuantization;
/* A union of pointers that points to memory for a given tensor. */
typedef union TfLitePtrUnion {
/* Do not access these members directly, if possible, use
* GetTensorData<TYPE>(tensor) instead, otherwise only access .data, as other
* members are deprecated. */
int32_t* i32;
int64_t* i64;
uint64_t* u64;
float* f;
TfLiteFloat16* f16;
double* f64;
char* raw;
const char* raw_const;
uint8_t* uint8;
bool* b;
int16_t* i16;
TfLiteComplex64* c64;
TfLiteComplex128* c128;
int8_t* int8;
/* Only use this member. */
void* data;
} TfLitePtrUnion;
// Memory allocation strategies.
// * kTfLiteMmapRo: Read-only memory-mapped data, or data externally allocated.
// * kTfLiteArenaRw: Arena allocated with no guarantees about persistence,
// and available during eval.
// * kTfLiteArenaRwPersistent: Arena allocated but persistent across eval, and
// only available during eval.
// * kTfLiteDynamic: Allocated during eval, or for string tensors.
// * kTfLitePersistentRo: Allocated and populated during prepare. This is
// useful for tensors that can be computed during prepare and treated
// as constant inputs for downstream ops (also in prepare).
// * kTfLiteCustom: Custom memory allocation provided by the user. See
// TfLiteCustomAllocation below.
typedef enum TfLiteAllocationType {
kTfLiteMemNone = 0,
kTfLiteMmapRo,
kTfLiteArenaRw,
kTfLiteArenaRwPersistent,
kTfLiteDynamic,
kTfLitePersistentRo,
kTfLiteCustom,
} TfLiteAllocationType;
// The delegates should use zero or positive integers to represent handles.
// -1 is reserved from unallocated status.
typedef int TfLiteBufferHandle;
enum {
kTfLiteNullBufferHandle = -1,
};
// Storage format of each dimension in a sparse tensor.
typedef enum TfLiteDimensionType {
kTfLiteDimDense = 0,
kTfLiteDimSparseCSR,
} TfLiteDimensionType;
// Metadata to encode each dimension in a sparse tensor.
typedef struct TfLiteDimensionMetadata {
TfLiteDimensionType format;
int dense_size;
TfLiteIntArray* array_segments;
TfLiteIntArray* array_indices;
} TfLiteDimensionMetadata;
// Parameters used to encode a sparse tensor. For detailed explanation of each
// field please refer to lite/schema/schema.fbs.
typedef struct TfLiteSparsity {
TfLiteIntArray* traversal_order;
TfLiteIntArray* block_map;
TfLiteDimensionMetadata* dim_metadata;
int dim_metadata_size;
} TfLiteSparsity;
// Defines a custom memory allocation not owned by the runtime.
// `data` should be aligned to kDefaultTensorAlignment defined in
// lite/util.h. (Currently 64 bytes)
// NOTE: See Interpreter.SetCustomAllocationForTensor for details on usage.
typedef struct TfLiteCustomAllocation {
void* data;
size_t bytes;
} TfLiteCustomAllocation;
// A tensor in the interpreter system which is a wrapper around a buffer of
// data including a dimensionality (or NULL if not currently defined).
#ifndef TF_LITE_STATIC_MEMORY
typedef struct TfLiteTensor {
// The data type specification for data stored in `data`. This affects
// what member of `data` union should be used.
TfLiteType type;
// A union of data pointers. The appropriate type should be used for a typed
// tensor based on `type`.
TfLitePtrUnion data;
// A pointer to a structure representing the dimensionality interpretation
// that the buffer should have. NOTE: the product of elements of `dims`
// and the element datatype size should be equal to `bytes` below.
TfLiteIntArray* dims;
// Quantization information.
TfLiteQuantizationParams params;
// How memory is mapped
// kTfLiteMmapRo: Memory mapped read only.
// i.e. weights
// kTfLiteArenaRw: Arena allocated read write memory
// (i.e. temporaries, outputs).
TfLiteAllocationType allocation_type;
// The number of bytes required to store the data of this Tensor. I.e.
// (bytes of each element) * dims[0] * ... * dims[n-1]. For example, if
// type is kTfLiteFloat32 and dims = {3, 2} then
// bytes = sizeof(float) * 3 * 2 = 4 * 3 * 2 = 24.
size_t bytes;
// An opaque pointer to a tflite::MMapAllocation
const void* allocation;
// Null-terminated name of this tensor.
const char* name;
// The delegate which knows how to handle `buffer_handle`.
// WARNING: This is an experimental interface that is subject to change.
struct TfLiteDelegate* delegate;
// An integer buffer handle that can be handled by `delegate`.
// The value is valid only when delegate is not null.
// WARNING: This is an experimental interface that is subject to change.
TfLiteBufferHandle buffer_handle;
// If the delegate uses its own buffer (e.g. GPU memory), the delegate is
// responsible to set data_is_stale to true.
// `delegate->CopyFromBufferHandle` can be called to copy the data from
// delegate buffer.
// WARNING: This is an // experimental interface that is subject to change.
bool data_is_stale;
// True if the tensor is a variable.
bool is_variable;
// Quantization information. Replaces params field above.
TfLiteQuantization quantization;
// Parameters used to encode a sparse tensor.
// This is optional. The field is NULL if a tensor is dense.
// WARNING: This is an experimental interface that is subject to change.
TfLiteSparsity* sparsity;
// Optional. Encodes shapes with unknown dimensions with -1. This field is
// only populated when unknown dimensions exist in a read-write tensor (i.e.
// an input or output tensor). (e.g. `dims` contains [1, 1, 1, 3] and
// `dims_signature` contains [1, -1, -1, 3]).
const TfLiteIntArray* dims_signature;
} TfLiteTensor;
// A structure representing an instance of a node.
// This structure only exhibits the inputs, outputs and user defined data, not
// other features like the type.
typedef struct TfLiteNode {
// Inputs to this node expressed as indices into the simulator's tensors.
TfLiteIntArray* inputs;
// Outputs to this node expressed as indices into the simulator's tensors.
TfLiteIntArray* outputs;
// intermediate tensors to this node expressed as indices into the simulator's
// tensors.
TfLiteIntArray* intermediates;
// Temporary tensors uses during the computations. This usually contains no
// tensors, but ops are allowed to change that if they need scratch space of
// any sort.
TfLiteIntArray* temporaries;
// Opaque data provided by the node implementer through `Registration.init`.
void* user_data;
// Opaque data provided to the node if the node is a builtin. This is usually
// a structure defined in builtin_op_data.h
void* builtin_data;
// Custom initial data. This is the opaque data provided in the flatbuffer.
// WARNING: This is an experimental interface that is subject to change.
const void* custom_initial_data;
int custom_initial_data_size;
// The pointer to the delegate. This is non-null only when the node is
// created by calling `interpreter.ModifyGraphWithDelegate`.
// WARNING: This is an experimental interface that is subject to change.
struct TfLiteDelegate* delegate;
} TfLiteNode;
#else // defined(TF_LITE_STATIC_MEMORY)?
// NOTE: This flag is opt-in only at compile time.
//
// Specific reduced TfLiteTensor struct for TF Micro runtime. This struct
// contains only the minimum fields required to initialize and prepare a micro
// inference graph. The fields in this struct have been ordered from
// largest-to-smallest for optimal struct sizeof.
//
// This struct does not use:
// - allocation
// - buffer_handle
// - data_is_stale
// - delegate
// - dims_signature
// - name
// - sparsity
typedef struct TfLiteTensor {
// TODO(b/155784997): Consider consolidating these quantization fields:
// Quantization information. Replaces params field above.
TfLiteQuantization quantization;
// Quantization information.
TfLiteQuantizationParams params;
// A union of data pointers. The appropriate type should be used for a typed
// tensor based on `type`.
TfLitePtrUnion data;
// A pointer to a structure representing the dimensionality interpretation
// that the buffer should have. NOTE: the product of elements of `dims`
// and the element datatype size should be equal to `bytes` below.
TfLiteIntArray* dims;
// The number of bytes required to store the data of this Tensor. I.e.
// (bytes of each element) * dims[0] * ... * dims[n-1]. For example, if
// type is kTfLiteFloat32 and dims = {3, 2} then
// bytes = sizeof(float) * 3 * 2 = 4 * 3 * 2 = 24.
size_t bytes;
// The data type specification for data stored in `data`. This affects
// what member of `data` union should be used.
TfLiteType type;
// How memory is mapped
// kTfLiteMmapRo: Memory mapped read only.
// i.e. weights
// kTfLiteArenaRw: Arena allocated read write memory
// (i.e. temporaries, outputs).
TfLiteAllocationType allocation_type;
// True if the tensor is a variable.
bool is_variable;
} TfLiteTensor;
// Specific reduced TfLiteNode struct for TF Micro runtime. This struct contains
// only the minimum fields required to represent a node.
//
// This struct does not use:
// - delegate
// - intermediates
// - temporaries
typedef struct TfLiteNode {
// Inputs to this node expressed as indices into the simulator's tensors.
TfLiteIntArray* inputs;
// Outputs to this node expressed as indices into the simulator's tensors.
TfLiteIntArray* outputs;
// Opaque data provided by the node implementer through `Registration.init`.
void* user_data;
// Opaque data provided to the node if the node is a builtin. This is usually
// a structure defined in builtin_op_data.h
void* builtin_data;
// Custom initial data. This is the opaque data provided in the flatbuffer.
// WARNING: This is an experimental interface that is subject to change.
const void* custom_initial_data;
int custom_initial_data_size;
} TfLiteNode;
#endif // TF_LITE_STATIC_MEMORY
// Light-weight tensor struct for TF Micro runtime. Provides the minimal amount
// of information required for a kernel to run during TfLiteRegistration::Eval.
// TODO(b/160955687): Move this field into TF_LITE_STATIC_MEMORY when TFLM
// builds with this flag by default internally.
typedef struct TfLiteEvalTensor {
// A union of data pointers. The appropriate type should be used for a typed
// tensor based on `type`.
TfLitePtrUnion data;
// A pointer to a structure representing the dimensionality interpretation
// that the buffer should have.
TfLiteIntArray* dims;
// The data type specification for data stored in `data`. This affects
// what member of `data` union should be used.
TfLiteType type;
} TfLiteEvalTensor;
#ifndef TF_LITE_STATIC_MEMORY
// Free data memory of tensor `t`.
void TfLiteTensorDataFree(TfLiteTensor* t);
// Free quantization data.
void TfLiteQuantizationFree(TfLiteQuantization* quantization);
// Free sparsity parameters.
void TfLiteSparsityFree(TfLiteSparsity* sparsity);
// Free memory of tensor `t`.
void TfLiteTensorFree(TfLiteTensor* t);
// Set all of a tensor's fields (and free any previously allocated data).
void TfLiteTensorReset(TfLiteType type, const char* name, TfLiteIntArray* dims,
TfLiteQuantizationParams quantization, char* buffer,
size_t size, TfLiteAllocationType allocation_type,
const void* allocation, bool is_variable,
TfLiteTensor* tensor);
// Resize the allocated data of a (dynamic) tensor. Tensors with allocation
// types other than kTfLiteDynamic will be ignored.
void TfLiteTensorRealloc(size_t num_bytes, TfLiteTensor* tensor);
#endif // TF_LITE_STATIC_MEMORY
// WARNING: This is an experimental interface that is subject to change.
//
// Currently, TfLiteDelegateParams has to be allocated in a way that it's
// trivially destructable. It will be stored as `builtin_data` field in
// `TfLiteNode` of the delegate node.
//
// See also the `CreateDelegateParams` function in `interpreter.cc` details.
typedef struct TfLiteDelegateParams {
struct TfLiteDelegate* delegate;
TfLiteIntArray* nodes_to_replace;
TfLiteIntArray* input_tensors;
TfLiteIntArray* output_tensors;
} TfLiteDelegateParams;
typedef struct TfLiteContext {
// Number of tensors in the context.
size_t tensors_size;
// The execution plan contains a list of the node indices in execution
// order. execution_plan->size is the current number of nodes. And,
// execution_plan->data[0] is the first node that needs to be run.
// TfLiteDelegates can traverse the current execution plan by iterating
// through each member of this array and using GetNodeAndRegistration() to
// access details about a node. i.e.
// TfLiteIntArray* execution_plan;
// TF_LITE_ENSURE_STATUS(context->GetExecutionPlan(context, &execution_plan));
// for (int exec_index = 0; exec_index < execution_plan->size; exec_index++) {
// int node_index = execution_plan->data[exec_index];
// TfLiteNode* node;
// TfLiteRegistration* reg;
// context->GetNodeAndRegistration(context, node_index, &node, &reg);
// }
// WARNING: This is an experimental interface that is subject to change.
TfLiteStatus (*GetExecutionPlan)(struct TfLiteContext* context,
TfLiteIntArray** execution_plan);
// An array of tensors in the interpreter context (of length `tensors_size`)
TfLiteTensor* tensors;
// opaque full context ptr (an opaque c++ data structure)
void* impl_;
// Request memory pointer be resized. Updates dimensions on the tensor.
// NOTE: ResizeTensor takes ownership of newSize.
TfLiteStatus (*ResizeTensor)(struct TfLiteContext*, TfLiteTensor* tensor,
TfLiteIntArray* new_size);
// Request that an error be reported with format string msg.
void (*ReportError)(struct TfLiteContext*, const char* msg, ...);
// Add `tensors_to_add` tensors, preserving pre-existing Tensor entries. If
// non-null, the value pointed to by `first_new_tensor_index` will be set to
// the index of the first new tensor.
TfLiteStatus (*AddTensors)(struct TfLiteContext*, int tensors_to_add,
int* first_new_tensor_index);
// Get a Tensor node by node_index.
// WARNING: This is an experimental interface that is subject to change.
TfLiteStatus (*GetNodeAndRegistration)(
struct TfLiteContext*, int node_index, TfLiteNode** node,
struct TfLiteRegistration** registration);
// Replace ops with one or more stub delegate operations. This function
// does not take ownership of `nodes_to_replace`.
TfLiteStatus (*ReplaceNodeSubsetsWithDelegateKernels)(
struct TfLiteContext*, struct TfLiteRegistration registration,
const TfLiteIntArray* nodes_to_replace, struct TfLiteDelegate* delegate);
// Number of threads that are recommended to subsystems like gemmlowp and
// eigen.
int recommended_num_threads;
// Access external contexts by type.
// WARNING: This is an experimental interface that is subject to change.
TfLiteExternalContext* (*GetExternalContext)(struct TfLiteContext*,
TfLiteExternalContextType);
// Set the value of a external context. Does not take ownership of the
// pointer.
// WARNING: This is an experimental interface that is subject to change.
void (*SetExternalContext)(struct TfLiteContext*, TfLiteExternalContextType,
TfLiteExternalContext*);
// Flag for allowing float16 precision for FP32 calculation.
// default: false.
// WARNING: This is an experimental API and subject to change.
bool allow_fp32_relax_to_fp16;
// Pointer to the op-level profiler, if set; nullptr otherwise.
void* profiler;
// Allocate persistent buffer which has the same life time as the interpreter.
// Returns nullptr on failure.
// The memory is allocated from heap for TFL, and from tail in TFLM.
// This method is only available in Init or Prepare stage.
// WARNING: This is an experimental interface that is subject to change.
void* (*AllocatePersistentBuffer)(struct TfLiteContext* ctx, size_t bytes);
// Allocate a buffer which will be deallocated right after invoke phase.
// The memory is allocated from heap in TFL, and from volatile arena in TFLM.
// This method is only available in invoke stage.
// NOTE: If possible use RequestScratchBufferInArena method to avoid memory
// allocation during inference time.
// WARNING: This is an experimental interface that is subject to change.
TfLiteStatus (*AllocateBufferForEval)(struct TfLiteContext* ctx, size_t bytes,
void** ptr);
// Request a scratch buffer in the arena through static memory planning.
// This method is only available in Prepare stage and the buffer is allocated
// by the interpreter between Prepare and Eval stage. In Eval stage,
// GetScratchBuffer API can be used to fetch the address.
// WARNING: This is an experimental interface that is subject to change.
TfLiteStatus (*RequestScratchBufferInArena)(struct TfLiteContext* ctx,
size_t bytes, int* buffer_idx);
// Get the scratch buffer pointer.
// This method is only available in Eval stage.
// WARNING: This is an experimental interface that is subject to change.
void* (*GetScratchBuffer)(struct TfLiteContext* ctx, int buffer_idx);
// Resize the memory pointer of the `tensor`. This method behaves the same as
// `ResizeTensor`, except that it makes a copy of the shape array internally
// so the shape array could be deallocated right afterwards.
// WARNING: This is an experimental interface that is subject to change.
TfLiteStatus (*ResizeTensorExplicit)(struct TfLiteContext* ctx,
TfLiteTensor* tensor, int dims,
const int* shape);
// This method provides a preview of post-delegation partitioning. Each
// TfLiteDelegateParams in the referenced array corresponds to one instance of
// the delegate kernel.
// Example usage:
//
// TfLiteIntArray* nodes_to_replace = ...;
// TfLiteDelegateParams* params_array;
// int num_partitions = 0;
// TF_LITE_ENSURE_STATUS(context->PreviewDelegatePartitioning(
// context, delegate, nodes_to_replace, &params_array, &num_partitions));
// for (int idx = 0; idx < num_partitions; idx++) {
// const auto& partition_params = params_array[idx];
// ...
// }
//
// NOTE: The context owns the memory referenced by partition_params_array. It
// will be cleared with another call to PreviewDelegateParitioning, or after
// TfLiteDelegateParams::Prepare returns.
//
// WARNING: This is an experimental interface that is subject to change.
TfLiteStatus (*PreviewDelegatePartitioning)(
struct TfLiteContext* context, const TfLiteIntArray* nodes_to_replace,
TfLiteDelegateParams** partition_params_array, int* num_partitions);
// Returns a TfLiteTensor struct for a given index.
// WARNING: This is an experimental interface that is subject to change.
// WARNING: This method may not be available on all platforms.
TfLiteTensor* (*GetTensor)(const struct TfLiteContext* context,
int tensor_idx);
// Returns a TfLiteEvalTensor struct for a given index.
// WARNING: This is an experimental interface that is subject to change.
// WARNING: This method may not be available on all platforms.
TfLiteEvalTensor* (*GetEvalTensor)(const struct TfLiteContext* context,
int tensor_idx);
} TfLiteContext;
typedef struct TfLiteRegistration {
// Initializes the op from serialized data.
// If a built-in op:
// `buffer` is the op's params data (TfLiteLSTMParams*).
// `length` is zero.
// If custom op:
// `buffer` is the op's `custom_options`.
// `length` is the size of the buffer.
//
// Returns a type-punned (i.e. void*) opaque data (e.g. a primitive pointer
// or an instance of a struct).
//
// The returned pointer will be stored with the node in the `user_data` field,
// accessible within prepare and invoke functions below.
// NOTE: if the data is already in the desired format, simply implement this
// function to return `nullptr` and implement the free function to be a no-op.
void* (*init)(TfLiteContext* context, const char* buffer, size_t length);
// The pointer `buffer` is the data previously returned by an init invocation.
void (*free)(TfLiteContext* context, void* buffer);
// prepare is called when the inputs this node depends on have been resized.
// context->ResizeTensor() can be called to request output tensors to be
// resized.
//
// Returns kTfLiteOk on success.
TfLiteStatus (*prepare)(TfLiteContext* context, TfLiteNode* node);
// Execute the node (should read node->inputs and output to node->outputs).
// Returns kTfLiteOk on success.
TfLiteStatus (*invoke)(TfLiteContext* context, TfLiteNode* node);
// profiling_string is called during summarization of profiling information
// in order to group executions together. Providing a value here will cause a
// given op to appear multiple times is the profiling report. This is
// particularly useful for custom ops that can perform significantly
// different calculations depending on their `user-data`.
const char* (*profiling_string)(const TfLiteContext* context,
const TfLiteNode* node);
// Builtin codes. If this kernel refers to a builtin this is the code
// of the builtin. This is so we can do marshaling to other frameworks like
// NN API.
// Note: It is the responsibility of the registration binder to set this
// properly.
int32_t builtin_code;
// Custom op name. If the op is a builtin, this will be null.
// Note: It is the responsibility of the registration binder to set this
// properly.
// WARNING: This is an experimental interface that is subject to change.
const char* custom_name;
// The version of the op.
// Note: It is the responsibility of the registration binder to set this
// properly.
int version;
} TfLiteRegistration;
// The flags used in `TfLiteDelegate`. Note that this is a bitmask, so the
// values should be 1, 2, 4, 8, ...etc.
typedef enum TfLiteDelegateFlags {
kTfLiteDelegateFlagsNone = 0,
// The flag is set if the delegate can handle dynamic sized tensors.
// For example, the output shape of a `Resize` op with non-constant shape
// can only be inferred when the op is invoked.
// In this case, the Delegate is responsible for calling
// `SetTensorToDynamic` to mark the tensor as a dynamic tensor, and calling
// `ResizeTensor` when invoking the op.
//
// If the delegate isn't capable to handle dynamic tensors, this flag need
// to be set to false.
kTfLiteDelegateFlagsAllowDynamicTensors = 1,
// This flag can be used by delegates (that allow dynamic tensors) to ensure
// applicable tensor shapes are automatically propagated in the case of tensor
// resizing.
// This means that non-dynamic (allocation_type != kTfLiteDynamic) I/O tensors
// of a delegate kernel will have correct shapes before its Prepare() method
// is called. The runtime leverages TFLite builtin ops in the original
// execution plan to propagate shapes.
//
// A few points to note:
// 1. This requires kTfLiteDelegateFlagsAllowDynamicTensors. If that flag is
// false, this one is redundant since the delegate kernels are re-initialized
// every time tensors are resized.
// 2. Enabling this flag adds some overhead to AllocateTensors(), since extra
// work is required to prepare the original execution plan.
// 3. This flag requires that the original execution plan only have ops with
// valid registrations (and not 'dummy' custom ops like with Flex).
// WARNING: This feature is experimental and subject to change.
kTfLiteDelegateFlagsRequirePropagatedShapes = 2
} TfLiteDelegateFlags;
// WARNING: This is an experimental interface that is subject to change.
typedef struct TfLiteDelegate {
// Data that delegate needs to identify itself. This data is owned by the
// delegate. The delegate is owned in the user code, so the delegate is
// responsible for doing this when it is destroyed.
void* data_;
// Invoked by ModifyGraphWithDelegate. This prepare is called, giving the
// delegate a view of the current graph through TfLiteContext*. It typically
// will look at the nodes and call ReplaceNodeSubsetsWithDelegateKernels()
// to ask the TensorFlow lite runtime to create macro-nodes to represent
// delegated subgraphs of the original graph.
TfLiteStatus (*Prepare)(TfLiteContext* context,
struct TfLiteDelegate* delegate);
// Copy the data from delegate buffer handle into raw memory of the given
// 'tensor'. Note that the delegate is allowed to allocate the raw bytes as
// long as it follows the rules for kTfLiteDynamic tensors, in which case this
// cannot be null.
TfLiteStatus (*CopyFromBufferHandle)(TfLiteContext* context,
struct TfLiteDelegate* delegate,
TfLiteBufferHandle buffer_handle,
TfLiteTensor* tensor);
// Copy the data from raw memory of the given 'tensor' to delegate buffer
// handle. This can be null if the delegate doesn't use its own buffer.
TfLiteStatus (*CopyToBufferHandle)(TfLiteContext* context,
struct TfLiteDelegate* delegate,
TfLiteBufferHandle buffer_handle,
TfLiteTensor* tensor);
// Free the Delegate Buffer Handle. Note: This only frees the handle, but
// this doesn't release the underlying resource (e.g. textures). The
// resources are either owned by application layer or the delegate.
// This can be null if the delegate doesn't use its own buffer.
void (*FreeBufferHandle)(TfLiteContext* context,
struct TfLiteDelegate* delegate,
TfLiteBufferHandle* handle);
// Bitmask flags. See the comments in `TfLiteDelegateFlags`.
int64_t flags;
} TfLiteDelegate;
// Build a 'null' delegate, with all the fields properly set to their default
// values.
TfLiteDelegate TfLiteDelegateCreate();
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // TENSORFLOW_LITE_C_COMMON_H_

View File

@ -1,38 +0,0 @@
/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "tensorflow/lite/core/api/error_reporter.h"
#include <cstdarg>
namespace tflite {
int ErrorReporter::Report(const char* format, ...) {
va_list args;
va_start(args, format);
int code = Report(format, args);
va_end(args);
return code;
}
// TODO(aselle): Make the name of ReportError on context the same, so
// we can use the ensure functions w/o a context and w/ a reporter.
int ErrorReporter::ReportError(void*, const char* format, ...) {
va_list args;
va_start(args, format);
int code = Report(format, args);
va_end(args);
return code;
}
} // namespace tflite

View File

@ -1,59 +0,0 @@
/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#ifndef TENSORFLOW_LITE_CORE_API_ERROR_REPORTER_H_
#define TENSORFLOW_LITE_CORE_API_ERROR_REPORTER_H_
#include <cstdarg>
namespace tflite {
/// A functor that reports error to supporting system. Invoked similar to
/// printf.
///
/// Usage:
/// ErrorReporter foo;
/// foo.Report("test %d", 5);
/// or
/// va_list args;
/// foo.Report("test %d", args); // where args is va_list
///
/// Subclass ErrorReporter to provide another reporting destination.
/// For example, if you have a GUI program, you might redirect to a buffer
/// that drives a GUI error log box.
class ErrorReporter {
public:
virtual ~ErrorReporter() {}
virtual int Report(const char* format, va_list args) = 0;
int Report(const char* format, ...);
int ReportError(void*, const char* format, ...);
};
} // namespace tflite
// You should not make bare calls to the error reporter, instead use the
// TF_LITE_REPORT_ERROR macro, since this allows message strings to be
// stripped when the binary size has to be optimized. If you are looking to
// reduce binary size, define TF_LITE_STRIP_ERROR_STRINGS when compiling and
// every call will be stubbed out, taking no memory.
#ifndef TF_LITE_STRIP_ERROR_STRINGS
#define TF_LITE_REPORT_ERROR(reporter, ...) \
do { \
static_cast<tflite::ErrorReporter*>(reporter)->Report(__VA_ARGS__); \
} while (false)
#else // TF_LITE_STRIP_ERROR_STRINGS
#define TF_LITE_REPORT_ERROR(reporter, ...)
#endif // TF_LITE_STRIP_ERROR_STRINGS
#endif // TENSORFLOW_LITE_CORE_API_ERROR_REPORTER_H_

View File

@ -1,301 +0,0 @@
/* Copyright 2018 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#ifndef TENSORFLOW_LITE_CORE_API_FLATBUFFER_CONVERSIONS_H_
#define TENSORFLOW_LITE_CORE_API_FLATBUFFER_CONVERSIONS_H_
// These functions transform codes and data structures that are defined in the
// flatbuffer serialization format into in-memory values that are used by the
// runtime API and interpreter.
#include <cstddef>
#include <new>
#include <type_traits>
#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/core/api/error_reporter.h"
#include "tensorflow/lite/schema/schema_generated.h"
namespace tflite {
// Interface class for builtin data allocations.
class BuiltinDataAllocator {
public:
virtual void* Allocate(size_t size, size_t alignment_hint) = 0;
virtual void Deallocate(void* data) = 0;
// Allocate a structure, but make sure it is a POD structure that doesn't
// require constructors to run. The reason we do this, is that Interpreter's C
// extension part will take ownership so destructors will not be run during
// deallocation.
template <typename T>
T* AllocatePOD() {
// TODO(b/154346074): Change this to is_trivially_destructible when all
// platform targets support that properly.
static_assert(std::is_pod<T>::value, "Builtin data structure must be POD.");
void* allocated_memory = this->Allocate(sizeof(T), alignof(T));
return new (allocated_memory) T();
}
virtual ~BuiltinDataAllocator() {}
};
// Parse the appropriate data out of the op.
//
// This handles builtin data explicitly as there are flatbuffer schemas.
// If it returns kTfLiteOk, it passes the data out with `builtin_data`. The
// calling function has to pass in an allocator object, and this allocator
// will be called to reserve space for the output data. If the calling
// function's allocator reserves memory on the heap, then it's the calling
// function's responsibility to free it.
// If it returns kTfLiteError, `builtin_data` will be `nullptr`.
TfLiteStatus ParseOpData(const Operator* op, BuiltinOperator op_type,
ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
// Converts the tensor data type used in the flat buffer to the representation
// used by the runtime.
TfLiteStatus ConvertTensorType(TensorType tensor_type, TfLiteType* type,
ErrorReporter* error_reporter);
TfLiteStatus ParseAbs(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseAdd(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseArgMax(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseArgMin(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseCeil(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseCast(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseConcatenation(const Operator* op,
ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseConv2D(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseCos(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseDepthwiseConv2D(const Operator* op,
ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseDequantize(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseDiv(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseEqual(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseExp(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseFill(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseFloor(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseFloorDiv(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseFloorMod(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseFullyConnected(const Operator* op,
ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseGreater(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseGreaterEqual(const Operator* op,
ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseHardSwish(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseL2Normalization(const Operator* op,
ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseLess(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseLessEqual(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseLog(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseLogicalAnd(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseLogicalNot(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseLogicalOr(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseLogistic(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseMaximum(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseMinimum(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseMul(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseNeg(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseNotEqual(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParsePack(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParsePad(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParsePadV2(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParsePool(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParsePow(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParsePrelu(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseQuantize(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseReducer(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseRelu(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseRelu6(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseReshape(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseResizeBilinear(const Operator* op,
ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseResizeNearestNeighbor(const Operator* op,
ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseRound(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseRsqrt(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseShape(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseSin(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseSoftmax(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseSpaceToDepth(const Operator* op,
ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseSplit(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseSplitV(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseSqrt(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseSquare(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseStridedSlice(const Operator* op,
ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseSub(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseSvdf(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseTanh(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseTransposeConv(const Operator* op,
ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
TfLiteStatus ParseUnpack(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator, void** builtin_data);
TfLiteStatus ParseZerosLike(const Operator* op, ErrorReporter* error_reporter,
BuiltinDataAllocator* allocator,
void** builtin_data);
} // namespace tflite
#endif // TENSORFLOW_LITE_CORE_API_FLATBUFFER_CONVERSIONS_H_

View File

@ -1,67 +0,0 @@
/* Copyright 2018 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/
#include "tensorflow/lite/core/api/op_resolver.h"
#include "flatbuffers/flatbuffers.h" // from @flatbuffers
#include "tensorflow/lite/c/common.h"
#include "tensorflow/lite/core/api/error_reporter.h"
#include "tensorflow/lite/schema/schema_utils.h"
namespace tflite {
TfLiteStatus GetRegistrationFromOpCode(
const OperatorCode* opcode, const OpResolver& op_resolver,
ErrorReporter* error_reporter, const TfLiteRegistration** registration) {
TfLiteStatus status = kTfLiteOk;
*registration = nullptr;
auto builtin_code = GetBuiltinCode(opcode);
int version = opcode->version();
if (builtin_code > BuiltinOperator_MAX ||
builtin_code < BuiltinOperator_MIN) {
TF_LITE_REPORT_ERROR(
error_reporter,
"Op builtin_code out of range: %d. Are you using old TFLite binary "
"with newer model?",
builtin_code);
status = kTfLiteError;
} else if (builtin_code != BuiltinOperator_CUSTOM) {
*registration = op_resolver.FindOp(builtin_code, version);
if (*registration == nullptr) {
TF_LITE_REPORT_ERROR(
error_reporter,
"Didn't find op for builtin opcode '%s' version '%d'\n",
EnumNameBuiltinOperator(builtin_code), version);
status = kTfLiteError;
}
} else if (!opcode->custom_code()) {
TF_LITE_REPORT_ERROR(
error_reporter,
"Operator with CUSTOM builtin_code has no custom_code.\n");
status = kTfLiteError;
} else {
const char* name = opcode->custom_code()->c_str();
*registration = op_resolver.FindOp(name, version);
if (*registration == nullptr) {
// Do not report error for unresolved custom op, we do the final check
// while preparing ops.
status = kTfLiteError;
}
}
return status;
}
} // namespace tflite

Some files were not shown because too many files have changed in this diff Show More