mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-14 14:08:19 +08:00
568 lines
22 KiB
C
568 lines
22 KiB
C
/**
|
|
******************************************************************************
|
|
* @file config_server.c
|
|
* @author William Xu
|
|
* @version V1.0.0
|
|
* @date 05-May-2014
|
|
* @brief Local TCP server for mico device configuration
|
|
******************************************************************************
|
|
* UNPUBLISHED PROPRIETARY SOURCE CODE
|
|
* Copyright (c) 2016 MXCHIP Inc.
|
|
*
|
|
* The contents of this file may not be disclosed to third parties, copied or
|
|
* duplicated in any form, in whole or in part, without the prior written
|
|
* permission of MXCHIP Corporation.
|
|
******************************************************************************
|
|
*/
|
|
|
|
#include "mico.h"
|
|
#include "system_internal.h"
|
|
#include "platform.h"
|
|
#include "easylink_internal.h"
|
|
|
|
#include "SocketUtils.h"
|
|
#include "HTTPUtils.h"
|
|
#include "StringUtils.h"
|
|
#include "CheckSumUtils.h"
|
|
|
|
#define kCONFIGURLRead "/config-read"
|
|
#define kCONFIGURLWrite "/config-write"
|
|
#define kCONFIGURLWriteByUAP "/config-write-uap" /* Don't reboot but connect to AP immediately */
|
|
#define kCONFIGURLOTA "/OTA"
|
|
|
|
#define kMIMEType_MXCHIP_OTA "application/ota-stream"
|
|
|
|
typedef struct _configContext_t{
|
|
uint32_t offset;
|
|
bool isFlashLocked;
|
|
CRC16_Context crc16_contex;
|
|
} configContext_t;
|
|
|
|
extern OSStatus ConfigIncommingJsonMessage( int fd, const char *input, bool *need_reboot, mico_Context_t * const inContext );
|
|
extern json_object* ConfigCreateReportJsonMessage( mico_Context_t * const inContext );
|
|
|
|
static void localConfiglistener_thread(uint32_t inContext);
|
|
static void localConfig_thread(uint32_t inFd);
|
|
static OSStatus _LocalConfigRespondInComingMessage(int fd, HTTPHeader_t* inHeader, system_context_t * const inContext);
|
|
static OSStatus onReceivedData(struct _HTTPHeader_t * httpHeader, uint32_t pos, uint8_t * data, size_t len, void * userContext );
|
|
static void onClearHTTPHeader(struct _HTTPHeader_t * httpHeader, void * userContext );
|
|
|
|
bool is_config_server_established = false;
|
|
|
|
/* Defined in uAP config mode */
|
|
extern OSStatus ConfigIncommingJsonMessageUAP( int fd, const uint8_t *input, size_t size, system_context_t * const inContext );
|
|
extern system_context_t* sys_context;
|
|
|
|
static mico_semaphore_t close_listener_sem = NULL, close_client_sem[ MAX_TCP_CLIENT_PER_SERVER ] = { NULL };
|
|
|
|
WEAK void config_server_delegate_report( json_object *app_menu, mico_Context_t *in_context )
|
|
{
|
|
UNUSED_PARAMETER(app_menu);
|
|
UNUSED_PARAMETER(in_context);
|
|
return;
|
|
}
|
|
|
|
WEAK void config_server_delegate_recv( const char *key, json_object *value, bool *need_reboot, mico_Context_t *in_context )
|
|
{
|
|
UNUSED_PARAMETER(key);
|
|
UNUSED_PARAMETER(value);
|
|
UNUSED_PARAMETER(need_reboot);
|
|
UNUSED_PARAMETER(in_context);
|
|
return;
|
|
}
|
|
|
|
OSStatus config_server_start ( void )
|
|
{
|
|
int i = 0;
|
|
OSStatus err = kNoErr;
|
|
|
|
require( sys_context, exit );
|
|
|
|
if( is_config_server_established )
|
|
return kNoErr;
|
|
|
|
is_config_server_established = true;
|
|
|
|
close_listener_sem = NULL;
|
|
for (; i < MAX_TCP_CLIENT_PER_SERVER; i++)
|
|
close_client_sem[ i ] = NULL;
|
|
err = mico_rtos_create_thread( NULL, MICO_APPLICATION_PRIORITY, "Config Server", localConfiglistener_thread, STACK_SIZE_LOCAL_CONFIG_SERVER_THREAD, 0 );
|
|
require_noerr(err, exit);
|
|
|
|
mico_thread_msleep(200);
|
|
|
|
exit:
|
|
return err;
|
|
}
|
|
|
|
OSStatus config_server_stop( void )
|
|
{
|
|
int i = 0;
|
|
OSStatus err = kNoErr;
|
|
|
|
if( !is_config_server_established )
|
|
return kNoErr;
|
|
|
|
for (; i < MAX_TCP_CLIENT_PER_SERVER; i++){
|
|
if( close_client_sem[ i ] != NULL )
|
|
mico_rtos_set_semaphore( &close_client_sem[ i ] );
|
|
}
|
|
mico_thread_msleep(50);
|
|
|
|
if( close_listener_sem != NULL )
|
|
mico_rtos_set_semaphore( &close_listener_sem );
|
|
|
|
mico_thread_msleep(500);
|
|
is_config_server_established = false;
|
|
|
|
return err;
|
|
}
|
|
|
|
void localConfiglistener_thread( mico_thread_arg_t arg)
|
|
{
|
|
OSStatus err = kUnknownErr;
|
|
int j;
|
|
struct sockaddr_in addr;
|
|
int sockaddr_t_size;
|
|
fd_set readfds;
|
|
char ip_address[16];
|
|
|
|
int localConfiglistener_fd = -1;
|
|
int close_listener_fd = -1;
|
|
|
|
mico_rtos_init_semaphore( &close_listener_sem, 1);
|
|
close_listener_fd = mico_create_event_fd( close_listener_sem );
|
|
|
|
/*Establish a TCP server fd that accept the tcp clients connections*/
|
|
localConfiglistener_fd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
|
|
require_action(IsValidSocket( localConfiglistener_fd ), exit, err = kNoResourcesErr );
|
|
addr.sin_family = AF_INET;
|
|
addr.sin_addr.s_addr =INADDR_ANY;
|
|
addr.sin_port = htons(MICO_CONFIG_SERVER_PORT);
|
|
err = bind(localConfiglistener_fd, (struct sockaddr *)&addr, sizeof(addr));
|
|
require_noerr( err, exit );
|
|
|
|
err = listen(localConfiglistener_fd, 1);
|
|
require_noerr( err, exit );
|
|
|
|
system_log("Config Server established at port: %d, fd: %d", MICO_CONFIG_SERVER_PORT, localConfiglistener_fd);
|
|
|
|
while(1){
|
|
FD_ZERO(&readfds);
|
|
FD_SET(localConfiglistener_fd, &readfds);
|
|
FD_SET(close_listener_fd, &readfds);
|
|
select( Max(localConfiglistener_fd, close_listener_fd) + 1, &readfds, NULL, NULL, NULL);
|
|
|
|
/* Check close requests */
|
|
if(FD_ISSET(close_listener_fd, &readfds)){
|
|
mico_rtos_get_semaphore( &close_listener_sem, 0 );
|
|
goto exit;
|
|
}
|
|
|
|
/* Check tcp connection requests */
|
|
if(FD_ISSET(localConfiglistener_fd, &readfds)){
|
|
sockaddr_t_size = sizeof(struct sockaddr_in);
|
|
j = accept(localConfiglistener_fd, (struct sockaddr *)&addr, (socklen_t *)&sockaddr_t_size);
|
|
if ( IsValidSocket( j ) ) {
|
|
strcpy(ip_address,inet_ntoa( addr.sin_addr ));
|
|
system_log("Config Client %s:%d connected, fd: %d", ip_address, addr.sin_port, j);
|
|
if(kNoErr != mico_rtos_create_thread(NULL, MICO_APPLICATION_PRIORITY, "Config Clients", localConfig_thread, STACK_SIZE_LOCAL_CONFIG_CLIENT_THREAD, (mico_thread_arg_t)j) )
|
|
SocketClose(&j);
|
|
}
|
|
}
|
|
}
|
|
|
|
exit:
|
|
if( close_listener_sem != NULL ){
|
|
mico_delete_event_fd( close_listener_fd );
|
|
mico_rtos_deinit_semaphore( &close_listener_sem );
|
|
close_listener_sem = NULL;
|
|
};
|
|
system_log("Exit: Config listener exit with err = %d", err);
|
|
SocketClose( &localConfiglistener_fd );
|
|
is_config_server_established = false;
|
|
mico_rtos_delete_thread(NULL);
|
|
return;
|
|
}
|
|
|
|
void localConfig_thread(uint32_t inFd)
|
|
{
|
|
OSStatus err = kNoErr;
|
|
int clientFd = (int)inFd;
|
|
int clientFdIsSet;
|
|
int close_sem_index;
|
|
fd_set readfds;
|
|
struct timeval t;
|
|
HTTPHeader_t *httpHeader = NULL;
|
|
int close_client_fd = -1;
|
|
configContext_t httpContext = {0, false};
|
|
|
|
for( close_sem_index = 0; close_sem_index < MAX_TCP_CLIENT_PER_SERVER; close_sem_index++ ){
|
|
if( close_client_sem[close_sem_index] == NULL )
|
|
break;
|
|
}
|
|
|
|
if( close_sem_index == MAX_TCP_CLIENT_PER_SERVER){
|
|
mico_rtos_delete_thread(NULL);
|
|
return;
|
|
}
|
|
|
|
mico_rtos_init_semaphore( &close_client_sem[close_sem_index], 1);
|
|
close_client_fd = mico_create_event_fd( close_client_sem[close_sem_index] );
|
|
|
|
httpHeader = HTTPHeaderCreateWithCallback( 512, onReceivedData, onClearHTTPHeader, &httpContext );
|
|
require_action( httpHeader, exit, err = kNoMemoryErr );
|
|
HTTPHeaderClear( httpHeader );
|
|
|
|
t.tv_sec = 60;
|
|
t.tv_usec = 0;
|
|
system_log("Free memory %d bytes", MicoGetMemoryInfo()->free_memory) ;
|
|
|
|
while(1){
|
|
FD_ZERO(&readfds);
|
|
FD_SET(clientFd, &readfds);
|
|
FD_SET(close_client_fd, &readfds);
|
|
clientFdIsSet = 0;
|
|
|
|
if(httpHeader->len == 0){
|
|
require(select( Max(clientFd, close_client_fd) + 1 , &readfds, NULL, NULL, &t) >= 0, exit);
|
|
clientFdIsSet = FD_ISSET(clientFd, &readfds);
|
|
}
|
|
|
|
/* Check close requests */
|
|
if(FD_ISSET(close_client_fd, &readfds)){
|
|
mico_rtos_get_semaphore( &close_client_sem[close_sem_index], 0 );
|
|
err = kConnectionErr;
|
|
goto exit;
|
|
}
|
|
|
|
if(clientFdIsSet||httpHeader->len){
|
|
err = SocketReadHTTPHeader( clientFd, httpHeader );
|
|
|
|
switch ( err )
|
|
{
|
|
case kNoErr:
|
|
// Read the rest of the HTTP body if necessary
|
|
//do{
|
|
err = SocketReadHTTPBody( clientFd, httpHeader );
|
|
|
|
if(httpHeader->dataEndedbyClose == true){
|
|
err = _LocalConfigRespondInComingMessage( clientFd, httpHeader, sys_context );
|
|
require_noerr(err, exit);
|
|
err = kConnectionErr;
|
|
goto exit;
|
|
}else{
|
|
require_noerr(err, exit);
|
|
err = _LocalConfigRespondInComingMessage( clientFd, httpHeader, sys_context );
|
|
require_noerr(err, exit);
|
|
}
|
|
|
|
HTTPHeaderClear( httpHeader );
|
|
break;
|
|
|
|
case EWOULDBLOCK:
|
|
// NO-OP, keep reading
|
|
break;
|
|
|
|
case kNoSpaceErr:
|
|
system_log("ERROR: Cannot fit HTTPHeader.");
|
|
goto exit;
|
|
|
|
case kConnectionErr:
|
|
// NOTE: kConnectionErr from SocketReadHTTPHeader means it's closed
|
|
system_log("ERROR: Connection closed.");
|
|
goto exit;
|
|
|
|
default:
|
|
system_log("ERROR: HTTP Header parse internal error: %d", err);
|
|
goto exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
exit:
|
|
system_log("Exit: Client exit with err = %d", err);
|
|
SocketClose(&clientFd);
|
|
|
|
if( close_client_sem[close_sem_index] != NULL )
|
|
{
|
|
mico_delete_event_fd( close_client_fd );
|
|
mico_rtos_deinit_semaphore( &close_client_sem[close_sem_index] );
|
|
close_client_sem[close_sem_index] = NULL;
|
|
};
|
|
|
|
HTTPHeaderDestory( &httpHeader );
|
|
mico_rtos_delete_thread(NULL);
|
|
return;
|
|
}
|
|
|
|
static OSStatus onReceivedData(struct _HTTPHeader_t * inHeader, uint32_t inPos, uint8_t * inData, size_t inLen, void * inUserContext )
|
|
{
|
|
OSStatus err = kUnknownErr;
|
|
const char * value;
|
|
size_t valueSize;
|
|
configContext_t *context = (configContext_t *)inUserContext;
|
|
mico_logic_partition_t* ota_partition = MicoFlashGetInfo( MICO_PARTITION_OTA_TEMP );
|
|
|
|
err = HTTPGetHeaderField( inHeader->buf, inHeader->len, "Content-Type", NULL, NULL, &value, &valueSize, NULL );
|
|
if(err == kNoErr && strnicmpx( value, valueSize, kMIMEType_MXCHIP_OTA ) == 0){
|
|
|
|
if( ota_partition->partition_owner == MICO_FLASH_NONE ){
|
|
system_log("OTA storage is not exist");
|
|
return kUnsupportedErr;
|
|
}
|
|
|
|
if(inPos == 0){
|
|
context->offset = 0x0;
|
|
CRC16_Init( &context->crc16_contex );
|
|
mico_rtos_lock_mutex(&sys_context->flashContentInRam_mutex); //We are write the Flash content, no other write is possible
|
|
context->isFlashLocked = true;
|
|
err = MicoFlashErase( MICO_PARTITION_OTA_TEMP, 0x0, ota_partition->partition_length);
|
|
require_noerr(err, flashErrExit);
|
|
err = MicoFlashWrite( MICO_PARTITION_OTA_TEMP, &context->offset, (uint8_t *)inData, inLen);
|
|
require_noerr(err, flashErrExit);
|
|
CRC16_Update( &context->crc16_contex, inData, inLen);
|
|
}else{
|
|
err = MicoFlashWrite( MICO_PARTITION_OTA_TEMP, &context->offset, (uint8_t *)inData, inLen);
|
|
require_noerr(err, flashErrExit);
|
|
CRC16_Update( &context->crc16_contex, inData, inLen);
|
|
}
|
|
}
|
|
else{
|
|
return kUnsupportedErr;
|
|
}
|
|
|
|
if(err!=kNoErr) system_log("onReceivedData");
|
|
return err;
|
|
|
|
flashErrExit:
|
|
mico_rtos_unlock_mutex(&sys_context->flashContentInRam_mutex);
|
|
return err;
|
|
}
|
|
|
|
static void onClearHTTPHeader(struct _HTTPHeader_t * inHeader, void * inUserContext )
|
|
{
|
|
UNUSED_PARAMETER(inHeader);
|
|
configContext_t *context = (configContext_t *)inUserContext;
|
|
|
|
if(context->isFlashLocked == true){
|
|
mico_rtos_unlock_mutex(&sys_context->flashContentInRam_mutex);
|
|
context->isFlashLocked = false;
|
|
}
|
|
}
|
|
|
|
OSStatus _LocalConfigRespondInComingMessage(int fd, HTTPHeader_t* inHeader, system_context_t * const inContext)
|
|
{
|
|
OSStatus err = kUnknownErr;
|
|
const char * json_str;
|
|
uint8_t *httpResponse = NULL;
|
|
size_t httpResponseLen = 0;
|
|
json_object* report = NULL, *config = NULL;
|
|
bool need_reboot = false;
|
|
uint16_t crc;
|
|
configContext_t *http_context = (configContext_t *)inHeader->userContext;
|
|
mico_logic_partition_t* ota_partition = MicoFlashGetInfo( MICO_PARTITION_OTA_TEMP );
|
|
char name[50];
|
|
|
|
json_object *sectors, *sector = NULL;
|
|
|
|
if(HTTPHeaderMatchURL( inHeader, kCONFIGURLRead ) == kNoErr){
|
|
//report = ConfigCreateReportJsonMessage( inContext );
|
|
|
|
mico_rtos_lock_mutex(&inContext->flashContentInRam_mutex);
|
|
snprintf(name, 50, "%s(%c%c%c%c%c%c)",MODEL,
|
|
inContext->micoStatus.mac[9], inContext->micoStatus.mac[10],
|
|
inContext->micoStatus.mac[12], inContext->micoStatus.mac[13],
|
|
inContext->micoStatus.mac[15], inContext->micoStatus.mac[16]);
|
|
report = json_object_new_object();
|
|
require_action(report, exit, err = kNoMemoryErr);
|
|
|
|
sectors = json_object_new_array();
|
|
require( sectors, exit );
|
|
|
|
json_object_object_add(report, "T", json_object_new_string("Current Configuration"));
|
|
json_object_object_add(report, "N", json_object_new_string(name));
|
|
json_object_object_add(report, "C", sectors);
|
|
|
|
json_object_object_add(report, "PO", json_object_new_string(PROTOCOL));
|
|
json_object_object_add(report, "HD", json_object_new_string(HARDWARE_REVISION));
|
|
json_object_object_add(report, "FW", json_object_new_string(FIRMWARE_REVISION));
|
|
json_object_object_add(report, "RF", json_object_new_string(inContext->micoStatus.rf_version));
|
|
|
|
#ifdef MICO_CONFIG_SERVER_REPORT_SYSTEM_DATA
|
|
/*Sector 1*/
|
|
sector = json_object_new_array();
|
|
require( sector, exit );
|
|
err = config_server_create_sector(sectors, "MICO SYSTEM", sector);
|
|
require_noerr(err, exit);
|
|
|
|
/*name cell*/
|
|
err = config_server_create_string_cell(sector, "Device Name", inContext->flashContentInRam.micoSystemConfig.name, "RW", NULL);
|
|
require_noerr(err, exit);
|
|
|
|
//RF power save switcher cell
|
|
err = config_server_create_bool_cell(sector, "RF power save", inContext->flashContentInRam.micoSystemConfig.rfPowerSaveEnable, "RW");
|
|
require_noerr(err, exit);
|
|
|
|
//MCU power save switcher cell
|
|
err = config_server_create_bool_cell(sector, "MCU power save", inContext->flashContentInRam.micoSystemConfig.mcuPowerSaveEnable, "RW");
|
|
require_noerr(err, exit);
|
|
|
|
/*SSID cell*/
|
|
err = config_server_create_string_cell(sector, "Wi-Fi", inContext->flashContentInRam.micoSystemConfig.ssid, "RW", NULL);
|
|
require_noerr(err, exit);
|
|
/*PASSWORD cell*/
|
|
err = config_server_create_string_cell(sector, "Password", inContext->flashContentInRam.micoSystemConfig.user_key, "RW", NULL);
|
|
require_noerr(err, exit);
|
|
/*DHCP cell*/
|
|
err = config_server_create_bool_cell(sector, "DHCP", inContext->flashContentInRam.micoSystemConfig.dhcpEnable, "RW");
|
|
require_noerr(err, exit);
|
|
/*Local cell*/
|
|
err = config_server_create_string_cell(sector, "IP address", inContext->micoStatus.localIp, "RW", NULL);
|
|
require_noerr(err, exit);
|
|
/*Netmask cell*/
|
|
err = config_server_create_string_cell(sector, "Net Mask", inContext->micoStatus.netMask, "RW", NULL);
|
|
require_noerr(err, exit);
|
|
/*Gateway cell*/
|
|
err = config_server_create_string_cell(sector, "Gateway", inContext->micoStatus.gateWay, "RW", NULL);
|
|
require_noerr(err, exit);
|
|
/*DNS server cell*/
|
|
err = config_server_create_string_cell(sector, "DNS Server", inContext->micoStatus.dnsServer, "RW", NULL);
|
|
require_noerr(err, exit);
|
|
#endif
|
|
|
|
/*Sector 2*/
|
|
sector = json_object_new_array();
|
|
require( sector, exit );
|
|
err = config_server_create_sector(sectors, "APPLICATION", sector);
|
|
require_noerr(err, exit);
|
|
|
|
config_server_delegate_report( sector, &inContext->flashContentInRam );
|
|
|
|
mico_rtos_unlock_mutex(&inContext->flashContentInRam_mutex);
|
|
|
|
json_str = json_object_to_json_string(report);
|
|
require_action( json_str, exit, err = kNoMemoryErr );
|
|
system_log("Send config object=%s", json_str);
|
|
err = CreateSimpleHTTPMessageNoCopy( kMIMEType_JSON, strlen(json_str), &httpResponse, &httpResponseLen );
|
|
require_noerr( err, exit );
|
|
require( httpResponse, exit );
|
|
err = SocketSend( fd, httpResponse, httpResponseLen );
|
|
require_noerr( err, exit );
|
|
err = SocketSend( fd, (uint8_t *)json_str, strlen(json_str) );
|
|
require_noerr( err, exit );
|
|
system_log("Current configuration sent");
|
|
goto exit;
|
|
}
|
|
else if(HTTPHeaderMatchURL( inHeader, kCONFIGURLWrite ) == kNoErr){
|
|
if(inHeader->contentLength > 0){
|
|
system_log("Recv new configuration, apply");
|
|
|
|
err = CreateSimpleHTTPOKMessage( &httpResponse, &httpResponseLen );
|
|
require_noerr( err, exit );
|
|
require( httpResponse, exit );
|
|
err = SocketSend( fd, httpResponse, httpResponseLen );
|
|
require_noerr( err, exit );
|
|
|
|
config = json_tokener_parse(inHeader->extraDataPtr);
|
|
require_action(config, exit, err = kUnknownErr);
|
|
system_log("Recv config object=%s", json_object_to_json_string(config));
|
|
mico_rtos_lock_mutex(&inContext->flashContentInRam_mutex);
|
|
json_object_object_foreach(config, key, val) {
|
|
if(!strcmp(key, "Device Name")){
|
|
strncpy(inContext->flashContentInRam.micoSystemConfig.name, json_object_get_string(val), maxNameLen);
|
|
need_reboot = true;
|
|
}else if(!strcmp(key, "RF power save")){
|
|
inContext->flashContentInRam.micoSystemConfig.rfPowerSaveEnable = json_object_get_boolean(val);
|
|
need_reboot = true;
|
|
}else if(!strcmp(key, "MCU power save")){
|
|
inContext->flashContentInRam.micoSystemConfig.mcuPowerSaveEnable = json_object_get_boolean(val);
|
|
need_reboot = true;
|
|
}else if(!strcmp(key, "Wi-Fi")){
|
|
strncpy(inContext->flashContentInRam.micoSystemConfig.ssid, json_object_get_string(val), maxSsidLen);
|
|
inContext->flashContentInRam.micoSystemConfig.channel = 0;
|
|
memset(inContext->flashContentInRam.micoSystemConfig.bssid, 0x0, 6);
|
|
inContext->flashContentInRam.micoSystemConfig.security = SECURITY_TYPE_AUTO;
|
|
memcpy(inContext->flashContentInRam.micoSystemConfig.key, inContext->flashContentInRam.micoSystemConfig.user_key, maxKeyLen);
|
|
inContext->flashContentInRam.micoSystemConfig.keyLength = inContext->flashContentInRam.micoSystemConfig.user_keyLength;
|
|
need_reboot = true;
|
|
}else if(!strcmp(key, "Password")){
|
|
inContext->flashContentInRam.micoSystemConfig.security = SECURITY_TYPE_AUTO;
|
|
strncpy(inContext->flashContentInRam.micoSystemConfig.key, json_object_get_string(val), maxKeyLen);
|
|
strncpy(inContext->flashContentInRam.micoSystemConfig.user_key, json_object_get_string(val), maxKeyLen);
|
|
inContext->flashContentInRam.micoSystemConfig.keyLength = strlen(inContext->flashContentInRam.micoSystemConfig.key);
|
|
inContext->flashContentInRam.micoSystemConfig.user_keyLength = strlen(inContext->flashContentInRam.micoSystemConfig.key);
|
|
need_reboot = true;
|
|
}else if(!strcmp(key, "DHCP")){
|
|
inContext->flashContentInRam.micoSystemConfig.dhcpEnable = json_object_get_boolean(val);
|
|
need_reboot = true;
|
|
}else if(!strcmp(key, "IP address")){
|
|
strncpy(inContext->flashContentInRam.micoSystemConfig.localIp, json_object_get_string(val), maxIpLen);
|
|
need_reboot = true;
|
|
}else if(!strcmp(key, "Net Mask")){
|
|
strncpy(inContext->flashContentInRam.micoSystemConfig.netMask, json_object_get_string(val), maxIpLen);
|
|
need_reboot = true;
|
|
}else if(!strcmp(key, "Gateway")){
|
|
strncpy(inContext->flashContentInRam.micoSystemConfig.gateWay, json_object_get_string(val), maxIpLen);
|
|
need_reboot = true;
|
|
}else if(!strcmp(key, "DNS Server")){
|
|
strncpy(inContext->flashContentInRam.micoSystemConfig.dnsServer, json_object_get_string(val), maxIpLen);
|
|
need_reboot = true;
|
|
}else{
|
|
config_server_delegate_recv( key, val, &need_reboot, &inContext->flashContentInRam );
|
|
}
|
|
}
|
|
mico_rtos_unlock_mutex(&inContext->flashContentInRam_mutex);
|
|
|
|
json_object_put(config);
|
|
|
|
inContext->flashContentInRam.micoSystemConfig.configured = allConfigured;
|
|
mico_system_context_update( &inContext->flashContentInRam );
|
|
|
|
if( need_reboot == true ){
|
|
mico_system_power_perform( &inContext->flashContentInRam, eState_Software_Reset );
|
|
}
|
|
}
|
|
goto exit;
|
|
}
|
|
else if(HTTPHeaderMatchURL( inHeader, kCONFIGURLWriteByUAP ) == kNoErr){
|
|
if(inHeader->contentLength > 0){
|
|
system_log( "Recv new configuration from uAP, apply and connect to AP" );
|
|
err = ConfigIncommingJsonMessageUAP( fd, (uint8_t *)inHeader->extraDataPtr, inHeader->extraDataLen, inContext );
|
|
require_noerr( err, exit );
|
|
}
|
|
goto exit;
|
|
}
|
|
else if(HTTPHeaderMatchURL( inHeader, kCONFIGURLOTA ) == kNoErr && ota_partition->partition_owner != MICO_FLASH_NONE){
|
|
if(inHeader->contentLength > 0){
|
|
system_log("Receive OTA data!");
|
|
CRC16_Final( &http_context->crc16_contex, &crc);
|
|
memset(&inContext->flashContentInRam.bootTable, 0, sizeof(boot_table_t));
|
|
inContext->flashContentInRam.bootTable.length = inHeader->contentLength;
|
|
inContext->flashContentInRam.bootTable.start_address = ota_partition->partition_start_addr;
|
|
inContext->flashContentInRam.bootTable.type = 'A';
|
|
inContext->flashContentInRam.bootTable.upgrade_type = 'U';
|
|
inContext->flashContentInRam.bootTable.crc = crc;
|
|
mico_system_context_update( &inContext->flashContentInRam );
|
|
SocketClose( &fd );
|
|
mico_system_power_perform( &inContext->flashContentInRam, eState_Software_Reset );
|
|
mico_thread_sleep( MICO_WAIT_FOREVER );
|
|
}
|
|
goto exit;
|
|
}
|
|
else{
|
|
return kNotFoundErr;
|
|
};
|
|
|
|
exit:
|
|
if(inHeader->persistent == false) //Return an err to close socket and exit the current thread
|
|
err = kConnectionErr;
|
|
if(httpResponse) free(httpResponse);
|
|
if(report) json_object_put(report);
|
|
if(config) json_object_put(config);
|
|
|
|
return err;
|
|
|
|
}
|
|
|