mirror of
https://github.com/oopuuu/zTC1.git
synced 2025-12-16 15:08:15 +08:00
修复mico-sdk错误
This commit is contained in:
@@ -1,70 +1,70 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file MFi_WAC.h
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide header file for start a Apple WAC (wireless accessory
|
||||
* configuration) function thread.
|
||||
******************************************************************************
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mico.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BUNDLE_SEED_ID "C6P64J2MZX"
|
||||
#define EA_PROTOCOL "com.issc.datapath"
|
||||
|
||||
/**
|
||||
* @brief Parameters controlled by the platform to configure the WAC process.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t macAddress[ 6 ]; /**< REQUIRED: Accessory MAC address, e.g. 00:11:22:33:44:55. */
|
||||
|
||||
bool isUnconfigured; /**< TRUE/FALSE: whether the accessory is unconfigured. Should be true for current cases. */
|
||||
bool supportsAirPlay; /**< TRUE/FALSE: whether the accessory supports AirPlay. */
|
||||
bool supportsAirPrint; /**< TRUE/FALSE: whether the accessory supports AirPrint. */
|
||||
bool supports2_4GHzWiFi; /**< TRUE/FALSE: whether the accessory supports 2.4 GHz Wi-Fi. */
|
||||
bool supports5GHzWiFi; /**< TRUE/FALSE: whether the accessory supports 5 GHz Wi-Fi. */
|
||||
bool supportsWakeOnWireless; /**< TRUE/FALSE: whether the accessory supports Wake On Wireless. */
|
||||
|
||||
char *firmwareRevision; /**< REQUIRED: Version of the accessory's firmware, e.g. 1.0.0. */
|
||||
char *hardwareRevision; /**< REQUIRED: Version of the accessory's hardware, e.g. 1.0.0. */
|
||||
char *serialNumber; /**< OPTIONAL: Accessory's serial number. */
|
||||
|
||||
char *name; /**< REQUIRED: Name of the accessory. */
|
||||
char *model; /**< REQUIRED: Model name of the accessory. */
|
||||
char *manufacturer; /**< REQUIRED: Manufacturer name of the accessory. */
|
||||
|
||||
char **eaProtocols; /**< OPTIONAL: Array of EA Protocol strings. */
|
||||
uint8_t numEAProtocols; /**< OPTIONAL: Number of EA Protocol strings contained in the eaProtocols array. */
|
||||
char *eaBundleSeedID; /**< OPTIONAL: Accessory manufacturer's BundleSeedID. */
|
||||
|
||||
} WACPlatformParameters_t;
|
||||
|
||||
void mfi_wac_lib_version( uint8_t *major, uint8_t *minor, uint8_t *revision );
|
||||
|
||||
OSStatus mfi_wac_start( mico_Context_t * const inContext, WACPlatformParameters_t *inWACPara, mico_i2c_t i2c, int timeOut );
|
||||
|
||||
OSStatus mfi_wac_stop( void );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file MFi_WAC.h
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide header file for start a Apple WAC (wireless accessory
|
||||
* configuration) function thread.
|
||||
******************************************************************************
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "mico.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define BUNDLE_SEED_ID "C6P64J2MZX"
|
||||
#define EA_PROTOCOL "com.issc.datapath"
|
||||
|
||||
/**
|
||||
* @brief Parameters controlled by the platform to configure the WAC process.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t macAddress[ 6 ]; /**< REQUIRED: Accessory MAC address, e.g. 00:11:22:33:44:55. */
|
||||
|
||||
bool isUnconfigured; /**< TRUE/FALSE: whether the accessory is unconfigured. Should be true for current cases. */
|
||||
bool supportsAirPlay; /**< TRUE/FALSE: whether the accessory supports AirPlay. */
|
||||
bool supportsAirPrint; /**< TRUE/FALSE: whether the accessory supports AirPrint. */
|
||||
bool supports2_4GHzWiFi; /**< TRUE/FALSE: whether the accessory supports 2.4 GHz Wi-Fi. */
|
||||
bool supports5GHzWiFi; /**< TRUE/FALSE: whether the accessory supports 5 GHz Wi-Fi. */
|
||||
bool supportsWakeOnWireless; /**< TRUE/FALSE: whether the accessory supports Wake On Wireless. */
|
||||
|
||||
char *firmwareRevision; /**< REQUIRED: Version of the accessory's firmware, e.g. 1.0.0. */
|
||||
char *hardwareRevision; /**< REQUIRED: Version of the accessory's hardware, e.g. 1.0.0. */
|
||||
char *serialNumber; /**< OPTIONAL: Accessory's serial number. */
|
||||
|
||||
char *name; /**< REQUIRED: Name of the accessory. */
|
||||
char *model; /**< REQUIRED: Model name of the accessory. */
|
||||
char *manufacturer; /**< REQUIRED: Manufacturer name of the accessory. */
|
||||
|
||||
char **eaProtocols; /**< OPTIONAL: Array of EA Protocol strings. */
|
||||
uint8_t numEAProtocols; /**< OPTIONAL: Number of EA Protocol strings contained in the eaProtocols array. */
|
||||
char *eaBundleSeedID; /**< OPTIONAL: Accessory manufacturer's BundleSeedID. */
|
||||
|
||||
} WACPlatformParameters_t;
|
||||
|
||||
void mfi_wac_lib_version( uint8_t *major, uint8_t *minor, uint8_t *revision );
|
||||
|
||||
OSStatus mfi_wac_start( mico_Context_t * const inContext, WACPlatformParameters_t *inWACPara, mico_i2c_t i2c, int timeOut );
|
||||
|
||||
OSStatus mfi_wac_stop( void );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#
|
||||
# Copyright 2016, MXCHIP Corporation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
|
||||
MFi_WAC_DIR := src
|
||||
|
||||
$(NAME)_SOURCES += \
|
||||
$(MFi_WAC_DIR)/MFi-SAP.c \
|
||||
$(MFi_WAC_DIR)/MFiSAPServer.c \
|
||||
$(MFi_WAC_DIR)/WAC.c
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Copyright 2016, MXCHIP Corporation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
|
||||
MFi_WAC_DIR := src
|
||||
|
||||
$(NAME)_SOURCES += \
|
||||
$(MFi_WAC_DIR)/MFi-SAP.c \
|
||||
$(MFi_WAC_DIR)/MFiSAPServer.c \
|
||||
$(MFi_WAC_DIR)/WAC.c
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
NAME := Lib_MiCO_System_WAC
|
||||
|
||||
ifneq ($(wildcard $(CURDIR)Lib_MFi_WAC.$(HOST_ARCH).$(TOOLCHAIN_NAME).release.a),)
|
||||
$(NAME)_PREBUILT_LIBRARY := Lib_MFi_WAC.$(HOST_ARCH).$(TOOLCHAIN_NAME).release.a
|
||||
else
|
||||
# Build from source
|
||||
include $(CURDIR)Lib_MFi_WAC_src.mk
|
||||
endif
|
||||
|
||||
$(NAME)_COMPONENTS += drivers/MiCODriverMFiAuth
|
||||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
NAME := Lib_MiCO_System_WAC
|
||||
|
||||
ifneq ($(wildcard $(CURDIR)Lib_MFi_WAC.$(HOST_ARCH).$(TOOLCHAIN_NAME).release.a),)
|
||||
$(NAME)_PREBUILT_LIBRARY := Lib_MFi_WAC.$(HOST_ARCH).$(TOOLCHAIN_NAME).release.a
|
||||
else
|
||||
# Build from source
|
||||
include $(CURDIR)Lib_MFi_WAC_src.mk
|
||||
endif
|
||||
|
||||
$(NAME)_COMPONENTS += drivers/MiCODriverMFiAuth
|
||||
|
||||
|
||||
@@ -1,175 +1,175 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_easylink.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 20-July-2015
|
||||
* @brief This file provide the easylink function for quick provisioning and
|
||||
* first time 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 "StringUtils.h"
|
||||
#include "system_internal.h"
|
||||
|
||||
|
||||
static void _bonjour_generate_txt_record( char *txt_record, uint32_t easyLink_id, WiFi_Interface interface,
|
||||
system_context_t * const inContext )
|
||||
{
|
||||
char *temp_txt2 = NULL;
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( FIRMWARE_REVISION );
|
||||
sprintf( txt_record, "FW=%s.", temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( HARDWARE_REVISION );
|
||||
sprintf( txt_record, "%sHD=%s.", txt_record, temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( PROTOCOL );
|
||||
sprintf( txt_record, "%sPO=%s.", txt_record, temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( inContext->micoStatus.rf_version );
|
||||
sprintf( txt_record, "%sRF=%s.", txt_record, temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( inContext->micoStatus.mac );
|
||||
sprintf( txt_record, "%sMAC=%s.", txt_record, temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( MicoGetVer( ) );
|
||||
sprintf( txt_record, "%sOS=%s.", txt_record, temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( MODEL );
|
||||
sprintf( txt_record, "%sMD=%s.", txt_record, temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( MANUFACTURER );
|
||||
sprintf( txt_record, "%sMF=%s.", txt_record, temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
if ( interface == Soft_AP )
|
||||
{
|
||||
sprintf( txt_record, "%swlan unconfigured=T.", txt_record );
|
||||
sprintf( txt_record, "%sFTC=T.", txt_record );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( txt_record, "%swlan unconfigured=F.", txt_record );
|
||||
#ifdef MICO_CONFIG_SERVER_ENABLE
|
||||
sprintf(txt_record, "%sFTC=T.", txt_record);
|
||||
#else
|
||||
sprintf( txt_record, "%sFTC=F.", txt_record );
|
||||
#endif
|
||||
}
|
||||
|
||||
sprintf( txt_record, "%sID=%lx.", txt_record, easyLink_id );
|
||||
}
|
||||
|
||||
OSStatus easylink_bonjour_start( WiFi_Interface interface, uint32_t easyLink_id, system_context_t * const inContext )
|
||||
{
|
||||
char *temp_txt = NULL;
|
||||
OSStatus err = kNoErr;
|
||||
net_para_st para;
|
||||
mdns_init_t init;
|
||||
|
||||
temp_txt = malloc( 500 );
|
||||
require_action( temp_txt, exit, err = kNoMemoryErr );
|
||||
|
||||
memset( &init, 0x0, sizeof(mdns_init_t) );
|
||||
|
||||
micoWlanGetIPStatus( ¶, interface );
|
||||
|
||||
init.service_name = "_easylink_config._tcp.local.";
|
||||
|
||||
/* name(xxxxxx).local. */
|
||||
snprintf( temp_txt, 100, "%s(%c%c%c%c%c%c).local.", 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] );
|
||||
init.host_name = (char*) __strdup( temp_txt );
|
||||
|
||||
/* name(xxxxxx). */
|
||||
snprintf( temp_txt, 100, "%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] );
|
||||
init.instance_name = (char*) __strdup( temp_txt );
|
||||
|
||||
init.service_port = MICO_CONFIG_SERVER_PORT;
|
||||
|
||||
_bonjour_generate_txt_record( temp_txt, easyLink_id, interface, inContext );
|
||||
|
||||
init.txt_record = (char*) __strdup( temp_txt );
|
||||
|
||||
if ( interface == Soft_AP )
|
||||
mdns_add_record( init, interface, 1500 );
|
||||
else
|
||||
mdns_add_record( init, interface, 10 );
|
||||
|
||||
free( init.host_name );
|
||||
free( init.instance_name );
|
||||
free( init.txt_record );
|
||||
|
||||
exit:
|
||||
if ( temp_txt ) free( temp_txt );
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus easylink_bonjour_update( WiFi_Interface interface, uint32_t easyLink_id, system_context_t * const inContext )
|
||||
{
|
||||
char *temp_txt = NULL;
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
temp_txt = malloc( 500 );
|
||||
require_action( temp_txt, exit, err = kNoMemoryErr );
|
||||
|
||||
_bonjour_generate_txt_record( temp_txt, easyLink_id, interface, inContext );
|
||||
|
||||
mdns_update_txt_record( "_easylink_config._tcp.local.", interface, temp_txt );
|
||||
|
||||
exit:
|
||||
if ( temp_txt ) free( temp_txt );
|
||||
return err;
|
||||
}
|
||||
|
||||
void easylink_remove_bonjour( void )
|
||||
{
|
||||
mdns_record_state_t easylink_service_state = RECORD_REMOVED;
|
||||
|
||||
/* Remove previous _easylink_config service if existed */
|
||||
easylink_service_state = mdns_get_record_status( "_easylink_config._tcp.local.", Station);
|
||||
if ( easylink_service_state != RECORD_REMOVED )
|
||||
{
|
||||
UnSetTimer( easylink_remove_bonjour );
|
||||
mdns_suspend_record( "_easylink_config._tcp.local.", Station, true );
|
||||
mico_rtos_delay_milliseconds( 1500 );
|
||||
}
|
||||
|
||||
/* Remove previous _easylink_config service if existed */
|
||||
easylink_service_state = mdns_get_record_status( "_easylink_config._tcp.local.", Soft_AP);
|
||||
if ( easylink_service_state != RECORD_REMOVED )
|
||||
{
|
||||
mdns_suspend_record( "_easylink_config._tcp.local.", Soft_AP, true );
|
||||
mico_rtos_delay_milliseconds( 1500 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_easylink.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 20-July-2015
|
||||
* @brief This file provide the easylink function for quick provisioning and
|
||||
* first time 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 "StringUtils.h"
|
||||
#include "system_internal.h"
|
||||
|
||||
|
||||
static void _bonjour_generate_txt_record( char *txt_record, uint32_t easyLink_id, WiFi_Interface interface,
|
||||
system_context_t * const inContext )
|
||||
{
|
||||
char *temp_txt2 = NULL;
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( FIRMWARE_REVISION );
|
||||
sprintf( txt_record, "FW=%s.", temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( HARDWARE_REVISION );
|
||||
sprintf( txt_record, "%sHD=%s.", txt_record, temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( PROTOCOL );
|
||||
sprintf( txt_record, "%sPO=%s.", txt_record, temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( inContext->micoStatus.rf_version );
|
||||
sprintf( txt_record, "%sRF=%s.", txt_record, temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( inContext->micoStatus.mac );
|
||||
sprintf( txt_record, "%sMAC=%s.", txt_record, temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( MicoGetVer( ) );
|
||||
sprintf( txt_record, "%sOS=%s.", txt_record, temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( MODEL );
|
||||
sprintf( txt_record, "%sMD=%s.", txt_record, temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
temp_txt2 = __strdup_trans_dot( MANUFACTURER );
|
||||
sprintf( txt_record, "%sMF=%s.", txt_record, temp_txt2 );
|
||||
free( temp_txt2 );
|
||||
|
||||
if ( interface == Soft_AP )
|
||||
{
|
||||
sprintf( txt_record, "%swlan unconfigured=T.", txt_record );
|
||||
sprintf( txt_record, "%sFTC=T.", txt_record );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( txt_record, "%swlan unconfigured=F.", txt_record );
|
||||
#ifdef MICO_CONFIG_SERVER_ENABLE
|
||||
sprintf(txt_record, "%sFTC=T.", txt_record);
|
||||
#else
|
||||
sprintf( txt_record, "%sFTC=F.", txt_record );
|
||||
#endif
|
||||
}
|
||||
|
||||
sprintf( txt_record, "%sID=%lx.", txt_record, easyLink_id );
|
||||
}
|
||||
|
||||
OSStatus easylink_bonjour_start( WiFi_Interface interface, uint32_t easyLink_id, system_context_t * const inContext )
|
||||
{
|
||||
char *temp_txt = NULL;
|
||||
OSStatus err = kNoErr;
|
||||
net_para_st para;
|
||||
mdns_init_t init;
|
||||
|
||||
temp_txt = malloc( 500 );
|
||||
require_action( temp_txt, exit, err = kNoMemoryErr );
|
||||
|
||||
memset( &init, 0x0, sizeof(mdns_init_t) );
|
||||
|
||||
micoWlanGetIPStatus( ¶, interface );
|
||||
|
||||
init.service_name = "_easylink_config._tcp.local.";
|
||||
|
||||
/* name(xxxxxx).local. */
|
||||
snprintf( temp_txt, 100, "%s(%c%c%c%c%c%c).local.", 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] );
|
||||
init.host_name = (char*) __strdup( temp_txt );
|
||||
|
||||
/* name(xxxxxx). */
|
||||
snprintf( temp_txt, 100, "%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] );
|
||||
init.instance_name = (char*) __strdup( temp_txt );
|
||||
|
||||
init.service_port = MICO_CONFIG_SERVER_PORT;
|
||||
|
||||
_bonjour_generate_txt_record( temp_txt, easyLink_id, interface, inContext );
|
||||
|
||||
init.txt_record = (char*) __strdup( temp_txt );
|
||||
|
||||
if ( interface == Soft_AP )
|
||||
mdns_add_record( init, interface, 1500 );
|
||||
else
|
||||
mdns_add_record( init, interface, 10 );
|
||||
|
||||
free( init.host_name );
|
||||
free( init.instance_name );
|
||||
free( init.txt_record );
|
||||
|
||||
exit:
|
||||
if ( temp_txt ) free( temp_txt );
|
||||
return err;
|
||||
}
|
||||
|
||||
OSStatus easylink_bonjour_update( WiFi_Interface interface, uint32_t easyLink_id, system_context_t * const inContext )
|
||||
{
|
||||
char *temp_txt = NULL;
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
temp_txt = malloc( 500 );
|
||||
require_action( temp_txt, exit, err = kNoMemoryErr );
|
||||
|
||||
_bonjour_generate_txt_record( temp_txt, easyLink_id, interface, inContext );
|
||||
|
||||
mdns_update_txt_record( "_easylink_config._tcp.local.", interface, temp_txt );
|
||||
|
||||
exit:
|
||||
if ( temp_txt ) free( temp_txt );
|
||||
return err;
|
||||
}
|
||||
|
||||
void easylink_remove_bonjour( void )
|
||||
{
|
||||
mdns_record_state_t easylink_service_state = RECORD_REMOVED;
|
||||
|
||||
/* Remove previous _easylink_config service if existed */
|
||||
easylink_service_state = mdns_get_record_status( "_easylink_config._tcp.local.", Station);
|
||||
if ( easylink_service_state != RECORD_REMOVED )
|
||||
{
|
||||
UnSetTimer( easylink_remove_bonjour );
|
||||
mdns_suspend_record( "_easylink_config._tcp.local.", Station, true );
|
||||
mico_rtos_delay_milliseconds( 1500 );
|
||||
}
|
||||
|
||||
/* Remove previous _easylink_config service if existed */
|
||||
easylink_service_state = mdns_get_record_status( "_easylink_config._tcp.local.", Soft_AP);
|
||||
if ( easylink_service_state != RECORD_REMOVED )
|
||||
{
|
||||
mdns_suspend_record( "_easylink_config._tcp.local.", Soft_AP, true );
|
||||
mico_rtos_delay_milliseconds( 1500 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,44 +1,44 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file airkiss_discovery.h
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 28-10-2015
|
||||
* @brief Head file for WECHAT device discovery protocol
|
||||
******************************************************************************
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __EASYLINK_INTERNAL_H
|
||||
#define __EASYLINK_INTERNAL_H
|
||||
|
||||
#include "mico.h"
|
||||
#include "system_internal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
OSStatus easylink_bonjour_start( WiFi_Interface interface, uint32_t easyLink_id, system_context_t * const inContext );
|
||||
OSStatus easylink_bonjour_update( WiFi_Interface interface, uint32_t easyLink_id, system_context_t * const inContext );
|
||||
void easylink_remove_bonjour( void );
|
||||
|
||||
|
||||
OSStatus easylink_softap_start( system_context_t * const inContext );
|
||||
uint32_t easylink_softap_get_identifier( void );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C" */
|
||||
#endif
|
||||
|
||||
#endif //__EASYLINK_INTERNAL_H
|
||||
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file airkiss_discovery.h
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 28-10-2015
|
||||
* @brief Head file for WECHAT device discovery protocol
|
||||
******************************************************************************
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __EASYLINK_INTERNAL_H
|
||||
#define __EASYLINK_INTERNAL_H
|
||||
|
||||
#include "mico.h"
|
||||
#include "system_internal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
OSStatus easylink_bonjour_start( WiFi_Interface interface, uint32_t easyLink_id, system_context_t * const inContext );
|
||||
OSStatus easylink_bonjour_update( WiFi_Interface interface, uint32_t easyLink_id, system_context_t * const inContext );
|
||||
void easylink_remove_bonjour( void );
|
||||
|
||||
|
||||
OSStatus easylink_softap_start( system_context_t * const inContext );
|
||||
uint32_t easylink_softap_get_identifier( void );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C" */
|
||||
#endif
|
||||
|
||||
#endif //__EASYLINK_INTERNAL_H
|
||||
|
||||
|
||||
|
||||
@@ -1,304 +1,334 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_easylink.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 20-July-2015
|
||||
* @brief This file provide the easylink function for quick provisioning and
|
||||
* first time 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 "easylink_internal.h"
|
||||
|
||||
#include "StringUtils.h"
|
||||
|
||||
//#if (MICO_WLAN_CONFIG_MODE == CONFIG_MODE_EASYLINK) || (MICO_WLAN_CONFIG_MODE == CONFIG_MODE_EASYLINK_WITH_SOFTAP)
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
/* EasyLink event callback functions*/
|
||||
static void easylink_wifi_status_cb( WiFiEvent event, system_context_t * const inContext );
|
||||
static void easylink_complete_cb( network_InitTypeDef_st *nwkpara, system_context_t * const inContext );
|
||||
static void easylink_extra_data_cb( int datalen, char* data, system_context_t * const inContext );
|
||||
|
||||
/* Thread perform easylink and connect to wlan */
|
||||
static void easylink_thread( uint32_t inContext ); /* Perform easylink and connect to wlan */
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
static mico_semaphore_t easylink_sem; /**< Used to suspend thread while easylink. */
|
||||
static mico_semaphore_t easylink_connect_sem; /**< Used to suspend thread while connection. */
|
||||
static bool easylink_success = false; /**< true: connect to wlan, false: start soft ap mode or roll back to previous settings */
|
||||
static uint32_t easylinkIndentifier = 0; /**< Unique for an easylink instance. */
|
||||
static mico_thread_t easylink_thread_handler = NULL;
|
||||
static bool easylink_thread_force_exit = false;
|
||||
|
||||
static mico_config_source_t source = CONFIG_BY_NONE;
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
/* MiCO callback when WiFi status is changed */
|
||||
static void easylink_wifi_status_cb( WiFiEvent event, system_context_t * const inContext )
|
||||
{
|
||||
switch ( event )
|
||||
{
|
||||
case NOTIFY_STATION_UP:
|
||||
/* Connected to AP, means that the wlan configuration is right, update configuration in flash and update
|
||||
bongjour txt record with new "easylinkIndentifier" */
|
||||
easylink_bonjour_update( Station, easylinkIndentifier, inContext );
|
||||
inContext->flashContentInRam.micoSystemConfig.configured = allConfigured;
|
||||
mico_system_context_update( &inContext->flashContentInRam ); //Update Flash content
|
||||
mico_rtos_set_semaphore( &easylink_connect_sem ); //Notify Easylink thread
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* MiCO callback when EasyLink is finished step 1, return SSID and KEY */
|
||||
static void easylink_complete_cb( network_InitTypeDef_st *nwkpara, system_context_t * const inContext )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_string( nwkpara, exit, err = kTimeoutErr, "EasyLink Timeout or terminated" );
|
||||
|
||||
/* Store SSID and KEY*/
|
||||
mico_rtos_lock_mutex( &inContext->flashContentInRam_mutex );
|
||||
memcpy( inContext->flashContentInRam.micoSystemConfig.ssid, nwkpara->wifi_ssid, maxSsidLen );
|
||||
memset( inContext->flashContentInRam.micoSystemConfig.bssid, 0x0, 6 );
|
||||
memcpy( inContext->flashContentInRam.micoSystemConfig.user_key, nwkpara->wifi_key, maxKeyLen );
|
||||
inContext->flashContentInRam.micoSystemConfig.user_keyLength = strlen( nwkpara->wifi_key );
|
||||
inContext->flashContentInRam.micoSystemConfig.dhcpEnable = true;
|
||||
mico_rtos_unlock_mutex( &inContext->flashContentInRam_mutex );
|
||||
system_log("Get SSID: %s, Key: %s", inContext->flashContentInRam.micoSystemConfig.ssid, inContext->flashContentInRam.micoSystemConfig.user_key);
|
||||
|
||||
source = (mico_config_source_t) nwkpara->wifi_retry_interval;
|
||||
exit:
|
||||
if ( err != kNoErr )
|
||||
{
|
||||
/*EasyLink timeout or error*/
|
||||
easylink_success = false;
|
||||
mico_rtos_set_semaphore( &easylink_sem );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* MiCO callback when EasyLink is finished step 2, return extra data
|
||||
data format: [AuthData#Identifier]<localIp/netMask/gateWay/dnsServer>
|
||||
Auth data: Provide to application, application will decide if this is a proter configuration for currnet device
|
||||
Identifier: Unique id for every easylink instance send by easylink mobile app
|
||||
localIp/netMask/gateWay/dnsServer: Device static ip address, use DHCP if not exist
|
||||
*/
|
||||
static void easylink_extra_data_cb( int datalen, char* data, system_context_t * const inContext )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
int index;
|
||||
uint32_t *identifier, ipInfoCount;
|
||||
char *debugString;
|
||||
struct in_addr ipv4_addr;
|
||||
|
||||
debugString = DataToHexStringWithSpaces( (const uint8_t *) data, datalen );
|
||||
system_log("Get user info: %s", debugString);
|
||||
free( debugString );
|
||||
|
||||
/* Find '#' that separate authdata and identifier*/
|
||||
for ( index = datalen - 1; index >= 0; index-- )
|
||||
{
|
||||
if ( data[index] == '#' && ((datalen - index) == 5 || (datalen - index) == 25) )
|
||||
break;
|
||||
}
|
||||
require_action( index >= 0, exit, err = kParamErr );
|
||||
|
||||
/* Check auth data by device */
|
||||
data[index++] = 0x0;
|
||||
err = mico_system_delegate_config_recv_auth_data( data );
|
||||
require_noerr( err, exit );
|
||||
|
||||
/* Read identifier */
|
||||
identifier = (uint32_t *) &data[index];
|
||||
easylinkIndentifier = *identifier;
|
||||
|
||||
/* Identifier: 1 x uint32_t or Identifier/localIp/netMask/gateWay/dnsServer: 5 x uint32_t */
|
||||
ipInfoCount = (datalen - index) / sizeof(uint32_t);
|
||||
require_action( ipInfoCount >= 1, exit, err = kParamErr );
|
||||
|
||||
mico_rtos_lock_mutex( &inContext->flashContentInRam_mutex );
|
||||
|
||||
if ( ipInfoCount == 1 )
|
||||
{ //Use DHCP to obtain local ip address
|
||||
inContext->flashContentInRam.micoSystemConfig.dhcpEnable = true;
|
||||
system_log("Get auth info: %s, EasyLink identifier: %lx", data, easylinkIndentifier);
|
||||
} else
|
||||
{ //Use static ip address
|
||||
inContext->flashContentInRam.micoSystemConfig.dhcpEnable = false;
|
||||
ipv4_addr.s_addr = *(identifier+1);
|
||||
strcpy( (char *) inContext->micoStatus.localIp, inet_ntoa( ipv4_addr ) );
|
||||
ipv4_addr.s_addr = *(identifier+2);
|
||||
strcpy( (char *) inContext->micoStatus.netMask, inet_ntoa( ipv4_addr ) );
|
||||
ipv4_addr.s_addr = *(identifier+3);
|
||||
strcpy( (char *) inContext->micoStatus.gateWay, inet_ntoa( ipv4_addr ) );
|
||||
ipv4_addr.s_addr = *(identifier+4);
|
||||
strcpy( (char *) inContext->micoStatus.dnsServer, inet_ntoa( ipv4_addr ) );
|
||||
|
||||
system_log("Get auth info: %s, EasyLink identifier: %lx, local IP info:%s %s %s %s ", data, easylinkIndentifier, inContext->flashContentInRam.micoSystemConfig.localIp,
|
||||
inContext->flashContentInRam.micoSystemConfig.netMask, inContext->flashContentInRam.micoSystemConfig.gateWay,inContext->flashContentInRam.micoSystemConfig.dnsServer);
|
||||
}
|
||||
mico_rtos_unlock_mutex( &inContext->flashContentInRam_mutex );
|
||||
source = CONFIG_BY_EASYLINK_V2;
|
||||
|
||||
exit:
|
||||
if ( err != kNoErr )
|
||||
{
|
||||
/*EasyLink error*/
|
||||
system_log("EasyLink step 2 ERROR, err: %d", err);
|
||||
easylink_success = false;
|
||||
} else
|
||||
/* Easylink success after step 1 and step 2 */
|
||||
easylink_success = true;
|
||||
|
||||
mico_rtos_set_semaphore( &easylink_sem );
|
||||
return;
|
||||
}
|
||||
|
||||
static void easylink_thread( uint32_t arg )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
system_context_t *context = (system_context_t *) arg;
|
||||
|
||||
easylinkIndentifier = 0x0;
|
||||
easylink_success = false;
|
||||
easylink_thread_force_exit = false;
|
||||
|
||||
source = CONFIG_BY_NONE;
|
||||
mico_system_notify_register( mico_notify_EASYLINK_WPS_COMPLETED, (void *) easylink_complete_cb, context );
|
||||
mico_system_notify_register( mico_notify_EASYLINK_GET_EXTRA_DATA, (void *) easylink_extra_data_cb, context );
|
||||
mico_system_notify_register( mico_notify_WIFI_STATUS_CHANGED, (void *) easylink_wifi_status_cb, context );
|
||||
|
||||
mico_rtos_init_semaphore( &easylink_sem, 1 );
|
||||
mico_rtos_init_semaphore( &easylink_connect_sem, 1 );
|
||||
|
||||
restart:
|
||||
mico_system_delegate_config_will_start( );
|
||||
system_log("Start easylink combo mode");
|
||||
micoWlanStartEasyLinkPlus( EasyLink_TimeOut / 1000 );
|
||||
while( mico_rtos_get_semaphore( &easylink_sem, 0 ) == kNoErr );
|
||||
err = mico_rtos_get_semaphore( &easylink_sem, MICO_WAIT_FOREVER );
|
||||
|
||||
/* Easylink force exit by user, clean and exit */
|
||||
if( err != kNoErr && easylink_thread_force_exit )
|
||||
{
|
||||
system_log("EasyLink waiting for terminate");
|
||||
micoWlanStopEasyLinkPlus( );
|
||||
mico_rtos_get_semaphore( &easylink_sem, 3000 );
|
||||
system_log("EasyLink canceled by user");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* EasyLink Success */
|
||||
if ( easylink_success == true )
|
||||
{
|
||||
mico_system_delegate_config_recv_ssid( context->flashContentInRam.micoSystemConfig.ssid,
|
||||
context->flashContentInRam.micoSystemConfig.user_key );
|
||||
system_connect_wifi_normal( context );
|
||||
|
||||
/* Wait for station connection */
|
||||
while( mico_rtos_get_semaphore( &easylink_connect_sem, 0 ) == kNoErr );
|
||||
err = mico_rtos_get_semaphore( &easylink_connect_sem, EasyLink_ConnectWlan_Timeout );
|
||||
/* Easylink force exit by user, clean and exit */
|
||||
if( err != kNoErr && easylink_thread_force_exit )
|
||||
{
|
||||
micoWlanSuspend();
|
||||
system_log("EasyLink connection canceled by user");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*SSID or Password is not correct, module cannot connect to wlan, so restart EasyLink again*/
|
||||
require_noerr_action_string( err, restart, micoWlanSuspend(), "Re-start easylink combo mode" );
|
||||
mico_system_delegate_config_success( source );
|
||||
|
||||
/* Start bonjour service for new device discovery */
|
||||
err = easylink_bonjour_start( Station, easylinkIndentifier, context );
|
||||
require_noerr( err, exit );
|
||||
SetTimer( 60 * 1000, easylink_remove_bonjour );
|
||||
|
||||
goto exit;
|
||||
}
|
||||
else /* EasyLink failed */
|
||||
{
|
||||
/* so roll back to previous settings (if it has) and connect */
|
||||
if ( context->flashContentInRam.micoSystemConfig.configured != unConfigured ) {
|
||||
system_log("Roll back to previous settings");
|
||||
MICOReadConfiguration( context );
|
||||
system_connect_wifi_normal( context );
|
||||
}
|
||||
else {
|
||||
/*module should power down in default setting*/
|
||||
system_log("Wi-Fi power off");
|
||||
micoWlanPowerOff();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
easylink_thread_force_exit = false;
|
||||
|
||||
mico_system_delegate_config_will_stop( );
|
||||
|
||||
mico_system_notify_remove( mico_notify_WIFI_STATUS_CHANGED, (void *)easylink_wifi_status_cb );
|
||||
mico_system_notify_remove( mico_notify_EASYLINK_WPS_COMPLETED, (void *)easylink_complete_cb );
|
||||
mico_system_notify_remove( mico_notify_EASYLINK_GET_EXTRA_DATA, (void *)easylink_extra_data_cb );
|
||||
|
||||
mico_rtos_deinit_semaphore( &easylink_sem );
|
||||
mico_rtos_deinit_semaphore( &easylink_connect_sem );
|
||||
easylink_thread_handler = NULL;
|
||||
mico_rtos_delete_thread( NULL );
|
||||
}
|
||||
|
||||
OSStatus mico_easylink( mico_Context_t * const in_context, mico_bool_t enable )
|
||||
{
|
||||
OSStatus err = kUnknownErr;
|
||||
|
||||
require_action( in_context, exit, err = kNotPreparedErr );
|
||||
|
||||
easylink_remove_bonjour( );
|
||||
|
||||
/* easylink thread existed? stop! */
|
||||
if ( easylink_thread_handler ) {
|
||||
system_log("EasyLink processing, force stop..");
|
||||
easylink_thread_force_exit = true;
|
||||
mico_rtos_thread_force_awake( &easylink_thread_handler );
|
||||
mico_rtos_thread_join( &easylink_thread_handler );
|
||||
}
|
||||
|
||||
if ( enable == MICO_TRUE ) {
|
||||
err = mico_rtos_create_thread( &easylink_thread_handler, MICO_APPLICATION_PRIORITY, "EASYLINK", easylink_thread,
|
||||
0x1000, (mico_thread_arg_t) in_context );
|
||||
require_noerr_string( err, exit, "ERROR: Unable to start the EasyLink thread." );
|
||||
|
||||
/* Make sure easylink is already running, and waiting for sem trigger */
|
||||
mico_rtos_delay_milliseconds( 100 );
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
//#endif
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_easylink.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 20-July-2015
|
||||
* @brief This file provide the easylink function for quick provisioning and
|
||||
* first time 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 "easylink_internal.h"
|
||||
|
||||
#include "StringUtils.h"
|
||||
|
||||
//#if (MICO_WLAN_CONFIG_MODE == CONFIG_MODE_EASYLINK) || (MICO_WLAN_CONFIG_MODE == CONFIG_MODE_EASYLINK_WITH_SOFTAP)
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
/* EasyLink event callback functions*/
|
||||
static void easylink_wifi_status_cb( WiFiEvent event, system_context_t * const inContext );
|
||||
static void easylink_complete_cb( network_InitTypeDef_st *nwkpara, system_context_t * const inContext );
|
||||
static void easylink_extra_data_cb( int datalen, char* data, system_context_t * const inContext );
|
||||
|
||||
/* Thread perform easylink and connect to wlan */
|
||||
static void easylink_thread( uint32_t inContext ); /* Perform easylink and connect to wlan */
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
static mico_semaphore_t easylink_sem; /**< Used to suspend thread while easylink. */
|
||||
static mico_semaphore_t easylink_connect_sem; /**< Used to suspend thread while connection. */
|
||||
static bool easylink_success = false; /**< true: connect to wlan, false: start soft ap mode or roll back to previous settings */
|
||||
static uint32_t easylinkIndentifier = 0; /**< Unique for an easylink instance. */
|
||||
static mico_thread_t easylink_thread_handler = NULL;
|
||||
static bool easylink_thread_force_exit = false;
|
||||
|
||||
static mico_config_source_t source = CONFIG_BY_NONE;
|
||||
static bool easylink_with_softap = false;
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
/* MiCO callback when WiFi status is changed */
|
||||
static void easylink_wifi_status_cb( WiFiEvent event, system_context_t * const inContext )
|
||||
{
|
||||
switch ( event )
|
||||
{
|
||||
case NOTIFY_STATION_UP:
|
||||
/* Connected to AP, means that the wlan configuration is right, update configuration in flash and update
|
||||
bongjour txt record with new "easylinkIndentifier" */
|
||||
easylink_bonjour_update( Station, easylinkIndentifier, inContext );
|
||||
inContext->flashContentInRam.micoSystemConfig.configured = allConfigured;
|
||||
mico_system_context_update( &inContext->flashContentInRam ); //Update Flash content
|
||||
mico_rtos_set_semaphore( &easylink_connect_sem ); //Notify Easylink thread
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* MiCO callback when EasyLink is finished step 1, return SSID and KEY */
|
||||
static void easylink_complete_cb( network_InitTypeDef_st *nwkpara, system_context_t * const inContext )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_string( nwkpara, exit, err = kTimeoutErr, "EasyLink Timeout or terminated" );
|
||||
|
||||
/* Store SSID and KEY*/
|
||||
mico_rtos_lock_mutex( &inContext->flashContentInRam_mutex );
|
||||
memcpy( inContext->flashContentInRam.micoSystemConfig.ssid, nwkpara->wifi_ssid, maxSsidLen );
|
||||
memset( inContext->flashContentInRam.micoSystemConfig.bssid, 0x0, 6 );
|
||||
memcpy( inContext->flashContentInRam.micoSystemConfig.user_key, nwkpara->wifi_key, maxKeyLen );
|
||||
inContext->flashContentInRam.micoSystemConfig.user_keyLength = strlen( nwkpara->wifi_key );
|
||||
inContext->flashContentInRam.micoSystemConfig.dhcpEnable = true;
|
||||
mico_rtos_unlock_mutex( &inContext->flashContentInRam_mutex );
|
||||
system_log("Get SSID: %s, Key: %s", inContext->flashContentInRam.micoSystemConfig.ssid, inContext->flashContentInRam.micoSystemConfig.user_key);
|
||||
|
||||
source = (mico_config_source_t) nwkpara->wifi_retry_interval;
|
||||
exit:
|
||||
if ( err != kNoErr )
|
||||
{
|
||||
/*EasyLink timeout or error*/
|
||||
easylink_success = false;
|
||||
mico_rtos_set_semaphore( &easylink_sem );
|
||||
}
|
||||
return;
|
||||
}
|
||||
#ifdef MICO_EASYLINK_AND_SOFTAP_ENABLED
|
||||
void easylink_uap_success(uint32_t id)
|
||||
{
|
||||
if (easylink_with_softap == false)
|
||||
return;
|
||||
|
||||
system_log("sofapt configured");
|
||||
easylinkIndentifier = id;
|
||||
easylink_success = true;
|
||||
micoWlanSuspendSoftAP();
|
||||
mico_rtos_set_semaphore( &easylink_sem );
|
||||
}
|
||||
|
||||
#endif
|
||||
/* MiCO callback when EasyLink is finished step 2, return extra data
|
||||
data format: [AuthData#Identifier]<localIp/netMask/gateWay/dnsServer>
|
||||
Auth data: Provide to application, application will decide if this is a proter configuration for currnet device
|
||||
Identifier: Unique id for every easylink instance send by easylink mobile app
|
||||
localIp/netMask/gateWay/dnsServer: Device static ip address, use DHCP if not exist
|
||||
*/
|
||||
static void easylink_extra_data_cb( int datalen, char* data, system_context_t * const inContext )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
int index;
|
||||
uint32_t ipInfoCount;
|
||||
char *debugString;
|
||||
struct in_addr ipv4_addr;
|
||||
|
||||
debugString = DataToHexStringWithSpaces( (const uint8_t *) data, datalen );
|
||||
system_log("Get user info: %s", debugString);
|
||||
free( debugString );
|
||||
|
||||
/* Find '#' that separate authdata and identifier*/
|
||||
for ( index = datalen - 1; index >= 0; index-- )
|
||||
{
|
||||
if ( data[index] == '#' && ((datalen - index) == 5 || (datalen - index) == 25) )
|
||||
break;
|
||||
}
|
||||
require_action( index >= 0, exit, err = kParamErr );
|
||||
|
||||
/* Check auth data by device */
|
||||
data[index++] = 0x0;
|
||||
err = mico_system_delegate_config_recv_auth_data( data );
|
||||
require_noerr( err, exit );
|
||||
|
||||
/* Read identifier */
|
||||
memcpy(&easylinkIndentifier, &data[index], 4);
|
||||
/* Identifier: 1 x uint32_t or Identifier/localIp/netMask/gateWay/dnsServer: 5 x uint32_t */
|
||||
ipInfoCount = (datalen - index) / sizeof(uint32_t);
|
||||
require_action( ipInfoCount >= 1, exit, err = kParamErr );
|
||||
|
||||
mico_rtos_lock_mutex( &inContext->flashContentInRam_mutex );
|
||||
|
||||
if ( ipInfoCount == 1 )
|
||||
{ //Use DHCP to obtain local ip address
|
||||
inContext->flashContentInRam.micoSystemConfig.dhcpEnable = true;
|
||||
system_log("Get auth info: %s, EasyLink identifier: %lx", data, easylinkIndentifier);
|
||||
} else
|
||||
{ //Use static ip address
|
||||
inContext->flashContentInRam.micoSystemConfig.dhcpEnable = false;
|
||||
memcpy(&ipv4_addr.s_addr, &data[index+4], 4);
|
||||
strcpy( (char *) inContext->micoStatus.localIp, inet_ntoa( ipv4_addr ) );
|
||||
memcpy(&ipv4_addr.s_addr, &data[index+8], 4);
|
||||
strcpy( (char *) inContext->micoStatus.netMask, inet_ntoa( ipv4_addr ) );
|
||||
memcpy(&ipv4_addr.s_addr, &data[index+12], 4);
|
||||
strcpy( (char *) inContext->micoStatus.gateWay, inet_ntoa( ipv4_addr ) );
|
||||
memcpy(&ipv4_addr.s_addr, &data[index+16], 4);
|
||||
strcpy( (char *) inContext->micoStatus.dnsServer, inet_ntoa( ipv4_addr ) );
|
||||
|
||||
system_log("Get auth info: %s, EasyLink identifier: %lx, local IP info:%s %s %s %s ", data, easylinkIndentifier, inContext->flashContentInRam.micoSystemConfig.localIp,
|
||||
inContext->flashContentInRam.micoSystemConfig.netMask, inContext->flashContentInRam.micoSystemConfig.gateWay,inContext->flashContentInRam.micoSystemConfig.dnsServer);
|
||||
}
|
||||
mico_rtos_unlock_mutex( &inContext->flashContentInRam_mutex );
|
||||
source = CONFIG_BY_EASYLINK_V2;
|
||||
|
||||
exit:
|
||||
if ( err != kNoErr )
|
||||
{
|
||||
/*EasyLink error*/
|
||||
system_log("EasyLink step 2 ERROR, err: %d", err);
|
||||
easylink_success = false;
|
||||
} else
|
||||
/* Easylink success after step 1 and step 2 */
|
||||
easylink_success = true;
|
||||
|
||||
mico_rtos_set_semaphore( &easylink_sem );
|
||||
return;
|
||||
}
|
||||
|
||||
static void easylink_thread( uint32_t arg )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
system_context_t *context = (system_context_t *) arg;
|
||||
|
||||
easylinkIndentifier = 0x0;
|
||||
easylink_success = false;
|
||||
easylink_thread_force_exit = false;
|
||||
|
||||
source = CONFIG_BY_NONE;
|
||||
mico_system_notify_register( mico_notify_EASYLINK_WPS_COMPLETED, (void *) easylink_complete_cb, context );
|
||||
mico_system_notify_register( mico_notify_EASYLINK_GET_EXTRA_DATA, (void *) easylink_extra_data_cb, context );
|
||||
mico_system_notify_register( mico_notify_WIFI_STATUS_CHANGED, (void *) easylink_wifi_status_cb, context );
|
||||
|
||||
mico_rtos_init_semaphore( &easylink_sem, 1 );
|
||||
mico_rtos_init_semaphore( &easylink_connect_sem, 1 );
|
||||
|
||||
restart:
|
||||
mico_system_delegate_config_will_start( );
|
||||
system_log("Start easylink combo mode");
|
||||
#ifdef MICO_EASYLINK_AND_SOFTAP_ENABLED
|
||||
if (easylink_with_softap == true) {
|
||||
char wifi_ssid[32];
|
||||
sprintf( wifi_ssid, "EasyLink_%c%c%c%c%c%c",
|
||||
context->micoStatus.mac[9], context->micoStatus.mac[10], context->micoStatus.mac[12],
|
||||
context->micoStatus.mac[13], context->micoStatus.mac[15], context->micoStatus.mac[16]);
|
||||
|
||||
system_log("Enable softap %s in easylink", wifi_ssid);
|
||||
OpenEasylink_softap( EasyLink_TimeOut / 1000, wifi_ssid, NULL, 6 );
|
||||
/* Start config server */
|
||||
config_server_start( );
|
||||
easylink_bonjour_start( Soft_AP, 0, context );
|
||||
} else
|
||||
#endif
|
||||
micoWlanStartEasyLinkPlus( EasyLink_TimeOut / 1000 );
|
||||
|
||||
while( mico_rtos_get_semaphore( &easylink_sem, 0 ) == kNoErr );
|
||||
err = mico_rtos_get_semaphore( &easylink_sem, EasyLink_TimeOut );
|
||||
|
||||
/* Easylink force exit by user, clean and exit */
|
||||
if( err != kNoErr && easylink_thread_force_exit )
|
||||
{
|
||||
system_log("EasyLink waiting for terminate");
|
||||
micoWlanStopEasyLinkPlus( );
|
||||
mico_rtos_get_semaphore( &easylink_sem, 3000 );
|
||||
system_log("EasyLink canceled by user");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* EasyLink Success */
|
||||
if ( easylink_success == true )
|
||||
{
|
||||
mico_system_delegate_config_recv_ssid( context->flashContentInRam.micoSystemConfig.ssid,
|
||||
context->flashContentInRam.micoSystemConfig.user_key );
|
||||
system_connect_wifi_normal( context );
|
||||
|
||||
/* Wait for station connection */
|
||||
while( mico_rtos_get_semaphore( &easylink_connect_sem, 0 ) == kNoErr );
|
||||
err = mico_rtos_get_semaphore( &easylink_connect_sem, EasyLink_ConnectWlan_Timeout );
|
||||
/* Easylink force exit by user, clean and exit */
|
||||
if( err != kNoErr && easylink_thread_force_exit )
|
||||
{
|
||||
micoWlanSuspend();
|
||||
system_log("EasyLink connection canceled by user");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*SSID or Password is not correct, module cannot connect to wlan, so restart EasyLink again*/
|
||||
require_noerr_action_string( err, restart, micoWlanSuspend(), "Re-start easylink combo mode" );
|
||||
mico_system_delegate_config_success( source );
|
||||
|
||||
/* Start bonjour service for new device discovery */
|
||||
err = easylink_bonjour_start( Station, easylinkIndentifier, context );
|
||||
require_noerr( err, exit );
|
||||
SetTimer( 60 * 1000, easylink_remove_bonjour );
|
||||
|
||||
goto exit;
|
||||
}
|
||||
else /* EasyLink failed */
|
||||
{
|
||||
/* so roll back to previous settings (if it has) and connect */
|
||||
if ( context->flashContentInRam.micoSystemConfig.configured != unConfigured ) {
|
||||
system_log("Roll back to previous settings");
|
||||
MICOReadConfiguration( context );
|
||||
system_connect_wifi_normal( context );
|
||||
}
|
||||
else {
|
||||
/*module should power down in default setting*/
|
||||
system_log("Wi-Fi power off");
|
||||
micoWlanPowerOff();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
easylink_thread_force_exit = false;
|
||||
|
||||
mico_system_delegate_config_will_stop( );
|
||||
|
||||
mico_system_notify_remove( mico_notify_WIFI_STATUS_CHANGED, (void *)easylink_wifi_status_cb );
|
||||
mico_system_notify_remove( mico_notify_EASYLINK_WPS_COMPLETED, (void *)easylink_complete_cb );
|
||||
mico_system_notify_remove( mico_notify_EASYLINK_GET_EXTRA_DATA, (void *)easylink_extra_data_cb );
|
||||
|
||||
mico_rtos_deinit_semaphore( &easylink_sem );
|
||||
mico_rtos_deinit_semaphore( &easylink_connect_sem );
|
||||
easylink_thread_handler = NULL;
|
||||
mico_rtos_delete_thread( NULL );
|
||||
}
|
||||
|
||||
OSStatus mico_easylink( mico_Context_t * const in_context, mico_bool_t enable, mico_bool_t softap )
|
||||
{
|
||||
OSStatus err = kUnknownErr;
|
||||
|
||||
require_action( in_context, exit, err = kNotPreparedErr );
|
||||
|
||||
easylink_remove_bonjour( );
|
||||
|
||||
/* easylink thread existed? stop! */
|
||||
if ( easylink_thread_handler ) {
|
||||
system_log("EasyLink processing, force stop..");
|
||||
easylink_thread_force_exit = true;
|
||||
mico_rtos_thread_force_awake( &easylink_thread_handler );
|
||||
mico_rtos_thread_join( &easylink_thread_handler );
|
||||
}
|
||||
|
||||
if ( enable == MICO_TRUE ) {
|
||||
if (softap == MICO_TRUE)
|
||||
easylink_with_softap = true;
|
||||
else
|
||||
easylink_with_softap = false;
|
||||
err = mico_rtos_create_thread( &easylink_thread_handler, MICO_APPLICATION_PRIORITY, "EASYLINK", easylink_thread,
|
||||
0x1000, (mico_thread_arg_t) in_context );
|
||||
require_noerr_string( err, exit, "ERROR: Unable to start the EasyLink thread." );
|
||||
|
||||
/* Make sure easylink is already running, and waiting for sem trigger */
|
||||
mico_rtos_delay_milliseconds( 100 );
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
//#endif
|
||||
|
||||
|
||||
@@ -1,125 +1,152 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_easylink_delegate.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide delegate functions from Easylink.
|
||||
******************************************************************************
|
||||
* 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 "platform_config.h"
|
||||
|
||||
#include "StringUtils.h"
|
||||
#include "system.h"
|
||||
|
||||
#define SYS_LED_TRIGGER_INTERVAL 100
|
||||
#define SYS_LED_TRIGGER_INTERVAL_AFTER_EASYLINK 500
|
||||
|
||||
static mico_timer_t _Led_EL_timer;
|
||||
static bool _Led_EL_timer_initialized = false;
|
||||
|
||||
static void _led_EL_Timeout_handler( void* arg )
|
||||
{
|
||||
(void)(arg);
|
||||
MicoGpioOutputTrigger((mico_gpio_t)MICO_SYS_LED);
|
||||
}
|
||||
|
||||
WEAK void mico_system_delegate_config_will_start( void )
|
||||
{
|
||||
/*Led trigger*/
|
||||
if(_Led_EL_timer_initialized == true)
|
||||
{
|
||||
mico_stop_timer(&_Led_EL_timer);
|
||||
mico_deinit_timer( &_Led_EL_timer );
|
||||
_Led_EL_timer_initialized = false;
|
||||
}
|
||||
|
||||
mico_init_timer(&_Led_EL_timer, SYS_LED_TRIGGER_INTERVAL, _led_EL_Timeout_handler, NULL);
|
||||
mico_start_timer(&_Led_EL_timer);
|
||||
_Led_EL_timer_initialized = true;
|
||||
return;
|
||||
}
|
||||
|
||||
WEAK void mico_system_delegate_soft_ap_will_start( void )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WEAK void mico_system_delegate_config_will_stop( void )
|
||||
{
|
||||
if(_Led_EL_timer_initialized == true)
|
||||
{
|
||||
mico_stop_timer(&_Led_EL_timer);
|
||||
mico_deinit_timer( &_Led_EL_timer );
|
||||
_Led_EL_timer_initialized = false;
|
||||
}
|
||||
MicoSysLed(true);
|
||||
return;
|
||||
}
|
||||
|
||||
WEAK void mico_system_delegate_config_recv_ssid ( char *ssid, char *key )
|
||||
{
|
||||
UNUSED_PARAMETER(ssid);
|
||||
UNUSED_PARAMETER(key);
|
||||
|
||||
if(_Led_EL_timer_initialized == true)
|
||||
{
|
||||
mico_stop_timer(&_Led_EL_timer);
|
||||
mico_deinit_timer( &_Led_EL_timer );
|
||||
_Led_EL_timer_initialized = false;
|
||||
}
|
||||
|
||||
mico_init_timer(&_Led_EL_timer, SYS_LED_TRIGGER_INTERVAL_AFTER_EASYLINK, _led_EL_Timeout_handler, NULL);
|
||||
mico_start_timer(&_Led_EL_timer);
|
||||
_Led_EL_timer_initialized = true;
|
||||
return;
|
||||
}
|
||||
|
||||
WEAK void mico_system_delegate_config_success( mico_config_source_t source )
|
||||
{
|
||||
//system_log( "Configed by %d", source );
|
||||
UNUSED_PARAMETER(source);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
WEAK OSStatus mico_system_delegate_config_recv_auth_data(char * anthData )
|
||||
{
|
||||
(void)(anthData);
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
WEAK void mico_easylink_monitor_delegate_will_start( void )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WEAK void mico_easylink_monitor_delegate_stoped( void )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WEAK void mico_easylink_monitor_delegate_connect_success( mico_config_source_t source )
|
||||
{
|
||||
UNUSED_PARAMETER( source );
|
||||
}
|
||||
|
||||
WEAK void mico_easylink_monitor_delegate_channel_changed( uint8_t currnet_channel )
|
||||
{
|
||||
UNUSED_PARAMETER( currnet_channel );
|
||||
}
|
||||
|
||||
WEAK void mico_easylink_monitor_delegate_package_recved( uint8_t * frame, int len )
|
||||
{
|
||||
UNUSED_PARAMETER( frame );
|
||||
UNUSED_PARAMETER( len );
|
||||
}
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_easylink_delegate.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide delegate functions from Easylink.
|
||||
******************************************************************************
|
||||
* 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 "platform_config.h"
|
||||
|
||||
#include "StringUtils.h"
|
||||
#include "system.h"
|
||||
|
||||
#define SYS_LED_TRIGGER_INTERVAL 100
|
||||
#define SYS_LED_TRIGGER_INTERVAL_AFTER_EASYLINK 500
|
||||
|
||||
static mico_timer_t _Led_EL_timer;
|
||||
static bool _Led_EL_timer_initialized = false;
|
||||
|
||||
static void _led_EL_Timeout_handler( void* arg )
|
||||
{
|
||||
(void)(arg);
|
||||
MicoGpioOutputTrigger((mico_gpio_t)MICO_SYS_LED);
|
||||
}
|
||||
|
||||
WEAK void mico_system_delegate_config_will_start( void )
|
||||
{
|
||||
/*Led trigger*/
|
||||
if(_Led_EL_timer_initialized == true)
|
||||
{
|
||||
mico_stop_timer(&_Led_EL_timer);
|
||||
mico_deinit_timer( &_Led_EL_timer );
|
||||
_Led_EL_timer_initialized = false;
|
||||
}
|
||||
|
||||
mico_init_timer(&_Led_EL_timer, SYS_LED_TRIGGER_INTERVAL, _led_EL_Timeout_handler, NULL);
|
||||
mico_start_timer(&_Led_EL_timer);
|
||||
_Led_EL_timer_initialized = true;
|
||||
return;
|
||||
}
|
||||
|
||||
WEAK void mico_system_delegate_soft_ap_will_start( void )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
WEAK void mico_system_delegate_config_will_stop( void )
|
||||
{
|
||||
if(_Led_EL_timer_initialized == true)
|
||||
{
|
||||
mico_stop_timer(&_Led_EL_timer);
|
||||
mico_deinit_timer( &_Led_EL_timer );
|
||||
_Led_EL_timer_initialized = false;
|
||||
}
|
||||
MicoSysLed(true);
|
||||
return;
|
||||
}
|
||||
|
||||
WEAK void mico_system_delegate_config_recv_ssid ( char *ssid, char *key )
|
||||
{
|
||||
UNUSED_PARAMETER(ssid);
|
||||
UNUSED_PARAMETER(key);
|
||||
|
||||
if(_Led_EL_timer_initialized == true)
|
||||
{
|
||||
mico_stop_timer(&_Led_EL_timer);
|
||||
mico_deinit_timer( &_Led_EL_timer );
|
||||
_Led_EL_timer_initialized = false;
|
||||
}
|
||||
|
||||
mico_init_timer(&_Led_EL_timer, SYS_LED_TRIGGER_INTERVAL_AFTER_EASYLINK, _led_EL_Timeout_handler, NULL);
|
||||
mico_start_timer(&_Led_EL_timer);
|
||||
_Led_EL_timer_initialized = true;
|
||||
return;
|
||||
}
|
||||
|
||||
WEAK mico_connect_fail_config_t mico_system_delegate_config_result( mico_config_source_t source, uint8_t result )
|
||||
{
|
||||
//system_log( "Configed by %d", source );
|
||||
UNUSED_PARAMETER(source);
|
||||
if(MICO_FALSE == result)
|
||||
{
|
||||
return RESTART_EASYLINK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return EXIT_EASYLINK;
|
||||
}
|
||||
}
|
||||
|
||||
WEAK void mico_system_delegate_config_success( mico_config_source_t source )
|
||||
{
|
||||
//system_log( "Configed by %d", source );
|
||||
UNUSED_PARAMETER(source);
|
||||
return;
|
||||
}
|
||||
|
||||
WEAK void mico_system_delegate_easylink_timeout( system_context_t *context )
|
||||
{
|
||||
/* so roll back to previous settings (if it has) and connect */
|
||||
if ( context->flashContentInRam.micoSystemConfig.configured != unConfigured ) {
|
||||
MICOReadConfiguration( context );
|
||||
system_connect_wifi_normal( context );
|
||||
}
|
||||
else {
|
||||
/*module should power down in default setting*/
|
||||
micoWlanPowerOff();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
WEAK OSStatus mico_system_delegate_config_recv_auth_data(char * anthData )
|
||||
{
|
||||
(void)(anthData);
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
WEAK void mico_easylink_monitor_delegate_will_start( void )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WEAK void mico_easylink_monitor_delegate_stoped( void )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WEAK void mico_easylink_monitor_delegate_connect_success( mico_config_source_t source )
|
||||
{
|
||||
UNUSED_PARAMETER( source );
|
||||
}
|
||||
|
||||
WEAK void mico_easylink_monitor_delegate_channel_changed( uint8_t currnet_channel )
|
||||
{
|
||||
UNUSED_PARAMETER( currnet_channel );
|
||||
}
|
||||
|
||||
WEAK void mico_easylink_monitor_delegate_package_recved( uint8_t * frame, int len )
|
||||
{
|
||||
UNUSED_PARAMETER( frame );
|
||||
UNUSED_PARAMETER( len );
|
||||
}
|
||||
|
||||
@@ -1,388 +1,388 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_easylink_monitor.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 20-May-2017
|
||||
* @brief This file provide the easylink function for quick provisioning and
|
||||
* first time 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 "easylink_internal.h"
|
||||
|
||||
#include "StringUtils.h"
|
||||
|
||||
//#if (MICO_WLAN_CONFIG_MODE == CONFIG_MODE_EASYLINK) || (MICO_WLAN_CONFIG_MODE == CONFIG_MODE_EASYLINK_WITH_SOFTAP)
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
/* EasyLink event callback functions*/
|
||||
static void easylink_wifi_status_cb( WiFiEvent event, system_context_t * const inContext );
|
||||
static void easylink_complete_cb( network_InitTypeDef_st *nwkpara, system_context_t * const inContext );
|
||||
static void easylink_extra_data_cb( int datalen, char* data, system_context_t * const inContext );
|
||||
|
||||
/* Thread perform easylink and connect to wlan */
|
||||
static void easylink_monitor_thread( uint32_t inContext ); /* Perform easylink and connect to wlan */
|
||||
|
||||
extern void mico_wlan_monitor_no_easylink(void);
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
static mico_timed_event_t _monitor_timed_check;
|
||||
static uint8_t wlan_channel = 1;
|
||||
static mico_bool_t wlan_channel_walker = MICO_TRUE;
|
||||
static uint32_t wlan_channel_walker_interval = 100;
|
||||
|
||||
static mico_semaphore_t easylink_sem; /**< Used to suspend thread while easylink. */
|
||||
static mico_semaphore_t easylink_connect_sem; /**< Used to suspend thread while connection. */
|
||||
static bool easylink_success = false; /**< true: connect to wlan, false: start soft ap mode or roll back to previous settings */
|
||||
static uint32_t easylink_id = 0; /**< Unique for an easylink instance. */
|
||||
static mico_thread_t easylink_monitor_thread_handler = NULL;
|
||||
static bool easylink_thread_force_exit = false;
|
||||
|
||||
static mico_config_source_t source = CONFIG_BY_NONE;
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
/* MiCO callback when WiFi status is changed */
|
||||
static void easylink_wifi_status_cb( WiFiEvent event, system_context_t * const inContext )
|
||||
{
|
||||
switch ( event )
|
||||
{
|
||||
case NOTIFY_STATION_UP:
|
||||
/* Connected to AP, means that the wlan configuration is right, update configuration in flash and update
|
||||
bongjour txt record with new "easylink_id" */
|
||||
easylink_bonjour_update( Station, easylink_id, inContext );
|
||||
inContext->flashContentInRam.micoSystemConfig.configured = allConfigured;
|
||||
mico_system_context_update( &inContext->flashContentInRam ); //Update Flash content
|
||||
mico_rtos_set_semaphore( &easylink_connect_sem ); //Notify Easylink thread
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* MiCO callback when EasyLink is finished step 1, return SSID and KEY */
|
||||
static void easylink_complete_cb( network_InitTypeDef_st *nwkpara, system_context_t * const inContext )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_string( nwkpara, exit, err = kTimeoutErr, "EasyLink Timeout or terminated" );
|
||||
|
||||
/* Store SSID and KEY*/
|
||||
mico_rtos_lock_mutex( &inContext->flashContentInRam_mutex );
|
||||
memcpy( inContext->flashContentInRam.micoSystemConfig.ssid, nwkpara->wifi_ssid, maxSsidLen );
|
||||
memset( inContext->flashContentInRam.micoSystemConfig.bssid, 0x0, 6 );
|
||||
memcpy( inContext->flashContentInRam.micoSystemConfig.user_key, nwkpara->wifi_key, maxKeyLen );
|
||||
inContext->flashContentInRam.micoSystemConfig.user_keyLength = strlen( nwkpara->wifi_key );
|
||||
inContext->flashContentInRam.micoSystemConfig.dhcpEnable = true;
|
||||
mico_rtos_unlock_mutex( &inContext->flashContentInRam_mutex );
|
||||
system_log("Get SSID: %s, Key: %s", inContext->flashContentInRam.micoSystemConfig.ssid, inContext->flashContentInRam.micoSystemConfig.user_key);
|
||||
|
||||
source = (mico_config_source_t) nwkpara->wifi_retry_interval;
|
||||
exit:
|
||||
if ( err != kNoErr )
|
||||
{
|
||||
/*EasyLink timeout or error*/
|
||||
easylink_success = false;
|
||||
mico_rtos_set_semaphore( &easylink_sem );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* MiCO callback when EasyLink is finished step 2, return extra data
|
||||
data format: [AuthData#Identifier]<localIp/netMask/gateWay/dnsServer>
|
||||
Auth data: Provide to application, application will decide if this is a proter configuration for currnet device
|
||||
Identifier: Unique id for every easylink instance send by easylink mobile app
|
||||
localIp/netMask/gateWay/dnsServer: Device static ip address, use DHCP if not exist
|
||||
*/
|
||||
static void easylink_extra_data_cb( int datalen, char* data, system_context_t * const inContext )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
int index;
|
||||
uint32_t *identifier, ipInfoCount;
|
||||
char *debugString;
|
||||
struct in_addr ipv4_addr;
|
||||
|
||||
debugString = DataToHexStringWithSpaces( (const uint8_t *) data, datalen );
|
||||
system_log("Get user info: %s", debugString);
|
||||
free( debugString );
|
||||
|
||||
/* Find '#' that separate authdata and identifier*/
|
||||
for ( index = datalen - 1; index >= 0; index-- )
|
||||
{
|
||||
if ( data[index] == '#' && ((datalen - index) == 5 || (datalen - index) == 25) )
|
||||
break;
|
||||
}
|
||||
require_action( index >= 0, exit, err = kParamErr );
|
||||
|
||||
/* Check auth data by device */
|
||||
data[index++] = 0x0;
|
||||
err = mico_system_delegate_config_recv_auth_data( data );
|
||||
require_noerr( err, exit );
|
||||
|
||||
/* Read identifier */
|
||||
identifier = (uint32_t *) &data[index];
|
||||
easylink_id = *identifier;
|
||||
|
||||
/* Identifier: 1 x uint32_t or Identifier/localIp/netMask/gateWay/dnsServer: 5 x uint32_t */
|
||||
ipInfoCount = (datalen - index) / sizeof(uint32_t);
|
||||
require_action( ipInfoCount >= 1, exit, err = kParamErr );
|
||||
|
||||
mico_rtos_lock_mutex( &inContext->flashContentInRam_mutex );
|
||||
|
||||
if ( ipInfoCount == 1 )
|
||||
{ //Use DHCP to obtain local ip address
|
||||
inContext->flashContentInRam.micoSystemConfig.dhcpEnable = true;
|
||||
system_log("Get auth info: %s, EasyLink identifier: %lx", data, easylink_id);
|
||||
} else
|
||||
{ //Use static ip address
|
||||
inContext->flashContentInRam.micoSystemConfig.dhcpEnable = false;
|
||||
ipv4_addr.s_addr = *(identifier+1);
|
||||
strcpy( (char *) inContext->micoStatus.localIp, inet_ntoa( ipv4_addr ) );
|
||||
ipv4_addr.s_addr = *(identifier+2);
|
||||
strcpy( (char *) inContext->micoStatus.netMask, inet_ntoa( ipv4_addr ) );
|
||||
ipv4_addr.s_addr = *(identifier+3);
|
||||
strcpy( (char *) inContext->micoStatus.gateWay, inet_ntoa( ipv4_addr ) );
|
||||
ipv4_addr.s_addr = *(identifier+4);
|
||||
strcpy( (char *) inContext->micoStatus.dnsServer, inet_ntoa( ipv4_addr ) );
|
||||
|
||||
system_log("Get auth info: %s, EasyLink identifier: %lx, local IP info:%s %s %s %s ", data, easylink_id, inContext->flashContentInRam.micoSystemConfig.localIp,
|
||||
inContext->flashContentInRam.micoSystemConfig.netMask, inContext->flashContentInRam.micoSystemConfig.gateWay,inContext->flashContentInRam.micoSystemConfig.dnsServer);
|
||||
}
|
||||
mico_rtos_unlock_mutex( &inContext->flashContentInRam_mutex );
|
||||
source = CONFIG_BY_EASYLINK_V2;
|
||||
|
||||
exit:
|
||||
if ( err != kNoErr )
|
||||
{
|
||||
/*EasyLink error*/
|
||||
system_log("EasyLink step 2 ERROR, err: %d", err);
|
||||
easylink_success = false;
|
||||
} else
|
||||
/* Easylink success after step 1 and step 2 */
|
||||
easylink_success = true;
|
||||
|
||||
mico_rtos_set_semaphore( &easylink_sem );
|
||||
return;
|
||||
}
|
||||
|
||||
static OSStatus _monitor_timed_check_cb(void *arg)
|
||||
{
|
||||
mico_time_t current;
|
||||
|
||||
mico_time_get_time( ¤t );
|
||||
if ( current > (mico_time_t) arg ) {
|
||||
easylink_success = false;
|
||||
mico_rtos_set_semaphore( &easylink_sem );
|
||||
}
|
||||
|
||||
if( wlan_channel_walker == MICO_TRUE){
|
||||
mico_wlan_set_channel( wlan_channel );
|
||||
mico_easylink_monitor_delegate_channel_changed( wlan_channel );
|
||||
wlan_channel++;
|
||||
if ( wlan_channel >= 14 ) wlan_channel = 1;
|
||||
}
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
static void monitor_cb( uint8_t * frame, int len )
|
||||
{
|
||||
mico_easylink_monitor_delegate_package_recved( frame, len );
|
||||
}
|
||||
|
||||
static void easylink_monitor_thread( uint32_t arg )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
system_context_t *context = (system_context_t *) arg;
|
||||
|
||||
mico_time_t current;
|
||||
easylink_id = 0x0;
|
||||
easylink_success = false;
|
||||
easylink_thread_force_exit = false;
|
||||
|
||||
source = CONFIG_BY_NONE;
|
||||
mico_system_notify_register( mico_notify_EASYLINK_WPS_COMPLETED, (void *) easylink_complete_cb, context );
|
||||
mico_system_notify_register( mico_notify_EASYLINK_GET_EXTRA_DATA, (void *) easylink_extra_data_cb, context );
|
||||
mico_system_notify_register( mico_notify_WIFI_STATUS_CHANGED, (void *) easylink_wifi_status_cb, context );
|
||||
|
||||
mico_rtos_init_semaphore( &easylink_sem, 1 );
|
||||
mico_rtos_init_semaphore( &easylink_connect_sem, 1 );
|
||||
|
||||
mico_wlan_register_monitor_cb( monitor_cb );
|
||||
|
||||
restart:
|
||||
mico_system_delegate_config_will_start( );
|
||||
system_log("Start easylink monitor mode");
|
||||
mico_easylink_monitor_delegate_will_start( );
|
||||
|
||||
mico_wlan_start_monitor( );
|
||||
|
||||
wlan_channel_walker = MICO_TRUE;
|
||||
mico_time_get_time( ¤t );
|
||||
mico_rtos_register_timed_event( &_monitor_timed_check, MICO_NETWORKING_WORKER_THREAD, _monitor_timed_check_cb,
|
||||
wlan_channel_walker_interval, (void *)(current + EasyLink_TimeOut) );
|
||||
|
||||
while( mico_rtos_get_semaphore( &easylink_sem, 0 ) == kNoErr );
|
||||
err = mico_rtos_get_semaphore( &easylink_sem, MICO_WAIT_FOREVER );
|
||||
|
||||
mico_rtos_deregister_timed_event( &_monitor_timed_check );
|
||||
mico_wlan_stop_monitor( );
|
||||
mico_easylink_monitor_delegate_stoped();
|
||||
|
||||
/* Easylink force exit by user, clean and exit */
|
||||
if( err != kNoErr && easylink_thread_force_exit )
|
||||
{
|
||||
system_log("EasyLink canceled by user");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* EasyLink Success */
|
||||
if ( easylink_success == true )
|
||||
{
|
||||
mico_system_delegate_config_recv_ssid( context->flashContentInRam.micoSystemConfig.ssid,
|
||||
context->flashContentInRam.micoSystemConfig.user_key );
|
||||
system_connect_wifi_normal( context );
|
||||
|
||||
/* Wait for station connection */
|
||||
while( mico_rtos_get_semaphore( &easylink_connect_sem, 0 ) == kNoErr );
|
||||
err = mico_rtos_get_semaphore( &easylink_connect_sem, EasyLink_ConnectWlan_Timeout );
|
||||
/* Easylink force exit by user, clean and exit */
|
||||
if( err != kNoErr && easylink_thread_force_exit )
|
||||
{
|
||||
micoWlanSuspend();
|
||||
system_log("EasyLink connection canceled by user");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*SSID or Password is not correct, module cannot connect to wlan, so restart EasyLink again*/
|
||||
require_noerr_action_string( err, restart, micoWlanSuspend(), "Re-start easylink combo mode" );
|
||||
|
||||
/* Start bonjour service for new device discovery */
|
||||
err = easylink_bonjour_start( Station, easylink_id, context );
|
||||
require_noerr( err, exit );
|
||||
SetTimer( 60 * 1000, easylink_remove_bonjour );
|
||||
|
||||
source = (source == CONFIG_BY_NONE) ? CONFIG_BY_MONITOR : source;
|
||||
mico_system_delegate_config_success( source );
|
||||
mico_easylink_monitor_delegate_connect_success( source );
|
||||
|
||||
goto exit;
|
||||
}
|
||||
else /* EasyLink failed */
|
||||
{
|
||||
/* so roll back to previous settings (if it has) and connect */
|
||||
if ( context->flashContentInRam.micoSystemConfig.configured != unConfigured ) {
|
||||
system_log("Roll back to previous settings");
|
||||
MICOReadConfiguration( context );
|
||||
system_connect_wifi_normal( context );
|
||||
}
|
||||
else {
|
||||
/*module should power down in default setting*/
|
||||
system_log("Wi-Fi power off");
|
||||
micoWlanPowerOff();
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
easylink_thread_force_exit = false;
|
||||
|
||||
mico_system_delegate_config_will_stop( );
|
||||
|
||||
mico_system_notify_remove( mico_notify_WIFI_STATUS_CHANGED, (void *)easylink_wifi_status_cb );
|
||||
mico_system_notify_remove( mico_notify_EASYLINK_WPS_COMPLETED, (void *)easylink_complete_cb );
|
||||
mico_system_notify_remove( mico_notify_EASYLINK_GET_EXTRA_DATA, (void *)easylink_extra_data_cb );
|
||||
|
||||
mico_rtos_deinit_semaphore( &easylink_sem );
|
||||
mico_rtos_deinit_semaphore( &easylink_connect_sem );
|
||||
easylink_monitor_thread_handler = NULL;
|
||||
mico_rtos_delete_thread( NULL );
|
||||
}
|
||||
|
||||
OSStatus mico_easylink_monitor_channel_walker( mico_bool_t enable, uint32_t interval )
|
||||
{
|
||||
wlan_channel_walker = enable;
|
||||
|
||||
if( enable == MICO_TRUE ) wlan_channel_walker_interval = interval;
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus mico_easylink_monitor_save_result( network_InitTypeDef_st *nwkpara )
|
||||
{
|
||||
system_context_t * context = system_context( );
|
||||
|
||||
if( context == NULL ) return kNotPreparedErr;
|
||||
|
||||
memcpy( context->flashContentInRam.micoSystemConfig.ssid, nwkpara->wifi_ssid, maxSsidLen );
|
||||
memset( context->flashContentInRam.micoSystemConfig.bssid, 0x0, 6 );
|
||||
memcpy( context->flashContentInRam.micoSystemConfig.user_key, nwkpara->wifi_key, maxKeyLen );
|
||||
context->flashContentInRam.micoSystemConfig.user_keyLength = strlen( nwkpara->wifi_key );
|
||||
context->flashContentInRam.micoSystemConfig.dhcpEnable = true;
|
||||
|
||||
system_log("Get SSID: %s, Key: %s", context->flashContentInRam.micoSystemConfig.ssid, context->flashContentInRam.micoSystemConfig.user_key);
|
||||
|
||||
easylink_success = true;
|
||||
mico_rtos_set_semaphore( &easylink_sem );
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus mico_easylink_monitor_with_easylink( mico_Context_t * const in_context, mico_bool_t enable )
|
||||
{
|
||||
OSStatus err = kUnknownErr;
|
||||
|
||||
require_action( in_context, exit, err = kNotPreparedErr );
|
||||
|
||||
easylink_remove_bonjour( );
|
||||
|
||||
/* easylink thread existed? stop! */
|
||||
if ( easylink_monitor_thread_handler ) {
|
||||
system_log("EasyLink monitor processing, force stop..");
|
||||
easylink_thread_force_exit = true;
|
||||
mico_rtos_thread_force_awake( &easylink_monitor_thread_handler );
|
||||
mico_rtos_thread_join( &easylink_monitor_thread_handler );
|
||||
}
|
||||
|
||||
if ( enable == MICO_TRUE ) {
|
||||
err = mico_rtos_create_thread( &easylink_monitor_thread_handler, MICO_APPLICATION_PRIORITY, "EASYLINK",
|
||||
easylink_monitor_thread, 0x1000, (mico_thread_arg_t) in_context );
|
||||
require_noerr_string( err, exit, "ERROR: Unable to start the EasyLink monitor thread." );
|
||||
|
||||
/* Make sure easylink is already running, and waiting for sem trigger */
|
||||
mico_rtos_delay_milliseconds( 100 );
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
OSStatus mico_easylink_monitor( mico_Context_t * const in_context, mico_bool_t enable )
|
||||
{
|
||||
mico_wlan_monitor_no_easylink();
|
||||
return mico_easylink_monitor_with_easylink( in_context, enable );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//#endif
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_easylink_monitor.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 20-May-2017
|
||||
* @brief This file provide the easylink function for quick provisioning and
|
||||
* first time 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 "easylink_internal.h"
|
||||
|
||||
#include "StringUtils.h"
|
||||
|
||||
//#if (MICO_WLAN_CONFIG_MODE == CONFIG_MODE_EASYLINK) || (MICO_WLAN_CONFIG_MODE == CONFIG_MODE_EASYLINK_WITH_SOFTAP)
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
/* EasyLink event callback functions*/
|
||||
static void easylink_wifi_status_cb( WiFiEvent event, system_context_t * const inContext );
|
||||
static void easylink_complete_cb( network_InitTypeDef_st *nwkpara, system_context_t * const inContext );
|
||||
static void easylink_extra_data_cb( int datalen, char* data, system_context_t * const inContext );
|
||||
|
||||
/* Thread perform easylink and connect to wlan */
|
||||
static void easylink_monitor_thread( uint32_t inContext ); /* Perform easylink and connect to wlan */
|
||||
|
||||
extern void mico_wlan_monitor_no_easylink(void);
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
|
||||
static mico_timed_event_t _monitor_timed_check;
|
||||
static uint8_t wlan_channel = 1;
|
||||
static mico_bool_t wlan_channel_walker = MICO_TRUE;
|
||||
static uint32_t wlan_channel_walker_interval = 100;
|
||||
|
||||
static mico_semaphore_t easylink_sem; /**< Used to suspend thread while easylink. */
|
||||
static mico_semaphore_t easylink_connect_sem; /**< Used to suspend thread while connection. */
|
||||
static bool easylink_success = false; /**< true: connect to wlan, false: start soft ap mode or roll back to previous settings */
|
||||
static uint32_t easylink_id = 0; /**< Unique for an easylink instance. */
|
||||
static mico_thread_t easylink_monitor_thread_handler = NULL;
|
||||
static bool easylink_thread_force_exit = false;
|
||||
|
||||
static mico_config_source_t source = CONFIG_BY_NONE;
|
||||
static mico_connect_fail_config_t connect_fail_config = EXIT_EASYLINK;
|
||||
|
||||
/******************************************************
|
||||
* Function Definitions
|
||||
******************************************************/
|
||||
|
||||
/* MiCO callback when WiFi status is changed */
|
||||
static void easylink_wifi_status_cb( WiFiEvent event, system_context_t * const inContext )
|
||||
{
|
||||
switch ( event )
|
||||
{
|
||||
case NOTIFY_STATION_UP:
|
||||
/* Connected to AP, means that the wlan configuration is right, update configuration in flash and update
|
||||
bongjour txt record with new "easylink_id" */
|
||||
easylink_bonjour_update( Station, easylink_id, inContext );
|
||||
inContext->flashContentInRam.micoSystemConfig.configured = allConfigured;
|
||||
mico_system_context_update( &inContext->flashContentInRam ); //Update Flash content
|
||||
mico_rtos_set_semaphore( &easylink_connect_sem ); //Notify Easylink thread
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* MiCO callback when EasyLink is finished step 1, return SSID and KEY */
|
||||
static void easylink_complete_cb( network_InitTypeDef_st *nwkpara, system_context_t * const inContext )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action_string( nwkpara, exit, err = kTimeoutErr, "EasyLink Timeout or terminated" );
|
||||
|
||||
/* Store SSID and KEY*/
|
||||
mico_rtos_lock_mutex( &inContext->flashContentInRam_mutex );
|
||||
memcpy( inContext->flashContentInRam.micoSystemConfig.ssid, nwkpara->wifi_ssid, maxSsidLen );
|
||||
memset( inContext->flashContentInRam.micoSystemConfig.bssid, 0x0, 6 );
|
||||
memcpy( inContext->flashContentInRam.micoSystemConfig.user_key, nwkpara->wifi_key, maxKeyLen );
|
||||
inContext->flashContentInRam.micoSystemConfig.user_keyLength = strlen( nwkpara->wifi_key );
|
||||
inContext->flashContentInRam.micoSystemConfig.dhcpEnable = true;
|
||||
mico_rtos_unlock_mutex( &inContext->flashContentInRam_mutex );
|
||||
system_log("Get SSID: %s, Key: %s", inContext->flashContentInRam.micoSystemConfig.ssid, inContext->flashContentInRam.micoSystemConfig.user_key);
|
||||
|
||||
source = (mico_config_source_t) nwkpara->wifi_retry_interval;
|
||||
exit:
|
||||
if ( err != kNoErr )
|
||||
{
|
||||
/*EasyLink timeout or error*/
|
||||
easylink_success = false;
|
||||
mico_rtos_set_semaphore( &easylink_sem );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* MiCO callback when EasyLink is finished step 2, return extra data
|
||||
data format: [AuthData#Identifier]<localIp/netMask/gateWay/dnsServer>
|
||||
Auth data: Provide to application, application will decide if this is a proter configuration for currnet device
|
||||
Identifier: Unique id for every easylink instance send by easylink mobile app
|
||||
localIp/netMask/gateWay/dnsServer: Device static ip address, use DHCP if not exist
|
||||
*/
|
||||
static void easylink_extra_data_cb( int datalen, char* data, system_context_t * const inContext )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
int index;
|
||||
uint32_t *identifier, ipInfoCount;
|
||||
char *debugString;
|
||||
struct in_addr ipv4_addr;
|
||||
|
||||
debugString = DataToHexStringWithSpaces( (const uint8_t *) data, datalen );
|
||||
system_log("Get user info: %s", debugString);
|
||||
free( debugString );
|
||||
|
||||
/* Find '#' that separate authdata and identifier*/
|
||||
for ( index = datalen - 1; index >= 0; index-- )
|
||||
{
|
||||
if ( data[index] == '#' && ((datalen - index) == 5 || (datalen - index) == 25) )
|
||||
break;
|
||||
}
|
||||
require_action( index >= 0, exit, err = kParamErr );
|
||||
|
||||
/* Check auth data by device */
|
||||
data[index++] = 0x0;
|
||||
err = mico_system_delegate_config_recv_auth_data( data );
|
||||
require_noerr( err, exit );
|
||||
|
||||
/* Read identifier */
|
||||
identifier = (uint32_t *) &data[index];
|
||||
easylink_id = *identifier;
|
||||
|
||||
/* Identifier: 1 x uint32_t or Identifier/localIp/netMask/gateWay/dnsServer: 5 x uint32_t */
|
||||
ipInfoCount = (datalen - index) / sizeof(uint32_t);
|
||||
require_action( ipInfoCount >= 1, exit, err = kParamErr );
|
||||
|
||||
mico_rtos_lock_mutex( &inContext->flashContentInRam_mutex );
|
||||
|
||||
if ( ipInfoCount == 1 )
|
||||
{ //Use DHCP to obtain local ip address
|
||||
inContext->flashContentInRam.micoSystemConfig.dhcpEnable = true;
|
||||
system_log("Get auth info: %s, EasyLink identifier: %lx", data, easylink_id);
|
||||
} else
|
||||
{ //Use static ip address
|
||||
inContext->flashContentInRam.micoSystemConfig.dhcpEnable = false;
|
||||
ipv4_addr.s_addr = *(identifier+1);
|
||||
strcpy( (char *) inContext->micoStatus.localIp, inet_ntoa( ipv4_addr ) );
|
||||
ipv4_addr.s_addr = *(identifier+2);
|
||||
strcpy( (char *) inContext->micoStatus.netMask, inet_ntoa( ipv4_addr ) );
|
||||
ipv4_addr.s_addr = *(identifier+3);
|
||||
strcpy( (char *) inContext->micoStatus.gateWay, inet_ntoa( ipv4_addr ) );
|
||||
ipv4_addr.s_addr = *(identifier+4);
|
||||
strcpy( (char *) inContext->micoStatus.dnsServer, inet_ntoa( ipv4_addr ) );
|
||||
|
||||
system_log("Get auth info: %s, EasyLink identifier: %lx, local IP info:%s %s %s %s ", data, easylink_id, inContext->flashContentInRam.micoSystemConfig.localIp,
|
||||
inContext->flashContentInRam.micoSystemConfig.netMask, inContext->flashContentInRam.micoSystemConfig.gateWay,inContext->flashContentInRam.micoSystemConfig.dnsServer);
|
||||
}
|
||||
mico_rtos_unlock_mutex( &inContext->flashContentInRam_mutex );
|
||||
source = CONFIG_BY_EASYLINK_V2;
|
||||
|
||||
exit:
|
||||
if ( err != kNoErr )
|
||||
{
|
||||
/*EasyLink error*/
|
||||
system_log("EasyLink step 2 ERROR, err: %d", err);
|
||||
easylink_success = false;
|
||||
} else
|
||||
/* Easylink success after step 1 and step 2 */
|
||||
easylink_success = true;
|
||||
|
||||
mico_rtos_set_semaphore( &easylink_sem );
|
||||
return;
|
||||
}
|
||||
|
||||
static OSStatus _monitor_timed_check_cb(void *arg)
|
||||
{
|
||||
mico_time_t current;
|
||||
|
||||
mico_time_get_time( ¤t );
|
||||
if ( current > (mico_time_t) arg ) {
|
||||
easylink_success = false;
|
||||
mico_rtos_set_semaphore( &easylink_sem );
|
||||
}
|
||||
|
||||
if( wlan_channel_walker == MICO_TRUE){
|
||||
mico_wlan_set_channel( wlan_channel );
|
||||
mico_easylink_monitor_delegate_channel_changed( wlan_channel );
|
||||
wlan_channel++;
|
||||
if ( wlan_channel >= 14 ) wlan_channel = 1;
|
||||
}
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
static void monitor_cb( uint8_t * frame, int len )
|
||||
{
|
||||
mico_easylink_monitor_delegate_package_recved( frame, len );
|
||||
}
|
||||
|
||||
static void easylink_monitor_thread( uint32_t arg )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
system_context_t *context = (system_context_t *) arg;
|
||||
|
||||
mico_time_t current;
|
||||
easylink_id = 0x0;
|
||||
easylink_success = false;
|
||||
easylink_thread_force_exit = false;
|
||||
|
||||
source = CONFIG_BY_NONE;
|
||||
mico_system_notify_register( mico_notify_EASYLINK_WPS_COMPLETED, (void *) easylink_complete_cb, context );
|
||||
mico_system_notify_register( mico_notify_EASYLINK_GET_EXTRA_DATA, (void *) easylink_extra_data_cb, context );
|
||||
mico_system_notify_register( mico_notify_WIFI_STATUS_CHANGED, (void *) easylink_wifi_status_cb, context );
|
||||
|
||||
mico_rtos_init_semaphore( &easylink_sem, 1 );
|
||||
mico_rtos_init_semaphore( &easylink_connect_sem, 1 );
|
||||
|
||||
mico_wlan_register_monitor_cb( monitor_cb );
|
||||
|
||||
restart:
|
||||
mico_system_delegate_config_will_start( );
|
||||
system_log("Start easylink monitor mode");
|
||||
mico_easylink_monitor_delegate_will_start( );
|
||||
|
||||
mico_wlan_start_monitor( );
|
||||
|
||||
wlan_channel_walker = MICO_TRUE;
|
||||
mico_time_get_time( ¤t );
|
||||
mico_rtos_register_timed_event( &_monitor_timed_check, MICO_NETWORKING_WORKER_THREAD, _monitor_timed_check_cb,
|
||||
wlan_channel_walker_interval, (void *)(current + EasyLink_TimeOut) );
|
||||
|
||||
while( mico_rtos_get_semaphore( &easylink_sem, 0 ) == kNoErr );
|
||||
err = mico_rtos_get_semaphore( &easylink_sem, MICO_WAIT_FOREVER );
|
||||
|
||||
mico_rtos_deregister_timed_event( &_monitor_timed_check );
|
||||
mico_wlan_stop_monitor( );
|
||||
mico_easylink_monitor_delegate_stoped();
|
||||
|
||||
/* Easylink force exit by user, clean and exit */
|
||||
if( err != kNoErr && easylink_thread_force_exit )
|
||||
{
|
||||
system_log("EasyLink canceled by user");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* EasyLink Success */
|
||||
if ( easylink_success == true )
|
||||
{
|
||||
mico_system_delegate_config_recv_ssid( context->flashContentInRam.micoSystemConfig.ssid,
|
||||
context->flashContentInRam.micoSystemConfig.user_key );
|
||||
system_connect_wifi_normal( context );
|
||||
|
||||
/* Wait for station connection */
|
||||
while( mico_rtos_get_semaphore( &easylink_connect_sem, 0 ) == kNoErr );
|
||||
err = mico_rtos_get_semaphore( &easylink_connect_sem, EasyLink_ConnectWlan_Timeout );
|
||||
/* Easylink force exit by user, clean and exit */
|
||||
if( err != kNoErr && easylink_thread_force_exit )
|
||||
{
|
||||
micoWlanSuspend();
|
||||
system_log("EasyLink connection canceled by user");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
source = (source == CONFIG_BY_NONE) ? CONFIG_BY_MONITOR : source;
|
||||
|
||||
/* Easylink connect result */
|
||||
if ( err != kNoErr )
|
||||
{
|
||||
connect_fail_config = mico_system_delegate_config_result( source, MICO_FALSE );
|
||||
if ( RESTART_EASYLINK == connect_fail_config )
|
||||
{
|
||||
system_log("Re-start easylink combo mode");
|
||||
micoWlanSuspend( );
|
||||
goto restart;
|
||||
} else {
|
||||
system_log("exit easylink combo mode");
|
||||
micoWlanSuspendStation( );
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mico_system_delegate_config_result( source, MICO_TRUE );
|
||||
mico_easylink_monitor_delegate_connect_success( source );
|
||||
}
|
||||
}
|
||||
else /* EasyLink failed */
|
||||
{
|
||||
mico_system_delegate_easylink_timeout( context );
|
||||
}
|
||||
|
||||
exit:
|
||||
easylink_thread_force_exit = false;
|
||||
|
||||
mico_system_delegate_config_will_stop( );
|
||||
|
||||
mico_system_notify_remove( mico_notify_WIFI_STATUS_CHANGED, (void *)easylink_wifi_status_cb );
|
||||
mico_system_notify_remove( mico_notify_EASYLINK_WPS_COMPLETED, (void *)easylink_complete_cb );
|
||||
mico_system_notify_remove( mico_notify_EASYLINK_GET_EXTRA_DATA, (void *)easylink_extra_data_cb );
|
||||
|
||||
mico_rtos_deinit_semaphore( &easylink_sem );
|
||||
mico_rtos_deinit_semaphore( &easylink_connect_sem );
|
||||
easylink_monitor_thread_handler = NULL;
|
||||
mico_rtos_delete_thread( NULL );
|
||||
}
|
||||
|
||||
OSStatus mico_easylink_monitor_channel_walker( mico_bool_t enable, uint32_t interval )
|
||||
{
|
||||
wlan_channel_walker = enable;
|
||||
|
||||
if( enable == MICO_TRUE ) wlan_channel_walker_interval = interval;
|
||||
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus mico_easylink_monitor_save_result( network_InitTypeDef_st *nwkpara )
|
||||
{
|
||||
system_context_t * context = system_context( );
|
||||
|
||||
if( context == NULL ) return kNotPreparedErr;
|
||||
|
||||
memcpy( context->flashContentInRam.micoSystemConfig.ssid, nwkpara->wifi_ssid, maxSsidLen );
|
||||
memset( context->flashContentInRam.micoSystemConfig.bssid, 0x0, 6 );
|
||||
memcpy( context->flashContentInRam.micoSystemConfig.user_key, nwkpara->wifi_key, maxKeyLen );
|
||||
context->flashContentInRam.micoSystemConfig.user_keyLength = strlen( nwkpara->wifi_key );
|
||||
context->flashContentInRam.micoSystemConfig.dhcpEnable = true;
|
||||
|
||||
system_log("Get SSID: %s, Key: %s", context->flashContentInRam.micoSystemConfig.ssid, context->flashContentInRam.micoSystemConfig.user_key);
|
||||
|
||||
easylink_success = true;
|
||||
mico_rtos_set_semaphore( &easylink_sem );
|
||||
return kNoErr;
|
||||
}
|
||||
|
||||
OSStatus mico_easylink_monitor_with_easylink( mico_Context_t * const in_context, mico_bool_t enable )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
|
||||
require_action( in_context, exit, err = kNotPreparedErr );
|
||||
|
||||
easylink_remove_bonjour( );
|
||||
|
||||
/* easylink thread existed? stop! */
|
||||
if ( easylink_monitor_thread_handler ) {
|
||||
system_log("EasyLink monitor processing, force stop..");
|
||||
easylink_thread_force_exit = true;
|
||||
mico_rtos_thread_force_awake( &easylink_monitor_thread_handler );
|
||||
mico_rtos_thread_join( &easylink_monitor_thread_handler );
|
||||
}
|
||||
|
||||
if ( enable == MICO_TRUE ) {
|
||||
err = mico_rtos_create_thread( &easylink_monitor_thread_handler, MICO_APPLICATION_PRIORITY, "EASYLINK",
|
||||
easylink_monitor_thread, 0x1000, (mico_thread_arg_t) in_context );
|
||||
require_noerr_string( err, exit, "ERROR: Unable to start the EasyLink monitor thread." );
|
||||
|
||||
/* Make sure easylink is already running, and waiting for sem trigger */
|
||||
mico_rtos_delay_milliseconds( 100 );
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
OSStatus mico_easylink_monitor( mico_Context_t * const in_context, mico_bool_t enable )
|
||||
{
|
||||
mico_wlan_monitor_no_easylink();
|
||||
return mico_easylink_monitor_with_easylink( in_context, enable );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//#endif
|
||||
|
||||
|
||||
@@ -1,292 +1,294 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_easylink_softap.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 20-July-2015
|
||||
* @brief This file provide the easylink function for quick provisioning and
|
||||
* first time 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 "StringUtils.h"
|
||||
#include "HTTPUtils.h"
|
||||
#include "SocketUtils.h"
|
||||
|
||||
#include "system.h"
|
||||
#include "easylink_internal.h"
|
||||
|
||||
/* Internal vars and functions */
|
||||
static mico_semaphore_t easylink_sem; /**< Used to suspend thread while easylink. */
|
||||
static mico_semaphore_t easylink_connect_sem; /**< Used to suspend thread while connection. */
|
||||
static bool easylink_success = false; /**< true: connect to wlan, false: start soft ap mode or roll back to previous settings */
|
||||
static uint32_t easylinkIndentifier = 0; /**< Unique for an easylink instance. */
|
||||
static mico_thread_t easylink_softap_thread_handler = NULL;
|
||||
static bool easylink_thread_force_exit = false;
|
||||
|
||||
/* Perform easylink and connect to wlan */
|
||||
static void easylink_softap_thread( uint32_t inContext );
|
||||
|
||||
/* MiCO callback when WiFi status is changed */
|
||||
static void easylink_wifi_status_cb( WiFiEvent event, system_context_t * const inContext )
|
||||
{
|
||||
switch ( event )
|
||||
{
|
||||
case NOTIFY_STATION_UP:
|
||||
/* Connected to AP, means that the wlan configuration is right, update configuration in flash and update
|
||||
bongjour txt record with new "easylinkIndentifier" */
|
||||
easylink_bonjour_update( Station, easylinkIndentifier, inContext );
|
||||
inContext->flashContentInRam.micoSystemConfig.configured = allConfigured;
|
||||
mico_system_context_update( &inContext->flashContentInRam ); //Update Flash content
|
||||
mico_rtos_set_semaphore( &easylink_connect_sem ); //Notify Easylink thread
|
||||
break;
|
||||
case NOTIFY_AP_DOWN:
|
||||
/* Remove bonjour service under soft ap interface */
|
||||
mdns_suspend_record( "_easylink_config._tcp.local.", Soft_AP, true );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OSStatus ConfigIncommingJsonMessageUAP( int fd, const uint8_t *input, size_t size, system_context_t * const inContext )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
json_object *new_obj;
|
||||
char *input_str = NULL;
|
||||
uint8_t *httpResponse = NULL;
|
||||
size_t httpResponseLen = 0;
|
||||
|
||||
inContext->flashContentInRam.micoSystemConfig.easyLinkByPass = EASYLINK_BYPASS_NO;
|
||||
|
||||
input_str = calloc( size + 1, sizeof(char) );
|
||||
require_action( input_str, exit, err = kNoMemoryErr );
|
||||
|
||||
memcpy( input_str, input, size );
|
||||
system_log("Recv config object=%s", input_str);
|
||||
new_obj = json_tokener_parse( input_str );
|
||||
require_action( new_obj, exit, err = kUnknownErr );
|
||||
|
||||
json_object_object_foreach( new_obj, key, val )
|
||||
{
|
||||
if ( !strcmp( key, "SSID" ) ) {
|
||||
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;
|
||||
}
|
||||
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 );
|
||||
memcpy( inContext->flashContentInRam.micoSystemConfig.key, inContext->flashContentInRam.micoSystemConfig.user_key, maxKeyLen );
|
||||
inContext->flashContentInRam.micoSystemConfig.keyLength = inContext->flashContentInRam.micoSystemConfig.user_keyLength;
|
||||
}
|
||||
else if ( !strcmp( key, "DHCP" ) ) {
|
||||
inContext->flashContentInRam.micoSystemConfig.dhcpEnable = json_object_get_boolean( val );
|
||||
}
|
||||
else if ( !strcmp( key, "IDENTIFIER" ) ) {
|
||||
easylinkIndentifier = (uint32_t) json_object_get_int( val );
|
||||
}
|
||||
else if ( !strcmp( key, "IP" ) ) {
|
||||
strncpy( inContext->flashContentInRam.micoSystemConfig.localIp, json_object_get_string( val ), maxIpLen );
|
||||
}
|
||||
else if ( !strcmp( key, "NETMASK" ) ) {
|
||||
strncpy( inContext->flashContentInRam.micoSystemConfig.netMask, json_object_get_string( val ), maxIpLen );
|
||||
}
|
||||
else if ( !strcmp( key, "GATEWAY" ) ) {
|
||||
strncpy( inContext->flashContentInRam.micoSystemConfig.gateWay, json_object_get_string( val ), maxIpLen );
|
||||
}
|
||||
else if ( !strcmp( key, "DNS1" ) ) {
|
||||
strncpy( inContext->flashContentInRam.micoSystemConfig.dnsServer, json_object_get_string( val ), maxIpLen );
|
||||
}
|
||||
}
|
||||
json_object_put( new_obj );
|
||||
|
||||
err = CreateSimpleHTTPOKMessage( &httpResponse, &httpResponseLen );
|
||||
require_noerr( err, exit );
|
||||
|
||||
err = SocketSend( fd, httpResponse, httpResponseLen );
|
||||
require_noerr( err, exit );
|
||||
|
||||
mico_rtos_delay_milliseconds( 1000 );
|
||||
|
||||
easylink_success = true;
|
||||
if( easylink_sem ) mico_rtos_set_semaphore( &easylink_sem );
|
||||
|
||||
exit:
|
||||
if ( input_str ) free( input_str );
|
||||
|
||||
if(httpResponse) free(httpResponse);
|
||||
return err;
|
||||
}
|
||||
|
||||
void easylink_softap_thread( uint32_t inContext )
|
||||
{
|
||||
system_log_trace();
|
||||
OSStatus err = kNoErr;
|
||||
system_context_t *context = (system_context_t *) inContext;
|
||||
network_InitTypeDef_st wNetConfig;
|
||||
|
||||
easylinkIndentifier = 0x0;
|
||||
easylink_success = false;
|
||||
|
||||
easylink_thread_force_exit = false;
|
||||
|
||||
mico_system_notify_register( mico_notify_WIFI_STATUS_CHANGED, (void *) easylink_wifi_status_cb, (void *) inContext );
|
||||
|
||||
mico_rtos_init_semaphore( &easylink_sem, 1 );
|
||||
mico_rtos_init_semaphore( &easylink_connect_sem, 1 );
|
||||
|
||||
restart:
|
||||
micoWlanSuspend( );
|
||||
mico_thread_msleep( 20 );
|
||||
|
||||
mico_system_delegate_config_will_start( );
|
||||
|
||||
memset( &wNetConfig, 0, sizeof(network_InitTypeDef_st) );
|
||||
wNetConfig.wifi_mode = Soft_AP;
|
||||
snprintf( wNetConfig.wifi_ssid, 32, "EasyLink_%c%c%c%c%c%c",
|
||||
context->micoStatus.mac[9], context->micoStatus.mac[10], context->micoStatus.mac[12],
|
||||
context->micoStatus.mac[13], context->micoStatus.mac[15], context->micoStatus.mac[16] );
|
||||
strcpy( (char*) wNetConfig.wifi_key, "" );
|
||||
strcpy( (char*) wNetConfig.local_ip_addr, "10.10.10.1" );
|
||||
strcpy( (char*) wNetConfig.net_mask, "255.255.255.0" );
|
||||
strcpy( (char*) wNetConfig.gateway_ip_addr, "10.10.10.1" );
|
||||
wNetConfig.dhcpMode = DHCP_Server;
|
||||
micoWlanStart( &wNetConfig );
|
||||
system_log("Establish soft ap: %s.....", wNetConfig.wifi_ssid);
|
||||
|
||||
/* Start bonjour service for device discovery under soft ap mode */
|
||||
err = easylink_bonjour_start( Soft_AP, 0, context );
|
||||
require_noerr( err, exit );
|
||||
|
||||
while( mico_rtos_get_semaphore( &easylink_sem, 0 ) == kNoErr );
|
||||
err = mico_rtos_get_semaphore( &easylink_sem, MICO_WAIT_FOREVER );
|
||||
|
||||
micoWlanSuspendSoftAP();
|
||||
|
||||
/* Easylink force exit by user, clean and exit */
|
||||
if( err != kNoErr && easylink_thread_force_exit )
|
||||
{
|
||||
system_log("EasyLink canceled by user");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* EasyLink Success */
|
||||
if ( easylink_success == true ) {
|
||||
mico_system_delegate_config_recv_ssid( context->flashContentInRam.micoSystemConfig.ssid,
|
||||
context->flashContentInRam.micoSystemConfig.user_key );
|
||||
|
||||
mico_thread_sleep(1);
|
||||
system_connect_wifi_normal( context );
|
||||
|
||||
/* Wait for station connection */
|
||||
while ( mico_rtos_get_semaphore( &easylink_connect_sem, 0 ) == kNoErr );
|
||||
err = mico_rtos_get_semaphore( &easylink_connect_sem, EasyLink_ConnectWlan_Timeout );
|
||||
/* Easylink force exit by user, clean and exit */
|
||||
if ( err != kNoErr && easylink_thread_force_exit )
|
||||
{
|
||||
micoWlanSuspend( );
|
||||
system_log("EasyLink connection canceled by user");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*SSID or Password is not correct, module cannot connect to wlan, so restart EasyLink again*/
|
||||
require_noerr_action_string( err, restart, micoWlanSuspend(), "Re-start easylink softap mode" );
|
||||
mico_system_delegate_config_success( CONFIG_BY_SOFT_AP );
|
||||
|
||||
/* Start bonjour service for new device discovery */
|
||||
err = easylink_bonjour_start( Station, easylinkIndentifier, context );
|
||||
require_noerr( err, exit );
|
||||
SetTimer( 60 * 1000, easylink_remove_bonjour );
|
||||
|
||||
goto exit;
|
||||
}
|
||||
else /* EasyLink failed */
|
||||
{
|
||||
/*so roll back to previous settings (if it has) and connect*/
|
||||
if(context->flashContentInRam.micoSystemConfig.configured != unConfigured)
|
||||
{
|
||||
system_log("Roll back to previous settings");
|
||||
MICOReadConfiguration( context );
|
||||
#ifdef EasyLink_Needs_Reboot
|
||||
context->flashContentInRam.micoSystemConfig.configured = allConfigured;
|
||||
mico_system_context_update( &context->flashContentInRam );
|
||||
#endif
|
||||
system_connect_wifi_normal( context );
|
||||
}
|
||||
else {
|
||||
/*module should power down in default setting*/
|
||||
system_log("Wi-Fi power off");
|
||||
micoWlanPowerOff( );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exit:
|
||||
easylink_thread_force_exit = false;
|
||||
|
||||
mico_system_delegate_config_will_stop( );
|
||||
|
||||
mico_system_notify_remove( mico_notify_WIFI_STATUS_CHANGED, (void *) easylink_wifi_status_cb );
|
||||
|
||||
#ifndef MICO_CONFIG_SERVER_ENABLE
|
||||
config_server_stop( );
|
||||
#endif
|
||||
|
||||
mico_rtos_deinit_semaphore( &easylink_sem );
|
||||
mico_rtos_deinit_semaphore( &easylink_connect_sem );
|
||||
easylink_softap_thread_handler = NULL;
|
||||
mico_rtos_delete_thread( NULL );
|
||||
}
|
||||
|
||||
OSStatus mico_easylink_softap( mico_Context_t * const in_context, mico_bool_t enable )
|
||||
{
|
||||
OSStatus err = kUnknownErr;
|
||||
|
||||
require_action( in_context, exit, err = kNotPreparedErr );
|
||||
|
||||
easylink_remove_bonjour( );
|
||||
|
||||
/* easylink soft thread existed? stop! */
|
||||
if ( easylink_softap_thread_handler ) {
|
||||
system_log("EasyLink SoftAP processing, force stop..");
|
||||
easylink_thread_force_exit = true;
|
||||
mico_rtos_thread_force_awake( &easylink_softap_thread_handler );
|
||||
mico_rtos_thread_join( &easylink_softap_thread_handler );
|
||||
}
|
||||
|
||||
if ( enable == MICO_TRUE ) {
|
||||
/* Start config server */
|
||||
err = config_server_start( );
|
||||
require_noerr( err, exit );
|
||||
|
||||
err = mico_rtos_create_thread( &easylink_softap_thread_handler, MICO_APPLICATION_PRIORITY, "EASYLINK AP",
|
||||
easylink_softap_thread, 0x1000, (mico_thread_arg_t) in_context );
|
||||
require_noerr_string( err, exit, "ERROR: Unable to start the EasyLink thread." );
|
||||
|
||||
/* Make sure easylink softap is already running, and waiting for sem trigger */
|
||||
mico_rtos_delay_milliseconds( 1000 );
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
//#endif
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_easylink_softap.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 20-July-2015
|
||||
* @brief This file provide the easylink function for quick provisioning and
|
||||
* first time 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 "StringUtils.h"
|
||||
#include "HTTPUtils.h"
|
||||
#include "SocketUtils.h"
|
||||
|
||||
#include "system.h"
|
||||
#include "easylink_internal.h"
|
||||
|
||||
/* Internal vars and functions */
|
||||
static mico_semaphore_t easylink_sem; /**< Used to suspend thread while easylink. */
|
||||
static mico_semaphore_t easylink_connect_sem; /**< Used to suspend thread while connection. */
|
||||
static bool easylink_success = false; /**< true: connect to wlan, false: start soft ap mode or roll back to previous settings */
|
||||
static uint32_t easylinkIndentifier = 0; /**< Unique for an easylink instance. */
|
||||
static mico_thread_t easylink_softap_thread_handler = NULL;
|
||||
static bool easylink_thread_force_exit = false;
|
||||
|
||||
/* Perform easylink and connect to wlan */
|
||||
static void easylink_softap_thread( uint32_t inContext );
|
||||
|
||||
/* MiCO callback when WiFi status is changed */
|
||||
static void easylink_wifi_status_cb( WiFiEvent event, system_context_t * const inContext )
|
||||
{
|
||||
switch ( event )
|
||||
{
|
||||
case NOTIFY_STATION_UP:
|
||||
/* Connected to AP, means that the wlan configuration is right, update configuration in flash and update
|
||||
bongjour txt record with new "easylinkIndentifier" */
|
||||
easylink_bonjour_update( Station, easylinkIndentifier, inContext );
|
||||
inContext->flashContentInRam.micoSystemConfig.configured = allConfigured;
|
||||
mico_system_context_update( &inContext->flashContentInRam ); //Update Flash content
|
||||
mico_rtos_set_semaphore( &easylink_connect_sem ); //Notify Easylink thread
|
||||
break;
|
||||
case NOTIFY_AP_DOWN:
|
||||
/* Remove bonjour service under soft ap interface */
|
||||
mdns_suspend_record( "_easylink_config._tcp.local.", Soft_AP, true );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OSStatus ConfigIncommingJsonMessageUAP( int fd, const uint8_t *input, size_t size, system_context_t * const inContext )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
json_object *new_obj;
|
||||
char *input_str = NULL;
|
||||
uint8_t *httpResponse = NULL;
|
||||
size_t httpResponseLen = 0;
|
||||
|
||||
inContext->flashContentInRam.micoSystemConfig.easyLinkByPass = EASYLINK_BYPASS_NO;
|
||||
|
||||
input_str = calloc( size + 1, sizeof(char) );
|
||||
require_action( input_str, exit, err = kNoMemoryErr );
|
||||
|
||||
memcpy( input_str, input, size );
|
||||
system_log("Recv config object=%s", input_str);
|
||||
new_obj = json_tokener_parse( input_str );
|
||||
require_action( new_obj, exit, err = kUnknownErr );
|
||||
|
||||
json_object_object_foreach( new_obj, key, val )
|
||||
{
|
||||
if ( !strcmp( key, "SSID" ) ) {
|
||||
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;
|
||||
}
|
||||
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 );
|
||||
memcpy( inContext->flashContentInRam.micoSystemConfig.key, inContext->flashContentInRam.micoSystemConfig.user_key, maxKeyLen );
|
||||
inContext->flashContentInRam.micoSystemConfig.keyLength = inContext->flashContentInRam.micoSystemConfig.user_keyLength;
|
||||
}
|
||||
else if ( !strcmp( key, "DHCP" ) ) {
|
||||
inContext->flashContentInRam.micoSystemConfig.dhcpEnable = json_object_get_boolean( val );
|
||||
}
|
||||
else if ( !strcmp( key, "IDENTIFIER" ) ) {
|
||||
easylinkIndentifier = (uint32_t) json_object_get_int( val );
|
||||
}
|
||||
else if ( !strcmp( key, "IP" ) ) {
|
||||
strncpy( inContext->flashContentInRam.micoSystemConfig.localIp, json_object_get_string( val ), maxIpLen );
|
||||
}
|
||||
else if ( !strcmp( key, "NETMASK" ) ) {
|
||||
strncpy( inContext->flashContentInRam.micoSystemConfig.netMask, json_object_get_string( val ), maxIpLen );
|
||||
}
|
||||
else if ( !strcmp( key, "GATEWAY" ) ) {
|
||||
strncpy( inContext->flashContentInRam.micoSystemConfig.gateWay, json_object_get_string( val ), maxIpLen );
|
||||
}
|
||||
else if ( !strcmp( key, "DNS1" ) ) {
|
||||
strncpy( inContext->flashContentInRam.micoSystemConfig.dnsServer, json_object_get_string( val ), maxIpLen );
|
||||
}
|
||||
}
|
||||
json_object_put( new_obj );
|
||||
|
||||
err = CreateSimpleHTTPOKMessage( &httpResponse, &httpResponseLen );
|
||||
require_noerr( err, exit );
|
||||
|
||||
err = SocketSend( fd, httpResponse, httpResponseLen );
|
||||
require_noerr( err, exit );
|
||||
|
||||
mico_rtos_delay_milliseconds( 1000 );
|
||||
|
||||
easylink_success = true;
|
||||
if( easylink_sem ) mico_rtos_set_semaphore( &easylink_sem );
|
||||
#ifdef MICO_EASYLINK_AND_SOFTAP_ENABLED
|
||||
easylink_uap_success(easylinkIndentifier);
|
||||
#endif
|
||||
exit:
|
||||
if ( input_str ) free( input_str );
|
||||
|
||||
if(httpResponse) free(httpResponse);
|
||||
return err;
|
||||
}
|
||||
|
||||
void easylink_softap_thread( uint32_t inContext )
|
||||
{
|
||||
system_log_trace();
|
||||
OSStatus err = kNoErr;
|
||||
system_context_t *context = (system_context_t *) inContext;
|
||||
network_InitTypeDef_st wNetConfig;
|
||||
|
||||
easylinkIndentifier = 0x0;
|
||||
easylink_success = false;
|
||||
|
||||
easylink_thread_force_exit = false;
|
||||
|
||||
mico_system_notify_register( mico_notify_WIFI_STATUS_CHANGED, (void *) easylink_wifi_status_cb, (void *) inContext );
|
||||
|
||||
mico_rtos_init_semaphore( &easylink_sem, 1 );
|
||||
mico_rtos_init_semaphore( &easylink_connect_sem, 1 );
|
||||
|
||||
restart:
|
||||
micoWlanSuspend( );
|
||||
mico_thread_msleep( 20 );
|
||||
|
||||
mico_system_delegate_config_will_start( );
|
||||
|
||||
memset( &wNetConfig, 0, sizeof(network_InitTypeDef_st) );
|
||||
wNetConfig.wifi_mode = Soft_AP;
|
||||
snprintf( wNetConfig.wifi_ssid, 32, "EasyLink_%c%c%c%c%c%c",
|
||||
context->micoStatus.mac[9], context->micoStatus.mac[10], context->micoStatus.mac[12],
|
||||
context->micoStatus.mac[13], context->micoStatus.mac[15], context->micoStatus.mac[16] );
|
||||
strcpy( (char*) wNetConfig.wifi_key, "" );
|
||||
strcpy( (char*) wNetConfig.local_ip_addr, "10.10.10.1" );
|
||||
strcpy( (char*) wNetConfig.net_mask, "255.255.255.0" );
|
||||
strcpy( (char*) wNetConfig.gateway_ip_addr, "10.10.10.1" );
|
||||
wNetConfig.dhcpMode = DHCP_Server;
|
||||
micoWlanStart( &wNetConfig );
|
||||
system_log("Establish soft ap: %s.....", wNetConfig.wifi_ssid);
|
||||
|
||||
/* Start bonjour service for device discovery under soft ap mode */
|
||||
err = easylink_bonjour_start( Soft_AP, 0, context );
|
||||
require_noerr( err, exit );
|
||||
|
||||
while( mico_rtos_get_semaphore( &easylink_sem, 0 ) == kNoErr );
|
||||
err = mico_rtos_get_semaphore( &easylink_sem, MICO_WAIT_FOREVER );
|
||||
|
||||
micoWlanSuspendSoftAP();
|
||||
|
||||
/* Easylink force exit by user, clean and exit */
|
||||
if( err != kNoErr && easylink_thread_force_exit )
|
||||
{
|
||||
system_log("EasyLink canceled by user");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* EasyLink Success */
|
||||
if ( easylink_success == true ) {
|
||||
mico_system_delegate_config_recv_ssid( context->flashContentInRam.micoSystemConfig.ssid,
|
||||
context->flashContentInRam.micoSystemConfig.user_key );
|
||||
|
||||
mico_thread_sleep(1);
|
||||
system_connect_wifi_normal( context );
|
||||
|
||||
/* Wait for station connection */
|
||||
while ( mico_rtos_get_semaphore( &easylink_connect_sem, 0 ) == kNoErr );
|
||||
err = mico_rtos_get_semaphore( &easylink_connect_sem, EasyLink_ConnectWlan_Timeout );
|
||||
/* Easylink force exit by user, clean and exit */
|
||||
if ( err != kNoErr && easylink_thread_force_exit )
|
||||
{
|
||||
micoWlanSuspend( );
|
||||
system_log("EasyLink connection canceled by user");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*SSID or Password is not correct, module cannot connect to wlan, so restart EasyLink again*/
|
||||
require_noerr_action_string( err, restart, micoWlanSuspend(), "Re-start easylink softap mode" );
|
||||
mico_system_delegate_config_success( CONFIG_BY_SOFT_AP );
|
||||
|
||||
/* Start bonjour service for new device discovery */
|
||||
err = easylink_bonjour_start( Station, easylinkIndentifier, context );
|
||||
require_noerr( err, exit );
|
||||
SetTimer( 60 * 1000, easylink_remove_bonjour );
|
||||
|
||||
goto exit;
|
||||
}
|
||||
else /* EasyLink failed */
|
||||
{
|
||||
/*so roll back to previous settings (if it has) and connect*/
|
||||
if(context->flashContentInRam.micoSystemConfig.configured != unConfigured)
|
||||
{
|
||||
system_log("Roll back to previous settings");
|
||||
MICOReadConfiguration( context );
|
||||
#ifdef EasyLink_Needs_Reboot
|
||||
context->flashContentInRam.micoSystemConfig.configured = allConfigured;
|
||||
mico_system_context_update( &context->flashContentInRam );
|
||||
#endif
|
||||
system_connect_wifi_normal( context );
|
||||
}
|
||||
else {
|
||||
/*module should power down in default setting*/
|
||||
system_log("Wi-Fi power off");
|
||||
micoWlanPowerOff( );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exit:
|
||||
easylink_thread_force_exit = false;
|
||||
|
||||
mico_system_delegate_config_will_stop( );
|
||||
|
||||
mico_system_notify_remove( mico_notify_WIFI_STATUS_CHANGED, (void *) easylink_wifi_status_cb );
|
||||
|
||||
#ifndef MICO_CONFIG_SERVER_ENABLE
|
||||
config_server_stop( );
|
||||
#endif
|
||||
|
||||
mico_rtos_deinit_semaphore( &easylink_sem );
|
||||
mico_rtos_deinit_semaphore( &easylink_connect_sem );
|
||||
easylink_softap_thread_handler = NULL;
|
||||
mico_rtos_delete_thread( NULL );
|
||||
}
|
||||
|
||||
OSStatus mico_easylink_softap( mico_Context_t * const in_context, mico_bool_t enable )
|
||||
{
|
||||
OSStatus err = kUnknownErr;
|
||||
|
||||
require_action( in_context, exit, err = kNotPreparedErr );
|
||||
|
||||
easylink_remove_bonjour( );
|
||||
|
||||
/* easylink soft thread existed? stop! */
|
||||
if ( easylink_softap_thread_handler ) {
|
||||
system_log("EasyLink SoftAP processing, force stop..");
|
||||
easylink_thread_force_exit = true;
|
||||
mico_rtos_thread_force_awake( &easylink_softap_thread_handler );
|
||||
mico_rtos_thread_join( &easylink_softap_thread_handler );
|
||||
}
|
||||
|
||||
if ( enable == MICO_TRUE ) {
|
||||
/* Start config server */
|
||||
err = config_server_start( );
|
||||
require_noerr( err, exit );
|
||||
|
||||
err = mico_rtos_create_thread( &easylink_softap_thread_handler, MICO_APPLICATION_PRIORITY, "EASYLINK AP",
|
||||
easylink_softap_thread, 0x1000, (mico_thread_arg_t) in_context );
|
||||
require_noerr_string( err, exit, "ERROR: Unable to start the EasyLink thread." );
|
||||
|
||||
/* Make sure easylink softap is already running, and waiting for sem trigger */
|
||||
mico_rtos_delay_milliseconds( 1000 );
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
//#endif
|
||||
|
||||
|
||||
@@ -1,134 +1,134 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_easylink.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 20-July-2015
|
||||
* @brief This file provide the easylink function for quick provisioning and
|
||||
* first time 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 "StringUtils.h"
|
||||
|
||||
#include "system.h"
|
||||
#include "easylink_internal.h"
|
||||
|
||||
//#if (MICO_WLAN_CONFIG_MODE == CONFIG_MODE_USER)
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
/* Perform easylink and connect to wlan */
|
||||
static void easylink_usr_thread( uint32_t inContext );
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
static mico_semaphore_t easylink_connect_sem; /**< Used to suspend thread while connection. */
|
||||
static mico_thread_t easylink_usr_thread_handler = NULL;
|
||||
static bool easylink_thread_force_exit = false;
|
||||
|
||||
|
||||
|
||||
/* MiCO callback when WiFi status is changed */
|
||||
static void easylink_wifi_status_cb( WiFiEvent event, system_context_t * const inContext )
|
||||
{
|
||||
system_log_trace();
|
||||
require( inContext, exit );
|
||||
|
||||
switch ( event )
|
||||
{
|
||||
case NOTIFY_STATION_UP:
|
||||
/* Connected to AP, means that the wlan configuration is right, update configuration in flash */
|
||||
inContext->flashContentInRam.micoSystemConfig.configured = allConfigured;
|
||||
mico_system_context_update( &inContext->flashContentInRam ); //Update Flash content
|
||||
mico_rtos_set_semaphore( &easylink_connect_sem ); //Notify Easylink thread
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
static void easylink_usr_thread( uint32_t inContext )
|
||||
{
|
||||
system_log_trace();
|
||||
OSStatus err = kNoErr;
|
||||
system_context_t *Context = (system_context_t *) inContext;
|
||||
|
||||
easylink_thread_force_exit = false;
|
||||
|
||||
mico_system_notify_register( mico_notify_WIFI_STATUS_CHANGED, (void *)easylink_wifi_status_cb, (void *) Context );
|
||||
mico_rtos_init_semaphore( &easylink_connect_sem, 1 );
|
||||
|
||||
system_log("Start easylink user mode");
|
||||
mico_system_delegate_config_will_start( );
|
||||
|
||||
/* Developer should save the ssid/key to system_context_t and connect to AP.
|
||||
* NOTIFY_STATION_UP event will save the new ssid, key to flash and wake up the easylink routine */
|
||||
while ( mico_rtos_get_semaphore( &easylink_connect_sem, 0 ) == kNoErr );
|
||||
err = mico_rtos_get_semaphore( &easylink_connect_sem, MICO_WAIT_FOREVER );
|
||||
|
||||
/* Easylink force exit by user, clean and exit */
|
||||
if ( err != kNoErr && easylink_thread_force_exit ){
|
||||
micoWlanSuspend( );
|
||||
system_log("EasyLink connection canceled by user");
|
||||
easylink_thread_force_exit = false;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mico_system_delegate_config_success( CONFIG_BY_USER );
|
||||
|
||||
exit:
|
||||
mico_system_delegate_config_will_stop( );
|
||||
mico_system_notify_remove( mico_notify_WIFI_STATUS_CHANGED, (void *) easylink_wifi_status_cb );
|
||||
|
||||
mico_rtos_deinit_semaphore( &easylink_connect_sem );
|
||||
easylink_usr_thread_handler = NULL;
|
||||
mico_rtos_delete_thread( NULL );
|
||||
}
|
||||
|
||||
OSStatus mico_easylink_usr( mico_Context_t * const in_context, mico_bool_t enable )
|
||||
{
|
||||
OSStatus err = kUnknownErr;
|
||||
|
||||
require_action( in_context, exit, err = kNotPreparedErr );
|
||||
|
||||
easylink_remove_bonjour( );
|
||||
|
||||
/* easylink thread existed? stop! */
|
||||
if ( easylink_usr_thread_handler ) {
|
||||
/* easylink usr thread existed? stop! */
|
||||
system_log("EasyLink usr processing, force stop..");
|
||||
easylink_thread_force_exit = true;
|
||||
mico_rtos_thread_force_awake( &easylink_usr_thread_handler );
|
||||
mico_rtos_thread_join( &easylink_usr_thread_handler );
|
||||
}
|
||||
|
||||
if ( enable == MICO_TRUE ) {
|
||||
err = mico_rtos_create_thread( &easylink_usr_thread_handler, MICO_APPLICATION_PRIORITY, "EASYLINK USR",
|
||||
easylink_usr_thread, 0x1000, (mico_thread_arg_t) in_context );
|
||||
require_noerr_string( err, exit, "ERROR: Unable to start the EasyLink usr thread." );
|
||||
|
||||
/* Make sure easylink is already running, and waiting for sem trigger */
|
||||
mico_rtos_delay_milliseconds( 100 );
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
//#endif
|
||||
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_easylink.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 20-July-2015
|
||||
* @brief This file provide the easylink function for quick provisioning and
|
||||
* first time 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 "StringUtils.h"
|
||||
|
||||
#include "system.h"
|
||||
#include "easylink_internal.h"
|
||||
|
||||
//#if (MICO_WLAN_CONFIG_MODE == CONFIG_MODE_USER)
|
||||
|
||||
/******************************************************
|
||||
* Function Declarations
|
||||
******************************************************/
|
||||
/* Perform easylink and connect to wlan */
|
||||
static void easylink_usr_thread( uint32_t inContext );
|
||||
|
||||
/******************************************************
|
||||
* Variables Definitions
|
||||
******************************************************/
|
||||
static mico_semaphore_t easylink_connect_sem; /**< Used to suspend thread while connection. */
|
||||
static mico_thread_t easylink_usr_thread_handler = NULL;
|
||||
static bool easylink_thread_force_exit = false;
|
||||
|
||||
|
||||
|
||||
/* MiCO callback when WiFi status is changed */
|
||||
static void easylink_wifi_status_cb( WiFiEvent event, system_context_t * const inContext )
|
||||
{
|
||||
system_log_trace();
|
||||
require( inContext, exit );
|
||||
|
||||
switch ( event )
|
||||
{
|
||||
case NOTIFY_STATION_UP:
|
||||
/* Connected to AP, means that the wlan configuration is right, update configuration in flash */
|
||||
inContext->flashContentInRam.micoSystemConfig.configured = allConfigured;
|
||||
mico_system_context_update( &inContext->flashContentInRam ); //Update Flash content
|
||||
mico_rtos_set_semaphore( &easylink_connect_sem ); //Notify Easylink thread
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
static void easylink_usr_thread( uint32_t inContext )
|
||||
{
|
||||
system_log_trace();
|
||||
OSStatus err = kNoErr;
|
||||
system_context_t *Context = (system_context_t *) inContext;
|
||||
|
||||
easylink_thread_force_exit = false;
|
||||
|
||||
mico_system_notify_register( mico_notify_WIFI_STATUS_CHANGED, (void *)easylink_wifi_status_cb, (void *) Context );
|
||||
mico_rtos_init_semaphore( &easylink_connect_sem, 1 );
|
||||
|
||||
system_log("Start easylink user mode");
|
||||
mico_system_delegate_config_will_start( );
|
||||
|
||||
/* Developer should save the ssid/key to system_context_t and connect to AP.
|
||||
* NOTIFY_STATION_UP event will save the new ssid, key to flash and wake up the easylink routine */
|
||||
while ( mico_rtos_get_semaphore( &easylink_connect_sem, 0 ) == kNoErr );
|
||||
err = mico_rtos_get_semaphore( &easylink_connect_sem, MICO_WAIT_FOREVER );
|
||||
|
||||
/* Easylink force exit by user, clean and exit */
|
||||
if ( err != kNoErr && easylink_thread_force_exit ){
|
||||
micoWlanSuspend( );
|
||||
system_log("EasyLink connection canceled by user");
|
||||
easylink_thread_force_exit = false;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mico_system_delegate_config_success( CONFIG_BY_USER );
|
||||
|
||||
exit:
|
||||
mico_system_delegate_config_will_stop( );
|
||||
mico_system_notify_remove( mico_notify_WIFI_STATUS_CHANGED, (void *) easylink_wifi_status_cb );
|
||||
|
||||
mico_rtos_deinit_semaphore( &easylink_connect_sem );
|
||||
easylink_usr_thread_handler = NULL;
|
||||
mico_rtos_delete_thread( NULL );
|
||||
}
|
||||
|
||||
OSStatus mico_easylink_usr( mico_Context_t * const in_context, mico_bool_t enable )
|
||||
{
|
||||
OSStatus err = kUnknownErr;
|
||||
|
||||
require_action( in_context, exit, err = kNotPreparedErr );
|
||||
|
||||
easylink_remove_bonjour( );
|
||||
|
||||
/* easylink thread existed? stop! */
|
||||
if ( easylink_usr_thread_handler ) {
|
||||
/* easylink usr thread existed? stop! */
|
||||
system_log("EasyLink usr processing, force stop..");
|
||||
easylink_thread_force_exit = true;
|
||||
mico_rtos_thread_force_awake( &easylink_usr_thread_handler );
|
||||
mico_rtos_thread_join( &easylink_usr_thread_handler );
|
||||
}
|
||||
|
||||
if ( enable == MICO_TRUE ) {
|
||||
err = mico_rtos_create_thread( &easylink_usr_thread_handler, MICO_APPLICATION_PRIORITY, "EASYLINK USR",
|
||||
easylink_usr_thread, 0x1000, (mico_thread_arg_t) in_context );
|
||||
require_noerr_string( err, exit, "ERROR: Unable to start the EasyLink usr thread." );
|
||||
|
||||
/* Make sure easylink is already running, and waiting for sem trigger */
|
||||
mico_rtos_delay_milliseconds( 100 );
|
||||
}
|
||||
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
//#endif
|
||||
|
||||
|
||||
@@ -1,75 +1,75 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file mico_easylink_wac.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide header file for start a Apple WAC (wireless accessory
|
||||
* configuration) function thread.
|
||||
******************************************************************************
|
||||
*
|
||||
* 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 "MFi_WAC.h"
|
||||
|
||||
#include "StringUtils.h"
|
||||
|
||||
#define BUNDLE_SEED_ID "C6P64J2MZX"
|
||||
#define EA_PROTOCOL "com.issc.datapath"
|
||||
|
||||
const char *eaProtocols[1] = {EA_PROTOCOL};
|
||||
|
||||
OSStatus mico_easylink_wac( mico_Context_t * const inContext, mico_bool_t enable )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
IPStatusTypedef para;
|
||||
uint8_t major_ver, minor_ver, revision;
|
||||
|
||||
if( enable == FALSE ) {
|
||||
return mfi_wac_stop();
|
||||
}
|
||||
|
||||
mfi_wac_lib_version( &major_ver, &minor_ver, &revision );
|
||||
system_log( "Import MFi WAC library v%d.%d.%d", major_ver, minor_ver, revision );
|
||||
|
||||
WACPlatformParameters_t* WAC_Params = NULL;
|
||||
WAC_Params = calloc(1, sizeof(WACPlatformParameters_t));
|
||||
require(WAC_Params, exit);
|
||||
|
||||
micoWlanGetIPStatus(¶, Station);
|
||||
|
||||
str2hex((unsigned char *)para.mac, WAC_Params->macAddress, 6);
|
||||
WAC_Params->isUnconfigured = 1;
|
||||
WAC_Params->supportsAirPlay = 0;
|
||||
WAC_Params->supportsAirPrint = 0;
|
||||
WAC_Params->supports2_4GHzWiFi = 1;
|
||||
WAC_Params->supports5GHzWiFi = 0;
|
||||
WAC_Params->supportsWakeOnWireless = 0;
|
||||
|
||||
WAC_Params->firmwareRevision = FIRMWARE_REVISION;
|
||||
WAC_Params->hardwareRevision = HARDWARE_REVISION;
|
||||
WAC_Params->serialNumber = SERIAL_NUMBER;
|
||||
WAC_Params->name = inContext->micoSystemConfig.name;
|
||||
WAC_Params->model = MODEL;
|
||||
WAC_Params->manufacturer = MANUFACTURER;
|
||||
|
||||
WAC_Params->numEAProtocols = 1;
|
||||
WAC_Params->eaBundleSeedID = BUNDLE_SEED_ID;
|
||||
WAC_Params->eaProtocols = (char **)eaProtocols;
|
||||
|
||||
err = mfi_wac_start( inContext, WAC_Params, MICO_I2C_CP, 1200 );
|
||||
require_noerr(err, exit);
|
||||
|
||||
exit:
|
||||
free(WAC_Params);
|
||||
return err;
|
||||
}
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file mico_easylink_wac.c
|
||||
* @author William Xu
|
||||
* @version V1.0.0
|
||||
* @date 05-May-2014
|
||||
* @brief This file provide header file for start a Apple WAC (wireless accessory
|
||||
* configuration) function thread.
|
||||
******************************************************************************
|
||||
*
|
||||
* 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 "MFi_WAC.h"
|
||||
|
||||
#include "StringUtils.h"
|
||||
|
||||
#define BUNDLE_SEED_ID "C6P64J2MZX"
|
||||
#define EA_PROTOCOL "com.issc.datapath"
|
||||
|
||||
const char *eaProtocols[1] = {EA_PROTOCOL};
|
||||
|
||||
OSStatus mico_easylink_wac( mico_Context_t * const inContext, mico_bool_t enable )
|
||||
{
|
||||
OSStatus err = kNoErr;
|
||||
IPStatusTypedef para;
|
||||
uint8_t major_ver, minor_ver, revision;
|
||||
|
||||
if( enable == FALSE ) {
|
||||
return mfi_wac_stop();
|
||||
}
|
||||
|
||||
mfi_wac_lib_version( &major_ver, &minor_ver, &revision );
|
||||
system_log( "Import MFi WAC library v%d.%d.%d", major_ver, minor_ver, revision );
|
||||
|
||||
WACPlatformParameters_t* WAC_Params = NULL;
|
||||
WAC_Params = calloc(1, sizeof(WACPlatformParameters_t));
|
||||
require(WAC_Params, exit);
|
||||
|
||||
micoWlanGetIPStatus(¶, Station);
|
||||
|
||||
str2hex((unsigned char *)para.mac, WAC_Params->macAddress, 6);
|
||||
WAC_Params->isUnconfigured = 1;
|
||||
WAC_Params->supportsAirPlay = 0;
|
||||
WAC_Params->supportsAirPrint = 0;
|
||||
WAC_Params->supports2_4GHzWiFi = 1;
|
||||
WAC_Params->supports5GHzWiFi = 0;
|
||||
WAC_Params->supportsWakeOnWireless = 0;
|
||||
|
||||
WAC_Params->firmwareRevision = FIRMWARE_REVISION;
|
||||
WAC_Params->hardwareRevision = HARDWARE_REVISION;
|
||||
WAC_Params->serialNumber = SERIAL_NUMBER;
|
||||
WAC_Params->name = inContext->micoSystemConfig.name;
|
||||
WAC_Params->model = MODEL;
|
||||
WAC_Params->manufacturer = MANUFACTURER;
|
||||
|
||||
WAC_Params->numEAProtocols = 1;
|
||||
WAC_Params->eaBundleSeedID = BUNDLE_SEED_ID;
|
||||
WAC_Params->eaProtocols = (char **)eaProtocols;
|
||||
|
||||
err = mfi_wac_start( inContext, WAC_Params, MICO_I2C_CP, 1200 );
|
||||
require_noerr(err, exit);
|
||||
|
||||
exit:
|
||||
free(WAC_Params);
|
||||
return err;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user