move security to APP_Framework
This commit is contained in:
parent
34ca5a215c
commit
ce480336d8
|
@ -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
|
||||||
|
|
|
@ -16,6 +16,9 @@ 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
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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 };
|
|
@ -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 };
|
|
@ -96,12 +96,3 @@ _ssize_t _write_r(struct _reent *ptr, int fd, const void *buf, size_t nbytes)
|
||||||
{
|
{
|
||||||
return write(fd, buf, nbytes);
|
return write(fd, buf, nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void exit(int __status);
|
|
||||||
void _exit(int __status){}
|
|
||||||
void _kill(int k)
|
|
||||||
{}
|
|
||||||
int _getpid(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -1,3 +0,0 @@
|
||||||
SRC_DIR := intelligent security
|
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -1,3 +0,0 @@
|
||||||
SRC_FILES := xs_adapter_bluetooth.c xs_adaper_bluetooth_register.c
|
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
SRC_FILES += xs_adapterAT_ethernet.c \
|
|
||||||
xs_adapterAT_ethernet_register.c
|
|
||||||
|
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
|
|
@ -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_cmd(AT+PING)failed ! 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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -1,3 +0,0 @@
|
||||||
SRC_FILES := xs_adapter_lora.c
|
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
SRC_DIR := bc28
|
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
|
|
@ -1,3 +0,0 @@
|
||||||
SRC_FILES := xs_adapter_at_nbiot.c xs_adapter_at_nbiot_register.c
|
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
SRC_FILES := xs_adapter_manager.c \
|
|
||||||
xs_adapter_at_agent.c
|
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
SRC_FILES += xs_adapter_at_wifi.c \
|
|
||||||
xs_adapter_at_wifi_register.c \
|
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
|
|
@ -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("ATOrderSend(AT+PING)failed ! 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("ATOrderSend(AT+PING)failed ! 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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -1,3 +0,0 @@
|
||||||
SRC_FILES := xs_adapter_zigbee.c xs_adaper_zigbee_register.c
|
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -1,5 +0,0 @@
|
||||||
ifeq ($(CONFIG_CONNECTION_ADAPTER), y)
|
|
||||||
SRC_DIR += Adapter
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
|
|
@ -1,2 +0,0 @@
|
||||||
menu "Control"
|
|
||||||
endmenu
|
|
|
@ -1,5 +0,0 @@
|
||||||
menu "Intelligence"
|
|
||||||
|
|
||||||
source "$KERNEL_DIR/framework/intelligent/tflite-mcu/Kconfig"
|
|
||||||
|
|
||||||
endmenu
|
|
|
@ -1,3 +0,0 @@
|
||||||
SRC_DIR := tflite-mcu
|
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
|
|
@ -1,4 +0,0 @@
|
||||||
config INTELLIGENT_TFLITE
|
|
||||||
bool "Tensorflow Lite for Micro"
|
|
||||||
select LIB_CPLUSPLUS
|
|
||||||
default n
|
|
|
@ -1,89 +0,0 @@
|
||||||
TFLITE_SRCS = \
|
|
||||||
source/tensorflow/lite/micro/all_ops_resolver.cc \
|
|
||||||
source/tensorflow/lite/micro/debug_log.cc \
|
|
||||||
source/tensorflow/lite/micro/memory_helpers.cc \
|
|
||||||
source/tensorflow/lite/micro/micro_allocator.cc \
|
|
||||||
source/tensorflow/lite/micro/micro_error_reporter.cc \
|
|
||||||
source/tensorflow/lite/micro/micro_interpreter.cc \
|
|
||||||
source/tensorflow/lite/micro/micro_profiler.cc \
|
|
||||||
source/tensorflow/lite/micro/micro_string.cc \
|
|
||||||
source/tensorflow/lite/micro/micro_time.cc \
|
|
||||||
source/tensorflow/lite/micro/micro_utils.cc \
|
|
||||||
source/tensorflow/lite/micro/recording_micro_allocator.cc \
|
|
||||||
source/tensorflow/lite/micro/recording_simple_memory_allocator.cc \
|
|
||||||
source/tensorflow/lite/micro/simple_memory_allocator.cc \
|
|
||||||
source/tensorflow/lite/micro/test_helpers.cc \
|
|
||||||
source/tensorflow/lite/micro/benchmarks/keyword_scrambled_model_data.cc \
|
|
||||||
source/tensorflow/lite/micro/memory_planner/greedy_memory_planner.cc \
|
|
||||||
source/tensorflow/lite/micro/memory_planner/linear_memory_planner.cc \
|
|
||||||
source/tensorflow/lite/micro/testing/test_conv_model.cc \
|
|
||||||
source/tensorflow/lite/c/common.c \
|
|
||||||
source/tensorflow/lite/core/api/error_reporter.cc \
|
|
||||||
source/tensorflow/lite/core/api/flatbuffer_conversions.cc \
|
|
||||||
source/tensorflow/lite/core/api/op_resolver.cc \
|
|
||||||
source/tensorflow/lite/core/api/tensor_utils.cc \
|
|
||||||
source/tensorflow/lite/kernels/internal/quantization_util.cc \
|
|
||||||
source/tensorflow/lite/kernels/kernel_util.cc \
|
|
||||||
source/tensorflow/lite/schema/schema_utils.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/activations.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/arg_min_max.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/ceil.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/circular_buffer.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/comparisons.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/concatenation.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/conv_test_common.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/dequantize.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/detection_postprocess.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/elementwise.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/ethosu.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/flexbuffers_generated_data.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/floor.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/hard_swish.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/kernel_runner.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/kernel_util.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/l2norm.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/logical.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/logistic.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/maximum_minimum.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/neg.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/pack.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/pad.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/prelu.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/quantize.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/quantize_common.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/reduce.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/reshape.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/resize_nearest_neighbor.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/round.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/shape.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/split.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/split_v.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/strided_slice.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/sub.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/svdf_common.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/tanh.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/transpose_conv.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/unpack.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/add.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/conv.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/depthwise_conv.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/fully_connected.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/mul.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/pooling.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/softmax.cc \
|
|
||||||
source/tensorflow/lite/micro/kernels/svdf.cc
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_INTELLIGENT_TFLITE),y)
|
|
||||||
SRC_FILES := $(TFLITE_SRCS) tf_fini_fix.c
|
|
||||||
#CPPPATHS += \
|
|
||||||
-Isource \
|
|
||||||
-Isource/third_party/gemmlowp \
|
|
||||||
-Isource/third_party/flatbuffers/include \
|
|
||||||
-Isource/third_party/ruy
|
|
||||||
DEFINES += -DTF_LITE_USE_GLOBAL_CMATH_FUNCTIONS \
|
|
||||||
-DTF_LITE_USE_GLOBAL_MAX \
|
|
||||||
-DTF_LITE_USE_GLOBAL_MIN \
|
|
||||||
-DTF_LITE_STATIC_MEMORY
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(KERNEL_ROOT)/compiler.mk
|
|
|
@ -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.
|
|
|
@ -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_
|
|
|
@ -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_
|
|
|
@ -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_
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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, ®);
|
|
||||||
// }
|
|
||||||
// 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, ¶ms_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_
|
|
|
@ -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
|
|
|
@ -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_
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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_
|
|
|
@ -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
|
|
|
@ -1,60 +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_OP_RESOLVER_H_
|
|
||||||
#define TENSORFLOW_LITE_CORE_API_OP_RESOLVER_H_
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "tensorflow/lite/c/common.h"
|
|
||||||
#include "tensorflow/lite/core/api/error_reporter.h"
|
|
||||||
#include "tensorflow/lite/schema/schema_generated.h"
|
|
||||||
|
|
||||||
namespace tflite {
|
|
||||||
|
|
||||||
/// Abstract interface that returns TfLiteRegistrations given op codes or custom
|
|
||||||
/// op names. This is the mechanism that ops being referenced in the flatbuffer
|
|
||||||
/// model are mapped to executable function pointers (TfLiteRegistrations).
|
|
||||||
class OpResolver {
|
|
||||||
public:
|
|
||||||
/// Finds the op registration for a builtin operator by enum code.
|
|
||||||
virtual const TfLiteRegistration* FindOp(tflite::BuiltinOperator op,
|
|
||||||
int version) const = 0;
|
|
||||||
/// Finds the op registration of a custom operator by op name.
|
|
||||||
virtual const TfLiteRegistration* FindOp(const char* op,
|
|
||||||
int version) const = 0;
|
|
||||||
|
|
||||||
// Returns optional delegates for resolving and handling ops in the flatbuffer
|
|
||||||
// model. This may be used in addition to the standard TfLiteRegistration
|
|
||||||
// lookup for graph resolution.
|
|
||||||
using TfLiteDelegatePtrVector =
|
|
||||||
std::vector<std::unique_ptr<TfLiteDelegate, void (*)(TfLiteDelegate*)>>;
|
|
||||||
virtual TfLiteDelegatePtrVector GetDelegates(int num_threads) const {
|
|
||||||
return TfLiteDelegatePtrVector();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~OpResolver() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handles the logic for converting between an OperatorCode structure extracted
|
|
||||||
// from a flatbuffer and information about a registered operator
|
|
||||||
// implementation.
|
|
||||||
TfLiteStatus GetRegistrationFromOpCode(const OperatorCode* opcode,
|
|
||||||
const OpResolver& op_resolver,
|
|
||||||
ErrorReporter* error_reporter,
|
|
||||||
const TfLiteRegistration** registration);
|
|
||||||
|
|
||||||
} // namespace tflite
|
|
||||||
|
|
||||||
#endif // TENSORFLOW_LITE_CORE_API_OP_RESOLVER_H_
|
|
|
@ -1,194 +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_PROFILER_H_
|
|
||||||
#define TENSORFLOW_LITE_CORE_API_PROFILER_H_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace tflite {
|
|
||||||
|
|
||||||
// A simple utility for enabling profiled event tracing in TensorFlow Lite.
|
|
||||||
class Profiler {
|
|
||||||
public:
|
|
||||||
// As certain Profiler instance might be only interested in certain event
|
|
||||||
// types, we define each event type value to allow a Profiler to use
|
|
||||||
// bitmasking bitwise operations to determine whether an event should be
|
|
||||||
// recorded or not.
|
|
||||||
enum class EventType {
|
|
||||||
// Default event type, the metadata field has no special significance.
|
|
||||||
DEFAULT = 1,
|
|
||||||
|
|
||||||
// The event is an operator invocation and the event_metadata field is the
|
|
||||||
// index of operator node.
|
|
||||||
OPERATOR_INVOKE_EVENT = 2,
|
|
||||||
|
|
||||||
// The event is an invocation for an internal operator of a TFLite delegate.
|
|
||||||
// The event_metadata field is the index of operator node that's specific to
|
|
||||||
// the delegate.
|
|
||||||
DELEGATE_OPERATOR_INVOKE_EVENT = 4,
|
|
||||||
|
|
||||||
// The event is a recording of runtime instrumentation such as the overall
|
|
||||||
// TFLite runtime status, the TFLite delegate status (if a delegate
|
|
||||||
// is applied), and the overall model inference latency etc.
|
|
||||||
// Note, the delegate status and overall status are stored as separate
|
|
||||||
// event_metadata fields. In particular, the delegate status is encoded
|
|
||||||
// as DelegateStatus::full_status().
|
|
||||||
GENERAL_RUNTIME_INSTRUMENTATION_EVENT = 8,
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~Profiler() {}
|
|
||||||
|
|
||||||
// Signals the beginning of an event and returns a handle to the profile
|
|
||||||
// event. The `event_metadata1` and `event_metadata2` have different
|
|
||||||
// interpretations based on the actual Profiler instance and the `event_type`.
|
|
||||||
// For example, as for the 'SubgraphAwareProfiler' defined in
|
|
||||||
// lite/core/subgraph.h, when the event_type is OPERATOR_INVOKE_EVENT,
|
|
||||||
// `event_metadata1` represents the index of a TFLite node, and
|
|
||||||
// `event_metadata2` represents the index of the subgraph that this event
|
|
||||||
// comes from.
|
|
||||||
virtual uint32_t BeginEvent(const char* tag, EventType event_type,
|
|
||||||
int64_t event_metadata1,
|
|
||||||
int64_t event_metadata2) = 0;
|
|
||||||
// Similar w/ the above, but `event_metadata2` defaults to 0.
|
|
||||||
uint32_t BeginEvent(const char* tag, EventType event_type,
|
|
||||||
int64_t event_metadata) {
|
|
||||||
return BeginEvent(tag, event_type, event_metadata, /*event_metadata2*/ 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signals an end to the specified profile event with 'event_metadata's, This
|
|
||||||
// is useful when 'event_metadata's are not available when the event begins
|
|
||||||
// or when one wants to overwrite the 'event_metadata's set at the beginning.
|
|
||||||
virtual void EndEvent(uint32_t event_handle, int64_t event_metadata1,
|
|
||||||
int64_t event_metadata2) {}
|
|
||||||
// Signals an end to the specified profile event.
|
|
||||||
virtual void EndEvent(uint32_t event_handle) = 0;
|
|
||||||
|
|
||||||
// Appends an event of type 'event_type' with 'tag' and 'event_metadata'
|
|
||||||
// which started at 'start' and ended at 'end'
|
|
||||||
// Note:
|
|
||||||
// In cases were ProfileSimmarizer and tensorflow::StatsCalculator are used
|
|
||||||
// they assume the value is in "usec", if in any case subclasses
|
|
||||||
// didn't put usec, then the values are not meaningful.
|
|
||||||
// TODO karimnosseir: Revisit and make the function more clear.
|
|
||||||
void AddEvent(const char* tag, EventType event_type, uint64_t start,
|
|
||||||
uint64_t end, int64_t event_metadata) {
|
|
||||||
AddEvent(tag, event_type, start, end, event_metadata,
|
|
||||||
/*event_metadata2*/ 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void AddEvent(const char* tag, EventType event_type, uint64_t start,
|
|
||||||
uint64_t end, int64_t event_metadata1,
|
|
||||||
int64_t event_metadata2) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
friend class ScopedProfile;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Adds a profile event to `profiler` that begins with the construction
|
|
||||||
// of the object and ends when the object goes out of scope.
|
|
||||||
// The lifetime of tag should be at least the lifetime of `profiler`.
|
|
||||||
// `profiler` may be null, in which case nothing is profiled.
|
|
||||||
class ScopedProfile {
|
|
||||||
public:
|
|
||||||
ScopedProfile(Profiler* profiler, const char* tag,
|
|
||||||
Profiler::EventType event_type = Profiler::EventType::DEFAULT,
|
|
||||||
int64_t event_metadata = 0)
|
|
||||||
: profiler_(profiler), event_handle_(0) {
|
|
||||||
if (profiler) {
|
|
||||||
event_handle_ = profiler_->BeginEvent(tag, event_type, event_metadata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~ScopedProfile() {
|
|
||||||
if (profiler_) {
|
|
||||||
profiler_->EndEvent(event_handle_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Profiler* profiler_;
|
|
||||||
uint32_t event_handle_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ScopedOperatorProfile : public ScopedProfile {
|
|
||||||
public:
|
|
||||||
ScopedOperatorProfile(Profiler* profiler, const char* tag, int node_index)
|
|
||||||
: ScopedProfile(profiler, tag, Profiler::EventType::OPERATOR_INVOKE_EVENT,
|
|
||||||
static_cast<uint32_t>(node_index)) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ScopedDelegateOperatorProfile : public ScopedProfile {
|
|
||||||
public:
|
|
||||||
ScopedDelegateOperatorProfile(Profiler* profiler, const char* tag,
|
|
||||||
int node_index)
|
|
||||||
: ScopedProfile(profiler, tag,
|
|
||||||
Profiler::EventType::DELEGATE_OPERATOR_INVOKE_EVENT,
|
|
||||||
static_cast<uint32_t>(node_index)) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class ScopedRuntimeInstrumentationProfile : public ScopedProfile {
|
|
||||||
public:
|
|
||||||
ScopedRuntimeInstrumentationProfile(Profiler* profiler, const char* tag)
|
|
||||||
: ScopedProfile(
|
|
||||||
profiler, tag,
|
|
||||||
Profiler::EventType::GENERAL_RUNTIME_INSTRUMENTATION_EVENT, -1) {}
|
|
||||||
|
|
||||||
void set_runtime_status(int64_t delegate_status, int64_t interpreter_status) {
|
|
||||||
if (profiler_) {
|
|
||||||
delegate_status_ = delegate_status;
|
|
||||||
interpreter_status_ = interpreter_status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~ScopedRuntimeInstrumentationProfile() {
|
|
||||||
if (profiler_) {
|
|
||||||
profiler_->EndEvent(event_handle_, delegate_status_, interpreter_status_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int64_t delegate_status_;
|
|
||||||
int64_t interpreter_status_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace tflite
|
|
||||||
|
|
||||||
#define TFLITE_VARNAME_UNIQ_IMPL(name, ctr) name##ctr
|
|
||||||
#define TFLITE_VARNAME_UNIQ(name, ctr) TFLITE_VARNAME_UNIQ_IMPL(name, ctr)
|
|
||||||
|
|
||||||
#define TFLITE_SCOPED_TAGGED_DEFAULT_PROFILE(profiler, tag) \
|
|
||||||
tflite::ScopedProfile TFLITE_VARNAME_UNIQ(_profile_, __COUNTER__)( \
|
|
||||||
(profiler), (tag))
|
|
||||||
|
|
||||||
#define TFLITE_SCOPED_TAGGED_OPERATOR_PROFILE(profiler, tag, node_index) \
|
|
||||||
tflite::ScopedOperatorProfile TFLITE_VARNAME_UNIQ(_profile_, __COUNTER__)( \
|
|
||||||
(profiler), (tag), (node_index))
|
|
||||||
|
|
||||||
#define TFLITE_SCOPED_DELEGATE_OPERATOR_PROFILE(profiler, tag, node_index) \
|
|
||||||
tflite::ScopedDelegateOperatorProfile TFLITE_VARNAME_UNIQ( \
|
|
||||||
_profile_, __COUNTER__)((profiler), (tag), (node_index))
|
|
||||||
|
|
||||||
#define TFLITE_ADD_RUNTIME_INSTRUMENTATION_EVENT( \
|
|
||||||
profiler, tag, event_metadata1, event_metadata2) \
|
|
||||||
do { \
|
|
||||||
if (profiler) { \
|
|
||||||
const auto handle = profiler->BeginEvent( \
|
|
||||||
tag, Profiler::EventType::GENERAL_RUNTIME_INSTRUMENTATION_EVENT, \
|
|
||||||
event_metadata1, event_metadata2); \
|
|
||||||
profiler->EndEvent(handle); \
|
|
||||||
} \
|
|
||||||
} while (false);
|
|
||||||
|
|
||||||
#endif // TENSORFLOW_LITE_CORE_API_PROFILER_H_
|
|
|
@ -1,50 +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/core/api/tensor_utils.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "tensorflow/lite/c/common.h"
|
|
||||||
|
|
||||||
namespace tflite {
|
|
||||||
|
|
||||||
TfLiteStatus ResetVariableTensor(TfLiteTensor* tensor) {
|
|
||||||
if (!tensor->is_variable) {
|
|
||||||
return kTfLiteOk;
|
|
||||||
}
|
|
||||||
// TODO(b/115961645): Implement - If a variable tensor has a buffer, reset it
|
|
||||||
// to the value of the buffer.
|
|
||||||
int value = 0;
|
|
||||||
if (tensor->type == kTfLiteInt8) {
|
|
||||||
value = tensor->params.zero_point;
|
|
||||||
}
|
|
||||||
// TODO(b/139446230): Provide a platform header to better handle these
|
|
||||||
// specific scenarios.
|
|
||||||
#if __ANDROID__ || defined(__x86_64__) || defined(__i386__) || \
|
|
||||||
defined(__i386) || defined(__x86__) || defined(__X86__) || \
|
|
||||||
defined(_X86_) || defined(_M_IX86) || defined(_M_X64)
|
|
||||||
memset(tensor->data.raw, value, tensor->bytes);
|
|
||||||
#else
|
|
||||||
char* raw_ptr = tensor->data.raw;
|
|
||||||
for (size_t i = 0; i < tensor->bytes; ++i) {
|
|
||||||
*raw_ptr = value;
|
|
||||||
raw_ptr++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return kTfLiteOk;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace tflite
|
|
|
@ -1,28 +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.
|
|
||||||
==============================================================================*/
|
|
||||||
|
|
||||||
#ifndef TENSORFLOW_LITE_CORE_API_TENSOR_UTILS_H_
|
|
||||||
#define TENSORFLOW_LITE_CORE_API_TENSOR_UTILS_H_
|
|
||||||
|
|
||||||
#include "tensorflow/lite/c/common.h"
|
|
||||||
|
|
||||||
namespace tflite {
|
|
||||||
|
|
||||||
// Resets a variable tensor to the default value.
|
|
||||||
TfLiteStatus ResetVariableTensor(TfLiteTensor* tensor);
|
|
||||||
|
|
||||||
} // namespace tflite
|
|
||||||
|
|
||||||
#endif // TENSORFLOW_LITE_CORE_API_TENSOR_UTILS_H_
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,117 +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_KERNELS_INTERNAL_COMPATIBILITY_H_
|
|
||||||
#define TENSORFLOW_LITE_KERNELS_INTERNAL_COMPATIBILITY_H_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include "tensorflow/lite/kernels/op_macros.h"
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef TFLITE_DCHECK
|
|
||||||
#define TFLITE_DCHECK(condition) (condition) ? (void)0 : TFLITE_ASSERT_FALSE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TFLITE_DCHECK_EQ
|
|
||||||
#define TFLITE_DCHECK_EQ(x, y) ((x) == (y)) ? (void)0 : TFLITE_ASSERT_FALSE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TFLITE_DCHECK_NE
|
|
||||||
#define TFLITE_DCHECK_NE(x, y) ((x) != (y)) ? (void)0 : TFLITE_ASSERT_FALSE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TFLITE_DCHECK_GE
|
|
||||||
#define TFLITE_DCHECK_GE(x, y) ((x) >= (y)) ? (void)0 : TFLITE_ASSERT_FALSE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TFLITE_DCHECK_GT
|
|
||||||
#define TFLITE_DCHECK_GT(x, y) ((x) > (y)) ? (void)0 : TFLITE_ASSERT_FALSE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TFLITE_DCHECK_LE
|
|
||||||
#define TFLITE_DCHECK_LE(x, y) ((x) <= (y)) ? (void)0 : TFLITE_ASSERT_FALSE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TFLITE_DCHECK_LT
|
|
||||||
#define TFLITE_DCHECK_LT(x, y) ((x) < (y)) ? (void)0 : TFLITE_ASSERT_FALSE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO(ahentz): Clean up: We should stick to the DCHECK versions.
|
|
||||||
#ifndef TFLITE_CHECK
|
|
||||||
#define TFLITE_CHECK(condition) (condition) ? (void)0 : TFLITE_ABORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TFLITE_CHECK_EQ
|
|
||||||
#define TFLITE_CHECK_EQ(x, y) ((x) == (y)) ? (void)0 : TFLITE_ABORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TFLITE_CHECK_NE
|
|
||||||
#define TFLITE_CHECK_NE(x, y) ((x) != (y)) ? (void)0 : TFLITE_ABORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TFLITE_CHECK_GE
|
|
||||||
#define TFLITE_CHECK_GE(x, y) ((x) >= (y)) ? (void)0 : TFLITE_ABORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TFLITE_CHECK_GT
|
|
||||||
#define TFLITE_CHECK_GT(x, y) ((x) > (y)) ? (void)0 : TFLITE_ABORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TFLITE_CHECK_LE
|
|
||||||
#define TFLITE_CHECK_LE(x, y) ((x) <= (y)) ? (void)0 : TFLITE_ABORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TFLITE_CHECK_LT
|
|
||||||
#define TFLITE_CHECK_LT(x, y) ((x) < (y)) ? (void)0 : TFLITE_ABORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TF_LITE_STATIC_MEMORY
|
|
||||||
// TODO(b/162019032): Consider removing these type-aliases.
|
|
||||||
//##if 0
|
|
||||||
using int8 = std::int8_t;
|
|
||||||
using uint8 = std::uint8_t;
|
|
||||||
using int16 = std::int16_t;
|
|
||||||
using uint16 = std::uint16_t;
|
|
||||||
using int32 = std::int32_t;
|
|
||||||
using uint32 = std::uint32_t;
|
|
||||||
#endif // !defined(TF_LITE_STATIC_MEMORY)
|
|
||||||
|
|
||||||
|
|
||||||
// TFLITE_DEPRECATED()
|
|
||||||
//
|
|
||||||
// Duplicated from absl/base/macros.h to avoid pulling in that library.
|
|
||||||
// Marks a deprecated class, struct, enum, function, method and variable
|
|
||||||
// declarations. The macro argument is used as a custom diagnostic message (e.g.
|
|
||||||
// suggestion of a better alternative).
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// class TFLITE_DEPRECATED("Use Bar instead") Foo {...};
|
|
||||||
// TFLITE_DEPRECATED("Use Baz instead") void Bar() {...}
|
|
||||||
//
|
|
||||||
// Every usage of a deprecated entity will trigger a warning when compiled with
|
|
||||||
// clang's `-Wdeprecated-declarations` option. This option is turned off by
|
|
||||||
// default, but the warnings will be reported by clang-tidy.
|
|
||||||
#if defined(__clang__) && __cplusplus >= 201103L
|
|
||||||
#define TFLITE_DEPRECATED(message) __attribute__((deprecated(message)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef TFLITE_DEPRECATED
|
|
||||||
#define TFLITE_DEPRECATED(message)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_COMPATIBILITY_H_
|
|
||||||
|
|
|
@ -1,40 +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.
|
|
||||||
==============================================================================*/
|
|
||||||
#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_CPPMATH_H_
|
|
||||||
#define TENSORFLOW_LITE_KERNELS_INTERNAL_CPPMATH_H_
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
namespace tflite {
|
|
||||||
|
|
||||||
#if defined(TF_LITE_USE_GLOBAL_CMATH_FUNCTIONS) || \
|
|
||||||
(defined(__ANDROID__) && !defined(__NDK_MAJOR__)) || defined(ARDUINO) || \
|
|
||||||
defined(__ZEPHYR__)
|
|
||||||
#define TF_LITE_GLOBAL_STD_PREFIX
|
|
||||||
#else
|
|
||||||
#define TF_LITE_GLOBAL_STD_PREFIX std
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DECLARE_STD_GLOBAL_SWITCH1(tf_name, std_name) \
|
|
||||||
template <class T> \
|
|
||||||
inline T tf_name(const T x) { \
|
|
||||||
return TF_LITE_GLOBAL_STD_PREFIX::std_name(x); \
|
|
||||||
}
|
|
||||||
|
|
||||||
DECLARE_STD_GLOBAL_SWITCH1(TfLiteRound, round);
|
|
||||||
|
|
||||||
} // namespace tflite
|
|
||||||
|
|
||||||
#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_CPPMATH_H_
|
|
|
@ -1,35 +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.
|
|
||||||
==============================================================================*/
|
|
||||||
#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_MAX_H_
|
|
||||||
#define TENSORFLOW_LITE_KERNELS_INTERNAL_MAX_H_
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
namespace tflite {
|
|
||||||
|
|
||||||
#if defined(TF_LITE_USE_GLOBAL_MAX) || defined(__ZEPHYR__)
|
|
||||||
inline float TfLiteMax(const float& x, const float& y) {
|
|
||||||
return std::max(x, y);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
template <class T>
|
|
||||||
inline T TfLiteMax(const T& x, const T& y) {
|
|
||||||
return std::fmax(x, y);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace tflite
|
|
||||||
|
|
||||||
#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_MAX_H_
|
|
|
@ -1,35 +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.
|
|
||||||
==============================================================================*/
|
|
||||||
#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_MIN_H_
|
|
||||||
#define TENSORFLOW_LITE_KERNELS_INTERNAL_MIN_H_
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
namespace tflite {
|
|
||||||
|
|
||||||
#if defined(TF_LITE_USE_GLOBAL_MIN) || defined(__ZEPHYR__)
|
|
||||||
inline float TfLiteMin(const float& x, const float& y) {
|
|
||||||
return std::min(x, y);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
template <class T>
|
|
||||||
inline T TfLiteMin(const T& x, const T& y) {
|
|
||||||
return std::fmin(x, y);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace tflite
|
|
||||||
|
|
||||||
#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_MIN_H_
|
|
|
@ -1,40 +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.
|
|
||||||
==============================================================================*/
|
|
||||||
#ifndef TENSORFLOW_LITE_KERNELS_INTERNAL_OPTIMIZED_NEON_CHECK_H_
|
|
||||||
#define TENSORFLOW_LITE_KERNELS_INTERNAL_OPTIMIZED_NEON_CHECK_H_
|
|
||||||
|
|
||||||
#if defined(__ARM_NEON__) || defined(__ARM_NEON)
|
|
||||||
#define USE_NEON
|
|
||||||
#include <arm_neon.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined __GNUC__ && defined __SSE4_1__ && !defined TF_LITE_DISABLE_X86_NEON
|
|
||||||
#define USE_NEON
|
|
||||||
#include "NEON_2_SSE.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// NEON_OR_PORTABLE(SomeFunc, args) calls NeonSomeFunc(args) if USE_NEON is
|
|
||||||
// defined, PortableSomeFunc(args) otherwise.
|
|
||||||
#ifdef USE_NEON
|
|
||||||
// Always use Neon code
|
|
||||||
#define NEON_OR_PORTABLE(funcname, ...) Neon##funcname(__VA_ARGS__)
|
|
||||||
|
|
||||||
#else
|
|
||||||
// No NEON available: Use Portable code
|
|
||||||
#define NEON_OR_PORTABLE(funcname, ...) Portable##funcname(__VA_ARGS__)
|
|
||||||
|
|
||||||
#endif // defined(USE_NEON)
|
|
||||||
|
|
||||||
#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_OPTIMIZED_NEON_CHECK_H_
|
|
|
@ -1,122 +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_KERNELS_INTERNAL_PORTABLE_TENSOR_H_
|
|
||||||
#define TENSORFLOW_LITE_KERNELS_INTERNAL_PORTABLE_TENSOR_H_
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "tensorflow/lite/c/common.h"
|
|
||||||
#include "tensorflow/lite/kernels/internal/tensor_ctypes.h"
|
|
||||||
#include "tensorflow/lite/kernels/internal/types.h"
|
|
||||||
|
|
||||||
namespace tflite {
|
|
||||||
|
|
||||||
inline RuntimeShape GetTensorShape(std::vector<int32_t> data) {
|
|
||||||
return RuntimeShape(data.size(), data.data());
|
|
||||||
}
|
|
||||||
|
|
||||||
// A list of tensors in a format that can be used by kernels like split and
|
|
||||||
// concatenation.
|
|
||||||
template <typename T>
|
|
||||||
class VectorOfTensors {
|
|
||||||
public:
|
|
||||||
// Build with the tensors in 'tensor_list'.
|
|
||||||
VectorOfTensors(const TfLiteContext& context,
|
|
||||||
const TfLiteIntArray& tensor_list) {
|
|
||||||
int num_tensors = tensor_list.size;
|
|
||||||
|
|
||||||
all_data_.reserve(num_tensors);
|
|
||||||
all_shape_.reserve(num_tensors);
|
|
||||||
all_shape_ptr_.reserve(num_tensors);
|
|
||||||
|
|
||||||
for (int i = 0; i < num_tensors; ++i) {
|
|
||||||
TfLiteTensor* t = &context.tensors[tensor_list.data[i]];
|
|
||||||
all_data_.push_back(GetTensorData<T>(t));
|
|
||||||
all_shape_.push_back(GetTensorShape(t));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Taking the pointer from inside a std::vector is only OK if the vector is
|
|
||||||
// never modified, so we populate all_shape in the previous loop and then we
|
|
||||||
// are free to grab iterators here.
|
|
||||||
for (int i = 0; i < num_tensors; ++i) {
|
|
||||||
all_shape_ptr_.push_back(&all_shape_[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Return a pointer to the data pointers of all tensors in the list. For
|
|
||||||
// example:
|
|
||||||
// float* const* f = v.data();
|
|
||||||
// f[0][1] is the second element of the first tensor.
|
|
||||||
T* const* data() const { return all_data_.data(); }
|
|
||||||
|
|
||||||
// Return a pointer the shape pointers of all tensors in the list. For
|
|
||||||
// example:
|
|
||||||
// const RuntimeShape* const* d = v.dims();
|
|
||||||
// dims[1] are the dimensions of the second tensor in the list.
|
|
||||||
const RuntimeShape* const* shapes() const { return all_shape_ptr_.data(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<T*> all_data_;
|
|
||||||
std::vector<RuntimeShape> all_shape_;
|
|
||||||
std::vector<RuntimeShape*> all_shape_ptr_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A list of quantized tensors in a format that can be used by kernels like
|
|
||||||
// split and concatenation.
|
|
||||||
class VectorOfQuantizedTensors : public VectorOfTensors<uint8_t> {
|
|
||||||
public:
|
|
||||||
// Build with the tensors in 'tensor_list'.
|
|
||||||
VectorOfQuantizedTensors(const TfLiteContext& context,
|
|
||||||
const TfLiteIntArray& tensor_list)
|
|
||||||
: VectorOfTensors<uint8_t>(context, tensor_list) {
|
|
||||||
for (int i = 0; i < tensor_list.size; ++i) {
|
|
||||||
TfLiteTensor* t = &context.tensors[tensor_list.data[i]];
|
|
||||||
zero_point_.push_back(t->params.zero_point);
|
|
||||||
scale_.push_back(t->params.scale);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const float* scale() const { return scale_.data(); }
|
|
||||||
const int32_t* zero_point() const { return zero_point_.data(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<int32_t> zero_point_;
|
|
||||||
std::vector<float> scale_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Writes randomly accessed values from `input` sequentially into `output`.
|
|
||||||
template <typename T>
|
|
||||||
class SequentialTensorWriter {
|
|
||||||
public:
|
|
||||||
SequentialTensorWriter(const TfLiteTensor* input, TfLiteTensor* output) {
|
|
||||||
input_data_ = GetTensorData<T>(input);
|
|
||||||
output_ptr_ = GetTensorData<T>(output);
|
|
||||||
}
|
|
||||||
SequentialTensorWriter(const T* input_data, T* output_data)
|
|
||||||
: input_data_(input_data), output_ptr_(output_data) {}
|
|
||||||
|
|
||||||
void Write(int position) { *output_ptr_++ = input_data_[position]; }
|
|
||||||
void WriteN(int position, int len) {
|
|
||||||
memcpy(output_ptr_, &input_data_[position], sizeof(T) * len);
|
|
||||||
output_ptr_ += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const T* input_data_;
|
|
||||||
T* output_ptr_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace tflite
|
|
||||||
|
|
||||||
#endif // TENSORFLOW_LITE_KERNELS_INTERNAL_PORTABLE_TENSOR_H_
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue