initial commit

This commit is contained in:
2024-12-15 00:34:01 +06:00
commit 31efbc726f
1576 changed files with 657692 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*.o
build/

6
.gitmodules vendored Normal file
View File

@@ -0,0 +1,6 @@
[submodule "lib/freertos"]
path = lib/freertos
url = https://github.com/FreeRTOS/FreeRTOS-Kernel.git
[submodule "rtl8710_openocd"]
path = rtl8710_openocd
url = https://git.hye.su/mira/rtl8710_openocd.git

53
Makefile Normal file
View File

@@ -0,0 +1,53 @@
MKFILES := mk
RTL8710_PATH ?= ./rtl8710_openocd
# build dir
BUILD_DIR ?= build
BIN_DIR := $(BUILD_DIR)/bin
# OTA config
OTA_IDX ?= 1
IMAGE2_OTA ?= image2_all_ota$(OTA_IDX).bin
BOOTLOADER ?= $(BUILD_DIR)/boot/boot_all.o
ifneq ($(OTA_IDX),1)
ifneq ($(OTA_IDX),2)
$(error OTA_IDX must be "1" or "2")
endif
endif
FLASH_ADDRESS := $(if $(OTA_IDX),0x80000,0x0B000)
FLASH_FILE := $(BIN_DIR)/image2_all_ota$(OTA_IDX).bin
.PHONY: all
all: ram_all
# build targets
.PHONY: ram_all mp clean build_info
ram_all:
$(MAKE) -f $(MKFILES)/application.mk
mp clean build_info:
$(MAKE) -f $(MKFILES)/application.mk $@
include $(RTL8710_PATH)/rtl8710-openocd.mk
INTERFACE := jlink
OPENOCD_BASE := openocd -f interface/$(INTERFACE).cfg \
-f $(RTL8710_SCRIPT_PATH)/rtl8710.ocd \
-c "init" -c "reset halt"
.PHONY: flash
flash:
@$(OPENOCD_BASE) \
-c 'rtl8710_flash_auto_erase 1' \
-c 'rtl8710_flash_auto_verify 1' \
-c 'rtl8710_flash_write $(FLASH_FILE) $(FLASH_ADDRESS)' \
-c 'rtl8710_reboot' \
-c 'reset run' \
-c 'shutdown'
# flasher targets
.PHONY: rtl-test rtl-mac rtl-dump rtl-full-erase rtl-restore rtl-restore-nae rtl-verify rtl-reset
export MKFILES OTA_IDX BUILD_DIR BIN_DIR IMAGE2_OTA BOOTLOADER

1427
export-rom_symbol_v01.txt Normal file

File diff suppressed because it is too large Load Diff

153
include/FreeRTOSConfig.h Normal file
View File

@@ -0,0 +1,153 @@
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif
#include "platform_autoconf.h"
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
*
* See http://www.freertos.org/a00110.html.
*----------------------------------------------------------*/
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ (SystemCoreClock)
#define configTICK_RATE_HZ ((uint32_t)1000)
// #define configSYSTICK_CLOCK_HZ 32768
#define configSTACK_DEPTH_TYPE size_t
#define configMINIMAL_STACK_SIZE ((configSTACK_DEPTH_TYPE)512)
#ifdef CONFIG_WIFI_EN
#define configTOTAL_HEAP_SIZE ((size_t)(100 * 1024))
#else
#define configTOTAL_HEAP_SIZE ((size_t)(20 * 1024))
#endif
#define configMAX_TASK_NAME_LEN (10)
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 0
#define configUSE_CO_ROUTINES 1
#define configUSE_MUTEXES 1
#define configUSE_TIMERS 1
#define configMAX_PRIORITIES (32)
#define PRIORITY_OFFSET (4)
#define configMAX_CO_ROUTINE_PRIORITIES (2)
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_ALTERNATIVE_API 0
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_RECURSIVE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 0
#define configGENERATE_RUN_TIME_STATS 0
#if configGENERATE_RUN_TIME_STATS
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() //( ulHighFrequencyTimerTicks
//= 0UL )
#define portGET_RUN_TIME_COUNTER_VALUE() \
xTickCount // ulHighFrequencyTimerTicks
#undef configUSE_TRACE_FACILITY
#define configUSE_TRACE_FACILITY 1
#define portCONFIGURE_STATS_PERIOD_VALUE 1000 // unit Ticks
#endif
#define configTIMER_TASK_PRIORITY (1)
#define configTIMER_QUEUE_LENGTH (10 + 64)
#define configTIMER_TASK_STACK_DEPTH \
(512) // USE_MIN_STACK_SIZE modify from 512 to 256
#if (__IASMARM__ != 1)
extern void freertos_pre_sleep_processing(unsigned int *expected_idle_time);
extern void freertos_post_sleep_processing(unsigned int *expected_idle_time);
extern int freertos_ready_to_sleep();
/* Enable tickless power saving. */
#define configUSE_TICKLESS_IDLE 1
/* In wlan usage, this value is suggested to use value less than 80 milliseconds
*/
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2
/* It's magic trick that let us can use our own sleep function */
#define configPRE_SLEEP_PROCESSING(x) (freertos_pre_sleep_processing(&x))
#define configPOST_SLEEP_PROCESSING(x) (freertos_post_sleep_processing(&x))
/* It's magic trick that let us can enable/disable tickless dynamically */
#define traceLOW_POWER_IDLE_BEGIN() \
; \
do { \
if (!freertos_ready_to_sleep()) { \
mtCOVERAGE_TEST_MARKER(); \
break; \
}
// portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime );
#define traceLOW_POWER_IDLE_END() \
; \
} \
while (0);
/* It's FreeRTOS related feature but it's not included in FreeRTOS design. */
#define configUSE_WAKELOCK_PMU 1
#endif // #if (__IASMARM__ != 1)
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_pcTaskGetTaskName 1
#define INCLUDE_xTimerPendFunctionCall 1
/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4 /* 15 priority levels */
#endif
/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x0f
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY \
(configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY \
(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
// #define RTK_MODE_TIMER
#define configSUPPORT_STATIC_ALLOCATION 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configAPPLICATION_ALLOCATED_HEAP 0
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
#endif /* FREERTOS_CONFIG_H */

9
include/build_info.h Normal file
View File

@@ -0,0 +1,9 @@
#define RTL_FW_COMPILE_TIME "2024/12/14-22:44:54"
#define RTL_FW_COMPILE_DATE "20241214"
#define UTS_VERSION "2024/12/14-22:44:54"
#define RTL8195AFW_COMPILE_TIME "2024/12/14-22:44:54"
#define RTL8195AFW_COMPILE_DATE "20241214"
#define RTL8195AFW_COMPILE_BY "mira"
#define RTL8195AFW_COMPILE_HOST "eirin"
#define RTL8195AFW_COMPILE_DOMAIN ""
#define RTL195AFW_COMPILER "gcc 14.1.0"

20
include/freertos_hooks.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef FREERTOS_HOOKS_H
#define FREERTOS_HOOKS_H
#include "FreeRTOS.h"
#include "task.h"
/**
* @brief Idle task hook function called by FreeRTOS idle task
*/
void vApplicationIdleHook(void);
/**
* @brief Stack overflow hook called when a stack overflow is detected
*
* @param pxTask Handle of the task that caused overflow
* @param pcTaskName Name of the task that caused overflow
*/
void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName);
#endif // FREERTOS_HOOKS_H

122
include/main.h Normal file
View File

@@ -0,0 +1,122 @@
#ifndef MAIN_H
#define MAIN_H
#include <autoconf.h>
#ifndef CONFIG_WLAN
#define CONFIG_WLAN 1
#endif
/* Header file declaration*/
void wlan_network();
/* Interactive Mode */
#define SERIAL_DEBUG_RX 1
/* WLAN and Netork */
#define STA_MODE_SSID "ap" /* Set SSID here */
#define AP_MODE_SSID "wlan_ap_ssid" /* Set SSID here */
#define AP_DEFAULT_CH 6
#define WLAN0_NAME "wlan0"
#define WLAN1_NAME "wlan1"
#define WPA_PASSPHRASE "1234567890" /* Max 32 cahracters */
#define WEP40_KEY {0x12, 0x34, 0x56, 0x78, 0x90}
#define ATVER_1 1 // For First AT command
#define ATVER_2 2 // For UART Module AT command
#if CONFIG_EXAMPLE_UART_ATCMD
#define ATCMD_VER ATVER_2
#else
#define ATCMD_VER ATVER_1
#endif
#if ATCMD_VER == ATVER_2
#undef CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 1
extern unsigned char sta_ip[4], sta_netmask[4], sta_gw[4];
extern unsigned char ap_ip[4], ap_netmask[4], ap_gw[4];
/*Static IP ADDRESS*/
#define IP_ADDR0 sta_ip[0]
#define IP_ADDR1 sta_ip[1]
#define IP_ADDR2 sta_ip[2]
#define IP_ADDR3 sta_ip[3]
/*NETMASK*/
#define NETMASK_ADDR0 sta_netmask[0]
#define NETMASK_ADDR1 sta_netmask[1]
#define NETMASK_ADDR2 sta_netmask[2]
#define NETMASK_ADDR3 sta_netmask[3]
/*Gateway Address*/
#define GW_ADDR0 sta_gw[0]
#define GW_ADDR1 sta_gw[1]
#define GW_ADDR2 sta_gw[2]
#define GW_ADDR3 sta_gw[3]
/*******************************************/
/*Static IP ADDRESS*/
#define AP_IP_ADDR0 ap_ip[0]
#define AP_IP_ADDR1 ap_ip[1]
#define AP_IP_ADDR2 ap_ip[2]
#define AP_IP_ADDR3 ap_ip[3]
/*NETMASK*/
#define AP_NETMASK_ADDR0 ap_netmask[0]
#define AP_NETMASK_ADDR1 ap_netmask[1]
#define AP_NETMASK_ADDR2 ap_netmask[2]
#define AP_NETMASK_ADDR3 ap_netmask[3]
/*Gateway Address*/
#define AP_GW_ADDR0 ap_gw[0]
#define AP_GW_ADDR1 ap_gw[1]
#define AP_GW_ADDR2 ap_gw[2]
#define AP_GW_ADDR3 ap_gw[3]
#else
/*Static IP ADDRESS*/
#define IP_ADDR0 192
#define IP_ADDR1 168
#define IP_ADDR2 1
#define IP_ADDR3 80
/*NETMASK*/
#define NETMASK_ADDR0 255
#define NETMASK_ADDR1 255
#define NETMASK_ADDR2 255
#define NETMASK_ADDR3 0
/*Gateway Address*/
#define GW_ADDR0 192
#define GW_ADDR1 168
#define GW_ADDR2 1
#define GW_ADDR3 1
/*******************************************/
/*Static IP ADDRESS*/
#define AP_IP_ADDR0 192
#define AP_IP_ADDR1 168
#define AP_IP_ADDR2 43
#define AP_IP_ADDR3 1
/*NETMASK*/
#define AP_NETMASK_ADDR0 255
#define AP_NETMASK_ADDR1 255
#define AP_NETMASK_ADDR2 255
#define AP_NETMASK_ADDR3 0
/*Gateway Address*/
#define AP_GW_ADDR0 192
#define AP_GW_ADDR1 168
#define AP_GW_ADDR2 43
#define AP_GW_ADDR3 1
#endif //#if ATCMD_VER == ATVER_2
#endif

242
include/platform_autoconf.h Normal file
View File

@@ -0,0 +1,242 @@
/*
* Automatically generated by make menuconfig: don't edit
*/
#define AUTOCONF_INCLUDED
/*
* < MENUCONFIG FOR CHIP CONFIG
*/
/*
* < CONFIG CHIP
*/
#define CONFIG_RTL8711B 1
#undef ARM_CORE_CM3
#define ARM_CORE_CM4 1
#define CONFIG_CHIP_A_CUT 1
#undef CONFIG_FPGA
/*
* < CONFIG CPU CLK
*/
#define CONFIG_CPU_CLK 1
#define CONFIG_CPU_125MHZ 1
#undef CONFIG_CPU_62_5MHZ
#undef CONFIG_CPU_31_25MHZ
#undef CONFIG_CPU_15_625MHZ
#undef CONFIG_CPU_7_8125MHZ
#undef CONFIG_CPU_4MHZ
#undef CONFIG_FPGA_CLK
#define PLATFORM_CLOCK (125000000)
#define CPU_CLOCK_SEL_VALUE (0)
/*
* < CONFIG OSC8M CLK
*/
#define CONFIG_OSC8M_CLK 1
#define CONFIG_OSC8M_8388608HZ 1
#undef CONFIG_OSC8M_8192000HZ
#undef CONFIG_OSC8M_8000000HZ
#undef CONFIG_OSC8M_16777216HZ
#define OSC8M_CLOCK (8388608)
/*
* < CONFIG TEST MODE
*/
#undef CONFIG_MP
#undef CONFIG_CP
#undef CONFIG_FT
#undef CONFIG_EQC
#undef CONFIG_RTL_SIM
#undef CONFIG_POST_SIM
/*
* < CONFIG OS
*/
#define CONFIG_KERNEL 1
#define PLATFORM_FREERTOS 1
#undef PLATFORM_ALIOS
#undef PLATFORM_UCOSII
#undef PLATFORM_ECOS
#undef CONFIG_TASK_SCHEDUL_DIS
#define TASK_SCHEDULER_DISABLED (0)
/*
* < CONFIG GTIMER
*/
#define CONFIG_TIMER_EN 1
#define CONFIG_TIMER_MODULE 1
/*
* < CONFIG WDG
*/
#define CONFIG_WDG 1
#define CONFIG_WDG_MODULE 1
/*
* < CONFIG GDMA
*/
#define CONFIG_GDMA_EN 1
#define CONFIG_GDMA_MODULE 1
/*
* < CONFIG GPIO
*/
#define CONFIG_GPIO_EN 1
#define CONFIG_GPIO_MODULE 1
/*
* < CONFIG SPI
*/
#define CONFIG_SPI_COM_EN 1
#define CONFIG_SPI_COM_MODULE 1
/*
* < CONFIG UART
*/
#define CONFIG_UART_EN 1
#define CONFIG_UART_MODULE 1
/*
* < CONFIG I2C
*/
#define CONFIG_I2C_EN 1
#define CONFIG_I2C_MODULE 1
/*
* < CONFIG I2S
*/
#define CONFIG_I2S_EN 1
#define CONFIG_I2S_MODULE 1
/*
* < CONFIG SOC PS
*/
#define CONFIG_SOC_PS_EN 1
#define CONFIG_SOC_PS_MODULE 1
/*
* < CONFIG CRYPTO
*/
#define CONFIG_CRYPTO_EN 1
#define CONFIG_CRYPTO_MODULE 1
/*
* < CONFIG PWM
*/
#define CONFIG_PWM_EN 1
/*
* < CONFIG EFUSE
*/
#define CONFIG_EFUSE_EN 1
#define CONFIG_EFUSE_MODULE 1
/*
* < CONFIG SPIC
*/
#define CONFIG_SPIC_EN 1
#define CONFIG_SPIC_MODULE 1
#define CONFIG_SPIC_PHASE_CALIBATION 1
#undef CONFIG_SPIC_4BYTES_ADDRESS
/*
* < CONFIG ADC
*/
#define CONFIG_ADC_EN 1
#define CONFIG_ADC_MODULE 1
/*
* < CONFIG SDIO Device
*/
#define CONFIG_SDIO_DEVICE_EN 1
#define CONFIG_SDIO_DEVICE_NORMAL 1
#define CONFIG_SDIO_DEVICE_MODULE 1
/*
* < CONFIG USB
*/
#define CONFIG_USB_EN 1
#define CONFIG_USB_MODULE 1
/*
* < CONFIG RDP
*/
#define CONFIG_RDP_ENABLE 1
/*
* < CONFIG PINMUX
*/
#undef CONFIG_PINMAP_ENABLE
/*
* < CONFIG PER TEST
*/
#undef CONFIG_PER_TEST
/*
* < CONFIG WIFI
*/
#define CONFIG_WIFI_EN 1
#define CONFIG_WIFI_NORMAL 1
#undef CONFIG_WIFI_TEST
#define CONFIG_WIFI_MODULE 1
/*
* < CONFIG NETWORK
*/
#define CONFIG_NETWORK 1
/*
* < CONFIG INIC
*/
#undef CONFIG_INIC_EN
/*
* < CONFIG USB_NIC
*/
#undef CONFIG_USB_DONGLE_NIC_EN
/*
* < RTK STD lib
*/
#define CONFIG_RTLIB_EN 1
#define CONFIG_RTLIB_MODULE 1
#undef CONFIG_RTLIB_VERIFY
/*
* < Add MBED SDK
*/
#undef CONFIG_MBED_ENABLED
/*
* < Build App Demo
*/
#undef CONFIG_APP_DEMO
/*
* < Dhrystone
*/
#undef CONFIG_DHRYSTONE_TEST
/*
* < SSL
*/
#undef CONFIG_SSL_ROM_TEST
/*
* < System Debug Message Config
*/
#define CONFIG_UART_LOG_HISTORY 1
#define CONFIG_DEBUG_LOG 1
#define CONFIG_DEBUG_ERR_MSG 1
#undef CONFIG_DEBUG_WARN_MSG
#undef CONFIG_DEBUG_INFO_MSG
/*
* < Build Option
*/
#define CONFIG_TOOLCHAIN_ASDK 1
#undef CONFIG_TOOLCHAIN_ARM_GCC
#define CONFIG_LINK_ROM_LIB 1
#undef CONFIG_LINK_ROM_SYMB

501
include/platform_opts.h Normal file
View File

@@ -0,0 +1,501 @@
/**
******************************************************************************
*This file contains general configurations for ameba platform
******************************************************************************
*/
#ifndef __PLATFORM_OPTS_H__
#define __PLATFORM_OPTS_H__
#include "platform_autoconf.h"
/*For MP mode setting*/
//#define SUPPORT_MP_MODE 1
/**
* For AT cmd Log service configurations
*/
#define SUPPORT_LOG_SERVICE 1
#if SUPPORT_LOG_SERVICE
#define LOG_SERVICE_BUFLEN 100 //can't larger than UART_LOG_CMD_BUFLEN(127)
#define CONFIG_LOG_HISTORY 0
#if CONFIG_LOG_HISTORY
#define LOG_HISTORY_LEN 5
#endif
#define SUPPORT_INTERACTIVE_MODE 0//on/off wifi_interactive_mode
#define CONFIG_LOG_SERVICE_LOCK 0
#endif
/* For DCT example*/
#define CONFIG_EXAMPLE_DCT 0
/**
* For interactive mode configurations, depents on log service
*/
#if SUPPORT_INTERACTIVE_MODE
#define CONFIG_INTERACTIVE_MODE 1
#define CONFIG_INTERACTIVE_EXT 0
#else
#define CONFIG_INTERACTIVE_MODE 0
#define CONFIG_INTERACTIVE_EXT 0
#endif
/**
* For FreeRTOS tickless configurations
*/
#define FREERTOS_PMU_TICKLESS_SUSPEND_SDRAM 1 // In sleep mode, 1: suspend SDRAM, 0: no act
/******************************************************************************/
/**
* For common flash usage
*/
#define AP_SETTING_SECTOR 0x000FE000
#define UART_SETTING_SECTOR 0x000FC000
#define SPI_SETTING_SECTOR 0x000FC000
#define FAST_RECONNECT_DATA (0x80000 - 0x1000)
#define FLASH_SECTOR_SIZE 0x1000
#define CONFIG_ENABLE_RDP 0
/**
* For Wlan configurations
*/
#define CONFIG_WLAN 1
#if CONFIG_WLAN
#define CONFIG_LWIP_LAYER 1
#define CONFIG_INIT_NET 1 //init lwip layer when start up
#define CONFIG_WIFI_IND_USE_THREAD 0 // wifi indicate worker thread
//on/off relative commands in log service
#define CONFIG_SSL_CLIENT 0
#define CONFIG_WEBSERVER 0
#define CONFIG_OTA_UPDATE 1
#define CONFIG_BSD_TCP 1//NOTE : Enable CONFIG_BSD_TCP will increase about 11KB code size
#define CONFIG_AIRKISS 0//on or off tencent airkiss
#define CONFIG_UART_SOCKET 0
#define CONFIG_JOYLINK 0//on or off for jdsmart or joylink
#define CONFIG_QQ_LINK 0//on or off for qqlink
#define CONFIG_UART_XMODEM 0//support uart xmodem upgrade or not
#define CONFIG_GOOGLE_NEST 0//on or off the at command control for google nest
#define CONFIG_TRANSPORT 0//on or off the at command for transport socket
#define CONFIG_ALINK 0//on or off for alibaba alink
#define CONFIG_HILINK 0//on or off for huawei hilink
#define CONFIG_GREE 0//on or off for gree
#define CONFIG_RIC 0//on or off for RICloud
/* For WPS and P2P */
#define CONFIG_ENABLE_WPS 0
#define CONFIG_ENABLE_P2P 0//on/off p2p cmd in log_service or interactive mode
#if CONFIG_ENABLE_WPS
#define CONFIG_ENABLE_WPS_DISCOVERY 1
#endif
#if CONFIG_ENABLE_P2P
#define CONFIG_ENABLE_WPS_AP 1
#undef CONFIG_WIFI_IND_USE_THREAD
#define CONFIG_WIFI_IND_USE_THREAD 1
#endif
#if (CONFIG_ENABLE_P2P && ((CONFIG_ENABLE_WPS_AP == 0) || (CONFIG_ENABLE_WPS == 0)))
#error "If CONFIG_ENABLE_P2P, need to define CONFIG_ENABLE_WPS_AP 1"
#endif
/* For SSL/TLS */
#define CONFIG_USE_POLARSSL 1
#define CONFIG_USE_MBEDTLS 0
#if ((CONFIG_USE_POLARSSL == 0) && (CONFIG_USE_MBEDTLS == 0)) || ((CONFIG_USE_POLARSSL == 1) && (CONFIG_USE_MBEDTLS == 1))
#undef CONFIG_USE_POLARSSL
#define CONFIG_USE_POLARSSL 1
#undef CONFIG_USE_MBEDTLS
#define CONFIG_USE_MBEDTLS 0
#endif
/* for syncpkt */
#define CONFIG_SYNCPKT
/* For Simple Link */
#define CONFIG_INCLUDE_SIMPLE_CONFIG 1
/* For DPP */
#define CONFIG_INCLUDE_DPP_CONFIG 0
/*For fast reconnection*/
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0
#if CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#define CONFIG_FAST_DHCP 1
#else
#define CONFIG_FAST_DHCP 0
#endif
/*For wowlan service settings*/
#define CONFIG_WOWLAN_SERVICE 0
#define CONFIG_GAGENT 0
/*Disable CONFIG_EXAMPLE_WLAN_FAST_CONNECT when CONFIG_GAGENT is enabled,because
reconnect to previous AP is not suitable when re-configuration.
*/
#if CONFIG_GAGENT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0
#endif
#define CONFIG_JOINLINK 0
/*For promisc rx unsupported pkt info */
#define CONFIG_UNSUPPORT_PLCPHDR_RPT 1
#endif //end of #if CONFIG_WLAN
/*******************************************************************************/
/**
* For Ethernet configurations
*/
#define CONFIG_ETHERNET 0
#if CONFIG_ETHERNET
#define CONFIG_LWIP_LAYER 1
#define CONFIG_INIT_NET 1 //init lwip layer when start up
//on/off relative commands in log service
#define CONFIG_SSL_CLIENT 0
#define CONFIG_BSD_TCP 0//NOTE : Enable CONFIG_BSD_TCP will increase about 11KB code size
#endif
/**
* For user to adjust SLEEP_INTERVAL
*/
#define CONFIG_DYNAMIC_TICKLESS 1
#if CONFIG_DYNAMIC_TICKLESS
#define DYNAMIC_TICKLESS_SLEEP_INTERVAL 10000 //10*1000ms
#else
#define DYNAMIC_TICKLESS_SLEEP_INTERVAL 0
#endif
/*******************************************************************************/
/**
* For iNIC configurations
*/
//#define CONFIG_INIC_EN 0//enable iNIC mode
#if CONFIG_INIC_EN
#ifndef CONFIG_LWIP_LAYER
#define CONFIG_LWIP_LAYER 0
#endif
#ifndef CONFIG_INIC_SDIO_HCI
#define CONFIG_INIC_SDIO_HCI 0 //for SDIO or USB iNIC
#endif
#ifndef CONFIG_INIC_CMD_RSP
#define CONFIG_INIC_CMD_RSP 0
#endif
#ifndef CONFIG_INIC_USB_HCI
#define CONFIG_INIC_USB_HCI 0
#endif
#endif
/******************End of iNIC configurations*******************/
/* for CoAP example*/
#define CONFIG_EXAMPLE_COAP 0
/* For aj_basic_example */
#define CONFIG_EXAMPLE_AJ_BASIC 0
/*For aj_ameba_led example*/
#define CONFIG_EXAMPLE_AJ_AMEBA_LED 0
/* For WIFI GET BEACON FRAME example */
#define CONFIG_EXAMPLE_GET_BEACON_FRAME 0
/* For WIFI MAC MONITOR example */
#define CONFIG_EXAMPLE_WIFI_MAC_MONITOR 0
/* For HTTP CLIENT example */
#define CONFIG_EXAMPLE_HTTP_CLIENT 0
/* For MQTT example */
#define CONFIG_EXAMPLE_MQTT 0
/* For WiGadget example */
#define CONFIG_EXAMPLE_WIGADGET 0
/*For google nest example*/
#define CONFIG_EXAMPLE_GOOGLE_NEST 0
/* For mDNS example */
#define CONFIG_EXAMPLE_MDNS 0
/* For multicast example */
#define CONFIG_EXAMPLE_MCAST 0
/* For XML example */
#define CONFIG_EXAMPLE_XML 0
/* For socket select example */
#define CONFIG_EXAMPLE_SOCKET_SELECT 0
/* For socket nonblocking connect example */
#define CONFIG_EXAMPLE_NONBLOCK_CONNECT 0
/* For socket TCP bidirectional transmission example */
#define CONFIG_EXAMPLE_SOCKET_TCP_TRX 0
/* For ssl download example */
#define CONFIG_EXAMPLE_SSL_DOWNLOAD 0
/* For http download example */
#define CONFIG_EXAMPLE_HTTP_DOWNLOAD 0
/* For httpc example */
#define CONFIG_EXAMPLE_HTTPC 0
/* For httpd example */
#define CONFIG_EXAMPLE_HTTPD 0
/* For http2 example */
#define CONFIG_EXAMPLE_HTTP2_CLIENT 0
/* For tcp keepalive example */
#define CONFIG_EXAMPLE_TCP_KEEPALIVE 0
/* For sntp show time example */
#define CONFIG_EXAMPLE_SNTP_SHOWTIME 0
/* For pppoe example */
#define CONFIG_EXAMPLE_PPPOE 0
/* For websocket client example */
#define CONFIG_EXAMPLE_WEBSOCKET_CLIENT 0
/* For websocket server example */
#define CONFIG_EXAMPLE_WEBSOCKET_SERVER 0
/*For promisc softap mode example */
#define CONFIG_EXAMPLE_PROMISC_SOFTAP_CONFIG 0
/*For Audio example */
#define CONFIG_EXAMPLE_AUDIO 0
#if CONFIG_EXAMPLE_AUDIO
#define FATFS_DISK_SD 1
#define CONFIG_EXAMPLE_CODEC_SGTL5000 0
#define CONFIG_EXAMPLE_CODEC_ALC5651 1
#endif
/* For UART Module AT command example */
#define CONFIG_EXAMPLE_UART_ATCMD 0
#if CONFIG_EXAMPLE_UART_ATCMD
#undef CONFIG_OTA_UPDATE
#define CONFIG_OTA_UPDATE 1
#undef CONFIG_TRANSPORT
#define CONFIG_TRANSPORT 1
#undef LOG_SERVICE_BUFLEN
#define LOG_SERVICE_BUFLEN 1600
#undef CONFIG_LOG_SERVICE_LOCK
#define CONFIG_LOG_SERVICE_LOCK 1
#undef CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0
#endif
/* For SPI Module AT command example */
#define CONFIG_EXAMPLE_SPI_ATCMD 0
#if CONFIG_EXAMPLE_SPI_ATCMD
#undef CONFIG_OTA_UPDATE
#define CONFIG_OTA_UPDATE 1
#undef CONFIG_TRANSPORT
#define CONFIG_TRANSPORT 1
#undef LOG_SERVICE_BUFLEN
#define LOG_SERVICE_BUFLEN 1600
#undef CONFIG_LOG_SERVICE_LOCK
#define CONFIG_LOG_SERVICE_LOCK 1
#undef CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0
#endif
/* For uvc example */
#ifdef CONFIG_UVC
/*for uvc_FATFS feature*/
#define CONFIG_UVC_SD_EN 0
#if CONFIG_UVC_SD_EN
#define CONFIG_FATFS_EN 1
#if CONFIG_FATFS_EN
// fatfs version
#define FATFS_R_10C
// fatfs disk interface
#define FATFS_DISK_USB 0
#define FATFS_DISK_SD 1
#endif
#endif
#endif
#define CONFIG_EXAMPLE_MEDIA_SS 0
#define CONFIG_EXAMPLE_MEDIA_MS 0
#define CONFIG_EXAMPLE_MEDIA_GEO_RTP 0
// Use media source/sink example
#if (CONFIG_EXAMPLE_MEDIA_SS==1) || (CONFIG_EXAMPLE_MEDIA_MS==1)
#undef CONFIG_INCLUDE_SIMPLE_CONFIG
#define CONFIG_INCLUDE_SIMPLE_CONFIG 0
#define CONFIG_ENABLE_WPS 0
#endif
/* For Mjpeg capture example*/
#define CONFIG_EXAMPLE_MJPEG_CAPTURE 0
#if CONFIG_EXAMPLE_MJPEG_CAPTURE
#define FATFS_DISK_SD 1
#endif
/****************** For EAP method example *******************/
#define CONFIG_EXAMPLE_EAP 0
// on/off specified eap method
#define CONFIG_ENABLE_PEAP 0
#define CONFIG_ENABLE_TLS 0
#define CONFIG_ENABLE_TTLS 0
// optional feature: whether to verify the cert of radius server
#define ENABLE_EAP_SSL_VERIFY_SERVER 0
#if CONFIG_ENABLE_PEAP || CONFIG_ENABLE_TLS || CONFIG_ENABLE_TTLS
#define CONFIG_ENABLE_EAP
#undef CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0
#undef CONFIG_FAST_DHCP
#define CONFIG_FAST_DHCP 0
#endif
#if CONFIG_ENABLE_TLS
#define ENABLE_EAP_SSL_VERIFY_CLIENT 1
#else
#define ENABLE_EAP_SSL_VERIFY_CLIENT 0
#endif
/******************End of EAP configurations*******************/
/* For usb mass storage example */
#define CONFIG_EXAMPLE_USB_MASS_STORAGE 0
/* For FATFS example*/
#define CONFIG_EXAMPLE_FATFS 0
#if CONFIG_EXAMPLE_FATFS
#define CONFIG_FATFS_EN 1
#if CONFIG_FATFS_EN
// fatfs version
#define FATFS_R_10C
// fatfs disk interface
#define FATFS_DISK_USB 0
#define FATFS_DISK_SD 1
#endif
#endif
/* For iNIC host example*/
#ifdef CONFIG_INIC_GSPI_HOST //this flag is defined in IAR project
#define CONFIG_EXAMPLE_INIC_GSPI_HOST 1
#if CONFIG_EXAMPLE_INIC_GSPI_HOST
#define CONFIG_INIC_HOST 1
#undef CONFIG_WLAN
#define CONFIG_WLAN 0
#undef CONFIG_INCLUDE_SIMPLE_CONFIG
#define CONFIG_INCLUDE_SIMPLE_CONFIG 0
#undef CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0
#undef CONFIG_LWIP_LAYER
#define CONFIG_LWIP_LAYER 1
#undef CONFIG_BSD_TCP
#define CONFIG_BSD_TCP 1
#endif
#endif
/*For uart update example*/
#define CONFIG_UART_UPDATE 0
#if CONFIG_UART_UPDATE
#undef CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 0
#endif
/*For arduino wifi shield example */
#define CONFIG_EXAMPLE_ARDUINO_WIFI 0
#if CONFIG_EXAMPLE_ARDUINO_WIFI
#undef CONFIG_WIFI_NORMAL
#endif
/* For uart adapter example */
/* Please also configure LWIP_UART_ADAPTER to 1
in lwip_opt.h for support uart adapter*/
#define CONFIG_EXAMPLE_UART_ADAPTER 0
#if CONFIG_EXAMPLE_UART_ADAPTER
#undef CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 1
#undef CONFIG_EXAMPLE_MDNS
#define CONFIG_EXAMPLE_MDNS 1
#endif
#if CONFIG_EXAMPLE_PROMISC_SOFTAP_CONFIG
#undef CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 1
#endif
/* For wifi scenarios example (Wi-Fi, WPS enrollee, P2P GO) */
// also need to enable WPS and P2P
#define CONFIG_EXAMPLE_WLAN_SCENARIO 0
/* For broadcast example */
#define CONFIG_EXAMPLE_BCAST 0
/* For high-load memory use case memory usage */
#define CONFIG_EXAMPLE_HIGH_LOAD_MEMORY_USE 0
/* For rarp example */
#define CONFIG_EXAMPLE_RARP 0
/* For ssl server example */
#define CONFIG_EXAMPLE_SSL_SERVER 0
/* For Amazon AWS IoT example */
#define CONFIG_EXAMPLE_AMAZON_AWS_IOT 0
/* For Amazon FreeRTOS SDK example */
#define CONFIG_EXAMPLE_AMAZON_FREERTOS 0
/* For Amazon FreeRTOS SDK AFQP Tests Example */
#define CONFIG_EXAMPLE_AMAZON_AFQP_TESTS 0
/*For wifi roaming example*/
#define CONFIG_EXAMPLE_WIFI_ROAMING 0
#define CONFIG_EXAMPLE_TICKLESS_WIFI_ROAMING 0
/*For cm backtrace example*/
#define CONFIG_EXAMPLE_CM_BACKTRACE 0
/*For china mobile andlink example*/
#define CONFIG_EXAMPLE_ANDLINK 0
#if CONFIG_EXAMPLE_ANDLINK
#undef CONFIG_EXAMPLE_WLAN_FAST_CONNECT
#define CONFIG_EXAMPLE_WLAN_FAST_CONNECT 1
#endif
/* For SOC BT8752 Uart communication*/
#define CONFIG_EXAMPLE_BT8752 0
#if CONFIG_QQ_LINK
#define FATFS_R_10C
#define FATFS_DISK_USB 0
#define FATFS_DISK_SD 1
#endif
#if CONFIG_ENABLE_WPS
#define WPS_CONNECT_RETRY_COUNT 4
#define WPS_CONNECT_RETRY_INTERVAL 5000 // in ms
#endif
#define AUTO_RECONNECT_COUNT 8
#define AUTO_RECONNECT_INTERVAL 5 // in sec
#if CONFIG_INIC_EN
#undef CONFIG_INCLUDE_SIMPLE_CONFIG
#define CONFIG_INCLUDE_SIMPLE_CONFIG 0
#define SUPPORT_INTERACTIVE_MODE 0
#define CONFIG_INTERACTIVE_MODE 0
#define CONFIG_INTERACTIVE_EXT 0
#define CONFIG_OTA_UPDATE 0
#endif
#endif

View File

@@ -0,0 +1,330 @@
#include <stdio.h>
#include "log_service.h"
#include "cmsis_os.h"
#include <platform/platform_stdlib.h>
#if CONFIG_JOYLINK
#if 1
void fATCJ(void *arg)
{
extern void joylink_erase(void);
printf("\r\n[ATCJ] Erase wifi and joylink info.");
if(arg){
printf("\r\n[ATCJ]Usage : ATCJ");
return;
}
joylink_erase();
}
// set joylink wifi config mode
void fATJM(void *arg)
{
extern int jl_wifi_config_mode;
printf("\nset joylink wifi config mode: softap\n");
if(arg){
printf("[ATCJ]Usage : ATJM\n");
return;
}
jl_wifi_config_mode = 1;
}
#else
void fATCJ(void *arg)
{
extern void cmd_jd_smart(int argc, char **argv);
int argc;
char *argv[MAX_ARGC] = {0};
printf("[ATCJ]:simple config command for jdsmart\n\r");
if(!arg){
printf("[ATCJ]Usage: ATCJ=simple_config\n\r");
return;
}
argv[0] = "simple_config";
if((argc = parse_param(arg, argv)) > 1){
cmd_jd_smart(argc, argv);
}
else
printf("[ATCJ]Usage: ATCJ=simple_config\n\r");
}
#endif
#endif
#if CONFIG_GAGENT
void fATCG(void *arg)
{
example_gagent();
}
void fATCE(void *arg)
{//Erase gagent config flash
extern int GAgent_DevEraseConfigData();
GAgent_DevEraseConfigData();
}
#endif
#if CONFIG_QQ_LINK
void fATCQ(void *arg)
{
int argc;
unsigned char *argv[MAX_ARGC] = {0};
extern void device_write_sn_license(int argc, unsigned char **argv);
extern void device_erase_all(int argc, unsigned char **argv);
if(!arg)
{
printf("\r\n[ATCQ] Write sn/license into flash or Erase all info\r\n");
printf("\r\n[ATCQ] Usage: ATCQ=erase");
printf("\r\n[ATCQ] Usage: ATCQ=sn,xxxxxxxx\r\n ATCQ=licensepart1,xxxxxxxx\r\n ATCQ=licensepart2,xxxxxxxx");
return;
}
argv[0] = "sn&&license&&erase";
argc = parse_param(arg, argv);
if(argc == 3) // Write sn&&license
{
device_write_sn_license(argc, argv);
}
else if(argc == 2) // Erase all info : ATCQ=erase
{
device_erase_all(argc, argv);
}
else
{
printf("\r\n[ATCQ] Usage: ATCQ=erase");
printf("\r\n[ATCQ]Usage: ATCQ=sn,xxxxxxxx\r\n ATCQ=licensepart1,xxxxxxxx\r\n ATCQ=licensepart2,xxxxxxxx");
}
}
#endif
#if CONFIG_AIRKISS_CLOUD
void fATCW(void *arg)
{
int argc;
unsigned char *argv[MAX_ARGC] = {0};
extern void airkiss_cloud_write_device_info(int argc, unsigned char **argv);
extern void airkiss_cloud_erase_ap_profile(int argc, unsigned char **argv);
if(!arg) goto USAGE;
argv[0] = "type/id/licese/erase";
argc = parse_param(arg, argv);
if(argc == 3) // Write typw/id/license
{
airkiss_cloud_write_device_info(argc, argv);
return;
}
else if(argc == 2) // Erase wifi profile : ATCW=erase
{
airkiss_cloud_erase_ap_profile(argc, argv);
return;
}
else
goto USAGE;
USAGE:
printf("\r\n[ATCW] Write ORDERLY device's type/id/license into flash or Erase wifi profile");
printf("\r\n[ATCW] Usage: ATCW=type,xxxxxxxx");
printf("\r\n[ATCW] Usage: ATCW=id,xxxxxxxx");
printf("\r\n[ATCW] Usage: ATCW=licensepart1,xxxxxxxx\t(80-Byte long)");
printf("\r\n[ATCW] Usage: ATCW=licensepart2,xxxxxxxx\t(80-Byte long)");
printf("\r\n[ATCW] Usage: ATCW=erase");
return;
}
#endif
#if CONFIG_ALINK
extern int alink_erase_wifi_config();
extern void alink_reset_to_factory(void *arg);
extern int alink_write_device_info(int argc, unsigned char **argv);
extern void alink_set_log_level(int argc, unsigned char **argv);
void fATCA(void *arg)
{
int argc;
int ret = -1;
unsigned char *argv[MAX_ARGC] = {0};
if(!arg) {
goto USAGE;
}
argv[0] = "k/s/l/e/r";
argc = parse_param(arg, argv);
if (argc == 3) {
/*Set log level: ATCA=l, trace/debug/info/warn/fatal/none
if set wrong, set info level by default*/
if (!strcmp(argv[1], "l")) {
alink_set_log_level(argc, argv);
return;
} else {
/* Write device key/device secret */
ret = alink_write_device_info(argc, argv);
if (ret) {
goto USAGE;
}
return;
}
} else if (argc == 2) {
/* Erase wifi profile or reset user account binding : "ATCA=e" or "ATCA=r" */
if (!strcmp(argv[1], "e")) {
alink_erase_wifi_config();
}else if(!strcmp(argv[1], "r")) {
alink_reset_to_factory(NULL);
}
}
USAGE:
printf("\r\n[ATCA] Write ORDERLY device's key/secret into flash, set log level or erase wifi profile");
printf("\r\n[ATCA] Usage: ATCA=k,xxxxxxxx\t(set device key, 20-Byte long)");
printf("\r\n[ATCA] Usage: ATCA=s,xxxxxxxx\t(set device secret, 32-Byte long)");
printf("\r\n[ATCA] Usage: ATCA=l,xxxx\t(set log level, trace/debug/info/warn/error/fatal/none)");
printf("\r\n[ATCA] Usage: ATCA=e\t(erase AP profile)");
printf("\r\n[ATCA] Usage: ATCA=r\t(reset user account binding)");
return;
}
void fATCZ(void *arg)
{
//Erase alink config flash
alink_erase_wifi_config();
}
void fATCT(void *arg)
{
alink_reset_to_factory(NULL);
}
#endif
#if (defined(CONFIG_RIC) && CONFIG_RIC)
#include "ric/ric_device.h"
#include "ric/ric_dev_ota_rtl8710b.h"
void fATCR(void *arg)
{
#if 0
int argc;
unsigned char len1, len2;
unsigned char *argv[MAX_ARGC] = {0};
argv[0] = "ricloud";
argc = parse_param(arg, argv);
if(argc == 2 && !strcmp("ota", argv[1])) {
ric_ota_v v = {0};
v.loop = 0;
ric_dev_msg_dump(MSG_OTA_REQ, (void *)&v);
}else if(argc == 3 && !strcmp("ota", argv[1]) && (!strcmp("0", argv[2]) || !strcmp("1", argv[2]))) {
ric_ota_v v = {0};
v.loop = *argv[2] - '0';
ric_dev_msg_dump(MSG_OTA_REQ, (void *)&v);
}else if(argc == 3 && !strcmp("ota", argv[1]) && !strcmp("s", argv[2])) {
ric_dev_msg_dump(MSG_OTA_STP, NULL);
}else if(argc == 4 && !strcmp("ota", argv[1]) && (!strcmp("0", argv[2]) || !strcmp("1", argv[2]))) {
ric_ota_v v = {0};
v.loop = *argv[2] - '0';
if(strlen(argv[3]) > sizeof(v.nv_num) -1) {
printf("\r\n[ATCR] error: the new version num should no longer than %d !", sizeof(v.nv_num) - 1);
}else {
strcpy(v.nv_num, argv[3]);
ric_dev_msg_dump(MSG_OTA_REQ, (void *)&v);
}
}else {
goto USAGE;
}
return;
USAGE:
printf("\r\n[ATCR] Control ameba operation to RICloud");
printf("\r\n[ATCR] Usage: ATCR=ota[,loop] ==>ota with default expected fw version num for one time [or one(loop:0) / infinite(loop:1) time(s)]");
printf("\r\n[ATCR] Usage: ATCR=ota,loop,version ==>ota with specified fw version num(version) for one(loop:0) or infinite(loop:1) time(s)");
printf("\r\n[ATCR] Usage: ATCR=ota,s ==>stop the infinite ota if it's started before");
return;
#endif
}
extern int ric_set_userid(char *);
extern int ric_set_server_ip(char *);
extern void ric_flash_erase_sector(uint32_t address);
void fATUS(void *arg)
{
int argc;
char *argv[MAX_ARGC] = {0};
argv[0] = "ricloud";
argc = parse_param(arg,argv);
if(argc == 3){
if(!strcmp("userid",argv[1]))
{
ric_set_userid(argv[2]);
}else if(!strcmp("svrip",argv[1])){
ric_set_server_ip(argv[2]);
}
}else if(argc == 2){
if(!strcmp("erase",argv[1])){
ric_flash_erase_sector(CONFIG_USER_INFO);
}
}else{
goto USAGE;
}
return;
USAGE:
printf("\r\n[ATUS] Setup User and Server info RICloud");
printf("\r\n[ATUS] Usage: ATUS=userid,xxxx ==>set registed user id");
printf("\r\n[ATUS] Usage: ATUS=svrip,xxx.xxx.xxx.xxx ==>set ricloud server ip address");
printf("\r\n[ATUS] Usage: ATUS=erase ==>erase user id and server ip address");
return;
}
#endif
void fATCx(void *arg)
{
}
#if CONFIG_GREE
extern void gree_erase_wifi_config();
void fATCR(void *arg)
{
gree_erase_wifi_config();
}
#endif
log_item_t at_cloud_items[ ] = {
#if CONFIG_JOYLINK
{"ATCJ", fATCJ,},
{"ATJM", fATJM,},
#endif
#if CONFIG_GAGENT
{"ATCG", fATCG,},
{"ATCE", fATCE,},
#endif
#if CONFIG_QQ_LINK
{"ATCQ", fATCQ,},
#endif
#if CONFIG_AIRKISS_CLOUD
{"ATCW", fATCW},
#endif
#if CONFIG_ALINK
{"ATCA", fATCA,},
{"ATCZ", fATCZ,},
{"ATCT", fATCT,},
#endif
#if CONFIG_GREE
{"ATCR", fATCR,},
#endif
#if (defined(CONFIG_RIC) && CONFIG_RIC)
{"ATCR", fATCR,},
{"ATUS", fATUS,},
#endif
{"ATC?", fATCx,},
};
void at_cloud_init(void)
{
log_service_add_table(at_cloud_items, sizeof(at_cloud_items)/sizeof(at_cloud_items[0]));
}
#if SUPPORT_LOG_SERVICE
log_module_init(at_cloud_init);
#endif

View File

@@ -0,0 +1,91 @@
#include <stdio.h>
#include "log_service.h"
#include "platform_opts.h"
#include <lwip_netconf.h>
#include "cmsis_os.h"
#include <platform/platform_stdlib.h>
#include <lwip/sockets.h>
#include <lwip/tcpip.h>
#define _AT_DHCP_ETHERNET_MII_ "ATE0"
#define _AT_SET_DEFAULT_INTERFACE "ATE1"
#if CONFIG_ETHERNET
extern int dhcp_ethernet_mii;
extern int ethernet_if_default;
extern struct netif xnetif[NET_IF_NUM];
void fATE0(void *arg)
{
int argc;
char *argv[MAX_ARGC] = {0};
printf("[ATE0]:DHCP configure for ethernet\n\r");
if(!arg){
printf("[ATE0]Usage to disable DHCP: ATE0=0\n");
printf("[ATE0]Usage to enable DHCP: ATE0=1\n");
return;
}
if('0' == *(char *)arg)
{
dhcp_ethernet_mii = 0;
}
else if('1' == *(char *)arg)
{
dhcp_ethernet_mii = 1;
LwIP_DHCP(NET_IF_NUM - 1, DHCP_START);
}
else
{
printf("[ATE0]Usage to disable DHCP: ATE0=0\n");
printf("[ATE0]Usage to enable DHCP: ATE0=1\n");
}
}
void fATE1(void *arg)
{
int argc;
char *argv[MAX_ARGC] = {0};
printf("[ATE1]:Set/check the default interface\n\r");
if(!arg){
if(ethernet_if_default)
printf("Ethernet is the default interface\n");
else
printf("wlan is the default interface\n");
return;
}
if('0' == *(char *)arg)
{
ethernet_if_default = 0;
printf("wlan is set to the default interface\n");
}
else if('1' == *(char *)arg)
{
ethernet_if_default = 1;
printf("ethernet is set to the default interface\n");
}
else
{
printf("[ATE0]Usage to check the default interface: ATE1\n");
printf("[ATE0]Usage to set ethernet as default interface: ATE1=1\n");
printf("[ATE0]Usage to set wlan as default interface: ATE1=0\n");
}
}
log_item_t at_ethernet_items[ ] = {
{"ATE0", fATE0,},
{"ATE1", fATE1,}
};
void at_ethernet_init(void)
{
log_service_add_table(at_ethernet_items, sizeof(at_ethernet_items)/sizeof(at_ethernet_items[0]));
}
log_module_init(at_ethernet_init);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,105 @@
#ifndef __ATCMD_LWIP_H__
#define __ATCMD_LWIP_H__
#include "main.h"
#include "osdep_service.h"
#include <lwip/opt.h>
#include "lwip/sockets.h"
#include "lwip/api.h"
#include "lwip/sys.h"
#include "lwip/igmp.h"
#include "lwip/inet.h"
#include "lwip/tcp.h"
#include "lwip/raw.h"
#include "lwip/udp.h"
#include "lwip/tcpip.h"
#include "lwip/pbuf.h"
#include "lwip/netdb.h"
#include "lwip_netconf.h"
#define _AT_TRANSPORT_MODE_ "ATP1"
#define _AT_TRANSPORT_LOCAL_PORT_ "ATP2"
#define _AT_TRANSPORT_REMOTE_IP_ "ATP3"
#define _AT_TRANSPORT_REMOTE_PORT_ "ATP4"
#define _AT_TRANSPORT_START_SERVER_ "ATP5"
#define _AT_TRANSPORT_START_CLIENT_ "ATP6"
#define _AT_TRANSPORT_SHOW_SETTING_ "ATP?"
#define _AT_TRANSPORT_RECEIVE_DATA_ "ATR0"
#define _AT_TRANSPORT_RECEIVE_PACKET_SIZE_ "ATR1"
#define _AT_TRANSPORT_WRITE_DATA_ "ATRA"
#define _AT_TRANSPORT_WRITE_PACKET_SIZE_ "ATRB"
#define NODE_MODE_TCP 0
#define NODE_MODE_UDP 1
#define NODE_MODE_SSL 2
#define NODE_ROLE_SERVER 0
#define NODE_ROLE_CLIENT 1
#define NODE_ROLE_SEED 2
#define INVALID_SOCKET_ID (-1)
//parameters
#ifndef NET_IF_NUM
#define NET_IF_NUM 2
#endif
#define ATCMD_LWIP_TASK_PRIORITY (tskIDLE_PRIORITY + 1)
#if ATCMD_VER == ATVER_2
#ifndef ATCMD_SUPPORT_SSL
#define ATCMD_SUPPORT_SSL 0
#endif
#define SERVER "127.0.0.1"
#define NUM_NS (MEMP_NUM_NETCONN) //maximum number of node and seed, same as NUM_SOCKETS
#define ETH_MAX_MTU 1500
#define INVALID_CON_ID (-1)
#define RECV_SELECT_TIMEOUT_SEC (0)
#define RECV_SELECT_TIMEOUT_USEC (20000) //20ms
typedef struct ns
{
int con_id;
int sockfd;
s8_t role;
int protocol;
u32_t addr;
u16_t port;
u32_t local_addr;
u16_t local_port;
xTaskHandle handletask;
struct ns* next;
struct ns* nextseed;
#if (ATCMD_VER == ATVER_2) && ATCMD_SUPPORT_SSL
void *context;
#endif
} node;
extern xTaskHandle atcmd_lwip_tt_task;
extern _sema atcmd_lwip_tt_sema;
extern volatile int atcmd_lwip_tt_datasize;
extern volatile int atcmd_lwip_tt_lasttickcnt;
#define ATCMD_LWIP_TT_MAX_DELAY_TIME_MS (20) //transparent transmission interval
extern int atcmd_lwip_is_tt_mode(void);
extern void atcmd_lwip_set_tt_mode(int enable);
int atcmd_lwip_send_data(node *curnode, u8 *data, u16 data_sz, struct sockaddr_in cli_addr);
int atcmd_lwip_receive_data(node *curnode, u8 *buffer, u16 buffer_size, int *recv_size,
u8_t *udp_clientaddr, u16_t *udp_clientport);
node* create_node(int mode, s8_t role);
void init_node_pool(void);
void delete_node(node *n);
int hang_node(node* insert_node);
int hang_seednode(node* main_node ,node* insert_node);
node *seek_node(int con_id);
node *tryget_node(int n);
#endif
#endif //#ifndef __ATCMD_LWIP_H__

View File

@@ -0,0 +1,260 @@
#include <platform_stdlib.h>
#include <platform_opts.h>
#include <gpio_api.h>
#include <analogout_api.h>
#include <analogin_api.h>
#include "log_service.h"
#include "atcmd_mp.h"
#if CONFIG_ATCMD_MP_EXT0
extern void fATM0(void *arg); // MP ext0 AT command
#endif
#if CONFIG_ATCMD_MP_EXT1
extern void fATM1(void *arg); // MP ext1 AT command
#endif
#if CONFIG_ATCMD_MP
//-------- AT MP commands ---------------------------------------------------------------
void fATMG(void *arg)
{
gpio_t gpio_test;
int argc = 0, val, cnts, i, write=0, data=0;
char *argv[MAX_ARGC] = {0}, port, num;
PinName pin = NC;
u32 tConfigDebugInfo = ConfigDebugInfo;
AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATMG]: _AT_MP_GPIO_TEST_");
if(!arg){
AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATMG] Usage: ATMG=w,PINNAMES(ex:A0B1C2...),VALUE(0/1)");
AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATMG] Usage: ATMG=r,PINNAMES(ex:A0B1C2...)");
return;
}
argc = parse_param(arg, argv);
cnts = strlen(argv[2]);
if(cnts % 2) return;
cnts /= 2;
if(cnts == 0) return;
if(strcmp(argv[1], "w") == 0){
write = 1;
if(strcmp(argv[3], "1") == 0)
data = 1;
}
// Remove debug info massage
_AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "[ATMG] %s: ", argv[1]);
ConfigDebugInfo = 0;
for(i=0; i<(cnts*2); i+=2){
pin = NC;
port = argv[2][i];
num = argv[2][i+1];
if(port >= 'a' && port <= 'z')
port -= ('a' - 'A');
if(num >= 'a' && num <= 'z')
num -= ('a' - 'A');
switch(port){
case 'A':
switch(num){
case '0': pin = PA_0; break; case '1': pin = PA_1; break; case '2': pin = PA_2; break; case '3': pin = PA_3; break;
case '4': pin = PA_4; break; case '5': pin = PA_5; break; case '6': pin = PA_6; break; case '7': pin = PA_7; break;
}
break;
case 'B':
switch(num){
case '0': pin = PB_0; break; case '1': pin = PB_1; break; case '2': pin = PB_2; break; case '3': pin = PB_3; break;
case '4': pin = PB_4; break; case '5': pin = PB_5; break; case '6': pin = PB_6; break; case '7': pin = PB_7; break;
}
break;
case 'C':
switch(num){
case '0': pin = PC_0; break; case '1': pin = PC_1; break; case '2': pin = PC_2; break; case '3': pin = PC_3; break;
case '4': pin = PC_4; break; case '5': pin = PC_5; break; case '6': pin = PC_6; break; case '7': pin = PC_7; break;
case '8': pin = PC_8; break; case '9': pin = PC_9; break;
}
break;
case 'D':
switch(num){
case '0': pin = PD_0; break; case '1': pin = PD_1; break; case '2': pin = PD_2; break; case '3': pin = PD_3; break;
case '4': pin = PD_4; break; case '5': pin = PD_5; break; case '6': pin = PD_6; break; case '7': pin = PD_7; break;
case '8': pin = PD_8; break; case '9': pin = PD_9; break;
}
break;
case 'E':
switch(num){
case '0': pin = PE_0; break; case '1': pin = PE_1; break; case '2': pin = PE_2; break; case '3': pin = PE_3; break;
case '4': pin = PE_4; break; case '5': pin = PE_5; break; case '6': pin = PE_6; break; case '7': pin = PE_7; break;
case '8': pin = PE_8; break; case '9': pin = PE_9; break; case 'A': pin = PE_A; break;
}
break;
case 'F':
switch(num){
case '0': pin = PF_0; break; case '1': pin = PF_1; break; case '2': pin = PF_2; break; case '3': pin = PF_3; break;
case '4': pin = PF_4; break; case '5': pin = PF_5; break;
}
break;
case 'G':
switch(num){
case '0': pin = PG_0; break; case '1': pin = PG_1; break; case '2': pin = PG_2; break; case '3': pin = PG_3; break;
case '4': pin = PG_4; break; case '5': pin = PG_5; break; case '6': pin = PG_6; break; case '7': pin = PG_7; break;
}
break;
case 'H':
switch(num){
case '0': pin = PH_0; break; case '1': pin = PH_1; break; case '2': pin = PH_2; break; case '3': pin = PH_3; break;
case '4': pin = PH_4; break; case '5': pin = PH_5; break; case '6': pin = PH_6; break; case '7': pin = PH_7; break;
}
break;
case 'I':
switch(num){
case '0': pin = PI_0; break; case '1': pin = PI_1; break; case '2': pin = PI_2; break; case '3': pin = PI_3; break;
case '4': pin = PI_4; break; case '5': pin = PI_5; break; case '6': pin = PI_6; break; case '7': pin = PI_7; break;
}
break;
case 'J':
switch(num){
case '0': pin = PJ_0; break; case '1': pin = PJ_1; break; case '2': pin = PJ_2; break; case '3': pin = PJ_3; break;
case '4': pin = PJ_4; break; case '5': pin = PJ_5; break; case '6': pin = PJ_6; break;
}
break;
case 'K':
switch(num){
case '0': pin = PK_0; break; case '1': pin = PK_1; break; case '2': pin = PK_2; break; case '3': pin = PK_3; break;
case '4': pin = PK_4; break; case '5': pin = PK_5; break; case '6': pin = PK_6; break;
}
break;
}
if(pin == NC){
_AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "X,");
continue;
}
// Initial input control pin
gpio_init(&gpio_test, pin);
if(write){
gpio_dir(&gpio_test, PIN_OUTPUT); // Direction: Output
gpio_mode(&gpio_test, PullNone); // No pull
gpio_write(&gpio_test, data);
_AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "%d,", data);
}else{
gpio_dir(&gpio_test, PIN_INPUT); // Direction: Input
gpio_mode(&gpio_test, PullUp); // Pull-High
val = gpio_read(&gpio_test);
_AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "%d,", val);
}
}
_AT_DBG_MSG(AT_FLAG_GPIO, AT_DBG_ALWAYS, "\n");
// Recover debug info massage
ConfigDebugInfo = tConfigDebugInfo;
}
void fATMR(void *arg)
{
u32 idx;
AT_PRINTK("[ATMR]: _AT_MP_SDR_TEST_");
#ifdef CONFIG_SDR_EN
for (idx = 0; idx < 0x200000; idx = idx+4){
HAL_WRITE32(0x30000000, idx, 0x12345678);
if (HAL_READ32(0x30000000, idx) != 0x12345678) {
AT_PRINTK("[ATMR]: SDR test fail addr 0x08x, value 0x08%x",(0x30000000+idx),HAL_READ32(0x30000000, idx));
return;
}
}
AT_PRINTK("[ATMR]: SDR test success");
#endif
}
void fATMD(void *arg)
{
int argc = 0;
char *argv[MAX_ARGC] = {0}, *ptmp;;
u16 vdac;
dac_t dac0;
argc = parse_param(arg, argv);
#if CONFIG_BT
analogout_init(&dac0, DA_0);
#endif
HalDelayUs(50*1000); // delay 50 ms for DAC_CAP 10uF
vdac = strtoul(argv[1], &ptmp, 16);
// 0x800(0v) ~ 0x000(1.65v) ~ 0x7ff(3.3v)
#if CONFIG_BT
analogout_write_u16(&dac0, vdac);
#endif
AT_PRINTK("[ATMD]: DAC = 0x%x", vdac);
}
#define AD2MV(ad,offset,gain) ((ad-offset)*1000/gain)
void fATMA(void *arg)
{
int argc = 0, channel;
char *argv[MAX_ARGC] = {0}, *ptmp;
u16 offset, gain, vadc, mv;
analogin_t adc;
argc = parse_param(arg, argv);
channel = atoi(argv[1]);
if(channel >= 1 && channel <= 3){
if(channel == 1)
analogin_init(&adc, AD_1);
else if(channel == 2)
analogin_init(&adc, AD_2);
else
analogin_init(&adc, AD_3);
vadc = (analogin_read_u16(&adc)>>4);
analogin_deinit(&adc);
sys_adc_calibration(0, &offset, &gain);
if((offset != 0xFFFF) && (gain != 0xFFFF)){
if(vadc < offset){
mv = 0;
}else{
mv = AD2MV(vadc, offset, gain);
}
AT_PRINTK("[ATMA]: ADC%d:0x%x = %d mv", channel, vadc, mv);
}else{
AT_PRINTK("[ATMA]: ADC%d:0x%x", channel, vadc);
}
}
}
void fATMt(void *arg)
{
int argc = 0;
char *argv[MAX_ARGC] = {0};
AT_PRINTK("[ATM#]: _AT_MP_TEST_");
argc = parse_param(arg, argv);
}
void fATMx(void *arg)
{
AT_PRINTK("[ATM?]: _AT_MP_HELP_");
}
log_item_t at_mp_items[] = {
{"ATMG", fATMG,}, // MP GPIO test
{"ATMR", fATMR,}, // MP SDR test
{"ATMD", fATMD,}, // MP DAC
{"ATMA", fATMA,}, // MP ADC
{"ATM#", fATMt,}, // test command
{"ATM?", fATMx,}, // Help
#if CONFIG_ATCMD_MP_EXT0
{"ATM0", fATM0,}, // MP ext0 AT command
#endif
#if CONFIG_ATCMD_MP_EXT1
{"ATM1", fATM1,}, // MP ext1 AT command
#endif
};
void at_mp_init(void)
{
log_service_add_table(at_mp_items, sizeof(at_mp_items)/sizeof(at_mp_items[0]));
}
#if SUPPORT_LOG_SERVICE
log_module_init(at_mp_init);
#endif
#endif // #if CONFIG_ATCMD_MP

View File

@@ -0,0 +1,19 @@
#ifndef __ATCMD_MP_H__
#define __ATCMD_MP_H__
#include <platform_opts.h>
#if CONFIG_BT
#define CONFIG_ATCMD_MP_EXT0 1 //support MP ext0 AT command
#else
#define CONFIG_ATCMD_MP_EXT0 0 //support MP ext0 AT command
#endif
#define CONFIG_ATCMD_MP_EXT1 0 //support MP ext1 AT command
typedef struct _at_command_mp_ext_item_{
char *mp_ext_cmd;
int (*mp_ext_fun)(void **argv, int argc);
char *mp_ext_usage;
}at_mp_ext_item_t;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
#ifndef __ATCMD_SYS_H__
#define __ATCMD_SYS_H__
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,161 @@
#ifndef __ATCMD_WIFI_H__
#define __ATCMD_WIFI_H__
#include "main.h"
#include "lwip_netconf.h"
#ifndef WLAN0_NAME
#define WLAN0_NAME "wlan0"
#endif
#ifndef WLAN1_NAME
#define WLAN1_NAME "wlan1"
#endif
/* Give default value if not defined */
#ifndef NET_IF_NUM
#ifdef CONFIG_CONCURRENT_MODE
#define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN) + 1)
#else
#define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN))
#endif // end of CONFIG_CONCURRENT_MODE
#endif // end of NET_IF_NUM
/*Static IP ADDRESS*/
#ifndef IP_ADDR0
#define IP_ADDR0 192
#define IP_ADDR1 168
#define IP_ADDR2 1
#define IP_ADDR3 80
#endif
/*NETMASK*/
#ifndef NETMASK_ADDR0
#define NETMASK_ADDR0 255
#define NETMASK_ADDR1 255
#define NETMASK_ADDR2 255
#define NETMASK_ADDR3 0
#endif
/*Gateway Address*/
#ifndef GW_ADDR0
#define GW_ADDR0 192
#define GW_ADDR1 168
#define GW_ADDR2 1
#define GW_ADDR3 1
#endif
/*Static IP ADDRESS*/
#ifndef AP_IP_ADDR0
#define AP_IP_ADDR0 192
#define AP_IP_ADDR1 168
#define AP_IP_ADDR2 43
#define AP_IP_ADDR3 1
#endif
/*NETMASK*/
#ifndef AP_NETMASK_ADDR0
#define AP_NETMASK_ADDR0 255
#define AP_NETMASK_ADDR1 255
#define AP_NETMASK_ADDR2 255
#define AP_NETMASK_ADDR3 0
#endif
/*Gateway Address*/
#ifndef AP_GW_ADDR0
#define AP_GW_ADDR0 192
#define AP_GW_ADDR1 168
#define AP_GW_ADDR2 43
#define AP_GW_ADDR3 1
#endif
#if CONFIG_EXAMPLE_UART_ATCMD
#include "wifi_structures.h"
#include <wlan_fast_connect/example_wlan_fast_connect.h>
typedef struct _UART_LOG_CONF_{
u32 BaudRate;
u8 DataBits;
u8 StopBits;
u8 Parity;
u8 FlowControl;
}UART_LOG_CONF, *PUART_LOG_CONF;
#define ATCMD_WIFI_CONN_STORE_MAX_NUM (1)
struct atcmd_wifi_conf{
int32_t auto_enable;
rtw_wifi_setting_t setting;
int32_t reconn_num;
int32_t reconn_last_index;
struct wlan_fast_reconnect reconn[ATCMD_WIFI_CONN_STORE_MAX_NUM];
};
#define ATCMD_LWIP_CONN_STORE_MAX_NUM (1)
struct atcmd_lwip_conn_info{
int32_t role; //client, server or seed
uint32_t protocol; //tcp or udp
uint32_t remote_addr; //remote ip
uint32_t remote_port; //remote port
uint32_t local_addr; //locale ip, not used yet
uint32_t local_port; //locale port, not used yet
uint32_t reserved; //reserve for further use
};
struct atcmd_lwip_conf {
int32_t enable; //enable or not
int32_t conn_num;
int32_t last_index;
int32_t reserved; //reserve for further use
struct atcmd_lwip_conn_info conn[ATCMD_LWIP_CONN_STORE_MAX_NUM];
};
typedef enum {
AT_PARTITION_ALL = 0,
AT_PARTITION_UART = 1,
AT_PARTITION_WIFI = 2,
AT_PARTITION_LWIP = 3
} AT_PARTITION;
typedef enum {
AT_PARTITION_READ = 0,
AT_PARTITION_WRITE = 1,
AT_PARTITION_ERASE = 2
} AT_PARTITION_OP;
//first segment for uart
#define UART_SETTING_BACKUP_SECTOR (0x8000)
#define UART_CONF_DATA_OFFSET (0)
#define UART_CONF_DATA_SIZE ((((sizeof(UART_LOG_CONF)-1)>>2) + 1)<<2)
//second segment for wifi config
#define WIFI_CONF_DATA_OFFSET (UART_CONF_DATA_OFFSET+UART_CONF_DATA_SIZE)
#define WIFI_CONF_DATA_SIZE ((((sizeof(struct atcmd_wifi_conf)-1)>>2) + 1)<<2)
//fouth segment for lwip config
#define LWIP_CONF_DATA_OFFSET (WIFI_CONF_DATA_OFFSET+WIFI_CONF_DATA_SIZE)
#define LWIP_CONF_DATA_SIZE ((((sizeof(struct atcmd_lwip_conf)-1)>>2) + 1)<<2)
extern void atcmd_update_partition_info(AT_PARTITION id, AT_PARTITION_OP ops, u8 *data, u16 len);
#define ATSTRING_LEN (LOG_SERVICE_BUFLEN)
extern char at_string[ATSTRING_LEN];
extern unsigned char gAT_Echo; // default echo on
//extern void uart_at_lock(void);
//extern void uart_at_unlock(void);
extern void uart_at_send_string(char *str);
extern void uart_at_send_buf(u8 *buf, u32 len);
#define at_printf(fmt, args...) do{\
/*uart_at_lock();*/\
snprintf(at_string, ATSTRING_LEN, fmt, ##args); \
uart_at_send_string(at_string);\
/*uart_at_unlock();*/\
}while(0)
#define at_print_data(data, size) do{\
/*uart_at_lock();*/\
uart_at_send_buf(data, size);\
/*uart_at_unlock();*/\
}while(0)
#else
#define at_printf(fmt, args...) do{printf(fmt, ##args);}while(0)
#define at_print_data(data, size) do{__rtl_memDump(data, size, NULL);}while(0)
#endif//#if CONFIG_EXAMPLE_UART_ATCMD
#endif

View File

@@ -0,0 +1,497 @@
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include "FreeRTOS.h"
#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1)
#include "freertos_pmu.h"
#endif
#include "log_service.h"
#include "task.h"
#include "semphr.h"
#include "main.h"
//#include "wifi_util.h"
#include "atcmd_wifi.h"
#if CONFIG_EXAMPLE_UART_ATCMD || CONFIG_EXAMPLE_SPI_ATCMD
#include "atcmd_lwip.h"
#endif
#if SUPPORT_LOG_SERVICE
//======================================================
struct list_head log_hash[ATC_INDEX_NUM];
extern void at_wifi_init(void);
extern void at_fs_init(void);
extern void at_sys_init(void);
extern void at_ethernet_init(void);
extern void at_google_init(void);
extern void at_transport_init(void);
//extern void at_app_init(void);
extern void at_mp_init(void);
extern void at_bt_init(void);
#if (CONFIG_JOYLINK || CONFIG_GAGENT || CONFIG_QQ_LINK || \
CONFIG_AIRKISS_CLOUD || CONFIG_ALINK || CONFIG_HILINK || CONFIG_GREE || \
(defined(CONFIG_RIC) && CONFIG_RIC))
extern void at_cloud_init(void);
#endif
void at_log_init(void);
char log_buf[LOG_SERVICE_BUFLEN];
#if CONFIG_LOG_HISTORY
char log_history[LOG_HISTORY_LEN][LOG_SERVICE_BUFLEN];
static unsigned int log_history_count = 0;
#endif
xSemaphoreHandle log_rx_interrupt_sema = NULL;
#if CONFIG_LOG_SERVICE_LOCK
xSemaphoreHandle log_service_sema = NULL;
#endif
extern xSemaphoreHandle uart_rx_interrupt_sema;
#if CONFIG_INIC_EN
extern unsigned char inic_cmd_ioctl;
#endif
//#if defined (__ICCARM__)
//#pragma section=".data.log_init"
//
//unsigned int __log_init_begin__;
//unsigned int __log_init_end__;
//#elif defined ( __CC_ARM ) || defined(__GNUC__)
#if defined (__ICCARM__) || defined ( __CC_ARM ) || defined(__GNUC__)
//#pragma section=".data.log_init"
log_init_t* __log_init_begin__;
log_init_t* __log_init_end__;
log_init_t log_init_table[] = {
at_wifi_init,
// at_fs_init,
at_sys_init,
at_log_init,
// at_app_init,
#if CONFIG_ETHERNET
at_ethernet_init,
#endif
#if CONFIG_GOOGLE_NEST
at_google_init,
#endif
#if CONFIG_TRANSPORT
at_transport_init,
#endif
#if CONFIG_ATCMD_MP
at_mp_init,
#endif
#if CONFIG_BT
at_bt_init,
#endif
#if (CONFIG_JOYLINK || CONFIG_GAGENT || CONFIG_QQ_LINK || \
CONFIG_AIRKISS_CLOUD || CONFIG_ALINK || CONFIG_HILINK || CONFIG_GREE || \
(defined(CONFIG_RIC) && CONFIG_RIC))
at_cloud_init,
#endif
};
#else
#error "not implement, add to linker script"
extern unsigned int __log_init_begin__;
extern unsigned int __log_init_end__;
#endif
#if defined(__GNUC__)
#define USE_STRSEP
#endif
//======================================================
int hash_index(char *str)
{
unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
unsigned int hash = 0;
while (*str)
{
hash = hash * seed + (*str++);
}
return (hash & 0x7FFFFFFF);
}
void log_add_new_command(log_item_t *new)
{
int index = hash_index(new->log_cmd)%ATC_INDEX_NUM;
list_add(&new->node, &log_hash[index]);
}
void start_log_service(void);
void log_service_init(void)
{
int i;
//#if defined (__ICCARM__)
// log_init_t *log_init_table;
// __log_init_begin__ = (unsigned int)__section_begin(".data.log_init");
// __log_init_end__ = (unsigned int)__section_end(".data.log_init");
// log_init_table = (log_init_t *)__log_init_begin__;
//#elif defined(__CC_ARM) || defined(__GNUC__)
#if defined (__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
__log_init_begin__ = log_init_table;
__log_init_end__ = __log_init_begin__ + sizeof(log_init_table);
#else
#error "not implement"
#endif
for(i=0;i<ATC_INDEX_NUM;i++)
INIT_LIST_HEAD(&log_hash[i]);
for(i=0;i<(__log_init_end__-__log_init_begin__)/sizeof(log_init_t); i++)
log_init_table[i]();
/* Initial uart rx swmaphore*/
vSemaphoreCreateBinary(log_rx_interrupt_sema);
xSemaphoreTake(log_rx_interrupt_sema, 1/portTICK_RATE_MS);
#if CONFIG_LOG_SERVICE_LOCK
log_service_lock_init();
#endif
start_log_service();
}
//sizeof(log_items)/sizeof(log_items[0])
void log_service_add_table(log_item_t *tbl, int len)
{
int i;
for(i=0;i<len;i++)
log_add_new_command(&tbl[i]);
}
void* log_action(char *cmd)
{
int search_cnt=0;
int index = hash_index(cmd)%ATC_INDEX_NUM;
struct list_head *head = &log_hash[index];
struct list_head *iterator;
log_item_t *item;
void *act = NULL;
list_for_each(iterator, head) {
item = list_entry(iterator, log_item_t, node);
search_cnt++;
if( strcmp(item->log_cmd, cmd) == 0){
//printf("%s match %s, search cnt %d\n\r", cmd, item->log_cmd, search_cnt);
act = (void*)item->at_act;
break;
}
}
return act;
}
void* log_handler(char *cmd)
{
log_act_t action=NULL;
char buf[LOG_SERVICE_BUFLEN];
memset(buf, 0, LOG_SERVICE_BUFLEN);
char *copy=buf;
char *token = NULL;
char *param = NULL;
char tok[5] = {0};//'\0'
#if CONFIG_LOG_HISTORY
strcpy(log_history[((log_history_count++)%LOG_HISTORY_LEN)], log_buf);
#endif
strncpy(copy, cmd,LOG_SERVICE_BUFLEN-1);
#if defined(USE_STRSEP)
token = _strsep(&copy, "=");
param = copy;
#else
token = strtok(copy, "=");
param = strtok(NULL, NULL);
#endif
if(token && (strlen(token) <= 4))
strcpy(tok, token);
else{
//printf("\n\rAT Cmd format error!\n");
return NULL;
};
//printf(" Command %s \n\r ", tok);
//printf(" Param %s \n\r", param);
action = (log_act_t)log_action(tok);
if(action){
action(param);
}
return (void*)action;
}
int parse_param(char *buf, char **argv)
{
int argc = 1;
char str_buf[LOG_SERVICE_BUFLEN];
memset(str_buf, 0, LOG_SERVICE_BUFLEN);
int str_count = 0;
int buf_cnt = 0;
if(buf == NULL)
goto exit;
while((argc < MAX_ARGC) && (*buf != '\0')) {
while((*buf == ',') || (*buf == '[') || (*buf == ']')){
if((*buf == ',') && (*(buf+1) == ',')){
argv[argc] = NULL;
argc++;
}
*buf = '\0';
buf++;
}
if(*buf == '\0')
break;
else if(*buf == '"'){
memset(str_buf,'\0',LOG_SERVICE_BUFLEN);
str_count = 0;
buf_cnt = 0;
*buf = '\0';
buf ++;
if(*buf == '\0')
break;
argv[argc] = buf;
while((*buf != '"')&&(*buf != '\0')){
if(*buf == '\\'){
buf ++;
buf_cnt++;
}
str_buf[str_count] = *buf;
str_count++;
buf_cnt++;
buf ++;
}
*buf = '\0';
memcpy(buf-buf_cnt,str_buf,buf_cnt);
}
else{
argv[argc] = buf;
}
argc++;
buf++;
while( (*buf != ',')&&(*buf != '\0')&&(*buf != '[')&&(*buf != ']') )
buf++;
}
exit:
return argc;
}
unsigned char gDbgLevel = AT_DBG_ERROR;
unsigned int gDbgFlag = 0xFFFFFFFF;
void at_set_debug_level(unsigned char newDbgLevel)
{
gDbgLevel = newDbgLevel;
}
void at_set_debug_mask(unsigned int newDbgFlag)
{
gDbgFlag = newDbgFlag;
}
#if SUPPORT_INTERACTIVE_MODE
extern char uart_buf[64];
void legency_interactive_handler(unsigned char argc, unsigned char **argv)
{
#if 0 //defined(CONFIG_PLATFORM_8195A)
if(argc<1)
{
DiagPrintf("Wrong argument number!\r\n");
return;
}
DiagPrintf("Wlan Normal Mode\n");
WlanNormal( argc, argv);
#else
strncpy(uart_buf, log_buf, 63);//uart_buf[64]
xSemaphoreGive(uart_rx_interrupt_sema);
#endif
}
#endif
#if CONFIG_WLAN
#ifndef WLAN0_NAME
#define WLAN0_NAME "wlan0"
#endif
#ifndef WLAN1_NAME
#define WLAN1_NAME "wlan1"
#endif
int mp_commnad_handler(char *cmd)
{
char buf[64];
char *token = NULL;
memset(buf, 0, 64);
//strcpy(buf, cmd);
strncpy(buf, cmd, (64-1));
token = strtok(buf, " ");
if(token && (strcmp(buf, "iwpriv") == 0)){
token = strtok(NULL, "");
wext_private_command(WLAN0_NAME, token, 1);
return 0;
}
return -1;
}
#endif
void print_help_msg(void){
#if CONFIG_WLAN
extern void print_wlan_help(void);
print_wlan_help();
#endif
//add other help message print here
}
int print_help_handler(char *cmd){
if(strcmp(cmd, "help") == 0){
print_help_msg();
return 0;
}
return -1;
}
#if CONFIG_LOG_SERVICE_LOCK
void log_service_lock(void)
{
rtw_down_sema(&log_service_sema);
}
u32 log_service_lock_timeout(u32 ms)
{
return rtw_down_timeout_sema(&log_service_sema, ms);
}
void log_service_unlock(void)
{
rtw_up_sema(&log_service_sema);
}
void log_service_lock_init(void){
rtw_init_sema(&log_service_sema, 1);
}
#endif
void log_service(void *param)
{
_AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, "\n\rStart LOG SERVICE MODE\n\r");
_AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, "\n\r# ");
while(1){
while(xSemaphoreTake(log_rx_interrupt_sema, portMAX_DELAY) != pdTRUE);
#if CONFIG_LOG_SERVICE_LOCK
log_service_lock();
#endif
if(log_handler((char *)log_buf) == NULL){
#if CONFIG_WLAN
if(mp_commnad_handler((char *)log_buf) < 0)
#endif
{
#if SUPPORT_INTERACTIVE_MODE
print_help_handler((char *)log_buf);
legency_interactive_handler(NULL, NULL);
#else
if(print_help_handler((char *)log_buf) < 0){
at_printf("\r\nunknown command '%s'", log_buf);
}
#endif
}
}
log_buf[0] = '\0';
#if CONFIG_INIC_EN
inic_cmd_ioctl = 0;
#endif
_AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, "\n\r[MEM] After do cmd, available heap %d\n\r", xPortGetFreeHeapSize());
_AT_DBG_MSG(AT_FLAG_COMMON, AT_DBG_ALWAYS, "\r\n\n# "); //"#" is needed for mp tool
#if CONFIG_EXAMPLE_UART_ATCMD
if(atcmd_lwip_is_tt_mode())
at_printf(STR_END_OF_ATDATA_RET);
else
at_printf(STR_END_OF_ATCMD_RET);
#endif
#if CONFIG_LOG_SERVICE_LOCK
log_service_unlock();
#endif
#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1)
pmu_release_wakelock(BIT(PMU_LOGUART_DEVICE));
#endif
}
}
#define STACKSIZE 1280
void start_log_service(void)
{
xTaskHandle CreatedTask;
int result;
#if CONFIG_USE_TCM_HEAP
/*********************************************************************
*
* ATCMD V2 supports commands for SSL
* It will cause problems while doing SSL operations if the stack is placed in TCM region
*
*********************************************************************/
void *stack_addr = NULL;
#if (ATCMD_VER == ATVER_1) || ((ATCMD_VER == ATVER_2)&&(ATCMD_SUPPORT_SSL == 0))
extern void *tcm_heap_malloc(int size);
stack_addr = tcm_heap_malloc(STACKSIZE * sizeof(int));
if(stack_addr == NULL){
}
#endif
result = xTaskGenericCreate(
log_service,
( signed portCHAR * ) "log_service",
STACKSIZE,
NULL,
tskIDLE_PRIORITY + 5,
&CreatedTask,
stack_addr,
NULL);
#else
result = xTaskCreate( log_service, ( signed portCHAR * ) "log_service", STACKSIZE, NULL, tskIDLE_PRIORITY + 5, &CreatedTask );
#endif
if(result != pdPASS) {
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
}
}
void fAT_exit(void *arg){
printf("\n\rLeave LOG SERVICE");
vTaskDelete(NULL);
}
#if CONFIG_LOG_HISTORY
void fAT_log(void *arg){
int i = 0;
printf("[AT]log history:\n\n\r");
if(log_history_count > LOG_HISTORY_LEN){
for(i=0; i<4; i++)
printf(" %s\n\r", log_history[((log_history_count+i)%LOG_HISTORY_LEN)]);
}
else{
for(i=0; i<(log_history_count-1); i++)
printf(" %s\n\r", log_history[i]);
}
}
#endif
log_item_t at_log_items[ ] = {
{"AT--", fAT_exit,},
#if CONFIG_LOG_HISTORY
{"AT??", fAT_log,},
#endif
{"ATxx", fAT_exit,}
};
void at_log_init(void)
{
log_service_add_table(at_log_items, sizeof(at_log_items)/sizeof(at_log_items[0]));
}
log_module_init(at_log_init);
#endif

View File

@@ -0,0 +1,127 @@
#ifndef LOG_SERVICE_H
#define LOG_SERVICE_H
#include "dlist.h"
/*
* Include user defined options first. Anything not defined in these files
* will be set to standard values. Override anything you dont like!
*/
#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B)
#include "platform_opts.h"
#include "platform_stdlib.h"
#endif
//#ifdef __ICCARM__
//#define STRINGIFY(s) #s
//#define SECTION(_name) _Pragma( STRINGIFY(location=_name))
//#define log_module_init(fn) \
// SECTION(".data.log_init") __root static void* log_##fn = (void*)fn
//#elif defined(__CC_ARM)
//#define log_module_init(fn) \
//static void* log_##fn __attribute__((section(".data.log_init"))) = (void*)fn;
//#define DiagPrintf printf
//#elif defined(__GNUC__)
//#define log_module_init(fn) \
//static void* log_##fn __attribute__((section(".data.log_init"))) = (void*)fn;
//#else
//#error "not implement"
//#endif
#define log_module_init(fn)
#define ATC_INDEX_NUM 32
#ifndef SUPPORT_LOG_SERVICE
#define SUPPORT_LOG_SERVICE 1
#endif
//LOG_SERVICE_BUFLEN: default, only 63 bytes could be used for keeping input
// cmd, the last byte is for string end ('\0').
#ifndef LOG_SERVICE_BUFLEN
#define LOG_SERVICE_BUFLEN 64
#endif
#ifndef CONFIG_LOG_HISTORY
#define CONFIG_LOG_HISTORY 0
#if CONFIG_LOG_HISTORY
#define LOG_HISTORY_LEN 5
#endif
#endif //#ifndef CONFIG_LOG_HISTORY
#ifndef MAX_ARGC
#define MAX_ARGC 12
#endif
#ifndef CONFIG_LOG_SERVICE_LOCK
#define CONFIG_LOG_SERVICE_LOCK 0 // //to protect log_buf[], only one command processed per time
#endif
#define AT_BIT(n) (1<<n)
#define AT_FLAG_DUMP AT_BIT(0)
#define AT_FLAG_EDIT AT_BIT(1)
#define AT_FLAG_ADC AT_BIT(2)
#define AT_FLAG_GPIO AT_BIT(3)
#define AT_FLAG_OTA AT_BIT(4)
#define AT_FLAG_NFC AT_BIT(5)
#define AT_FLAG_OS AT_BIT(6)
#define AT_FLAG_LWIP AT_BIT(7)
#define AT_FLAG_COMMON AT_BIT(8)
#define AT_FLAG_WIFI AT_BIT(9)
#define AT_FLAG_RDP AT_BIT(10)
enum{
AT_DBG_OFF = 0,
AT_DBG_ALWAYS,
AT_DBG_ERROR,
AT_DBG_WARNING,
AT_DBG_INFO
};
extern unsigned char gDbgLevel;
extern unsigned int gDbgFlag;
#define AT_PRINTK(...) \
do{ \
printf(__VA_ARGS__); \
printf("\r\n"); \
}while(0)
#define _AT_PRINTK(...) printf(__VA_ARGS__)
#define AT_DBG_MSG(flag, level, ...) \
do{ \
if(((flag) & gDbgFlag) && (level <= gDbgLevel)){ \
AT_PRINTK(__VA_ARGS__); \
} \
}while(0)
#define _AT_DBG_MSG(flag, level, ...) \
do{ \
if(((flag) & gDbgFlag) && (level <= gDbgLevel)){ \
_AT_PRINTK(__VA_ARGS__); \
} \
}while(0)
#ifndef SUPPORT_INTERACTIVE_MODE
#define SUPPORT_INTERACTIVE_MODE 0
#endif //#ifndef SUPPORT_INTERACTIVE_MODE
typedef void (*log_init_t)(void);
typedef void (*log_act_t)(void*);
typedef struct _at_command_item_{
char *log_cmd;
log_act_t at_act;
struct list_head node;
}log_item_t;
void log_service_add_table(log_item_t *tbl, int len);
int parse_param(char *buf, char **argv);
#if CONFIG_LOG_SERVICE_LOCK
void log_service_lock_init(void);
void log_service_lock(void);
u32 log_service_lock_timeout(u32 ms);
void log_service_unlock(void);
#endif
#define C_NUM_AT_CMD 4 //"ATxx", 4 characters
#define C_NUM_AT_CMD_DLT 1 //"=", 1 charater
#define STR_END_OF_ATCMD_RET "\r\n\n# " //each AT command response will end with this string
#define STR_END_OF_ATDATA_RET "\r\n\n> " //data transparent transmission indicator
#endif

View File

@@ -0,0 +1,669 @@
/* Includes ------------------------------------------------------------------*/
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/dhcp.h"
#include "lwip/dns.h"
#include "ethernetif.h"
#include "main.h"
#include "lwip_netconf.h"
#ifdef LWIP_HOOK_TCP_ISN
#include "lwip/tcp.h"
#endif
#if CONFIG_WLAN
#include "wifi_ind.h"
#endif
#if defined(STM32F2XX)
#include "stm322xg_eval_lcd.h"
#elif defined(STM32F4XX)
#include "stm324xg_eval_lcd.h"
#endif
#include <platform/platform_stdlib.h>
#if defined(CONFIG_FAST_DHCP) && CONFIG_FAST_DHCP
#include "wlan_fast_connect/example_wlan_fast_connect.h"
#endif
/*Static IP ADDRESS*/
#ifndef IP_ADDR0
#define IP_ADDR0 192
#define IP_ADDR1 168
#define IP_ADDR2 1
#define IP_ADDR3 80
#endif
/*NETMASK*/
#ifndef NETMASK_ADDR0
#define NETMASK_ADDR0 255
#define NETMASK_ADDR1 255
#define NETMASK_ADDR2 255
#define NETMASK_ADDR3 0
#endif
/*Gateway Address*/
#ifndef GW_ADDR0
#define GW_ADDR0 192
#define GW_ADDR1 168
#define GW_ADDR2 1
#define GW_ADDR3 1
#endif
/*Static IP ADDRESS*/
#ifndef AP_IP_ADDR0
#define AP_IP_ADDR0 192
#define AP_IP_ADDR1 168
#define AP_IP_ADDR2 43
#define AP_IP_ADDR3 1
#endif
/*NETMASK*/
#ifndef AP_NETMASK_ADDR0
#define AP_NETMASK_ADDR0 255
#define AP_NETMASK_ADDR1 255
#define AP_NETMASK_ADDR2 255
#define AP_NETMASK_ADDR3 0
#endif
/*Gateway Address*/
#ifndef AP_GW_ADDR0
#define AP_GW_ADDR0 192
#define AP_GW_ADDR1 168
#define AP_GW_ADDR2 43
#define AP_GW_ADDR3 1
#endif
/*Static IP ADDRESS FOR ETHERNET*/
#ifndef ETH_IP_ADDR0
#define ETH_IP_ADDR0 192
#define ETH_IP_ADDR1 168
#define ETH_IP_ADDR2 0
#define ETH_IP_ADDR3 80
#endif
/*NETMASK FOR ETHERNET*/
#ifndef ETH_NETMASK_ADDR0
#define ETH_NETMASK_ADDR0 255
#define ETH_NETMASK_ADDR1 255
#define ETH_NETMASK_ADDR2 255
#define ETH_NETMASK_ADDR3 0
#endif
/*Gateway address for ethernet*/
#ifndef ETH_GW_ADDR0
#define ETH_GW_ADDR0 192
#define ETH_GW_ADDR1 168
#define ETH_GW_ADDR2 0
#define ETH_GW_ADDR3 1
#endif
/* Private define ------------------------------------------------------------*/
#define MAX_DHCP_TRIES 5
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
struct netif xnetif[NET_IF_NUM]; /* network interface structure */
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initializes the lwIP stack
* @param None
* @retval None
*/
#if CONFIG_WLAN
extern int error_flag;
extern rtw_mode_t wifi_mode;
#endif
int lwip_init_done = 0;
void LwIP_Init(void)
{
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
int8_t idx = 0;
/* Create tcp_ip stack thread */
tcpip_init( NULL, NULL );
/* - netif_add(struct netif *netif, struct ip_addr *ipaddr,
struct ip_addr *netmask, struct ip_addr *gw,
void *state, err_t (* init)(struct netif *netif),
err_t (* input)(struct pbuf *p, struct netif *netif))
Adds your network interface to the netif_list. Allocate a struct
netif and pass a pointer to this structure as the first argument.
Give pointers to cleared ip_addr structures when using DHCP,
or fill them with sane numbers otherwise. The state pointer may be NULL.
The init function pointer must point to a initialization function for
your ethernet netif interface. The following code illustrates it's use.*/
//printf("NET_IF_NUM:%d\n\r",NET_IF_NUM);
for(idx=0;idx<NET_IF_NUM;idx++){
#if LWIP_VERSION_MAJOR >= 2
if(idx==0){
IP4_ADDR(ip_2_ip4(&ipaddr), IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
IP4_ADDR(ip_2_ip4(&netmask), NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(ip_2_ip4(&gw), GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
}
else{
IP4_ADDR(ip_2_ip4(&ipaddr), AP_IP_ADDR0, AP_IP_ADDR1, AP_IP_ADDR2, AP_IP_ADDR3);
IP4_ADDR(ip_2_ip4(&netmask), AP_NETMASK_ADDR0, AP_NETMASK_ADDR1 , AP_NETMASK_ADDR2, AP_NETMASK_ADDR3);
IP4_ADDR(ip_2_ip4(&gw), AP_GW_ADDR0, AP_GW_ADDR1, AP_GW_ADDR2, AP_GW_ADDR3);
}
#else
if(idx==0){
IP4_ADDR(&ipaddr, IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
}
else{
IP4_ADDR(&ipaddr, AP_IP_ADDR0, AP_IP_ADDR1, AP_IP_ADDR2, AP_IP_ADDR3);
IP4_ADDR(&netmask, AP_NETMASK_ADDR0, AP_NETMASK_ADDR1 , AP_NETMASK_ADDR2, AP_NETMASK_ADDR3);
IP4_ADDR(&gw, AP_GW_ADDR0, AP_GW_ADDR1, AP_GW_ADDR2, AP_GW_ADDR3);
}
#endif
#if CONFIG_ETHERNET
if(idx == NET_IF_NUM - 1)
{
#if LWIP_VERSION_MAJOR >= 2
IP4_ADDR(ip_2_ip4(&ipaddr), ETH_IP_ADDR0, ETH_IP_ADDR1, ETH_IP_ADDR2, ETH_IP_ADDR3);
IP4_ADDR(ip_2_ip4(&netmask), ETH_NETMASK_ADDR0, ETH_NETMASK_ADDR1 , ETH_NETMASK_ADDR2, ETH_NETMASK_ADDR3);
IP4_ADDR(ip_2_ip4(&gw), ETH_GW_ADDR0, ETH_GW_ADDR1, ETH_GW_ADDR2, ETH_GW_ADDR3);
#else
IP4_ADDR(&ipaddr, ETH_IP_ADDR0, ETH_IP_ADDR1, ETH_IP_ADDR2, ETH_IP_ADDR3);
IP4_ADDR(&netmask, ETH_NETMASK_ADDR0, ETH_NETMASK_ADDR1 , ETH_NETMASK_ADDR2, ETH_NETMASK_ADDR3);
IP4_ADDR(&gw, ETH_GW_ADDR0, ETH_GW_ADDR1, ETH_GW_ADDR2, ETH_GW_ADDR3);
#endif
}
#endif
xnetif[idx].name[0] = 'r';
xnetif[idx].name[1] = '0'+idx;
#if LWIP_VERSION_MAJOR >= 2
#if CONFIG_ETHERNET
if(idx == NET_IF_NUM - 1)
netif_add(&xnetif[idx], ip_2_ip4(&ipaddr), ip_2_ip4(&netmask),ip_2_ip4(&gw), NULL, &ethernetif_mii_init, &tcpip_input);
else
netif_add(&xnetif[idx], ip_2_ip4(&ipaddr), ip_2_ip4(&netmask),ip_2_ip4(&gw), NULL, &ethernetif_init, &tcpip_input);
#else
netif_add(&xnetif[idx], ip_2_ip4(&ipaddr), ip_2_ip4(&netmask),ip_2_ip4(&gw), NULL, &ethernetif_init, &tcpip_input);
#endif
#else
#if CONFIG_ETHERNET
if(idx == NET_IF_NUM - 1)
netif_add(&xnetif[idx], &ipaddr, &netmask, &gw, NULL, &ethernetif_mii_init, &tcpip_input);
else
netif_add(&xnetif[idx], &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);
#else
netif_add(&xnetif[idx], &ipaddr, &netmask, &gw, NULL, &ethernetif_init, &tcpip_input);
#endif
#endif
printf("interface %d is initialized\n", idx);
}
/* Registers the default network interface. */
netif_set_default(&xnetif[0]);
/*move these operations to wifi_on/wifi_off*/
#if 0
/* When the netif is fully configured this function must be called.*/
for(idx = 0;idx < NET_IF_NUM;idx++)
netif_set_up(&xnetif[idx]);
#endif
lwip_init_done = 1;
}
#if defined(CONFIG_FAST_DHCP) && CONFIG_FAST_DHCP
extern write_reconnect_ptr p_write_reconnect_ptr;
extern uint32_t offer_ip;
extern uint32_t server_ip;
extern u8 is_the_same_ap;
#endif
#if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_STA_STA_MODE)
#undef IP_ADDR2
#undef GW_ADDR2
static u8_t static_addr2 = 0;
#define IP_ADDR2 static_addr2
#define GW_ADDR2 static_addr2
#endif
/**
* @brief LwIP_DHCP_Process_Handle
* @param None
* @retval None
*/
uint8_t LwIP_DHCP(uint8_t idx, uint8_t dhcp_state)
{
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
uint32_t IPaddress;
uint8_t iptab[4];
uint8_t DHCP_state;
struct netif *pnetif = NULL;
struct dhcp *dhcp = NULL;
DHCP_state = dhcp_state;
#if !CONFIG_ETHERNET
if(idx > 1)
idx = 1;
#endif
/* STA+STA: Set different ip network prefix for each interface*/
#if defined(CONFIG_CONCURRENT_MODE) && defined(CONFIG_STA_STA_MODE)
if(idx == 0) {
static_addr2 = 1;
} else {
static_addr2 = 2;
}
#endif
pnetif = &xnetif[idx];
if(DHCP_state == 0){
#if LWIP_VERSION_MAJOR >= 2
ip_addr_set_zero(&pnetif->ip_addr);
ip_addr_set_zero(&pnetif->netmask);
ip_addr_set_zero(&pnetif->gw);
#else
pnetif->ip_addr.addr = 0;
pnetif->netmask.addr = 0;
pnetif->gw.addr = 0;
#endif
}
#if LWIP_VERSION_MAJOR >= 2
dhcp = ((struct dhcp*)netif_get_client_data(pnetif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP));
if(!netif_is_up(pnetif)) // netif should be set up before doing dhcp request (in lwip v2.0.0)
{
netif_set_up(pnetif);
}
#else
dhcp = pnetif->dhcp;
#endif
for (;;)
{
//printf("\n\r ========DHCP_state:%d============\n\r",DHCP_state);
switch (DHCP_state)
{
case DHCP_START:
{
/*acqurie wakelock to guarantee dhcp*/
rtw_wakelock_timeout(4*1000);
#if CONFIG_WLAN
wifi_unreg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl);
#endif
#if defined(CONFIG_FAST_DHCP) && CONFIG_FAST_DHCP
if(is_the_same_ap){
if( (offer_ip != 0 && offer_ip != 0xFFFFFFFF) || (dhcp != NULL) ){
if(dhcp == NULL){
dhcp = (struct dhcp *)mem_malloc(sizeof(struct dhcp));
if (dhcp == NULL) {
printf("dhcp_start(): could not allocate dhcp\n");
return -1;
}
}
memset(dhcp, 0, sizeof(struct dhcp));
dhcp->offered_ip_addr.addr = (u32_t)offer_ip;
dhcp->server_ip_addr.addr = (u32_t)server_ip;
#if LWIP_VERSION_MAJOR >= 2
netif_set_client_data(pnetif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, dhcp);
#else
pnetif->dhcp = dhcp;
#endif
}
}else{
if(dhcp != NULL){
memset(dhcp, 0, sizeof(struct dhcp));
}
}
#endif
dhcp_start(pnetif);
#if LWIP_VERSION_MAJOR >= 2
dhcp = ((struct dhcp*)netif_get_client_data(pnetif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP));
#else
dhcp = pnetif->dhcp;
#endif
IPaddress = 0;
DHCP_state = DHCP_WAIT_ADDRESS;
}
break;
case DHCP_WAIT_ADDRESS:
{
/* If DHCP stopped by wifi_disconn_hdl*/
#if LWIP_VERSION_MAJOR >= 2
#include "lwip/prot/dhcp.h"
if(dhcp->state == DHCP_STATE_OFF)
{
IP4_ADDR(ip_2_ip4(&ipaddr), IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
IP4_ADDR(ip_2_ip4(&netmask), NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(ip_2_ip4(&gw), GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
netif_set_addr(pnetif, ip_2_ip4(&ipaddr), ip_2_ip4(&netmask),ip_2_ip4(&gw));
printf("\n\rLwIP_DHCP: dhcp stop.");
return DHCP_STOP;
}
#else
if(dhcp->state == DHCP_OFF)
{
IP4_ADDR(&ipaddr, IP_ADDR0 ,IP_ADDR1 , IP_ADDR2 , IP_ADDR3 );
IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
netif_set_addr(pnetif, &ipaddr , &netmask, &gw);
printf("\n\rLwIP_DHCP: dhcp stop.");
return DHCP_STOP;
}
#endif
/* Read the new IP address */
#if LWIP_VERSION_MAJOR >= 2
IPaddress = ip_addr_get_ip4_u32(netif_ip_addr4(pnetif));
#else
IPaddress = pnetif->ip_addr.addr;
#endif
if (IPaddress!=0)
{
#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS
tcp_randomize_local_port();
udp_randomize_local_port();
#endif
DHCP_state = DHCP_ADDRESS_ASSIGNED;
#if CONFIG_WLAN
wifi_reg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl, NULL);
#endif
/* Stop DHCP */
// dhcp_stop(pnetif); /* can not stop, need to renew, Robbie*/
iptab[0] = (uint8_t)(IPaddress >> 24);
iptab[1] = (uint8_t)(IPaddress >> 16);
iptab[2] = (uint8_t)(IPaddress >> 8);
iptab[3] = (uint8_t)(IPaddress);
printf("\n\rInterface %d IP address : %d.%d.%d.%d", idx, iptab[3], iptab[2], iptab[1], iptab[0]);
#if defined(CONFIG_FAST_DHCP) && CONFIG_FAST_DHCP
#if LWIP_VERSION_MAJOR >= 2
dhcp = ((struct dhcp*)netif_get_client_data(pnetif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP));
#else
dhcp = pnetif->dhcp;
#endif
restore_wifi_info_to_flash((uint32_t)dhcp->offered_ip_addr.addr, (uint32_t)dhcp->server_ip_addr.addr);
#endif
#if CONFIG_WLAN
error_flag = RTW_NO_ERROR;
#endif
return DHCP_ADDRESS_ASSIGNED;
}
else
{
/* DHCP timeout */
if (dhcp->tries > MAX_DHCP_TRIES)
{
DHCP_state = DHCP_TIMEOUT;
/* Stop DHCP */
dhcp_stop(pnetif);
/* Static address used */
#if LWIP_VERSION_MAJOR >= 2
IP4_ADDR(ip_2_ip4(&ipaddr), IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
IP4_ADDR(ip_2_ip4(&netmask), NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(ip_2_ip4(&gw), GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
netif_set_addr(pnetif, ip_2_ip4(&ipaddr), ip_2_ip4(&netmask),ip_2_ip4(&gw));
#else
IP4_ADDR(&ipaddr, IP_ADDR0 ,IP_ADDR1 , IP_ADDR2 , IP_ADDR3 );
IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
netif_set_addr(pnetif, &ipaddr , &netmask, &gw);
#endif
iptab[0] = IP_ADDR3;
iptab[1] = IP_ADDR2;
iptab[2] = IP_ADDR1;
iptab[3] = IP_ADDR0;
printf("\n\rInterface %d DHCP timeout",idx);
printf("\n\rStatic IP address : %d.%d.%d.%d", iptab[3], iptab[2], iptab[1], iptab[0]);
#if defined(CONFIG_FAST_DHCP) && CONFIG_FAST_DHCP
restore_wifi_info_to_flash((uint32_t)dhcp->offered_ip_addr.addr, (uint32_t)dhcp->server_ip_addr.addr);
#endif
#if CONFIG_WLAN
error_flag = RTW_DHCP_FAIL;
#endif
#if CONFIG_ETHERNET
if(idx == NET_IF_NUM -1) // This is the ethernet interface, set it up for static ip address
netif_set_up(pnetif);
#endif
return DHCP_TIMEOUT;
}
}
}
break;
case DHCP_RELEASE_IP:
#if CONFIG_WLAN
wifi_unreg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl);
#endif
printf("\n\rLwIP_DHCP: Release ip");
#if LWIP_VERSION_MAJOR >= 2
dhcp_release(pnetif);
#else
if(dhcp && dhcp->state != DHCP_OFF)
dhcp_release_unicast(pnetif);
#endif
return DHCP_RELEASE_IP;
case DHCP_STOP:
#if CONFIG_WLAN
wifi_unreg_event_handler(WIFI_EVENT_BEACON_AFTER_DHCP, wifi_rx_beacon_hdl);
#endif
printf("\n\rLwIP_DHCP: dhcp stop.");
dhcp_stop(pnetif);
return DHCP_STOP;
default:
break;
}
/* wait 250 ms */
vTaskDelay(10);
}
}
void LwIP_ReleaseIP(uint8_t idx)
{
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
struct netif *pnetif = &xnetif[idx];
#if LWIP_VERSION_MAJOR >= 2
IP4_ADDR(ip_2_ip4(&ipaddr), 0, 0, 0, 0);
IP4_ADDR(ip_2_ip4(&netmask), 255, 255 , 255, 0);
IP4_ADDR(ip_2_ip4(&gw), 0, 0, 0, 0);
netif_set_addr(pnetif, ip_2_ip4(&ipaddr), ip_2_ip4(&netmask),ip_2_ip4(&gw));
#else
IP4_ADDR(&ipaddr, 0, 0, 0, 0);
IP4_ADDR(&netmask, 255, 255, 255, 0);
IP4_ADDR(&gw, 0, 0, 0, 0);
netif_set_addr(pnetif, &ipaddr , &netmask, &gw);
#endif
}
uint8_t* LwIP_GetMAC(struct netif *pnetif)
{
return (uint8_t *) (pnetif->hwaddr);
}
uint8_t* LwIP_GetIP(struct netif *pnetif)
{
return (uint8_t *) &(pnetif->ip_addr);
}
uint8_t* LwIP_GetGW(struct netif *pnetif)
{
return (uint8_t *) &(pnetif->gw);
}
uint8_t* LwIP_GetMASK(struct netif *pnetif)
{
return (uint8_t *) &(pnetif->netmask);
}
uint8_t* LwIP_GetBC(struct netif *pnetif)
{
#if LWIP_VERSION_MAJOR >= 2
//struct dhcp *dhcp = ((struct dhcp*)netif_get_client_data(pnetif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP));
return NULL;
#else
return (uint8_t *) &(pnetif->dhcp->offered_bc_addr);
#endif
}
#if LWIP_DNS
void LwIP_GetDNS(struct ip_addr* dns)
{
#if LWIP_VERSION_MAJOR >= 2
struct ip_addr *tmp = (struct ip_addr *)dns_getserver(0);
*dns = *tmp;
#else
*dns = dns_getserver(0);
#endif
}
void LwIP_SetDNS(struct ip_addr* dns)
{
dns_setserver(0, dns);
}
#endif
void LwIP_UseStaticIP(struct netif *pnetif)
{
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
/* Static address used */
if(pnetif->name[1] == '0'){
#if CONFIG_WLAN
if((wifi_mode == RTW_MODE_STA)||(wifi_mode == RTW_MODE_STA_AP)){
#if LWIP_VERSION_MAJOR >= 2
IP4_ADDR(ip_2_ip4(&ipaddr), IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
IP4_ADDR(ip_2_ip4(&netmask), NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(ip_2_ip4(&gw), GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
#else
IP4_ADDR(&ipaddr, IP_ADDR0 ,IP_ADDR1 , IP_ADDR2 , IP_ADDR3 );
IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
#endif
}
else if(wifi_mode == RTW_MODE_AP){
#if LWIP_VERSION_MAJOR >= 2
IP4_ADDR(ip_2_ip4(&ipaddr), AP_IP_ADDR0, AP_IP_ADDR1, AP_IP_ADDR2, AP_IP_ADDR3);
IP4_ADDR(ip_2_ip4(&netmask), AP_NETMASK_ADDR0, AP_NETMASK_ADDR1 , AP_NETMASK_ADDR2, AP_NETMASK_ADDR3);
IP4_ADDR(ip_2_ip4(&gw), AP_GW_ADDR0, AP_GW_ADDR1, AP_GW_ADDR2, AP_GW_ADDR3);
#else
IP4_ADDR(&ipaddr, AP_IP_ADDR0, AP_IP_ADDR1, AP_IP_ADDR2, AP_IP_ADDR3);
IP4_ADDR(&netmask, AP_NETMASK_ADDR0, AP_NETMASK_ADDR1 , AP_NETMASK_ADDR2, AP_NETMASK_ADDR3);
IP4_ADDR(&gw, AP_GW_ADDR0, AP_GW_ADDR1, AP_GW_ADDR2, AP_GW_ADDR3);
#endif
}
#endif
}else{
#if LWIP_VERSION_MAJOR >= 2
IP4_ADDR(ip_2_ip4(&ipaddr), AP_IP_ADDR0, AP_IP_ADDR1, AP_IP_ADDR2, AP_IP_ADDR3);
IP4_ADDR(ip_2_ip4(&netmask), AP_NETMASK_ADDR0, AP_NETMASK_ADDR1 , AP_NETMASK_ADDR2, AP_NETMASK_ADDR3);
IP4_ADDR(ip_2_ip4(&gw), AP_GW_ADDR0, AP_GW_ADDR1, AP_GW_ADDR2, AP_GW_ADDR3);
#else
IP4_ADDR(&ipaddr, AP_IP_ADDR0, AP_IP_ADDR1, AP_IP_ADDR2, AP_IP_ADDR3);
IP4_ADDR(&netmask, AP_NETMASK_ADDR0, AP_NETMASK_ADDR1 , AP_NETMASK_ADDR2, AP_NETMASK_ADDR3);
IP4_ADDR(&gw, AP_GW_ADDR0, AP_GW_ADDR1, AP_GW_ADDR2, AP_GW_ADDR3);
#endif
}
#if LWIP_VERSION_MAJOR >= 2
netif_set_addr(pnetif, ip_2_ip4(&ipaddr), ip_2_ip4(&netmask),ip_2_ip4(&gw));
#else
netif_set_addr(pnetif, &ipaddr , &netmask, &gw);
#endif
}
#if LWIP_AUTOIP
#include <lwip/autoip.h>
#if LWIP_VERSION_MAJOR >= 2
#include <lwip/prot/autoip.h>
#endif
void LwIP_AUTOIP(struct netif *pnetif)
{
uint8_t *ip = LwIP_GetIP(pnetif);
struct autoip *autoip = NULL;
autoip_start(pnetif);
#if LWIP_VERSION_MAJOR >= 2
autoip = ((struct autoip*)netif_get_client_data(pnetif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP));
#else
autoip = pnetif->autoip;
#endif
while((autoip->state == AUTOIP_STATE_PROBING) || (autoip->state == AUTOIP_STATE_ANNOUNCING)) {
vTaskDelay(1000);
}
if(*((uint32_t *) ip) == 0) {
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
printf("AUTOIP timeout\n");
/* Static address used */
#if LWIP_VERSION_MAJOR >= 2
IP4_ADDR(ip_2_ip4(&ipaddr), IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3);
IP4_ADDR(ip_2_ip4(&netmask), NETMASK_ADDR0, NETMASK_ADDR1 , NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(ip_2_ip4(&gw), GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
netif_set_addr(pnetif, ip_2_ip4(&ipaddr), ip_2_ip4(&netmask),ip_2_ip4(&gw));
#else
IP4_ADDR(&ipaddr, IP_ADDR0 ,IP_ADDR1 , IP_ADDR2 , IP_ADDR3 );
IP4_ADDR(&netmask, NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3);
IP4_ADDR(&gw, GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3);
netif_set_addr(pnetif, &ipaddr , &netmask, &gw);
#endif
printf("Static IP address : %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
}
else {
printf("\nLink-local address: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);
}
}
#endif
#if LWIP_IPV6
/* Get IPv6 address with lwip 1.5.0 */
void LwIP_AUTOIP_IPv6(struct netif *pnetif)
{
#if LWIP_VERSION_MAJOR >= 2
uint8_t *ipv6 = (uint8_t *) netif_ip6_addr(pnetif, 0)->addr;
#else
uint8_t *ipv6 = (uint8_t *) &(pnetif->ip6_addr[0].addr[0]);
#endif
netif_create_ip6_linklocal_address(pnetif, 1);
printf("\nIPv6 link-local address: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
ipv6[0], ipv6[1], ipv6[2], ipv6[3], ipv6[4], ipv6[5], ipv6[6], ipv6[7],
ipv6[8], ipv6[9], ipv6[10], ipv6[11], ipv6[12], ipv6[13], ipv6[14], ipv6[15]);
}
#endif
uint32_t LWIP_Get_Dynamic_Sleep_Interval()
{
#ifdef DYNAMIC_TICKLESS_SLEEP_INTERVAL
return DYNAMIC_TICKLESS_SLEEP_INTERVAL;
#else
return 0;
#endif
}

View File

@@ -0,0 +1,79 @@
/******************************************************************************
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
*
******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __NETCONF_H
#define __NETCONF_H
#ifdef __cplusplus
extern "C" {
#endif
#include "tcpip.h"
/* Includes ------------------------------------------------------------------*/
#include <platform/platform_stdlib.h>
#include "platform_opts.h"
#include "autoconf.h"
// macros
/* Give default value if not defined */
#ifndef NET_IF_NUM
#ifdef CONFIG_CONCURRENT_MODE
#define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN) + 1)
#else
#define NET_IF_NUM ((CONFIG_ETHERNET) + (CONFIG_WLAN))
#endif // end of CONFIG_CONCURRENT_MODE
#endif // end of NET_IF_NUM
/* Private typedef -----------------------------------------------------------*/
typedef enum
{
DHCP_START=0,
DHCP_WAIT_ADDRESS,
DHCP_ADDRESS_ASSIGNED,
DHCP_RELEASE_IP,
DHCP_STOP,
DHCP_TIMEOUT
} DHCP_State_TypeDef;
/* Extern functions ------------------------------------------------------------*/
void wifi_rx_beacon_hdl( char* buf, int buf_len, int flags, void* userdata);
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void LwIP_Init(void);
uint8_t LwIP_DHCP(uint8_t idx, uint8_t dhcp_state);
unsigned char* LwIP_GetMAC(struct netif *pnetif);
unsigned char* LwIP_GetIP(struct netif *pnetif);
unsigned char* LwIP_GetGW(struct netif *pnetif);
uint8_t* LwIP_GetMASK(struct netif *pnetif);
uint8_t* LwIP_GetBC(struct netif *pnetif);
#if LWIP_DNS
void LwIP_GetDNS(struct ip_addr* dns);
void LwIP_SetDNS(struct ip_addr* dns);
#endif
void LwIP_UseStaticIP(struct netif *pnetif);
#if LWIP_AUTOIP
void LwIP_AUTOIP(struct netif *pnetif);
#endif
#if LWIP_IPV6
void LwIP_AUTOIP_IPv6(struct netif *pnetif);
#endif
uint32_t LWIP_Get_Dynamic_Sleep_Interval();
#ifdef __cplusplus
}
#endif
#endif /* __NETCONF_H */
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,341 @@
/******************************************************************************
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
*
******************************************************************************/
#ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__
#include <platform/platform_stdlib.h>
#include "platform_opts.h"
#define WIFI_LOGO_CERTIFICATION_CONFIG 0 //for ping 10k test buffer setting
/**
* SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
* critical regions during buffer allocation, deallocation and memory
* allocation and deallocation.
*/
#define SYS_LIGHTWEIGHT_PROT 1
/* Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphores
should be used instead */
#define LWIP_COMPAT_MUTEX 1
#define LWIP_COMPAT_MUTEX 1
#define ETHARP_TRUST_IP_MAC 0
#define IP_REASSEMBLY 1
#define IP_FRAG 1
#define ARP_QUEUEING 0
/**
* NO_SYS==1: Provides VERY minimal functionality. Otherwise,
* use lwIP facilities.
*/
#define NO_SYS 0
#ifndef CONFIG_DYNAMIC_TICKLESS
#define CONFIG_DYNAMIC_TICKLESS 0
#endif
/* ---------- Memory options ---------- */
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
byte alignment -> define MEM_ALIGNMENT to 2. */
#define MEM_ALIGNMENT 4
/* MEM_SIZE: the size of the heap memory. If the application will send
a lot of data that needs to be copied, this should be set high. */
#if WIFI_LOGO_CERTIFICATION_CONFIG
#define MEM_SIZE (20*1024) //for ping 10k test
#elif CONFIG_ETHERNET
#define MEM_SIZE (6*1024) //for iperf test
#else
#define MEM_SIZE (5*1024)
#endif
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
sends a lot of data out of ROM (or other static memory), this
should be set high. */
#define MEMP_NUM_PBUF 100
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
per active UDP "connection". */
#define MEMP_NUM_UDP_PCB 6
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
connections. */
#define MEMP_NUM_TCP_PCB 10
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
connections. */
#define MEMP_NUM_TCP_PCB_LISTEN 5
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
segments. */
#define MEMP_NUM_TCP_SEG 20
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
timeouts. */
#define MEMP_NUM_SYS_TIMEOUT 10
/* ---------- Pbuf options ---------- */
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
#if WIFI_LOGO_CERTIFICATION_CONFIG
#define PBUF_POOL_SIZE 40 //for ping 10k test
#else
#define PBUF_POOL_SIZE 20
#endif
/* IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled.*/
#if WIFI_LOGO_CERTIFICATION_CONFIG
#define IP_REASS_MAX_PBUFS 40 //for ping 10k test
#else
#define IP_REASS_MAX_PBUFS 10
#endif
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
#define PBUF_POOL_BUFSIZE 500
/* ---------- TCP options ---------- */
#define LWIP_TCP 1
#define TCP_TTL 255
/* Controls if TCP should queue segments that arrive out of
order. Define to 0 if your device is low on memory. */
#define TCP_QUEUE_OOSEQ 1
/* TCP Maximum segment size. */
#define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */
/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF (5*TCP_MSS)
/* TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least
as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. */
#define TCP_SND_QUEUELEN (4* TCP_SND_BUF/TCP_MSS)
/* TCP receive window. */
#define TCP_WND (4*TCP_MSS)
/* ---------- ICMP options ---------- */
#define LWIP_ICMP 1
/* ---------- ARP options ----------- */
#define LWIP_ARP 1
/* ---------- DHCP options ---------- */
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
turning this on does currently not work. */
#define LWIP_DHCP 1
/* ---------- UDP options ---------- */
#define LWIP_UDP 1
#define UDP_TTL 255
/* ---------- DNS options ---------- */
#define LWIP_DNS 1
/* ---------- UPNP options --------- */
#define LWIP_UPNP 0
/* ---------- SO_SNDRCVTIMEO_NONSTANDARD options --------- */
#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 1
/* ---------- SO_REUSE options --------- */
#define SO_REUSE 1
/* Support Multicast */
#define LWIP_IGMP 1
#define LWIP_RAND() rand()
extern unsigned int sys_now(void);
#define LWIP_SRAND() srand(sys_now())
#define LWIP_MTU_ADJUST 1
/* Support TCP Keepalive */
#define LWIP_TCP_KEEPALIVE 1
/*LWIP_UART_ADAPTER==1: Enable LWIP_UART_ADAPTER when CONFIG_GAGENT is enabled,
because some GAGENT functions denpond on the following macro definitions.*/
#define LWIP_UART_ADAPTER 0
#if LWIP_UART_ADAPTER || CONFIG_ETHERNET
#undef LWIP_SO_SNDTIMEO
#define LWIP_SO_SNDTIMEO 1
#undef SO_REUSE
#define SO_REUSE 1
#undef MEMP_NUM_NETCONN
#define MEMP_NUM_NETCONN 10
#undef TCP_WND
#define TCP_WND (4*TCP_MSS)
#define TCP_KEEPIDLE_DEFAULT 10000UL
#define TCP_KEEPINTVL_DEFAULT 1000UL
#define TCP_KEEPCNT_DEFAULT 10U
#endif
#if CONFIG_EXAMPLE_UART_ATCMD || CONFIG_EXAMPLE_SPI_ATCMD
#undef LWIP_SO_SNDTIMEO
#define LWIP_SO_SNDTIMEO 1
#undef SO_REUSE
#define SO_REUSE 1
#undef SO_REUSE_RXTOALL
#define SO_REUSE_RXTOALL 1
#undef MEMP_NUM_NETCONN
#define MEMP_NUM_NETCONN 10
#undef MEMP_NUM_TCP_PCB
#define MEMP_NUM_TCP_PCB (MEMP_NUM_NETCONN)
#undef MEMP_NUM_UDP_PCB
#define MEMP_NUM_UDP_PCB (MEMP_NUM_NETCONN)
#undef TCP_WND
#define TCP_WND (4*TCP_MSS)
#define TCP_KEEPIDLE_DEFAULT 10000UL
#define TCP_KEEPINTVL_DEFAULT 1000UL
#define TCP_KEEPCNT_DEFAULT 10U
#define ERRNO 1
#endif
#if (CONFIG_EXAMPLE_ANDLINK || CONFIG_LIBCOAP)
#define MEMP_USE_CUSTOM_POOLS 1
#endif
/* ---------- Statistics options ---------- */
#define LWIP_STATS 0
#define LWIP_PROVIDE_ERRNO 1
/*
--------------------------------------
---------- Checksum options ----------
--------------------------------------
*/
/*
The STM32F2x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums by hardware:
- To use this feature let the following define uncommented.
- To disable it and process by CPU comment the the checksum.
*/
//Do checksum by lwip - WLAN nic does not support Checksum offload
//#define CHECKSUM_BY_HARDWARE
#ifdef CHECKSUM_BY_HARDWARE
/* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/
#define CHECKSUM_GEN_IP 0
/* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/
#define CHECKSUM_GEN_UDP 0
/* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/
#define CHECKSUM_GEN_TCP 0
/* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/
#define CHECKSUM_CHECK_IP 0
/* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/
#define CHECKSUM_CHECK_UDP 0
/* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/
#define CHECKSUM_CHECK_TCP 0
#else
/* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/
#define CHECKSUM_GEN_IP 1
/* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/
#define CHECKSUM_GEN_UDP 1
/* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/
#define CHECKSUM_GEN_TCP 1
/* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/
#define CHECKSUM_CHECK_IP 1
/* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/
#define CHECKSUM_CHECK_UDP 1
/* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/
#define CHECKSUM_CHECK_TCP 1
#endif
/*
----------------------------------------------
---------- Sequential layer options ----------
----------------------------------------------
*/
/**
* LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
*/
#define LWIP_NETCONN 1
/*
------------------------------------
---------- Socket options ----------
------------------------------------
*/
/**
* LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
*/
#define LWIP_SOCKET 1
/*
-----------------------------------
---------- DEBUG options ----------
-----------------------------------
*/
#define LWIP_DEBUG 1
/*
---------------------------------
---------- OS options ----------
---------------------------------
*/
#define TCPIP_THREAD_STACKSIZE 1000
#define TCPIP_MBOX_SIZE 6
#define DEFAULT_UDP_RECVMBOX_SIZE 6
#define DEFAULT_TCP_RECVMBOX_SIZE 6
#define DEFAULT_RAW_RECVMBOX_SIZE 6
#define DEFAULT_ACCEPTMBOX_SIZE 6
#define DEFAULT_THREAD_STACKSIZE 500
#define TCPIP_THREAD_PRIO (configMAX_PRIORITIES - 2)
/* Added by Realtek */
#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 1
#ifndef DNS_IGNORE_REPLY_ERR
#define DNS_IGNORE_REPLY_ERR 1
#endif /* DNS_IGNORE_REPLY_ERR */
/* Added by Realtek. For DHCP server reply unicast DHCP packets before the ip actually assigned. */
#define ETHARP_SUPPORT_STATIC_ENTRIES 1
/* Extra options for lwip_v2.0.2 which should not affect lwip_v1.4.1 */
#define LWIP_TCPIP_CORE_LOCKING 0
#define LWIP_TCPIP_TIMEOUT 1
#define LWIP_SO_RCVTIMEO 1
#define LWIP_SOCKET_SET_ERRNO 0
#undef LWIP_DEBUG
#define LWIP_RAW 1
#define LWIP_AUTOIP 1
#define TCPIP_THREAD_NAME "TCP_IP"
#define LWIP_IPV6 0
#if LWIP_IPV6
#undef MEMP_NUM_SYS_TIMEOUT
#define MEMP_NUM_SYS_TIMEOUT 13
#endif
#include "lwip/init.h" //for version control
#endif /* __LWIPOPTS_H__ */
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,68 @@
#ifndef MAIN_H
#define MAIN_H
#include <autoconf.h>
#define CONFIG_WLAN 1
/* Header file declaration*/
void wlan_network();
/* Interactive Mode */
#define SERIAL_DEBUG_RX 1
#if defined(__ICCARM__)
static
#endif
char uart_buf[64];
/* WLAN and Netork */
#define STA_MODE_SSID "ap" /* Set SSID here */
#define AP_MODE_SSID "wlan_ap_ssid" /* Set SSID here */
#define AP_DEFAULT_CH 6
#define WLAN0_NAME "wlan0"
#define WLAN1_NAME "wlan1"
#define WPA_PASSPHRASE "1234567890" /* Max 32 cahracters */
#define WEP40_KEY {0x12, 0x34, 0x56, 0x78, 0x90}
/*Static IP ADDRESS*/
#define IP_ADDR0 192
#define IP_ADDR1 168
#define IP_ADDR2 1
#define IP_ADDR3 80
/*NETMASK*/
#define NETMASK_ADDR0 255
#define NETMASK_ADDR1 255
#define NETMASK_ADDR2 255
#define NETMASK_ADDR3 0
/*Gateway Address*/
#define GW_ADDR0 192
#define GW_ADDR1 168
#define GW_ADDR2 1
#define GW_ADDR3 1
/*******************************************/
/*Static IP ADDRESS*/
#define AP_IP_ADDR0 192
#define AP_IP_ADDR1 168
#define AP_IP_ADDR2 43
#define AP_IP_ADDR3 1
/*NETMASK*/
#define AP_NETMASK_ADDR0 255
#define AP_NETMASK_ADDR1 255
#define AP_NETMASK_ADDR2 255
#define AP_NETMASK_ADDR3 0
/*Gateway Address*/
#define AP_GW_ADDR0 192
#define AP_GW_ADDR1 168
#define AP_GW_ADDR2 43
#define AP_GW_ADDR3 1
#endif

View File

@@ -0,0 +1,21 @@
//----------------------------------------------------------------------------//
#ifndef __MAIN_TEST_H
#define __MAIN_TEST_H
#ifdef __cplusplus
extern "C" {
#endif
/* Exported test functions ------------------------------------------------------- */
void do_ping_test(char *ip, int size, int count, int interval);
void do_ping_call(char *ip, int loop, int count);
void interactive_question(char *question, char *choice, char *buf, int buf_size);
void start_interactive_mode(void);
#ifdef __cplusplus
}
#endif
#endif // __MAIN_TEST_H
//----------------------------------------------------------------------------//

View File

@@ -0,0 +1,50 @@
/**
******************************************************************************
* @file netconf.h
* @author MCD Application Team
* @version V1.1.0
* @date 07-October-2011
* @brief This file contains all the functions prototypes for the netconf.c
* file.
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __NETCONF_H
#define __NETCONF_H
#ifdef __cplusplus
extern "C" {
#endif
// TODO: remove this file
#include "lwip_netconf.h"
#if 0
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void LwIP_Init(void);
void LwIP_DHCP(void);
#endif
#ifdef __cplusplus
}
#endif
#endif /* __NETCONF_H */
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,8 @@
#ifndef __RTL8195A_IT_H_
#define __RTL8195A_IT_H_
int irq_alloc_wlan(void *contex);
#endif //__RTL8195A_IT_H_

View File

@@ -0,0 +1,46 @@
#ifndef _UTIL_H
#define _UTIL_H
#include <wireless.h>
#include <wlan_intf.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "wifi_util.h"
#if 0
typedef enum _WIFI_EVENT_INDICATE{
WIFI_EVENT_CONNECT = 0,
WIFI_EVENT_DISCONNECT = 1,
WIFI_EVENT_FOURWAY_HANDSHAKE_DONE = 2,
}WIFI_EVENT_INDICATE;
int wext_get_ssid(const char *ifname, __u8 *ssid);
int wext_set_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len);
int wext_set_auth_param(const char *ifname, __u16 idx, __u32 value);
int wext_set_key_ext(const char *ifname, __u16 alg, const __u8 *addr, int key_idx, int set_tx, const __u8 *seq, __u16 seq_len, __u8 *key, __u16 key_len);
int wext_get_enc_ext(const char *ifname, __u16 *alg);
int wext_set_passphrase(const char *ifname, const __u8 *passphrase, __u16 passphrase_len);
int wext_get_passphrase(const char *ifname, __u8 *passphrase);
int wext_set_mode(const char *ifname, int mode);
int wext_get_mode(const char *ifname, int *mode);
int wext_set_ap_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len);
int wext_set_country(const char *ifname, char *country_code);
int wext_get_rssi(const char *ifname, int *rssi);
int wext_set_channel(const char *ifname, __u8 ch);
int wext_get_channel(const char *ifname, __u8 *ch);
int wext_set_scan(const char *ifname, char *buf, __u16 buf_len);
int wext_get_scan(const char *ifname, char *buf, __u16 buf_len);
int wext_mp_command(const char *ifname, char *cmd, int show_msg);
int wext_wifi_priv(const char *ifname, int argc, char **argv);
void wext_wlan_indicate(unsigned int cmd, union iwreq_data *wrqu, char *extra);
#endif
#define wext_handshake_done rltk_wlan_handshake_done
#ifdef __cplusplus
}
#endif
#endif /* _UTIL_H */

View File

@@ -0,0 +1,262 @@
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include <lwip/sockets.h>
#include <lwip/raw.h>
#include <lwip/icmp.h>
#include <lwip/inet_chksum.h>
#include <lwip/netdb.h>
#include <platform/platform_stdlib.h>
#define PING_IP "192.168.159.1"
#define PING_TO 1000
#define PING_ID 0xABCD
#define BUF_SIZE 10000
#define STACKSIZE 1024
static unsigned short ping_seq = 0;
static int infinite_loop, ping_count, data_size, ping_interval, ping_call;
static int ping_total_time = 0, ping_received_count = 0;
static void generate_ping_echo(unsigned char *buf, int size)
{
int i;
struct icmp_echo_hdr *pecho;
for(i = 0; i < size; i ++) {
buf[sizeof(struct icmp_echo_hdr) + i] = (unsigned char) i;
}
pecho = (struct icmp_echo_hdr *) buf;
ICMPH_TYPE_SET(pecho, ICMP_ECHO);
ICMPH_CODE_SET(pecho, 0);
pecho->chksum = 0;
pecho->id = PING_ID;
pecho->seqno = htons(++ ping_seq);
//Checksum includes icmp header and data. Need to calculate after fill up icmp header
pecho->chksum = inet_chksum(pecho, sizeof(struct icmp_echo_hdr) + size);
}
void ping_test(void *param)
{
int i, ping_socket;
int pint_timeout = PING_TO;
struct sockaddr_in to_addr, from_addr;
int from_addr_len = sizeof(struct sockaddr);
int ping_size, reply_size;
unsigned char *ping_buf, *reply_buf;
unsigned int ping_time, reply_time;
struct ip_hdr *iphdr;
struct icmp_echo_hdr *pecho;
unsigned int min_time = 1000, max_time = 0;
struct hostent *server_host;
char *host = param;
ping_total_time = 0;
ping_received_count = 0;
if(data_size > BUF_SIZE){
printf("\n\r[ERROR] %s: data size error, can't exceed %d",__func__,BUF_SIZE);
return;
}
//Ping size = icmp header(8 bytes) + data size
ping_size = sizeof(struct icmp_echo_hdr) + data_size;
ping_buf = pvPortMalloc(ping_size);
if(NULL == ping_buf){
printf("\n\r[ERROR] %s: Allocate ping_buf failed",__func__);
return;
}
reply_buf = pvPortMalloc(ping_size);
if(NULL == reply_buf){
vPortFree(ping_buf);
printf("\n\r[ERROR] %s: Allocate reply_buf failed",__func__);
return;
}
printf("\n\r[%s] PING %s %d(%d) bytes of data\n", __FUNCTION__, host, data_size, sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr) + data_size);
for(i = 0; (i < ping_count) || (infinite_loop == 1); i ++) {
ping_socket = socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP);
#if defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD) && (LWIP_SO_SNDRCVTIMEO_NONSTANDARD == 0) // lwip 1.5.0
struct timeval timeout;
timeout.tv_sec = pint_timeout / 1000;
timeout.tv_usec = pint_timeout % 1000 * 1000;
setsockopt(ping_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
#else // lwip 1.4.1
setsockopt(ping_socket, SOL_SOCKET, SO_RCVTIMEO, &pint_timeout, sizeof(pint_timeout));
#endif
to_addr.sin_len = sizeof(to_addr);
to_addr.sin_family = AF_INET;
if (inet_aton(host, &to_addr.sin_addr) == 0) {
server_host = gethostbyname(host);
if(server_host == NULL){
printf("\n\r[%s] Get host name failed in the %d ping test\n", __FUNCTION__, (i + 1));
close(ping_socket);
vTaskDelay(ping_interval * configTICK_RATE_HZ);
continue;
}
memcpy((void *) &to_addr.sin_addr, (void *) server_host->h_addr, server_host->h_length);
}
else
to_addr.sin_addr.s_addr = inet_addr(host);
generate_ping_echo(ping_buf, data_size);
sendto(ping_socket, ping_buf, ping_size, 0, (struct sockaddr *) &to_addr, sizeof(to_addr));
ping_time = xTaskGetTickCount();
if((reply_size = recvfrom(ping_socket, reply_buf, ping_size, 0, (struct sockaddr *) &from_addr, (socklen_t *) &from_addr_len))
>= (int)(sizeof(struct ip_hdr) + sizeof(struct icmp_echo_hdr)) && (from_addr.sin_addr.s_addr == to_addr.sin_addr.s_addr)) {
reply_time = xTaskGetTickCount();
iphdr = (struct ip_hdr *)reply_buf;
pecho = (struct icmp_echo_hdr *)(reply_buf + (IPH_HL(iphdr) * 4));
if((pecho->id == PING_ID) && (pecho->seqno == htons(ping_seq))) {
printf("\n\r[%s] %d bytes from %s: icmp_seq=%d time=%d ms", __FUNCTION__, reply_size - sizeof(struct icmp_echo_hdr), inet_ntoa(from_addr.sin_addr), htons(pecho->seqno), (reply_time - ping_time) * portTICK_RATE_MS);
ping_received_count++;
ping_total_time += (reply_time - ping_time) * portTICK_RATE_MS;
if((reply_time - ping_time) > max_time) max_time = (reply_time - ping_time);
if((reply_time - ping_time) < min_time) min_time = (reply_time - ping_time);
}
}
else
printf("\n\r[%s] Request timeout for icmp_seq %d\n", __FUNCTION__, ping_seq);
close(ping_socket);
vTaskDelay(ping_interval * configTICK_RATE_HZ);
}
printf("\n\r[%s] %d packets transmitted, %d received, %d%% packet loss, average %d ms", __FUNCTION__, ping_count, ping_received_count, (ping_count-ping_received_count)*100/ping_count, ping_total_time/ping_received_count);
printf("\n\r[%s] min: %d ms, max: %d ms\n\r", __FUNCTION__, min_time, max_time);
vPortFree(ping_buf);
vPortFree(reply_buf);
vPortFree(host);
if(!ping_call)
vTaskDelete(NULL);
}
void do_ping_call(char *ip, int loop, int count)
{
ping_call = 1;
ping_seq = 0;
data_size = 120;
ping_interval = 1;
infinite_loop = loop;
ping_count = count;
char * host;
host = pvPortMalloc(strlen(ip) + 1);
memset(host, 0, (strlen(ip) + 1));
memcpy(host, ip, strlen(ip));
ping_test(host);
}
int get_ping_report(int *ping_lost){
*ping_lost = ping_count - ping_received_count;
return 0;
}
void cmd_ping(int argc, char **argv)
{
int argv_count = 2;
char * host;
if(argc < 2)
goto Exit;
//ping cmd default value
infinite_loop = 0;
ping_count = 4;
data_size = 32;
ping_interval = 1;
ping_call = 1;
ping_seq = 0;
while(argv_count<=argc){
//first operation
if(argv_count == 2){
host = pvPortMalloc(strlen(argv[argv_count-1]) + 1);
memset(host, 0, (strlen(argv[argv_count-1]) + 1));
strncpy(host, argv[argv_count-1], strlen(argv[argv_count-1]));
argv_count++;
}
else{
if(strcmp(argv[argv_count-1], "-t") == 0){
infinite_loop = 1;
argv_count++;
}
else if(strcmp(argv[argv_count-1], "-n") == 0){
if(argc < (argv_count+1))
goto Exit;
ping_count = (int) atoi(argv[argv_count]);
argv_count+=2;
}
else if(strcmp(argv[argv_count-1], "-l") == 0){
if(argc < (argv_count+1))
goto Exit;
data_size = (int) atoi(argv[argv_count]);
argv_count+=2;
}
else{
goto Exit;
}
}
}
ping_test(host);
return;
Exit:
printf("\n\r[ATWI] Usage: ATWI=[host],[options]\n");
printf("\n\r -t Ping the specified host until stopped\n");
printf(" \r -n # Number of echo requests to send (default 4 times)\n");
printf(" \r -l # Send buffer size (default 32 bytes)\n");
printf("\n\r Example:\n");
printf(" \r ATWI=192.168.1.2,-n,100,-l,5000\n");
return;
}
void do_ping_test(char *ip, int size, int count, int interval)
{
char *host;
if((sizeof(struct icmp_echo_hdr) + size) > BUF_SIZE) {
printf("\n\r%s BUF_SIZE(%d) is too small", __FUNCTION__, BUF_SIZE);
return;
}
if(ip == NULL){
host = pvPortMalloc(strlen(PING_IP) + 1);
memset(host, 0, (strlen(PING_IP) + 1));
strcpy(host, PING_IP);
}
else{
host = pvPortMalloc(strlen(ip) + 1);
memset(host, 0, (strlen(ip) + 1));
strcpy(host, ip);
}
ping_call = 0;
ping_seq = 0;
data_size = size;
ping_interval = interval;
if(count == 0) {
infinite_loop = 1;
ping_count = 0;
}
else {
infinite_loop = 0;
ping_count = count;
}
if(xTaskCreate(ping_test, ((const signed char*)"ping_test"), STACKSIZE, host, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
}

View File

@@ -0,0 +1,71 @@
/******************************************************************************
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
*
******************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include "main.h"
#include "main_test.h"
#if CONFIG_WLAN
#include "wifi_conf.h"
#include "wlan_intf.h"
#include "wifi_constants.h"
#endif
#include "lwip_netconf.h"
#include <platform/platform_stdlib.h>
#ifndef CONFIG_INIT_NET
#define CONFIG_INIT_NET 1
#endif
#ifndef CONFIG_INTERACTIVE_MODE
#define CONFIG_INTERACTIVE_MODE 1
#endif
#define STACKSIZE (512 + 768)
xSemaphoreHandle uart_rx_interrupt_sema = NULL;
void init_thread(void *param)
{
#if CONFIG_INIT_NET
#if CONFIG_LWIP_LAYER
/* Initilaize the LwIP stack */
LwIP_Init();
#endif
#endif
#if CONFIG_WIFI_IND_USE_THREAD
wifi_manager_init();
#endif
#if CONFIG_WLAN
wifi_on(RTW_MODE_STA);
#if CONFIG_AUTO_RECONNECT
//setup reconnection flag
wifi_set_autoreconnect(1);
#endif
printf("\n\r%s(%d), Available heap 0x%x", __FUNCTION__, __LINE__, xPortGetFreeHeapSize());
#endif
#if CONFIG_INTERACTIVE_MODE
/* Initial uart rx swmaphore*/
vSemaphoreCreateBinary(uart_rx_interrupt_sema);
xSemaphoreTake(uart_rx_interrupt_sema, 1/portTICK_RATE_MS);
start_interactive_mode();
#endif
/* Kill init thread after all init tasks done */
vTaskDelete(NULL);
}
void wlan_network()
{
if(xTaskCreate(init_thread, ((const char*)"init"), STACKSIZE, NULL, tskIDLE_PRIORITY + 3 + PRIORITY_OFFSET, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}

View File

@@ -0,0 +1,262 @@
#ifndef __LIST_H
#define __LIST_H
#if defined ( __CC_ARM )
#ifndef inline
#define inline __inline
#endif
#endif
/* This file is from Linux Kernel (include/linux/list.h)
* and modified by simply removing hardware prefetching of list items.
* Here by copyright, credits attributed to wherever they belong.
* Kulesh Shanmugasundaram (kulesh [squiggly] isis.poly.edu)
*/
/*
* Simple doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *newitem,
struct list_head *prev,
struct list_head *next)
{
next->prev = newitem;
newitem->next = next;
newitem->prev = prev;
prev->next = newitem;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *newitem, struct list_head *head)
{
__list_add(newitem, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *newitem, struct list_head *head)
{
__list_add(newitem, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty on entry does not return true after this, the entry is in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = (struct list_head *) 0;
entry->prev = (struct list_head *) 0;
}
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
list_add(list, head);
}
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(struct list_head *head)
{
return head->next == head;
}
static inline void __list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
/**
* list_splice - join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(struct list_head *list, struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head);
}
/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head);
INIT_LIST_HEAD(list);
}
}
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*/
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
/**
* list_first_entry - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_head within the struct.
*
* Note, that list is expected to be not empty.
*/
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); \
pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); \
pos = pos->prev)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop counter.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry(pos, head, member, type) \
for (pos = list_entry((head)->next, type, member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, type, member))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member, type) \
for (pos = list_entry((head)->next, type, member), \
n = list_entry(pos->member.next, type, member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, type, member))
#endif

View File

@@ -0,0 +1,337 @@
/**************************************************
* mktime/localtime wrap for gcc compiler
* port from newlib v3.2.0
**************************************************/
#if defined(__GNUC__)
#include <platform_stdlib.h>
#define SECSPERMIN 60L
#define MINSPERHOUR 60L
#define HOURSPERDAY 24L
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
#define SECSPERDAY (SECSPERHOUR * HOURSPERDAY)
#define DAYSPERWEEK 7
#define MONSPERYEAR 12
#define YEAR_BASE 1900
#define EPOCH_YEAR 1970
#define EPOCH_WDAY 4
#define EPOCH_YEARS_SINCE_LEAP 2
#define EPOCH_YEARS_SINCE_CENTURY 70
#define EPOCH_YEARS_SINCE_LEAP_CENTURY 370
#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
#define EPOCH_ADJUSTMENT_DAYS 719468L
/* year to which the adjustment was made */
#define ADJUSTED_EPOCH_YEAR 0
/* 1st March of year 0 is Wednesday */
#define ADJUSTED_EPOCH_WDAY 3
/* there are 97 leap years in 400-year periods. ((400 - 97) * 365 + 97 * 366) */
#define DAYS_PER_ERA 146097L
/* there are 24 leap years in 100-year periods. ((100 - 24) * 365 + 24 * 366) */
#define DAYS_PER_CENTURY 36524L
/* there is one leap year every 4 years */
#define DAYS_PER_4_YEARS (3 * 365 + 366)
/* number of days in a non-leap year */
#define DAYS_PER_YEAR 365
/* number of days in January */
#define DAYS_IN_JANUARY 31
/* number of days in non-leap February */
#define DAYS_IN_FEBRUARY 28
/* number of years per era */
#define YEARS_PER_ERA 400
#define _SEC_IN_MINUTE 60L
#define _SEC_IN_HOUR 3600L
#define _SEC_IN_DAY 86400L
static const int DAYS_IN_MONTH[12] =
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
#define _DAYS_IN_MONTH(x) ((x == 1) ? days_in_feb : DAYS_IN_MONTH[x])
static const int _DAYS_BEFORE_MONTH[12] =
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
#define _ISLEAP(y) (((y) % 4) == 0 && (((y) % 100) != 0 || (((y)+1900) % 400) == 0))
#define _DAYS_IN_YEAR(year) (_ISLEAP(year) ? 366 : 365)
struct tm *
gmtime_r (const time_t *__restrict tim_p,
struct tm *__restrict res)
{
long days, rem;
const time_t lcltime = *tim_p;
int era, weekday, year;
unsigned erayear, yearday, month, day;
unsigned long eraday;
days = lcltime / SECSPERDAY + EPOCH_ADJUSTMENT_DAYS;
rem = lcltime % SECSPERDAY;
if (rem < 0)
{
rem += SECSPERDAY;
--days;
}
/* compute hour, min, and sec */
res->tm_hour = (int) (rem / SECSPERHOUR);
rem %= SECSPERHOUR;
res->tm_min = (int) (rem / SECSPERMIN);
res->tm_sec = (int) (rem % SECSPERMIN);
/* compute day of week */
if ((weekday = ((ADJUSTED_EPOCH_WDAY + days) % DAYSPERWEEK)) < 0)
weekday += DAYSPERWEEK;
res->tm_wday = weekday;
/* compute year, month, day & day of year */
/* for description of this algorithm see
* http://howardhinnant.github.io/date_algorithms.html#civil_from_days */
era = (days >= 0 ? days : days - (DAYS_PER_ERA - 1)) / DAYS_PER_ERA;
eraday = days - era * DAYS_PER_ERA; /* [0, 146096] */
erayear = (eraday - eraday / (DAYS_PER_4_YEARS - 1) + eraday / DAYS_PER_CENTURY -
eraday / (DAYS_PER_ERA - 1)) / 365; /* [0, 399] */
yearday = eraday - (DAYS_PER_YEAR * erayear + erayear / 4 - erayear / 100); /* [0, 365] */
month = (5 * yearday + 2) / 153; /* [0, 11] */
day = yearday - (153 * month + 2) / 5 + 1; /* [1, 31] */
month += month < 10 ? 2 : -10;
year = ADJUSTED_EPOCH_YEAR + erayear + era * YEARS_PER_ERA + (month <= 1);
res->tm_yday = yearday >= DAYS_PER_YEAR - DAYS_IN_JANUARY - DAYS_IN_FEBRUARY ?
yearday - (DAYS_PER_YEAR - DAYS_IN_JANUARY - DAYS_IN_FEBRUARY) :
yearday + DAYS_IN_JANUARY + DAYS_IN_FEBRUARY + isleap(erayear);
res->tm_year = year - YEAR_BASE;
res->tm_mon = month;
res->tm_mday = day;
res->tm_isdst = 0;
return (res);
}
struct tm * __wrap_localtime (const time_t * tim_p)
{
struct _reent *reent = _REENT;
_REENT_CHECK_TM(reent);
return gmtime_r (tim_p, (struct tm *)_REENT_TM(reent));
}
static void
validate_structure (struct tm *tim_p)
{
div_t res;
int days_in_feb = 28;
/* calculate time & date to account for out of range values */
if (tim_p->tm_sec < 0 || tim_p->tm_sec > 59)
{
res = div (tim_p->tm_sec, 60);
tim_p->tm_min += res.quot;
if ((tim_p->tm_sec = res.rem) < 0)
{
tim_p->tm_sec += 60;
--tim_p->tm_min;
}
}
if (tim_p->tm_min < 0 || tim_p->tm_min > 59)
{
res = div (tim_p->tm_min, 60);
tim_p->tm_hour += res.quot;
if ((tim_p->tm_min = res.rem) < 0)
{
tim_p->tm_min += 60;
--tim_p->tm_hour;
}
}
if (tim_p->tm_hour < 0 || tim_p->tm_hour > 23)
{
res = div (tim_p->tm_hour, 24);
tim_p->tm_mday += res.quot;
if ((tim_p->tm_hour = res.rem) < 0)
{
tim_p->tm_hour += 24;
--tim_p->tm_mday;
}
}
if (tim_p->tm_mon < 0 || tim_p->tm_mon > 11)
{
res = div (tim_p->tm_mon, 12);
tim_p->tm_year += res.quot;
if ((tim_p->tm_mon = res.rem) < 0)
{
tim_p->tm_mon += 12;
--tim_p->tm_year;
}
}
if (_DAYS_IN_YEAR (tim_p->tm_year) == 366)
days_in_feb = 29;
if (tim_p->tm_mday <= 0)
{
while (tim_p->tm_mday <= 0)
{
if (--tim_p->tm_mon == -1)
{
tim_p->tm_year--;
tim_p->tm_mon = 11;
days_in_feb =
((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ?
29 : 28);
}
tim_p->tm_mday += _DAYS_IN_MONTH (tim_p->tm_mon);
}
}
else
{
while (tim_p->tm_mday > _DAYS_IN_MONTH (tim_p->tm_mon))
{
tim_p->tm_mday -= _DAYS_IN_MONTH (tim_p->tm_mon);
if (++tim_p->tm_mon == 12)
{
tim_p->tm_year++;
tim_p->tm_mon = 0;
days_in_feb =
((_DAYS_IN_YEAR (tim_p->tm_year) == 366) ?
29 : 28);
}
}
}
}
time_t __wrap_mktime (struct tm *tim_p)
{
time_t tim = 0;
long days = 0;
int year, isdst=0;
__tzinfo_type *tz = __gettzinfo ();
/* validate structure */
validate_structure (tim_p);
/* compute hours, minutes, seconds */
tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) +
(tim_p->tm_hour * _SEC_IN_HOUR);
/* compute days in year */
days += tim_p->tm_mday - 1;
days += _DAYS_BEFORE_MONTH[tim_p->tm_mon];
if (tim_p->tm_mon > 1 && _DAYS_IN_YEAR (tim_p->tm_year) == 366)
days++;
/* compute day of the year */
tim_p->tm_yday = days;
if (tim_p->tm_year > 10000 || tim_p->tm_year < -10000)
return (time_t) -1;
/* compute days in other years */
if ((year = tim_p->tm_year) > 70)
{
for (year = 70; year < tim_p->tm_year; year++)
days += _DAYS_IN_YEAR (year);
}
else if (year < 70)
{
for (year = 69; year > tim_p->tm_year; year--)
days -= _DAYS_IN_YEAR (year);
days -= _DAYS_IN_YEAR (year);
}
/* compute total seconds */
tim += (time_t)days * _SEC_IN_DAY;
if (_daylight)
{
int tm_isdst;
int y = tim_p->tm_year + YEAR_BASE;
/* Convert user positive into 1 */
tm_isdst = tim_p->tm_isdst > 0 ? 1 : tim_p->tm_isdst;
isdst = tm_isdst;
if (y == tz->__tzyear || __tzcalc_limits (y))
{
/* calculate start of dst in dst local time and
start of std in both std local time and dst local time */
time_t startdst_dst = tz->__tzrule[0].change
- (time_t) tz->__tzrule[1].offset;
time_t startstd_dst = tz->__tzrule[1].change
- (time_t) tz->__tzrule[1].offset;
time_t startstd_std = tz->__tzrule[1].change
- (time_t) tz->__tzrule[0].offset;
/* if the time is in the overlap between dst and std local times */
if (tim >= startstd_std && tim < startstd_dst)
; /* we let user decide or leave as -1 */
else
{
isdst = (tz->__tznorth
? (tim >= startdst_dst && tim < startstd_std)
: (tim >= startdst_dst || tim < startstd_std));
/* if user committed and was wrong, perform correction, but not
* if the user has given a negative value (which
* asks mktime() to determine if DST is in effect or not) */
if (tm_isdst >= 0 && (isdst ^ tm_isdst) == 1)
{
/* we either subtract or add the difference between
time zone offsets, depending on which way the user got it
wrong. The diff is typically one hour, or 3600 seconds,
and should fit in a 16-bit int, even though offset
is a long to accomodate 12 hours. */
int diff = (int) (tz->__tzrule[0].offset
- tz->__tzrule[1].offset);
if (!isdst)
diff = -diff;
tim_p->tm_sec += diff;
tim += diff; /* we also need to correct our current time calculation */
int mday = tim_p->tm_mday;
validate_structure (tim_p);
mday = tim_p->tm_mday - mday;
/* roll over occurred */
if (mday) {
/* compensate for month roll overs */
if (mday > 1)
mday = -1;
else if (mday < -1)
mday = 1;
/* update days for wday calculation */
days += mday;
/* handle yday */
if ((tim_p->tm_yday += mday) < 0) {
--year;
tim_p->tm_yday = _DAYS_IN_YEAR(year) - 1;
} else {
mday = _DAYS_IN_YEAR(year);
if (tim_p->tm_yday > (mday - 1))
tim_p->tm_yday -= mday;
}
}
}
}
}
}
/* add appropriate offset to put time in gmt format */
if (isdst == 1)
tim += (time_t) tz->__tzrule[1].offset;
else /* otherwise assume std time */
tim += (time_t) tz->__tzrule[0].offset;
/* reset isdst flag to what we have calculated */
tim_p->tm_isdst = isdst;
/* compute day of the week */
if ((tim_p->tm_wday = (days + 4) % 7) < 0)
tim_p->tm_wday += 7;
return tim;
}
#endif

View File

@@ -0,0 +1,265 @@
/******************************************************************************
*
* Copyright(c) 2007 - 2014 Realtek Corporation. All rights reserved.
*
*
******************************************************************************/
#ifndef __PLATFORM_STDLIB_H__
#define __PLATFORM_STDLIB_H__
#define USE_CLIB_PATCH 0
#if defined (__GNUC__)
/* build rom should set USE_RTL_ROM_CLIB=0 */
#include <rt_lib_rom.h>
#endif
#ifdef CONFIG_BUILD_ROM
#define USE_RTL_ROM_CLIB 0
#else
#define BUFFERED_PRINTF 0
#define USE_RTL_ROM_CLIB 1
#endif
#if defined(CONFIG_PLATFORM_8195A)
#if defined (__IARSTDLIB__)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "diag.h"
#define strsep(str, delim) _strsep(str, delim)
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "diag.h"
#include "strproc.h"
#include "basic_types.h"
#include "hal_misc.h"
#if USE_RTL_ROM_CLIB
#include "rtl_lib.h"
#endif
#undef printf
#undef sprintf
#undef snprintf
#undef atoi
#undef memcmp
#undef memcpy
#undef memset
#undef strcmp
#undef strcpy
#undef strlen
#undef strncmp
#undef strncpy
#undef strsep
#undef strtok
#if USE_RTL_ROM_CLIB
#undef memchr
#undef memmove
#undef strcat
#undef strchr
#undef strncat
#undef strstr
#endif
#if USE_RTL_ROM_CLIB
#if BUFFERED_PRINTF
extern int buffered_printf(const char* fmt, ...);
#define printf buffered_printf
#else
#define printf rtl_printf
#endif
#define sprintf rtl_sprintf
#define snprintf rtl_snprintf
#define memchr rtl_memchr
#define memcmp rtl_memcmp
#define memcpy rtl_memcpy
#define memmove rtl_memmove
#define memset rtl_memset
#define strcat rtl_strcat
#define strchr rtl_strchr
#define strcmp(s1, s2) rtl_strcmp((const char *)s1, (const char *)s2)
#define strcpy rtl_strcpy
#define strlen(str) rtl_strlen((const char *)str)
#define strncat rtl_strncat
#define strncmp(s1, s2, n) rtl_strncmp((const char *)s1, (const char *)s2, n)
#define strncpy rtl_strncpy
#define strstr rtl_strstr
#define strsep rtl_strsep
#define strtok rtl_strtok
#else
#if USE_CLIB_PATCH
extern int DiagSscanfPatch(const char *buf, const char *fmt, ...);
extern char* DiagStrtokPatch(char *str, const char* delim);
extern char* DiagStrstrPatch(char *string, char *substring);
extern int DiagSnPrintfPatch(char *buf, size_t size, const char *fmt, ...);
extern u32 DiagPrintfPatch(const char *fmt, ...);
extern u32 DiagSPrintfPatch(u8 *buf, const char *fmt, ...);
#define printf DiagPrintfPatch
#define sprintf DiagSPrintfPatch
#define snprintf DiagSnPrintfPatch
#define strstr(a, b) DiagStrstrPatch((char *)(a), (char *)(b))
#define strtok DiagStrtokPatch
#else
#define printf DiagPrintf
#define sprintf(fmt, arg...) DiagSPrintf((u8*)fmt, ##arg)
#if defined (__GNUC__)
#define snprintf DiagSnPrintf // NULL function
#define strstr(str1, str2) prvStrStr(str1, str2) // NULL function
#endif
#define strtok(str, delim) _strsep(str, delim)
#endif
#define memcmp(dst, src, sz) _memcmp(dst, src, sz)
#define memcpy(dst, src, sz) _memcpy(dst, src, sz)
#define memset(dst, val, sz) _memset(dst, val, sz)
#define strchr(s, c) _strchr(s, c) // for B-cut ROM
#define strcmp(str1, str2) prvStrCmp((const unsigned char *) str1, (const unsigned char *) str2)
#define strcpy(dest, src) _strcpy(dest, src)
#define strlen(str) prvStrLen((const unsigned char *) str)
#define strncmp(str1, str2, cnt) _strncmp(str1, str2, cnt)
#define strncpy(dest, src, count) _strncpy(dest, src, count)
#define strsep(str, delim) _strsep(str, delim)
#endif
#define atoi(str) prvAtoi(str)
#define strpbrk(cs, ct) _strpbrk(cs, ct) // for B-cut ROM
#if USE_CLIB_PATCH
#undef sscanf
#define sscanf DiagSscanfPatch
#else
#if defined (__GNUC__)
#undef sscanf //_sscanf
//extern int DiagSscanfPatch(const char *buf, const char *fmt, ...);
//#define sscanf DiagSscanfPatch
#define sscanf sscanf // use libc sscanf
#endif
#endif
#endif // defined (__IARSTDLIB__)
//
// memory management
//
extern void *pvPortMalloc( size_t xWantedSize );
extern void vPortFree( void *pv );
#define malloc pvPortMalloc
#define free vPortFree
#elif defined (CONFIG_PLATFORM_8711B)
#if defined (__IARSTDLIB__)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdarg.h> /* va_list */
#include "diag.h"
#define strsep(str, delim) _strsep(str, delim)
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h> /* va_list */
#include "diag.h"
#include "strproc.h"
#include "memproc.h"
#include "basic_types.h"
#if USE_RTL_ROM_CLIB
#include "rtl_lib.h"
#include "rom_libc_string.h"
#endif
#undef printf
#undef sprintf
#undef snprintf
#undef memchr
#undef memcmp
#undef memcpy
#undef memset
#undef memmove
#undef strcmp
#undef strcpy
#undef strlen
#undef strncmp
#undef strncpy
#undef strsep
#undef strtok
#undef strcat
#undef strchr
#undef strncat
#undef strstr
#undef atol
#undef atoi
#undef strpbrk
#if USE_RTL_ROM_CLIB
#if BUFFERED_PRINTF
extern int buffered_printf(const char* fmt, ...);
#define printf buffered_printf
#else
#define printf rtl_printf
#endif
#define sprintf rtl_sprintf
#define snprintf rtl_snprintf
#define vsnprintf rtl_vsnprintf
#else
#define printf DiagPrintf
#define sprintf(fmt, arg...) DiagSPrintf((u8*)fmt, ##arg)
#define snprintf DiagSnPrintf // NULL function
#define vsnprintf(buf, size, fmt, ap) VSprintf(buf, fmt, ap)
#endif
#define memchr __rtl_memchr_v1_00
#define memcmp(dst, src, sz) _memcmp(dst, src, sz)
#define memcpy(dst, src, sz) _memcpy(dst, src, sz)
#define memmove __rtl_memmove_v1_00
#define memset(dst, val, sz) _memset(dst, val, sz)
#define strchr(s, c) _strchr(s, c) // for B-cut ROM
#define strcmp(str1, str2) prvStrCmp((const unsigned char *) str1, (const unsigned char *) str2)
#define strcpy(dest, src) _strcpy(dest, src)
#define strlen(str) prvStrLen((const unsigned char *) str)
#define strsep(str, delim) _strsep(str, delim)
#define strstr(str1, str2) prvStrStr(str1, str2) // NULL function
#define strtok(str, delim) prvStrtok(str, delim)//_strsep(str, delim)
#define strcat __rtl_strcat_v1_00
#define strncmp(str1, str2, cnt) _strncmp(str1, str2, cnt)
#define strncpy(dest, src, count) _strncpy(dest, src, count)
#define strncat __rtl_strncat_v1_00
#define atol(str) strtol(str,NULL,10)
#define atoi(str) prvAtoi(str)
#define strpbrk(cs, ct) _strpbrk(cs, ct) // for B-cut ROM
#if defined (__GNUC__)
#undef sscanf
#define sscanf _sscanf_patch
#define rand Rand
#endif
//extern int _sscanf_patch(const char *buf, const char *fmt, ...);
//#define sscanf _sscanf_patch
#endif // defined (__IARSTDLIB__)
//
// memory management
//
extern void *pvPortMalloc( size_t xWantedSize );
extern void vPortFree( void *pv );
extern void* pvPortReAlloc( void *pv, size_t xWantedSize );
#define malloc pvPortMalloc
#define free vPortFree
#define realloc pvPortReAlloc
#elif defined(USE_STM322xG_EVAL) || defined(USE_STM324xG_EVAL) || defined(STM32F10X_XL)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#endif
#endif //__PLATFORM_STDLIB_H__

View File

@@ -0,0 +1,918 @@
/*
this is the c lib patch, It can help when the clib provided by IAR
does not work well.
How to use this:
1.You must include platform_stdlib.h in you source file。
2.There is a macro USE_CLIB_PATCH in platform_stdlib.h should be opened.
If there is some problems using this patch,
You'd better check if you code runs into these functions:
DiagSscanfPatch
DiagStrtokPatch
DiagStrstrPatch
DiagSnPrintfPatch
DiagPrintfPatch
DiagSPrintfPatch
DiagPrintfPatch
DiagSPrintfPatch
DiagSnPrintfPatch
DiagStrstrPatch
DiagStrtokPatch
*/
#ifndef CONFIG_PLATFORM_8711B
#include <stdarg.h>
#define DiagPutChar HalSerialPutcRtl8195a
#define IN
#define NULL 0
typedef unsigned int size_t;
typedef unsigned int SIZE_T;
typedef unsigned long long u64;
typedef unsigned int u32;
typedef unsigned short int u16;
typedef unsigned char u8;
typedef signed long long s64;
typedef signed int s32;
typedef signed short int s16;
typedef unsigned char bool;
#define in_range(c, lo, up) ((u8)c >= lo && (u8)c <= up)
#define isprint(c) in_range(c, 0x20, 0x7f)
#define isdigit(c) in_range(c, '0', '9')
#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F'))
#define islower(c) in_range(c, 'a', 'z')
#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == ',')
#define ULLONG_MAX (~0ULL)
#define USHRT_MAX ((u16)(~0U))
#define KSTRTOX_OVERFLOW (1U << 31)
#define SHRT_MAX ((s16)(USHRT_MAX>>1))
static inline char _tolower(const char c)
{
return c | 0x20;
}
extern s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder);
extern s64 div_s64(s64 dividend, s32 divisor);
extern inline char _tolower(const char c);
extern u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder);
extern u64 div_u64(u64 dividend, u32 divisor);
extern unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p);
extern const char *_parse_integer_fixup_radix(const char *s, unsigned int *base);
extern char *skip_spaces(const char *str);
extern int skip_atoi(const char **s);
extern void HalSerialPutcRtl8195a(u8 c);
static unsigned long long simple_strtoull_patch(const char *cp, char **endp, unsigned int base)
{
unsigned long long result;
unsigned int rv;
cp = _parse_integer_fixup_radix(cp, &base);
rv = _parse_integer(cp, base, &result);
return result;
}
static long long simple_strtoll_patch(const char *cp, char **endp, unsigned int base)
{
if(*cp == '-')
return -simple_strtoull_patch(cp + 1, endp, base);
return simple_strtoull_patch(cp, endp, base);
}
static unsigned long simple_strtoul_patch(const char *cp, char **endp, unsigned int base)
{
return simple_strtoull_patch(cp, endp, base);
}
static long simple_strtol_patch(const char *cp, char **endp, unsigned int base)
{
if(*cp == '-')
return -simple_strtoul_patch(cp + 1, endp, base);
return simple_strtoul_patch(cp, endp, base);
}
static int judge_digit_width(const char *str)
{
int width = 0;
while(isdigit(*str)) {
width++;
str++;
}
return width;
}
static int _vsscanf_patch(const char *buf, const char *fmt, va_list args)
{
const char *str = buf;
char *next;
char digit;
int num = 0;
int i =0;
u8 qualifier;
unsigned int base;
union {
long long s;
unsigned long long u;
} val;
s16 field_width;
bool is_sign;
char str_store[20] = {0};
while(*fmt) {
/* skip any white space in format */
/* white space in format matchs any amount of
* white space, including none, in the input.
*/
if(isspace(*fmt)) {
fmt = skip_spaces(++fmt);
str = skip_spaces(str);
}
/* anything that is not a conversion must match exactly */
if(*fmt != '%' && *fmt) {
if(*fmt++ != *str++) {
break;
}
continue;
}
if(!*fmt) {
break;
}
++fmt;
/* skip this conversion.
* advance both strings to next white space
*/
if(*fmt == '*') {
if(!*str) {
break;
}
while(!isspace(*fmt) && *fmt != '%' && *fmt)
fmt++;
while(!isspace(*str) && *str)
str++;
continue;
}
/* get field width */
field_width = -1;
if(isdigit(*fmt)) {
field_width = skip_atoi(&fmt);
if(field_width <= 0) {
break;
}
}
/* get conversion qualifier */
qualifier = -1;
if(*fmt == 'h' || _tolower(*fmt) == 'l' ||
_tolower(*fmt) == 'z') {
qualifier = *fmt++;
if(qualifier == *fmt) {
if(qualifier == 'h') {
qualifier = 'H';
fmt++;
} else if(qualifier == 'l') {
qualifier = 'L';
fmt++;
}
}
}
if(!*fmt) {
break;
}
if(*fmt == 'n') {
/* return number of characters read so far */
*va_arg(args, int *) = str - buf;
++fmt;
continue;
}
if(!*str) {
break;
}
base = 10;
is_sign = 0;
switch(*fmt++) {
case 'c': {
char *s = (char *)va_arg(args, char*);
if(field_width == -1)
field_width = 1;
do {
*s++ = *str++;
} while(--field_width > 0 && *str);
num++;
}
continue;
case 's': {
char *s = (char *)va_arg(args, char *);
if(field_width == -1)
field_width = SHRT_MAX;
/* first, skip leading white space in buffer */
str = skip_spaces(str);
/* now copy until next white space */
while(*str && !isspace(*str) && field_width--) {
*s++ = *str++;
}
*s = '\0';
num++;
}
continue;
case 'o':
base = 8;
break;
case 'x':
case 'X':
base = 16;
break;
case 'i':
base = 0;
case 'd':
is_sign = 1;
case 'u':
break;
case '%':
/* looking for '%' in str */
if(*str++ != '%') {
return num;
}
continue;
default:
/* invalid format; stop here */
return num;
}
/* have some sort of integer conversion.
* first, skip white space in buffer.
*/
str = skip_spaces(str);
digit = *str;
if(is_sign && digit == '-')
digit = *(str + 1);
if(!digit
|| (base == 16 && !isxdigit(digit))
|| (base == 10 && !isdigit(digit))
|| (base == 8 && (!isdigit(digit) || digit > '7'))
|| (base == 0 && !isdigit(digit))) {
break;
}
//here problem *******************************************
//troy add ,fix support %2d, but not support %d
if(field_width <= 0) {
field_width = judge_digit_width(str);
}
/////troy add, fix str passed inwidth wrong
for(i = 0; i<field_width ; i++)
str_store[i] = str[i];
next = (char*)str + field_width;
if(is_sign) {
val.s = qualifier != 'L' ?
simple_strtol_patch(str_store, &next, base) :
simple_strtoll_patch(str_store, &next, base);
} else {
val.u = qualifier != 'L' ?
simple_strtoul_patch(str_store, &next, base) :
simple_strtoull_patch(str_store, &next, base);
}
////troy add
for(i = 0; i<20 ; i++)
str_store[i] = 0;
//判断转换的字符串的宽度是否大于 %2d
if(field_width > 0 && next - str > field_width) {
if(base == 0)
_parse_integer_fixup_radix(str, &base);
while(next - str > field_width) {
if(is_sign) {
val.s = div_s64(val.s, base);
} else {
val.u = div_u64(val.u, base);
}
--next;
}
}
switch(qualifier) {
case 'H': /* that's 'hh' in format */
if(is_sign)
*va_arg(args, signed char *) = val.s;
else
*va_arg(args, unsigned char *) = val.u;
break;
case 'h':
if(is_sign)
*va_arg(args, short *) = val.s;
else
*va_arg(args, unsigned short *) = val.u;
break;
case 'l':
if(is_sign)
*va_arg(args, long *) = val.s;
else
*va_arg(args, unsigned long *) = val.u;
break;
case 'L':
if(is_sign)
*va_arg(args, long long *) = val.s;
else
*va_arg(args, unsigned long long *) = val.u;
break;
case 'Z':
case 'z':
*va_arg(args, size_t *) = val.u;
break;
default:
if(is_sign)
*va_arg(args, int *) = val.s;
else
*va_arg(args, unsigned int *) = val.u;
break;
}
num++;
if(!next) {
break;
}
str = next;
}
return num;
}
int DiagSscanfPatch(const char *buf, const char *fmt, ...)
{
va_list args;
int i;
va_start(args, fmt);
i = _vsscanf_patch(buf, fmt, args);
va_end(args);
return i;
}
/*********************************************************/
char* DiagStrtokPatch(char *str, const char* delim) {
static char* _buffer;
if(str != NULL) _buffer = str;
if(_buffer[0] == '\0') return NULL;
char *ret = _buffer, *b;
const char *d;
for(b = _buffer; *b !='\0'; b++) {
for(d = delim; *d != '\0'; d++) {
if(*b == *d) {
*b = '\0';
_buffer = b+1;
// skip the beginning delimiters
if(b == ret) {
ret++;
continue;
}
return ret;
}
}
}
return ret;
}
/*********************************************************/
char *DiagStrstrPatch(char *string, char *substring)
{
register char *a, *b;
/* First scan quickly through the two strings looking for a
* single-character match. When it's found, then compare the
* rest of the substring.
*/
b = substring;
if(*b == 0) {
return string;
}
for(; *string != 0; string += 1) {
if(*string != *b) {
continue;
}
a = string;
while(1) {
if(*b == 0) {
return string;
}
if(*a++ != *b++) {
break;
}
}
b = substring;
}
return (char *) 0;
}
/*********************************************************/
int DiagSnPrintfPatch(char *buf, size_t size, const char *fmt, ...)
{
va_list ap;
char *p, *s, *buf_end = NULL;
const int *dp = ((const int *)&fmt)+1;
if(buf == NULL)
return 0;
va_start(ap, fmt);
s = buf;
buf_end = size? (buf + size):(char*)~0;
for(; *fmt != '\0'; ++fmt) {
if(*fmt != '%') {
*s++ = *fmt;
if(s >= buf_end) {
goto Exit;
}
continue;
}
if(*++fmt == 's') {
for(p = (char *)*dp++; *p != '\0'; p++) {
*s++ = *p;
if(s >= buf_end) {
goto Exit;
}
}
}
else { /* Length of item is bounded */
char tmp[20], *q = tmp;
int alt = 0;
int shift = 0;// = 12;
const long *lpforchk = (const long *)dp;
if((*lpforchk) < 0x10) {
shift = 0;
}
else if(((*lpforchk) >= 0x10) && ((*lpforchk) < 0x100)) {
shift = 4;
}
else if(((*lpforchk) >= 0x100) && ((*lpforchk) < 0x1000)) {
shift = 8;
}
else if(((*lpforchk) >= 0x1000) && ((*lpforchk) < 0x10000)) {
shift = 12;
}
else if(((*lpforchk) >= 0x10000) && ((*lpforchk) < 0x100000)) {
shift = 16;
}
else if(((*lpforchk) >= 0x100000) && ((*lpforchk) < 0x1000000)) {
shift = 20;
}
else if(((*lpforchk) >= 0x1000000) && ((*lpforchk) < 0x10000000)) {
shift = 24;
}
else if((*lpforchk) >= 0x10000000) {
shift = 28;
}
else {
shift = 28;
}
if((*fmt >= '0') && (*fmt <= '9'))
{
int width;
unsigned char fch = *fmt;
for(width=0; (fch>='0') && (fch<='9'); fch=*++fmt)
{ width = width * 10 + fch - '0';
}
shift=(width-1)*4;
}
/*
* Before each format q points to tmp buffer
* After each format q points past end of item
*/
if((*fmt == 'x')||(*fmt == 'X') || (*fmt == 'p') || (*fmt == 'P')) {
/* With x86 gcc, sizeof(long) == sizeof(int) */
const long *lp = (const long *)dp;
long h = *lp++;
int hex_count = 0;
unsigned long h_back = h;
int ncase = (*fmt & 0x20);
dp = (const int *)lp;
if((*fmt == 'p') || (*fmt == 'P'))
alt=1;
if(alt) {
*q++ = '0';
*q++ = 'X' | ncase;
}
while(h_back) {
hex_count += (h_back & 0xF) ? 1 : 0;
h_back = h_back >> 4;
}
if(shift < (hex_count - 1)*4)
shift = (hex_count - 1)*4;
for(; shift >= 0; shift -= 4)
*q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase;
}
else if(*fmt == 'd') {
int i = *dp++;
char *r;
int digit_space = 0;
if(i < 0) {
*q++ = '-';
i = -i;
digit_space++;
}
p = q; /* save beginning of digits */
do {
*q++ = '0' + (i % 10);
i /= 10;
digit_space++;
} while(i);
for(; shift >= 0; shift -= 4) {
if(digit_space-- > 0) {
; //do nothing
} else {
*q++ = '0';
}
}
/* reverse digits, stop in middle */
r = q; /* don't alter q */
while(--r > p) {
i = *r;
*r = *p;
*p++ = i;
}
}
else if(*fmt == 'c')
*q++ = *dp++;
else
*q++ = *fmt;
/* now output the saved string */
for(p = tmp; p < q; ++p) {
*s++ = *p;
if(s >= buf_end) {
goto Exit;
}
}
}
}
Exit:
if(buf)
*s = '\0';
va_end(ap);
return(s-buf);
}
/*********************************************************/
static int VSprintfPatch(char *buf, const char *fmt, const int *dp)
{
char *p, *s;
s = buf;
for(; *fmt != '\0'; ++fmt) {
if(*fmt != '%') {
if(buf) {
*s++ = *fmt;
} else {
DiagPutChar(*fmt);
}
continue;
}
if(*++fmt == 's') {
for(p = (char *)*dp++; *p != '\0'; p++) {
if(buf) {
*s++ = *p;
} else {
DiagPutChar(*p);
}
}
}
else { /* Length of item is bounded */
char tmp[20], *q = tmp;
int alt = 0;
int shift = 0;// = 12;
const long *lpforchk = (const long *)dp;
if((*lpforchk) < 0x10) {
shift = 0;
}
else if(((*lpforchk) >= 0x10) && ((*lpforchk) < 0x100)) {
shift = 4;
}
else if(((*lpforchk) >= 0x100) && ((*lpforchk) < 0x1000)) {
shift = 8;
}
else if(((*lpforchk) >= 0x1000) && ((*lpforchk) < 0x10000)) {
shift = 12;
}
else if(((*lpforchk) >= 0x10000) && ((*lpforchk) < 0x100000)) {
shift = 16;
}
else if(((*lpforchk) >= 0x100000) && ((*lpforchk) < 0x1000000)) {
shift = 20;
}
else if(((*lpforchk) >= 0x1000000) && ((*lpforchk) < 0x10000000)) {
shift = 24;
}
else if((*lpforchk) >= 0x10000000) {
shift = 28;
}
else {
shift = 28;
}
#if 1 //wei patch for %02x
if((*fmt >= '0') && (*fmt <= '9'))
{
int width;
unsigned char fch = *fmt;
for(width=0; (fch>='0') && (fch<='9'); fch=*++fmt)
{ width = width * 10 + fch - '0';
}
shift=(width-1)*4;
}
#endif
/*
* Before each format q points to tmp buffer
* After each format q points past end of item
*/
if((*fmt == 'x')||(*fmt == 'X') || (*fmt == 'p') || (*fmt == 'P')) {
/* With x86 gcc, sizeof(long) == sizeof(int) */
const long *lp = (const long *)dp;
long h = *lp++;
int hex_count = 0;
unsigned long h_back = h;
int ncase = (*fmt & 0x20);
dp = (const int *)lp;
if((*fmt == 'p') || (*fmt == 'P'))
alt=1;
if(alt) {
*q++ = '0';
*q++ = 'X' | ncase;
}
//hback 是实际得到的数据hex_count是统计数据的HEX字符个数
while(h_back) {
hex_count += (h_back & 0xF) ? 1 : 0;
h_back = h_back >> 4;
}
//这里修复 example 字符有4个但是用了%02x导致字符被截断的情况
if(shift < (hex_count - 1)*4)
shift = (hex_count - 1)*4;
//printf("(%d,%d)", hex_count, shift);
for(; shift >= 0; shift -= 4) {
*q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase;
}
}
else if(*fmt == 'd') {
int i = *dp++;
char *r;
int digit_space = 0;
if(i < 0) {
*q++ = '-';
i = -i;
digit_space++;
}
p = q; /* save beginning of digits */
do {
*q++ = '0' + (i % 10);
i /= 10;
digit_space++;
} while(i);
//这里修复 example用了%08d后在数字前面没有0的情况
for(; shift >= 0; shift -= 4) {
if(digit_space-- > 0) {
; //do nothing
} else {
*q++ = '0';
}
}
/* reverse digits, stop in middle */
r = q; /* don't alter q */
while(--r > p) {
i = *r;
*r = *p;
*p++ = i;
}
}
else if(*fmt == 'c')
*q++ = *dp++;
else
*q++ = *fmt;
/* now output the saved string */
for(p = tmp; p < q; ++p) {
if(buf) {
*s++ = *p;
} else {
DiagPutChar(*p);
}
if((*p) == '\n') {
DiagPutChar('\r');
}
}
}
}
if(buf)
*s = '\0';
return (s - buf);
}
u32 DiagPrintfPatch(
IN const char *fmt, ...
)
{
(void)VSprintfPatch(0, fmt, ((const int *)&fmt)+1);
return 1;
}
u32 DiagSPrintfPatch(
IN u8 *buf,
IN const char *fmt, ...
)
{
(void)VSprintfPatch((char*)buf, fmt, ((const int *)&fmt)+1);
return 1;
}
#endif

View File

@@ -0,0 +1,7 @@
#ifndef _TIME_64_GCC_H
#define _TIME_64_GCC_H
#define __time_t_defined
#define time_t long long
#endif //_TIME_64_GCC_H

View File

@@ -0,0 +1,149 @@
#include <PinNames.h>
#include <pinmap.h>
#include <gpio_api.h>
#include <wifi_wowlan.h>
#include <freertos_pmu.h>
#include <wifi_conf.h>
#define CONFIG_WOWLAN_DEV_NT96658 //build for Nova NT96658
//#define CONFIG_WOWLAN_DEV_OV788 //build for OmniVision OV788
#if defined(CONFIG_WOWLAN_DEV_NT96658) && defined(CONFIG_WOWLAN_DEV_OV788)
#error "CONFIG_WOWLAN_DEV_NT96658 and CONFIG_WOWLAN_DEV_OV788 are mutually exclusive. "
#endif
#ifdef CONFIG_WOWLAN_DEV_NT96658
#define WOW_WIFI_IN_PIN PE_4 //JTAG pin, so JTAG must be disable before using this pin as wakeup pin
#define WOW_TRIGGER_INTERVAL 500
#elif defined(CONFIG_WOWLAN_DEV_OV788)
#define WOW_WIFI_IN_PIN PD_5
#define WOW_WLAN_ON_PIN PB_3
#define WOW_TRIGGER_INTERVAL 200
#else
#error "Either CONFIG_WOWLAN_DEV_NT96658 or CONFIG_WOWLAN_DEV_OV788 should be defined, but not both. "
#endif
//pin assignment for SDIO, default pull high
#define SD_D2 PA_0
#define SD_D3 PA_1
#define SD_CMD PA_2
#define SD_CLK PA_3
#define SD_D0 PA_4
#define SD_D1 PA_5
#define SD_CD PA_6
gpio_t wow_gpio_wifi_in; //WOWLAN WAKEUP TRIGGER PORT
gpio_t wow_gpio_wlan_on; //RECORD WOWLAN STATUS: 1:OFF, 0:ON
int dev_wowlan_init(void){
WOWLAN_PRINTK("WOWLAN: device init!");
#ifdef CONFIG_WOWLAN_DEV_OV788
// Initial WLAN_ON pin
gpio_init(&wow_gpio_wlan_on, WOW_WLAN_ON_PIN);
gpio_dir(&wow_gpio_wlan_on, PIN_OUTPUT);
gpio_mode(&wow_gpio_wlan_on, PullNone);
gpio_write(&wow_gpio_wlan_on, 1);
#endif
return 0;
}
int dev_wowlan_enable(void){
WOWLAN_PRINTK("WOWLAN: device enable!");
// Init WIFI_IN pin (wakeup pin)
gpio_init(&wow_gpio_wifi_in, WOW_WIFI_IN_PIN);
gpio_dir(&wow_gpio_wifi_in, PIN_OUTPUT);
gpio_mode(&wow_gpio_wifi_in, PullNone);
gpio_write(&wow_gpio_wifi_in, 0);
#ifdef CONFIG_WOWLAN_DEV_OV788
gpio_write(&wow_gpio_wlan_on, 0);
#endif
#if CONFIG_WLAN
wifi_set_power_mode(0xff, 1);
#endif
return 0;
}
int dev_wowlan_wakeup_process(void){
WOWLAN_PRINTK("WOWLAN: device wake up!");
#if defined(CONFIG_WOWLAN_DEV_NT96658) || defined(CONFIG_WOWLAN_DEV_OV788)
#if defined(configUSE_WAKELOCK_PMU) && (configUSE_WAKELOCK_PMU == 1)
//acquire wakelock to keep system awake
pmu_acquire_wakelock(PMU_SDIO_DEVICE);
#endif
#endif
#ifdef CONFIG_WOWLAN_DEV_OV788
//record wowlan status
gpio_write(&wow_gpio_wlan_on, 1);
#endif
#if defined(CONFIG_WOWLAN_DEV_NT96658)
//restore SDIO pin status for bus communication
pin_mode(SD_D0, PullUp);
pin_mode(SD_D1, PullUp);
pin_mode(SD_D2, PullUp);
pin_mode(SD_D3, PullUp);
pin_mode(SD_CMD, PullUp);
pin_mode(SD_CLK, PullDown);
#endif
//send signal to awake host
gpio_write(&wow_gpio_wifi_in, 0);
wowlan_mdelay_os(WOW_TRIGGER_INTERVAL);
gpio_write(&wow_gpio_wifi_in, 1);
wowlan_mdelay_os(WOW_TRIGGER_INTERVAL);
gpio_write(&wow_gpio_wifi_in, 0);
wowlan_mdelay_os(WOW_TRIGGER_INTERVAL);
return 0;
}
int dev_wowlan_sleep_process(void){
#if defined(CONFIG_WOWLAN_DEV_NT96658)
//pull control for SDIO pin only when host is already power off
if(rtw_wowlan_is_enabled() && (rtw_wowlan_get_wk_reason() == 0)){
WOWLAN_PRINTK("pull control");
//configure SDIO pin status for avoiding current leakage
pin_mode(SD_D0, PullNone);
pin_mode(SD_D1, PullNone);
pin_mode(SD_D2, PullNone);
pin_mode(SD_D3, PullNone);
pin_mode(SD_CMD, PullNone);
pin_mode(SD_CLK, PullNone);
}
#endif
return 0;
}
int dev_wowlan_disable(void){
WOWLAN_PRINTK("WOWLAN: device disable!");
#if CONFIG_WLAN
wifi_set_power_mode(0xff, 0);
#endif
#ifdef CONFIG_WOWLAN_DEV_OV788
gpio_write(&wow_gpio_wlan_on, 1);
#endif
return 0;
}
void dev_wowlan_ops_init(void *dev_ops){
struct rtw_wowlan_ops *ops = (struct rtw_wowlan_ops *)dev_ops;
WOWLAN_PRINTK("WOWLAN: device ops init!");
ops->DevWowlanInit = dev_wowlan_init;
ops->DevWowlanEnable = dev_wowlan_enable;
ops->DevWowlanDisable = dev_wowlan_disable;
ops->DevWowlanWakeUp = dev_wowlan_wakeup_process;
ops->DevWowlanSleep = dev_wowlan_sleep_process;
}

View File

@@ -0,0 +1,385 @@
#ifndef _WIFI_WOWLAN_H_
#define _WIFI_WOWLAN_H_
#include <platform_stdlib.h>
#include <osdep_service.h>
#define WOWLAN_DBG 1
enum{
WOWLAN_DBG_OFF = 0,
WOWLAN_DBG_ALWAYS,
WOWLAN_DBG_ERROR,
WOWLAN_DBG_WARNING,
WOWLAN_DBG_INFO
};
#if WOWLAN_DBG
//#define WOWLAN_DUMP_MSG
#define WOWLAN_DUMP_MSG_1 //dump packet when setting
static unsigned char gWowlanDbgLevel = WOWLAN_DBG_ERROR;
#define WOWLAN_PRINTK(fmt, args...) printf(fmt"\r\n",## args)
#define _WOWLAN_PRINTK(fmt, args...) printf(fmt,## args)
#define WOWLAN_DBG_MSG(level, fmt, args...) \
do{ \
if(level <= gWowlanDbgLevel){ \
WOWLAN_PRINTK(fmt,## args); \
} \
}while(0)
#else
#define WOWLAN_PRINTK(fmt, args...)
#define WOWLAN_DBG_MSG(level, fmt, args...)
#endif
#ifndef u8
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#endif
#ifndef BIT
#define BIT(x) ((u32)1 << (x))
#endif
#ifndef le16_to_cpu //need a general definition for the whole system
#define cpu_to_le32(x) ((u32)(x))
#define le32_to_cpu(x) ((u32)(x))
#define cpu_to_le16(x) ((u16)(x))
#define le16_to_cpu(x) ((u16)(x))
#endif
#ifndef IP_FMT
#define IP_FMT "%d.%d.%d.%d"
#endif
#ifndef IP_ARG
#define IP_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3]
#endif
#ifndef MAC_FMT
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
#endif
#ifndef MAC_ARG
#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
#endif
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
#ifndef ethhdr
struct ethhdr
{
unsigned char h_dest[ETH_ALEN]; /* destination eth addr */
unsigned char h_source[ETH_ALEN]; /* source ether addr */
unsigned short h_proto; /* packet type ID field */
};
#endif
#ifndef wowlan_memcpy
#define wowlan_memcpy(d, s, n) rtw_memcpy((void*)(d), ((void*)(s)), (n))
#endif
#ifndef wowlan_malloc
#define wowlan_malloc(sz) rtw_malloc(sz)
#endif
#ifndef wowlan_zmalloc
#define wowlan_zmalloc(sz) rtw_zmalloc(sz)
#endif
#ifndef wowlan_memset
#define wowlan_memset(pbuf, c, sz) rtw_memset(pbuf, c, sz)
#endif
#ifndef wowlan_mfree
#define wowlan_mfree(p, sz) rtw_mfree(((u8*)(p)), (sz))
#endif
#ifndef wowlan_memcmp
#define wowlan_memcmp(s1, s2, n) rtw_memcmp(((void*)(s1)), ((void*)(s2)), (n))
#endif
#ifndef wowlan_mdelay_os
#define wowlan_mdelay_os(ms) rtw_mdelay_os(ms)
#endif
/*Mutex services*/
typedef _mutex _wowlock;
__inline static void _init_wowlock(_wowlock *plock)
{
rtw_mutex_init(plock);
}
__inline static void _free_wowlock(_wowlock *plock)
{
rtw_mutex_free(plock);
}
__inline static void _enter_wowlock(_wowlock *plock)
{
rtw_mutex_get(plock);
}
__inline static void _exit_wowlock(_wowlock *plock)
{
rtw_mutex_put(plock);
}
/*Timer services*/
typedef _timerHandle _wowTimer;
#define TMR_AUTO_RELOAD_EN _TRUE
#define TMR_AUTO_RELOAD_DIS _FALSE
__inline static void
_wowlan_init_timer(_wowTimer *ptimer, void *adapter, TIMER_FUN pfunc,void* cntx, const char *name, u32 auto_reload)
{
*ptimer = rtw_timerCreate(
(signed const char *)name, // Just a text name, not used by the RTOS kernel.
TIMER_MAX_DELAY, // Timer Period, not 0
auto_reload, // Whether timer will auto-load themselves when expires
cntx, // Uniq id used to identify which timer expire..
pfunc // Timer callback
);
}
__inline static void
_wowlan_set_timer(_wowTimer *ptimer, u32 delay_time_ms)
{
if(rtw_timerChangePeriod(*ptimer, rtw_ms_to_systime(delay_time_ms), TIMER_MAX_DELAY) == _FAIL)
WOWLAN_PRINTK("Fail to set timer period");
}
__inline static void
_wowlan_cancel_timer(_wowTimer *ptimer)
{
rtw_timerStop(*ptimer, TIMER_MAX_DELAY);
}
__inline static void
_wowlan_del_timer(_wowTimer *ptimer)
{
rtw_timerDelete(*ptimer, TIMER_MAX_DELAY);
}
__inline static void *
_wowlan_get_timer_cntx(_wowTimer timer)
{
#ifdef PLATFORM_FREERTOS
#include <FreeRTOS.h>
#include <timers.h>
return pvTimerGetTimerID(timer);
#else
#error "_wowlan_get_timer_cntx is not defined"
#endif
}
enum rtw_wowlan_wakeup_reason {
RTW_WOWLAN_WAKEUP_BY_PATTERN = BIT(0),
RTW_WOWLAN_WAKEUP_BY_DISCONNECTION = BIT(1),
RTW_WOWLAN_WAKEUP_MAX = 0x7FFFFFFF
};
enum rtw_wowlan_cmd_id{
RTW_WOWLAN_CMD_ENABLE = 0x01, // enable wowlan service
RTW_WOWLAN_CMD_PATTERNS = 0x02, // wowlan pattern setting
RTW_WOWLAN_CMD_PROT_OFFLOAD_CONFIG = 0x03, //ARP offload setting
RTW_WOWLAN_CMD_GET_STATUS = 0x04, // get rtw_wowlan_status
RTW_WOWLAN_CMD_CLEAR_ALL = 0x05, //clear wowlan content
RTW_WOWLAN_CMD_KEEPALIVE = 0x06, //for keep alive packet setting
RTW_WOWLAN_CMD_MAX = 0xff
};
#define RTW_WOWLAN_MAX_RX_FILTERS (5)
#define RTW_WOWLAN_RX_FILTER_MAX_FIELDS (8)
#define RTW_WOWLAN_ID_OFFSET (100) //to match some application, ID starts from 100
#define RTW_WOWLAN_MIN_FILTERS_ID (RTW_WOWLAN_ID_OFFSET)
#define RTW_WOWLAN_MAX_FILTERS_ID (RTW_WOWLAN_ID_OFFSET+RTW_WOWLAN_MAX_RX_FILTERS-1)
struct rtw_wowlan_rx_filter_field {
u16 offset;
u8 len;
u8 flags;
u8 *mask;
u8 *pattern;
};
struct rtw_wowlan_rx_filter {
u8 action;
u8 offset;
u8 num_fields;
struct rtw_wowlan_rx_filter_field fields[RTW_WOWLAN_RX_FILTER_MAX_FIELDS];
};
#if defined(__IAR_SYSTEMS_ICC__)|| defined (__GNUC__)
#pragma pack(1)
#else
#error "this structure needs to be packed!"
#endif
struct rtw_wowlan_status {
u32 wakeup_reasons; //record wake up reason
u32 filter_id; //record which pattern is matched
};
#if defined(__IAR_SYSTEMS_ICC__)|| defined (__GNUC__)
#pragma pack()
#else
#error "this structure needs to be packed!"
#endif
/**
* struct rtw_wowlan_keepalive_packet
*
* @payload_len: data payload length
* @payload: data payload buffer
* @data_interval: interval at which to send data packets
**/
#define RTW_WOWLAN_MAX_KPALIVE_PKT 3
#define RTW_WOWLAN_MAX_KPALIVE_PKT_SZ 512
struct rtw_wowlan_keepalive_packet{
u8 packet_id;
int payload_len;
u8 *payload;
u32 data_interval;
_wowTimer keepalive_tmr;
};
struct rtw_wowlan_ops {
int (*DevWowlanInit)(void);
int (*DevWowlanEnable)(void);
int (*DevWowlanDisable)(void);
int (*DevWowlanWakeUp)(void);
int (*DevWowlanSleep)(void);
};
/**
* enum rtw_wowlan_proto_offloads - enabled protocol offloads
* @RTW_WOWLAN_PROTO_OFFLOAD_ARP: ARP data is enabled
*/
enum rtw_wowlan_proto_offloads {
RTW_WOWLAN_PROTO_OFFLOAD_ARP = BIT(0),
RTW_WOWLAN_PROTO_OFFLOAD_MAX = 0x7FFFFFFF
};
/**
* struct rtw_wowlan_proto_offload_common - ARP/NS offload common part
* @enabled: enable flags
* @remote_ipv4_addr: remote address to answer to (or zero if all)
* @host_ipv4_addr: our IPv4 address to respond to queries for
* @arp_mac_addr: our MAC address for ARP responses
* @reserved: unused
*/
struct rtw_wowlan_proto_offload_common{
int proto_enabled;
u32 remote_ipv4_addr;
u32 host_ipv4_addr;
u8 host_mac_addr[ETH_ALEN];
u16 reserved;
};
struct rtw_wowlan {
_wowlock wow_mutex;
bool enabled;
struct rtw_wowlan_status status;
struct rtw_wowlan_ops ops;
struct rtw_wowlan_proto_offload_common proto;
bool proto_offload_enabled;
struct rtw_wowlan_rx_filter *rx_filter[RTW_WOWLAN_MAX_RX_FILTERS];
bool rx_filter_enabled[RTW_WOWLAN_MAX_RX_FILTERS];/* RX Data filter rule state - enabled/disabled */
struct rtw_wowlan_keepalive_packet *tx_keepalive[RTW_WOWLAN_MAX_KPALIVE_PKT];
bool tx_keepalive_enabled[RTW_WOWLAN_MAX_KPALIVE_PKT];/* TX keep avlive rule state - enabled/disabled */
};
#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
#define cpIpAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3])
#define RTW_WOWLAN_GET_ARP_PKT_OPERATION(__pHeader) ReadEF2Byte( ((u8*)(__pHeader)) + 6)
#define RTW_WOWLAN_GET_ARP_PKT_SENDER_MAC_ADDR(__pHeader, _val) cpMacAddr((u8*)(_val), ((u8*)(__pHeader))+8)
#define RTW_WOWLAN_GET_ARP_PKT_SENDER_IP_ADDR(__pHeader, _val) cpIpAddr((u8*)(_val), ((u8*)(__pHeader))+14)
#define RTW_WOWLAN_GET_ARP_PKT_TARGET_MAC_ADDR(__pHeader, _val) cpMacAddr((u8*)(_val), ((u8*)(__pHeader))+18)
#define RTW_WOWLAN_GET_ARP_PKT_TARGET_IP_ADDR(__pHeader, _val) cpIpAddr((u8*)(_val), ((u8*)(__pHeader))+24)
#define RTW_WOWLAN_SET_ARP_PKT_HW(__pHeader, __Value) WriteEF2Byte( ((u8*)(__pHeader)) + 0, __Value)
#define RTW_WOWLAN_SET_ARP_PKT_PROTOCOL(__pHeader, __Value) WriteEF2Byte( ((u8*)(__pHeader)) + 2, __Value)
#define RTW_WOWLAN_SET_ARP_PKT_HW_ADDR_LEN(__pHeader, __Value) WriteEF1Byte( ((u8*)(__pHeader)) + 4, __Value)
#define RTW_WOWLAN_SET_ARP_PKT_PROTOCOL_ADDR_LEN(__pHeader, __Value) WriteEF1Byte( ((u8*)(__pHeader)) + 5, __Value)
#define RTW_WOWLAN_SET_ARP_PKT_OPERATION(__pHeader, __Value) WriteEF2Byte( ((u8*)(__pHeader)) + 6, __Value)
#define RTW_WOWLAN_SET_ARP_PKT_SENDER_MAC_ADDR(__pHeader, _val) cpMacAddr(((u8*)(__pHeader))+8, (u8*)(_val))
#define RTW_WOWLAN_SET_ARP_PKT_SENDER_IP_ADDR(__pHeader, _val) cpIpAddr(((u8*)(__pHeader))+14, (u8*)(_val))
#define RTW_WOWLAN_SET_ARP_PKT_TARGET_MAC_ADDR(__pHeader, _val) cpMacAddr(((u8*)(__pHeader))+18, (u8*)(_val))
#define RTW_WOWLAN_SET_ARP_PKT_TARGET_IP_ADDR(__pHeader, _val) cpIpAddr(((u8*)(__pHeader))+24, (u8*)(_val))
#define RTW_WOWLAN_ARP_PKT_LEN 0x2A
#define RTW_WOWLAN_ARP_PKT_OPERATION_REQ 0x0100 //arp request
#define RTW_WOWLAN_ARP_PKT_OPERATION_RSP 0x0200 //arp response
extern u8 key_2char2num(u8 hch, u8 lch);
extern _LONG_CALL_ void __rtl_memDump_v1_00(const u8 *start, u32 size, char * strHeader);
#define rtw_wowlan_DumpForBytes(pData, Len) __rtl_memDump_v1_00(pData, Len, NULL)
#define PWOWLAN_TO_STATUS(pwowlan) (&pwowlan->status)
#define PWOWLAN_TO_OPS(pwowlan) (&pwowlan->ops)
#define PWOWLAN_TO_PROTO(pwowlan) (&pwowlan->proto)
#define PWOWLAN_TO_RX_FILTER(pwowlan) (pwowlan->rx_filter)
#define PWOWLAN_TO_TX_KEEPALIVE(pwowlan) (pwowlan->tx_keepalive)
/**
* rtw_wowlan_init: initialize wowlan service
* arg: None
* return: _SUCCESS or _FAIL
*/
extern int rtw_wowlan_init(void);
/**
* cmd_wowlan_service: input commands to configure wowlan service
* arg:
* @argc: number of input parameter
* @argv: content of input string
* return: None
*/
extern void cmd_wowlan_service(int argc, char **argv);
/**
* rtw_wowlan_process_rx_packet: entry for packet process in wowlan service once it starts
* arg:
* @rx_pkt: receive packet from wlan/ethernet
* @pkt_len: receive packet length
* return: _SUCCESS or _FAIL
*/
extern int rtw_wowlan_process_rx_packet(char *rx_pkt, u16 pkt_len);
/**
* rtw_wowlan_wakeup_process: wake up process once the reasons are matched,
* refer to enum rtw_wowlan_wakeup_reason
* arg:
* @reason: wake up reason, refer to enum rtw_wowlan_wakeup_reason
* return: None
*/
extern void rtw_wowlan_wakeup_process(int reason);
/**
* rtw_wowlan_is_enabled: if wowlan service is already enabled
* this function is called in rx path and wifi_inidication when wowlan service is running
* arg: None
* return: _True if enable or _False if disable
*/
extern int rtw_wowlan_is_enabled(void);
/**
* rtw_wowlan_get_wk_reason: query wake up reason, refer to enum rtw_wowlan_wakeup_reason
* arg: None
* return: wakeup_reason
*/
extern int rtw_wowlan_get_wk_reason(void);
/**
* rtw_wowlan_dev_sleep: sleep process on Ameba side, pull control for example
* this function is linked to dev_wowlan_sleep_process() in dev_wowlan.c
* arg: None
* return: None
*/
extern void rtw_wowlan_dev_sleep(void);
#endif

View File

@@ -0,0 +1,589 @@
/*
* SSL/TLS interface definition
* Copyright (c) 2004-2013, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef TLS_H
#define TLS_H
struct tls_connection;
struct tls_random {
const u8 *client_random;
size_t client_random_len;
const u8 *server_random;
size_t server_random_len;
};
enum tls_event {
TLS_CERT_CHAIN_SUCCESS,
TLS_CERT_CHAIN_FAILURE,
TLS_PEER_CERTIFICATE,
TLS_ALERT
};
/*
* Note: These are used as identifier with external programs and as such, the
* values must not be changed.
*/
enum tls_fail_reason {
TLS_FAIL_UNSPECIFIED = 0,
TLS_FAIL_UNTRUSTED = 1,
TLS_FAIL_REVOKED = 2,
TLS_FAIL_NOT_YET_VALID = 3,
TLS_FAIL_EXPIRED = 4,
TLS_FAIL_SUBJECT_MISMATCH = 5,
TLS_FAIL_ALTSUBJECT_MISMATCH = 6,
TLS_FAIL_BAD_CERTIFICATE = 7,
TLS_FAIL_SERVER_CHAIN_PROBE = 8,
TLS_FAIL_DOMAIN_SUFFIX_MISMATCH = 9,
TLS_FAIL_DOMAIN_MISMATCH = 10,
};
#define TLS_MAX_ALT_SUBJECT 10
union tls_event_data {
struct {
int depth;
const char *subject;
enum tls_fail_reason reason;
const char *reason_txt;
const struct wpabuf *cert;
} cert_fail;
struct {
int depth;
const char *subject;
const struct wpabuf *cert;
const u8 *hash;
size_t hash_len;
const char *altsubject[TLS_MAX_ALT_SUBJECT];
int num_altsubject;
} peer_cert;
struct {
int is_local;
const char *type;
const char *description;
} alert;
};
struct tls_config {
const char *opensc_engine_path;
const char *pkcs11_engine_path;
const char *pkcs11_module_path;
int fips_mode;
int cert_in_cb;
const char *openssl_ciphers;
unsigned int tls_session_lifetime;
void (*event_cb)(void *ctx, enum tls_event ev,
union tls_event_data *data);
void *cb_ctx;
};
#define TLS_CONN_ALLOW_SIGN_RSA_MD5 BIT(0)
#define TLS_CONN_DISABLE_TIME_CHECKS BIT(1)
#define TLS_CONN_DISABLE_SESSION_TICKET BIT(2)
#define TLS_CONN_REQUEST_OCSP BIT(3)
#define TLS_CONN_REQUIRE_OCSP BIT(4)
#define TLS_CONN_DISABLE_TLSv1_1 BIT(5)
#define TLS_CONN_DISABLE_TLSv1_2 BIT(6)
#define TLS_CONN_EAP_FAST BIT(7)
#define TLS_CONN_DISABLE_TLSv1_0 BIT(8)
/**
* struct tls_connection_params - Parameters for TLS connection
* @ca_cert: File or reference name for CA X.509 certificate in PEM or DER
* format
* @ca_cert_blob: ca_cert as inlined data or %NULL if not used
* @ca_cert_blob_len: ca_cert_blob length
* @ca_path: Path to CA certificates (OpenSSL specific)
* @subject_match: String to match in the subject of the peer certificate or
* %NULL to allow all subjects
* @altsubject_match: String to match in the alternative subject of the peer
* certificate or %NULL to allow all alternative subjects
* @suffix_match: String to suffix match in the dNSName or CN of the peer
* certificate or %NULL to allow all domain names. This may allow subdomains an
* wildcard certificates. Each domain name label must have a full match.
* @domain_match: String to match in the dNSName or CN of the peer
* certificate or %NULL to allow all domain names. This requires a full,
* case-insensitive match.
* @client_cert: File or reference name for client X.509 certificate in PEM or
* DER format
* @client_cert_blob: client_cert as inlined data or %NULL if not used
* @client_cert_blob_len: client_cert_blob length
* @private_key: File or reference name for client private key in PEM or DER
* format (traditional format (RSA PRIVATE KEY) or PKCS#8 (PRIVATE KEY)
* @private_key_blob: private_key as inlined data or %NULL if not used
* @private_key_blob_len: private_key_blob length
* @private_key_passwd: Passphrase for decrypted private key, %NULL if no
* passphrase is used.
* @dh_file: File name for DH/DSA data in PEM format, or %NULL if not used
* @dh_blob: dh_file as inlined data or %NULL if not used
* @dh_blob_len: dh_blob length
* @engine: 1 = use engine (e.g., a smartcard) for private key operations
* (this is OpenSSL specific for now)
* @engine_id: engine id string (this is OpenSSL specific for now)
* @ppin: pointer to the pin variable in the configuration
* (this is OpenSSL specific for now)
* @key_id: the private key's id when using engine (this is OpenSSL
* specific for now)
* @cert_id: the certificate's id when using engine
* @ca_cert_id: the CA certificate's id when using engine
* @openssl_ciphers: OpenSSL cipher configuration
* @flags: Parameter options (TLS_CONN_*)
* @ocsp_stapling_response: DER encoded file with cached OCSP stapling response
* or %NULL if OCSP is not enabled
*
* TLS connection parameters to be configured with tls_connection_set_params()
* and tls_global_set_params().
*
* Certificates and private key can be configured either as a reference name
* (file path or reference to certificate store) or by providing the same data
* as a pointer to the data in memory. Only one option will be used for each
* field.
*/
struct tls_connection_params {
const char *ca_cert;
const u8 *ca_cert_blob;
size_t ca_cert_blob_len;
const char *ca_path;
const char *subject_match;
const char *altsubject_match;
const char *suffix_match;
const char *domain_match;
const char *client_cert;
const u8 *client_cert_blob;
size_t client_cert_blob_len;
const char *private_key;
const u8 *private_key_blob;
size_t private_key_blob_len;
const char *private_key_passwd;
const char *dh_file;
const u8 *dh_blob;
size_t dh_blob_len;
/* OpenSSL specific variables */
int engine;
const char *engine_id;
const char *pin;
const char *key_id;
const char *cert_id;
const char *ca_cert_id;
const char *openssl_ciphers;
unsigned int flags;
const char *ocsp_stapling_response;
};
/**
* tls_init - Initialize TLS library
* @conf: Configuration data for TLS library
* Returns: Context data to be used as tls_ctx in calls to other functions,
* or %NULL on failure.
*
* Called once during program startup and once for each RSN pre-authentication
* session. In other words, there can be two concurrent TLS contexts. If global
* library initialization is needed (i.e., one that is shared between both
* authentication types), the TLS library wrapper should maintain a reference
* counter and do global initialization only when moving from 0 to 1 reference.
*/
//ssl_context * tls_init(const struct tls_config *conf);
void * tls_init(const struct tls_config *conf);
/**
* tls_deinit - Deinitialize TLS library
* @tls_ctx: TLS context data from tls_init()
*
* Called once during program shutdown and once for each RSN pre-authentication
* session. If global library deinitialization is needed (i.e., one that is
* shared between both authentication types), the TLS library wrapper should
* maintain a reference counter and do global deinitialization only when moving
* from 1 to 0 references.
*/
void tls_deinit(void *tls_ctx);
/**
* tls_get_errors - Process pending errors
* @tls_ctx: TLS context data from tls_init()
* Returns: Number of found error, 0 if no errors detected.
*
* Process all pending TLS errors.
*/
int tls_get_errors(void *tls_ctx);
/**
* tls_connection_init - Initialize a new TLS connection
* @tls_ctx: TLS context data from tls_init()
* Returns: Connection context data, conn for other function calls
*/
struct tls_connection * tls_connection_init(void *tls_ctx);
/**
* tls_connection_deinit - Free TLS connection data
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
*
* Release all resources allocated for TLS connection.
*/
void tls_connection_deinit(void *tls_ctx, struct tls_connection *conn);
/**
* tls_connection_established - Has the TLS connection been completed?
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* Returns: 1 if TLS connection has been completed, 0 if not.
*/
int tls_connection_established(void *tls_ctx, struct tls_connection *conn);
/**
* tls_connection_shutdown - Shutdown TLS connection
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* Returns: 0 on success, -1 on failure
*
* Shutdown current TLS connection without releasing all resources. New
* connection can be started by using the same conn without having to call
* tls_connection_init() or setting certificates etc. again. The new
* connection should try to use session resumption.
*/
int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn);
enum {
TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN = -4,
TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED = -3,
TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED = -2
};
/**
* tls_connection_set_params - Set TLS connection parameters
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @params: Connection parameters
* Returns: 0 on success, -1 on failure,
* TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED (-2) on error causing PKCS#11 engine
* failure, or
* TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED (-3) on failure to verify the
* PKCS#11 engine private key, or
* TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN (-4) on PIN error causing PKCS#11 engine
* failure.
*/
int __must_check
tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
const struct tls_connection_params *params);
/**
* tls_global_set_params - Set TLS parameters for all TLS connection
* @tls_ctx: TLS context data from tls_init()
* @params: Global TLS parameters
* Returns: 0 on success, -1 on failure,
* TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED (-2) on error causing PKCS#11 engine
* failure, or
* TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED (-3) on failure to verify the
* PKCS#11 engine private key, or
* TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN (-4) on PIN error causing PKCS#11 engine
* failure.
*/
int __must_check tls_global_set_params(
void *tls_ctx, const struct tls_connection_params *params);
/**
* tls_global_set_verify - Set global certificate verification options
* @tls_ctx: TLS context data from tls_init()
* @check_crl: 0 = do not verify CRLs, 1 = verify CRL for the user certificate,
* 2 = verify CRL for all certificates
* Returns: 0 on success, -1 on failure
*/
int __must_check tls_global_set_verify(void *tls_ctx, int check_crl);
/**
* tls_connection_set_verify - Set certificate verification options
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @verify_peer: 1 = verify peer certificate
* @flags: Connection flags (TLS_CONN_*)
* @session_ctx: Session caching context or %NULL to use default
* @session_ctx_len: Length of @session_ctx in bytes.
* Returns: 0 on success, -1 on failure
*/
int __must_check tls_connection_set_verify(void *tls_ctx,
struct tls_connection *conn,
int verify_peer,
unsigned int flags,
const u8 *session_ctx,
size_t session_ctx_len);
/**
* tls_connection_get_random - Get random data from TLS connection
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @data: Structure of client/server random data (filled on success)
* Returns: 0 on success, -1 on failure
*/
int __must_check tls_connection_get_random(void *tls_ctx,
struct tls_connection *conn,
struct tls_random *data);
/**
* tls_connection_prf - Use TLS-PRF to derive keying material
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @label: Label (e.g., description of the key) for PRF
* @server_random_first: seed is 0 = client_random|server_random,
* 1 = server_random|client_random
* @skip_keyblock: Skip TLS key block from the beginning of PRF output
* @out: Buffer for output data from TLS-PRF
* @out_len: Length of the output buffer
* Returns: 0 on success, -1 on failure
*
* tls_connection_prf() is required so that further keying material can be
* derived from the master secret. Example implementation of this function is in
* tls_prf_sha1_md5() when it is called with seed set to
* client_random|server_random (or server_random|client_random). For TLSv1.2 and
* newer, a different PRF is needed, though.
*/
int __must_check tls_connection_prf(void *tls_ctx,
struct tls_connection *conn,
const char *label,
int server_random_first,
int skip_keyblock,
u8 *out, size_t out_len);
/**
* tls_connection_handshake - Process TLS handshake (client side)
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @in_data: Input data from TLS server
* @appl_data: Pointer to application data pointer, or %NULL if dropped
* Returns: Output data, %NULL on failure
*
* The caller is responsible for freeing the returned output data. If the final
* handshake message includes application data, this is decrypted and
* appl_data (if not %NULL) is set to point this data. The caller is
* responsible for freeing appl_data.
*
* This function is used during TLS handshake. The first call is done with
* in_data == %NULL and the library is expected to return ClientHello packet.
* This packet is then send to the server and a response from server is given
* to TLS library by calling this function again with in_data pointing to the
* TLS message from the server.
*
* If the TLS handshake fails, this function may return %NULL. However, if the
* TLS library has a TLS alert to send out, that should be returned as the
* output data. In this case, tls_connection_get_failed() must return failure
* (> 0).
*
* tls_connection_established() should return 1 once the TLS handshake has been
* completed successfully.
*/
struct wpabuf * tls_connection_handshake(void *tls_ctx,
struct tls_connection *conn,
const struct wpabuf *in_data,
struct wpabuf **appl_data);
struct wpabuf * tls_connection_handshake2(void *tls_ctx,
struct tls_connection *conn,
const struct wpabuf *in_data,
struct wpabuf **appl_data,
int *more_data_needed);
/**
* tls_connection_server_handshake - Process TLS handshake (server side)
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @in_data: Input data from TLS peer
* @appl_data: Pointer to application data pointer, or %NULL if dropped
* Returns: Output data, %NULL on failure
*
* The caller is responsible for freeing the returned output data.
*/
struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
struct tls_connection *conn,
const struct wpabuf *in_data,
struct wpabuf **appl_data);
/**
* tls_connection_encrypt - Encrypt data into TLS tunnel
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @in_data: Plaintext data to be encrypted
* Returns: Encrypted TLS data or %NULL on failure
*
* This function is used after TLS handshake has been completed successfully to
* send data in the encrypted tunnel. The caller is responsible for freeing the
* returned output data.
*/
struct wpabuf * tls_connection_encrypt(void *tls_ctx,
struct tls_connection *conn,
const struct wpabuf *in_data);
/**
* tls_connection_decrypt - Decrypt data from TLS tunnel
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @in_data: Encrypted TLS data
* Returns: Decrypted TLS data or %NULL on failure
*
* This function is used after TLS handshake has been completed successfully to
* receive data from the encrypted tunnel. The caller is responsible for
* freeing the returned output data.
*/
struct wpabuf * tls_connection_decrypt(void *tls_ctx,
struct tls_connection *conn,
const struct wpabuf *in_data);
struct wpabuf * tls_connection_decrypt2(void *tls_ctx,
struct tls_connection *conn,
const struct wpabuf *in_data,
int *more_data_needed);
/**
* tls_connection_resumed - Was session resumption used
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* Returns: 1 if current session used session resumption, 0 if not
*/
int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn);
enum {
TLS_CIPHER_NONE,
TLS_CIPHER_RC4_SHA /* 0x0005 */,
TLS_CIPHER_AES128_SHA /* 0x002f */,
TLS_CIPHER_RSA_DHE_AES128_SHA /* 0x0031 */,
TLS_CIPHER_ANON_DH_AES128_SHA /* 0x0034 */
};
/**
* tls_connection_set_cipher_list - Configure acceptable cipher suites
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @ciphers: Zero (TLS_CIPHER_NONE) terminated list of allowed ciphers
* (TLS_CIPHER_*).
* Returns: 0 on success, -1 on failure
*/
int __must_check tls_connection_set_cipher_list(void *tls_ctx,
struct tls_connection *conn,
u8 *ciphers);
/**
* tls_get_version - Get the current TLS version number
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @buf: Buffer for returning the TLS version number
* @buflen: buf size
* Returns: 0 on success, -1 on failure
*
* Get the currently used TLS version number.
*/
int __must_check tls_get_version(void *tls_ctx, struct tls_connection *conn,
char *buf, size_t buflen);
/**
* tls_get_cipher - Get current cipher name
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @buf: Buffer for the cipher name
* @buflen: buf size
* Returns: 0 on success, -1 on failure
*
* Get the name of the currently used cipher.
*/
int __must_check tls_get_cipher(void *tls_ctx, struct tls_connection *conn,
char *buf, size_t buflen);
/**
* tls_connection_enable_workaround - Enable TLS workaround options
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* Returns: 0 on success, -1 on failure
*
* This function is used to enable connection-specific workaround options for
* buffer SSL/TLS implementations.
*/
int __must_check tls_connection_enable_workaround(void *tls_ctx,
struct tls_connection *conn);
/**
* tls_connection_client_hello_ext - Set TLS extension for ClientHello
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* @ext_type: Extension type
* @data: Extension payload (%NULL to remove extension)
* @data_len: Extension payload length
* Returns: 0 on success, -1 on failure
*/
int __must_check tls_connection_client_hello_ext(void *tls_ctx,
struct tls_connection *conn,
int ext_type, const u8 *data,
size_t data_len);
/**
* tls_connection_get_failed - Get connection failure status
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
*
* Returns >0 if connection has failed, 0 if not.
*/
int tls_connection_get_failed(void *tls_ctx, struct tls_connection *conn);
/**
* tls_connection_get_read_alerts - Get connection read alert status
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* Returns: Number of times a fatal read (remote end reported error) has
* happened during this connection.
*/
int tls_connection_get_read_alerts(void *tls_ctx, struct tls_connection *conn);
/**
* tls_connection_get_write_alerts - Get connection write alert status
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
* Returns: Number of times a fatal write (locally detected error) has happened
* during this connection.
*/
int tls_connection_get_write_alerts(void *tls_ctx,
struct tls_connection *conn);
typedef int (*tls_session_ticket_cb)
(void *ctx, const u8 *ticket, size_t len, const u8 *client_random,
const u8 *server_random, u8 *master_secret);
int __must_check tls_connection_set_session_ticket_cb(
void *tls_ctx, struct tls_connection *conn,
tls_session_ticket_cb cb, void *ctx);
void tls_connection_set_log_cb(struct tls_connection *conn,
void (*log_cb)(void *ctx, const char *msg),
void *ctx);
#define TLS_BREAK_VERIFY_DATA BIT(0)
#define TLS_BREAK_SRV_KEY_X_HASH BIT(1)
#define TLS_BREAK_SRV_KEY_X_SIGNATURE BIT(2)
#define TLS_DHE_PRIME_511B BIT(3)
#define TLS_DHE_PRIME_767B BIT(4)
#define TLS_DHE_PRIME_15 BIT(5)
#define TLS_DHE_PRIME_58B BIT(6)
#define TLS_DHE_NON_PRIME BIT(7)
void tls_connection_set_test_flags(struct tls_connection *conn, u32 flags);
int tls_get_library_version(char *buf, size_t buf_len);
void tls_connection_set_success_data(struct tls_connection *conn,
struct wpabuf *data);
void tls_connection_set_success_data_resumed(struct tls_connection *conn);
const struct wpabuf *
tls_connection_get_success_data(struct tls_connection *conn);
void tls_connection_remove_session(struct tls_connection *conn);
#endif /* TLS_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,548 @@
/*
* wpa_supplicant/hostapd / common helper functions, etc.
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef COMMON_H
#define COMMON_H
#include "utils/os.h"
#define TO_TEST_WPS 0
#define ETH_ALEN 6
#if defined(__linux__) || defined(__GLIBC__)
#include <endian.h>
#include <byteswap.h>
#endif /* __linux__ */
#if defined(PLATFORM_FREERTOS)
//#include "little_endian.h"
//#include "basic_types.h"
#endif /* PLATFORM_FREERTOS */
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \
defined(__OpenBSD__)
#include <sys/types.h>
#include <sys/endian.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
#ifdef __OpenBSD__
#define bswap_16 swap16
#define bswap_32 swap32
#define bswap_64 swap64
#else /* __OpenBSD__ */
#define bswap_16 bswap16
#define bswap_32 bswap32
#define bswap_64 bswap64
#endif /* __OpenBSD__ */
#endif /* defined(__FreeBSD__) || defined(__NetBSD__) || * defined(__DragonFly__) || defined(__OpenBSD__) */
#ifdef __APPLE__
#include <sys/types.h>
#include <machine/endian.h>
#define __BYTE_ORDER _BYTE_ORDER
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
#define __BIG_ENDIAN _BIG_ENDIAN
static inline unsigned short bswap_16(unsigned short v)
{
return ((v & 0xff) << 8) | (v >> 8);
}
static inline unsigned int bswap_32(unsigned int v)
{
return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
((v & 0xff0000) >> 8) | (v >> 24);
}
#endif /* __APPLE__ */
#ifdef CONFIG_TI_COMPILER
#define __BIG_ENDIAN 4321
#define __LITTLE_ENDIAN 1234
#ifdef __big_endian__
#define __BYTE_ORDER __BIG_ENDIAN
#else
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif
#endif /* CONFIG_TI_COMPILER */
#ifdef CONFIG_NATIVE_WINDOWS
#include <winsock.h>
typedef int socklen_t;
#ifndef MSG_DONTWAIT
#define MSG_DONTWAIT 0 /* not supported */
#endif
#endif /* CONFIG_NATIVE_WINDOWS */
#ifdef _MSC_VER
#define inline __inline
#undef vsnprintf
#define vsnprintf _vsnprintf
#undef close
#define close closesocket
#endif /* _MSC_VER */
/* Define platform specific integer types */
#ifdef _MSC_VER
typedef UINT64 u64;
typedef UINT32 u32;
typedef UINT16 u16;
typedef UINT8 u8;
typedef INT64 s64;
typedef INT32 s32;
typedef INT16 s16;
typedef INT8 s8;
#define WPA_TYPES_DEFINED
#endif /* _MSC_VER */
#ifdef __vxworks
typedef unsigned long long u64;
typedef UINT32 u32;
typedef UINT16 u16;
typedef UINT8 u8;
typedef long long s64;
typedef INT32 s32;
typedef INT16 s16;
typedef INT8 s8;
#define WPA_TYPES_DEFINED
#endif /* __vxworks */
#ifdef CONFIG_TI_COMPILER
#ifdef _LLONG_AVAILABLE
typedef unsigned long long u64;
#else
/*
* TODO: 64-bit variable not available. Using long as a workaround to test the
* build, but this will likely not work for all operations.
*/
typedef unsigned long u64;
#endif
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
#define WPA_TYPES_DEFINED
#endif /* CONFIG_TI_COMPILER */
#ifndef WPA_TYPES_DEFINED
#ifdef CONFIG_USE_INTTYPES_H
#include <inttypes.h>
#else
//#include <stdint.h>
#endif
#if 0
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef int64_t s64;
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
#endif
#define WPA_TYPES_DEFINED
#endif /* !WPA_TYPES_DEFINED */
/* Define platform specific byte swapping macros */
#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS)
static inline unsigned short wpa_swap_16(unsigned short v)
{
return ((v & 0xff) << 8) | (v >> 8);
}
static inline unsigned int wpa_swap_32(unsigned int v)
{
return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
((v & 0xff0000) >> 8) | (v >> 24);
}
#define le_to_host16(n) (n)
#define host_to_le16(n) (n)
#define be_to_host16(n) wpa_swap_16(n)
#define host_to_be16(n) wpa_swap_16(n)
#define le_to_host32(n) (n)
#define be_to_host32(n) wpa_swap_32(n)
#define host_to_be32(n) wpa_swap_32(n)
#define WPA_BYTE_SWAP_DEFINED
#endif /* __CYGWIN__ || CONFIG_NATIVE_WINDOWS */
#ifndef WPA_BYTE_SWAP_DEFINED
#if 0
#ifndef __BYTE_ORDER
#ifndef __LITTLE_ENDIAN
#ifndef __BIG_ENDIAN
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#if defined(sparc)
#define __BYTE_ORDER __BIG_ENDIAN
#endif
#endif /* __BIG_ENDIAN */
#endif /* __LITTLE_ENDIAN */
#endif /* __BYTE_ORDER */
#else
#ifndef __LITTLE_ENDIAN
#define __LITTLE_ENDIAN 1234
#endif
#ifndef __BIG_ENDIAN
#define __BIG_ENDIAN 4321
#endif
#ifndef __BYTE_ORDER
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif
#endif
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define le_to_host16(n) ((__force u16) (le16) (n))
#define host_to_le16(n) ((__force le16) (u16) (n))
#define be_to_host16(n) bswap_16((__force u16) (be16) (n))
#define host_to_be16(n) ((__force be16) bswap_16((n)))
#define le_to_host32(n) ((__force u32) (le32) (n))
#define host_to_le32(n) ((__force le32) (u32) (n))
#define be_to_host32(n) bswap_32((__force u32) (be32) (n))
#define host_to_be32(n) ((__force be32) bswap_32((n)))
#define le_to_host64(n) ((__force u64) (le64) (n))
#define host_to_le64(n) ((__force le64) (u64) (n))
#define be_to_host64(n) bswap_64((__force u64) (be64) (n))
#define host_to_be64(n) ((__force be64) bswap_64((n)))
#elif __BYTE_ORDER == __BIG_ENDIAN
#define le_to_host16(n) bswap_16(n)
#define host_to_le16(n) bswap_16(n)
#define be_to_host16(n) (n)
#define host_to_be16(n) (n)
#define le_to_host32(n) bswap_32(n)
#define be_to_host32(n) (n)
#define host_to_be32(n) (n)
#define le_to_host64(n) bswap_64(n)
#define host_to_le64(n) bswap_64(n)
#define be_to_host64(n) (n)
#define host_to_be64(n) (n)
#ifndef WORDS_BIGENDIAN
#define WORDS_BIGENDIAN
#endif
#else
//#error Could not determine CPU byte order
#endif
#define WPA_BYTE_SWAP_DEFINED
#endif /* !WPA_BYTE_SWAP_DEFINED */
/* Macros for handling unaligned memory accesses */
#define WPA_GET_BE16(a) ((u16) (((a)[0] << 8) | (a)[1]))
#define WPA_PUT_BE16(a, val) \
do { \
(a)[0] = ((u16) (val)) >> 8; \
(a)[1] = ((u16) (val)) & 0xff; \
} while (0)
#define WPA_GET_LE16(a) ((u16) (((a)[1] << 8) | (a)[0]))
#define WPA_PUT_LE16(a, val) \
do { \
(a)[1] = ((u16) (val)) >> 8; \
(a)[0] = ((u16) (val)) & 0xff; \
} while (0)
#define WPA_GET_BE24(a) ((((u32) (a)[0]) << 16) | (((u32) (a)[1]) << 8) | \
((u32) (a)[2]))
#define WPA_PUT_BE24(a, val) \
do { \
(a)[0] = (u8) ((((u32) (val)) >> 16) & 0xff); \
(a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \
(a)[2] = (u8) (((u32) (val)) & 0xff); \
} while (0)
#define WPA_GET_BE32(a) ((((u32) (a)[0]) << 24) | (((u32) (a)[1]) << 16) | \
(((u32) (a)[2]) << 8) | ((u32) (a)[3]))
#define WPA_PUT_BE32(a, val) \
do { \
(a)[0] = (u8) ((((u32) (val)) >> 24) & 0xff); \
(a)[1] = (u8) ((((u32) (val)) >> 16) & 0xff); \
(a)[2] = (u8) ((((u32) (val)) >> 8) & 0xff); \
(a)[3] = (u8) (((u32) (val)) & 0xff); \
} while (0)
#define WPA_GET_LE32(a) ((((u32) (a)[3]) << 24) | (((u32) (a)[2]) << 16) | \
(((u32) (a)[1]) << 8) | ((u32) (a)[0]))
#define WPA_PUT_LE32(a, val) \
do { \
(a)[3] = (u8) ((((u32) (val)) >> 24) & 0xff); \
(a)[2] = (u8) ((((u32) (val)) >> 16) & 0xff); \
(a)[1] = (u8) ((((u32) (val)) >> 8) & 0xff); \
(a)[0] = (u8) (((u32) (val)) & 0xff); \
} while (0)
#define WPA_GET_BE64(a) ((((u64) (a)[0]) << 56) | (((u64) (a)[1]) << 48) | \
(((u64) (a)[2]) << 40) | (((u64) (a)[3]) << 32) | \
(((u64) (a)[4]) << 24) | (((u64) (a)[5]) << 16) | \
(((u64) (a)[6]) << 8) | ((u64) (a)[7]))
#define WPA_PUT_BE64(a, val) \
do { \
(a)[0] = (u8) (((u64) (val)) >> 56); \
(a)[1] = (u8) (((u64) (val)) >> 48); \
(a)[2] = (u8) (((u64) (val)) >> 40); \
(a)[3] = (u8) (((u64) (val)) >> 32); \
(a)[4] = (u8) (((u64) (val)) >> 24); \
(a)[5] = (u8) (((u64) (val)) >> 16); \
(a)[6] = (u8) (((u64) (val)) >> 8); \
(a)[7] = (u8) (((u64) (val)) & 0xff); \
} while (0)
#define WPA_GET_LE64(a) ((((u64) (a)[7]) << 56) | (((u64) (a)[6]) << 48) | \
(((u64) (a)[5]) << 40) | (((u64) (a)[4]) << 32) | \
(((u64) (a)[3]) << 24) | (((u64) (a)[2]) << 16) | \
(((u64) (a)[1]) << 8) | ((u64) (a)[0]))
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
#ifndef IFNAMSIZ
#define IFNAMSIZ 16
#endif
#ifndef ETH_P_ALL
#define ETH_P_ALL 0x0003
#endif
#ifndef ETH_P_80211_ENCAP
#define ETH_P_80211_ENCAP 0x890d /* TDLS comes under this category */
#endif
#ifndef ETH_P_PAE
#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
#endif /* ETH_P_PAE */
#ifndef ETH_P_EAPOL
#define ETH_P_EAPOL ETH_P_PAE
#endif /* ETH_P_EAPOL */
#ifndef ETH_P_RSN_PREAUTH
#define ETH_P_RSN_PREAUTH 0x88c7
#endif /* ETH_P_RSN_PREAUTH */
#ifndef ETH_P_RRB
#define ETH_P_RRB 0x890D
#endif /* ETH_P_RRB */
#if 0 //#ifdef __GNUC__
#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
#define STRUCT_PACKED __attribute__ ((packed))
#else
#define PRINTF_FORMAT(a,b)
#define STRUCT_PACKED
#endif
#ifdef CONFIG_ANSI_C_EXTRA
#if !defined(_MSC_VER) || _MSC_VER < 1400
/* snprintf - used in number of places; sprintf() is _not_ a good replacement
* due to possible buffer overflow; see, e.g.,
* http://www.ijs.si/software/snprintf/ for portable implementation of
* snprintf. */
int snprintf(char *str, size_t size, const char *format, ...);
/* vsnprintf - only used for wpa_msg() in wpa_supplicant.c */
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
#endif /* !defined(_MSC_VER) || _MSC_VER < 1400 */
/* getopt - only used in main.c */
int getopt(int argc, char *const argv[], const char *optstring);
extern char *optarg;
extern int optind;
#ifndef CONFIG_NO_SOCKLEN_T_TYPEDEF
#ifndef __socklen_t_defined
typedef int socklen_t;
#endif
#endif
/* inline - define as __inline or just define it to be empty, if needed */
#ifdef CONFIG_NO_INLINE
#define inline
#else
#define inline __inline
#endif
#ifndef __func__
#define __func__ "__func__ not defined"
#endif
#ifndef bswap_16
#define bswap_16(a) ((((u16) (a) << 8) & 0xff00) | (((u16) (a) >> 8) & 0xff))
#endif
#ifndef bswap_32
#define bswap_32(a) ((((u32) (a) << 24) & 0xff000000) | \
(((u32) (a) << 8) & 0xff0000) | \
(((u32) (a) >> 8) & 0xff00) | \
(((u32) (a) >> 24) & 0xff))
#endif
#ifndef MSG_DONTWAIT
#define MSG_DONTWAIT 0
#endif
#ifdef _WIN32_WCE
void perror(const char *s);
#endif /* _WIN32_WCE */
#endif /* CONFIG_ANSI_C_EXTRA */
#ifndef MAC2STR
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
/*
* Compact form for string representation of MAC address
* To be used, e.g., for constructing dbus paths for P2P Devices
*/
#define COMPACT_MACSTR "%02x%02x%02x%02x%02x%02x"
#endif
#ifndef BIT
#define BIT(x) (1 << (x))
#endif
/*
* Definitions for sparse validation
* (http://kernel.org/pub/linux/kernel/people/josh/sparse/)
*/
#ifdef __CHECKER__
#define __force __attribute__((force))
#define __bitwise __attribute__((bitwise))
#else
#define __force
#define __bitwise
#endif
typedef u16 __bitwise be16;
typedef u16 __bitwise le16;
typedef u32 __bitwise be32;
typedef u32 __bitwise le32;
typedef u64 __bitwise be64;
typedef u64 __bitwise le64;
#ifndef __must_check
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define __must_check __attribute__((__warn_unused_result__))
#else
#define __must_check
#endif /* __GNUC__ */
#endif /* __must_check */
//int hwaddr_aton(const char *txt, u8 *addr);
int hwaddr_compact_aton(const char *txt, u8 *addr);
int hwaddr_aton2(const char *txt, u8 *addr);
int hex2byte(const char *hex);
int hexstr2bin(const char *hex, u8 *buf, size_t len);
void inc_byte_array(u8 *counter, size_t len);
void wpa_get_ntp_timestamp(u8 *buf);
//int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len);
int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
size_t len);
#ifdef CONFIG_NATIVE_WINDOWS
void wpa_unicode2ascii_inplace(TCHAR *str);
TCHAR * wpa_strdup_tchar(const char *str);
#else /* CONFIG_NATIVE_WINDOWS */
#define wpa_unicode2ascii_inplace(s) do { } while (0)
#define wpa_strdup_tchar(s) strdup((s))
#endif /* CONFIG_NATIVE_WINDOWS */
void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len);
size_t printf_decode(u8 *buf, size_t maxlen, const char *str);
const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len);
char * wpa_config_parse_string(const char *value, size_t *len);
int is_hex(const u8 *data, size_t len);
size_t merge_byte_arrays(u8 *res, size_t res_len,
const u8 *src1, size_t src1_len,
const u8 *src2, size_t src2_len);
static inline int is_zero_ether_addr(const u8 *a)
{
return !(a[0] | a[1] | a[2] | a[3] | a[4] | a[5]);
}
static inline int is_broadcast_ether_addr(const u8 *a)
{
return (a[0] & a[1] & a[2] & a[3] & a[4] & a[5]) == 0xff;
}
#define broadcast_ether_addr (const u8 *) "\xff\xff\xff\xff\xff\xff"
#include "wpa_debug.h"
char * dup_binstr(const void *src, size_t len);
struct wpa_freq_range_list {
struct wpa_freq_range {
unsigned int min;
unsigned int max;
} *range;
unsigned int num;
};
int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value);
int freq_range_list_includes(const struct wpa_freq_range_list *list,
unsigned int freq);
char * freq_range_list_str(const struct wpa_freq_range_list *list);
int int_array_len(const int *a);
void int_array_concat(int **res, const int *a);
void int_array_sort_unique(int *a);
void int_array_add_unique(int **res, int a);
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
void str_clear_free(char *str);
void bin_clear_free(void *bin, size_t len);
int random_mac_addr(u8 *addr);
int random_mac_addr_keep_oui(u8 *addr);
const char * cstr_token(const char *str, const char *delim, const char **last);
char * str_token(char *str, const char *delim, char **context);
size_t utf8_escape(const char *inp, size_t in_size,
char *outp, size_t out_size);
size_t utf8_unescape(const char *inp, size_t in_size,
char *outp, size_t out_size);
int is_ctrl_char(char c);
#ifndef bswap_16
#define bswap_16(a) ((((u16) (a) << 8) & 0xff00) | (((u16) (a) >> 8) & 0xff))
#endif
/*
* gcc 4.4 ends up generating strict-aliasing warnings about some very common
* networking socket uses that do not really result in a real problem and
* cannot be easily avoided with union-based type-punning due to struct
* definitions including another struct in system header files. To avoid having
* to fully disable strict-aliasing warnings, provide a mechanism to hide the
* typecast from aliasing for now. A cleaner solution will hopefully be found
* in the future to handle these cases.
*/
void * __hide_aliasing_typecast(void *foo);
#define aliasing_hide_typecast(a,t) (t *) __hide_aliasing_typecast((a))
#ifdef CONFIG_VALGRIND
#include <valgrind/memcheck.h>
#define WPA_MEM_DEFINED(ptr, len) VALGRIND_MAKE_MEM_DEFINED((ptr), (len))
#else /* CONFIG_VALGRIND */
#define WPA_MEM_DEFINED(ptr, len) do { } while (0)
#endif /* CONFIG_VALGRIND */
#endif /* COMMON_H */

View File

@@ -0,0 +1,119 @@
#ifndef INCLUDES_H
#define INCLUDES_H
#define CONFIG_NO_STDOUT_DEBUG
#ifndef CONFIG_NO_STDOUT_DEBUG
/* Event messages with fixed prefix */
/** Authentication completed successfully and data connection enabled */
#define WPA_EVENT_CONNECTED "CTRL-EVENT-CONNECTED "
/** Disconnected, data connection is not available */
#define WPA_EVENT_DISCONNECTED "CTRL-EVENT-DISCONNECTED "
/** Association rejected during connection attempt */
#define WPA_EVENT_ASSOC_REJECT "CTRL-EVENT-ASSOC-REJECT "
/** Authentication rejected during connection attempt */
#define WPA_EVENT_AUTH_REJECT "CTRL-EVENT-AUTH-REJECT "
/** wpa_supplicant is exiting */
#define WPA_EVENT_TERMINATING "CTRL-EVENT-TERMINATING "
/** Password change was completed successfully */
#define WPA_EVENT_PASSWORD_CHANGED "CTRL-EVENT-PASSWORD-CHANGED "
/** EAP-Request/Notification received */
#define WPA_EVENT_EAP_NOTIFICATION "CTRL-EVENT-EAP-NOTIFICATION "
/** EAP authentication started (EAP-Request/Identity received) */
#define WPA_EVENT_EAP_STARTED "CTRL-EVENT-EAP-STARTED "
/** EAP method proposed by the server */
#define WPA_EVENT_EAP_PROPOSED_METHOD "CTRL-EVENT-EAP-PROPOSED-METHOD "
/** EAP method selected */
#define WPA_EVENT_EAP_METHOD "CTRL-EVENT-EAP-METHOD "
/** EAP peer certificate from TLS */
#define WPA_EVENT_EAP_PEER_CERT "CTRL-EVENT-EAP-PEER-CERT "
/** EAP peer certificate alternative subject name component from TLS */
#define WPA_EVENT_EAP_PEER_ALT "CTRL-EVENT-EAP-PEER-ALT "
/** EAP TLS certificate chain validation error */
#define WPA_EVENT_EAP_TLS_CERT_ERROR "CTRL-EVENT-EAP-TLS-CERT-ERROR "
/** EAP status */
#define WPA_EVENT_EAP_STATUS "CTRL-EVENT-EAP-STATUS "
/** EAP authentication completed successfully */
#define WPA_EVENT_EAP_SUCCESS "CTRL-EVENT-EAP-SUCCESS "
/** EAP authentication failed (EAP-Failure received) */
#define WPA_EVENT_EAP_FAILURE "CTRL-EVENT-EAP-FAILURE "
/** Network block temporarily disabled (e.g., due to authentication failure) */
#define WPA_EVENT_TEMP_DISABLED "CTRL-EVENT-SSID-TEMP-DISABLED "
/** Temporarily disabled network block re-enabled */
#define WPA_EVENT_REENABLED "CTRL-EVENT-SSID-REENABLED "
/** New scan started */
#define WPA_EVENT_SCAN_STARTED "CTRL-EVENT-SCAN-STARTED "
/** New scan results available */
#define WPA_EVENT_SCAN_RESULTS "CTRL-EVENT-SCAN-RESULTS "
/** Scan command failed */
#define WPA_EVENT_SCAN_FAILED "CTRL-EVENT-SCAN-FAILED "
/** wpa_supplicant state change */
#define WPA_EVENT_STATE_CHANGE "CTRL-EVENT-STATE-CHANGE "
/** A new BSS entry was added (followed by BSS entry id and BSSID) */
#define WPA_EVENT_BSS_ADDED "CTRL-EVENT-BSS-ADDED "
/** A BSS entry was removed (followed by BSS entry id and BSSID) */
#define WPA_EVENT_BSS_REMOVED "CTRL-EVENT-BSS-REMOVED "
/** No suitable network was found */
#define WPA_EVENT_NETWORK_NOT_FOUND "CTRL-EVENT-NETWORK-NOT-FOUND "
/** Change in the signal level was reported by the driver */
#define WPA_EVENT_SIGNAL_CHANGE "CTRL-EVENT-SIGNAL-CHANGE "
/** Regulatory domain channel */
#define WPA_EVENT_REGDOM_CHANGE "CTRL-EVENT-REGDOM-CHANGE "
/** RSN IBSS 4-way handshakes completed with specified peer */
#define IBSS_RSN_COMPLETED "IBSS-RSN-COMPLETED "
/** Notification of frequency conflict due to a concurrent operation.
*
* The indicated network is disabled and needs to be re-enabled before it can
* be used again.
*/
#define WPA_EVENT_FREQ_CONFLICT "CTRL-EVENT-FREQ-CONFLICT "
/** Frequency ranges that the driver recommends to avoid */
#define WPA_EVENT_AVOID_FREQ "CTRL-EVENT-AVOID-FREQ "
/** WPS overlap detected in PBC mode */
#define WPS_EVENT_OVERLAP "WPS-OVERLAP-DETECTED "
/** Available WPS AP with active PBC found in scan results */
#define WPS_EVENT_AP_AVAILABLE_PBC "WPS-AP-AVAILABLE-PBC "
/** Available WPS AP with our address as authorized in scan results */
#define WPS_EVENT_AP_AVAILABLE_AUTH "WPS-AP-AVAILABLE-AUTH "
/** Available WPS AP with recently selected PIN registrar found in scan results
*/
#define WPS_EVENT_AP_AVAILABLE_PIN "WPS-AP-AVAILABLE-PIN "
/** Available WPS AP found in scan results */
#define WPS_EVENT_AP_AVAILABLE "WPS-AP-AVAILABLE "
/** A new credential received */
#define WPS_EVENT_CRED_RECEIVED "WPS-CRED-RECEIVED "
/** M2D received */
#define WPS_EVENT_M2D "WPS-M2D "
/** WPS registration failed after M2/M2D */
#define WPS_EVENT_FAIL "WPS-FAIL "
/** WPS registration completed successfully */
#define WPS_EVENT_SUCCESS "WPS-SUCCESS "
/** WPS enrollment attempt timed out and was terminated */
#define WPS_EVENT_TIMEOUT "WPS-TIMEOUT "
/* PBC mode was activated */
#define WPS_EVENT_ACTIVE "WPS-PBC-ACTIVE "
/* PBC mode was disabled */
#define WPS_EVENT_DISABLE "WPS-PBC-DISABLE "
#define WPS_EVENT_ENROLLEE_SEEN "WPS-ENROLLEE-SEEN "
#define WPS_EVENT_OPEN_NETWORK "WPS-OPEN-NETWORK "
/* WPS ER events */
#define WPS_EVENT_ER_AP_ADD "WPS-ER-AP-ADD "
#define WPS_EVENT_ER_AP_REMOVE "WPS-ER-AP-REMOVE "
#define WPS_EVENT_ER_ENROLLEE_ADD "WPS-ER-ENROLLEE-ADD "
#define WPS_EVENT_ER_ENROLLEE_REMOVE "WPS-ER-ENROLLEE-REMOVE "
#define WPS_EVENT_ER_AP_SETTINGS "WPS-ER-AP-SETTINGS "
#define WPS_EVENT_ER_SET_SEL_REG "WPS-ER-AP-SET-SEL-REG "
#endif /* CONFIG_NO_STDOUT_DEBUG */
//#define DBG_871X(...) vTaskDelay(100)
//DBG_871X_LEVEL(_drv_always_, "no beacon for a long time, disconnect or roaming\n");
//#define DBG_871X(...) DBG_871X_LEVEL(_drv_always_,...)
#endif /* INCLUDES_H */

View File

@@ -0,0 +1,599 @@
/*
* OS specific functions
* Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef OS_H
#define OS_H
//#include "basic_types.h"
#include <autoconf.h>
#include "osdep_service.h"
//#include "freertos/wrapper.h"
#include "utils/rom/rom_wps_os.h"
typedef void* xqueue_handle_t;
typedef long os_time_t;
typedef _timer os_timer;
/**
* os_sleep - Sleep (sec, usec)
* @sec: Number of seconds to sleep
* @usec: Number of microseconds to sleep
*/
void os_sleep(os_time_t sec, os_time_t usec);
struct os_time {
os_time_t sec;
os_time_t usec;
};
struct os_reltime {
os_time_t sec;
os_time_t usec;
};
/**
* os_get_time - Get current time (sec, usec)
* @t: Pointer to buffer for the time
* Returns: 0 on success, -1 on failure
*/
int os_get_time(struct os_time *t);
int os_get_reltime(struct os_reltime *t);
/* Helper macros for handling struct os_time */
/* (&timeout->time, &tmp->time) */
#define os_time_before(a, b) \
((a)->sec < (b)->sec || \
((a)->sec == (b)->sec && (a)->usec < (b)->usec))
#define os_time_sub(a, b, res) do { \
(res)->sec = (a)->sec - (b)->sec; \
(res)->usec = (a)->usec - (b)->usec; \
if ((res)->usec < 0) { \
(res)->sec--; \
(res)->usec += 1000000; \
} \
} while (0)
/**
* os_mktime - Convert broken-down time into seconds since 1970-01-01
* @year: Four digit year
* @month: Month (1 .. 12)
* @day: Day of month (1 .. 31)
* @hour: Hour (0 .. 23)
* @min: Minute (0 .. 59)
* @sec: Second (0 .. 60)
* @t: Buffer for returning calendar time representation (seconds since
* 1970-01-01 00:00:00)
* Returns: 0 on success, -1 on failure
*
* Note: The result is in seconds from Epoch, i.e., in UTC, not in local time
* which is used by POSIX mktime().
*/
int os_mktime(int year, int month, int day, int hour, int min, int sec,
os_time_t *t);
struct os_tm {
int sec; /* 0..59 or 60 for leap seconds */
int min; /* 0..59 */
int hour; /* 0..23 */
int day; /* 1..31 */
int month; /* 1..12 */
int year; /* Four digit year */
};
int os_gmtime(os_time_t t, struct os_tm *tm);
/* Helpers for handling struct os_time */
/* Helpers for handling struct os_reltime */
static inline int os_reltime_before(struct os_reltime *a,
struct os_reltime *b)
{
return os_time_before(a,b);
}
static inline void os_reltime_sub(struct os_reltime *a, struct os_reltime *b,
struct os_reltime *res)
{
os_time_sub(a,b,res);
}
static inline void os_reltime_age(struct os_reltime *start,
struct os_reltime *age)
{
struct os_reltime now;
os_get_time((struct os_time *)&now);
os_reltime_sub(&now, start, age);
}
static inline int os_reltime_expired(struct os_reltime *now,
struct os_reltime *ts,
os_time_t timeout_secs)
{
struct os_reltime age;
os_reltime_sub(now, ts, &age);
return (age.sec > timeout_secs) ||
(age.sec == timeout_secs && age.usec > 0);
}
/**
* os_daemonize - Run in the background (detach from the controlling terminal)
* @pid_file: File name to write the process ID to or %NULL to skip this
* Returns: 0 on success, -1 on failure
*/
int os_daemonize(const char *pid_file);
/**
* os_daemonize_terminate - Stop running in the background (remove pid file)
* @pid_file: File name to write the process ID to or %NULL to skip this
*/
void os_daemonize_terminate(const char *pid_file);
/**
* os_get_random - Get cryptographically strong pseudo random data
* @buf: Buffer for pseudo random data
* @len: Length of the buffer
* Returns: 0 on success, -1 on failure
*/
int os_get_random(unsigned char *buf, size_t len);
/**
* os_random - Get pseudo random value (not necessarily very strong)
* Returns: Pseudo random value
*/
unsigned long os_random(void);
/**
* os_rel2abs_path - Get an absolute path for a file
* @rel_path: Relative path to a file
* Returns: Absolute path for the file or %NULL on failure
*
* This function tries to convert a relative path of a file to an absolute path
* in order for the file to be found even if current working directory has
* changed. The returned value is allocated and caller is responsible for
* freeing it. It is acceptable to just return the same path in an allocated
* buffer, e.g., return strdup(rel_path). This function is only used to find
* configuration files when os_daemonize() may have changed the current working
* directory and relative path would be pointing to a different location.
*/
char * os_rel2abs_path(const char *rel_path);
/**
* os_program_init - Program initialization (called at start)
* Returns: 0 on success, -1 on failure
*
* This function is called when a programs starts. If there are any OS specific
* processing that is needed, it can be placed here. It is also acceptable to
* just return 0 if not special processing is needed.
*/
int os_program_init(void);
/**
* os_program_deinit - Program deinitialization (called just before exit)
*
* This function is called just before a program exists. If there are any OS
* specific processing, e.g., freeing resourced allocated in os_program_init(),
* it should be done here. It is also acceptable for this function to do
* nothing.
*/
void os_program_deinit(void);
/**
* os_setenv - Set environment variable
* @name: Name of the variable
* @value: Value to set to the variable
* @overwrite: Whether existing variable should be overwritten
* Returns: 0 on success, -1 on error
*
* This function is only used for wpa_cli action scripts. OS wrapper does not
* need to implement this if such functionality is not needed.
*/
int os_setenv(const char *name, const char *value, int overwrite);
/**
* os_unsetenv - Delete environent variable
* @name: Name of the variable
* Returns: 0 on success, -1 on error
*
* This function is only used for wpa_cli action scripts. OS wrapper does not
* need to implement this if such functionality is not needed.
*/
int os_unsetenv(const char *name);
/**
* os_readfile - Read a file to an allocated memory buffer
* @name: Name of the file to read
* @len: For returning the length of the allocated buffer
* Returns: Pointer to the allocated buffer or %NULL on failure
*
* This function allocates memory and reads the given file to this buffer. Both
* binary and text files can be read with this function. The caller is
* responsible for freeing the returned buffer with os_free().
*/
char * os_readfile(const char *name, size_t *len);
//#if 0
/**
* os_zalloc - Allocate and zero memory
* @size: Number of bytes to allocate
* Returns: Pointer to allocated and zeroed memory or %NULL on failure
*
* Caller is responsible for freeing the returned buffer with os_free().
*/
void * os_zalloc(size_t size);
/**
* os_calloc - Allocate and zero memory for an array
* @nmemb: Number of members in the array
* @size: Number of bytes in each member
* Returns: Pointer to allocated and zeroed memory or %NULL on failure
*
* This function can be used as a wrapper for os_zalloc(nmemb * size) when an
* allocation is used for an array. The main benefit over os_zalloc() is in
* having an extra check to catch integer overflows in multiplication.
*
* Caller is responsible for freeing the returned buffer with os_free().
*/
static inline void * os_calloc(size_t nmemb, size_t size)
{
if (size && nmemb > (~(size_t) 0) / size)
return NULL;
return os_zalloc(nmemb * size);
}
//#endif
static inline int os_memcmp_const(const void *a, const void *b, size_t len)
{
const u8 *aa = a;
const u8 *bb = b;
size_t i;
u8 res;
for (res = 0, i = 0; i < len; i++)
res |= aa[i] ^ bb[i];
return res;
}
/*
* The following functions are wrapper for standard ANSI C or POSIX functions.
* By default, they are just defined to use the standard function name and no
* os_*.c implementation is needed for them. This avoids extra function calls
* by allowing the C pre-processor take care of the function name mapping.
*
* If the target system uses a C library that does not provide these functions,
* build_config.h can be used to define the wrappers to use a different
* function name. This can be done on function-by-function basis since the
* defines here are only used if build_config.h does not define the os_* name.
* If needed, os_*.c file can be used to implement the functions that are not
* included in the C library on the target system. Alternatively,
* OS_NO_C_LIB_DEFINES can be defined to skip all defines here in which case
* these functions need to be implemented in os_*.c file for the target system.
*/
#ifdef OS_NO_C_LIB_DEFINES
/**
* os_malloc - Allocate dynamic memory
* @size: Size of the buffer to allocate
* Returns: Allocated buffer or %NULL on failure
*
* Caller is responsible for freeing the returned buffer with os_free().
*/
void * os_malloc(size_t size);
/**
* os_realloc - Re-allocate dynamic memory
* @ptr: Old buffer from os_malloc() or os_realloc()
* @size: Size of the new buffer
* Returns: Allocated buffer or %NULL on failure
*
* Caller is responsible for freeing the returned buffer with os_free().
* If re-allocation fails, %NULL is returned and the original buffer (ptr) is
* not freed and caller is still responsible for freeing it.
*/
void * os_realloc(void *ptr, size_t size);
/**
* os_free - Free dynamic memory
* @ptr: Old buffer from os_malloc() or os_realloc(); can be %NULL
*/
void os_free(void *ptr);
/**
* os_memcpy - Copy memory area
* @dest: Destination
* @src: Source
* @n: Number of bytes to copy
* Returns: dest
*
* The memory areas src and dst must not overlap. os_memmove() can be used with
* overlapping memory.
*/
void * os_memcpy(void *dest, const void *src, size_t n);
/**
* os_memmove - Copy memory area
* @dest: Destination
* @src: Source
* @n: Number of bytes to copy
* Returns: dest
*
* The memory areas src and dst may overlap.
*/
void *os_memmove(void *dest, const void *src, size_t n);
/**
* os_memset - Fill memory with a constant byte
* @s: Memory area to be filled
* @c: Constant byte
* @n: Number of bytes started from s to fill with c
* Returns: s
*/
void *os_memset(void *s, int c, size_t n);
/**
* os_memcmp - Compare memory areas
* @s1: First buffer
* @s2: Second buffer
* @n: Maximum numbers of octets to compare
* Returns: An integer less than, equal to, or greater than zero if s1 is
* found to be less than, to match, or be greater than s2. Only first n
* characters will be compared.
*/
int os_memcmp(const void *s1, const void *s2, size_t n);
/**
* os_strdup - Duplicate a string
* @s: Source string
* Returns: Allocated buffer with the string copied into it or %NULL on failure
*
* Caller is responsible for freeing the returned buffer with os_free().
*/
char *os_strdup(const char *s);
/**
* os_strlen - Calculate the length of a string
* @s: '\0' terminated string
* Returns: Number of characters in s (not counting the '\0' terminator)
*/
size_t os_strlen(const char *s);
/**
* os_strcasecmp - Compare two strings ignoring case
* @s1: First string
* @s2: Second string
* Returns: An integer less than, equal to, or greater than zero if s1 is
* found to be less than, to match, or be greatred than s2
*/
int os_strcasecmp(const char *s1, const char *s2);
/**
* os_strncasecmp - Compare two strings ignoring case
* @s1: First string
* @s2: Second string
* @n: Maximum numbers of characters to compare
* Returns: An integer less than, equal to, or greater than zero if s1 is
* found to be less than, to match, or be greater than s2. Only first n
* characters will be compared.
*/
int os_strncasecmp(const char *s1, const char *s2, size_t n);
/**
* os_strchr - Locate the first occurrence of a character in string
* @s: String
* @c: Character to search for
* Returns: Pointer to the matched character or %NULL if not found
*/
char *os_strchr(const char *s, int c);
/**
* os_strrchr - Locate the last occurrence of a character in string
* @s: String
* @c: Character to search for
* Returns: Pointer to the matched character or %NULL if not found
*/
char *os_strrchr(const char *s, int c);
/**
* os_strcmp - Compare two strings
* @s1: First string
* @s2: Second string
* Returns: An integer less than, equal to, or greater than zero if s1 is
* found to be less than, to match, or be greatred than s2
*/
int os_strcmp(const char *s1, const char *s2);
/**
* os_strncmp - Compare two strings
* @s1: First string
* @s2: Second string
* @n: Maximum numbers of characters to compare
* Returns: An integer less than, equal to, or greater than zero if s1 is
* found to be less than, to match, or be greater than s2. Only first n
* characters will be compared.
*/
int os_strncmp(const char *s1, const char *s2, size_t n);
/**
* os_strncpy - Copy a string
* @dest: Destination
* @src: Source
* @n: Maximum number of characters to copy
* Returns: dest
*/
char *os_strncpy(char *dest, const char *src, size_t n);
/**
* os_strstr - Locate a substring
* @haystack: String (haystack) to search from
* @needle: Needle to search from haystack
* Returns: Pointer to the beginning of the substring or %NULL if not found
*/
char *os_strstr(const char *haystack, const char *needle);
/**
* os_snprintf - Print to a memory buffer
* @str: Memory buffer to print into
* @size: Maximum length of the str buffer
* @format: printf format
* Returns: Number of characters printed (not including trailing '\0').
*
* If the output buffer is truncated, number of characters which would have
* been written is returned. Since some C libraries return -1 in such a case,
* the caller must be prepared on that value, too, to indicate truncation.
*
* Note: Some C library implementations of snprintf() may not guarantee null
* termination in case the output is truncated. The OS wrapper function of
* os_snprintf() should provide this guarantee, i.e., to null terminate the
* output buffer if a C library version of the function is used and if that
* function does not guarantee null termination.
*
* If the target system does not include snprintf(), see, e.g.,
* http://www.ijs.si/software/snprintf/ for an example of a portable
* implementation of snprintf.
*/
int os_snprintf(char *str, size_t size, const char *format, ...);
#else /* OS_NO_C_LIB_DEFINES */
#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B)
#ifdef CONFIG_MEM_MONITOR
u8* os_malloc(u32 sz);
void os_mfree(u8 *pbuf, u32 sz);
#ifndef os_free
#define os_free(p, sz) os_mfree(((u8*)(p)), (sz))
#endif
#else
#ifndef os_malloc
#define os_malloc(sz) _rtw_malloc(sz)
#endif
#ifndef os_free
#define os_free(p, sz) _rtw_mfree(((u8*)(p)), (sz))
#endif
#endif
#endif
extern void *os_zalloc(size_t size);
extern char *os_strdup(const char *string_copy_from);
#ifndef os_sleep
#define os_sleep(s, us) rtw_mdelay_os((s)*1000 + (us)/1000)
#endif
#ifndef os_memcpy
#define os_memcpy(d, s, n) rtw_memcpy((void*)(d), ((void*)(s)), (n))
#endif
#ifndef os_memmove
#define os_memmove(d, s, n) memmove((d), (s), (n))
#endif
#ifndef os_memset
#define os_memset(pbuf, c, sz) rtw_memset(pbuf, c, sz)
#endif
#ifndef os_memcmp
#define os_memcmp(s1, s2, n) rtw_memcmp(((void*)(s1)), ((void*)(s2)), (n))
#endif
#ifndef os_memcmp_p2p
#define os_memcmp_p2p(s1, s2, n) memcmp((s1), (s2), (n))
#endif
#ifndef os_get_random_bytes
#define os_get_random_bytes(d,sz) rtw_get_random_bytes(((void*)(d)), (sz))
#endif
#ifndef os_strlen
#define os_strlen(s) strlen(s)
#endif
#ifndef os_strcasecmp
#ifdef _MSC_VER
#define os_strcasecmp(s1, s2) _stricmp((s1), (s2))
#else
#define os_strcasecmp(s1, s2) strcasecmp((s1), (s2))
#endif
#endif
#ifndef os_strncasecmp
#ifdef _MSC_VER
#define os_strncasecmp(s1, s2, n) _strnicmp((s1), (s2), (n))
#else
#define os_strncasecmp(s1, s2, n) strncasecmp((s1), (s2), (n))
#endif
#endif
#ifndef os_init_timer
#define os_init_timer(t, p, f, x, n) rtw_init_timer((t), (p), (f), (x), (n))
#endif
#ifndef os_set_timer
#define os_set_timer(t, d) rtw_set_timer((t), (d))
#endif
#ifndef os_cancel_timer
#define os_cancel_timer(t) rtw_cancel_timer(t)
#endif
#ifndef os_del_timer
#define os_del_timer(t) rtw_del_timer(t)
#endif
#ifndef os_atoi
#define os_atoi(s) rtw_atoi(s)
#endif
#ifndef os_strchr
#define os_strchr(s, c) strchr((s), (c))
#endif
#ifndef os_strcmp
#define os_strcmp(s1, s2) strcmp((s1), (s2))
#endif
#ifndef os_strncmp
#define os_strncmp(s1, s2, n) strncmp((s1), (s2), (n))
#endif
#ifndef os_strncpy
#define os_strncpy(d, s, n) strncpy((d), (s), (n))
#endif
#ifndef os_strrchr
#define os_strrchr(s, c) strrchr((s), (c))
#endif
#ifndef os_strstr
#define os_strstr(h, n) strstr((h), (n))
#endif
#ifndef os_snprintf
#ifdef _MSC_VER
#define os_snprintf _snprintf
#else
#define os_snprintf snprintf
#endif
#endif
#endif /* OS_NO_C_LIB_DEFINES */
static inline void * os_realloc_array(void *ptr, size_t nmemb, size_t size)
{
if (size && nmemb > (~(size_t) 0) / size)
return NULL;
if(ptr == NULL){
return os_malloc(nmemb * size);
}
else{
return os_realloc(ptr, nmemb * size, nmemb * size);
}
}
void *os_xqueue_create(unsigned long uxQueueLength, unsigned long uxItemSize) ;
int os_xqueue_receive(xqueue_handle_t xQueue, void * const pvBuffer, unsigned long xSecsToWait);
void os_xqueue_delete(xqueue_handle_t xQueue );
int os_xqueue_send(xqueue_handle_t xQueue, const void * const pvItemToQueue, unsigned long xSecsToWait);
#endif /* OS_H */

View File

@@ -0,0 +1,119 @@
/*
* OS specific functions for UNIX/POSIX systems
* Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "utils/os.h"
//#ifdef CONFIG_WPS
#if !defined(CONFIG_PLATFORM_8195A) && !defined(CONFIG_PLATFORM_8711B)
#ifdef CONFIG_MEM_MONITOR
#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK
_list wpa_mem_table;
int wpa_mem_used_num;
//int wpa_mem_used_size;
#endif
extern int min_free_heap_size;
u8* os_malloc(u32 sz)
{
int free_heap_size = rtw_getFreeHeapSize();
u8 *pbuf = _rtw_malloc(sz);
#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK
add_mem_usage(&wpa_mem_table, pbuf, sz, &wpa_mem_used_num, MEM_MONITOR_FLAG_WPAS);
#else
add_mem_usage(NULL, pbuf, sz, NULL, MEM_MONITOR_FLAG_WPAS);
#endif
if(min_free_heap_size > free_heap_size)
min_free_heap_size = free_heap_size;
return pbuf;
}
void os_mfree(u8 *pbuf, u32 sz)
{
_rtw_mfree(pbuf, sz);
#if CONFIG_MEM_MONITOR & MEM_MONITOR_LEAK
del_mem_usage(&wpa_mem_table, pbuf, &wpa_mem_used_num, MEM_MONITOR_FLAG_WPAS);
#else
del_mem_usage(NULL, pbuf, NULL, MEM_MONITOR_FLAG_WPAS);
#endif
}
#endif//CONFIG_MEM_MONITOR
#endif// !defined(CONFIG_PLATFORM_8195A)
#ifndef OS_NO_C_LIB_DEFINES
char *os_strdup(const char *string_copy_from)
{
char *string_copy_to = NULL;
string_copy_to = os_zalloc(strlen(string_copy_from) + 1);
os_memcpy((void *)string_copy_to, string_copy_from, strlen(string_copy_from));
string_copy_to[strlen(string_copy_from)] = '\0';
return string_copy_to;
}
#endif
int os_get_random(unsigned char *buf, size_t len)
{
//TODO implement it
rtw_get_random_bytes(buf, len);
return 0;
}
int os_get_time(struct os_time *t){
unsigned int tt = rtw_get_current_time();
t->sec = (os_time_t) (tt / 1000);
t->usec = (os_time_t) (tt % 1000)*1000;
return 0;
}
int os_get_reltime(struct os_reltime *t){
os_get_time((struct os_time *)t);
return 0;
}
#if 0
void *os_xqueue_create(unsigned long uxQueueLength, unsigned long uxItemSize)
{
return xQueueCreate( uxQueueLength, uxItemSize );
}
int os_xqueue_receive(xqueue_handle_t xQueue, void * const pvBuffer, unsigned long xSecsToWait)
{
return xQueueReceive((xQueueHandle)xQueue, pvBuffer, (portTickType)(xSecsToWait*configTICK_RATE_HZ));
}
void os_xqueue_delete(xqueue_handle_t xQueue )
{
vQueueDelete((xQueueHandle)xQueue);
}
int os_xqueue_send(xqueue_handle_t xQueue, const void * const pvItemToQueue, unsigned long xSecsToWait)
{
return xQueueSendToBack((xQueueHandle)xQueue, pvItemToQueue, (portTickType)(xSecsToWait*configTICK_RATE_HZ));
}
#else
void *os_xqueue_create(unsigned long uxQueueLength, unsigned long uxItemSize)
{
void* xQueue = NULL;
rtw_init_xqueue(&xQueue, "queue", uxItemSize, uxQueueLength);
return xQueue;
}
int os_xqueue_receive(xqueue_handle_t xQueue, void * const pvBuffer, unsigned long xSecsToWait)
{
return rtw_pop_from_xqueue(&xQueue, pvBuffer, xSecsToWait*1000);
}
void os_xqueue_delete(xqueue_handle_t xQueue )
{
rtw_deinit_xqueue(&xQueue);
}
int os_xqueue_send(xqueue_handle_t xQueue, const void * const pvItemToQueue, unsigned long xSecsToWait)
{
return rtw_push_to_xqueue(&xQueue, (void*)pvItemToQueue, xSecsToWait*1000);
}
#endif
//#endif

View File

@@ -0,0 +1,24 @@
/*
* OS specific functions
* Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef ROM_WPS_OS_H
#define ROM_WPS_OS_H
#if defined(CONFIG_PLATFORM_8195A) || defined(CONFIG_PLATFORM_8711B)
#include <rom_wlan_ram_map.h>
extern struct _rom_wlan_ram_map rom_wlan_ram_map;
#define os_malloc(sz) rom_wlan_ram_map.rtw_malloc(sz)
#define os_free(p, sz) rom_wlan_ram_map.rtw_mfree(((u8*)(p)), (sz))
#endif
extern u8 *WPS_realloc(u8 *old_buf, u32 old_sz, u32 new_sz);
#define os_realloc(p, os, ns) WPS_realloc(((u8*)(p)),(os),(ns))
#endif /* ROM_WPS_OS_H */

View File

@@ -0,0 +1,31 @@
/*
* Universally Unique IDentifier (UUID)
* Copyright (c) 2008, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef UUID_H
#define UUID_H
#include <platform/platform_stdlib.h>
#define UUID_LEN 16
int uuid_str2bin(const char *str, u8 *bin);
static int uuid_bin2str(const u8 *bin, char *str, size_t max_len)
{
int len;
len = os_snprintf(str, max_len, "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
"%02x%02x-%02x%02x%02x%02x%02x%02x",
bin[0], bin[1], bin[2], bin[3],
bin[4], bin[5], bin[6], bin[7],
bin[8], bin[9], bin[10], bin[11],
bin[12], bin[13], bin[14], bin[15]);
if (len < 0 || (size_t) len >= max_len)
return -1;
return 0;
}
int is_nil_uuid(const u8 *uuid);
#endif /* UUID_H */

View File

@@ -0,0 +1,79 @@
/*
* wpa_supplicant/hostapd / Debug prints
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef WPA_DEBUG_H
#define WPA_DEBUG_H
#include "utils/wpabuf.h"
/* Debugging function - conditional printf and hex dump. Driver wrappers can
* use these for debugging purposes. */
enum {
MSG_EXCESSIVE, MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_ALWAYS, MSG_WARNING, MSG_ERROR
};
#define wpa_debug_print_timestamp() do { } while (0)
#define wpa_hexdump(l,t,b,le) do { } while (0)
#define wpa_hexdump_buf_key(l,t,b) do { } while (0)
#define wpa_hexdump_ascii_key(l,t,b,le) do { } while (0)
#define wpa_debug_open_file(p) do { } while (0)
#define wpa_debug_close_file() do { } while (0)
#define wpa_dbg(args...) do { } while (0)
#define wpa_msg_ctrl(args...) do { } while (0)
#define wpa_msg_register_cb(f) do { } while (0)
#define wpa_msg_register_ifname_cb(f) do { } while (0)
static inline int wpa_debug_reopen_file(void)
{
return 0;
}
#define wprintf(fmt, arg...) printf("[%d] "fmt, rtw_get_current_time(),##arg)
#ifdef CONFIG_NO_STDOUT_DEBUG
#define wpa_printf(args...) do { } while (0)
#define wpa_hexdump_buf(l,t,b) do { } while (0)
#define wpa_hexdump_key(l,t,b,le) do { } while (0)
#define wpa_hexdump_ascii(l,t,b,le) do { } while (0)
#define wpa_msg(args...) do { } while (0)
#else
//void wpa_printf(int level, const char *fmt, ...);
#define wpa_printf(level, fmt, arg...) \
do {\
if (level >= MSG_INFO) {\
{\
printf("\r\n%d:", rtw_get_current_time());\
printf(fmt, ##arg);\
printf("\n\r");\
} \
}\
}while(0)
#define wpa_msg(ctx,level,fmt,arg...) wpa_printf((level),(fmt), ##arg)
void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len);
void wpa_hexdump_buf(int level, const char *title,
const struct wpabuf *buf);
void wpa_hexdump_ascii(int level, const char *title, const void *buf,
size_t len);
#ifdef EAPOL_TEST
#define WPA_ASSERT(a) \
do { \
if (!(a)) { \
printf("WPA_ASSERT FAILED '" #a "' " \
"%s %s:%d\n", \
__FUNCTION__, __FILE__, __LINE__); \
exit(1); \
} \
} while (0)
#else
#define WPA_ASSERT(a) do { } while (0)
#endif
#endif //CONFIG_NO_STDOUT_DEBUG
#endif /* WPA_DEBUG_H */

View File

@@ -0,0 +1,188 @@
/*
* Dynamic data buffer
* Copyright (c) 2007-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef WPABUF_H
#define WPABUF_H
/* wpabuf::buf is a pointer to external data */
#define WPABUF_FLAG_EXT_DATA BIT(0)
/*
* Internal data structure for wpabuf. Please do not touch this directly from
* elsewhere. This is only defined in header file to allow inline functions
* from this file to access data.
*/
struct wpabuf {
size_t size; /* total size of the allocated buffer (i.e allocated buffer size)*/
size_t used; /* length of data in the buffer (i.e data length) */
u8 *buf; /* pointer to the head of the buffer (i.e buffer address) */
unsigned int flags;
/* optionally followed by the allocated buffer */
};
int wpabuf_resize(struct wpabuf **buf, size_t add_len);
struct wpabuf * wpabuf_alloc(size_t len);
struct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len);
struct wpabuf * wpabuf_alloc_copy(const void *data, size_t len);
struct wpabuf * wpabuf_dup(const struct wpabuf *src);
void wpabuf_free(struct wpabuf *buf);
void * wpabuf_put(struct wpabuf *buf, size_t len);
struct wpabuf * wpabuf_concat(struct wpabuf *a, struct wpabuf *b);
struct wpabuf * wpabuf_zeropad(struct wpabuf *buf, size_t len);
void wpabuf_printf(struct wpabuf *buf, char *fmt, ...) PRINTF_FORMAT(2, 3);
/**
* wpabuf_size - Get the currently allocated size of a wpabuf buffer
* @buf: wpabuf buffer
* Returns: Currently allocated size of the buffer
*/
static inline size_t wpabuf_size(const struct wpabuf *buf)
{
return buf->size;
}
/**
* wpabuf_len - Get the current length of a wpabuf buffer data
* @buf: wpabuf buffer
* Returns: Currently used length of the buffer
*/
static inline size_t wpabuf_len(const struct wpabuf *buf)
{
return buf->used;
}
/**
* wpabuf_tailroom - Get size of available tail room in the end of the buffer
* @buf: wpabuf buffer
* Returns: Tail room (in bytes) of available space in the end of the buffer
*/
static inline size_t wpabuf_tailroom(const struct wpabuf *buf)
{
return buf->size - buf->used;
}
/**
* wpabuf_head - Get pointer to the head of the buffer data
* @buf: wpabuf buffer
* Returns: Pointer to the head of the buffer data
*/
static inline const void *wpabuf_head(const struct wpabuf *buf)
{
return buf->buf;
}
static inline const u8 *wpabuf_head_u8(const struct wpabuf *buf)
{
return wpabuf_head(buf);
}
/**
* wpabuf_mhead - Get modifiable pointer to the head of the buffer data
* @buf: wpabuf buffer
* Returns: Pointer to the head of the buffer data
*/
static inline void *wpabuf_mhead(struct wpabuf *buf)
{
return buf->buf;
}
static inline u8 *wpabuf_mhead_u8(struct wpabuf *buf)
{
return wpabuf_mhead(buf);
}
static inline void wpabuf_put_u8(struct wpabuf *buf, u8 data)
{
u8 *pos = NULL;
if ( buf == NULL)
return;
pos = wpabuf_put(buf, 1);
*pos = data;
}
static inline void wpabuf_put_le16(struct wpabuf *buf, u16 data)
{
u8 *pos = NULL;
if ( buf == NULL)
return;
pos = wpabuf_put(buf, 2);
WPA_PUT_LE16(pos, data);
}
static inline void wpabuf_put_le32(struct wpabuf *buf, u32 data)
{
u8 *pos = NULL;
if ( buf == NULL)
return;
pos = wpabuf_put(buf, 4);
WPA_PUT_LE32(pos, data);
}
static inline void wpabuf_put_be16(struct wpabuf *buf, u16 data)
{
u8 *pos = NULL;
if ( buf == NULL)
return;
pos = wpabuf_put(buf, 2);
WPA_PUT_BE16(pos, data);
}
static inline void wpabuf_put_be24(struct wpabuf *buf, u32 data)
{
u8 *pos = NULL;
if ( buf == NULL)
return;
pos = wpabuf_put(buf, 3);
WPA_PUT_BE24(pos, data);
}
static inline void wpabuf_put_be32(struct wpabuf *buf, u32 data)
{
u8 *pos = NULL;
if ( buf == NULL)
return;
pos = wpabuf_put(buf, 4);
WPA_PUT_BE32(pos, data);
}
// encr >> 16 B 64 - 16 = 48
static inline void wpabuf_put_data(struct wpabuf *buf, const void *data, size_t len)
{
if ( buf == NULL)
return;
if (data)
os_memcpy(wpabuf_put(buf, len), data, len);
}
static inline void wpabuf_put_buf(struct wpabuf *dst,
const struct wpabuf *src)
{
if ( dst == NULL)
return;
wpabuf_put_data(dst, wpabuf_head(src), wpabuf_len(src));
}
static inline void wpabuf_set(struct wpabuf *buf, const void *data, size_t len)
{
if ( buf == NULL)
return;
buf->buf = (u8 *) data;
buf->flags = WPABUF_FLAG_EXT_DATA;
buf->size = buf->used = len;
}
static inline void wpabuf_put_str(struct wpabuf *dst, const char *str)
{
if ( dst == NULL)
return;
wpabuf_put_data(dst, str, os_strlen(str));
}
#endif /* WPABUF_H */

View File

@@ -0,0 +1,324 @@
/*
* Wi-Fi Protected Setup - message definitions
* Copyright (c) 2008, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef WPS_DEFS_H
#define WPS_DEFS_H
#ifdef CONFIG_WPS2
#define WPS_VERSION 0x20
#else /* CONFIG_WPS2 */
#define WPS_VERSION 0x10
#endif /* CONFIG_WPS2 */
/* Diffie-Hellman 1536-bit MODP Group; RFC 3526, Group 5 */
#define WPS_DH_GROUP (5)
#define WPS_UUID_LEN (16)
#define WPS_NONCE_LEN (16)
#define WPS_AUTHENTICATOR_LEN (8)
#define WPS_AUTHKEY_LEN (32)
#define WPS_KEYWRAPKEY_LEN (16)
#define WPS_EMSK_LEN (32)
#define WPS_PSK_LEN (16)
#define WPS_SECRET_NONCE_LEN (16)
#define WPS_HASH_LEN (32)
#define WPS_KWA_LEN (8)
#define WPS_MGMTAUTHKEY_LEN (32)
#define WPS_MGMTENCKEY_LEN (16)
#define WPS_MGMT_KEY_ID_LEN (16)
#define WPS_OOB_DEVICE_PASSWORD_MIN_LEN (16)
#define WPS_OOB_DEVICE_PASSWORD_LEN (32)
#define WPS_OOB_PUBKEY_HASH_LEN (20)
/* Attribute Types */
enum wps_attribute {
ATTR_AP_CHANNEL = 0x1001,
ATTR_ASSOC_STATE = 0x1002,
ATTR_AUTH_TYPE = 0x1003,
ATTR_AUTH_TYPE_FLAGS = 0x1004,
ATTR_AUTHENTICATOR = 0x1005,
ATTR_CONFIG_METHODS = 0x1008,
ATTR_CONFIG_ERROR = 0x1009,
ATTR_CONFIRM_URL4 = 0x100a,
ATTR_CONFIRM_URL6 = 0x100b,
ATTR_CONN_TYPE = 0x100c,
ATTR_CONN_TYPE_FLAGS = 0x100d,
ATTR_CRED = 0x100e,
ATTR_ENCR_TYPE = 0x100f,
ATTR_ENCR_TYPE_FLAGS = 0x1010,
ATTR_DEV_NAME = 0x1011,
ATTR_DEV_PASSWORD_ID = 0x1012,
ATTR_E_HASH1 = 0x1014,
ATTR_E_HASH2 = 0x1015,
ATTR_E_SNONCE1 = 0x1016,
ATTR_E_SNONCE2 = 0x1017,
ATTR_ENCR_SETTINGS = 0x1018,
ATTR_ENROLLEE_NONCE = 0x101a,
ATTR_FEATURE_ID = 0x101b,
ATTR_IDENTITY = 0x101c,
ATTR_IDENTITY_PROOF = 0x101d,
ATTR_KEY_WRAP_AUTH = 0x101e,
ATTR_KEY_ID = 0x101f,
ATTR_MAC_ADDR = 0x1020,
ATTR_MANUFACTURER = 0x1021,
ATTR_MSG_TYPE = 0x1022,
ATTR_MODEL_NAME = 0x1023,
ATTR_MODEL_NUMBER = 0x1024,
ATTR_NETWORK_INDEX = 0x1026,
ATTR_NETWORK_KEY = 0x1027,
ATTR_NETWORK_KEY_INDEX = 0x1028,
ATTR_NEW_DEVICE_NAME = 0x1029,
ATTR_NEW_PASSWORD = 0x102a,
ATTR_OOB_DEVICE_PASSWORD = 0x102c,
ATTR_OS_VERSION = 0x102d,
ATTR_POWER_LEVEL = 0x102f,
ATTR_PSK_CURRENT = 0x1030,
ATTR_PSK_MAX = 0x1031,
ATTR_PUBLIC_KEY = 0x1032,
ATTR_RADIO_ENABLE = 0x1033,
ATTR_REBOOT = 0x1034,
ATTR_REGISTRAR_CURRENT = 0x1035,
ATTR_REGISTRAR_ESTABLISHED = 0x1036,
ATTR_REGISTRAR_LIST = 0x1037,
ATTR_REGISTRAR_MAX = 0x1038,
ATTR_REGISTRAR_NONCE = 0x1039,
ATTR_REQUEST_TYPE = 0x103a,
ATTR_RESPONSE_TYPE = 0x103b,
ATTR_RF_BANDS = 0x103c,
ATTR_R_HASH1 = 0x103d,
ATTR_R_HASH2 = 0x103e,
ATTR_R_SNONCE1 = 0x103f,
ATTR_R_SNONCE2 = 0x1040,
ATTR_SELECTED_REGISTRAR = 0x1041,
ATTR_SERIAL_NUMBER = 0x1042,
ATTR_WPS_STATE = 0x1044,
ATTR_SSID = 0x1045,
ATTR_TOTAL_NETWORKS = 0x1046,
ATTR_UUID_E = 0x1047,
ATTR_UUID_R = 0x1048,
ATTR_VENDOR_EXT = 0x1049,
ATTR_VERSION = 0x104a,
ATTR_X509_CERT_REQ = 0x104b,
ATTR_X509_CERT = 0x104c,
ATTR_EAP_IDENTITY = 0x104d,
ATTR_MSG_COUNTER = 0x104e,
ATTR_PUBKEY_HASH = 0x104f,
ATTR_REKEY_KEY = 0x1050,
ATTR_KEY_LIFETIME = 0x1051,
ATTR_PERMITTED_CFG_METHODS = 0x1052,
ATTR_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053,
ATTR_PRIMARY_DEV_TYPE = 0x1054,
ATTR_SECONDARY_DEV_TYPE_LIST = 0x1055,
ATTR_PORTABLE_DEV = 0x1056,
ATTR_AP_SETUP_LOCKED = 0x1057,
ATTR_APPLICATION_EXT = 0x1058,
ATTR_EAP_TYPE = 0x1059,
ATTR_IV = 0x1060,
ATTR_KEY_PROVIDED_AUTO = 0x1061,
ATTR_802_1X_ENABLED = 0x1062,
ATTR_APPSESSIONKEY = 0x1063,
ATTR_WEPTRANSMITKEY = 0x1064,
ATTR_REQUESTED_DEV_TYPE = 0x106a,
ATTR_EXTENSIBILITY_TEST = 0x10fa /* _NOT_ defined in the spec */
};
#define WPS_VENDOR_ID_WFA 14122
/* WFA Vendor Extension subelements */
enum {
WFA_ELEM_VERSION2 = 0x00,
WFA_ELEM_AUTHORIZEDMACS = 0x01,
WFA_ELEM_NETWORK_KEY_SHAREABLE = 0x02,
WFA_ELEM_REQUEST_TO_ENROLL = 0x03,
WFA_ELEM_SETTINGS_DELAY_TIME = 0x04
};
/* Device Password ID */
enum wps_dev_password_id {
DEV_PW_DEFAULT = 0x0000,
DEV_PW_USER_SPECIFIED = 0x0001,
DEV_PW_MACHINE_SPECIFIED = 0x0002,
DEV_PW_REKEY = 0x0003,
DEV_PW_PUSHBUTTON = 0x0004,
DEV_PW_REGISTRAR_SPECIFIED = 0x0005
};
/* Message Type */
enum wps_msg_type {
WPS_START = 0x00,
WPS_Beacon = 0x01,
WPS_ProbeRequest = 0x02,
WPS_ProbeResponse = 0x03,
WPS_M1 = 0x04,
WPS_M2 = 0x05,
WPS_M2D = 0x06,
WPS_M3 = 0x07,
WPS_M4 = 0x08,
WPS_M5 = 0x09,
WPS_M6 = 0x0a,
WPS_M7 = 0x0b,
WPS_M8 = 0x0c,
WPS_WSC_ACK = 0x0d,
WPS_WSC_NACK = 0x0e,
WPS_WSC_DONE = 0x0f
};
/* Authentication Type Flags */
#define WPS_AUTH_OPEN 0x0001
#define WPS_AUTH_WPAPSK 0x0002
#define WPS_AUTH_SHARED 0x0004
#define WPS_AUTH_WPA 0x0008
#define WPS_AUTH_WPA2 0x0010
#define WPS_AUTH_WPA2PSK 0x0020
#define WPS_AUTH_TYPES (WPS_AUTH_OPEN | WPS_AUTH_WPAPSK | WPS_AUTH_SHARED | \
WPS_AUTH_WPA | WPS_AUTH_WPA2 | WPS_AUTH_WPA2PSK)
/* Encryption Type Flags */
#define WPS_ENCR_NONE 0x0001
#define WPS_ENCR_WEP 0x0002
#define WPS_ENCR_TKIP 0x0004
#define WPS_ENCR_AES 0x0008
#define WPS_ENCR_TYPES (WPS_ENCR_NONE | WPS_ENCR_WEP | WPS_ENCR_TKIP | \
WPS_ENCR_AES)
/* Configuration Error */
enum wps_config_error {
WPS_CFG_NO_ERROR = 0,
WPS_CFG_OOB_IFACE_READ_ERROR = 1,
WPS_CFG_DECRYPTION_CRC_FAILURE = 2,
WPS_CFG_24_CHAN_NOT_SUPPORTED = 3,
WPS_CFG_50_CHAN_NOT_SUPPORTED = 4,
WPS_CFG_SIGNAL_TOO_WEAK = 5,
WPS_CFG_NETWORK_AUTH_FAILURE = 6,
WPS_CFG_NETWORK_ASSOC_FAILURE = 7,
WPS_CFG_NO_DHCP_RESPONSE = 8,
WPS_CFG_FAILED_DHCP_CONFIG = 9,
WPS_CFG_IP_ADDR_CONFLICT = 10,
WPS_CFG_NO_CONN_TO_REGISTRAR = 11,
WPS_CFG_MULTIPLE_PBC_DETECTED = 12,
WPS_CFG_ROGUE_SUSPECTED = 13,
WPS_CFG_DEVICE_BUSY = 14,
WPS_CFG_SETUP_LOCKED = 15,
WPS_CFG_MSG_TIMEOUT = 16,
WPS_CFG_REG_SESS_TIMEOUT = 17,
WPS_CFG_DEV_PASSWORD_AUTH_FAILURE = 18
};
/* RF Bands */
#define WPS_RF_24GHZ (0x01)
#define WPS_RF_50GHZ (0x02)
/* Config Methods */
#define WPS_CONFIG_USBA (0x0001)
#define WPS_CONFIG_ETHERNET (0x0002)
#define WPS_CONFIG_LABEL (0x0004)
#define WPS_CONFIG_DISPLAY (0x0008)
#define WPS_CONFIG_EXT_NFC_TOKEN (0x0010)
#define WPS_CONFIG_INT_NFC_TOKEN (0x0020)
#define WPS_CONFIG_NFC_INTERFACE (0x0040)
#define WPS_CONFIG_PUSHBUTTON (0x0080)
#define WPS_CONFIG_KEYPAD (0x0100)
#ifdef CONFIG_WPS2
#define WPS_CONFIG_VIRT_PUSHBUTTON (0x0280)
#define WPS_CONFIG_PHY_PUSHBUTTON (0x0480)
#define WPS_CONFIG_VIRT_DISPLAY (0x2008)
#define WPS_CONFIG_PHY_DISPLAY (0x4008)
#endif /* CONFIG_WPS2 */
/* Connection Type Flags */
#define WPS_CONN_ESS (0x01)
#define WPS_CONN_IBSS (0x02)
/* Wi-Fi Protected Setup State */
enum wps_state {
WPS_STATE_NOT_CONFIGURED = 1,
WPS_STATE_CONFIGURED = 2
};
/* Association State */
enum wps_assoc_state {
WPS_ASSOC_NOT_ASSOC = 0,
WPS_ASSOC_CONN_SUCCESS = 1,
WPS_ASSOC_CFG_FAILURE = 2,
WPS_ASSOC_FAILURE = 3,
WPS_ASSOC_IP_FAILURE = 4
};
#define WPS_DEV_OUI_WFA (0x0050f204)
enum wps_dev_categ {
WPS_DEV_COMPUTER = 1,
WPS_DEV_INPUT = 2,
WPS_DEV_PRINTER = 3,
WPS_DEV_CAMERA = 4,
WPS_DEV_STORAGE = 5,
WPS_DEV_NETWORK_INFRA = 6,
WPS_DEV_DISPLAY = 7,
WPS_DEV_MULTIMEDIA = 8,
WPS_DEV_GAMING = 9,
WPS_DEV_PHONE = 10
};
enum wps_dev_subcateg {
WPS_DEV_COMPUTER_PC = 1,
WPS_DEV_COMPUTER_SERVER = 2,
WPS_DEV_COMPUTER_MEDIA_CENTER = 3,
WPS_DEV_PRINTER_PRINTER = 1,
WPS_DEV_PRINTER_SCANNER = 2,
WPS_DEV_CAMERA_DIGITAL_STILL_CAMERA = 1,
WPS_DEV_STORAGE_NAS = 1,
WPS_DEV_NETWORK_INFRA_AP = 1,
WPS_DEV_NETWORK_INFRA_ROUTER = 2,
WPS_DEV_NETWORK_INFRA_SWITCH = 3,
WPS_DEV_DISPLAY_TV = 1,
WPS_DEV_DISPLAY_PICTURE_FRAME = 2,
WPS_DEV_DISPLAY_PROJECTOR = 3,
WPS_DEV_MULTIMEDIA_DAR = 1,
WPS_DEV_MULTIMEDIA_PVR = 2,
WPS_DEV_MULTIMEDIA_MCX = 3,
WPS_DEV_GAMING_XBOX = 1,
WPS_DEV_GAMING_XBOX360 = 2,
WPS_DEV_GAMING_PLAYSTATION = 3,
WPS_DEV_PHONE_WINDOWS_MOBILE = 1
};
/* Request Type */
enum wps_request_type {
WPS_REQ_ENROLLEE_INFO = 0,
WPS_REQ_ENROLLEE = 1,
WPS_REQ_REGISTRAR = 2,
WPS_REQ_WLAN_MANAGER_REGISTRAR = 3
};
/* Response Type */
enum wps_response_type {
WPS_RESP_ENROLLEE_INFO = 0,
WPS_RESP_ENROLLEE = 1,
WPS_RESP_REGISTRAR = 2,
WPS_RESP_AP = 3
};
/* Walk Time for push button configuration (in seconds) */
#define WPS_PBC_WALK_TIME (120)
#define WPS_MAX_AUTHORIZED_MACS (5)
#endif /* WPS_DEFS_H */

View File

@@ -0,0 +1,610 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "queue.h"
#include "utils/os.h"
#include <lwip_netconf.h>
#include <lwip/netif.h>
#include "wifi/wifi_conf.h"
#include <platform/platform_stdlib.h>
#define WLAN0_NAME "wlan0"
#ifndef ENABLE
#define ENABLE (1)
#endif
#ifndef DISABLE
#define DISABLE (0)
#endif
u8 eap_phase = 0;
u8 eap_method = 0;
// eap config arguments
char *eap_target_ssid = NULL;
char *eap_identity = NULL;
char *eap_password = NULL;
// if set eap_ca_cert and defined(EAP_SSL_VERIFY_SERVER), client will verify server's cert
const unsigned char *eap_ca_cert = NULL;
// if set eap_client_cert, eap_client_key, and defined(EAP_SSL_VERIFY_CLIENT), client will send its cert to server
const unsigned char *eap_client_cert = NULL;
const unsigned char *eap_client_key = NULL;
char *eap_client_key_pwd = NULL;
void eap_eapol_recvd_hdl(char *buf, int buf_len, int flags, void* handler_user_data);
void eap_eapol_start_hdl(char *buf, int buf_len, int flags, void* handler_user_data);
static int connect_by_open_system(char *target_ssid);
void set_eap_phase(unsigned char is_trigger_eap){
eap_phase = is_trigger_eap;
}
int get_eap_phase(void){
return eap_phase;
}
int get_eap_method(void){
return eap_method;
}
void reset_config(void){
eap_target_ssid = NULL;
eap_identity = NULL;
eap_password = NULL;
eap_ca_cert = NULL;
eap_client_cert = NULL;
eap_client_key = NULL;
eap_client_key_pwd = NULL;
}
void judge_station_disconnect(void)
{
int mode = 0;
unsigned char ssid[33];
wext_get_mode(WLAN0_NAME, &mode);
switch(mode) {
case IW_MODE_MASTER: //In AP mode
wifi_off();
vTaskDelay(20);
wifi_on(RTW_MODE_STA);
break;
case IW_MODE_INFRA: //In STA mode
if(wext_get_ssid(WLAN0_NAME, ssid) > 0)
wifi_disconnect();
}
}
void eap_disconnected_hdl(char *buf, int buf_len, int flags, void* handler_user_data){
// printf("disconnected\n");
wifi_unreg_event_handler(WIFI_EVENT_EAPOL_RECVD, eap_eapol_recvd_hdl);
wifi_unreg_event_handler(WIFI_EVENT_DISCONNECT, eap_disconnected_hdl);
eap_peer_unregister_methods();
eap_sm_deinit();
//reset_config();
}
/*
void eap_config(void){
eap_target_ssid = "Test_eap";
eap_identity = "guest2";
eap_password = "test2";
eap_client_cert = \
"-----BEGIN CERTIFICATE-----\r\n" \
"MIIC9zCCAd8CAQMwDQYJKoZIhvcNAQEEBQAwgZMxCzAJBgNVBAYTAkZSMQ8wDQYD\r\n" \
"VQQIEwZSYWRpdXMxEjAQBgNVBAcTCVNvbWV3aGVyZTEVMBMGA1UEChMMRXhhbXBs\r\n" \
"ZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQGA1UE\r\n" \
"AxMdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTYwMzE1MDgwNzEx\r\n" \
"WhcNMTcwMzE1MDgwNzExWjBzMQswCQYDVQQGEwJGUjEPMA0GA1UECBMGUmFkaXVz\r\n" \
"MRUwEwYDVQQKEwxFeGFtcGxlIEluYy4xGjAYBgNVBAMUEXVzZXIyQGV4YW1wbGUu\r\n" \
"Y29tMSAwHgYJKoZIhvcNAQkBFhF1c2VyMkBleGFtcGxlLmNvbTCBnzANBgkqhkiG\r\n" \
"9w0BAQEFAAOBjQAwgYkCgYEAqESlV4OYfBcIgZ+Cs8mWpiBjhvKoa0/kIe7saqhC\r\n" \
"e5q4snox0jdkUpLcc4vOs3vQ7ZGnimqTltA9oF6XNUzTWW4vlJTKEfrCWK085l7c\r\n" \
"DHFvHavH3E6vuP71lI7jq4PLXbo2TvZK+uBul4ozjzVWihaZBtz8eLHq446h/D/p\r\n" \
"kzkCAwEAATANBgkqhkiG9w0BAQQFAAOCAQEAAfhVAIkNdeeUNJud720uUHVnIcxz\r\n" \
"GXWI+Svi1qchuTEnRNhLwXmnE+A0WWSHyfdR6FvzdT3xtz3K50iOif8jY2gCGkSK\r\n" \
"8RjKr97228SwbrGO9y9+dYIjH1uz9cBpoVKcpzdsWpKObrDPDYyReHSWo99jM2+O\r\n" \
"vfJxnBw4PLiBj7Q0/dpd6o4JXyp7Cxa0mB4/+cZqjCzzuKfuK3WP7j6laMCV6mg4\r\n" \
"wRZ528IdwDqB7OOqsDm1PVQM8vzny9PM6ikWUCRTVNQJN8RDLkrHR3FRjy15YLdt\r\n" \
"yOfDqVnT/z0wGBaxnNziSJjqPGHPpRi4bJFGXwXOhtknKmciKzfj9/npoQ==\r\n" \
"-----END CERTIFICATE-----\r\n";
eap_client_key = \
"-----BEGIN RSA PRIVATE KEY-----\r\n" \
"MIICXQIBAAKBgQCoRKVXg5h8FwiBn4KzyZamIGOG8qhrT+Qh7uxqqEJ7mriyejHS\r\n" \
"N2RSktxzi86ze9DtkaeKapOW0D2gXpc1TNNZbi+UlMoR+sJYrTzmXtwMcW8dq8fc\r\n" \
"Tq+4/vWUjuOrg8tdujZO9kr64G6XijOPNVaKFpkG3Px4serjjqH8P+mTOQIDAQAB\r\n" \
"AoGARI+LyweshssfxSkIKVc3EcNaqi6PHwJzUrw2ChM624AkR1xwllXJg7ehKVdK\r\n" \
"xmjprRLO8CASuL1qjsBb3fTKnBl+sIVxIFS0AI4Y3ri8VUKbangvSsI7pCzAFry7\r\n" \
"p1gmy9WWRV2ZEa+dV8xcrjb3bloT7hcdeLehgBCvExJIQM0CQQDXlSAKdW3AhYyj\r\n" \
"1A+pfyBSGxJbpSwNyyWgwHIHHjxendxmdUbrc8EbAu1eNKbP58TLgdCZsKcMonAv\r\n" \
"MY1Y2/nnAkEAx9CrUaCU8pJqXTRypM5JtexLKnYMJhpnA9uUILBQOq4Oe0eruyF5\r\n" \
"SaSxhyJYXY491ahWYPF0PTb3jkUhoN+l3wJBAJZthjgGDJlEFwjSFkOtYz4nib3N\r\n" \
"GVpeoFj1MBvrazCScpJDz0LIOLzCZCNSFfwIu3dNk+NKMqZMSn+D0h9pD40CQQC5\r\n" \
"K9n4NXaTLbjAU2CC9mE85JPr76XmkcUxwAWQHZTcLH1jJdIyAx1hb+zNLLjzSmRn\r\n" \
"Yi9ae6ibKhtUjyBQ87HFAkA2Bb3z7NUx+AA2g2HZocFZFShBxylACyQkl8FAFZtf\r\n" \
"osudmKdFQHyAWuBMex4tpz/OLTqJ1ecL1JQeC7OvlpEX\r\n" \
"-----END RSA PRIVATE KEY-----\r\n";
eap_ca_cert = \
"-----BEGIN CERTIFICATE-----\r\n" \
"MIIEpzCCA4+gAwIBAgIJAPvZaozpdfjkMA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD\r\n" \
"VQQGEwJGUjEPMA0GA1UECBMGUmFkaXVzMRIwEAYDVQQHEwlTb21ld2hlcmUxFTAT\r\n" \
"BgNVBAoTDEV4YW1wbGUgSW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBs\r\n" \
"ZS5jb20xJjAkBgNVBAMTHUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4X\r\n" \
"DTE2MDMxNDExMjU0OVoXDTE2MDQxMzExMjU0OVowgZMxCzAJBgNVBAYTAkZSMQ8w\r\n" \
"DQYDVQQIEwZSYWRpdXMxEjAQBgNVBAcTCVNvbWV3aGVyZTEVMBMGA1UEChMMRXhh\r\n" \
"bXBsZSBJbmMuMSAwHgYJKoZIhvcNAQkBFhFhZG1pbkBleGFtcGxlLmNvbTEmMCQG\r\n" \
"A1UEAxMdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqGSIb3\r\n" \
"DQEBAQUAA4IBDwAwggEKAoIBAQC9pireu0aCDLNfMaGv3vId7RXjUhQwSK0jV2Oc\r\n" \
"SyvlKWH3P/N+5kLrP2iL6SCzyETVDXZ0vOsAMjcBF0zHp16prXV0d51cTUqeWBb0\r\n" \
"I5UnGxleIuuOfSg8zLUJoBWZPqLv++eZ5WgOKHt7SXocjvg7TU5t/TMB0Y8OCz3H\r\n" \
"CW2vJ/XKMgMA9HDUu4g57cJu88i1JPRpyFaz/HIQBc7+UNb9z+q09uTZKWTmEMqi\r\n" \
"E2U0EEIs7EtbxnOze1/8C4XNlmztrEdwvu6UEBU/TFkUoh9M646NkkBK7wP9n9pv\r\n" \
"T0nPQRJiiCrICzVqUtlEi9lIKpbBSMbQ0KzrGF7lGTgm4rz9AgMBAAGjgfswgfgw\r\n" \
"HQYDVR0OBBYEFIVyecka74kvOKIW0BjlTc/B+a2NMIHIBgNVHSMEgcAwgb2AFIVy\r\n" \
"ecka74kvOKIW0BjlTc/B+a2NoYGZpIGWMIGTMQswCQYDVQQGEwJGUjEPMA0GA1UE\r\n" \
"CBMGUmFkaXVzMRIwEAYDVQQHEwlTb21ld2hlcmUxFTATBgNVBAoTDEV4YW1wbGUg\r\n" \
"SW5jLjEgMB4GCSqGSIb3DQEJARYRYWRtaW5AZXhhbXBsZS5jb20xJjAkBgNVBAMT\r\n" \
"HUV4YW1wbGUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5ggkA+9lqjOl1+OQwDAYDVR0T\r\n" \
"BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAZYHM26sxbKOckVqJJ1QY0U2QFlGP\r\n" \
"1GYd8v27znxdnRmSonDvv3GjFfhwoyDk0JUuxkK/33ikCxihrgoO/EQTY9BV2OpW\r\n" \
"qkB1PDtb3i5ZRNvfjmW0pVA4p+GmdTGaEE5pTlcVnorzVrUeFKaZakb+IDFYzmeF\r\n" \
"xp8B3Bb5wvinDligLOaJnSlgS8QeeIab9HZfaVTTuPmVK6zE6D54Y0dJPnykvDdE\r\n" \
"cGN0FC+migfilFjJgkDJ0r78nwes55L8zjoofiZuO03rrHww6ARc3v1jYzAufddk\r\n" \
"QTiZHgjlMQb2XXMmXLn8kBgoDnqkXFNe8j0h8uxIJSrjOoIyn1h1wvX5/w==\r\n" \
"-----END CERTIFICATE-----\r\n";
}
*/
int eap_start(char *method){
#ifdef CONFIG_ENABLE_EAP
int ret = -1;
//unsigned long tick1 = xTaskGetTickCount();
//unsigned long tick2;
if(rltk_wlan_running(WLAN1_IDX)){
printf("\n\rNot support con-current mode!\n\r");
return -1;
}
judge_station_disconnect();
#if CONFIG_ENABLE_PEAP
if(strcmp(method,"peap") == 0){
ret = set_eap_peap_method();
}
#endif
#if CONFIG_ENABLE_TLS
if(strcmp(method,"tls") == 0){
ret = set_eap_tls_method();
}
#endif
#if CONFIG_ENABLE_TTLS
if(strcmp(method,"ttls") == 0){
ret = set_eap_ttls_method();
}
#endif
if(ret == -1){
printf("\r\neap method %s not supported\r\n", method);
return -1;
}
eap_method = get_eap_ctx_method();
printf("\n==================== %s_start ====================\n", method);
//eap_config();
set_eap_phase(ENABLE);
wifi_reg_event_handler(WIFI_EVENT_EAPOL_START, eap_eapol_start_hdl, NULL);
wifi_reg_event_handler(WIFI_EVENT_EAPOL_RECVD, eap_eapol_recvd_hdl, NULL);
ret = connect_by_open_system(eap_target_ssid);
#if CONFIG_LWIP_LAYER
/* Start DHCPClient */
if(ret == 0)
LwIP_DHCP(0, DHCP_START);
#endif
wifi_unreg_event_handler(WIFI_EVENT_EAPOL_START, eap_eapol_start_hdl);
// for re-authentication when session timeout
wifi_reg_event_handler(WIFI_EVENT_DISCONNECT, eap_disconnected_hdl, NULL);
//wifi_unreg_event_handler(WIFI_EVENT_EAPOL_RECVD, eap_eapol_recvd_hdl);
set_eap_phase(DISABLE);
// eap failed, disconnect
if(ret != 0){
judge_station_disconnect();
eap_disconnected_hdl(NULL, 0, 0, NULL);
rtw_msleep_os(200); //wait handler done
printf("\r\nERROR: connect to AP by %s failed\n", method);
}
eap_sm_deinit();
printf("\n==================== %s_finish ====================\n", method);
//tick2 = xTaskGetTickCount();
//printf("\r\nConnected after %dms.\n", (tick2-tick1));
return ret;
#else
return -1;
#endif
}
static int connect_by_open_system(char *target_ssid)
{
int retry_count = 0, ret;
if (target_ssid != NULL) {
while (1) {
rtw_msleep_os(500); //wait scan complete.
ret = wifi_connect(target_ssid,
RTW_SECURITY_OPEN,
NULL,
strlen(target_ssid),
0,
0,
NULL);
if (ret == RTW_SUCCESS) {
//printf("\r\n[EAP]Associate with AP success\n");
break;
}
if (retry_count == 0) {
//printf("\r\n[EAP]Associate with AP failed %d\n", ret);
return -1;
}
retry_count --;
printf("Retry connection...\n");
judge_station_disconnect();
set_eap_phase(ENABLE);
}
} else {
printf("\r\n[EAP]Target SSID is NULL\n");
return -1;
}
return 0;
}
static void eap_autoreconnect_thread(void *method)
{
eap_start((char*)method);
vTaskDelete(NULL);
}
void eap_autoreconnect_hdl(u8 method_id){
#ifdef CONFIG_ENABLE_EAP
char *method;
switch(method_id){
case 25: // EAP_TYPE_PEAP
method = "peap";
break;
case 13: // EAP_TYPE_TLS
method = "tls";
break;
case 21: // EAP_TYPE_TTLS
method = "ttls";
break;
default:
printf("invalid eap method\n");
return;
}
if(xTaskCreate(eap_autoreconnect_thread, ((const char*)"eap_autoreconnect_thread"), 1024, (void*) method, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed\n", __FUNCTION__);
#endif
}
// copy from ssl_client_ext.c
#if CONFIG_USE_POLARSSL
#include <polarssl/ssl.h>
#include <polarssl/memory.h>
int max_buf_bio_size = SSL_BUFFER_LEN;
#if ENABLE_EAP_SSL_VERIFY_CLIENT
static x509_crt* _cli_crt = NULL;
static pk_context* _clikey_rsa = NULL;
#endif
#if ENABLE_EAP_SSL_VERIFY_SERVER
static x509_crt* _ca_crt = NULL;
static int eap_verify(void *data, x509_crt *crt, int depth, int *flags)
{
//char buf[1024];
((void) data);
printf("\nVerify requested for (Depth %d):\n", depth);
//x509_crt_info(buf, sizeof(buf) - 1, "", crt);
//printf("%s", buf);
if(((*flags) & BADCERT_EXPIRED) != 0)
printf("server certificate has expired\n");
if(((*flags) & BADCERT_REVOKED) != 0)
printf(" ! server certificate has been revoked\n");
if(((*flags) & BADCERT_CN_MISMATCH) != 0)
printf(" ! CN mismatch\n");
if(((*flags) & BADCERT_NOT_TRUSTED) != 0)
printf(" ! self-signed or not signed by a trusted CA\n");
if(((*flags) & BADCRL_NOT_TRUSTED) != 0)
printf(" ! CRL not trusted\n");
if(((*flags) & BADCRL_EXPIRED) != 0)
printf(" ! CRL expired\n");
if(((*flags) & BADCERT_OTHER) != 0)
printf(" ! other (unknown) flag\n");
if((*flags) == 0)
printf(" Certificate verified without error flags\n");
return(0);
}
#endif
int eap_cert_init(void)
{
#if ENABLE_EAP_SSL_VERIFY_CLIENT
if(eap_client_cert != NULL && eap_client_key != NULL){
_cli_crt = polarssl_malloc(sizeof(x509_crt));
if(_cli_crt)
x509_crt_init(_cli_crt);
else
return -1;
_clikey_rsa = polarssl_malloc(sizeof(pk_context));
if(_clikey_rsa)
pk_init(_clikey_rsa);
else
return -1;
}
#endif
#if ENABLE_EAP_SSL_VERIFY_SERVER
if(eap_ca_cert != NULL){
_ca_crt = polarssl_malloc(sizeof(x509_crt));
if(_ca_crt)
x509_crt_init(_ca_crt);
else
return -1;
}
#endif
return 0;
}
void eap_client_cert_free(void)
{
#if ENABLE_EAP_SSL_VERIFY_CLIENT
if(eap_client_cert != NULL && eap_client_key != NULL){
if(_cli_crt) {
x509_crt_free(_cli_crt);
polarssl_free(_cli_crt);
_cli_crt = NULL;
}
if(_clikey_rsa) {
pk_free(_clikey_rsa);
polarssl_free(_clikey_rsa);
_clikey_rsa = NULL;
}
}
#endif
}
void eap_server_cert_free(void)
{
#if ENABLE_EAP_SSL_VERIFY_SERVER
if(eap_ca_cert != NULL){
if(_ca_crt) {
x509_crt_free(_ca_crt);
polarssl_free(_ca_crt);
_ca_crt = NULL;
}
}
#endif
}
int eap_cert_setup(ssl_context *ssl)
{
#if ENABLE_EAP_SSL_VERIFY_CLIENT
if(eap_client_cert != NULL && eap_client_key != NULL){
if(x509_crt_parse(_cli_crt, eap_client_cert, strlen(eap_client_cert)) != 0)
return -1;
if(pk_parse_key(_clikey_rsa, eap_client_key, strlen(eap_client_key), eap_client_key_pwd, strlen(eap_client_key_pwd)) != 0)
return -1;
ssl_set_own_cert(ssl, _cli_crt, _clikey_rsa);
}
#endif
#if ENABLE_EAP_SSL_VERIFY_SERVER
if(eap_ca_cert != NULL){
if(x509_crt_parse(_ca_crt, eap_ca_cert, strlen(eap_ca_cert)) != 0)
return -1;
ssl_set_ca_chain(ssl, _ca_crt, NULL, NULL);
ssl_set_authmode(ssl, SSL_VERIFY_REQUIRED);
ssl_set_verify(ssl, eap_verify, NULL);
}
#endif
return 0;
}
#elif CONFIG_USE_MBEDTLS
#include <mbedtls/config.h>
#include <mbedtls/platform.h>
#include <mbedtls/ssl.h>
#include <mbedtls/ssl_internal.h>
#if CONFIG_EXAMPLE_AMAZON_FREERTOS || CONFIG_EXAMPLE_AMAZON_AFQP_TESTS
int max_buf_bio_size = MBEDTLS_SSL_IN_BUFFER_LEN;
#else
int max_buf_bio_size = MBEDTLS_SSL_BUFFER_LEN;
#endif
struct eap_tls{
void *ssl;
void *conf;
void *fd;
};
#if ENABLE_EAP_SSL_VERIFY_CLIENT
static mbedtls_x509_crt* _cli_crt = NULL;
static mbedtls_pk_context* _clikey_rsa = NULL;
#endif
#if ENABLE_EAP_SSL_VERIFY_SERVER
static mbedtls_x509_crt* _ca_crt = NULL;
static int eap_verify(void *data, mbedtls_x509_crt *crt, int depth, int *flags)
{
//char buf[1024];
((void) data);
printf("\nVerify requested for (Depth %d):\n", depth);
//mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
//printf("%s", buf);
if(((*flags) & MBEDTLS_X509_BADCERT_EXPIRED) != 0)
printf("server certificate has expired\n");
if(((*flags) & MBEDTLS_X509_BADCERT_REVOKED) != 0)
printf(" ! server certificate has been revoked\n");
if(((*flags) & MBEDTLS_X509_BADCERT_CN_MISMATCH) != 0)
printf(" ! CN mismatch\n");
if(((*flags) & MBEDTLS_X509_BADCERT_NOT_TRUSTED) != 0)
printf(" ! self-signed or not signed by a trusted CA\n");
if(((*flags) & MBEDTLS_X509_BADCRL_NOT_TRUSTED) != 0)
printf(" ! CRL not trusted\n");
if(((*flags) & MBEDTLS_X509_BADCRL_EXPIRED) != 0)
printf(" ! CRL expired\n");
if(((*flags) & MBEDTLS_X509_BADCERT_OTHER) != 0)
printf(" ! other (unknown) flag\n");
if((*flags) == 0)
printf(" Certificate verified without error flags\n");
return(0);
}
#endif
int eap_cert_init(void)
{
#if ENABLE_EAP_SSL_VERIFY_CLIENT
if(eap_client_cert != NULL && eap_client_key != NULL){
_cli_crt = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
if(_cli_crt)
mbedtls_x509_crt_init(_cli_crt);
else
return -1;
_clikey_rsa = mbedtls_calloc(1, sizeof(mbedtls_pk_context));
if(_clikey_rsa)
mbedtls_pk_init(_clikey_rsa);
else
return -1;
}
#endif
#if ENABLE_EAP_SSL_VERIFY_SERVER
if(eap_ca_cert != NULL){
_ca_crt = mbedtls_calloc(1, sizeof(mbedtls_x509_crt));
if(_ca_crt)
mbedtls_x509_crt_init(_ca_crt);
else
return -1;
}
#endif
return 0;
}
void eap_client_cert_free(void)
{
#if ENABLE_EAP_SSL_VERIFY_CLIENT
if(eap_client_cert != NULL && eap_client_key != NULL){
if(_cli_crt) {
mbedtls_x509_crt_free(_cli_crt);
mbedtls_free(_cli_crt);
_cli_crt = NULL;
}
if(_clikey_rsa) {
mbedtls_pk_free(_clikey_rsa);
mbedtls_free(_clikey_rsa);
_clikey_rsa = NULL;
}
}
#endif
}
void eap_server_cert_free(void)
{
#if ENABLE_EAP_SSL_VERIFY_SERVER
if(eap_ca_cert != NULL){
if(_ca_crt) {
mbedtls_x509_crt_free(_ca_crt);
mbedtls_free(_ca_crt);
_ca_crt = NULL;
}
}
#endif
}
int eap_cert_setup(struct eap_tls *tls_context)
{
#if ENABLE_EAP_SSL_VERIFY_CLIENT
if(eap_client_cert != NULL && eap_client_key != NULL){
if(mbedtls_x509_crt_parse(_cli_crt, eap_client_cert, strlen(eap_client_cert)+1) != 0)
return -1;
if(mbedtls_pk_parse_key(_clikey_rsa, eap_client_key, strlen(eap_client_key)+1, eap_client_key_pwd, strlen(eap_client_key_pwd)+1) != 0)
return -1;
mbedtls_ssl_conf_own_cert(tls_context->conf, _cli_crt, _clikey_rsa);
}
#endif
#if ENABLE_EAP_SSL_VERIFY_SERVER
if(eap_ca_cert != NULL){
if(mbedtls_x509_crt_parse(_ca_crt, eap_ca_cert, strlen(eap_ca_cert)+1) != 0)
return -1;
mbedtls_ssl_conf_ca_chain(tls_context->conf, _ca_crt, NULL);
mbedtls_ssl_conf_authmode(tls_context->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_verify(tls_context->conf, eap_verify, NULL);
}
#endif
return 0;
}
#endif /*CONFIG_USE_MBEDTLS*/

View File

@@ -0,0 +1,269 @@
#include "FreeRTOS.h"
#include "task.h"
#include "utils/os.h"
#include <lwip/netif.h>
#include <wifi/wifi_conf.h>
#include "wps/wps_defs.h"
#if CONFIG_ENABLE_P2P
enum p2p_wps_method {
WPS_NOT_READY, WPS_PIN_DISPLAY, WPS_PIN_KEYPAD, WPS_PBC
};
/*NETMASK*/
#define P2P_NETMASK_ADDR0 255
#define P2P_NETMASK_ADDR1 255
#define P2P_NETMASK_ADDR2 255
#define P2P_NETMASK_ADDR3 0
/*Gateway Address*/
#define P2P_GW_ADDR0 192
#define P2P_GW_ADDR1 168
#define P2P_GW_ADDR2 42
#define P2P_GW_ADDR3 1
#define P2P_GO_NEGO_RESULT_SIZE 376//256
xqueue_handle_t queue_for_p2p_nego;
extern void dhcps_init(struct netif * pnetif);
static int hex2num(char c)
{
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
return -1;
}
/**
* hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format)
* @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
* @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
* Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
*/
int hwaddr_aton(const char *txt, u8 *addr)
{
int i;
for (i = 0; i < 6; i++) {
int a, b;
a = hex2num(*txt++);
if (a < 0)
return -1;
b = hex2num(*txt++);
if (b < 0)
return -1;
*addr++ = (a << 4) | b;
if (i < 5 && *txt++ != ':')
return -1;
}
return 0;
}
int wifi_start_p2p_go(char *ssid, char *passphrase, u8 channel)
{
extern struct netif xnetif[NET_IF_NUM];
struct netif * pnetif = &xnetif[0];
struct ip_addr ipaddr;
struct ip_addr netmask;
struct ip_addr gw;
IP4_ADDR(&ipaddr, P2P_GW_ADDR0, P2P_GW_ADDR1, P2P_GW_ADDR2, P2P_GW_ADDR3);
IP4_ADDR(&netmask, P2P_NETMASK_ADDR0, P2P_NETMASK_ADDR1 , P2P_NETMASK_ADDR2, P2P_NETMASK_ADDR3);
IP4_ADDR(&gw, P2P_GW_ADDR0, P2P_GW_ADDR1, P2P_GW_ADDR2, P2P_GW_ADDR3);
netif_set_addr(pnetif, &ipaddr, &netmask,&gw);
// start ap
if(wifi_start_ap(ssid,
RTW_SECURITY_WPA2_AES_PSK,
passphrase,
strlen(ssid),
strlen(passphrase),
channel
) != RTW_SUCCESS) {
printf("\n\rERROR: Operation failed!");
return -1;
}
netif_set_default(pnetif);
// start dhcp server
dhcps_init(pnetif);
return 0;
}
void app_callback(char *msg)
{
//From Application
}
void cmd_wifi_p2p_start(int argc, char **argv)
{
extern struct netif xnetif[NET_IF_NUM];
int listen_ch = 1;
int op_ch = 5;
int go_intent = 1;
#if 1
u32 r = 0;
os_get_random((u8 *) &r, sizeof(r));
go_intent = r%15+1; /*1-15*/
os_get_random((u8 *) &r, sizeof(r));
listen_ch = 1 + (r % 3) * 5;
os_get_random((u8 *) &r, sizeof(r));
op_ch = 1 + (r % 3) * 5;
#endif
wifi_off();
os_sleep(0, 20000);
wifi_on(RTW_MODE_P2P);
wifi_p2p_init(xnetif[0].hwaddr, go_intent, listen_ch, op_ch);
}
int cmd_wifi_p2p_auto_go_start(int argc, char **argv)
{
u8 *passphrase = "12345678";
u8 channel = 6; // 1, 6, 11
const char *ssid_in = "DIRECT-34-Ameba";
const char *dev_name = "Ameba1234"; // max strlen 32
const char *manufacturer = "by customer"; // max strlen 64
const char *model_name = "customer"; // max strlen 32
const char *model_number = "v2.0"; // max strlen 32
const char *serial_number = "9"; // max strlen 32
const u8 pri_dev_type[8] = {0x00,0x0A,0x00,0x50,0xF2,0x04,0x00,0x01}; // category ID:0x00,0x0A; sub category ID:0x00,0x01
u8 res[P2P_GO_NEGO_RESULT_SIZE];
u16 config_methods = WPS_CONFIG_DISPLAY | WPS_CONFIG_KEYPAD | WPS_CONFIG_PUSHBUTTON;
if(!is_wifi_p2p_initialized())
return -1;
wifi_p2p_set_dev_name(dev_name);
wifi_p2p_set_manufacturer(manufacturer);
wifi_p2p_set_model_name(model_name);
wifi_p2p_set_model_number(model_number);
wifi_p2p_set_serial_number(serial_number);
wifi_p2p_set_pri_dev_type(pri_dev_type);
wifi_p2p_set_ssid(ssid_in);
wifi_p2p_set_config_methods(config_methods);
wifi_p2p_init_auto_go_params(res, passphrase, channel);
wifi_p2p_start_auto_go(res);
return 0;
}
void cmd_wifi_p2p_stop(int argc, char **argv)
{
wifi_p2p_deinit();
wifi_off();
}
void cmd_p2p_listen(int argc, char **argv)
{
u32 timeout = 0;
if(argc == 2){
timeout = os_atoi((u8*)argv[1]);
printf("\r\n%s(): timeout=%d\n", __func__, timeout);
if(timeout > 3600)
timeout = 3600;
}
wifi_cmd_p2p_listen(timeout);
}
void cmd_p2p_find(int argc, char **argv)
{
wifi_cmd_p2p_find();
}
void cmd_p2p_peers(int argc, char **argv)
{
wifi_cmd_p2p_peers();
}
void cmd_p2p_info(int argc, char **argv)
{
wifi_cmd_p2p_info();
}
void cmd_p2p_disconnect(int argc, char **argv)
{
wifi_cmd_p2p_disconnect();
}
void cmd_p2p_connect(int argc, char **argv)
{
enum p2p_wps_method config_method = WPS_PBC;
char *pin = NULL;
u8 dest[ETH_ALEN] = {0x44, 0x6d, 0x57, 0xd7, 0xce, 0x41};
u8 res[P2P_GO_NEGO_RESULT_SIZE];
int ret = 0, result = 0;
#if 1
if((argc != 2) && (argc != 3) && (argc != 4)) {
printf("\n\rUsage: p2p_connect DEST_ADDR [pbc|pin] [pin code]\n");
printf("\n\rExample: p2p_connect 00:e0:4c:87:00:15 pin 12345678\n");
return;
}
if (hwaddr_aton(argv[1], dest)){
printf("\r\nP2P_CONNECT: dest address is not correct!\n");
return;
}
//printf("\r\nDEST: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", dest[0], dest[1], dest[2], dest[3], dest[4], dest[5]);
config_method = WPS_PBC;
if(argc == 3) {
if(os_strncmp(argv[2], "pbc", 3) == 0)
config_method = WPS_PBC;
else if(os_strncmp(argv[2], "pin", 3) == 0){
config_method = WPS_PIN_DISPLAY;
}else{
printf("\n\rUnknown config method!\n");
printf("\n\rUsage: p2p_connect DEST_ADDR [pbc|pin] \n");
printf("\n\rExample: p2p_connect 00:e0:4c:87:00:15 pin\n");
return;
}
}
else if(argc == 4) {
if(os_strncmp(argv[2], "pin", 3) == 0){
config_method = WPS_PIN_KEYPAD;
pin = argv[3];
}else{
printf("\n\rUnknown config method!\n");
printf("\n\rUsage: p2p_connect DEST_ADDR [pbc|pin] [pin code]\n");
printf("\n\rExample: p2p_connect 00:e0:4c:87:00:15 pin 12345678\n");
return;
}
}
#else //For test
u8 dest1[ETH_ALEN] = {0xea, 0x92, 0xa4, 0x9b, 0x61, 0xd6}; //NEXUS 4
//u8 dest1[ETH_ALEN] = {0x0e, 0x37, 0xdc, 0xfc, 0xc4, 0x12}; //HUAWEI U9508_c001
//u8 dest1[ETH_ALEN] = {0x42, 0xcb, 0xa8, 0xd3, 0x2c, 0x50}; //HUAWEI G610-T00
os_memcpy(dest, dest1, ETH_ALEN);
config_method = WPS_PBC;
#endif
if (queue_for_p2p_nego!= NULL) {
os_xqueue_delete(queue_for_p2p_nego);
queue_for_p2p_nego = NULL;
}
queue_for_p2p_nego = os_xqueue_create(1, P2P_GO_NEGO_RESULT_SIZE);
if(queue_for_p2p_nego != NULL) {
ret = wifi_cmd_p2p_connect(dest, config_method, pin);
if(ret == 0)
result = os_xqueue_receive(queue_for_p2p_nego, res, 15);
os_xqueue_delete(queue_for_p2p_nego);
queue_for_p2p_nego = NULL;
if((ret == 0) || (result == 0))
wifi_p2p_start_wps(res);
}
}
#endif //CONFIG_ENABLE_P2P

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,75 @@
/**
******************************************************************************
* @file wifi_wps_config.h
* @author
* @version
* @brief This file provides user interfaces for WPS functionality.
******************************************************************************
* @attention
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
******************************************************************************
*/
/** @addtogroup wpsp2p WPS/P2P
* @ingroup wlan
* @brief WPS/P2P functions
* @{
*/
/**
* @brief Start WPS enrollee process.
* @warning Before invoking this function, the Wi-Fi should be enabled by using @ref wifi_on().
* @param[in] wps_config: WPS configure method. Options are: WPS_CONFIG_DISPLAY, WPS_CONFIG_KEYPAD, and WPS_CONFIG_PUSHBUTTON.
* @param[in] pin: PIN number. Can be set to NULL if using WPS_CONFIG_PUSHBUTTON.
* @param[in] channel: Channel. Currently un-used, can be set to 0.
* @param[in] ssid: Target network SSID. Can be set to NULL if no target network specified.
* @return 0 on success.
* @note Please make sure CONFIG_ENABLE_WPS is enabled in platform_opts.h.\n
* You can reference @ref cmd_wps() to know how to choose input parameters.
*/
int wps_start(u16 wps_config, char *pin, u8 channel, char *ssid);
/**
* @brief Command to start WPS enrollee process for commonly use. Can refer to ATWW in atcmd_wifi.c.
* @warning Before invoking this function, the Wi-Fi should be enabled by using @ref wifi_on().
* @param[in] argc: Command line argument. Argument count.
* @param[in] argv: Command line argument. Argument vector.
* @return 0 on success.
* @note Command style for example:
* - cmd_wps pbc
* - cmd_wps pin
* - cmd_wps pin 12345678
* @note Please make sure CONFIG_ENABLE_WPS is enabled in platform_opts.h.
*/
void cmd_wps(int argc, char **argv);
/**
* @brief Start a WPS registrar thread.
* @warning Before invoking this function, the Wi-Fi should be in SoftAP mode.
* @param[in] config_methods: WPS configure method. Options are: WPS_CONFIG_DISPLAY, WPS_CONFIG_KEYPAD, and WPS_CONFIG_PUSHBUTTON.
* @param[in] pin: PIN number. Can be set to NULL.
* @return None
* @note Please make sure CONFIG_ENABLE_WPS and CONFIG_ENABLE_WPS_AP are enabled in platform_opts.h.\n
* You can reference @ref cmd_ap_wps() to know how to choose input parameters.
*/
void wifi_start_ap_wps_thread(u16 config_methods, char *pin);
/**
* @brief Command to start WPS registrar process for commonly use. Can refer to ATWw in atcmd_wifi.c.
* @warning Before invoking this function, the Wi-Fi should be in SoftAP mode.
* @param[in] argc: Command line argument. Argument count.
* @param[in] argv: Command line argument. Argument vector.
* @return 0 on success
* @note Command style for example:
* - cmd_ap_wps pbc
* - cmd_ap_wps pin
* - cmd_ap_wps pin 12345678
* @note Please make sure CONFIG_ENABLE_WPS and CONFIG_ENABLE_WPS_AP are enabled in platform_opts.h.
*/
void cmd_ap_wps(int argc, char **argv);
/*\@}*/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,272 @@
//----------------------------------------------------------------------------//
#include "wifi/wifi_ind.h"
#include "wifi/wifi_conf.h"
#include "osdep_service.h"
#include "platform_stdlib.h"
/******************************************************
* Constants
******************************************************/
#define WIFI_INDICATE_MSG 0
#define WIFI_MANAGER_STACKSIZE 1300
#define WIFI_MANAGER_PRIORITY (0) //Actual priority is 4 since calling rtw_create_task
#define WIFI_MANAGER_Q_SZ 8
#define WIFI_EVENT_MAX_ROW 3
/******************************************************
* Globals
******************************************************/
static event_list_elem_t event_callback_list[WIFI_EVENT_MAX][WIFI_EVENT_MAX_ROW];
#if CONFIG_WIFI_IND_USE_THREAD
static rtw_worker_thread_t wifi_worker_thread;
#endif
//----------------------------------------------------------------------------//
#if CONFIG_WIFI_IND_USE_THREAD
static rtw_result_t rtw_send_event_to_worker(int event_cmd, char *buf, int buf_len, int flags)
{
rtw_event_message_t message;
int i;
rtw_result_t ret = RTW_SUCCESS;
char *local_buf = NULL;
if(event_cmd >= WIFI_EVENT_MAX)
return RTW_BADARG;
for(i = 0; i < WIFI_EVENT_MAX_ROW; i++){
if(event_callback_list[event_cmd][i].handler == NULL)
continue;
message.function = (event_handler_t)event_callback_list[event_cmd][i].handler;
message.buf_len = buf_len;
if(buf_len){
local_buf = (char*)pvPortMalloc(buf_len);
if(local_buf == NULL)
return RTW_NOMEM;
memcpy(local_buf, buf, buf_len);
//printf("\n!!!!!Allocate %p(%d) for evcmd %d\n", local_buf, buf_len, event_cmd);
}
message.buf = local_buf;
message.flags = flags;
message.user_data = event_callback_list[event_cmd][i].handler_user_data;
ret = rtw_push_to_xqueue(&wifi_worker_thread.event_queue, &message, 0);
if(ret != RTW_SUCCESS){
if(local_buf){
printf("\r\nrtw_send_event_to_worker: enqueue cmd %d failed and free %p(%d)\n", event_cmd, local_buf, buf_len);
vPortFree(local_buf);
}
break;
}
}
return ret;
}
#else
static rtw_result_t rtw_indicate_event_handle(int event_cmd, char *buf, int buf_len, int flags)
{
rtw_event_handler_t handle = NULL;
int i;
if(event_cmd >= WIFI_EVENT_MAX)
return RTW_BADARG;
for(i = 0; i < WIFI_EVENT_MAX_ROW; i++){
handle = event_callback_list[event_cmd][i].handler;
if(handle == NULL)
continue;
handle(buf, buf_len, flags, event_callback_list[event_cmd][i].handler_user_data);
}
return RTW_SUCCESS;
}
#endif
void wifi_indication( rtw_event_indicate_t event, char *buf, int buf_len, int flags)
{
//
// If upper layer application triggers additional operations on receiving of wext_wlan_indicate,
// please strictly check current stack size usage (by using uxTaskGetStackHighWaterMark() )
// , and tries not to share the same stack with wlan driver if remaining stack space is
// not available for the following operations.
// ex: using semaphore to notice another thread.
switch(event)
{
case WIFI_EVENT_DISCONNECT:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r %s():Disconnection indication received", __FUNCTION__);
#endif
break;
case WIFI_EVENT_CONNECT:
// For WPA/WPA2 mode, indication of connection does not mean data can be
// correctly transmitted or received. Data can be correctly transmitted or
// received only when 4-way handshake is done.
// Please check WIFI_EVENT_FOURWAY_HANDSHAKE_DONE event
#if(WIFI_INDICATE_MSG==1)
// Sample: return mac address
if(buf != NULL && buf_len == 6)
{
printf("\n\r%s():Connect indication received: %02x:%02x:%02x:%02x:%02x:%02x", __FUNCTION__,
buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
}
#endif
break;
case WIFI_EVENT_FOURWAY_HANDSHAKE_DONE:
#if(WIFI_INDICATE_MSG==1)
if(buf != NULL)
{
if(buf_len == strlen(IW_EXT_STR_FOURWAY_DONE))
printf("\n\r%s():%s", __FUNCTION__, buf);
}
#endif
break;
case WIFI_EVENT_SCAN_RESULT_REPORT:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_SCAN_RESULT_REPORT\n", __func__);
#endif
break;
case WIFI_EVENT_SCAN_DONE:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_SCAN_DONE\n", __func__);
#endif
break;
case WIFI_EVENT_RECONNECTION_FAIL:
#if(WIFI_INDICATE_MSG==1)
if(buf != NULL){
if(buf_len == strlen(IW_EXT_STR_RECONNECTION_FAIL))
printf("\n\r%s", buf);
}
#endif
break;
case WIFI_EVENT_NO_NETWORK:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_NO_NETWORK\n", __func__);
#endif
break;
case WIFI_EVENT_RX_MGNT:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_RX_MGNT\n", __func__);
#endif
break;
#if CONFIG_ENABLE_P2P
case WIFI_EVENT_SEND_ACTION_DONE:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_SEND_ACTION_DONE\n", __func__);
#endif
break;
#endif //CONFIG_ENABLE_P2P
case WIFI_EVENT_STA_ASSOC:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_STA_ASSOC\n", __func__);
#endif
break;
case WIFI_EVENT_STA_DISASSOC:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_STA_DISASSOC\n", __func__);
#endif
break;
#ifdef CONFIG_WPS
case WIFI_EVENT_STA_WPS_START:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_STA_WPS_START\n", __func__);
#endif
break;
case WIFI_EVENT_WPS_FINISH:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_WPS_FINISH\n", __func__);
#endif
break;
case WIFI_EVENT_EAPOL_RECVD:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_EAPOL_RECVD\n", __func__);
#endif
break;
#endif
case WIFI_EVENT_BEACON_AFTER_DHCP:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_BEACON_AFTER_DHCP\n", __func__);
#endif
break;
case WIFI_EVENT_IP_CHANGED:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_IP_CHANNGED\n", __func__);
#endif
break;
case WIFI_EVENT_ICV_ERROR:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_ICV_ERROR\n", __func__);
#endif
case WIFI_EVENT_CHALLENGE_FAIL:
#if(WIFI_INDICATE_MSG==1)
printf("\n\r%s(): WIFI_EVENT_CHALLENGE_FAIL\n", __func__);
#endif
break;
}
#if CONFIG_INIC_EN
inic_indicate_event(event, buf, buf_len, flags);
#endif//CONFIG_INIC_EN
#if CONFIG_WIFI_IND_USE_THREAD
rtw_send_event_to_worker(event, buf, buf_len, flags);
#else
rtw_indicate_event_handle(event, buf, buf_len, flags);
#endif
}
void wifi_reg_event_handler(unsigned int event_cmds, rtw_event_handler_t handler_func, void *handler_user_data)
{
int i = 0, j = 0;
if(event_cmds < WIFI_EVENT_MAX){
for(i=0; i < WIFI_EVENT_MAX_ROW; i++){
if(event_callback_list[event_cmds][i].handler == NULL){
for(j=0; j<WIFI_EVENT_MAX_ROW; j++){
if(event_callback_list[event_cmds][j].handler == handler_func){
return;
}
}
event_callback_list[event_cmds][i].handler = handler_func;
event_callback_list[event_cmds][i].handler_user_data = handler_user_data;
return;
}
}
}
}
void wifi_unreg_event_handler(unsigned int event_cmds, rtw_event_handler_t handler_func)
{
int i;
if(event_cmds < WIFI_EVENT_MAX){
for(i = 0; i < WIFI_EVENT_MAX_ROW; i++){
if(event_callback_list[event_cmds][i].handler == handler_func){
event_callback_list[event_cmds][i].handler = NULL;
event_callback_list[event_cmds][i].handler_user_data = NULL;
return;
}
}
}
}
void init_event_callback_list(){
memset(event_callback_list, 0, sizeof(event_callback_list));
}
int wifi_manager_init()
{
#if CONFIG_WIFI_IND_USE_THREAD
rtw_create_worker_thread(&wifi_worker_thread,
WIFI_MANAGER_PRIORITY,
WIFI_MANAGER_STACKSIZE,
WIFI_MANAGER_Q_SZ);
#endif
return 0;
}
void rtw_wifi_manager_deinit()
{
#if CONFIG_WIFI_IND_USE_THREAD
rtw_delete_worker_thread(&wifi_worker_thread);
#endif
}

View File

@@ -0,0 +1,111 @@
/**
******************************************************************************
* @file wifi_ind.h
* @author
* @version
* @brief This file provides the functions related to event handler mechanism.
******************************************************************************
* @attention
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
******************************************************************************
*/
#ifndef _WIFI_INDICATE_H
#define _WIFI_INDICATE_H
/** @addtogroup nic NIC
* @ingroup wlan
* @brief NIC functions
* @{
*/
#include "wifi_conf.h"
typedef void (*rtw_event_handler_t)(char *buf, int buf_len, int flags, void* handler_user_data );
typedef struct
{
// rtw_event_indicate_t event_cmd;
rtw_event_handler_t handler;
void* handler_user_data;
} event_list_elem_t;
/**
* @brief Initialize the event callback list.
* @warning Please make sure this function has been invoked before
* using the event handler related mechanism.
* @param None
* @return None
*/
void init_event_callback_list(void);
/**
* @brief Wlan driver indicate event to upper layer through wifi_indication.
* @param[in] event: An event reported from driver to upper layer application. Please refer to rtw_event_indicate_t enum.
* @param[in] buf: If it is not NUL, buf is a pointer to the buffer for message string.
* @param[in] buf_len: The length of the buffer.
* @param[in] flags: Indicate some extra information, sometimes it is 0.
* @retval None
* @note If upper layer application triggers additional operations on receiving of wext_wlan_indicate,
* please strictly check current stack size usage (by using uxTaskGetStackHighWaterMark() ),
* and tries not to share the same stack with wlan driver if remaining stack space is not available
* for the following operations.
* ex: using semaphore to notice another thread instead of handing event directly in wifi_indication().
* - Wifi event list
*
* 0. WIFI_EVENT_CONNECT : Indicate station connect to AP
* 1. WIFI_EVENT_DISCONNECT : Indicate station disconnect with AP
* 2. WIFI_EVENT_FOURWAY_HANDSHAKE_DONE : Indicate fourway handshake done in station mode when connects to WPA/WPA2 AP.
* 3. WIFI_EVENT_SCAN_RESULT_REPORT : Indicate wifi scan result report event. The event is for application to get the wifi scan result
* 4. WIFI_EVENT_SCAN_DONE : Indicate wifi scan done
* 5. WIFI_EVENT_RECONNECTION_FAIL : Indicate wifi reconnection failed
* 6. WIFI_EVENT_SEND_ACTION_DONE : Indicate the action frame status in p2p. Need to define CONFIG_P2P_NEW in wlan library, default is disable.
* 7. WIFI_EVENT_RX_MGNT : Indicate managerment frame receive
* 8. WIFI_EVENT_STA_ASSOC : Indicate client associate in AP mode
* 9. WIFI_EVENT_STA_DISASSOC : Indicate client disassociate in AP mode
* 10. WIFI_EVENT_STA_WPS_START : Indicate WPS process starting. This event is used in wps process.
* 11. WIFI_EVENT_WPS_FINISH : Indicate WPS process finish. This event is used in wps process.
* 12. WIFI_EVENT_EAPOL_START : Indicate receiving EAPOL_START packets in eap process. This event is used in eap process.
* 13. WIFI_EVENT_EAPOL_RECVD : Indicate receiving EAPOL packets in wps process. This event is used in wps process.
* 14. WIFI_EVENT_NO_NETWORK : Indicate the event that wifi connect failed cause of wifi scan can't scan the specific AP.
* 15. WIFI_EVENT_BEACON_AFTER_DHCP : Indicate station receive beacon after DHCP done. It is used to know the wifi connection is OK by receiving beacon after getting IP.
* 16. WIFI_EVENT_IP_CHANGED : Indicate IP has changed. It is application layer event, it is demoed in example_wifi_roaming.c
* 17. WIFI_EVENT_ICV_ERROR : Indicate that the receiving packets has ICV error.
* 18. WIFI_EVENT_CHALLENGE_FAIL : Indicate authentication failed because of challenge failure
* 19. WIFI_EVENT_MAX : It stands for the end of wifi event.
*/
extern void wifi_indication( rtw_event_indicate_t event, char *buf, int buf_len, int flags);
/**
* @brief Register the event listener.
* @param[in] event_cmds : The event command number indicated.
* @param[in] handler_func : the callback function which will
* receive and process the event.
* @param[in] handler_user_data : user specific data that will be
* passed directly to the callback function.
* @return RTW_SUCCESS : if successfully registers the event.
* @return RTW_ERROR : if an error occurred.
* @note Set the same event_cmds with empty handler_func will
* unregister the event_cmds.
*/
extern void wifi_reg_event_handler(unsigned int event_cmds, rtw_event_handler_t handler_func, void *handler_user_data);
/**
* @brief Un-register the event listener.
* @param[in] event_cmds : The event command number indicated.
* @param[in] handler_func : the callback function which will
* receive and process the event.
*
* @return RTW_SUCCESS : if successfully un-registers the event .
* @return RTW_ERROR : if an error occurred.
*/
extern void wifi_unreg_event_handler(unsigned int event_cmds, rtw_event_handler_t handler_func);
/*\@}*/
#endif //_WIFI_INDICATE_H

View File

@@ -0,0 +1,523 @@
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "tcpip.h"
#include "wifi/wifi_conf.h"
#ifndef CONFIG_WLAN
#define CONFIG_WLAN 1
#endif
#if CONFIG_WLAN
#include <platform/platform_stdlib.h>
// Add extra interfaces to make release sdk able to determine promisc API linking
void promisc_deinit(void *padapter)
{
#ifdef CONFIG_PROMISC
_promisc_deinit(padapter);
#endif
}
int promisc_recv_func(void *padapter, void *rframe)
{
// Never reach here if not define CONFIG_PROMISC
#ifdef CONFIG_PROMISC
return _promisc_recv_func(padapter, rframe);
#else
return 0;
#endif
}
int promisc_recv_lens_func(void *padapter, u8 *payload, u8 plen)
{
// Never reach here if not define CONFIG_PROMISC
#ifdef CONFIG_PROMISC
#if CONFIG_UNSUPPORT_PLCPHDR_RPT
return _promisc_recv_lens_func(padapter, payload, plen);
#else
return 0;
#endif
#else
return 0;
#endif
}
int promisc_filter_retransmit_pkt(u8 enable, u8 filter_interval_ms)
{
#ifdef CONFIG_PROMISC
#if CONFIG_UNSUPPORT_PLCPHDR_RPT
return _promisc_filter_retransmit_plcp_pkt(enable, filter_interval_ms);
#else
return -1;//_promisc_filter_retransmit_normal_pkt(enable);
#endif
#else
return -1;
#endif
}
int promisc_filter_with_len(u16 len)
{
// Never reach here if not define CONFIG_PROMISC
#ifdef CONFIG_PROMISC
#if CONFIG_UNSUPPORT_PLCPHDR_RPT
return _promisc_filter_with_len(len);
#else
return -1;
#endif
#else
return -1;
#endif
}
int promisc_set(rtw_rcr_level_t enabled, void (*callback)(unsigned char*, unsigned int, void*), unsigned char len_used)
{
#ifdef CONFIG_PROMISC
return _promisc_set(enabled, callback, len_used);
#else
return -1;
#endif
}
unsigned char is_promisc_enabled(void)
{
#ifdef CONFIG_PROMISC
return _is_promisc_enabled();
#else
return 0;
#endif
}
int promisc_get_fixed_channel(void *fixed_bssid, u8 *ssid, int *ssid_length)
{
#ifdef CONFIG_PROMISC
return _promisc_get_fixed_channel(fixed_bssid, ssid, ssid_length);
#else
return 0;
#endif
}
void promisc_filter_by_ap_and_phone_mac(u8 enable, void *ap_mac, void *phone_mac)
{
#ifdef CONFIG_PROMISC
_promisc_filter_by_ap_and_phone_mac(enable, ap_mac, phone_mac);
#endif
}
// End of Add extra interfaces
struct eth_frame {
struct eth_frame *prev;
struct eth_frame *next;
unsigned char da[6];
unsigned char sa[6];
unsigned int len;
unsigned char type;
signed char rssi;
};
#if CONFIG_INIC_CMD_RSP
#if defined(__IAR_SYSTEMS_ICC__)||defined (__GNUC__)
#pragma pack(1)
#endif
struct inic_eth_frame {
unsigned char da[6];
unsigned char sa[6];
unsigned int len;
unsigned char type;
};
#if defined(__IAR_SYSTEMS_ICC__)||defined (__GNUC__)
#pragma pack()
#endif
static struct inic_eth_frame *inic_frame, *inic_frame_tail = NULL;
static int inic_frame_cnt = 0;
#define MAX_INIC_FRAME_NUM 50 //maximum packets for each channel
extern void inic_c2h_msg(const char *atcmd, char status, char *msg, u16 msg_len);
#endif
struct eth_buffer {
struct eth_frame *head;
struct eth_frame *tail;
};
static struct eth_buffer eth_buffer;
#ifdef CONFIG_PROMISC
#define MAX_PACKET_FILTER_INFO 5
#define FILTER_ID_INIT_VALUE 10
rtw_packet_filter_info_t paff_array[MAX_PACKET_FILTER_INFO]={0, 0, 0, 0, 0};
static u8 packet_filter_enable_num = 0;
void promisc_init_packet_filter()
{
int i = 0;
for(i=0; i<MAX_PACKET_FILTER_INFO; i++){
paff_array[i].filter_id = FILTER_ID_INIT_VALUE;
paff_array[i].enable = 0;
paff_array[i].patt.mask_size = 0;
paff_array[i].rule = RTW_POSITIVE_MATCHING;
paff_array[i].patt.mask = NULL;
paff_array[i].patt.pattern = NULL;
}
packet_filter_enable_num = 0;
}
int promisc_add_packet_filter(u8 filter_id, rtw_packet_filter_pattern_t *patt, rtw_packet_filter_rule_t rule)
{
int i = 0;
while(i < MAX_PACKET_FILTER_INFO){
if(paff_array[i].filter_id == FILTER_ID_INIT_VALUE){
break;
}
i++;
}
if(i == MAX_PACKET_FILTER_INFO)
return -1;
paff_array[i].filter_id = filter_id;
paff_array[i].patt.offset= patt->offset;
paff_array[i].patt.mask_size = patt->mask_size;
paff_array[i].patt.mask = pvPortMalloc(patt->mask_size);
memcpy(paff_array[i].patt.mask, patt->mask, patt->mask_size);
paff_array[i].patt.pattern= pvPortMalloc(patt->mask_size);
memcpy(paff_array[i].patt.pattern, patt->pattern, patt->mask_size);
paff_array[i].rule = rule;
paff_array[i].enable = 0;
return 0;
}
int promisc_enable_packet_filter(u8 filter_id)
{
int i = 0;
while(i < MAX_PACKET_FILTER_INFO){
if(paff_array[i].filter_id == filter_id)
break;
i++;
}
if(i == MAX_PACKET_FILTER_INFO)
return -1;
paff_array[i].enable = 1;
packet_filter_enable_num++;
return 0;
}
int promisc_disable_packet_filter(u8 filter_id)
{
int i = 0;
while(i < MAX_PACKET_FILTER_INFO){
if(paff_array[i].filter_id == filter_id)
break;
i++;
}
if(i == MAX_PACKET_FILTER_INFO)
return -1;
paff_array[i].enable = 0;
packet_filter_enable_num--;
return 0;
}
int promisc_remove_packet_filter(u8 filter_id)
{
int i = 0;
while(i < MAX_PACKET_FILTER_INFO){
if(paff_array[i].filter_id == filter_id)
break;
i++;
}
if(i == MAX_PACKET_FILTER_INFO)
return -1;
paff_array[i].filter_id = FILTER_ID_INIT_VALUE;
paff_array[i].enable = 0;
paff_array[i].patt.mask_size = 0;
paff_array[i].rule = 0;
if(paff_array[i].patt.mask){
vPortFree(paff_array[i].patt.mask);
paff_array[i].patt.mask = NULL;
}
if(paff_array[i].patt.pattern){
vPortFree(paff_array[i].patt.pattern);
paff_array[i].patt.pattern = NULL;
}
return 0;
}
#endif
/* Make callback simple to prevent latency to wlan rx when promiscuous mode */
static void promisc_callback(unsigned char *buf, unsigned int len, void* userdata)
{
struct eth_frame *frame = (struct eth_frame *) pvPortMalloc(sizeof(struct eth_frame));
if(frame) {
frame->prev = NULL;
frame->next = NULL;
memcpy(frame->da, buf, 6);
memcpy(frame->sa, buf+6, 6);
frame->len = len;
frame->rssi = ((ieee80211_frame_info_t *)userdata)->rssi;
taskENTER_CRITICAL();
if(eth_buffer.tail) {
eth_buffer.tail->next = frame;
frame->prev = eth_buffer.tail;
eth_buffer.tail = frame;
}
else {
eth_buffer.head = frame;
eth_buffer.tail = frame;
}
taskEXIT_CRITICAL();
}
}
struct eth_frame* retrieve_frame(void)
{
struct eth_frame *frame = NULL;
taskENTER_CRITICAL();
if(eth_buffer.head) {
frame = eth_buffer.head;
if(eth_buffer.head->next) {
eth_buffer.head = eth_buffer.head->next;
eth_buffer.head->prev = NULL;
}
else {
eth_buffer.head = NULL;
eth_buffer.tail = NULL;
}
}
taskEXIT_CRITICAL();
return frame;
}
static void promisc_test(int duration, unsigned char len_used)
{
int ch;
unsigned int start_time;
struct eth_frame *frame;
eth_buffer.head = NULL;
eth_buffer.tail = NULL;
wifi_enter_promisc_mode();
wifi_set_promisc(RTW_PROMISC_ENABLE, promisc_callback, len_used);
for(ch = 1; ch <= 13; ch ++) {
if(wifi_set_channel(ch) == 0)
printf("\n\n\rSwitch to channel(%d)", ch);
start_time = xTaskGetTickCount();
while(1) {
unsigned int current_time = xTaskGetTickCount();
if((current_time - start_time) < (duration * configTICK_RATE_HZ)) {
frame = retrieve_frame();
if(frame) {
int i;
printf("\n\rDA:");
for(i = 0; i < 6; i ++)
printf(" %02x", frame->da[i]);
printf(", SA:");
for(i = 0; i < 6; i ++)
printf(" %02x", frame->sa[i]);
printf(", len=%d", frame->len);
printf(", RSSI=%d", frame->rssi);
#if CONFIG_INIC_CMD_RSP
if(inic_frame_tail){
if(inic_frame_cnt < MAX_INIC_FRAME_NUM){
memcpy(inic_frame_tail->da, frame->da, 6);
memcpy(inic_frame_tail->sa, frame->sa, 6);
inic_frame_tail->len = frame->len;
inic_frame_tail++;
inic_frame_cnt++;
}
}
#endif
vPortFree((void *) frame);
}
else
vTaskDelay(1); //delay 1 tick
}
else
break;
}
#if CONFIG_INIC_CMD_RSP
if(inic_frame){
inic_c2h_msg("ATWM", RTW_SUCCESS, (char *)inic_frame, sizeof(struct inic_eth_frame)*inic_frame_cnt);
memset(inic_frame, '\0', sizeof(struct inic_eth_frame)*MAX_INIC_FRAME_NUM);
inic_frame_tail = inic_frame;
inic_frame_cnt = 0;
rtw_msleep_os(10);
}
#endif
}
wifi_set_promisc(RTW_PROMISC_DISABLE, NULL, 0);
while((frame = retrieve_frame()) != NULL)
vPortFree((void *) frame);
}
static void promisc_callback_all(unsigned char *buf, unsigned int len, void* userdata)
{
struct eth_frame *frame = (struct eth_frame *) pvPortMalloc(sizeof(struct eth_frame));
if(frame) {
frame->prev = NULL;
frame->next = NULL;
#if CONFIG_UNSUPPORT_PLCPHDR_RPT
if(((ieee80211_frame_info_t *)userdata)->type == RTW_RX_UNSUPPORT){
//NOTICE: buf structure now is rtw_rx_info_t.
frame->type = 0xFF;
memset(frame->da, 0, 6);
memset(frame->sa, 0, 6);
}
else
#endif
{
memcpy(frame->da, buf+4, 6);
memcpy(frame->sa, buf+10, 6);
frame->type = *buf;
}
frame->len = len;
/*
* type is the first byte of Frame Control Field of 802.11 frame
* If the from/to ds information is needed, type could be reused as follows:
* frame->type = ((((ieee80211_frame_info_t *)userdata)->i_fc & 0x0100) == 0x0100) ? 2 : 1;
* 1: from ds; 2: to ds
*/
frame->rssi = ((ieee80211_frame_info_t *)userdata)->rssi;
taskENTER_CRITICAL();
if(eth_buffer.tail) {
eth_buffer.tail->next = frame;
frame->prev = eth_buffer.tail;
eth_buffer.tail = frame;
}
else {
eth_buffer.head = frame;
eth_buffer.tail = frame;
}
taskEXIT_CRITICAL();
}
}
static void promisc_test_all(int duration, unsigned char len_used)
{
int ch;
unsigned int start_time;
struct eth_frame *frame;
eth_buffer.head = NULL;
eth_buffer.tail = NULL;
wifi_enter_promisc_mode();
wifi_set_promisc(RTW_PROMISC_ENABLE_2, promisc_callback_all, len_used);
for(ch = 1; ch <= 13; ch ++) {
if(wifi_set_channel(ch) == 0)
printf("\n\n\rSwitch to channel(%d)", ch);
start_time = xTaskGetTickCount();
while(1) {
unsigned int current_time = xTaskGetTickCount();
if((current_time - start_time) < (duration * configTICK_RATE_HZ)) {
frame = retrieve_frame();
if(frame) {
int i;
printf("\n\rTYPE: 0x%x, ", frame->type);
printf("DA:");
for(i = 0; i < 6; i ++)
printf(" %02x", frame->da[i]);
printf(", SA:");
for(i = 0; i < 6; i ++)
printf(" %02x", frame->sa[i]);
printf(", len=%d", frame->len);
printf(", RSSI=%d", frame->rssi);
#if CONFIG_INIC_CMD_RSP
if(inic_frame_tail){
if(inic_frame_cnt < MAX_INIC_FRAME_NUM){
memcpy(inic_frame_tail->da, frame->da, 6);
memcpy(inic_frame_tail->sa, frame->sa, 6);
inic_frame_tail->len = frame->len;
inic_frame_tail->type = frame->type;
inic_frame_tail++;
inic_frame_cnt++;
}
}
#endif
vPortFree((void *) frame);
}
else
vTaskDelay(1); //delay 1 tick
}
else
break;
}
#if CONFIG_INIC_CMD_RSP
if(inic_frame){
inic_c2h_msg("ATWM", RTW_SUCCESS, (char *)inic_frame, sizeof(struct inic_eth_frame)*inic_frame_cnt);
memset(inic_frame, '\0', sizeof(struct inic_eth_frame)*MAX_INIC_FRAME_NUM);
inic_frame_tail = inic_frame;
inic_frame_cnt = 0;
rtw_msleep_os(10);
}
#endif
}
wifi_set_promisc(RTW_PROMISC_DISABLE, NULL, 0);
while((frame = retrieve_frame()) != NULL)
vPortFree((void *) frame);
}
void cmd_promisc(int argc, char **argv)
{
int duration;
#if CONFIG_INIC_CMD_RSP
inic_frame_tail = inic_frame = pvPortMalloc(sizeof(struct inic_eth_frame)*MAX_INIC_FRAME_NUM);
if(inic_frame == NULL){
inic_c2h_msg("ATWM", RTW_BUFFER_UNAVAILABLE_TEMPORARY, NULL, 0);
return;
}
#endif
#ifdef CONFIG_PROMISC
wifi_init_packet_filter();
#endif
if((argc == 2) && ((duration = atoi(argv[1])) > 0))
//promisc_test(duration, 0);
promisc_test_all(duration, 0);
else if((argc == 3) && ((duration = atoi(argv[1])) > 0) && (strcmp(argv[2], "with_len") == 0))
promisc_test(duration, 1);
else
printf("\n\rUsage: %s DURATION_SECONDS [with_len]", argv[0]);
#if CONFIG_INIC_CMD_RSP
if(inic_frame)
vPortFree(inic_frame);
inic_frame_tail = NULL;
inic_frame_cnt = 0;
#endif
}
#endif //#if CONFIG_WLAN

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
#ifndef __WIFI_SIMPLE_CONFIG_H
#define __WIFI_SIMPLE_CONFIG_H
/*****************************wifi_simple_config.h****************************/
enum sc_result {
SC_ERROR = -1, /* default error code*/
SC_NO_CONTROLLER_FOUND = 1, /* cannot get sta(controller) in the air which starts a simple config session */
SC_CONTROLLER_INFO_PARSE_FAIL, /* cannot parse the sta's info */
SC_TARGET_CHANNEL_SCAN_FAIL, /* cannot scan the target channel */
SC_JOIN_BSS_FAIL, /* fail to connect to target ap */
SC_DHCP_FAIL, /* fail to get ip address from target ap */
/* fail to create udp socket to send info to controller. note that client isolation
must be turned off in ap. we cannot know if ap has configured this */
SC_UDP_SOCKET_CREATE_FAIL,
SC_TERMINATE,
SC_SUCCESS, /* default success code */
};
int SC_send_simple_config_ack(u8 round);
void print_simple_config_result(enum sc_result sc_code);
#endif //__WIFI_SIMPLE_CONFIG_H

View File

@@ -0,0 +1,117 @@
#ifndef __SIMPLE_CONFIG_H__
#define __SIMPLE_CONFIG_H__
#ifdef __cplusplus
extern "C" {
#endif
/* This macro means user take simple config
* lib to another platform such as linux, and
* have no rom crypto libs of simple config,
* so we take simple_config_crypto as a sw lib
* This macro is used by Realtek internal to generate simple config lib
* Please delete this macro after generation.
*/
#define SIMPLE_CONFIG_PLATFORM_LIB 0
#include "platform_opts.h"
#include "autoconf.h"
/* platform related settings */
#if (defined(CONFIG_PLATFORM_8195A)|| defined(CONFIG_PLATFORM_8711B))
#undef u32
#undef s32
#undef u8
#undef s8
#undef u16
#undef s16
typedef unsigned int u32;
typedef signed int s32;
typedef unsigned char u8;
typedef char s8;
typedef unsigned short int u16;
typedef signed short int s16;
#else
#include "osdep_service.h"
#endif
typedef int (*simple_config_printf_fn) (char const * fmt, ...);
typedef void* (*simple_config_memset_fn) (void *dst0, s32 Val, u32 length);
typedef void* (*simple_config_memcpy_fn) ( void *s1, const void *s2, u32 n );
typedef u32 (*simple_config_strlen_fn) (const char *s);
typedef char * (*simple_config_strcpy_fn) (char *dest, const char *src);
typedef void (*simple_config_free_fn) (u8 *pbuf, u32 sz);
typedef u8* (*simple_config_zmalloc_fn) (u32 sz);
typedef u8* (*simple_config_malloc_fn) (u32 sz);
typedef int (*simple_config_memcmp_fn) (const void *av, const void *bv, u32 len);
typedef u32 (*simple_config_ntohl_fn)(u32 x);
struct simple_config_lib_config {
simple_config_printf_fn printf;
simple_config_memset_fn memset;
simple_config_memcpy_fn memcpy;
simple_config_strlen_fn strlen;
simple_config_strcpy_fn strcpy;
simple_config_free_fn free;
simple_config_zmalloc_fn zmalloc;
simple_config_malloc_fn malloc;
simple_config_memcmp_fn memcmp;
simple_config_ntohl_fn _ntohl;
int *is_promisc_callback_unlock;
};
#pragma pack(1)
struct rtk_test_sc {
/* API exposed to user */
unsigned char ssid[32];
unsigned char password[65];
unsigned int ip_addr;
};
// for softAP mode
typedef enum {
SOFTAP_ERROR = -1,
SOFTAP_INIT,
SOFTAP_RECV_A,
SOFTAP_HANDSHAKE_DONE,
SOFTAP_DECODE_SUCCESS,
} SC_softAP_status;
#pragma pack(1)
typedef struct _SC_softAP_decode_ctx {
u8 nonceA[16];
u8 nonceB[32];
u8 mac[6];
SC_softAP_status softAP_decode_status;
} SC_softAP_decode_ctx;
/* expose data */
extern s32 is_promisc_callback_unlock;
extern u8 g_bssid[6];
extern u8 get_channel_flag;
extern u8 g_security_mode;
/* expose API */
extern s32 rtk_sc_init(char *custom_pin_code, struct simple_config_lib_config* config);
extern int rtl_pre_parse(u8 *mac_addr, u8 *buf, void *userdata, u8 **da, u8 **sa, unsigned int *len);
extern s32 rtk_start_parse_packet(u8 *da, u8 *sa, s32 len, void * user_data, void *backup_sc);
extern SC_softAP_status softAP_simpleConfig_parse(unsigned char *buf, int len, void *backup_sc_ctx, void *psoftAP_ctx);
extern void rtk_restart_simple_config(void);
extern void rtk_sc_deinit();
extern void wifi_enter_promisc_mode();
extern void whc_fix_channel();
extern void whc_unfix_channel();
#ifdef __cplusplus
}
#endif
#endif /* __SIMPLE_CONFIG_H__*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,114 @@
#ifndef _UTIL_H
#define _UTIL_H
#include <wireless.h>
#include <wlan_intf.h>
#include <wifi_constants.h>
#include "wifi_structures.h"
#ifdef __cplusplus
extern "C" {
#endif
int wext_get_ssid(const char *ifname, __u8 *ssid);
int wext_set_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len);
int wext_set_bssid(const char *ifname, const __u8 *bssid);
int wext_get_bssid(const char *ifname, __u8 *bssid);
int wext_set_auth_param(const char *ifname, __u16 idx, __u32 value);
int wext_set_mfp_support(const char *ifname, __u8 value);
#ifdef CONFIG_SAE_SUPPORT
int wext_set_group_id(const char *ifname, __u8 value);
int wext_set_support_wpa3(__u8 enable);
__u8 wext_get_support_wpa3(void);
#endif
#ifdef CONFIG_PMKSA_CACHING
int wext_set_pmk_cache_enable(const char *ifname, __u8 value);
#endif
int wext_set_key_ext(const char *ifname, __u16 alg, const __u8 *addr, int key_idx, int set_tx, const __u8 *seq, __u16 seq_len, __u8 *key, __u16 key_len);
int wext_get_enc_ext(const char *ifname, __u16 *alg, __u8 *key_idx, __u8 *passphrase);
int wext_get_auth_type(const char *ifname, __u32 *auth_type);
int wext_set_passphrase(const char *ifname, const __u8 *passphrase, __u16 passphrase_len);
int wext_get_passphrase(const char *ifname, __u8 *passphrase);
int wext_set_mode(const char *ifname, int mode);
int wext_get_mode(const char *ifname, int *mode);
int wext_set_ap_ssid(const char *ifname, const __u8 *ssid, __u16 ssid_len);
int wext_set_country(const char *ifname, rtw_country_code_t country_code);
int wext_get_rssi(const char *ifname, int *rssi);
int wext_get_snr(const char *ifname, int *snr);
int wext_set_channel(const char *ifname, __u8 ch);
int wext_get_channel(const char *ifname, __u8 *ch);
int wext_register_multicast_address(const char *ifname, rtw_mac_t *mac);
int wext_unregister_multicast_address(const char *ifname, rtw_mac_t *mac);
int wext_set_scan(const char *ifname, char *buf, __u16 buf_len, __u16 flags);
int wext_get_scan(const char *ifname, char *buf, __u16 buf_len);
int wext_set_mac_address(const char *ifname, char * mac);
int wext_get_mac_address(const char *ifname, char * mac);
int wext_enable_powersave(const char *ifname, __u8 lps_mode, __u8 ips_mode);
int wext_disable_powersave(const char *ifname);
int wext_set_tdma_param(const char *ifname, __u8 slot_period, __u8 rfon_period_len_1, __u8 rfon_period_len_2, __u8 rfon_period_len_3);
int wext_set_lps_dtim(const char *ifname, __u8 lps_dtim);
int wext_get_lps_dtim(const char *ifname, __u8 *lps_dtim);
int wext_get_tx_power(const char *ifname, __u8 *poweridx);
int wext_set_txpower(const char *ifname, int poweridx);
int wext_get_associated_client_list(const char *ifname, void * client_list_buffer, __u16 buffer_length);
int wext_get_ap_info(const char *ifname, rtw_bss_info_t * ap_info, rtw_security_t* security);
int wext_mp_command(const char *ifname, char *cmd, int show_msg);
int wext_private_command(const char *ifname, char *cmd, int show_msg);
int wext_private_command_with_retval(const char *ifname, char *cmd, char *ret_buf, int ret_len);
void wext_wlan_indicate(unsigned int cmd, union iwreq_data *wrqu, char *extra);
int wext_set_pscan_channel(const char *ifname, __u8 *ch, __u8 *pscan_config, __u8 length);
int wext_set_autoreconnect(const char *ifname, __u8 mode, __u8 retry_times, __u16 timeout);
int wext_get_autoreconnect(const char *ifname, __u8 *mode);
int wext_set_adaptivity(rtw_adaptivity_mode_t adaptivity_mode);
int wext_set_adaptivity_th_l2h_ini(__u8 l2h_threshold);
int wext_set_trp_tis(__u8 enable);
#if defined(CONFIG_WLAN_LOW_PW)
void wext_set_low_power_mode(__u8 enable);
#endif
int wext_get_auto_chl(const char *ifname, unsigned char *channel_set, unsigned char channel_num);
int wext_set_sta_num(unsigned char ap_sta_num);
int wext_del_station(const char *ifname, unsigned char* hwaddr);
int wext_init_mac_filter(void);
int wext_deinit_mac_filter(void);
int wext_add_mac_filter(unsigned char* hwaddr);
int wext_del_mac_filter(unsigned char* hwaddr);
void wext_set_indicate_mgnt(int enable);
#ifdef CONFIG_CUSTOM_IE
int wext_add_custom_ie(const char *ifname, void * cus_ie, int ie_num);
int wext_update_custom_ie(const char *ifname, void * cus_ie, int ie_index);
int wext_del_custom_ie(const char *ifname);
#endif
#define wext_handshake_done rltk_wlan_handshake_done
int wext_send_mgnt(const char *ifname, char *buf, __u16 buf_len, __u16 flags);
int wext_send_eapol(const char *ifname, char *buf, __u16 buf_len, __u16 flags);
int wext_set_gen_ie(const char *ifname, char *buf, __u16 buf_len, __u16 flags);
void wext_suspend_softap(const char *ifname);
int wext_ap_switch_chl_and_inform(unsigned char new_channel);
int wext_get_nhm_ratio_level(const char *ifname, __u32 *level);
int wext_get_retry_drop_num(const char *ifname, rtw_fw_retry_drop_t * retry);
int wext_get_sw_trx_statistics(const char *ifname, rtw_net_device_stats_t *stats);
void wext_set_indicate_mgnt(int enable);
void wext_set_lowrssi_use_b(int enable,int rssi);
#ifndef CONFIG_MCC_STA_AP_MODE
int wext_get_RxInfo(const char *ifname, __u8* BeaconCnt, int *rssi, __u8* CurIGValue, __u32* Fa_Ofdm_count, __u32* Fa_Cck_count);
int wext_get_RxCrcInfo(const char *ifname, __u32* CCK_Crc_Fail, __u32* CCK_Crc_OK, __u32* OFDM_Crc_Fail, __u32* OFDM_Crc_OK, __u32* HT_Crc_Fail, __u32* HT_Crc_OK);
int wext_get_TxInfo(const char *ifname, __u32 *tx_ok, __u32 *tx_retry, __u32 *tx_drop);
int wext_get_PSInfo(const char *ifname, __u32* tim_wake_up_count);
#endif
#ifdef CONFIG_SYNCPKT
int wext_set_syncpkt_da(const char *ifname, __u8 *da);
int wext_send_syncpkt(const char *ifname, __u8 flag, __u8 pktnum, __u8 interval);
int wext_disable_fw_ips(const char *ifname, __u8 enable);
#endif
int wext_set_adaptivity_enable(const char *ifname, __u8 value);
__u8 wext_get_adaptivity_enable(const char *ifname);
int wext_set_adaptivity_mode(const char *ifname, __u8 mode);
__u8 wext_get_adaptivity_mode(const char *ifname);
__u8 wext_get_channel_plan(const char *ifname);
#ifdef __cplusplus
}
#endif
#endif /* _UTIL_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
#ifndef _GOOGLENEST_H_
#define _GOOGLENEST_H_
#include "platform_opts.h"
#define GOOGLENEST_TLS_POLARSSL 0 /*!< Use PolarSSL for TLS when GOOGLENEST */
#define GOOGLENEST_TLS_MBEDTLS 1 /*!< Use mbedTLS for TLS when GOOGLENEST */
#if CONFIG_USE_POLARSSL
#define GOOGLENEST_USE_TLS GOOGLENEST_TLS_POLARSSL
#elif CONFIG_USE_MBEDTLS
#define GOOGLENEST_USE_TLS GOOGLENEST_TLS_MBEDTLS
#endif
#define BUFFER_SIZE 512
typedef struct {
int socket;
void *tls;
char *host;
} googlenest_context;
int gn_connect(googlenest_context *googlenest, char *host, int port);
void gn_close(googlenest_context *googlenest);
int gn_put(googlenest_context *googlenest, char *uri, char *content);
int gn_patch(googlenest_context *googlenest, char *uri, char *content);
int gn_post(googlenest_context *googlenest, char *uri, char *content, unsigned char *out_buffer, unsigned int out_len);
int gn_get(googlenest_context *googlenest, char *uri, unsigned char *out_buffer, unsigned int out_len);
int gn_delete(googlenest_context *googlenest, char *uri);
int gn_stream(googlenest_context *googlenest, char *uri);
void google_retrieve_data_hook_callback(void (*callback)(char *));
void *gn_tls_connect(int *sock , char *host, int port);
void gn_tls_close(void *tls_in,int *sock);
int gn_tls_write(void *tls_in, char *request, int request_len);
int gn_tls_read(void *tls_in, char *buffer, int buf_len);
#endif

View File

@@ -0,0 +1,217 @@
#include "FreeRTOS.h"
#include "task.h"
#include "platform_stdlib.h"
#include "google_nest.h"
#if (GOOGLENEST_USE_TLS == GOOGLENEST_TLS_POLARSSL)
#include <polarssl/net.h>
#include <polarssl/ssl.h>
#include <polarssl/error.h>
#include <polarssl/memory.h>
struct gn_tls{
ssl_context ctx;
};
#elif (GOOGLENEST_USE_TLS == GOOGLENEST_TLS_MBEDTLS)
#include "mbedtls/net.h"
#include "mbedtls/ssl.h"
#include "mbedtls/error.h"
struct gn_tls{
mbedtls_ssl_context ctx;
mbedtls_ssl_config conf;
mbedtls_net_context socket;
};
static void* _calloc_func(size_t nmemb, size_t size) {
size_t mem_size;
void *ptr = NULL;
mem_size = nmemb * size;
ptr = pvPortMalloc(mem_size);
if(ptr)
memset(ptr, 0, mem_size);
return ptr;
}
static char *gn_itoa(int value){
char *val_str;
int tmp = value, len = 1;
while((tmp /= 10) > 0)
len ++;
val_str = (char *) pvPortMalloc(len + 1);
sprintf(val_str, "%d", value);
return val_str;
}
#endif /* GOOGLENEST_USE_TLS */
static int _random_func(void *p_rng, unsigned char *output, unsigned int output_len) {
rtw_get_random_bytes(output, output_len);
return 0;
}
void *gn_tls_connect(int *sock , char *host, int port){
#if (GOOGLENEST_USE_TLS == GOOGLENEST_TLS_POLARSSL)
int ret;
struct gn_tls *tls =NULL;
memory_set_own(pvPortMalloc, vPortFree);
tls = (struct gn_tls *) malloc(sizeof(struct gn_tls));
if(tls){
ssl_context *ssl = &tls->ctx;
memset(tls, 0, sizeof(struct gn_tls));
if((ret = net_connect(sock, host, port)) != 0) {
printf("\n[GOOGLENEST] ERROR: net_connect %d\n", ret);
goto exit;
}
if((ret = ssl_init(ssl)) != 0) {
printf("\n[GOOGLENEST] ERROR: ssl_init %d\n", ret);
goto exit;
}
ssl_set_endpoint(ssl, SSL_IS_CLIENT);
ssl_set_authmode(ssl, SSL_VERIFY_NONE);
ssl_set_rng(ssl, _random_func, NULL);
ssl_set_bio(ssl, net_recv, sock, net_send, sock);
if((ret = ssl_handshake(ssl)) != 0) {
printf("\n[GOOGLENEST] ERROR: ssl_handshake -0x%x\n", -ret);
goto exit;
}
}
else{
printf("\n[GOOGLENEST] ERROR: malloc\n");
ret = -1;
goto exit;
}
exit:
if(ret && tls) {
net_close(*sock);
ssl_free(&tls->ctx);
free(tls);
tls = NULL;
}
return (void *) tls;
#elif (GOOGLENEST_USE_TLS == GOOGLENEST_TLS_MBEDTLS)
int ret;
struct gn_tls *tls =NULL;
mbedtls_platform_set_calloc_free(_calloc_func, vPortFree);
tls = (struct gn_tls *) malloc(sizeof(struct gn_tls));
if(tls){
mbedtls_ssl_context *ssl = &tls->ctx;
mbedtls_ssl_config *conf = &tls->conf;
mbedtls_net_context *server_fd = &tls->socket;
memset(tls, 0, sizeof(struct gn_tls));
server_fd->fd = *sock;
char *port_str = gn_itoa(port);
if((ret = mbedtls_net_connect(server_fd, host, port_str, MBEDTLS_NET_PROTO_TCP)) != 0) {
printf("\n[GOOGLENEST] ERROR: net_connect %d\n", ret);
goto exit;
}
free(port_str);
*sock = server_fd->fd;
mbedtls_ssl_init(ssl);
mbedtls_ssl_config_init(conf);
mbedtls_ssl_set_bio(ssl, server_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
if((ret = mbedtls_ssl_config_defaults(conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
printf("\n[GOOGLENEST] ERROR: ssl_config %d\n", ret);
goto exit;
}
mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_NONE);
mbedtls_ssl_conf_rng(conf, _random_func, NULL);
if((ret = mbedtls_ssl_setup(ssl, conf)) != 0) {
printf("\n[GOOGLENEST] ERROR: ssl_setup %d\n", ret);
goto exit;
}
if((ret = mbedtls_ssl_handshake(ssl)) != 0) {
printf("\n[GOOGLENEST] ERROR: ssl_handshake -0x%x\n", -ret);
goto exit;
}
}
else {
printf("\n[GOOGLENEST] ERROR: malloc\n");
ret = -1;
goto exit;
}
exit:
if(ret && tls){
mbedtls_net_free(&tls->socket);
mbedtls_ssl_free(&tls->ctx);
mbedtls_ssl_config_free(&tls->conf);
free(tls);
tls = NULL;
}
return (void *) tls;
#endif /* GOOGLENEST_USE_TLS */
}
void gn_tls_close(void *tls_in,int *sock){
struct gn_tls *tls = (struct gn_tls *)tls_in;
#if (GOOGLENEST_USE_TLS == GOOGLENEST_TLS_POLARSSL)
if(tls)
ssl_close_notify(&tls->ctx);
if(*sock != -1){
net_close(*sock);
*sock = -1;
}
ssl_free(&tls->ctx);
free(tls);
tls = NULL;
#elif (GOOGLENEST_USE_TLS == GOOGLENEST_TLS_MBEDTLS)
if(tls)
mbedtls_ssl_close_notify(&tls->ctx);
if(*sock != -1){
mbedtls_net_free(&tls->socket);
*sock = -1;
}
mbedtls_ssl_free(&tls->ctx);
mbedtls_ssl_config_free(&tls->conf);
free(tls);
tls = NULL;
#endif /* GOOGLENEST_USE_TLS */
}
int gn_tls_write(void *tls_in, char *request, int request_len){
struct gn_tls *tls = (struct gn_tls *)tls_in;
#if (GOOGLENEST_USE_TLS == GOOGLENEST_TLS_POLARSSL)
return ssl_write(&tls->ctx, request, request_len);
#elif (GOOGLENEST_USE_TLS == GOOGLENEST_TLS_MBEDTLS)
return mbedtls_ssl_write(&tls->ctx, request, request_len);
#endif /* GOOGLENEST_USE_TLS */
}
int gn_tls_read(void *tls_in, char *buffer, int buf_len){
struct gn_tls *tls = (struct gn_tls *)tls_in;
#if (GOOGLENEST_USE_TLS == GOOGLENEST_TLS_POLARSSL)
return ssl_read(&tls->ctx, buffer, buf_len);
#elif (GOOGLENEST_USE_TLS == GOOGLENEST_TLS_MBEDTLS)
return mbedtls_ssl_read(&tls->ctx, buffer, buf_len);
#endif /* GOOGLENEST_USE_TLS */
}

View File

@@ -0,0 +1,873 @@
/*******************************************************************************
* Copyright (c) 2014, 2015 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Allan Stockdill-Mander/Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTClient.h"
const char * const msg_types_str[]=
{
"Reserved",
"CONNECT",
"CONNACK",
"PUBLISH",
"PUBACK",
"PUBREC",
"PUBREL",
"PUBCOMP",
"SUBSCRIBE",
"SUBACK",
"UNSUBSCRIBE",
"UNSUBACK",
"PINGREQ",
"PINGRESP",
"DISCONNECT",
"Reserved"
};
const char * const mqtt_status_str[]=
{
"MQTT_START",
"MQTT_CONNECT",
"MQTT_SUBTOPIC",
"MQTT_RUNNING"
};
static void NewMessageData(MessageData* md, MQTTString* aTopicName, MQTTMessage* aMessage) {
md->topicName = aTopicName;
md->message = aMessage;
}
static int getNextPacketId(MQTTClient *c) {
return c->next_packetid = (c->next_packetid == MAX_PACKET_ID) ? 1 : c->next_packetid + 1;
}
static int sendPacket(MQTTClient* c, int length, Timer* timer)
{
int rc = FAILURE,
sent = 0;
while (sent < length && !TimerIsExpired(timer))
{
rc = c->ipstack->mqttwrite(c->ipstack, &c->buf[sent], length, TimerLeftMS(timer));
if (rc < 0) // there was an error writing the data
break;
sent += rc;
}
if (sent == length)
{
TimerCountdown(&c->ping_timer, c->keepAliveInterval); // record the fact that we have successfully sent the packet
rc = SUCCESS;
}
else{
rc = FAILURE;
mqtt_printf(MQTT_DEBUG, "Send packet failed");
}
if (c->ipstack->my_socket < 0) {
c->isconnected = 0;
}
return rc;
}
void MQTTClientInit(MQTTClient* c, Network* network, unsigned int command_timeout_ms,
unsigned char* sendbuf, size_t sendbuf_size, unsigned char* readbuf, size_t readbuf_size)
{
int i;
c->ipstack = network;
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
c->messageHandlers[i].topicFilter = 0;
c->command_timeout_ms = command_timeout_ms;
c->buf = sendbuf;
c->buf_size = sendbuf_size;
c->readbuf = readbuf;
c->readbuf_size = readbuf_size;
c->isconnected = 0;
c->ping_outstanding = 0;
c->defaultMessageHandler = NULL;
c->next_packetid = 1;
c->ipstack->m2m_rxevent = 0;
c->mqttstatus = MQTT_START;
TimerInit(&c->cmd_timer);
TimerInit(&c->ping_timer);
}
static int decodePacket(MQTTClient* c, int* value, int timeout)
{
unsigned char i;
int multiplier = 1;
int len = 0;
const int MAX_NO_OF_REMAINING_LENGTH_BYTES = 4;
*value = 0;
do
{
int rc = MQTTPACKET_READ_ERROR;
if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
{
rc = MQTTPACKET_READ_ERROR; /* bad data */
goto exit;
}
rc = c->ipstack->mqttread(c->ipstack, &i, 1, timeout);
if (rc != 1)
goto exit;
*value += (i & 127) * multiplier;
multiplier *= 128;
} while ((i & 128) != 0);
exit:
return len;
}
static int readPacket(MQTTClient* c, Timer* timer)
{
int rc = FAILURE;
MQTTHeader header = {0};
int len = 0;
int rem_len = 0;
/* 1. read the header byte. This has the packet type in it */
if (c->ipstack->mqttread(c->ipstack, c->readbuf, 1, TimerLeftMS(timer)) != 1){
mqtt_printf(MQTT_MSGDUMP, "read packet header failed");
goto exit;
}
len = 1;
/* 2. read the remaining length. This is variable in itself */
decodePacket(c, &rem_len, TimerLeftMS(timer));
len += MQTTPacket_encode(c->readbuf + 1, rem_len); /* put the original remaining length back into the buffer */
if(len + rem_len > c->readbuf_size){
mqtt_printf(MQTT_WARNING, "rem_len = %d, read buffer will overflow", rem_len);
rc = BUFFER_OVERFLOW;
goto exit;
}
/* 3. read the rest of the buffer using a callback to supply the rest of the data */
if (rem_len > 0 && (c->ipstack->mqttread(c->ipstack, c->readbuf + len, rem_len, TimerLeftMS(timer)) != rem_len)){
mqtt_printf(MQTT_MSGDUMP, "read the rest of the data failed");
goto exit;
}
header.byte = c->readbuf[0];
rc = header.bits.type;
exit:
if (c->ipstack->my_socket < 0) {
c->isconnected = 0;
}
return rc;
}
// assume topic filter and name is in correct format
// # can only be at end
// + and # can only be next to separator
static char isTopicMatched(char* topicFilter, MQTTString* topicName)
{
char* curf = topicFilter;
char* curn = topicName->lenstring.data;
char* curn_end = curn + topicName->lenstring.len;
while (*curf && curn < curn_end)
{
if (*curn == '/' && *curf != '/')
break;
if (*curf != '+' && *curf != '#' && *curf != *curn)
break;
if (*curf == '+')
{ // skip until we meet the next separator, or end of string
char* nextpos = curn + 1;
while (nextpos < curn_end && *nextpos != '/')
nextpos = ++curn + 1;
}
else if (*curf == '#')
curn = curn_end - 1; // skip until end of string
curf++;
curn++;
};
return (curn == curn_end) && (*curf == '\0');
}
int deliverMessage(MQTTClient* c, MQTTString* topicName, MQTTMessage* message)
{
int i;
int rc = FAILURE;
// we have to find the right message handler - indexed by topic
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
{
if (c->messageHandlers[i].topicFilter != 0 && (MQTTPacket_equals(topicName, (char*)c->messageHandlers[i].topicFilter) ||
isTopicMatched((char*)c->messageHandlers[i].topicFilter, topicName)))
{
if (c->messageHandlers[i].fp != NULL)
{
MessageData md;
NewMessageData(&md, topicName, message);
c->messageHandlers[i].fp(&md);
rc = SUCCESS;
}
}
}
if (rc == FAILURE && c->defaultMessageHandler != NULL)
{
MessageData md;
NewMessageData(&md, topicName, message);
c->defaultMessageHandler(&md);
rc = SUCCESS;
}
return rc;
}
int keepalive(MQTTClient* c)
{
int rc = FAILURE;
if (c->keepAliveInterval == 0)
{
rc = SUCCESS;
goto exit;
}
if (TimerIsExpired(&c->ping_timer))
{
if (!c->ping_outstanding)
{
Timer timer;
TimerInit(&timer);
TimerCountdownMS(&timer, 1000);
int len = MQTTSerialize_pingreq(c->buf, c->buf_size);
if (len > 0 && (rc = sendPacket(c, len, &timer)) == SUCCESS) // send the ping packet
c->ping_outstanding = 1;
}
}
exit:
return rc;
}
void MQTTCloseSession(MQTTClient* c)
{
c->ping_outstanding = 0;
c->isconnected = 0;
}
int cycle(MQTTClient* c, Timer* timer)
{
// read the socket, see what work is due
unsigned short packet_type = readPacket(c, timer);
int len = 0, rc = SUCCESS;
if (packet_type == (unsigned short)BUFFER_OVERFLOW || packet_type == (unsigned short)FAILURE) {
rc = FAILURE;
goto exit;
}
mqtt_printf(MQTT_DEBUG, "Read packet type: %d", packet_type);
switch (packet_type)
{
case CONNACK:
case PUBACK:
case SUBACK:
break;
case PUBLISH:
{
MQTTString topicName;
MQTTMessage msg;
int intQoS;
if (MQTTDeserialize_publish(&msg.dup, &intQoS, &msg.retained, &msg.id, &topicName,
(unsigned char**)&msg.payload, (int*)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1)
goto exit;
msg.qos = (enum QoS)intQoS;
deliverMessage(c, &topicName, &msg);
if (msg.qos != QOS0)
{
if (msg.qos == QOS1)
len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id);
else if (msg.qos == QOS2)
len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id);
if (len <= 0)
rc = FAILURE;
else {
#if 1
sendPacket(c, len, timer);
#else
// it's odd that ACK PUB also need success
rc = sendPacket(c, len, timer);
#endif
}
if (rc == FAILURE)
goto exit; // there was a problem
}
break;
}
case PUBREC:
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
rc = FAILURE;
else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREL, 0, mypacketid)) <= 0)
rc = FAILURE;
else if ((rc = sendPacket(c, len, timer)) != SUCCESS) // send the PUBREL packet
rc = FAILURE; // there was a problem
if (rc == FAILURE)
goto exit; // there was a problem
break;
}
case PUBREL:
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
rc = FAILURE;
else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBCOMP, 0, mypacketid)) <= 0)
rc = FAILURE;
else if ((rc = sendPacket(c, len, timer)) != SUCCESS) // send the PUBREL packet
rc = FAILURE; // there was a problem
if (rc == FAILURE)
goto exit; // there was a problem
break;
}
case PUBCOMP:
break;
case PINGRESP:
c->ping_outstanding = 0;
break;
}
if (keepalive(c) != SUCCESS) {
//check only keepalive FAILURE status so that previous FAILURE status can be considered as FAULT
rc = FAILURE;
}
exit:
if (rc == SUCCESS)
rc = packet_type;
return rc;
}
int MQTTYield(MQTTClient* c, int timeout_ms)
{
int rc = SUCCESS;
Timer timer;
TimerInit(&timer);
TimerCountdownMS(&timer, timeout_ms);
do
{
if (cycle(c, &timer) == FAILURE)
{
rc = FAILURE;
break;
}
} while (!TimerIsExpired(&timer));
return rc;
}
int waitfor(MQTTClient* c, int packet_type, Timer* timer)
{
int rc = FAILURE;
do
{
if (TimerIsExpired(timer))
break; // we timed out
}
while ((rc = cycle(c, timer)) != packet_type);
return rc;
}
int MQTTConnect(MQTTClient* c, MQTTPacket_connectData* options)
{
Timer connect_timer;
int rc = FAILURE;
MQTTPacket_connectData default_options = MQTTPacket_connectData_initializer;
int len = 0;
if (c->isconnected) /* don't send connect packet again if we are already connected */
goto exit;
TimerInit(&connect_timer);
TimerCountdownMS(&connect_timer, c->command_timeout_ms);
if (options == 0)
options = &default_options; /* set default options if none were supplied */
c->keepAliveInterval = options->keepAliveInterval;
TimerCountdown(&c->ping_timer, c->keepAliveInterval);
if ((len = MQTTSerialize_connect(c->buf, c->buf_size, options)) <= 0)
goto exit;
if ((rc = sendPacket(c, len, &connect_timer)) != SUCCESS) // send the connect packet
goto exit; // there was a problem
#if defined(WAIT_FOR_ACK)
// this will be a blocking call, wait for the connack
if (waitfor(c, CONNACK, &connect_timer) == CONNACK)
{
unsigned char connack_rc = 255;
unsigned char sessionPresent = 0;
if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, c->readbuf, c->readbuf_size) == 1)
rc = connack_rc;
else
rc = FAILURE;
}
else{
mqtt_printf(MQTT_DEBUG, "Not received CONNACK");
rc = FAILURE;
}
#endif
exit:
if (rc == SUCCESS)
{
c->isconnected = 1;
c->ping_outstanding = 0;
}
return rc;
}
int MQTTSubscribe(MQTTClient* c, const char* topicFilter, enum QoS qos, messageHandler messageHandler)
{
int rc = FAILURE;
Timer timer;
int len = 0;
MQTTString topic = MQTTString_initializer;
topic.cstring = (char *)topicFilter;
if (!c->isconnected)
goto exit;
TimerInit(&timer);
TimerCountdownMS(&timer, c->command_timeout_ms);
len = MQTTSerialize_subscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic, (int*)&qos);
if (len <= 0)
goto exit;
if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the subscribe packet
goto exit; // there was a problem
#if defined(WAIT_FOR_ACK)
if (waitfor(c, SUBACK, &timer) == SUBACK) // wait for suback
{
int count = 0, grantedQoS = -1;
unsigned short mypacketid;
if (MQTTDeserialize_suback(&mypacketid, 1, &count, &grantedQoS, c->readbuf, c->readbuf_size) == 1)
rc = grantedQoS; // 0, 1, 2 or 0x80
if (rc != 0x80)
{
int i;
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
{
if (c->messageHandlers[i].topicFilter == topicFilter)
{
rc = 0;
goto exit; //already subscribed
}
}
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
{
if (c->messageHandlers[i].topicFilter == 0)
{
c->messageHandlers[i].topicFilter = topicFilter;
c->messageHandlers[i].fp = messageHandler;
rc = 0;
break;
}
}
}
}
else
rc = FAILURE;
#endif
exit:
if (rc == FAILURE)
MQTTCloseSession(c);
return rc;
}
int MQTTUnsubscribe(MQTTClient* c, const char* topicFilter)
{
int rc = FAILURE;
Timer timer;
MQTTString topic = MQTTString_initializer;
topic.cstring = (char *)topicFilter;
int len = 0;
if (!c->isconnected)
goto exit;
TimerInit(&timer);
TimerCountdownMS(&timer, c->command_timeout_ms);
if ((len = MQTTSerialize_unsubscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic)) <= 0)
goto exit;
if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the subscribe packet
goto exit; // there was a problem
#if defined(WAIT_FOR_ACK)
if (waitfor(c, UNSUBACK, &timer) == UNSUBACK)
{
unsigned short mypacketid; // should be the same as the packetid above
if (MQTTDeserialize_unsuback(&mypacketid, c->readbuf, c->readbuf_size) == 1)
rc = 0;
int i;
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
{
if (c->messageHandlers[i].topicFilter == topicFilter)
{
c->messageHandlers[i].topicFilter = 0;
c->messageHandlers[i].fp = NULL;
}
}
}
else
rc = FAILURE;
#endif
exit:
if (rc == FAILURE)
MQTTCloseSession(c);
return rc;
}
int MQTTPublish(MQTTClient* c, const char* topicName, MQTTMessage* message)
{
int rc = FAILURE;
Timer timer;
MQTTString topic = MQTTString_initializer;
topic.cstring = (char *)topicName;
int len = 0;
if (!c->isconnected)
goto exit;
TimerInit(&timer);
TimerCountdownMS(&timer, c->command_timeout_ms);
if (message->qos == QOS1 || message->qos == QOS2)
message->id = getNextPacketId(c);
len = MQTTSerialize_publish(c->buf, c->buf_size, 0, message->qos, message->retained, message->id,
topic, (unsigned char*)message->payload, message->payloadlen);
if (len <= 0)
goto exit;
if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the subscribe packet
goto exit; // there was a problem
#if defined(WAIT_FOR_ACK)
if (message->qos == QOS1)
{
if (waitfor(c, PUBACK, &timer) == PUBACK)
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
rc = FAILURE;
}
else{
rc = FAILURE;
mqtt_printf(MQTT_DEBUG, "Not received PUBACK");
}
}
else if (message->qos == QOS2)
{
if (waitfor(c, PUBCOMP, &timer) == PUBCOMP)
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
rc = FAILURE;
}
else{
rc = FAILURE;
mqtt_printf(MQTT_DEBUG, "Not received PUBCOMP");
}
}
#endif
exit:
if (rc == FAILURE)
MQTTCloseSession(c);
return rc;
}
int MQTTDisconnect(MQTTClient* c)
{
int rc = FAILURE;
Timer timer; // we might wait for incomplete incoming publishes to complete
int len = 0;
TimerInit(&timer);
TimerCountdownMS(&timer, c->command_timeout_ms);
len = MQTTSerialize_disconnect(c->buf, c->buf_size);
if (len > 0)
rc = sendPacket(c, len, &timer); // send the disconnect packet
MQTTCloseSession(c);
return rc;
}
#if defined(MQTT_TASK)
void MQTTSetStatus(MQTTClient* c, int mqttstatus)
{
c->mqttstatus = mqttstatus;
mqtt_printf(MQTT_INFO, "Set mqtt status to %s", mqtt_status_str[mqttstatus]);
}
int MQTTDataHandle(MQTTClient* c, fd_set *readfd, MQTTPacket_connectData *connectData, messageHandler messageHandler, char* address, int port, char* topic)
{
short packet_type = 0;
int rc = 0;
int mqttstatus = c->mqttstatus;
int mqtt_rxevent = 0;
int mqtt_fd = c->ipstack->my_socket;
mqtt_rxevent = (mqtt_fd >= 0) ? FD_ISSET( mqtt_fd, readfd) : 0;
if(mqttstatus == MQTT_START) {
mqtt_printf(MQTT_INFO, "MQTT start");
if(c->isconnected){
c->isconnected = 0;
}
mqtt_printf(MQTT_INFO, "Connect Network \"%s\"", address);
if((rc = NetworkConnect(c->ipstack, address, port)) != 0){
mqtt_printf(MQTT_INFO, "Return code from network connect is %d\n", rc);
goto exit;
}
mqtt_printf(MQTT_INFO, "\"%s\" Connected", address);
mqtt_printf(MQTT_INFO, "Start MQTT connection");
TimerInit(&c->cmd_timer);
TimerCountdownMS(&c->cmd_timer, c->command_timeout_ms);
if ((rc = MQTTConnect(c, connectData)) != 0){
mqtt_printf(MQTT_INFO, "Return code from MQTT connect is %d\n", rc);
goto exit;
}
MQTTSetStatus(c, MQTT_CONNECT);
goto exit;
}
if(mqtt_rxevent){
c->ipstack->m2m_rxevent = 0;
Timer timer;
TimerInit(&timer);
TimerCountdownMS(&timer, 1000);
packet_type = readPacket(c, &timer);
if(packet_type > 0 && packet_type < 15)
mqtt_printf(MQTT_DEBUG, "Read packet type is %s", msg_types_str[packet_type]);
else{
mqtt_printf(MQTT_DEBUG, "Read packet type is %d", packet_type);
MQTTSetStatus(c, MQTT_START);
c->ipstack->disconnect(c->ipstack);
rc = FAILURE;
goto exit;
}
}
switch(mqttstatus){
case MQTT_CONNECT:
if (packet_type == CONNACK)
{
unsigned char connack_rc = 255;
unsigned char sessionPresent = 0;
if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, c->readbuf, c->readbuf_size) == 1){
rc = connack_rc;
mqtt_printf(MQTT_INFO, "MQTT Connected");
TimerInit(&c->cmd_timer);
TimerCountdownMS(&c->cmd_timer, c->command_timeout_ms);
if ((rc = MQTTSubscribe(c, topic, QOS2, messageHandler)) != 0){
mqtt_printf(MQTT_INFO, "Return code from MQTT subscribe is %d\n", rc);
}else{
mqtt_printf(MQTT_INFO, "Subscribe to Topic: %s", topic);
MQTTSetStatus(c, MQTT_SUBTOPIC);
}
}else{
mqtt_printf(MQTT_DEBUG, "Deserialize CONNACK failed");
rc = FAILURE;
}
}else if(TimerIsExpired(&c->cmd_timer)){
mqtt_printf(MQTT_DEBUG, "Not received CONNACK");
rc = FAILURE;
}
if(rc == FAILURE){
MQTTSetStatus(c, MQTT_START);
}
break;
case MQTT_SUBTOPIC:
if(packet_type == SUBACK){
int count = 0, grantedQoS = -1;
unsigned short mypacketid;
int isSubscribed = 0;
if (MQTTDeserialize_suback(&mypacketid, 1, &count, &grantedQoS, c->readbuf, c->readbuf_size) == 1){
rc = grantedQoS; // 0, 1, 2 or 0x80
mqtt_printf(MQTT_DEBUG, "grantedQoS: %d", grantedQoS);
}
if (rc != 0x80)
{
int i;
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
{
if (c->messageHandlers[i].topicFilter == topic)
{
isSubscribed = 1;
break;
}
}
if(!isSubscribed)
for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
{
if (c->messageHandlers[i].topicFilter == 0)
{
c->messageHandlers[i].topicFilter = topic;
c->messageHandlers[i].fp = messageHandler;
break;
}
}
rc = 0;
MQTTSetStatus(c, MQTT_RUNNING);
}
}else if(TimerIsExpired(&c->cmd_timer)){
mqtt_printf(MQTT_DEBUG, "Not received SUBACK");
rc = FAILURE;
}
if(rc == FAILURE){
MQTTSetStatus(c, MQTT_START);
}
break;
case MQTT_RUNNING:
if(packet_type>0){
int len = 0;
Timer timer;
TimerInit(&timer);
TimerCountdownMS(&timer, 10000);
switch(packet_type){
case CONNACK:
break;
case PUBACK:
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
rc = FAILURE;
break;
}
case SUBACK:
break;
case UNSUBACK:
break;
case PUBLISH:
{
MQTTString topicName;
MQTTMessage msg;
int intQoS;
if (MQTTDeserialize_publish(&msg.dup, &intQoS, &msg.retained, &msg.id, &topicName,
(unsigned char**)&msg.payload, (int*)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1)
{
rc = FAILURE;
mqtt_printf(MQTT_DEBUG, "Deserialize PUBLISH failed");
goto exit;
}
msg.qos = (enum QoS)intQoS;
deliverMessage(c, &topicName, &msg);
if (msg.qos != QOS0)
{
if (msg.qos == QOS1){
len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id);
mqtt_printf(MQTT_DEBUG, "send PUBACK");
}else if (msg.qos == QOS2){
len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id);
mqtt_printf(MQTT_DEBUG, "send PUBREC");
}else{
mqtt_printf(MQTT_DEBUG, "invalid QoS: %d", msg.qos);
}
if (len <= 0){
rc = FAILURE;
mqtt_printf(MQTT_DEBUG, "Serialize_ack failed");
goto exit;
}else{
if((rc = sendPacket(c, len, &timer)) == FAILURE){
MQTTSetStatus(c, MQTT_START);
goto exit; // there was a problem
}
}
}
break;
}
case PUBREC:
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1){
mqtt_printf(MQTT_DEBUG, "Deserialize PUBREC failed");
rc = FAILURE;
}else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREL, 0, mypacketid)) <= 0){
mqtt_printf(MQTT_DEBUG, "Serialize PUBREL failed");
rc = FAILURE;
}else if ((rc = sendPacket(c, len, &timer)) != SUCCESS){ // send the PUBREL packet
rc = FAILURE; // there was a problem
MQTTSetStatus(c, MQTT_START);
}
break;
}
case PUBREL:
{
unsigned short mypacketid;
unsigned char dup, type;
if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1){
mqtt_printf(MQTT_DEBUG, "Deserialize PUBREL failed");
rc = FAILURE;
}else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBCOMP, 0, mypacketid)) <= 0){
mqtt_printf(MQTT_DEBUG, "Serialize PUBCOMP failed");
rc = FAILURE;
}else if ((rc = sendPacket(c, len, &timer)) != SUCCESS){ // send the PUBCOMP packet
rc = FAILURE; // there was a problem
MQTTSetStatus(c, MQTT_START);
}
break;
}
case PUBCOMP:
break;
case PINGRESP:
c->ping_outstanding = 0;
break;
}
}
if (keepalive(c) != SUCCESS) {
//check only keepalive FAILURE status so that previous FAILURE status can be considered as FAULT
rc = FAILURE;
}
break;
default:
break;
}
exit:
return rc;
}
#endif

View File

@@ -0,0 +1,225 @@
/**
******************************************************************************
* @file MQTTClient.h
* @author
* @version
* @brief This file provides user interface for MQTT client.
******************************************************************************
* @attention
*
* This module is a confidential and proprietary property of RealTek and possession or use of this module requires written permission of RealTek.
*
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
******************************************************************************
*/
#if !defined(__MQTT_CLIENT_C_)
#define __MQTT_CLIENT_C_
/** @addtogroup mqtt MQTT
* @ingroup network
* @brief MQTT client functions
* @{
*/
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(WIN32_DLL) || defined(WIN64_DLL)
#define DLLImport __declspec(dllimport)
#define DLLExport __declspec(dllexport)
#elif defined(LINUX_SO)
#define DLLImport extern
#define DLLExport __attribute__ ((visibility ("default")))
#else
#define DLLImport
#define DLLExport
#endif
#include "../MQTTPacket/MQTTPacket.h"
#include "stdio.h"
#include "MQTTFreertos.h"
#define MQTT_TASK
#if !defined(MQTT_TASK)
#define WAIT_FOR_ACK
#endif
#define MQTT_SENDBUF_LEN 1024
#define MQTT_READBUF_LEN 1024
enum mqtt_status{
MQTT_START = 0,
MQTT_CONNECT = 1,
MQTT_SUBTOPIC = 2,
MQTT_RUNNING = 3
};
#if defined(MQTTCLIENT_PLATFORM_HEADER)
/* The following sequence of macros converts the MQTTCLIENT_PLATFORM_HEADER value
* into a string constant suitable for use with include.
*/
#define xstr(s) str(s)
#define str(s) #s
#include xstr(MQTTCLIENT_PLATFORM_HEADER)
#endif
#define MAX_PACKET_ID 65535 /* according to the MQTT specification - do not change! */
#if !defined(MAX_MESSAGE_HANDLERS)
#define MAX_MESSAGE_HANDLERS 5 /* redefinable - how many subscriptions do you want? */
#endif
enum QoS { QOS0, QOS1, QOS2 };
/* all failure return codes must be negative */
enum returnCode { BUFFER_OVERFLOW = -2, FAILURE = -1 };//, SUCCESS = 0
/* The Platform specific header must define the Network and Timer structures and functions
* which operate on them.
*
typedef struct Network
{
int (*mqttread)(Network*, unsigned char* read_buffer, int, int);
int (*mqttwrite)(Network*, unsigned char* send_buffer, int, int);
} Network;*/
/* The Timer structure must be defined in the platform specific header,
* and have the following functions to operate on it. */
extern void TimerInit(Timer*);
extern char TimerIsExpired(Timer*);
extern void TimerCountdownMS(Timer*, unsigned int);
extern void TimerCountdown(Timer*, unsigned int);
extern int TimerLeftMS(Timer*);
typedef struct MQTTMessage
{
enum QoS qos;
unsigned char retained;
unsigned char dup;
unsigned short id;
void *payload;
size_t payloadlen;
} MQTTMessage;
typedef struct MessageData
{
MQTTMessage* message;
MQTTString* topicName;
} MessageData;
typedef void (*messageHandler)(MessageData*);
typedef struct MQTTClient
{
unsigned int next_packetid,
command_timeout_ms;
size_t buf_size,
readbuf_size;
unsigned char *buf,
*readbuf;
unsigned int keepAliveInterval;
char ping_outstanding;
int isconnected;
struct MessageHandlers
{
const char* topicFilter;
void (*fp) (MessageData*);
} messageHandlers[MAX_MESSAGE_HANDLERS]; /* Message handlers are indexed by subscription topic */
void (*defaultMessageHandler) (MessageData*);
Network* ipstack;
Timer ping_timer;
Timer cmd_timer;
int mqttstatus;
} MQTTClient;
#define DefaultClient {0, 0, 0, 0, NULL, NULL, 0, 0, 0}
/**
* @brief Create an MQTT client object
* @param client : The context of MQTT client
* @param network : The Network context
* @param command_timeout_ms : The command timeout of MQTT
* @param sendbuf : The array of MQTT send buffer
* @param sendbuf_size : The size of send buffer
* @param readbuf : The array of MQTT receive buffer
* @param readbuf_size : The size of receive buffer
* @return none
*/
DLLExport void MQTTClientInit(MQTTClient* client, Network* network, unsigned int command_timeout_ms,
unsigned char* sendbuf, size_t sendbuf_size, unsigned char* readbuf, size_t readbuf_size);
/**
* @brief Send an MQTT connect packet down the network and wait for a Connack
* The nework object must be connected to the network endpoint before calling this function
* @param client c
* @param options : The connect options of MQTT
* @return 0 : success
* -1 : failed
*/
DLLExport int MQTTConnect(MQTTClient* client, MQTTPacket_connectData* options);
/**
* @brief Send an MQTT publish packet and wait for all acks to complete for all QoSs
* @param client : The context of MQTT client
* @param topic : The MQTT topic to publish
* @param message : The message to send
* @return 0 : success
* -1 : failed
*/
DLLExport int MQTTPublish(MQTTClient* client, const char*, MQTTMessage*);
/**
* @brief Send an MQTT subscribe packet and wait for suback before returning.
* @param client : The context of MQTT client
* @param topicFilter : The topic filter to subscribe
* @param QoS : The MQTT QOS value
* @param messageHandler : The MQTT message handler
* @return 0 : success
* -1 : failed
*/
DLLExport int MQTTSubscribe(MQTTClient* client, const char* topicFilter, enum QoS, messageHandler);
/**
* @brief Send an MQTT unsubscribe packet and wait for unsuback before returning.
* @param client : The context of MQTT client
* @param topicFilter : The topic filter to unsubscribe
* @return 0 : success
* -1 : failed
*/
DLLExport int MQTTUnsubscribe(MQTTClient* client, const char* topicFilter);
/**
* @brief Send an MQTT disconnect packet and close the connection
* @param client : The context of MQTT client
* @return 0 : success
* -1 : failed
*/
DLLExport int MQTTDisconnect(MQTTClient* client);
/**
* @brief MQTT receive packet background function
* @param client : The context of MQTT client
* @param time : The timeout of receive MQTT packets, in milliseconds
* @return 0 : success
* -1 : failed
*/
DLLExport int MQTTYield(MQTTClient* client, int time);
#if defined(MQTT_TASK)
void MQTTSetStatus(MQTTClient* c, int mqttstatus);
int MQTTDataHandle(MQTTClient* c, fd_set *readfd, MQTTPacket_connectData *connectData, messageHandler messageHandler, char* address, int port, char* topic);
#endif
#if defined(__cplusplus)
}
#endif
/*\@}*/
#endif

View File

@@ -0,0 +1,906 @@
/*******************************************************************************
* Copyright (c) 2014, 2015 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Allan Stockdill-Mander - initial API and implementation and/or initial documentation
* Ian Craggs - convert to FreeRTOS
*******************************************************************************/
#include "MQTTFreertos.h"
#include "netdb.h"
#ifdef LWIP_IPV6
#undef LWIP_IPV6
#endif
#ifdef inet_ntop
#undef inet_ntop
#endif
#ifdef inet_pton
#undef inet_pton
#endif
#define LWIP_IPV6 0
#if LWIP_IPV6
#define inet_ntop(af,src,dst,size) \
(((af) == AF_INET6) ? ip6addr_ntoa_r((src),(dst),(size)) \
: (((af) == AF_INET) ? ipaddr_ntoa_r((src),(dst),(size)) : NULL))
#define inet_pton(af,src,dst) \
(((af) == AF_INET6) ? inet6_aton((src),(dst)) \
: (((af) == AF_INET) ? inet_aton((src),(dst)) : 0))
#else /* LWIP_IPV6 */
#define inet_ntop(af,src,dst,size) \
(((af) == AF_INET) ? ipaddr_ntoa_r((src),(dst),(size)) : NULL)
#define inet_pton(af,src,dst) \
(((af) == AF_INET) ? inet_aton((src),(dst)) : 0)
#endif /* LWIP_IPV6 */
int ThreadStart(Thread* thread, void (*fn)(void*), void* arg)
{
int rc = 0;
uint16_t usTaskStackSize = (configMINIMAL_STACK_SIZE * 5);
UBaseType_t uxTaskPriority = uxTaskPriorityGet(NULL); /* set the priority as the same as the calling task*/
rc = xTaskCreate(fn, /* The function that implements the task. */
"MQTTTask", /* Just a text name for the task to aid debugging. */
usTaskStackSize, /* The stack size is defined in FreeRTOSIPConfig.h. */
arg, /* The task parameter, not used in this case. */
uxTaskPriority, /* The priority assigned to the task is defined in FreeRTOSConfig.h. */
&thread->task); /* The task handle is not used. */
return rc;
}
void MutexInit(Mutex* mutex)
{
mutex->sem = xSemaphoreCreateMutex();
}
int MutexLock(Mutex* mutex)
{
return xSemaphoreTake(mutex->sem, portMAX_DELAY);
}
int MutexUnlock(Mutex* mutex)
{
return xSemaphoreGive(mutex->sem);
}
void TimerCountdownMS(Timer* timer, unsigned int timeout_ms)
{
timer->xTicksToWait = timeout_ms / portTICK_PERIOD_MS; /* convert milliseconds to ticks */
vTaskSetTimeOutState(&timer->xTimeOut); /* Record the time at which this function was entered. */
}
void TimerCountdown(Timer* timer, unsigned int timeout)
{
TimerCountdownMS(timer, timeout * 1000);
}
int TimerLeftMS(Timer* timer)
{
xTaskCheckForTimeOut(&timer->xTimeOut, &timer->xTicksToWait); /* updates xTicksToWait to the number left */
return (timer->xTicksToWait * portTICK_PERIOD_MS);
}
char TimerIsExpired(Timer* timer)
{
return xTaskCheckForTimeOut(&timer->xTimeOut, &timer->xTicksToWait) == pdTRUE;
}
void TimerInit(Timer* timer)
{
timer->xTicksToWait = 0;
memset(&timer->xTimeOut, '\0', sizeof(timer->xTimeOut));
}
#if CONFIG_USE_POLARSSL
int FreeRTOS_read(Network* n, unsigned char* buffer, int len, int timeout_ms)
{
TickType_t xTicksToWait = timeout_ms / portTICK_PERIOD_MS; /* convert milliseconds to ticks */
TimeOut_t xTimeOut;
int recvLen = 0;
int so_error = 0;
socklen_t errlen = sizeof(so_error);
vTaskSetTimeOutState(&xTimeOut); /* Record the time at which this function was entered. */
do
{
int rc = 0;
#if defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD) && (LWIP_SO_SNDRCVTIMEO_NONSTANDARD == 0)
// timeout format is changed in lwip 1.5.0
struct timeval timeout;
timeout.tv_sec = xTicksToWait / 1000;
timeout.tv_usec = ( xTicksToWait % 1000 ) * 1000;
setsockopt(n->my_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval));
#else
setsockopt(n->my_socket, SOL_SOCKET, SO_RCVTIMEO, &xTicksToWait, sizeof(xTicksToWait));
#endif
#if (MQTT_OVER_SSL)
if (n->use_ssl)
rc = ssl_read(n->ssl, buffer + recvLen, len - recvLen);
else
#endif
rc = recv(n->my_socket, buffer + recvLen, len - recvLen, 0);
if (rc > 0)
recvLen += rc;
else if (rc < 0)
{
getsockopt(n->my_socket, SOL_SOCKET, SO_ERROR, &so_error, &errlen);
if (so_error && (so_error != EAGAIN)) {
n->disconnect(n);
}
recvLen = rc;
break;
}
} while (recvLen < len && xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE);
return recvLen;
}
int FreeRTOS_write(Network* n, unsigned char* buffer, int len, int timeout_ms)
{
TickType_t xTicksToWait = timeout_ms / portTICK_PERIOD_MS; /* convert milliseconds to ticks */
TimeOut_t xTimeOut;
int sentLen = 0;
int so_error = 0;
socklen_t errlen = sizeof(so_error);
vTaskSetTimeOutState(&xTimeOut); /* Record the time at which this function was entered. */
do
{
int rc = 0;
#if defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD) && (LWIP_SO_SNDRCVTIMEO_NONSTANDARD == 0)
// timeout format is changed in lwip 1.5.0
struct timeval timeout;
timeout.tv_sec = xTicksToWait / 1000;
timeout.tv_usec = ( xTicksToWait % 1000 ) * 1000;
setsockopt(n->my_socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval));
#else
setsockopt(n->my_socket, SOL_SOCKET, SO_SNDTIMEO, &xTicksToWait, sizeof(xTicksToWait));
#endif
#if (MQTT_OVER_SSL)
if (n->use_ssl)
rc = ssl_write(n->ssl, buffer + sentLen, len - sentLen);
else
#endif
rc = send(n->my_socket, buffer + sentLen, len - sentLen, 0);
if (rc > 0)
sentLen += rc;
else if (rc < 0)
{
getsockopt(n->my_socket, SOL_SOCKET, SO_ERROR, &so_error, &errlen);
if (so_error && (so_error != EAGAIN)) {
n->disconnect(n);
}
sentLen = rc;
break;
}
} while (sentLen < len && xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE);
return sentLen;
}
void FreeRTOS_disconnect(Network* n)
{
if (n->my_socket >= 0) {
shutdown(n->my_socket, SHUT_RDWR);
close(n->my_socket);
n->my_socket = -1;
#if (MQTT_OVER_SSL)
if (n->use_ssl) {
ssl_free(n->ssl);
free(n->ssl);
n->ssl = NULL;
}
#endif
}
}
void NetworkInit(Network* n)
{
n->my_socket = -1;
n->mqttread = FreeRTOS_read;
n->mqttwrite = FreeRTOS_write;
n->disconnect = FreeRTOS_disconnect;
#if (MQTT_OVER_SSL)
n->use_ssl = 0;
n->ssl = NULL;
n->rootCA = NULL;
n->clientCA = NULL;
n->private_key = NULL;
#endif
}
#if (MQTT_OVER_SSL)
static int mqtt_tls_verify( void *data, x509_crt *crt, int depth, int *flags )
{
char buf[1024];
mqtt_printf(MQTT_DEBUG, "\nVerify requested for (Depth %d):\n", depth );
x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
mqtt_printf(MQTT_DEBUG, "%s", buf );
if( ( (*flags) & BADCERT_EXPIRED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! server certificate has expired\n" );
if( ( (*flags) & BADCERT_REVOKED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! server certificate has been revoked\n" );
if( ( (*flags) & BADCERT_CN_MISMATCH ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! CN mismatch\n" );
if( ( (*flags) & BADCERT_NOT_TRUSTED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! self-signed or not signed by a trusted CA\n" );
if( ( (*flags) & BADCRL_NOT_TRUSTED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! CRL not trusted\n" );
if( ( (*flags) & BADCRL_EXPIRED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! CRL expired\n" );
if( ( (*flags) & BADCERT_OTHER ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! other (unknown) flag\n" );
if ( ( *flags ) == 0 )
mqtt_printf(MQTT_DEBUG, " This certificate has no flags\n" );
return( 0 );
}
static int my_random(void *p_rng, unsigned char *output, size_t output_len)
{
rtw_get_random_bytes(output, output_len);
return 0;
}
#endif // #if (MQTT_OVER_SSL)
int NetworkConnect(Network* n, char* addr, int port)
{
struct sockaddr_in sAddr;
int retVal = -1;
struct hostent *hptr;
char **pptr;
char str[32];
int keepalive_enable = 1;
int keep_idle = 30;
if(n->my_socket >= 0){
n->disconnect(n);
}
if ((hptr = gethostbyname(addr)) == 0)
{
mqtt_printf(MQTT_DEBUG, "gethostbyname failed!");
goto exit;
}
pptr = hptr->h_addr_list;
for(; *pptr!=NULL; pptr++)
{
inet_ntop(hptr->h_addrtype, (const ip_addr_t *)*pptr, str, sizeof(str));
}
inet_ntop(hptr->h_addrtype, (const ip_addr_t *)hptr->h_addr, str, sizeof(str));
sAddr.sin_family = AF_INET;
sAddr.sin_port = htons(port);
sAddr.sin_addr.s_addr = inet_addr(str);
mqtt_printf(MQTT_DEBUG, "addr = %s", str);
if ((n->my_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
goto exit;
}
setsockopt( n->my_socket, SOL_SOCKET, SO_KEEPALIVE,
(const char *) &keepalive_enable, sizeof( keepalive_enable ) );
setsockopt( n->my_socket, IPPROTO_TCP, TCP_KEEPIDLE,
(const char *) &keep_idle, sizeof( keep_idle ) );
if ((retVal = connect(n->my_socket, (struct sockaddr*)&sAddr, sizeof(sAddr))) < 0)
{
close(n->my_socket);
n->my_socket = -1;
mqtt_printf(MQTT_DEBUG, "Connect failed!!");
goto exit;
}
#if (MQTT_OVER_SSL)
x509_crt *root_crt;
x509_crt *client_crt;
pk_context *client_rsa;
root_crt = NULL;
client_crt = NULL;
client_rsa = NULL;
if ( n->use_ssl != 0 ) {
memory_set_own(pvPortMalloc, vPortFree);
n->ssl = (ssl_context *) malloc( sizeof(ssl_context) );
if ( n->ssl == NULL ) {
mqtt_printf(MQTT_DEBUG, "malloc ssl failed!");
goto err;
}
memset(n->ssl, 0, sizeof(ssl_context));
if ( ssl_init(n->ssl) != 0 ) {
mqtt_printf(MQTT_DEBUG, "init ssl failed!");
goto err;
}
ssl_set_endpoint(n->ssl, SSL_IS_CLIENT);
if (n->rootCA != NULL) {
root_crt = (x509_crt *) polarssl_malloc( sizeof(x509_crt) );
if ( root_crt == NULL ) {
mqtt_printf(MQTT_DEBUG, "malloc root_crt failed!");
goto err;
}
memset(root_crt, 0, sizeof(x509_crt));
ssl_set_authmode( n->ssl, SSL_VERIFY_REQUIRED );
if (x509_crt_parse( root_crt, n->rootCA, strlen(n->rootCA) ) != 0) {
mqtt_printf(MQTT_DEBUG, "parse root_crt failed!");
goto err;
}
ssl_set_ca_chain( n->ssl, root_crt, NULL, NULL );
ssl_set_verify( n->ssl, mqtt_tls_verify, NULL );
mqtt_printf(MQTT_DEBUG, "root_crt parse done");
} else {
ssl_set_authmode(n->ssl, SSL_VERIFY_NONE);
}
if (n->clientCA != NULL && n->private_key != NULL) {
client_crt = (x509_crt *) polarssl_malloc( sizeof(x509_crt) );
if ( client_crt == NULL ) {
mqtt_printf(MQTT_DEBUG, "malloc client_crt failed!");
goto err;
}
memset(client_crt, 0, sizeof(x509_crt));
x509_crt_init(client_crt);
client_rsa = (pk_context *) polarssl_malloc( sizeof(pk_context) );
if ( client_rsa == NULL ) {
mqtt_printf(MQTT_DEBUG, "malloc client_rsa failed!");
goto err;
}
memset(client_rsa, 0, sizeof(pk_context));
pk_init(client_rsa);
if ( x509_crt_parse(client_crt, n->clientCA, strlen(n->clientCA)) != 0 ) {
mqtt_printf(MQTT_DEBUG, "parse client_crt failed!");
goto err;
}
if ( pk_parse_key(client_rsa, n->private_key, strlen(n->private_key), NULL, 0) != 0 ) {
mqtt_printf(MQTT_DEBUG, "parse client_rsa failed!");
goto err;
}
ssl_set_own_cert(n->ssl, client_crt, client_rsa);
mqtt_printf(MQTT_DEBUG, "client_crt parse done");
}
ssl_set_rng(n->ssl, my_random, NULL);
ssl_set_bio(n->ssl, net_recv, &n->my_socket, net_send, &n->my_socket);
retVal = ssl_handshake(n->ssl);
if (retVal < 0) {
mqtt_printf(MQTT_DEBUG, "ssl handshake failed err:-0x%04X", -retVal);
goto err;
} else {
mqtt_printf(MQTT_DEBUG, "ssl handshake success");
}
}
if (client_rsa) {
pk_free(client_rsa);
polarssl_free(client_rsa);
}
if (client_crt) {
x509_crt_free(client_crt);
polarssl_free(client_crt);
}
if (root_crt) {
x509_crt_free(root_crt);
polarssl_free(root_crt);
}
goto exit;
err:
if (client_rsa) {
pk_free(client_rsa);
polarssl_free(client_rsa);
}
if (client_crt) {
x509_crt_free(client_crt);
polarssl_free(client_crt);
}
if (root_crt) {
x509_crt_free(root_crt);
polarssl_free(root_crt);
}
net_close(n->my_socket);
ssl_free(n->ssl);
free(n->ssl);
retVal = -1;
#endif // #if (MQTT_OVER_SSL)
exit:
return retVal;
}
#elif CONFIG_USE_MBEDTLS /* CONFIG_USE_POLARSSL */
int FreeRTOS_read(Network* n, unsigned char* buffer, int len, int timeout_ms)
{
TickType_t xTicksToWait = timeout_ms / portTICK_PERIOD_MS; /* convert milliseconds to ticks */
TimeOut_t xTimeOut;
int recvLen = 0;
int so_error = 0;
socklen_t errlen = sizeof(so_error);
vTaskSetTimeOutState(&xTimeOut); /* Record the time at which this function was entered. */
do
{
int rc = 0;
#if defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD) && (LWIP_SO_SNDRCVTIMEO_NONSTANDARD == 0)
// timeout format is changed in lwip 1.5.0
struct timeval timeout;
timeout.tv_sec = xTicksToWait / 1000;
timeout.tv_usec = ( xTicksToWait % 1000 ) * 1000;
setsockopt(n->my_socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval));
#else
setsockopt(n->my_socket, SOL_SOCKET, SO_RCVTIMEO, &xTicksToWait, sizeof(xTicksToWait));
#endif
#if (MQTT_OVER_SSL)
if (n->use_ssl)
rc = mbedtls_ssl_read(n->ssl, buffer + recvLen, len - recvLen);
else
#endif
rc = recv(n->my_socket, buffer + recvLen, len - recvLen, 0);
if (rc > 0)
recvLen += rc;
else if (rc < 0)
{
getsockopt(n->my_socket, SOL_SOCKET, SO_ERROR, &so_error, &errlen);
if (so_error && (so_error != EAGAIN)) {
n->disconnect(n);
}
recvLen = rc;
break;
}
} while (recvLen < len && xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE);
return recvLen;
}
int FreeRTOS_write(Network* n, unsigned char* buffer, int len, int timeout_ms)
{
TickType_t xTicksToWait = timeout_ms / portTICK_PERIOD_MS; /* convert milliseconds to ticks */
TimeOut_t xTimeOut;
int sentLen = 0;
int so_error = 0;
socklen_t errlen = sizeof(so_error);
vTaskSetTimeOutState(&xTimeOut); /* Record the time at which this function was entered. */
do
{
int rc = 0;
#if defined(LWIP_SO_SNDRCVTIMEO_NONSTANDARD) && (LWIP_SO_SNDRCVTIMEO_NONSTANDARD == 0)
// timeout format is changed in lwip 1.5.0
struct timeval timeout;
timeout.tv_sec = xTicksToWait / 1000;
timeout.tv_usec = ( xTicksToWait % 1000 ) * 1000;
setsockopt(n->my_socket, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval));
#else
setsockopt(n->my_socket, SOL_SOCKET, SO_SNDTIMEO, &xTicksToWait, sizeof(xTicksToWait));
#endif
#if (MQTT_OVER_SSL)
if (n->use_ssl)
rc = mbedtls_ssl_write(n->ssl, buffer + sentLen, len - sentLen);
else
#endif
rc = send(n->my_socket, buffer + sentLen, len - sentLen, 0);
if (rc > 0)
sentLen += rc;
else if (rc < 0)
{
getsockopt(n->my_socket, SOL_SOCKET, SO_ERROR, &so_error, &errlen);
if (so_error && (so_error != EAGAIN)) {
n->disconnect(n);
}
sentLen = rc;
break;
}
} while (sentLen < len && xTaskCheckForTimeOut(&xTimeOut, &xTicksToWait) == pdFALSE);
return sentLen;
}
void FreeRTOS_disconnect(Network* n)
{
if (n->my_socket >= 0){
shutdown(n->my_socket, SHUT_RDWR);
close(n->my_socket);
n->my_socket = -1;
#if (MQTT_OVER_SSL)
if (n->use_ssl) {
mbedtls_ssl_free(n->ssl);
mbedtls_ssl_config_free(n->conf);
free(n->ssl);
free(n->conf);
n->ssl = NULL;
n->conf = NULL;
}
#endif
}
}
void NetworkInit(Network* n)
{
n->my_socket = -1;
n->mqttread = FreeRTOS_read;
n->mqttwrite = FreeRTOS_write;
n->disconnect = FreeRTOS_disconnect;
#if (MQTT_OVER_SSL)
n->use_ssl = 0;
n->ssl = NULL;
n->conf = NULL;
n->rootCA = NULL;
n->clientCA = NULL;
n->private_key = NULL;
#endif
}
#if (MQTT_OVER_SSL)
static int mqtt_tls_verify( void *data, mbedtls_x509_crt *crt, int depth, int *flags )
{
char buf[1024];
mqtt_printf(MQTT_DEBUG, "\nVerify requested for (Depth %d):\n", depth );
mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt );
mqtt_printf(MQTT_DEBUG, "%s", buf );
if( ( (*flags) & MBEDTLS_X509_BADCERT_EXPIRED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! server certificate has expired\n" );
if( ( (*flags) & MBEDTLS_X509_BADCERT_REVOKED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! server certificate has been revoked\n" );
if( ( (*flags) & MBEDTLS_X509_BADCERT_CN_MISMATCH ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! CN mismatch\n" );
if( ( (*flags) & MBEDTLS_X509_BADCERT_NOT_TRUSTED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! self-signed or not signed by a trusted CA\n" );
if( ( (*flags) & MBEDTLS_X509_BADCRL_NOT_TRUSTED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! CRL not trusted\n" );
if( ( (*flags) & MBEDTLS_X509_BADCRL_EXPIRED ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! CRL expired\n" );
if( ( (*flags) & MBEDTLS_X509_BADCERT_OTHER ) != 0 )
mqtt_printf(MQTT_DEBUG, " ! other (unknown) flag\n" );
if ( ( *flags ) == 0 )
mqtt_printf(MQTT_DEBUG, " This certificate has no flags\n" );
return( 0 );
}
static void* my_calloc(size_t nelements, size_t elementSize)
{
size_t size;
void *ptr = NULL;
size = nelements * elementSize;
ptr = pvPortMalloc(size);
if(ptr)
memset(ptr, 0, size);
return ptr;
}
static int my_random(void *p_rng, unsigned char *output, size_t output_len)
{
rtw_get_random_bytes(output, output_len);
return 0;
}
#endif // #if (MQTT_OVER_SSL)
int NetworkConnect(Network* n, char* addr, int port)
{
struct sockaddr_in sAddr;
int retVal = -1;
struct hostent *hptr;
char **pptr;
char str[32];
int keepalive_enable = 1;
int keep_idle = 30;
if(n->my_socket >= 0){
n->disconnect(n);
}
if ((hptr = gethostbyname(addr)) == 0)
{
mqtt_printf(MQTT_DEBUG, "gethostbyname failed!");
goto exit;
}
pptr = hptr->h_addr_list;
for(; *pptr!=NULL; pptr++)
{
inet_ntop(hptr->h_addrtype, (const ip_addr_t *)*pptr, str, sizeof(str));
}
inet_ntop(hptr->h_addrtype, (const ip_addr_t *)hptr->h_addr, str, sizeof(str));
sAddr.sin_family = AF_INET;
sAddr.sin_port = htons(port);
sAddr.sin_addr.s_addr = inet_addr(str);
mqtt_printf(MQTT_DEBUG, "addr = %s", str);
if ((n->my_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
goto exit;
}
setsockopt( n->my_socket, SOL_SOCKET, SO_KEEPALIVE,
(const char *) &keepalive_enable, sizeof( keepalive_enable ) );
setsockopt( n->my_socket, IPPROTO_TCP, TCP_KEEPIDLE,
(const char *) &keep_idle, sizeof( keep_idle ) );
if ((retVal = connect(n->my_socket, (struct sockaddr*)&sAddr, sizeof(sAddr))) < 0)
{
close(n->my_socket);
n->my_socket = -1;
mqtt_printf(MQTT_DEBUG, "Connect failed!!");
goto exit;
}
#if (MQTT_OVER_SSL)
mbedtls_x509_crt *root_crt;
mbedtls_x509_crt *client_crt;
mbedtls_pk_context *client_rsa;
root_crt = NULL;
client_crt = NULL;
client_rsa = NULL;
if ( n->use_ssl != 0 ) {
mbedtls_platform_set_calloc_free(my_calloc, vPortFree);
n->ssl = (mbedtls_ssl_context *) malloc( sizeof(mbedtls_ssl_context) );
n->conf = (mbedtls_ssl_config *) malloc( sizeof(mbedtls_ssl_config) );
if (( n->ssl == NULL )||( n->conf == NULL )) {
mqtt_printf(MQTT_DEBUG, "malloc ssl failed!");
goto err;
}
mbedtls_ssl_init(n->ssl);
mbedtls_ssl_config_init(n->conf);
if((mbedtls_ssl_config_defaults(n->conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
mqtt_printf(MQTT_DEBUG, "ssl config defaults failed!");
goto err;
}
mbedtls_ssl_set_bio(n->ssl, &n->my_socket, mbedtls_net_send, mbedtls_net_recv, NULL);
mbedtls_ssl_conf_rng(n->conf, my_random, NULL);
#if MBEDTLS_SSL_MAX_CONTENT_LEN == 512
if(mbedtls_ssl_conf_max_frag_len(n->conf, MBEDTLS_SSL_MAX_FRAG_LEN_512) < 0) {
printf("ssl conf max frag len failed!");
goto err;
}
#elif MBEDTLS_SSL_MAX_CONTENT_LEN == 1024
if(mbedtls_ssl_conf_max_frag_len(n->conf, MBEDTLS_SSL_MAX_FRAG_LEN_1024) < 0) {
printf("ssl conf max frag len failed!");
goto err;
}
#elif MBEDTLS_SSL_MAX_CONTENT_LEN == 2048
if(mbedtls_ssl_conf_max_frag_len(n->conf, MBEDTLS_SSL_MAX_FRAG_LEN_2048) < 0) {
printf("ssl conf max frag len failed!");
goto err;
}
#elif MBEDTLS_SSL_MAX_CONTENT_LEN == 4096
if(mbedtls_ssl_conf_max_frag_len(n->conf, MBEDTLS_SSL_MAX_FRAG_LEN_4096) < 0) {
printf("ssl conf max frag len failed!");
goto err;
}
#endif
if((mbedtls_ssl_setup(n->ssl, n->conf)) != 0) {
mqtt_printf(MQTT_DEBUG,"mbedtls_ssl_setup failed!");
goto err;
}
if (n->rootCA != NULL) {
root_crt = (mbedtls_x509_crt *) mbedtls_calloc( sizeof(mbedtls_x509_crt), 1);
if ( root_crt == NULL ) {
mqtt_printf(MQTT_DEBUG, "malloc root_crt failed!");
goto err;
}
mbedtls_x509_crt_init(root_crt);
if (mbedtls_x509_crt_parse( root_crt, (const unsigned char *)n->rootCA, strlen(n->rootCA)+1 ) != 0) {
mqtt_printf(MQTT_DEBUG, "parse root_crt failed!");
goto err;
}
mbedtls_ssl_conf_ca_chain( n->conf, root_crt, NULL);
mbedtls_ssl_conf_authmode(n->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_verify( n->conf, (int (*)(void *, mbedtls_x509_crt *, int, uint32_t *))mqtt_tls_verify, NULL );
mqtt_printf(MQTT_DEBUG, "root_crt parse done");
} else {
mbedtls_ssl_conf_authmode(n->conf, MBEDTLS_SSL_VERIFY_NONE);
}
if (n->clientCA != NULL && n->private_key != NULL) {
client_crt = (mbedtls_x509_crt *) mbedtls_calloc( sizeof(mbedtls_x509_crt), 1);
if ( client_crt == NULL ) {
mqtt_printf(MQTT_DEBUG, "malloc client_crt failed!");
goto err;
}
mbedtls_x509_crt_init(client_crt);
client_rsa = (mbedtls_pk_context *) mbedtls_calloc( sizeof(mbedtls_pk_context), 1);
if ( client_rsa == NULL ) {
mqtt_printf(MQTT_DEBUG, "malloc client_rsa failed!");
goto err;
}
mbedtls_pk_init(client_rsa);
if ( mbedtls_x509_crt_parse(client_crt, (const unsigned char *)n->clientCA, strlen(n->clientCA)+1) != 0 ) {
mqtt_printf(MQTT_DEBUG, "parse client_crt failed!");
goto err;
}
if ( mbedtls_pk_parse_key(client_rsa, (const unsigned char *)n->private_key, strlen(n->private_key)+1, NULL, 0) != 0 ) {
mqtt_printf(MQTT_DEBUG, "parse client_rsa failed!");
goto err;
}
mbedtls_ssl_conf_own_cert(n->conf, client_crt, client_rsa);
}
retVal = mbedtls_ssl_handshake(n->ssl);
if (retVal < 0) {
mqtt_printf(MQTT_DEBUG, "ssl handshake failed err:-0x%04X", -retVal);
goto err;
} else {
mqtt_printf(MQTT_DEBUG, "ssl handshake success");
}
}
if (client_rsa) {
mbedtls_pk_free(client_rsa);
mbedtls_free(client_rsa);
}
if (client_crt) {
mbedtls_x509_crt_free(client_crt);
mbedtls_free(client_crt);
}
if (root_crt) {
mbedtls_x509_crt_free(root_crt);
mbedtls_free(root_crt);
}
goto exit;
err:
if (client_rsa) {
mbedtls_pk_free(client_rsa);
mbedtls_free(client_rsa);
}
if (client_crt) {
mbedtls_x509_crt_free(client_crt);
mbedtls_free(client_crt);
}
if (root_crt) {
mbedtls_x509_crt_free(root_crt);
mbedtls_free(root_crt);
}
mbedtls_net_free((mbedtls_net_context *)&n->my_socket);
mbedtls_ssl_free(n->ssl);
mbedtls_ssl_config_free(n->conf);
free(n->ssl);
free(n->conf);
retVal = -1;
#endif // #if (MQTT_OVER_SSL)
exit:
return retVal;
}
#endif /* CONFIG_USE_POLARSSL */
#if 0
int NetworkConnectTLS(Network *n, char* addr, int port, SlSockSecureFiles_t* certificates, unsigned char sec_method, unsigned int cipher, char server_verify)
{
SlSockAddrIn_t sAddr;
int addrSize;
int retVal;
unsigned long ipAddress;
retVal = sl_NetAppDnsGetHostByName(addr, strlen(addr), &ipAddress, AF_INET);
if (retVal < 0) {
return -1;
}
sAddr.sin_family = AF_INET;
sAddr.sin_port = sl_Htons((unsigned short)port);
sAddr.sin_addr.s_addr = sl_Htonl(ipAddress);
addrSize = sizeof(SlSockAddrIn_t);
n->my_socket = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, SL_SEC_SOCKET);
if (n->my_socket < 0) {
return -1;
}
SlSockSecureMethod method;
method.secureMethod = sec_method;
retVal = sl_SetSockOpt(n->my_socket, SL_SOL_SOCKET, SL_SO_SECMETHOD, &method, sizeof(method));
if (retVal < 0) {
return retVal;
}
SlSockSecureMask mask;
mask.secureMask = cipher;
retVal = sl_SetSockOpt(n->my_socket, SL_SOL_SOCKET, SL_SO_SECURE_MASK, &mask, sizeof(mask));
if (retVal < 0) {
return retVal;
}
if (certificates != NULL) {
retVal = sl_SetSockOpt(n->my_socket, SL_SOL_SOCKET, SL_SO_SECURE_FILES, certificates->secureFiles, sizeof(SlSockSecureFiles_t));
if (retVal < 0)
{
return retVal;
}
}
retVal = sl_Connect(n->my_socket, (SlSockAddr_t *)&sAddr, addrSize);
if (retVal < 0) {
if (server_verify || retVal != -453) {
sl_Close(n->my_socket);
return retVal;
}
}
SysTickIntRegister(SysTickIntHandler);
SysTickPeriodSet(80000);
SysTickEnable();
return retVal;
}
#endif

View File

@@ -0,0 +1,122 @@
/*******************************************************************************
* Copyright (c) 2014, 2015 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Allan Stockdill-Mander - initial API and implementation and/or initial documentation
*******************************************************************************/
#if !defined(MQTTFreeRTOS_H)
#define MQTTFreeRTOS_H
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
#include "lwip/sockets.h"
#include "osdep_service.h"
#define MQTT_OVER_SSL (1)
#if (MQTT_OVER_SSL)
#if CONFIG_USE_POLARSSL
#include "polarssl/config.h"
#include "polarssl/net.h"
#include "polarssl/ssl.h"
#include "polarssl/error.h"
#include "polarssl/memory.h"
#elif CONFIG_USE_MBEDTLS
#include "mbedtls/config.h"
#include "mbedtls/platform.h"
#include "mbedtls/net_sockets.h"
#include "mbedtls/ssl.h"
#include "mbedtls/error.h"
#include "mbedtls/debug.h"
#endif
#endif
enum {
MQTT_EXCESSIVE, MQTT_MSGDUMP, MQTT_DEBUG, MQTT_INFO, MQTT_ALWAYS, MQTT_WARNING, MQTT_ERROR
};
#define FreeRTOS_Select select
#define mqtt_printf(level, fmt, arg...) \
do {\
if (level >= MQTT_DEBUG) {\
{\
printf("\r\n[%d]mqtt:", rtw_get_current_time());\
printf(fmt, ##arg);\
printf("\n\r");\
} \
}\
}while(0)
typedef struct Timer
{
TickType_t xTicksToWait;
TimeOut_t xTimeOut;
} Timer;
typedef struct Network Network;
struct Network
{
int my_socket;
int (*mqttread) (Network*, unsigned char*, int, int);
int (*mqttwrite) (Network*, unsigned char*, int, int);
void (*disconnect) (Network*);
int m2m_rxevent;
#if (MQTT_OVER_SSL)
unsigned char use_ssl;
#if CONFIG_USE_POLARSSL
ssl_context *ssl;
#elif CONFIG_USE_MBEDTLS
mbedtls_ssl_context *ssl;
mbedtls_ssl_config *conf;
#endif
char *rootCA;
char *clientCA;
char *private_key;
#endif
};
void TimerInit(Timer*);
char TimerIsExpired(Timer*);
void TimerCountdownMS(Timer*, unsigned int);
void TimerCountdown(Timer*, unsigned int);
int TimerLeftMS(Timer*);
typedef struct Mutex
{
SemaphoreHandle_t sem;
} Mutex;
void MutexInit(Mutex*);
int MutexLock(Mutex*);
int MutexUnlock(Mutex*);
typedef struct Thread
{
TaskHandle_t task;
} Thread;
int ThreadStart(Thread*, void (*fn)(void*), void* arg);
int FreeRTOS_read(Network*, unsigned char*, int, int);
int FreeRTOS_write(Network*, unsigned char*, int, int);
void FreeRTOS_disconnect(Network*);
void NetworkInit(Network*);
int NetworkConnect(Network*, char*, int);
/*int NetworkConnectTLS(Network*, char*, int, SlSockSecureFiles_t*, unsigned char, unsigned int, char);*/
#endif

View File

@@ -0,0 +1,139 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Xiang Rong - 442039 Add makefile to Embedded C client
*******************************************************************************/
#ifndef MQTTCONNECT_H_
#define MQTTCONNECT_H_
#if !defined(DLLImport)
#define DLLImport
#endif
#if !defined(DLLExport)
#define DLLExport
#endif
typedef union
{
unsigned char all; /**< all connect flags */
#if defined(REVERSED)
struct
{
unsigned int username : 1; /**< 3.1 user name */
unsigned int password : 1; /**< 3.1 password */
unsigned int willRetain : 1; /**< will retain setting */
unsigned int willQoS : 2; /**< will QoS value */
unsigned int will : 1; /**< will flag */
unsigned int cleansession : 1; /**< clean session flag */
unsigned int : 1; /**< unused */
} bits;
#else
struct
{
unsigned int : 1; /**< unused */
unsigned int cleansession : 1; /**< cleansession flag */
unsigned int will : 1; /**< will flag */
unsigned int willQoS : 2; /**< will QoS value */
unsigned int willRetain : 1; /**< will retain setting */
unsigned int password : 1; /**< 3.1 password */
unsigned int username : 1; /**< 3.1 user name */
} bits;
#endif
} MQTTConnectFlags; /**< connect flags byte */
/**
* Defines the MQTT "Last Will and Testament" (LWT) settings for
* the connect packet.
*/
typedef struct
{
/** The eyecatcher for this structure. must be MQTW. */
char struct_id[4];
/** The version number of this structure. Must be 0 */
int struct_version;
/** The LWT topic to which the LWT message will be published. */
MQTTString topicName;
/** The LWT payload. */
MQTTString message;
/**
* The retained flag for the LWT message (see MQTTAsync_message.retained).
*/
unsigned char retained;
/**
* The quality of service setting for the LWT message (see
* MQTTAsync_message.qos and @ref qos).
*/
char qos;
} MQTTPacket_willOptions;
#define MQTTPacket_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 0, {NULL, {0, NULL}}, {NULL, {0, NULL}}, 0, 0 }
typedef struct
{
/** The eyecatcher for this structure. must be MQTC. */
char struct_id[4];
/** The version number of this structure. Must be 0 */
int struct_version;
/** Version of MQTT to be used. 3 = 3.1 4 = 3.1.1
*/
unsigned char MQTTVersion;
MQTTString clientID;
unsigned short keepAliveInterval;
unsigned char cleansession;
unsigned char willFlag;
MQTTPacket_willOptions will;
MQTTString username;
MQTTString password;
} MQTTPacket_connectData;
typedef union
{
unsigned char all; /**< all connack flags */
#if defined(REVERSED)
struct
{
unsigned int sessionpresent : 1; /**< session present flag */
unsigned int : 7; /**< unused */
} bits;
#else
struct
{
unsigned int : 7; /**< unused */
unsigned int sessionpresent : 1; /**< session present flag */
} bits;
#endif
} MQTTConnackFlags; /**< connack flags byte */
#define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 0, 4, {NULL, {0, NULL}}, 60, 1, 0, \
MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} }
DLLExport int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options);
DLLExport int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len);
DLLExport int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent);
DLLExport int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen);
DLLExport int MQTTSerialize_disconnect(unsigned char* buf, int buflen);
DLLExport int MQTTSerialize_pingreq(unsigned char* buf, int buflen);
#endif /* MQTTCONNECT_H_ */

View File

@@ -0,0 +1,214 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Determines the length of the MQTT connect packet that would be produced using the supplied connect options.
* @param options the options to be used to build the connect packet
* @return the length of buffer needed to contain the serialized version of the packet
*/
int MQTTSerialize_connectLength(MQTTPacket_connectData* options)
{
int len = 0;
FUNC_ENTRY;
if (options->MQTTVersion == 3)
len = 12; /* variable depending on MQTT or MQIsdp */
else if (options->MQTTVersion == 4)
len = 10;
len += MQTTstrlen(options->clientID)+2;
if (options->willFlag)
len += MQTTstrlen(options->will.topicName)+2 + MQTTstrlen(options->will.message)+2;
if (options->username.cstring || options->username.lenstring.data)
len += MQTTstrlen(options->username)+2;
if (options->password.cstring || options->password.lenstring.data)
len += MQTTstrlen(options->password)+2;
FUNC_EXIT_RC(len);
return len;
}
/**
* Serializes the connect options into the buffer.
* @param buf the buffer into which the packet will be serialized
* @param len the length in bytes of the supplied buffer
* @param options the options to be used to build the connect packet
* @return serialized length, or error if 0
*/
int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options)
{
unsigned char *ptr = buf;
MQTTHeader header = {0};
MQTTConnectFlags flags = {0};
int len = 0;
int rc = -1;
FUNC_ENTRY;
if (MQTTPacket_len(len = MQTTSerialize_connectLength(options)) > buflen)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = CONNECT;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, len); /* write remaining length */
if (options->MQTTVersion == 4)
{
writeCString(&ptr, "MQTT");
writeChar(&ptr, (char) 4);
}
else
{
writeCString(&ptr, "MQIsdp");
writeChar(&ptr, (char) 3);
}
flags.all = 0;
flags.bits.cleansession = options->cleansession;
flags.bits.will = (options->willFlag) ? 1 : 0;
if (flags.bits.will)
{
flags.bits.willQoS = options->will.qos;
flags.bits.willRetain = options->will.retained;
}
if (options->username.cstring || options->username.lenstring.data)
flags.bits.username = 1;
if (options->password.cstring || options->password.lenstring.data)
flags.bits.password = 1;
writeChar(&ptr, flags.all);
writeInt(&ptr, options->keepAliveInterval);
writeMQTTString(&ptr, options->clientID);
if (options->willFlag)
{
writeMQTTString(&ptr, options->will.topicName);
writeMQTTString(&ptr, options->will.message);
}
if (flags.bits.username)
writeMQTTString(&ptr, options->username);
if (flags.bits.password)
writeMQTTString(&ptr, options->password);
rc = ptr - buf;
exit: FUNC_EXIT_RC(rc);
return rc;
}
/**
* Deserializes the supplied (wire) buffer into connack data - return code
* @param sessionPresent the session present flag returned (only for MQTT 3.1.1)
* @param connack_rc returned integer value of the connack return code
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param len the length in bytes of the data in the supplied buffer
* @return error code. 1 is success, 0 is failure
*/
int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = 0;
int mylen;
MQTTConnackFlags flags = {0};
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != CONNACK)
goto exit;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
if (enddata - curdata < 2)
goto exit;
flags.all = readChar(&curdata);
*sessionPresent = flags.bits.sessionpresent;
*connack_rc = readChar(&curdata);
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes a 0-length packet into the supplied buffer, ready for writing to a socket
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer, to avoid overruns
* @param packettype the message type
* @return serialized length, or error if 0
*/
int MQTTSerialize_zero(unsigned char* buf, int buflen, unsigned char packettype)
{
MQTTHeader header = {0};
int rc = -1;
unsigned char *ptr = buf;
FUNC_ENTRY;
if (buflen < 2)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = packettype;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, 0); /* write remaining length */
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes a disconnect packet into the supplied buffer, ready for writing to a socket
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer, to avoid overruns
* @return serialized length, or error if 0
*/
int MQTTSerialize_disconnect(unsigned char* buf, int buflen)
{
return MQTTSerialize_zero(buf, buflen, DISCONNECT);
}
/**
* Serializes a disconnect packet into the supplied buffer, ready for writing to a socket
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer, to avoid overruns
* @return serialized length, or error if 0
*/
int MQTTSerialize_pingreq(unsigned char* buf, int buflen)
{
return MQTTSerialize_zero(buf, buflen, PINGREQ);
}

View File

@@ -0,0 +1,147 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "StackTrace.h"
#include "MQTTPacket.h"
#include <string.h>
#define min(a, b) ((a < b) ? a : b)
/**
* Validates MQTT protocol name and version combinations
* @param protocol the MQTT protocol name as an MQTTString
* @param version the MQTT protocol version number, as in the connect packet
* @return correct MQTT combination? 1 is true, 0 is false
*/
int MQTTPacket_checkVersion(MQTTString* protocol, int version)
{
int rc = 0;
if (version == 3 && memcmp(protocol->lenstring.data, "MQIsdp",
min(6, protocol->lenstring.len)) == 0)
rc = 1;
else if (version == 4 && memcmp(protocol->lenstring.data, "MQTT",
min(4, protocol->lenstring.len)) == 0)
rc = 1;
return rc;
}
/**
* Deserializes the supplied (wire) buffer into connect data structure
* @param data the connect data structure to be filled out
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param len the length in bytes of the data in the supplied buffer
* @return error code. 1 is success, 0 is failure
*/
int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len)
{
MQTTHeader header = {0};
MQTTConnectFlags flags = {0};
unsigned char* curdata = buf;
unsigned char* enddata = &buf[len];
int rc = 0;
MQTTString Protocol;
int version;
int mylen = 0;
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != CONNECT)
goto exit;
curdata += MQTTPacket_decodeBuf(curdata, &mylen); /* read remaining length */
if (!readMQTTLenString(&Protocol, &curdata, enddata) ||
enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */
goto exit;
version = (int)readChar(&curdata); /* Protocol version */
/* If we don't recognize the protocol version, we don't parse the connect packet on the
* basis that we don't know what the format will be.
*/
if (MQTTPacket_checkVersion(&Protocol, version))
{
flags.all = readChar(&curdata);
data->cleansession = flags.bits.cleansession;
data->keepAliveInterval = readInt(&curdata);
if (!readMQTTLenString(&data->clientID, &curdata, enddata))
goto exit;
data->willFlag = flags.bits.will;
if (flags.bits.will)
{
data->will.qos = flags.bits.willQoS;
data->will.retained = flags.bits.willRetain;
if (!readMQTTLenString(&data->will.topicName, &curdata, enddata) ||
!readMQTTLenString(&data->will.message, &curdata, enddata))
goto exit;
}
if (flags.bits.username)
{
if (enddata - curdata < 3 || !readMQTTLenString(&data->username, &curdata, enddata))
goto exit; /* username flag set, but no username supplied - invalid */
if (flags.bits.password &&
(enddata - curdata < 3 || !readMQTTLenString(&data->password, &curdata, enddata)))
goto exit; /* password flag set, but no password supplied - invalid */
}
else if (flags.bits.password)
goto exit; /* password flag set without username - invalid */
rc = 1;
}
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes the connack packet into the supplied buffer.
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param connack_rc the integer connack return code to be used
* @param sessionPresent the MQTT 3.1.1 sessionPresent flag
* @return serialized length, or error if 0
*/
int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent)
{
MQTTHeader header = {0};
int rc = 0;
unsigned char *ptr = buf;
MQTTConnackFlags flags = {0};
FUNC_ENTRY;
if (buflen < 2)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = CONNACK;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
flags.all = 0;
flags.bits.sessionpresent = sessionPresent;
writeChar(&ptr, flags.all);
writeChar(&ptr, connack_rc);
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}

View File

@@ -0,0 +1,105 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "StackTrace.h"
#include "MQTTPacket.h"
#include <string.h>
#define min(a, b) ((a < b) ? 1 : 0)
/**
* Deserializes the supplied (wire) buffer into publish data
* @param dup returned integer - the MQTT dup flag
* @param qos returned integer - the MQTT QoS value
* @param retained returned integer - the MQTT retained flag
* @param packetid returned integer - the MQTT packet identifier
* @param topicName returned MQTTString - the MQTT topic in the publish
* @param payload returned byte buffer - the MQTT publish payload
* @param payloadlen returned integer - the length of the MQTT payload
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return error code. 1 is success
*/
int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName,
unsigned char** payload, int* payloadlen, unsigned char* buf, int buflen)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = 0;
int mylen = 0;
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != PUBLISH)
goto exit;
*dup = header.bits.dup;
*qos = header.bits.qos;
*retained = header.bits.retain;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
if (!readMQTTLenString(topicName, &curdata, enddata) ||
enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */
goto exit;
if (*qos > 0)
*packetid = readInt(&curdata);
*payloadlen = enddata - curdata;
*payload = curdata;
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Deserializes the supplied (wire) buffer into an ack
* @param packettype returned integer - the MQTT packet type
* @param dup returned integer - the MQTT dup flag
* @param packetid returned integer - the MQTT packet identifier
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return error code. 1 is success, 0 is failure
*/
int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = 0;
int mylen;
FUNC_ENTRY;
header.byte = readChar(&curdata);
*dup = header.bits.dup;
*packettype = header.bits.type;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
if (enddata - curdata < 2)
goto exit;
*packetid = readInt(&curdata);
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}

View File

@@ -0,0 +1,255 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "StackTrace.h"
#include "MQTTPacket.h"
#include <string.h>
const char* MQTTPacket_names[] =
{
"RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL",
"PUBCOMP", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK",
"PINGREQ", "PINGRESP", "DISCONNECT"
};
const char* MQTTPacket_getName(unsigned short packetid)
{
return MQTTPacket_names[packetid];
}
int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data)
{
int strindex = 0;
strindex = snprintf(strbuf, strbuflen,
"CONNECT MQTT version %d, client id %.*s, clean session %d, keep alive %d",
(int)data->MQTTVersion, data->clientID.lenstring.len, data->clientID.lenstring.data,
(int)data->cleansession, data->keepAliveInterval);
if (data->willFlag)
strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
", will QoS %d, will retain %d, will topic %.*s, will message %.*s",
data->will.qos, data->will.retained,
data->will.topicName.lenstring.len, data->will.topicName.lenstring.data,
data->will.message.lenstring.len, data->will.message.lenstring.data);
if (data->username.lenstring.data && data->username.lenstring.len > 0)
strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
", user name %.*s", data->username.lenstring.len, data->username.lenstring.data);
if (data->password.lenstring.data && data->password.lenstring.len > 0)
strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
", password %.*s", data->password.lenstring.len, data->password.lenstring.data);
return strindex;
}
int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent)
{
int strindex = snprintf(strbuf, strbuflen, "CONNACK session present %d, rc %d", sessionPresent, connack_rc);
return strindex;
}
int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,
unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen)
{
int strindex = snprintf(strbuf, strbuflen,
"PUBLISH dup %d, QoS %d, retained %d, packet id %d, topic %.*s, payload length %d, payload %.*s",
dup, qos, retained, packetid,
(topicName.lenstring.len < 20) ? topicName.lenstring.len : 20, topicName.lenstring.data,
payloadlen, (payloadlen < 20) ? payloadlen : 20, payload);
return strindex;
}
int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid)
{
int strindex = snprintf(strbuf, strbuflen, "%s, packet id %d", MQTTPacket_names[packettype], packetid);
if (dup)
strindex += snprintf(strbuf + strindex, strbuflen - strindex, ", dup %d", dup);
return strindex;
}
int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,
MQTTString topicFilters[], int requestedQoSs[])
{
return snprintf(strbuf, strbuflen,
"SUBSCRIBE dup %d, packet id %d count %d topic %.*s qos %d",
dup, packetid, count,
topicFilters[0].lenstring.len, topicFilters[0].lenstring.data,
requestedQoSs[0]);
}
int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs)
{
return snprintf(strbuf, strbuflen,
"SUBACK packet id %d count %d granted qos %d", packetid, count, grantedQoSs[0]);
}
int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,
int count, MQTTString topicFilters[])
{
return snprintf(strbuf, strbuflen,
"UNSUBSCRIBE dup %d, packet id %d count %d topic %.*s",
dup, packetid, count,
topicFilters[0].lenstring.len, topicFilters[0].lenstring.data);
}
char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
{
int index = 0;
int rem_length = 0;
MQTTHeader header = {0};
header.byte = buf[index++];
index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
switch (header.bits.type)
{
case CONNACK:
{
unsigned char sessionPresent, connack_rc;
if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) == 1)
MQTTStringFormat_connack(strbuf, strbuflen, connack_rc, sessionPresent);
}
break;
case PUBLISH:
{
unsigned char dup, retained, *payload;
unsigned short packetid;
int qos, payloadlen;
MQTTString topicName = MQTTString_initializer;
if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
&payload, &payloadlen, buf, buflen) == 1)
MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
topicName, payload, payloadlen);
}
break;
case PUBACK:
case PUBREC:
case PUBREL:
case PUBCOMP:
{
unsigned char packettype, dup;
unsigned short packetid;
if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
}
break;
case SUBACK:
{
unsigned short packetid;
int maxcount = 1, count = 0;
int grantedQoSs[1];
if (MQTTDeserialize_suback(&packetid, maxcount, &count, grantedQoSs, buf, buflen) == 1)
MQTTStringFormat_suback(strbuf, strbuflen, packetid, count, grantedQoSs);
}
break;
case UNSUBACK:
{
unsigned short packetid;
if (MQTTDeserialize_unsuback(&packetid, buf, buflen) == 1)
MQTTStringFormat_ack(strbuf, strbuflen, UNSUBACK, 0, packetid);
}
break;
case PINGREQ:
case PINGRESP:
case DISCONNECT:
snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
break;
}
return strbuf;
}
char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
{
int index = 0;
int rem_length = 0;
MQTTHeader header = {0};
header.byte = buf[index++];
index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
switch (header.bits.type)
{
case CONNECT:
{
MQTTPacket_connectData data;
if ((MQTTDeserialize_connect(&data, buf, buflen)) == 1)
MQTTStringFormat_connect(strbuf, strbuflen, &data);
}
break;
case PUBLISH:
{
unsigned char dup, retained, *payload;
unsigned short packetid;
int qos, payloadlen;
MQTTString topicName = MQTTString_initializer;
if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
&payload, &payloadlen, buf, buflen) == 1)
MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
topicName, payload, payloadlen);
}
break;
case PUBACK:
case PUBREC:
case PUBREL:
case PUBCOMP:
{
unsigned char packettype, dup;
unsigned short packetid;
if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
}
break;
case SUBSCRIBE:
{
unsigned char dup;
unsigned short packetid;
int maxcount = 1, count = 0;
MQTTString topicFilters[1];
int requestedQoSs[1];
if (MQTTDeserialize_subscribe(&dup, &packetid, maxcount, &count,
topicFilters, requestedQoSs, buf, buflen) == 1)
MQTTStringFormat_subscribe(strbuf, strbuflen, dup, packetid, count, topicFilters, requestedQoSs);;
}
break;
case UNSUBSCRIBE:
{
unsigned char dup;
unsigned short packetid;
int maxcount = 1, count = 0;
MQTTString topicFilters[1];
if (MQTTDeserialize_unsubscribe(&dup, &packetid, maxcount, &count, topicFilters, buf, buflen) == 1)
MQTTStringFormat_unsubscribe(strbuf, strbuflen, dup, packetid, count, topicFilters);
}
break;
case PINGREQ:
case PINGRESP:
case DISCONNECT:
snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
break;
}
strbuf[strbuflen] = '\0';
return strbuf;
}

View File

@@ -0,0 +1,37 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#if !defined(MQTTFORMAT_H)
#define MQTTFORMAT_H
#include "StackTrace.h"
#include "MQTTPacket.h"
const char* MQTTPacket_getName(unsigned short packetid);
int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data);
int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent);
int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,
unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen);
int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid);
int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,
MQTTString topicFilters[], int requestedQoSs[]);
int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs);
int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,
int count, MQTTString topicFilters[]);
char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen);
char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen);
#endif

View File

@@ -0,0 +1,410 @@
/****************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Sergio R. Caprile - non-blocking packet read functions for stream transport
*******************************************************************************/
#include "StackTrace.h"
#include "MQTTPacket.h"
#include <string.h>
/**
* Encodes the message length according to the MQTT algorithm
* @param buf the buffer into which the encoded data is written
* @param length the length to be encoded
* @return the number of bytes written to buffer
*/
int MQTTPacket_encode(unsigned char* buf, int length)
{
int rc = 0;
FUNC_ENTRY;
do
{
char d = length % 128;
length /= 128;
/* if there are more digits to encode, set the top bit of this digit */
if (length > 0)
d |= 0x80;
buf[rc++] = d;
} while (length > 0);
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Decodes the message length according to the MQTT algorithm
* @param getcharfn pointer to function to read the next character from the data source
* @param value the decoded length returned
* @return the number of bytes read from the socket
*/
int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value)
{
unsigned char c;
int multiplier = 1;
int len = 0;
#define MAX_NO_OF_REMAINING_LENGTH_BYTES 4
FUNC_ENTRY;
*value = 0;
do
{
int rc = MQTTPACKET_READ_ERROR;
if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
{
rc = MQTTPACKET_READ_ERROR; /* bad data */
goto exit;
}
rc = (*getcharfn)(&c, 1);
if (rc != 1)
goto exit;
*value += (c & 127) * multiplier;
multiplier *= 128;
} while ((c & 128) != 0);
exit:
FUNC_EXIT_RC(len);
return len;
}
int MQTTPacket_len(int rem_len)
{
rem_len += 1; /* header byte */
/* now remaining_length field */
if (rem_len < 128)
rem_len += 1;
else if (rem_len < 16384)
rem_len += 2;
else if (rem_len < 2097151)
rem_len += 3;
else
rem_len += 4;
return rem_len;
}
static unsigned char* bufptr;
int bufchar(unsigned char* c, int count)
{
int i;
for (i = 0; i < count; ++i)
*c = *bufptr++;
return count;
}
int MQTTPacket_decodeBuf(unsigned char* buf, int* value)
{
bufptr = buf;
return MQTTPacket_decode(bufchar, value);
}
/**
* Calculates an integer from two bytes read from the input buffer
* @param pptr pointer to the input buffer - incremented by the number of bytes used & returned
* @return the integer value calculated
*/
int readInt(unsigned char** pptr)
{
unsigned char* ptr = *pptr;
int len = 256*(*ptr) + (*(ptr+1));
*pptr += 2;
return len;
}
/**
* Reads one character from the input buffer.
* @param pptr pointer to the input buffer - incremented by the number of bytes used & returned
* @return the character read
*/
char readChar(unsigned char** pptr)
{
char c = **pptr;
(*pptr)++;
return c;
}
/**
* Writes one character to an output buffer.
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
* @param c the character to write
*/
void writeChar(unsigned char** pptr, char c)
{
**pptr = c;
(*pptr)++;
}
/**
* Writes an integer as 2 bytes to an output buffer.
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
* @param anInt the integer to write
*/
void writeInt(unsigned char** pptr, int anInt)
{
**pptr = (unsigned char)(anInt / 256);
(*pptr)++;
**pptr = (unsigned char)(anInt % 256);
(*pptr)++;
}
/**
* Writes a "UTF" string to an output buffer. Converts C string to length-delimited.
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
* @param string the C string to write
*/
void writeCString(unsigned char** pptr, const char* string)
{
int len = strlen(string);
writeInt(pptr, len);
memcpy(*pptr, string, len);
*pptr += len;
}
int getLenStringLen(char* ptr)
{
int len = 256*((unsigned char)(*ptr)) + (unsigned char)(*(ptr+1));
return len;
}
void writeMQTTString(unsigned char** pptr, MQTTString mqttstring)
{
if (mqttstring.lenstring.len > 0)
{
writeInt(pptr, mqttstring.lenstring.len);
memcpy(*pptr, mqttstring.lenstring.data, mqttstring.lenstring.len);
*pptr += mqttstring.lenstring.len;
}
else if (mqttstring.cstring)
writeCString(pptr, mqttstring.cstring);
else
writeInt(pptr, 0);
}
/**
* @param mqttstring the MQTTString structure into which the data is to be read
* @param pptr pointer to the output buffer - incremented by the number of bytes used & returned
* @param enddata pointer to the end of the data: do not read beyond
* @return 1 if successful, 0 if not
*/
int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata)
{
int rc = 0;
FUNC_ENTRY;
/* the first two bytes are the length of the string */
if (enddata - (*pptr) > 1) /* enough length to read the integer? */
{
mqttstring->lenstring.len = readInt(pptr); /* increments pptr to point past length */
if (&(*pptr)[mqttstring->lenstring.len] <= enddata)
{
mqttstring->lenstring.data = (char*)*pptr;
*pptr += mqttstring->lenstring.len;
rc = 1;
}
}
mqttstring->cstring = NULL;
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Return the length of the MQTTstring - C string if there is one, otherwise the length delimited string
* @param mqttstring the string to return the length of
* @return the length of the string
*/
int MQTTstrlen(MQTTString mqttstring)
{
int rc = 0;
if (mqttstring.cstring)
rc = strlen(mqttstring.cstring);
else
rc = mqttstring.lenstring.len;
return rc;
}
/**
* Compares an MQTTString to a C string
* @param a the MQTTString to compare
* @param bptr the C string to compare
* @return boolean - equal or not
*/
int MQTTPacket_equals(MQTTString* a, char* bptr)
{
int alen = 0,
blen = 0;
char *aptr;
if (a->cstring)
{
aptr = a->cstring;
alen = strlen(a->cstring);
}
else
{
aptr = a->lenstring.data;
alen = a->lenstring.len;
}
blen = strlen(bptr);
return (alen == blen) && (strncmp(aptr, bptr, alen) == 0);
}
/**
* Helper function to read packet data from some source into a buffer
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param getfn pointer to a function which will read any number of bytes from the needed source
* @return integer MQTT packet type, or -1 on error
* @note the whole message must fit into the caller's buffer
*/
int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int))
{
int rc = -1;
MQTTHeader header = {0};
int len = 0;
int rem_len = 0;
/* 1. read the header byte. This has the packet type in it */
if ((*getfn)(buf, 1) != 1)
goto exit;
len = 1;
/* 2. read the remaining length. This is variable in itself */
MQTTPacket_decode(getfn, &rem_len);
len += MQTTPacket_encode(buf + 1, rem_len); /* put the original remaining length back into the buffer */
/* 3. read the rest of the buffer using a callback to supply the rest of the data */
if((rem_len + len) > buflen)
goto exit;
if ((*getfn)(buf + len, rem_len) != rem_len)
goto exit;
header.byte = buf[0];
rc = header.bits.type;
exit:
return rc;
}
/**
* Decodes the message length according to the MQTT algorithm, non-blocking
* @param trp pointer to a transport structure holding what is needed to solve getting data from it
* @param value the decoded length returned
* @return integer the number of bytes read from the socket, 0 for call again, or -1 on error
*/
static int MQTTPacket_decodenb(MQTTTransport *trp)
{
unsigned char c;
int rc = MQTTPACKET_READ_ERROR;
FUNC_ENTRY;
if(trp->len == 0){ /* initialize on first call */
trp->multiplier = 1;
trp->rem_len = 0;
}
do {
int frc;
if (++(trp->len) > MAX_NO_OF_REMAINING_LENGTH_BYTES)
goto exit;
if ((frc=(*trp->getfn)(trp->sck, &c, 1)) == -1)
goto exit;
if (frc == 0){
rc = 0;
goto exit;
}
trp->rem_len += (c & 127) * trp->multiplier;
trp->multiplier *= 128;
} while ((c & 128) != 0);
rc = trp->len;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Helper function to read packet data from some source into a buffer, non-blocking
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param trp pointer to a transport structure holding what is needed to solve getting data from it
* @return integer MQTT packet type, 0 for call again, or -1 on error
* @note the whole message must fit into the caller's buffer
*/
int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp)
{
int rc = -1, frc;
MQTTHeader header = {0};
switch(trp->state){
default:
trp->state = 0;
/*FALLTHROUGH*/
case 0:
/* read the header byte. This has the packet type in it */
if ((frc=(*trp->getfn)(trp->sck, buf, 1)) == -1)
goto exit;
if (frc == 0)
return 0;
trp->len = 0;
++trp->state;
/*FALLTHROUGH*/
/* read the remaining length. This is variable in itself */
case 1:
if((frc=MQTTPacket_decodenb(trp)) == MQTTPACKET_READ_ERROR)
goto exit;
if(frc == 0)
return 0;
trp->len = 1 + MQTTPacket_encode(buf + 1, trp->rem_len); /* put the original remaining length back into the buffer */
if((trp->rem_len + trp->len) > buflen)
goto exit;
++trp->state;
/*FALLTHROUGH*/
case 2:
/* read the rest of the buffer using a callback to supply the rest of the data */
if ((frc=(*trp->getfn)(trp->sck, buf + trp->len, trp->rem_len)) == -1)
goto exit;
if (frc == 0)
return 0;
trp->rem_len -= frc;
trp->len += frc;
if(trp->rem_len)
return 0;
header.byte = buf[0];
rc = header.bits.type;
break;
}
exit:
trp->state = 0;
return rc;
}

View File

@@ -0,0 +1,133 @@
/*******************************************************************************
/ * Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Xiang Rong - 442039 Add makefile to Embedded C client
*******************************************************************************/
#ifndef MQTTPACKET_H_
#define MQTTPACKET_H_
#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */
extern "C" {
#endif
#if defined(WIN32_DLL) || defined(WIN64_DLL)
#define DLLImport __declspec(dllimport)
#define DLLExport __declspec(dllexport)
#elif defined(LINUX_SO)
#define DLLImport extern
#define DLLExport __attribute__ ((visibility ("default")))
#else
#define DLLImport
#define DLLExport
#endif
enum errors
{
MQTTPACKET_BUFFER_TOO_SHORT = -2,
MQTTPACKET_READ_ERROR = -1,
MQTTPACKET_READ_COMPLETE
};
enum msgTypes
{
CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL,
PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK,
PINGREQ, PINGRESP, DISCONNECT
};
/**
* Bitfields for the MQTT header byte.
*/
typedef union
{
unsigned char byte; /**< the whole byte */
#if defined(REVERSED)
struct
{
unsigned int type : 4; /**< message type nibble */
unsigned int dup : 1; /**< DUP flag bit */
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
unsigned int retain : 1; /**< retained flag bit */
} bits;
#else
struct
{
unsigned int retain : 1; /**< retained flag bit */
unsigned int qos : 2; /**< QoS value, 0, 1 or 2 */
unsigned int dup : 1; /**< DUP flag bit */
unsigned int type : 4; /**< message type nibble */
} bits;
#endif
} MQTTHeader;
typedef struct
{
int len;
char* data;
} MQTTLenString;
typedef struct
{
char* cstring;
MQTTLenString lenstring;
} MQTTString;
#define MQTTString_initializer {NULL, {0, NULL}}
int MQTTstrlen(MQTTString mqttstring);
#include "MQTTConnect.h"
#include "MQTTPublish.h"
#include "MQTTSubscribe.h"
#include "MQTTUnsubscribe.h"
#include "MQTTFormat.h"
int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char type, unsigned char dup, unsigned short packetid);
int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen);
int MQTTPacket_len(int rem_len);
int MQTTPacket_equals(MQTTString* a, char* b);
int MQTTPacket_encode(unsigned char* buf, int length);
int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value);
int MQTTPacket_decodeBuf(unsigned char* buf, int* value);
int readInt(unsigned char** pptr);
char readChar(unsigned char** pptr);
void writeChar(unsigned char** pptr, char c);
void writeInt(unsigned char** pptr, int anInt);
int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata);
void writeCString(unsigned char** pptr, const char* string);
void writeMQTTString(unsigned char** pptr, MQTTString mqttstring);
DLLExport int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int));
typedef struct {
int (*getfn)(void *, unsigned char*, int); /* must return -1 for error, 0 for call again, or the number of bytes read */
void *sck; /* pointer to whatever the system may use to identify the transport */
int multiplier;
int rem_len;
int len;
char state;
}MQTTTransport;
int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp);
#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
}
#endif
#endif /* MQTTPACKET_H_ */

View File

@@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Xiang Rong - 442039 Add makefile to Embedded C client
*******************************************************************************/
#ifndef MQTTPUBLISH_H_
#define MQTTPUBLISH_H_
#if !defined(DLLImport)
#define DLLImport
#endif
#if !defined(DLLExport)
#define DLLExport
#endif
DLLExport int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,
MQTTString topicName, unsigned char* payload, int payloadlen);
DLLExport int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName,
unsigned char** payload, int* payloadlen, unsigned char* buf, int len);
DLLExport int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid);
DLLExport int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid);
DLLExport int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid);
#endif /* MQTTPUBLISH_H_ */

View File

@@ -0,0 +1,169 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=453144
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Determines the length of the MQTT publish packet that would be produced using the supplied parameters
* @param qos the MQTT QoS of the publish (packetid is omitted for QoS 0)
* @param topicName the topic name to be used in the publish
* @param payloadlen the length of the payload to be sent
* @return the length of buffer needed to contain the serialized version of the packet
*/
int MQTTSerialize_publishLength(int qos, MQTTString topicName, int payloadlen)
{
int len = 0;
len += 2 + MQTTstrlen(topicName) + payloadlen;
if (qos > 0)
len += 2; /* packetid */
return len;
}
/**
* Serializes the supplied publish data into the supplied buffer, ready for sending
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param dup integer - the MQTT dup flag
* @param qos integer - the MQTT QoS value
* @param retained integer - the MQTT retained flag
* @param packetid integer - the MQTT packet identifier
* @param topicName MQTTString - the MQTT topic in the publish
* @param payload byte buffer - the MQTT publish payload
* @param payloadlen integer - the length of the MQTT payload
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,
MQTTString topicName, unsigned char* payload, int payloadlen)
{
unsigned char *ptr = buf;
MQTTHeader header = {0};
int rem_len = 0;
int rc = 0;
FUNC_ENTRY;
if (MQTTPacket_len(rem_len = MQTTSerialize_publishLength(qos, topicName, payloadlen)) > buflen)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.bits.type = PUBLISH;
header.bits.dup = dup;
header.bits.qos = qos;
header.bits.retain = retained;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
writeMQTTString(&ptr, topicName);
if (qos > 0)
writeInt(&ptr, packetid);
memcpy(ptr, payload, payloadlen);
ptr += payloadlen;
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes the ack packet into the supplied buffer.
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param type the MQTT packet type
* @param dup the MQTT dup flag
* @param packetid the MQTT packet identifier
* @return serialized length, or error if 0
*/
int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char packettype, unsigned char dup, unsigned short packetid)
{
MQTTHeader header = {0};
int rc = 0;
unsigned char *ptr = buf;
FUNC_ENTRY;
if (buflen < 4)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.bits.type = packettype;
header.bits.dup = dup;
header.bits.qos = (packettype == PUBREL) ? 1 : 0;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
writeInt(&ptr, packetid);
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes a puback packet into the supplied buffer.
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param packetid integer - the MQTT packet identifier
* @return serialized length, or error if 0
*/
int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid)
{
return MQTTSerialize_ack(buf, buflen, PUBACK, 0, packetid);
}
/**
* Serializes a pubrel packet into the supplied buffer.
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param dup integer - the MQTT dup flag
* @param packetid integer - the MQTT packet identifier
* @return serialized length, or error if 0
*/
int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid)
{
return MQTTSerialize_ack(buf, buflen, PUBREL, dup, packetid);
}
/**
* Serializes a pubrel packet into the supplied buffer.
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param packetid integer - the MQTT packet identifier
* @return serialized length, or error if 0
*/
int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid)
{
return MQTTSerialize_ack(buf, buflen, PUBCOMP, 0, packetid);
}

View File

@@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Xiang Rong - 442039 Add makefile to Embedded C client
*******************************************************************************/
#ifndef MQTTSUBSCRIBE_H_
#define MQTTSUBSCRIBE_H_
#if !defined(DLLImport)
#define DLLImport
#endif
#if !defined(DLLExport)
#define DLLExport
#endif
DLLExport int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
int count, MQTTString topicFilters[], int requestedQoSs[]);
DLLExport int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid,
int maxcount, int* count, MQTTString topicFilters[], int requestedQoSs[], unsigned char* buf, int len);
DLLExport int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs);
DLLExport int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int len);
#endif /* MQTTSUBSCRIBE_H_ */

View File

@@ -0,0 +1,135 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Determines the length of the MQTT subscribe packet that would be produced using the supplied parameters
* @param count the number of topic filter strings in topicFilters
* @param topicFilters the array of topic filter strings to be used in the publish
* @return the length of buffer needed to contain the serialized version of the packet
*/
int MQTTSerialize_subscribeLength(int count, MQTTString topicFilters[])
{
int i;
int len = 2; /* packetid */
for (i = 0; i < count; ++i)
len += 2 + MQTTstrlen(topicFilters[i]) + 1; /* length + topic + req_qos */
return len;
}
/**
* Serializes the supplied subscribe data into the supplied buffer, ready for sending
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied bufferr
* @param dup integer - the MQTT dup flag
* @param packetid integer - the MQTT packet identifier
* @param count - number of members in the topicFilters and reqQos arrays
* @param topicFilters - array of topic filter names
* @param requestedQoSs - array of requested QoS
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, int count,
MQTTString topicFilters[], int requestedQoSs[])
{
unsigned char *ptr = buf;
MQTTHeader header = {0};
int rem_len = 0;
int rc = 0;
int i = 0;
FUNC_ENTRY;
if (MQTTPacket_len(rem_len = MQTTSerialize_subscribeLength(count, topicFilters)) > buflen)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = SUBSCRIBE;
header.bits.dup = dup;
header.bits.qos = 1;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
writeInt(&ptr, packetid);
for (i = 0; i < count; ++i)
{
writeMQTTString(&ptr, topicFilters[i]);
writeChar(&ptr, requestedQoSs[i]);
}
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Deserializes the supplied (wire) buffer into suback data
* @param packetid returned integer - the MQTT packet identifier
* @param maxcount - the maximum number of members allowed in the grantedQoSs array
* @param count returned integer - number of members in the grantedQoSs array
* @param grantedQoSs returned array of integers - the granted qualities of service
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return error code. 1 is success, 0 is failure
*/
int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int buflen)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = 0;
int mylen;
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != SUBACK)
goto exit;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
if (enddata - curdata < 2)
goto exit;
*packetid = readInt(&curdata);
*count = 0;
while (curdata < enddata)
{
if (*count > maxcount)
{
rc = -1;
goto exit;
}
grantedQoSs[(*count)++] = readChar(&curdata);
}
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}

View File

@@ -0,0 +1,110 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Deserializes the supplied (wire) buffer into subscribe data
* @param dup integer returned - the MQTT dup flag
* @param packetid integer returned - the MQTT packet identifier
* @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays
* @param count - number of members in the topicFilters and requestedQoSs arrays
* @param topicFilters - array of topic filter names
* @param requestedQoSs - array of requested QoS
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[],
int requestedQoSs[], unsigned char* buf, int buflen)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = -1;
int mylen = 0;
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != SUBSCRIBE)
goto exit;
*dup = header.bits.dup;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
*packetid = readInt(&curdata);
*count = 0;
while (curdata < enddata)
{
if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata))
goto exit;
if (curdata >= enddata) /* do we have enough data to read the req_qos version byte? */
goto exit;
requestedQoSs[*count] = readChar(&curdata);
(*count)++;
}
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes the supplied suback data into the supplied buffer, ready for sending
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param packetid integer - the MQTT packet identifier
* @param count - number of members in the grantedQoSs array
* @param grantedQoSs - array of granted QoS
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs)
{
MQTTHeader header = {0};
int rc = -1;
unsigned char *ptr = buf;
int i;
FUNC_ENTRY;
if (buflen < 2 + count)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = SUBACK;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, 2 + count); /* write remaining length */
writeInt(&ptr, packetid);
for (i = 0; i < count; ++i)
writeChar(&ptr, grantedQoSs[i]);
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}

View File

@@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Xiang Rong - 442039 Add makefile to Embedded C client
*******************************************************************************/
#ifndef MQTTUNSUBSCRIBE_H_
#define MQTTUNSUBSCRIBE_H_
#if !defined(DLLImport)
#define DLLImport
#endif
#if !defined(DLLExport)
#define DLLExport
#endif
DLLExport int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
int count, MQTTString topicFilters[]);
DLLExport int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int max_count, int* count, MQTTString topicFilters[],
unsigned char* buf, int len);
DLLExport int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid);
DLLExport int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int len);
#endif /* MQTTUNSUBSCRIBE_H_ */

View File

@@ -0,0 +1,104 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Determines the length of the MQTT unsubscribe packet that would be produced using the supplied parameters
* @param count the number of topic filter strings in topicFilters
* @param topicFilters the array of topic filter strings to be used in the publish
* @return the length of buffer needed to contain the serialized version of the packet
*/
int MQTTSerialize_unsubscribeLength(int count, MQTTString topicFilters[])
{
int i;
int len = 2; /* packetid */
for (i = 0; i < count; ++i)
len += 2 + MQTTstrlen(topicFilters[i]); /* length + topic*/
return len;
}
/**
* Serializes the supplied unsubscribe data into the supplied buffer, ready for sending
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @param dup integer - the MQTT dup flag
* @param packetid integer - the MQTT packet identifier
* @param count - number of members in the topicFilters array
* @param topicFilters - array of topic filter names
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,
int count, MQTTString topicFilters[])
{
unsigned char *ptr = buf;
MQTTHeader header = {0};
int rem_len = 0;
int rc = -1;
int i = 0;
FUNC_ENTRY;
if (MQTTPacket_len(rem_len = MQTTSerialize_unsubscribeLength(count, topicFilters)) > buflen)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = UNSUBSCRIBE;
header.bits.dup = dup;
header.bits.qos = 1;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
writeInt(&ptr, packetid);
for (i = 0; i < count; ++i)
writeMQTTString(&ptr, topicFilters[i]);
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Deserializes the supplied (wire) buffer into unsuback data
* @param packetid returned integer - the MQTT packet identifier
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return error code. 1 is success, 0 is failure
*/
int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int buflen)
{
unsigned char type = 0;
unsigned char dup = 0;
int rc = 0;
FUNC_ENTRY;
rc = MQTTDeserialize_ack(&type, &dup, packetid, buf, buflen);
if (type == UNSUBACK)
rc = 1;
FUNC_EXIT_RC(rc);
return rc;
}

View File

@@ -0,0 +1,100 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "MQTTPacket.h"
#include "StackTrace.h"
#include <string.h>
/**
* Deserializes the supplied (wire) buffer into unsubscribe data
* @param dup integer returned - the MQTT dup flag
* @param packetid integer returned - the MQTT packet identifier
* @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays
* @param count - number of members in the topicFilters and requestedQoSs arrays
* @param topicFilters - array of topic filter names
* @param buf the raw buffer data, of the correct length determined by the remaining length field
* @param buflen the length in bytes of the data in the supplied buffer
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[],
unsigned char* buf, int len)
{
MQTTHeader header = {0};
unsigned char* curdata = buf;
unsigned char* enddata = NULL;
int rc = 0;
int mylen = 0;
FUNC_ENTRY;
header.byte = readChar(&curdata);
if (header.bits.type != UNSUBSCRIBE)
goto exit;
*dup = header.bits.dup;
curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */
enddata = curdata + mylen;
*packetid = readInt(&curdata);
*count = 0;
while (curdata < enddata)
{
if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata))
goto exit;
(*count)++;
}
rc = 1;
exit:
FUNC_EXIT_RC(rc);
return rc;
}
/**
* Serializes the supplied unsuback data into the supplied buffer, ready for sending
* @param buf the buffer into which the packet will be serialized
* @param buflen the length in bytes of the supplied buffer
* @param packetid integer - the MQTT packet identifier
* @return the length of the serialized data. <= 0 indicates error
*/
int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid)
{
MQTTHeader header = {0};
int rc = 0;
unsigned char *ptr = buf;
FUNC_ENTRY;
if (buflen < 2)
{
rc = MQTTPACKET_BUFFER_TOO_SHORT;
goto exit;
}
header.byte = 0;
header.bits.type = UNSUBACK;
writeChar(&ptr, header.byte); /* write header */
ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
writeInt(&ptr, packetid);
rc = ptr - buf;
exit:
FUNC_EXIT_RC(rc);
return rc;
}

View File

@@ -0,0 +1,78 @@
/*******************************************************************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Ian Craggs - initial API and implementation and/or initial documentation
* Ian Craggs - fix for bug #434081
*******************************************************************************/
#ifndef STACKTRACE_H_
#define STACKTRACE_H_
#include <stdio.h>
#define NOSTACKTRACE 1
#if defined(NOSTACKTRACE)
#define FUNC_ENTRY
#define FUNC_ENTRY_NOLOG
#define FUNC_ENTRY_MED
#define FUNC_ENTRY_MAX
#define FUNC_EXIT
#define FUNC_EXIT_NOLOG
#define FUNC_EXIT_MED
#define FUNC_EXIT_MAX
#define FUNC_EXIT_RC(x)
#define FUNC_EXIT_MED_RC(x)
#define FUNC_EXIT_MAX_RC(x)
#else
#if defined(WIN32)
#define inline __inline
#define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM)
#define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1)
#define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM)
#define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM)
#define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM)
#define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, -1)
#define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM)
#define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM)
#define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM)
#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM)
#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM)
#else
#define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM)
#define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1)
#define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM)
#define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM)
#define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM)
#define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1)
#define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM)
#define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM)
#define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM)
#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM)
#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM)
void StackTrace_entry(const char* name, int line, int trace);
void StackTrace_exit(const char* name, int line, void* return_value, int trace);
void StackTrace_printStack(FILE* dest);
char* StackTrace_get(unsigned long);
#endif
#endif
#endif /* STACKTRACE_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,271 @@
#include "osdep_service.h"
#include "serial_api.h"
#include <timer_api.h>
#include "freertos_pmu.h"
#include <mDNS/mDNS.h>
#include "gpio_api.h"
#include "gpio_irq_api.h"
#include "PinNames.h"
/******************************************************
* Macros
******************************************************/
#define UA_ERROR 0
#define UA_WARNING 1
#define UA_INFO 2
#define UA_DEBUG 3
#define UA_NONE 0xFF
#define UA_DEBUG_LEVEL UA_INFO
#define UA_UART_THREAD_PRIORITY 5
#define UA_UART_THREAD_STACKSIZE 512
#define UA_TCP_SERVER_FD_NUM 1
#define UA_TCP_CLIENT_FD_NUM 1
#define UA_UART_RECV_BUFFER_LEN 8196
#define UA_UART_FRAME_LEN 1400
#define UA_UART_MAX_DELAY_TIME 100
#define UA_CHAT_SOCKET_PORT 5001
#define UA_CONTROL_SOCKET_PORT 6001
#define UA_SC_SOFTAP_EN 1
#ifdef CONFIG_PLATFORM_8195A
#define UA_UART_TX_PIN PA_7
#define UA_UART_RX_PIN PA_6
#define UA_GPIO_LED_PIN PC_5
#define UA_GPIO_IRQ_PIN PC_4
#define UA_GPIO_TIMER TIMER0
#define UA_GPIO_WAKEUP_PIN PC_3
#endif
#ifdef CONFIG_PLATFORM_8711B
#define UA_UART_TX_PIN PA_23
#define UA_UART_RX_PIN PA_18
#define UA_GPIO_LED_PIN PA_5
#define UA_GPIO_IRQ_PIN PA_12
#define UA_GPIO_TIMER TIMER2
#define UA_GPIO_WAKEUP_PIN PA_0
#endif
#define UA_CONTROL_PREFIX "AMEBA_UART"
#define UA_PS_ENABLE 0
#define UA_WAKELOCK PMU_DEV_USER_BASE
#define UA_FAST_RECONNECT_TCP_DATA (0xF5000 + 0x1000)
#if (UA_DEBUG_LEVEL== UA_NONE)
#define ua_printf(level, fmt, arg...)
#else
#define ua_printf(level, fmt, arg...) \
do {\
if (level <= UA_DEBUG_LEVEL) {\
if (level <= UA_ERROR) {\
rtw_down_sema(&ua_print_sema);\
printf("\r\nERROR: " fmt, ##arg);\
rtw_up_sema(&ua_print_sema);\
} \
else {\
rtw_down_sema(&ua_print_sema);\
printf("\r\n"fmt, ##arg);\
rtw_up_sema(&ua_print_sema);\
} \
}\
}while(0)
#endif
#define UA_PRINT_DATA(_HexData, _HexDataLen) \
if(UA_DEBUG_LEVEL == UA_DEBUG) \
{ \
int __i; \
u8 *ptr = (u8 *)_HexData; \
printf("--------Len=%d\n\r", _HexDataLen); \
for( __i=0; __i<(int)_HexDataLen; __i++ ) \
{ \
printf("%02X%s", ptr[__i], (((__i + 1) % 4) == 0)?" ":" "); \
if (((__i + 1) % 16) == 0) printf("\n\r"); \
} \
printf("\n\r"); \
}
#define UA_SOCKET_CHECK(_ua_socket) \
if(_ua_socket == NULL) \
{ \
printf("ERROR: ua_socket = NULL\n\r"); \
return; \
}
#define UA_SOCKET_CHECK_2(_ua_socket) \
if(_ua_socket == NULL) \
{ \
printf("ERROR: ua_socket = NULL\n\r"); \
return -1; \
}
/******************************************************
* Constants
******************************************************/
typedef enum
{
UART_ADAPTER_LED_ON = 0,
UART_ADAPTER_LED_OFF = 1,
UART_ADAPTER_LED_FAST_TWINKLE = 2,
UART_ADAPTER_LED_SLOW_TWINKLE = 3,
}ua_led_mode_t;
typedef enum
{
UART_CTRL_MODE_SET_REQ = 0,
UART_CTRL_MODE_SET_RSP = 1,
UART_CTRL_MODE_GET_REQ = 2,
UART_CTRL_MODE_GET_RSP = 3,
}ua_ctrl_mode_t;
typedef enum
{
UART_CTRL_TYPE_BAUD_RATE = 0x01,
UART_CTRL_TYPE_WORD_LEN = 0x02,
UART_CTRL_TYPE_PARITY = 0x04,
UART_CTRL_TYPE_STOP_BIT = 0x08,
UART_CTRL_TYPE_TCP_SERVER_CREATE = 0x10,
UART_CTRL_TYPE_TCP_SERVER_DELETE = 0x20,
UART_CTRL_TYPE_TCP_CLIENT_CONNECT = 0x40,
UART_CTRL_TYPE_TCP_CLIENT_DISCONNECT = 0x80,
UART_CTRL_TYPE_TCP_GROUP_ID = 0x100,
}ua_ctrl_type_t;
/******************************************************
* Structures
******************************************************/
typedef struct _ua_uart_param_t
{
u8 WordLen;
u8 Parity;
u8 StopBit;
u8 FlowControl;
int BaudRate;
}ua_uart_param_t;
typedef struct _ua_uart_socket_t
{
int fd;
char rcv_ch;
volatile char overlap;
int recv_bytes;
volatile int pread;
volatile int pwrite;
volatile unsigned int tick_last_update;
unsigned int tick_current;
volatile int tx_busy;
volatile int uart_ps;
volatile int uart_ps_cnt;
char recv_buf[UA_UART_RECV_BUFFER_LEN];
long rx_cnt;
long miss_cnt;
serial_t uart_sobj;
ua_uart_param_t uart_param;
_sema action_sema;
_sema tcp_tx_rx_sema;
_sema dma_tx;
}ua_uart_socket_t;
typedef struct _ua_tcp_socket_t
{
int chat_socket;
int control_socket;
int chat_server_listen_socket;
int control_server_listen_socket;
int transmit_recv_socket;
int transmit_send_socket;
int transmit_server_listen_socket;
int group_id;
u32 server_port;
u32 client_port;
char client_ip[16];
int send_flag;
int recv_flag;
long rx_cnt;
long tx_cnt;
volatile int tcp_ps;
volatile int tcp_ps_cnt;
}ua_tcp_socket_t;
typedef struct _ua_gpio_t
{
gpio_t gpio_led;
gpio_t gpio_btn;
gpio_irq_t gpio_btn_irq;
gtimer_t gpio_timer;
}ua_gpio_t;
typedef struct _ua_socket_t
{
ua_uart_socket_t uart;
ua_tcp_socket_t tcp;
ua_gpio_t gpio;
ip_addr_t ip;
DNSServiceRef dnsServiceRef;
DNSServiceRef dnsServiceRef2;
}ua_socket_t;
typedef struct _ua_mbox_buffer
{
char data[UA_UART_FRAME_LEN];
int data_len;
}ua_mbox_buffer_t;
//Save Uart Settings when get uart information
typedef struct _ua_uart_get_str
{
int BaudRate; //The baud rate
char number; //The number of data bits
char parity; //The parity(0: none, 1:odd, 2:evn, default:0)
char StopBits; //The number of stop bits
char FlowControl; //support flow control is 1
}ua_uart_get_str;
//Uart Setting information
typedef struct _ua_uart_set_str
{
char UartName[8]; // the name of uart
int BaudRate; //The baud rate
char number; //The number of data bits
char parity; //The parity(default NONE)
char StopBits; //The number of stop bits
char FlowControl; //support flow control is 1
}ua_uart_set_str;
int uartadapter_init();
void uartadapter_tcp_send_data(ua_socket_t *ua_socket, char *buffer, int size);
void uartadapter_tcp_send_control(ua_socket_t *ua_socket, char *buffer, int size);
void uartadapter_tcp_transmit_server_thread(void *param);
void uartadapter_tcp_transmit_client_thread(void *param);
int uartadapter_tcpclient(ua_socket_t *ua_socket, const char *host_ip, unsigned short usPort);
void uartadapter_tcp_transmit_client_forever_thread(void *param);
void example_uart_adapter_init();
void cmd_uart_adapter(int argc, char **argv);
void uartadapter_tcp_transmit_socket_handler(ua_socket_t *ua_socket, char *tcp_rxbuf);

View File

@@ -0,0 +1,82 @@
#include "FreeRTOS.h"
#include "task.h"
#include "wifi_conf.h"
#include "wifi_ind.h"
#include "google/google_nest.h"
#include "flash_api.h"
#include "wigadget.h"
#include <lwip/netif.h>
#include "shtc1.h"
#define CLOUD_PORT 443
extern struct netif xnetif[NET_IF_NUM];
void cloud_link_task(void *param){
googlenest_context googlenest;
unsigned char URI[64];
unsigned char data[97] = {0};
unsigned char host_addr[64] = {0};
flash_t cloud_flash;
u8 *mac = (u8 *)LwIP_GetMAC(&xnetif[0]);
char i[16], j[16];
float temperature = 1.123f;
float humidity = 2.456f;
int ret = 0;
vTaskDelay(2000);
sprintf(URI, "ht_sensor/%02x%02x%02x%02x%02x%02x.json", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
memset(host_addr, 0, sizeof(host_addr));
if(flash_stream_read(&cloud_flash, FLASH_IOT_DATA, 97, (uint8_t *) data) == 1){
memset(host_addr, 0 , 64);
memcpy(host_addr, data+33, 64);
while(1) {
printf("\r\n\r\n\r\n\r\n\r\n\r\n=====>START CLOUD LINKING\r\n\r\n");
memset(i, 0, 16);
memset(j, 0, 16);
#if PSEUDO_DATA
sprintf(i,"%.2f", temperature++);
sprintf(j, "%.2f", humidity++);
if(temperature > 60)
temperature = 1.123f;
if(humidity > 98)
humidity = 2.456f;
#else
ret = SHTC_GetTempAndHumi(&temperature, &humidity);
sprintf(i, "%.2f", temperature);
sprintf(j, "%.2f", humidity);
#endif
if(ret < 0)
printf("\r\n\r\n<-----LOCAL LINK FAILED!!(get infor failed)\r\n\r\n");
else{
gen_json_data(i, j, data);
printf("\r\nCLOUD-LINK--Sending data : \r\n%s\r\n", data);
memset(&googlenest, 0, sizeof(googlenest_context));
if(gn_connect(&googlenest, host_addr, CLOUD_PORT) == 0) {
if(gn_put(&googlenest, URI, data) != 0)
printf("\r\n\r\nPUT data failed!\r\n\r\n");
gn_close(&googlenest);
printf("\r\n\r\n<=====CLOUD LINK OK!!\r\n\r\n");
}
else{
printf("\r\n\r\n<=====CLOUD LINK FAILED!!(google nest connecting)\r\n\r\n");
}
free(data);
vTaskDelay(10000);
}
}
}
else
printf("\r\n\r\n<=====CLOUD LINK FAILED!!(flash reading)\r\n\r\n");
}
void start_cloud_link(void)
{
if(xTaskCreate(cloud_link_task, ((const char*)"cloud_link_task"), 3584, NULL, tskIDLE_PRIORITY + 4, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
}

View File

@@ -0,0 +1,11 @@
#ifndef CLOUD_LINK_H
#define CLOUD_LINK_THREAD_H
#include "wigadget.h"
void start_cloud_link(void);
void cloud_link_task(void *param);
#endif

View File

@@ -0,0 +1,25 @@
#ifndef _WI_ENCRYPT_H_
#define _WI_ENCRYPT_H_
#include "rom_aes.h"
typedef union
{ unsigned int l;
unsigned char b[4];
} aes_inf;
typedef struct
{
aes_context ctx;
aes_inf inf;
} aes_encrypt_ctx;
typedef struct
{
aes_context ctx;
aes_inf inf;
} aes_decrypt_ctx;
#endif

View File

@@ -0,0 +1,195 @@
#include "FreeRTOS.h"
#include "task.h"
#include "device.h"
#include "PinNames.h"
#include "basic_types.h"
#include "diag.h"
#include "osdep_service.h"
#include "i2c_api.h"
#include "pinmap.h"
#include "shtc1.h"
#ifdef CONFIG_PLATFORM_8195A
#define MBED_I2C_MTR_SDA PB_3
#define MBED_I2C_MTR_SCL PB_2
#endif
#ifdef CONFIG_PLATFORM_8711B
#define MBED_I2C_MTR_SDA PA_19
#define MBED_I2C_MTR_SCL PA_22
#endif
#define MBED_I2C_SLAVE_ADDR0 0x70
#define POLYNOMIAL 0x131 // P(x) = x^8 + x^5 + x^4 + 1 = 100110001
#define MBED_I2C_BUS_CLK 100000 //hz
#define I2C_DATA_MAX_LENGTH 16
static uint8_t i2cdata_write[I2C_DATA_MAX_LENGTH];
static uint8_t i2cdata_read[I2C_DATA_MAX_LENGTH];
static int i2cdata_read_pos;
static i2c_t i2cmaster;
// Sensor Commands
#define READ_ID 0xEFC8 // command: read ID register
#define SOFT_RESET 0x805D // soft resetSample Code for SHTC1
#define MEAS_T_RH_POLLING 0x7866 // meas. read T first, clock stretching disabled
#define MEAS_T_RH_CLOCKSTR 0x7CA2 // meas. read T first, clock stretching enabled
#define MEAS_RH_T_POLLING 0x58E0 // meas. read RH first, clock stretching disabled
#define MEAS_RH_T_CLOCKSTR 0x5C24 // meas. read RH first, clock stretching enabled
static int SHTC1_GetID(uint16_t *id);
static void SHTC1_WriteCommand(uint16_t cmd);
static int SHTC1_Read2BytesAndCrc(uint16_t *data);
static int SHTC1_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum);
static float SHTC1_CalcTemperature(uint16_t rawValue);
static float SHTC1_CalcHumidity(uint16_t rawValue);
int SHTC_Init(uint16_t *pID)
{
int error = NO_ERROR;
DiagPrintf("SHTC1_Init \r\n");
i2c_init((i2c_t*)&i2cmaster, MBED_I2C_MTR_SDA ,MBED_I2C_MTR_SCL);
i2c_frequency((i2c_t*)&i2cmaster,MBED_I2C_BUS_CLK);
if (pID == NULL )
return NULL_ERROR;
error = SHTC1_GetID(pID);
return error;
}
static int SHTC1_GetID(uint16_t *id)
{
int error = NO_ERROR;
uint8_t bytes[2];
uint8_t checksum;
SHTC1_WriteCommand(READ_ID);
i2c_read((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 3, 1);
i2cdata_read_pos = 0;
error = SHTC1_Read2BytesAndCrc(id);
return error;
}
static int SHTC1_Read2BytesAndCrc(uint16_t *data)
{
int error;
int readed;
uint8_t bytes[2];
uint8_t checksum;
bytes[0] = i2cdata_read[i2cdata_read_pos++];
bytes[1] = i2cdata_read[i2cdata_read_pos++];
checksum = i2cdata_read[i2cdata_read_pos++];
error = SHTC1_CheckCrc(bytes, 2, checksum);
*data = (bytes[0] << 8) | bytes[1];
return error;
}
static int SHTC1_CheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum)
{
uint8_t bit; // bit mask
uint8_t crc = 0xFF; // calculated checksum
uint8_t byteCtr; // byte counter
for(byteCtr = 0; byteCtr < nbrOfBytes; byteCtr++){
crc ^= (data[byteCtr]);
for(bit = 8; bit > 0; --bit){
if(crc & 0x80)
crc = (crc << 1) ^ POLYNOMIAL;
else
crc = (crc << 1);
}
}
if(crc != checksum)
return CHECKSUM_ERROR;
else
return NO_ERROR;
}
static void SHTC1_WriteCommand(uint16_t cmd)
{
int writebytes;
i2cdata_write[0] = (uint8_t)(cmd >>8);
i2cdata_write[1] = (uint8_t)(cmd&0xFF);
i2c_write((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, &i2cdata_write[0], 2, 1);
}
static float SHTC1_CalcTemperature(uint16_t rawValue)
{
return 175.0 * (float)rawValue / 65536.0 - 45.0;
}
static float SHTC1_CalcHumidity(uint16_t rawValue)
{
return 100.0 * (float)rawValue / 65536.0;
}
int SHTC_GetTempAndHumi(float *temp, float *humi)
{
int error;
uint16_t rawValueTemp;
uint16_t rawValueHumi;
SHTC1_WriteCommand(MEAS_T_RH_CLOCKSTR);
i2c_read((i2c_t*)&i2cmaster, MBED_I2C_SLAVE_ADDR0, (char*)&i2cdata_read[0], 6, 1);
i2cdata_read_pos = 0;
error = NO_ERROR;
error |= SHTC1_Read2BytesAndCrc(&rawValueTemp);
error |= SHTC1_Read2BytesAndCrc(&rawValueHumi);
if ( error == NO_ERROR ) {
*temp = SHTC1_CalcTemperature(rawValueTemp);
*humi = SHTC1_CalcHumidity(rawValueHumi);
}
return error;
}
static void example_shtc1_thread(void *param)
{
int error;
uint16_t shtc1_id;
float temperature = 1.123f;
float humidity = 2.456f;
DBG_8195A("sleep 10 sec. to wait for UART console\n");
rtw_msleep_os(10000);
DBG_8195A("start i2c example - SHTC1\n");
error = SHTC_Init(&shtc1_id);
if ( error == NO_ERROR )
DiagPrintf("SHTC1 init ok, id=0x%x\r\n", shtc1_id);
else {
DiagPrintf("SHTC1 init FAILED! \r\n");
for(;;);
}
while(1){
error = SHTC_GetTempAndHumi(&temperature, &humidity);
rtl_printf("temp=%f, humidity=%f, error=%d\n", temperature, humidity, error);
rtw_msleep_os(1000);
}
}
void example_shtc1(void)
{
if(xTaskCreate(example_shtc1_thread, ((const char*)"example_shtc1_thread"), 512, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate(init_thread) failed", __FUNCTION__);
}

View File

@@ -0,0 +1,13 @@
#ifndef SHTC1_H
#define SHTC1_H
#define NO_ERROR 0x00
#define ACK_ERROR 0x01
#define CHECKSUM_ERROR 0x02
#define NULL_ERROR 0x03
int SHTC_GetTempAndHumi(float *temp, float *humi);
int SHTC_Init(uint16_t *pID);
void example_shtc1(void);
#endif

View File

@@ -0,0 +1,732 @@
#include "FreeRTOS.h"
#include "task.h"
#include "wifi_conf.h"
#include "wifi_ind.h"
#include "sockets.h"
#include <mDNS/mDNS.h>
#include <lwip_netconf.h>
#include <lwip/netif.h>
#include "flash_api.h"
#include "encrypt.h"
#include "gpio_api.h"
#include "gpio_irq_api.h"
#include "cJSON.h"
#include "cloud_link.h"
#include "wigadget.h"
#include "shtc1.h"
#define PORT 6866
#define MAX_BUFFER_SIZE 256
#define ENC_SIZE 64
#define CONTROL_TYPE 1
#ifdef CONFIG_PLATFORM_8195A
#define GPIO_SOFTAP_RESET_PIN PC_4
#endif
#ifdef CONFIG_PLATFORM_8711B
#define GPIO_SOFTAP_RESET_PIN PA_0
#endif
flash_t iot_flash;
uint8_t aes_key[16];
static unsigned char tx_buffer[MAX_BUFFER_SIZE];
static unsigned char rx_buffer[MAX_BUFFER_SIZE];
extern struct netif xnetif[NET_IF_NUM];
#define DEBUG_IOT 1
#define IOT_LOG(level, fmt, ...) printf("\n\r[IOT %s] %s: " fmt "\n", level, __FUNCTION__, ##__VA_ARGS__)
#if DEBUG_IOT == 2
#define IOT_DEBUG(fmt, ...) IOT_LOG("DEBUG", fmt, ##__VA_ARGS__)
#else
#define IOT_DEBUG(fmt, ...)
#endif
#if DEBUG_IOT
#define IOT_ERROR(fmt, ...) IOT_LOG("ERROR", fmt, ##__VA_ARGS__)
#else
#define IOT_ERROR(fmt, ...)
#endif
void encrypt_data_aes(unsigned char *plaint_text, unsigned char *enc_data);
void decrypt_data_aes(unsigned char *enc_data, unsigned char *dec_data, int data_len);
static unsigned int arc4random(void)
{
unsigned int res = xTaskGetTickCount();
static unsigned int seed = 0xDEADB00B;
seed = ((seed & 0x007F00FF) << 7) ^
((seed & 0x0F80FF00) >> 8) ^ // be sure to stir those low bits
(res << 13) ^ (res >> 9); // using the clock too!
return seed;
}
static char *iot_itoa(int value)
{
char *val_str;
int tmp = value, len = 1;
while((tmp /= 10) > 0)
len ++;
val_str = (char *) malloc(len + 1);
sprintf(val_str, "%d", value);
return val_str;
}
void gen_json_data(char *i, char *j, unsigned char *json_data)
{
cJSON_Hooks memoryHook;
memoryHook.malloc_fn = malloc;
memoryHook.free_fn = free;
cJSON_InitHooks(&memoryHook);
memset(json_data, 0, ENC_SIZE);
cJSON *IOTJSObject = NULL;
char *data;
if((IOTJSObject = cJSON_CreateObject()) != NULL) {
cJSON_AddItemToObject(IOTJSObject, "TEM", cJSON_CreateString(i));
cJSON_AddItemToObject(IOTJSObject, "HUM", cJSON_CreateString(j));
data = cJSON_Print(IOTJSObject);
memcpy(json_data, data, strlen(data));
cJSON_Delete(IOTJSObject);
free(data);
}
}
void encrypt_data_aes(unsigned char *plaint_text, unsigned char *enc_data)
{
unsigned char iv[16] = {0};
unsigned char* iv_bak = "AAAAAAAAAAAAAAAA";
aes_encrypt_ctx enc_ctx;
memset(&enc_ctx, 0, sizeof(enc_ctx));
memset(iv, 0, sizeof(iv));
memcpy(iv, iv_bak, sizeof(iv));
memset(enc_data, 0, sizeof(enc_data));
aes_init();
aes_encrypt_key(aes_key, 16, &enc_ctx);
aes_cbc_encrypt(plaint_text, enc_data, ENC_SIZE, iv, &enc_ctx);
}
void decrypt_data_aes(unsigned char *enc_data, unsigned char *dec_data, int data_len)
{
unsigned char iv[16] = {0};
unsigned char* iv_bak = "AAAAAAAAAAAAAAAA";
aes_decrypt_ctx dec_ctx;
memset(&dec_ctx, 0, sizeof(dec_ctx));
memset(iv, 0, sizeof(iv));
memcpy(iv, iv_bak, sizeof(iv));
memset(dec_data, 0, sizeof(dec_data));
aes_init();
aes_decrypt_key(aes_key, 16, &dec_ctx);
aes_cbc_decrypt(enc_data, dec_data, data_len, iv, &dec_ctx);
IOT_DEBUG("Decrypt data: %s\r\n",dec_data);
}
void iotapp_platform_reset(void)
{
HAL_WRITE32(SYSTEM_CTRL_BASE, 0x14, 0x00000021);
osDelay(100);
HAL_WRITE32(0xE000ED00, 0x0C, (0x5FA << 16) |
(HAL_READ32(0xE000ED00, 0x0C) & (7 << 8)) |
(1 << 2));
while(1) osDelay(1000);
}
void iotapp_reset_irq_handler(uint32_t id, gpio_irq_event event)
{
printf("\n\r\n\r\n\r\n\r<<<<<<Reset the device>>>>>>>\n\r\n\r\n\r\n\r");
flash_erase_sector(&iot_flash, FLASH_IOT_DATA);
iotapp_platform_reset();
}
int local_link(unsigned char *tx_data)
{
int sockfd, newsockfd;
socklen_t client;
struct sockaddr_in serv_addr, cli_addr;
uint8_t rx_data[ENC_SIZE];
unsigned char enc_data[ENC_SIZE];
unsigned char dec_data[ENC_SIZE];
int ret = 0, opt = 1, k = 1, j;
char *result = NULL, *backup = NULL;
unsigned char *data = NULL;
char *delims = ", ";
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
IOT_ERROR("ERROR opening socket");
ret = -1;
goto exit2;
}
if((setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt))) < 0){
IOT_ERROR("ERROR on setting socket option");
ret = -1;
goto exit2;
}
memset((char *)&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(PORT);
if (bind(sockfd, (struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) {
IOT_ERROR("ERROR on binding");
ret = -1;
goto exit2;
}
if(listen(sockfd , 20) < 0){
IOT_ERROR("ERROR on listening");
ret = -1;
goto exit2;
}
client = sizeof(cli_addr);
if((newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr,&client)) < 0){
IOT_ERROR("ERROR on accept");
ret = -1;
goto exit;
}
if ((ret = read(newsockfd,rx_buffer,sizeof(rx_buffer))) < 0){
IOT_ERROR("ERROR reading from socket");
ret = -1;
goto exit;
}
IOT_DEBUG("cmd received: %s, length: %d\r\n",rx_buffer, ret);
//Changing received data to string
if (!strncmp(rx_buffer, "[", strlen("["))){
data = rx_buffer + strlen("[");
for(j = 1; j < 5; j++){
if (data[ret - j] == ']')
data[ret -j] = '\0';
}
}
else
strcpy(data, rx_buffer);
memset(rx_data, 0, sizeof(rx_data));
result = strtok_r(data, delims, &backup);
rx_data[0]=(uint8_t)atoi(result);
while((result = strtok_r(NULL, delims, &backup)) != NULL)
rx_data[k++]=(uint8_t)atoi(result);
memset(dec_data, 0, sizeof(dec_data));
//Decrpyt the received data
decrypt_data_aes(rx_data, dec_data, 16);
if(strncmp(dec_data, "request", strlen("request")) == 0){
//Encrypt the sending data
memset(enc_data, 0, strlen(enc_data));
encrypt_data_aes(tx_data, enc_data);
//Changing encrpyt data to JAVA type string
for (j = 0; j < ENC_SIZE; j++){
char *temp;
temp = iot_itoa(enc_data[j]);
if(j == 0)
strcpy(tx_buffer, "[");
strcat(tx_buffer,temp);
if (j == (ENC_SIZE - 1))
strcat(tx_buffer,"]");
else
strcat(tx_buffer,",");
free(temp);
temp = NULL;
}
IOT_DEBUG("Data reply to APP: %s\r\nLength of data: %d\r\n", tx_buffer, strlen(tx_buffer));
if ((ret = write(newsockfd,tx_buffer,strlen(tx_buffer))) < 0){
IOT_ERROR("ERROR writing to socket");
ret = -1;
goto exit;
}
else
IOT_DEBUG("Sending %d bytes data OK!\r\n", ret);
}
else if(strncmp(dec_data, "remove", strlen("remove")) == 0){
printf("\n\r\n\r\n\r\n\r<<<<<<Reset the device >>>>>>>\n\r\n\r\n\r\n\r");
flash_erase_sector(&iot_flash, FLASH_IOT_DATA);
write(newsockfd,"Remove OK",strlen("Remove OK"));
close(newsockfd);
close(sockfd);
iotapp_platform_reset();
}
else{
IOT_ERROR("ERROR wrong KEY or wrong request!");
write(newsockfd,"The KEY or the request is not correct!",strlen("The KEY or the request is not correct!"));
ret = -1;
goto exit;
}
exit:
if(close(newsockfd) != 0)
goto exit;
exit2:
if(close(sockfd) != 0)
goto exit2;
return ret;
}
static void local_link_task(void *param)
{
unsigned char data[ENC_SIZE] = {0};
vTaskDelay(1000);
char i[16], j[16];
float temperature = 1.123f;
float humidity = 2.456f;
int ret = 0;
while(1){
memset(i, 0, 16);
memset(j, 0, 16);
#if PSEUDO_DATA
sprintf(i,"%.2f", temperature++);
sprintf(j, "%.2f", humidity++);
if(temperature > 60)
temperature = 1.123f;
if(humidity > 98)
humidity = 2.456f;
#else
ret = SHTC_GetTempAndHumi(&temperature, &humidity);
sprintf(i,"%.2f", temperature);
sprintf(j, "%.2f", humidity);
#endif
if(ret < 0)
printf("\r\n\r\n<-----LOCAL LINK FAILED!!(get infor failed)\r\n\r\n");
else{
printf("\r\n\r\n----->START LOCAL LINKING\r\n\r\n");
gen_json_data(i, j, data);
printf("Sending data : %s\r\n", data);
if (local_link(data) < 0)
printf("\r\n\r\n<-----LOCAL LINK FAILED!!\r\n\r\n");
else
printf("\r\n\r\n<-----LOCAL LINK OK!!\r\n\r\n");
vTaskDelay(1000);
}
}
}
void start_local_link(void)
{
if(xTaskCreate(local_link_task, ((const char*)"local_link_task"), 5376, NULL, tskIDLE_PRIORITY + 4, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
}
int pair_device(unsigned char *tx_buffer, unsigned char *rx_buffer, int handshake)
{
int sockfd, newsockfd;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
int ret = 0;
int opt = 1;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
IOT_ERROR("ERROR opening socket");
ret = -1;
goto exit;
}
if((setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt))) < 0){
IOT_ERROR("ERROR on setting socket option");
ret = -1;
goto exit;
}
memset((char *)&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_len = sizeof(serv_addr);
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(PORT);
if ((bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))) < 0) {
IOT_ERROR("ERROR on binding");
ret = -1;
goto exit;
}
if ((listen(sockfd, 5)) < 0){
IOT_ERROR("ERROR on listening tcp server socket fd");
ret = -1;
goto exit;
}
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t*)&clilen);
if (newsockfd < 0) {
IOT_ERROR("ERROR on accept");
ret = -1;
goto exit2;
}
ret = read(newsockfd, rx_buffer, MAX_BUFFER_SIZE);
if (ret <= 0){
IOT_ERROR("ERROR reading from socket");
ret = -1;
goto exit2;
}
IOT_DEBUG("Request received: %s, byte: %d\r\n",rx_buffer, ret);
if(handshake == 1){
if(strncmp(rx_buffer,"PAIR", strlen("PAIR")) != 0){
write(newsockfd, "ERROR", strlen("ERROR"));
IOT_ERROR("ERROR on first handshake!");
ret = -1;
goto exit2;
}
}
else if(handshake == 2){
if((rx_buffer == NULL) ||(strlen(rx_buffer) < 32)){
write(newsockfd, "ERROR", strlen("ERROR"));
IOT_ERROR("ERROR on second handshake!");
ret = -1;
goto exit2;
}
}
else if(handshake == 3){
unsigned char account[64];
unsigned char enc_acc[64];
char *result = NULL, *backup = NULL;
unsigned char *data = NULL;
char *delims = ", ";
int j, k = 1;
if (!strncmp(rx_buffer, "[", strlen("["))){
data = rx_buffer + strlen("[");
for(j = 1; j < 5; j++){
if (data[ret - j] == ']')
data[ret -j] = '\0';
}
}
else
strcpy(data, rx_buffer);
memset(enc_acc, 0, sizeof(enc_acc));
result = strtok_r(data, delims, &backup);
enc_acc[0]=(uint8_t)atoi(result);
while((result = strtok_r(NULL, delims, &backup)) != NULL)
enc_acc[k++]=(uint8_t)atoi(result);
IOT_DEBUG("The value of k: %d", k);
memset(account, 0, sizeof(account));
decrypt_data_aes(enc_acc, account, k);
if((strncmp(account,"https://", strlen("https://"))) != 0){
write(newsockfd, "ERROR", strlen("ERROR"));
IOT_ERROR("ERROR on third handshake!");
ret = -1;
goto exit2;
}
else{
IOT_DEBUG("The received Firebase URL:%s", account);
memset(rx_buffer, 0, strlen(rx_buffer));
memcpy(rx_buffer, (account+strlen("https://")), (strlen(account) + strlen("https://")));
}
}
ret = write(newsockfd, tx_buffer, strlen(tx_buffer));
IOT_DEBUG("Data send: %s\r\n",tx_buffer);
if (ret < 0){
IOT_ERROR("ERROR writing to socket");
}
exit:
if(close(newsockfd) != 0)
goto exit;
exit2:
if(close(sockfd) != 0)
goto exit2;
return ret;
}
static void pair_device_task(void)
{
int i, j, k, HANDSHAKE;
uint8_t PAIR_STATE[1] = {0};
if(CONTROL_TYPE == 1){
printf("\r\n\r\n<<<<<<CONTROL_TYPE = 1 Need 3 times handshake>>>>>>\r\n\r\n");
HANDSHAKE = 3;
}
else{
printf("\r\n\r\n<<<<<<CONTROL_TYPE = 0 Need 2 times handshake>>>>>>\r\n\r\n");
HANDSHAKE = 2;
}
printf("\r\n\r\n=========>PAIR_STATE = 0 Start to pair\r\n\r\n");
for(i = 0; i < HANDSHAKE; i++){
static const uint8_t basepoint[32] = {9};
uint8_t mysecret[32];
uint8_t mypublic[32];
uint8_t theirpublic[32] = {0};
uint8_t shared_key[32];
//First handshake
if(i == 0){
printf("\r\n\r\n===>Start the first handshake\r\n\r\n");
memset(tx_buffer, 0, sizeof(tx_buffer));
memset(rx_buffer, 0, sizeof(rx_buffer));
for(j = 0; j < 32; j ++)
mysecret[j] = (uint8_t) arc4random();
mysecret[j] = '\0';
curve25519_donna(mypublic, mysecret, basepoint);
for (j = 0; j < 32; j++){
char *temp;
temp = iot_itoa(mypublic[j]);
if(j == 0)
strcpy(tx_buffer, "[");
strcat(tx_buffer,temp);
if (j == 31)
strcat(tx_buffer,"]");
else
strcat(tx_buffer,",");
free(temp);
temp = NULL;
}
if(pair_device(tx_buffer, rx_buffer, 1) >= 0)
printf("\r\n\r\n<===First handshake OK!!\r\n\r\n");
else{
i--;
printf("\r\n\r\n<===First handshake FAILED!!\r\n\r\n");
}
}
//Second handshake
if(i == 1){
printf("\r\n\r\n=====>Start the second handshake\r\n\r\n");
vTaskDelay(200);
memset(tx_buffer, 0, sizeof(tx_buffer));
if(CONTROL_TYPE == 1)
memcpy(tx_buffer, "FIREBASE URL", sizeof("FIREBASE URL"));
else
memcpy(tx_buffer, "PAIR OK", sizeof("PAIR OK"));
memset(rx_buffer, 0, sizeof(rx_buffer));
if(pair_device(tx_buffer, rx_buffer, 2) >= 0){
char *result = NULL, *backup = NULL;
unsigned char *data = NULL;
char *delims = ", ";
k = 1;
if (!strncmp(rx_buffer, "[", strlen("["))){
data = rx_buffer + strlen("[");
int len;
len = strlen(data);
for(j = 1; j < 5; j++){
if (data[len - j] == ']')
data[len -j] = '\0';
}
}
else
strcpy(data, rx_buffer);
memset(theirpublic, 0, sizeof(theirpublic));
result = strtok_r(data, delims, &backup);
theirpublic[0]=(uint8_t)atoi(result);
while((result = strtok_r(NULL, delims, &backup)) != NULL)
theirpublic[k++] = (uint8_t)atoi(result);
curve25519_donna(shared_key, mysecret, theirpublic);
for(j = 0; j < 16; j ++)
aes_key[j] = shared_key[j];
//Store the KEY in FLASH
if(CONTROL_TYPE == 0){
PAIR_STATE[0] = 1;
uint8_t data[33];
memset(data, 0, 33);
memcpy(data, PAIR_STATE, 1);
memcpy(data+1, shared_key, 32);
flash_erase_sector(&iot_flash, FLASH_IOT_DATA);
flash_stream_write(&iot_flash, FLASH_IOT_DATA, 33, (uint8_t *) data);
IOT_DEBUG("PAIR_STATE: %d\r\n", PAIR_STATE[0]);
}
printf("\r\n\r\n<=====Second handshake OK!!\r\n\r\n");
}
else{
i = i - 2;
printf("\r\n\r\n<=====Second handshake FAILED!!\r\n\r\n");
}
}
//Third handshake
if(i == 2){
printf("\r\n\r\n=======>Start the third handshake\r\n\r\n");
vTaskDelay(200);
memset(tx_buffer, 0, sizeof(tx_buffer));
memcpy(tx_buffer, "PAIR OK", sizeof("PAIR OK"));
memset(rx_buffer, 0, sizeof(rx_buffer));
if(pair_device(tx_buffer, rx_buffer, 3) >= 0){
IOT_DEBUG("rx_buffer: %s, sizeof rx_buffer:%d\r\n", rx_buffer, sizeof(rx_buffer));
PAIR_STATE[0] = 1;
uint8_t data[97];
memset(data, 0, 97);
memcpy(data, PAIR_STATE, 1);
memcpy(data+1, shared_key, 32);
memcpy(data+33, rx_buffer, 64);
flash_erase_sector(&iot_flash, FLASH_IOT_DATA);
flash_stream_write(&iot_flash, FLASH_IOT_DATA, 97, (uint8_t *) data);
IOT_DEBUG("PAIR_STATE: %d\r\n", PAIR_STATE[0]);
printf("\r\n\r\n<=======Third handshake OK!!\r\n\r\n");
}
else{
i = i - 3;
printf("\r\n\r\n<=======Third handshake FAILED!!\r\n\r\n");
}
}
}
printf("\r\n\r\n<=========Pairing OK!!\r\n\r\n");
}
static void mdns_task(void *param)
{
DNSServiceRef dnsServiceRef = NULL;
TXTRecordRef txtRecord;
unsigned char txt_buf[128];
uint8_t *mac, *ip;
int j, ret = 0;
uint8_t *flash_data;
uint8_t PAIR_STATE[1] = {0};
static unsigned char MAC_ADD[21];
static unsigned char IP[16];
static unsigned char port[6];
uint16_t shtc1_id;
// Delay to wait for IP by DHCP and get the information of IP and MAC
printf("\n\r\n\r\n\r\n\r<<<<<<Waiting for 20 seconds to connect Wi-Fi>>>>>>>\n\r\n\r\n\r\n\r");
vTaskDelay(20000);
ip = LwIP_GetIP(&xnetif[0]);
mac = LwIP_GetMAC(&xnetif[0]);
sprintf(MAC_ADD, "%02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
sprintf(IP, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
sprintf(port, "%d", PORT);
IOT_DEBUG("MAC => %s\r\n", MAC_ADD) ;
IOT_DEBUG("IP => %s\r\n", IP);
IOT_DEBUG("PORT => %s\r\n", port);
//Get the value of PAIR_STATE and the AES key in flash
flash_data = (uint8_t *)malloc(33);
flash_stream_read(&iot_flash, FLASH_IOT_DATA, 33, (uint8_t *)flash_data);
memcpy(PAIR_STATE, flash_data, 1);
if(PAIR_STATE[0] != 0x1)
PAIR_STATE[0] = 0;
else{
for(j = 0;j < 16; j++){
aes_key[j] = flash_data[j+1];
}
}
free(flash_data);
IOT_DEBUG("PAIR_STATE now: %d\r\n", PAIR_STATE[0]);
IOT_DEBUG("=>mDNS Init\r\n");
if(mDNSResponderInit() == 0) {
printf("\r\n\r\n========>Start to register mDNS service\r\n\r\n");
//The device not paired before
if(PAIR_STATE[0] == 0){
TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf);
TXTRecordSetValue(&txtRecord, "IP", strlen(IP), IP);
TXTRecordSetValue(&txtRecord, "PORT", strlen(port), port);
TXTRecordSetValue(&txtRecord, "MAC_ADDR", strlen(MAC_ADD), MAC_ADD);
TXTRecordSetValue(&txtRecord, "PAIR_STATE", strlen("0"), "0");
TXTRecordSetValue(&txtRecord, "SERVICE_NAME", strlen("ht_sensor"), "ht_sensor");
if(CONTROL_TYPE == 1)
TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("1"), "1");
else
TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("0"), "0");
dnsServiceRef = mDNSRegisterService("ht_sensor", "_Ameba._tcp", "local", PORT, &txtRecord);
TXTRecordDeallocate(&txtRecord);
printf("\r\n\r\n<========Registering mDNS service OK!!\r\n\r\n");
pair_device_task();
}
//The device was paired
else if(PAIR_STATE[0] == 0x1){
TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf);
TXTRecordSetValue(&txtRecord, "IP", strlen(ip), ip);
TXTRecordSetValue(&txtRecord, "PORT", strlen(port), port);
TXTRecordSetValue(&txtRecord, "MAC_ADDR", strlen(MAC_ADD), MAC_ADD);
TXTRecordSetValue(&txtRecord, "PAIR_STATE", strlen("1"), "1");
TXTRecordSetValue(&txtRecord, "SERVICE_NAME", strlen("ht_sensor"), "ht_sensor");
if(CONTROL_TYPE == 1)
TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("1"), "1");
else
TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("0"), "0");
dnsServiceRef = mDNSRegisterService("ht_sensor", "_Ameba._tcp", "local", PORT, &txtRecord);
TXTRecordDeallocate(&txtRecord);
printf("\r\n\r\n<========Registering mDNS service OK!! PAIR_STATE = 1\r\n\r\n");
}
#if PSEUDO_DATA
printf("\r\n\r\n========>Using the speudo data\r\n\r\n");
if(CONTROL_TYPE == 1) start_cloud_link();
start_local_link();
#else
//Init the shtc1 sensor
printf("\r\n\r\n========>Init the temperature and humidity sensor\r\n\r\n");
ret = SHTC_Init(&shtc1_id);
if ( ret == NO_ERROR ){
printf("\r\n\r\n<========Senser init OK! ID = 0x%x \r\n\r\n", shtc1_id);
if(CONTROL_TYPE == 1) start_cloud_link();
start_local_link();
}
else {
printf("\r\n\r\n<========Senser init FAILED! ID = 0x%x \r\n\r\n", shtc1_id);
ret = -1;
}
#endif
}
else
ret = -1;
if(ret == 0){
while(1){
IOT_DEBUG("Update the mDNS textrecord!\r\n");
TXTRecordCreate(&txtRecord, sizeof(txt_buf), txt_buf);
TXTRecordSetValue(&txtRecord, "IP", strlen(IP), IP);
TXTRecordSetValue(&txtRecord, "PORT", strlen(port), port);
TXTRecordSetValue(&txtRecord, "MAC_ADDR", strlen(MAC_ADD), MAC_ADD);
TXTRecordSetValue(&txtRecord, "PAIR_STATE", strlen("1"), "1");
if(CONTROL_TYPE == 1)
TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("1"), "1");
else
TXTRecordSetValue(&txtRecord, "CONTROL_TYPE", strlen("0"), "0");
TXTRecordSetValue(&txtRecord, "SERVICE_NAME", strlen("ht_sensor"), "ht_sensor");
mDNSUpdateService(dnsServiceRef, &txtRecord, 0);
TXTRecordDeallocate(&txtRecord);
vTaskDelay(2*60*1000);
}
}
else{
if(dnsServiceRef)
mDNSDeregisterService(dnsServiceRef);
IOT_DEBUG("<=mDNS Deinit\r\n\r\n");
mDNSResponderDeinit();
}
}
void example_wigadget(void)
{
if(xTaskCreate(mdns_task, ((const char*)"mdns_task"), 3072, NULL, tskIDLE_PRIORITY + 1, NULL) != pdPASS)
printf("\n\r%s xTaskCreate failed", __FUNCTION__);
gpio_t gpio_softap_reset_button;
gpio_irq_t gpioirq_softap_reset_button;
gpio_irq_init(&gpioirq_softap_reset_button, GPIO_SOFTAP_RESET_PIN, iotapp_reset_irq_handler, (uint32_t)(&gpio_softap_reset_button));
gpio_irq_set(&gpioirq_softap_reset_button, IRQ_FALL, 1);
gpio_irq_enable(&gpioirq_softap_reset_button);
}

View File

@@ -0,0 +1,11 @@
#ifndef WIGADGET_H
#define WIGADGET_H
#define FLASH_IOT_DATA (0x0007E000)
#define PSEUDO_DATA 1
void example_wigadget(void);
void gen_json_data(char *i, char *j, unsigned char *json_data);
#endif /* WIGADGET_H */

View File

@@ -0,0 +1,728 @@
/********************************************************************************
* Copyright (c) 2014, Realtek Semiconductor Corp.
* All rights reserved.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*******************************************************************************
*/
#if !defined(CONFIG_PLATFORM_8711B)
#include "xmport_uart.h"
#include "xmport_loguart.h"
#include "rtl8195a.h"
#include "xmodem.h"
#include "hal_spi_flash.h"
#include "rtl8195a_spi_flash.h"
#include <platform/platform_stdlib.h>
enum {
XMODEM_UART_0 = 0,
XMODEM_UART_1 = 1,
XMODEM_UART_2 = 2,
XMODEM_LOG_UART = 3
};
FWU_DATA_SECTION char xMFrameBuf[XM_BUFFER_SIZE];
FWU_DATA_SECTION XMODEM_CTRL xMCtrl;
FWU_DATA_SECTION static u32 fw_img1_size;
FWU_DATA_SECTION static u32 fw_img2_size;
FWU_DATA_SECTION static u32 fw_img2_addr;
FWU_DATA_SECTION static u32 fw_img3_size;
FWU_DATA_SECTION static u32 fw_img3_addr;
FWU_DATA_SECTION static u32 flash_wr_offset;
FWU_DATA_SECTION static u32 flash_erased_addr;
FWU_DATA_SECTION static u8 start_with_img1;
FWU_DATA_SECTION static u32 flash_wr_err_cnt;
FWU_DATA_SECTION HAL_RUART_ADAPTER xmodem_uart_adp; // we can dynamic allocate memory for this object to save memory
static union { uint32_t u; unsigned char c[4]; } file_checksum;
static u32 updated_img2_size = 0;
static u32 default_img2_addr = 0;
FWU_RODATA_SECTION const char Img2Signature[8]="81958711";
extern u32 SpicCalibrationPattern[4];
extern const u8 ROM_IMG1_VALID_PATTEN[];
extern HAL_RUART_ADAPTER *pxmodem_uart_adp;
#ifdef CONFIG_GPIO_EN
extern HAL_GPIO_ADAPTER gBoot_Gpio_Adapter;
extern PHAL_GPIO_ADAPTER _pHAL_Gpio_Adapter;
#endif
void xDelayUs(u32 us)
{
HalDelayUs(us);
}
extern BOOLEAN SpicFlashInitRtl8195A(u8 SpicBitMode);
_LONG_CALL_
extern VOID SpicWaitBusyDoneRtl8195A(VOID);
extern VOID SpicWaitWipDoneRefinedRtl8195A(SPIC_INIT_PARA SpicInitPara);
FWU_TEXT_SECTION void FWU_WriteWord(u32 Addr, u32 FData)
{
SPIC_INIT_PARA SpicInitPara = {0};
HAL_WRITE32(SPI_FLASH_BASE, Addr, FData);
// Wait spic busy done
SpicWaitBusyDoneRtl8195A();
// Wait flash busy done (wip=0)
SpicWaitWipDoneRefinedRtl8195A(SpicInitPara);
}
FWU_TEXT_SECTION u32 xModem_MemCmp(const u32 *av, const u32 *bv, u32 len)
{
const u32 *a = av;
const u32 *b = (u32*)((u8*)bv+SPI_FLASH_BASE);
u32 len4b = len >> 2;
u32 i;
for (i=0; i<len4b; i++) {
if (a[i] != b[i]) {
DBG_MISC_ERR("OTU: Flash write check error @ 0x%08x\r\n", (u32)(&b[i]));
return ((u32)(&b[i]));
}
}
return 0;
}
FWU_TEXT_SECTION
u32 xModem_Frame_Img2(char *ptr, uint32_t frame_num, uint32_t frame_size)
{
u32 address;
u32 ImageIndex=0;
u32 rx_len=0;
u32 *chk_sr;
u32 *chk_dr;
u32 err_addr;
if (frame_num == 1) {
// Parse Image2 header
memset(&file_checksum, 0, sizeof(file_checksum));
flash_wr_offset = fw_img2_addr;
fw_img2_size = rtk_le32_to_cpu(*((u32*)ptr)) + 0x14;
if ((fw_img2_size & 0x03) != 0) {
DBG_MISC_ERR("xModem_Frame_ImgAll Err#2: fw_img2_addr=0x%x fw_img2_size(%d) isn't 4-bytes aligned\r\n", fw_img2_addr, fw_img2_size);
fw_img1_size = 0;
fw_img2_size = 0;
return rx_len;
}
if (fw_img2_size > (2*1024*1024)) {
DBG_MISC_ERR("xModem_Frame_ImgAll Image2 to Big: fw_img2_addr=0x%x fw_img2_size(%d) \r\n", fw_img2_addr, fw_img2_size);
fw_img1_size = 0;
fw_img2_size = 0;
return rx_len;
}
fw_img3_addr = fw_img2_addr + fw_img2_size;
updated_img2_size = fw_img2_size;
// erase Flash first
address = fw_img2_addr & (~0xfff); // 4k aligned, 4k is the page size of flash memory
while ((address) < (fw_img2_addr+fw_img2_size)) {
SpicSectorEraseFlashRtl8195A(SPI_FLASH_BASE + address);
address += 0x1000;
}
flash_erased_addr = address;
}
if (fw_img2_size > 0) {
// writing image2
chk_sr = (u32*)((u8*)ptr+ImageIndex);
chk_dr = (u32*)flash_wr_offset;
while (ImageIndex < frame_size) {
FWU_WriteWord(flash_wr_offset, (*((u32*)(ptr+ImageIndex))));
ImageIndex += 4;
flash_wr_offset += 4;
rx_len += 4;
fw_img2_size -= 4;
if (fw_img2_size == 0) {
// Image2 write done,
break;
}
}
err_addr = xModem_MemCmp(chk_sr, chk_dr, (flash_wr_offset - (u32)chk_dr));
if (err_addr) {
flash_wr_err_cnt++;
}
}
// checksum attached at file end
file_checksum.c[0] = ptr[rx_len - 4];
file_checksum.c[1] = ptr[rx_len - 3];
file_checksum.c[2] = ptr[rx_len - 2];
file_checksum.c[3] = ptr[rx_len - 1];
return rx_len;
}
FWU_TEXT_SECTION
s32
xModem_Init_UART_Port(u8 uart_idx, u8 pin_mux, u32 baud_rate)
{
if (uart_idx <= XMODEM_UART_2) {
// update firmware via generic UART
pxmodem_uart_adp = &xmodem_uart_adp; // we can use dynamic allocate to save memory
xmodem_uart_init(uart_idx, pin_mux, baud_rate);
xmodem_uart_func_hook(&(xMCtrl.ComPort));
} else if(uart_idx == XMODEM_LOG_UART) {
// update firmware via Log UART
xmodem_loguart_init(baud_rate);
xmodem_loguart_func_hook(&(xMCtrl.ComPort));
} else {
// invalid UART port
DBG_MISC_ERR("xModem_Init_UART_Port: Invaild UART port(%d)\n", uart_idx);
return -1;
}
return 0;
}
FWU_TEXT_SECTION
VOID
xModem_DeInit_UART_Port(u8 uart_idx)
{
if (uart_idx <= XMODEM_UART_2) {
xmodem_uart_deinit();
} else if (uart_idx == XMODEM_LOG_UART) {
xmodem_loguart_deinit();
}
}
FWU_TEXT_SECTION
__weak s32
UpdatedImg2AddrValidate(
u32 Image2Addr,
u32 DefImage2Addr,
u32 DefImage2Size
)
{
if (Image2Addr == 0xffffffff) {
// Upgraded Image2 isn't exist
return 0; // invalid address
}
if ((Image2Addr & 0xfff) != 0) {
// Not 4K aligned
return 0; // invalid address
}
if (Image2Addr <= DefImage2Addr) {
// Updated image2 address must bigger than the addrss of default image2
return 0; // invalid address
}
if (Image2Addr < (DefImage2Addr+DefImage2Size)) {
// Updated image2 overlap with the default image2
return 0; // invalid address
}
return 1; // this address is valid
}
FWU_TEXT_SECTION
VOID
WriteImg2Sign(
u32 Image2Addr
)
{
u32 img2_sig[2];
_memcpy((void*)img2_sig, (void*)Img2Signature, 8);
FWU_WriteWord((Image2Addr + 8), img2_sig[0]);
FWU_WriteWord((Image2Addr + 12), img2_sig[1]);
// set the default imag2's signature to old
if(default_img2_addr != Image2Addr)
{
printf("set the signature of default img2 to old\n");
FWU_WriteWord((default_img2_addr + 8), 0x35393130);
FWU_WriteWord((default_img2_addr + 12), 0x31313738);
}
}
static void xmodem_write_ota_addr_to_system_data(u32 newImg2Addr)
{
FWU_WriteWord(FLASH_SYSTEM_DATA_ADDR, newImg2Addr);
return;
}
FWU_TEXT_SECTION
u32
SelectImg2ToUpdate(
u32 *OldImg2Addr
)
{
u32 DefImage2Addr=0xFFFFFFFF; // the default Image2 addr.
u32 SecImage2Addr=0xFFFFFFFF; // the 2nd image2 addr.
u32 ATSCAddr=0xFFFFFFFF;
u32 UpdImage2Addr; // the addr of the image2 to be updated
u32 DefImage2Len;
*OldImg2Addr = 0;
DefImage2Addr = (HAL_READ32(SPI_FLASH_BASE, 0x18)&0xFFFF) * 1024;
if ((DefImage2Addr != 0) && ((DefImage2Addr < (16*1024*1024)))) {
// Valid Default Image2 Addr: != 0 & located in 16M
DefImage2Len = HAL_READ32(SPI_FLASH_BASE, DefImage2Addr);
default_img2_addr = DefImage2Addr;
// Get the pointer of the upgraded Image2
SecImage2Addr = HAL_READ32(SPI_FLASH_BASE, FLASH_SYSTEM_DATA_ADDR);
if (UpdatedImg2AddrValidate(SecImage2Addr, DefImage2Addr, DefImage2Len)) {
UpdImage2Addr = SecImage2Addr; // Update the 2nd image2
} else {
// The upgraded image2 isn't exist or invalid so we can just update the default image2
//UpdImage2Addr = DefImage2Addr; // Update the default image2
UpdImage2Addr = 0x80000; // Update to a predefined address
}
} else {
UpdImage2Addr = 0;
}
xmodem_write_ota_addr_to_system_data(UpdImage2Addr);
return UpdImage2Addr;
}
static uint32_t xmodem_get_flash_checksum()
{
uint32_t flash_checksum = 0;
if(updated_img2_size == 0)
{
printf("img2 size is wrong\n");
return 0;
}
for(int i = 0; i < updated_img2_size - 4; i++)
flash_checksum += HAL_READ8(SPI_FLASH_BASE, fw_img2_addr + i);
return flash_checksum;
}
FWU_TEXT_SECTION
void OTU_FW_Update(u8 uart_idx, u8 pin_mux, u32 baud_rate)
{
u32 wr_len;
u32 OldImage2Addr=0; // the addr of the image2 will become old one
SPIC_INIT_PARA SpicInitPara = {0};
fw_img1_size = 0;
fw_img2_size = 0;
fw_img2_addr = 0;
fw_img3_size = 0;
fw_img3_addr = 0;
flash_wr_offset = 0;
flash_erased_addr = 0;
start_with_img1 = 0;;
flash_wr_err_cnt = 0;
u32 flash_checksum = 0;
// Get the address of the image2 to be updated
SPI_FLASH_PIN_FCTRL(ON);
if (!SpicFlashInitRtl8195A(SpicOneBitMode)){
SPI_FLASH_PIN_FCTRL(OFF);
DBG_MISC_ERR("OTU_FW_Update: SPI Init Fail!!!!!!\n");
return;
}
SpicWaitWipDoneRefinedRtl8195A(SpicInitPara);
printf("FW Update Over UART%d, PinMux=%d, Baud=%d\r\n", uart_idx, pin_mux, baud_rate);
fw_img2_addr = SelectImg2ToUpdate(&OldImage2Addr);
// Start to update the Image2 through xModem on peripheral device
printf("FW Update Image2 @ 0x%x\r\n", fw_img2_addr);
// We update the image via xModem on UART now, if we want to uase other peripheral device
// to update the image then we need to redefine the API
if (xModem_Init_UART_Port(uart_idx, pin_mux, baud_rate) < 0) {
return;
}
xModemStart(&xMCtrl, xMFrameBuf, xModem_Frame_Img2); // Support Image format: Image2 only
wr_len = xModemRxBuffer(&xMCtrl, (2*1024*1024));
xModemEnd(&xMCtrl);
xModem_DeInit_UART_Port(uart_idx);
// add checksum check
flash_checksum = xmodem_get_flash_checksum();
printf("flash_checksum: %x file_checksum: %x\n", flash_checksum, file_checksum.u);
if(flash_checksum != file_checksum.u)
printf("checksum error, please retry to update\n");
else
{
if ((wr_len > 0) && (flash_wr_err_cnt == 0)) {
// Firmware update OK, now write the signature to active this image
WriteImg2Sign(fw_img2_addr);
}
else
printf("error in writen to flash");
}
printf("OTU_FW_Update Done, Write Len=%d\n", wr_len);
SPI_FLASH_PIN_FCTRL(OFF);
}
#else
#include "xmodem.h"
#include "xmport_uart.h"
#include <platform/platform_stdlib.h>
#include "flash_api.h"
#include "device_lock.h"
char xMFrameBuf[XM_BUFFER_SIZE];
XMODEM_CTRL _xMCtrl;
extern const update_file_img_id OtaImgId[2];
static update_ota_target_hdr OtaTargetHdr;
static u32 fw_img2_addr;
static u32 flash_wr_err_cnt;
static int SigCnt;
static u8 signature[9];
static update_dw_info DownloadInfo[2];
static int ImageCnt;
static u32 OtaFg;
static s32 RemainBytes;
static u32 i;
static u32 TempLen;
static s32 OtaImgSize;
static int size;
void xDelayUs(u32 us)
{
DelayUs(us);
}
void xmodem_uart_func_hook(XMODEM_COM_PORT *pXComPort)
{
pXComPort->poll = (char(*)(void))xmodem_uart_readable;
pXComPort->put = xmodem_uart_putc;
pXComPort->get = (char(*)(void))xmodem_uart_getc;
}
s32
xModem_Init_UART_Port(u8 uart_idx, u8 pin_mux, u32 baud_rate)
{
xmodem_uart_init(uart_idx, pin_mux, baud_rate);
xmodem_uart_func_hook(&(_xMCtrl.ComPort));
return 0;
}
VOID
xModem_DeInit_UART_Port(u8 uart_idx)
{
xmodem_uart_deinit();
}
int GetDownloadInfo(u32 addr, update_ota_target_hdr * pOtaTgtHdr)
{
u32 ImageCnt;
/*init download information buffer*/
memset((u8 *)&DownloadInfo, 0, 2*sizeof(update_dw_info));
/*arrange OTA/RDP image download information*/
if(pOtaTgtHdr->RdpStatus == ENABLE) {
ImageCnt = 2;
if(pOtaTgtHdr->FileImgHdr.Offset < pOtaTgtHdr->FileRdpHdr.Offset) {
DownloadInfo[0].ImgId = OTA_IMAG;
/* get OTA image and Write New Image to flash, skip the signature,
not write signature first for power down protection*/
DownloadInfo[0].FlashAddr = addr -SPI_FLASH_BASE + 8;
DownloadInfo[0].ImageLen = pOtaTgtHdr->FileImgHdr.ImgLen - 8;/*skip the signature*/
DownloadInfo[0].ImgOffset = pOtaTgtHdr->FileImgHdr.Offset;
DownloadInfo[1].ImgId = RDP_IMAG;
DownloadInfo[1].FlashAddr = RDP_FLASH_ADDR - SPI_FLASH_BASE;
DownloadInfo[1].ImageLen = pOtaTgtHdr->FileRdpHdr.ImgLen;
DownloadInfo[1].ImgOffset = pOtaTgtHdr->FileRdpHdr.Offset;
} else {
DownloadInfo[0].ImgId = RDP_IMAG;
DownloadInfo[0].FlashAddr = RDP_FLASH_ADDR - SPI_FLASH_BASE;
DownloadInfo[0].ImageLen = pOtaTgtHdr->FileRdpHdr.ImgLen;
DownloadInfo[0].ImgOffset = pOtaTgtHdr->FileRdpHdr.Offset;
DownloadInfo[1].ImgId = OTA_IMAG;
/* get OTA image and Write New Image to flash, skip the signature,
not write signature first for power down protection*/
DownloadInfo[1].FlashAddr = addr -SPI_FLASH_BASE + 8;
DownloadInfo[1].ImageLen = pOtaTgtHdr->FileImgHdr.ImgLen - 8;/*skip the signature*/
DownloadInfo[1].ImgOffset = pOtaTgtHdr->FileImgHdr.Offset;
}
}else {
ImageCnt = 1;
DownloadInfo[0].ImgId = OTA_IMAG;
/* get OTA image and Write New Image to flash, skip the signature,
not write signature first for power down protection*/
DownloadInfo[0].FlashAddr = addr -SPI_FLASH_BASE + 8;
DownloadInfo[0].ImageLen = pOtaTgtHdr->FileImgHdr.ImgLen - 8;/*skip the signature*/
DownloadInfo[0].ImgOffset = pOtaTgtHdr->FileImgHdr.Offset;
}
printf("\n\r OTA Image Address = %x\n", addr);
if(pOtaTgtHdr->RdpStatus == ENABLE) {
printf("\n\r RDP Image Address = %x\n", RDP_FLASH_ADDR);
}
return ImageCnt;
}
u32 xModem_Frame_Img2(char *ptr, uint32_t frame_num, uint32_t frame_size)
{
uint32_t uart_ota_target_index = OTA_INDEX_2;
u32 fw_img2_size;
u8 *pImgId = NULL;
u32 IncFg = 0;
flash_t flash;
int read_bytes;
int read_bytes_buf;
u32 TempCnt = 0;
u32 TailCnt = 0;
u8 * buf = NULL;
printf("\rframe_num: %d frame_size: %d", frame_num, frame_size);
if (flash_wr_err_cnt)
return 0;
if (frame_num == 1) {
/* check OTA index we should update */
if (ota_get_cur_index() == OTA_INDEX_1) {
uart_ota_target_index = OTA_INDEX_2;
printf("\n\rOTA2 address space will be upgraded\n");
} else {
uart_ota_target_index = OTA_INDEX_1;
printf("\n\rOTA1 address space will be upgraded\n");
}
pImgId = (u8 *)&OtaImgId[uart_ota_target_index];
/* -----step3: parse firmware file header and get the target OTA image header-----*/
/* parse firmware file header and get the target OTA image header-----*/
if(!get_ota_tartget_header((u8*)ptr, frame_size, &OtaTargetHdr, pImgId)){
printf("\n\rget OTA header failed\n");
flash_wr_err_cnt++;
return 0;
}
/*get new image addr and check new address validity*/
if(!get_ota_address(uart_ota_target_index, &fw_img2_addr, &OtaTargetHdr)){
printf("\n\rget OTA address failed\n");
flash_wr_err_cnt++;
return 0;
}
/*get new image length from the firmware header*/
fw_img2_size = OtaTargetHdr.FileImgHdr.ImgLen;
/*-------------------step4: erase flash space for new firmware--------------*/
/*erase flash space new OTA image */
erase_ota_target_flash(fw_img2_addr, fw_img2_size);
/*erase flash space for new RDP image*/
if(OtaTargetHdr.RdpStatus == ENABLE) {
device_mutex_lock(RT_DEV_LOCK_FLASH);
flash_erase_sector(&flash, RDP_FLASH_ADDR - SPI_FLASH_BASE);
device_mutex_unlock(RT_DEV_LOCK_FLASH);
printf("\n\r RDP image size: %d", OtaTargetHdr.FileRdpHdr.ImgLen);
}
/*arrange OTA/RDP image download information*/
ImageCnt = GetDownloadInfo(fw_img2_addr, &OtaTargetHdr);
/*initialize the reveiving counter*/
RemainBytes = DownloadInfo[0].ImageLen;
}
/*downloading parse the OTA and RDP image from the data stream sent by server*/
while(i < ImageCnt){
/*download the new firmware from server*/
if(RemainBytes > 0){
buf = (u8*)ptr;
if(IncFg == 1) {
IncFg = 0;
read_bytes = read_bytes_buf;
} else {
read_bytes = frame_size;
if(read_bytes <= 0){
return 0; // it may not happen
}
read_bytes_buf = read_bytes;
TempLen += frame_size;
}
if(TempLen > DownloadInfo[i].ImgOffset) {
if(!OtaFg) { /*reach the desired image, the first packet process*/
OtaFg = 1;
TempCnt = TempLen -DownloadInfo[i].ImgOffset;
if(DownloadInfo[i].ImgId == OTA_IMAG) {
if(TempCnt < 8) {
SigCnt = TempCnt;
} else {
SigCnt = 8;
}
_memcpy(signature, buf + read_bytes -TempCnt, SigCnt);
if((SigCnt < 8) || (TempCnt -8 == 0)) {
return 0;
}
buf = buf + (read_bytes -TempCnt + 8);
read_bytes = TempCnt -8;
} else {
buf = buf + read_bytes -TempCnt;
read_bytes = TempCnt;
}
} else { /*normal packet process*/
if(DownloadInfo[i].ImgId == OTA_IMAG) {
if(SigCnt < 8) {
if(read_bytes < (8 -SigCnt)) {
_memcpy(signature + SigCnt, buf, read_bytes);
SigCnt += read_bytes;
return 0;
} else {
_memcpy(signature + SigCnt, buf, (8 -SigCnt));
buf = buf + (8 - SigCnt);
read_bytes -= (8 - SigCnt) ;
SigCnt = 8;
if(!read_bytes) {
return 0;
}
}
}
}
}
RemainBytes -= read_bytes;
if(RemainBytes < 0) {
read_bytes = read_bytes -(-RemainBytes);
}
device_mutex_lock(RT_DEV_LOCK_FLASH);
if(flash_stream_write(&flash, DownloadInfo[i].FlashAddr + size, read_bytes, buf) < 0){
printf("\n\r[%s] Write sector failed", __FUNCTION__);
device_mutex_unlock(RT_DEV_LOCK_FLASH);
flash_wr_err_cnt++;
return 0;
}
device_mutex_unlock(RT_DEV_LOCK_FLASH);
size += read_bytes;
}else{
return 0 + TailCnt; /* not reach desired image */
}
}else{
return 0; /* no desired image */
}
if(RemainBytes <= 0){
/*if complete downloading OTA image, acquire the image size*/
if(DownloadInfo[i].ImgId == OTA_IMAG) {
OtaImgSize = size;
}
TailCnt = read_bytes;
/*update flag status*/
size = 0;
OtaFg = 0;
IncFg = 1;
/*the next image length*/
if(++i < ImageCnt)
RemainBytes = DownloadInfo[i].ImageLen;
}else{
return read_bytes + TailCnt;
}
}
return 0 + TailCnt;/* no desired image */
}
int
WriteImg2Sign(
u32 wr_len
)
{
int ret = 1 ;
uint32_t uart_ota_target_index = OTA_INDEX_2;
flash_t flash;
if(fw_img2_addr == OTA1_ADDR)
uart_ota_target_index = OTA_INDEX_1;
else
uart_ota_target_index = OTA_INDEX_2;
if((OtaImgSize <= 0) || (OtaImgSize != (OtaTargetHdr.FileImgHdr.ImgLen - 8))) {
printf("\n\rdownload new firmware failed\n");
return 1;
}
printf("\n\rwrite size = %d", OtaImgSize);
printf("\n\rsignature = %s",signature);
/*-------------step6: verify checksum and update signature-----------------*/
if(verify_ota_checksum(fw_img2_addr, OtaImgSize, signature, &OtaTargetHdr)){
if(!change_ota_signature(fw_img2_addr, signature, uart_ota_target_index)) {
printf("\n%s: change signature failed\n", __FUNCTION__);
return 1;
}
ret = 0;
} else {
/*if checksum error, clear the signature zone which has been
written in flash in case of boot from the wrong firmware*/
#if 1
device_mutex_lock(RT_DEV_LOCK_FLASH);
flash_erase_sector(&flash, fw_img2_addr - SPI_FLASH_BASE);
device_mutex_unlock(RT_DEV_LOCK_FLASH);
#endif
}
return ret;
}
void OTU_FW_Update(u8 uart_idx, u8 pin_mux, u32 baud_rate)
{
u32 wr_len = 0;
int ret = 1;
memset(signature, 0, sizeof(signature));
memset(&OtaTargetHdr, 0, sizeof(OtaTargetHdr));
memset((u8 *)&DownloadInfo, 0, 2*sizeof(update_dw_info));
fw_img2_addr = 0;
flash_wr_err_cnt = 0;
SigCnt = 0;
ImageCnt = 0;
OtaFg = 0;
RemainBytes = 0;
i = 0;
TempLen = 0;
OtaImgSize = 0;
size = 0;
printf("FW Update Over UART%d, PinMux=%d, Baud=%d\r\n", uart_idx, pin_mux, baud_rate);
// Baud rate setting is used by UART_SetBaud,not serial_baud. Baud rate setting cannot be successful when LOW_POWER_RX_ENABLE
if(uart_config[0].LOW_POWER_RX_ENABLE){
UART_LPRxpathSet(UART0_DEV, DISABLE);
UART_LPRxIPClockSet(UART0_DEV, UART_RX_CLK_XTAL_40M);
}
// Start to update the Image2 through xModem on peripheral device
// We update the image via xModem on UART now, if we want to use other peripheral device
// to update the image then we need to redefine the API
if (xModem_Init_UART_Port(uart_idx, pin_mux, baud_rate) < 0) {
return;
}
xModemStart(&_xMCtrl, xMFrameBuf, xModem_Frame_Img2);
wr_len = _xModemRxBuffer(&_xMCtrl, (2*1024*1024));
xModemEnd(&_xMCtrl);
xModem_DeInit_UART_Port(uart_idx);
printf("FW Update Image2 @ 0x%x\r\n", fw_img2_addr);
if ((wr_len > 0) && (flash_wr_err_cnt == 0)){
ret = WriteImg2Sign(wr_len);
}
else
printf("\n\rerror in writen to flash");
if(!ret)
printf("\n\rOTU_FW_Update Success");
if(uart_config[0].LOW_POWER_RX_ENABLE){
UART_LPRxpathSet(UART0_DEV, ENABLE);
UART_LPRxIPClockSet(UART0_DEV, UART_RX_CLK_OSC_8M);
}
printf("\n\rOTU_FW_Update Done, Write Len=%d\n", wr_len);
}
#endif

View File

@@ -0,0 +1,129 @@
/**
******************************************************************************
* @file xmodem.h
* @author
* @version
* @brief This file provides user interface for xmodem, support Xmode Tx & Rx
******************************************************************************
* @attention
*
* This module is a confidential and proprietary property of RealTek and possession or use of this module requires written permission of RealTek.
*
* Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
******************************************************************************
*/
#ifndef _XMODE_H_
#define _XMODE_H_
/** @addtogroup xmodem XMODEM
* @ingroup hal
* @brief Xmodem TX & RX function
* @{
*/
#include <basic_types.h>
#if defined(CONFIG_PLATFORM_8711B)
#define xModemRxBuffer _xModemRxBuffer
#endif
/*****************
* X-Modem status
*****************/
#define XMODEM_OK 1
#define XMODEM_CANCEL 2
#define XMODEM_ACK 3
#define XMODEM_NAK 4
#define XMODEM_COMPLETE 5
#define XMODEM_NO_SESSION 6
#define XMODEM_ABORT 7
#define XMODEM_TIMEOUT 8
/****************************
* flow control character
****************************/
#define SOH 0x01 /* Start of header */
#define STX 0x02 /* Start of header XModem-1K */
#define EOT 0x04 /* End of transmission */
#define ACK 0x06 /* Acknowledge */
#define NAK 0x15 /* Not acknowledge */
#define CAN 0x18 /* Cancel */
#define ESC 0x1b /* User Break */
/****************************
* Xmode paramters
****************************/
#define FRAME_SIZE 132 /* X-modem structure */
#define FRAME_SIZE_1K 1028 /* X-modem structure */
#define XM_BUFFER_SIZE 1024 /* X-modem buffer */
#define TIMEOUT 180 /* max timeout */
#define RETRY_COUNT 20 /* Try times */
#define xWAITTIME 0x00400000 /* waitiing time */
#define WAIT_FRAME_TIME (10000*100) /* 10 sec, wait frame timeout */
#define WAIT_CHAR_TIME (1000*100) /* 1 sec, wait char timeout */
/***********************
* frame structure
***********************/
typedef struct
{
unsigned char soh;
unsigned char recordNo;
unsigned char recordNoInverted;
unsigned char buffer[XM_BUFFER_SIZE];
unsigned char CRC;
} XMODEM_FRAME;
typedef struct _XMODEM_COM_PORT_ {
char (*poll) (void);
char (*get)(void);
void (*put)(char c);
}XMODEM_COM_PORT, *PXMODEM_COM_PORT;
typedef struct _XMODEM_CTRL_ {
u16 xMUsing;
u16 currentFrame; /* current frame number */
u16 previousFrame; /* previous frame number */
u16 expected;
s16 rStatus;
s32 rFinish;
u32 total_frame;
u32 rx_len;
char *pXFrameBuf;
u32 (*RxFrameHandler)(char *ptr, u32 frame_num, u32 frame_size);
XMODEM_COM_PORT ComPort;
}XMODEM_CTRL, *PXMODEM_CTRL;
typedef u32 (*RxFrameHandler_t)(char *ptr, u32 frame_num, u32 frame_size);
/**
* @brief Initial comport, buffer, buffer handler
* @param pXMCtrl : xmodem comport
* @param FrameBuf : pointer of RX frame buffer
* @param RxFrameHdl : callback of receiving RX frame
* @return XMODEM_OK : initial OK
XMODEM_NO_SESSION : initial failed, xmodem is using
*/
extern s16 xModemStart(XMODEM_CTRL *pXMCtrl, char *FrameBuf, RxFrameHandler_t RxFrameHdl);
/**
* @brief Close xmodem comport
* @param pXMCtrl : xmodem comport
* @return XMODEM_OK : OK
* XMODEM_NO_SESSION : Close xmodem failed, xmodem has already closed
*/
extern s16 xModemEnd(XMODEM_CTRL *pXMCtrl);
/**
* @brief xmodem receive frame
* @param pXMCtrl : xmodem comport
* @param MaxSize : the maximum size of total RX frame
* @return successful : return total RX frame length
* failed : return MaxSize+1
*/
extern s32 xModemRxBuffer(XMODEM_CTRL *pXMCtrl, s32 MaxSize);
/*\@}*/
#endif /* _XMODE_H_ */

View File

@@ -0,0 +1,25 @@
/*
* Routines to access hardware
*
* Copyright (c) 2013 Realtek Semiconductor Corp.
*
* This module is a confidential and proprietary property of RealTek and
* possession or use of this module requires written permission of RealTek.
*/
#ifndef _XMPORT_LOGUART_H_
#define _XMPORT_LOGUART_H_
#include "xmodem.h"
//void xmodem_loguart_init(void);
void xmodem_loguart_init(u32 BaudRate);
void xmodem_loguart_func_hook(XMODEM_COM_PORT *pXComPort);
void xmodem_loguart_deinit(void);
char xmodem_loguart_readable(void);
char xmodem_loguart_writable(void);
char xmodem_loguart_getc(void);
void xmodem_loguart_putc(char c);
#endif // end of "#define _XMPORT_LOGUART_H_"

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