void EasyLinkNotify_EasyLinkCompleteHandler(network_InitTypeDef_st *nwkpara, mico_Context_t * const inContext) { OSStatus err; easylink_log_trace(); easylink_log("EasyLink return"); require_action(inContext, exit, err = kParamErr); require_action(nwkpara, exit, err = kTimeoutErr); mico_rtos_lock_mutex(&inContext->flashContentInRam_mutex); memcpy(inContext->flashContentInRam.micoSystemConfig.ssid, nwkpara->wifi_ssid, maxSsidLen); memcpy(inContext->flashContentInRam.micoSystemConfig.user_key, nwkpara->wifi_key, maxKeyLen); inContext->flashContentInRam.micoSystemConfig.user_keyLength = strlen(nwkpara->wifi_key); mico_rtos_unlock_mutex(&inContext->flashContentInRam_mutex); easylink_log("Get SSID: %s, Key: %s", inContext->flashContentInRam.micoSystemConfig.ssid, inContext->flashContentInRam.micoSystemConfig.user_key); return; /*EasyLink is not start*/ exit: easylink_log("ERROR, err: %d", err); #if defined (CONFIG_MODE_EASYLINK_WITH_SOFTAP) EasylinkFailed = true; mico_rtos_set_semaphore(&easylink_sem); #else ConfigWillStop(inContext); /*so roll back to previous settings (if it has) and reboot*/ mico_rtos_lock_mutex(&inContext->flashContentInRam_mutex); if(inContext->flashContentInRam.micoSystemConfig.configured != unConfigured){ inContext->flashContentInRam.micoSystemConfig.configured = allConfigured; MICOUpdateConfiguration(inContext); PlatformSoftReboot(); } mico_rtos_unlock_mutex(&inContext->flashContentInRam_mutex); /*module should powd down in default setting*/ wifi_power_down(); #endif return; }
void _easylinkConnectWiFi_fast( mico_Context_t * const inContext) { easylink_log_trace(); network_InitTypeDef_adv_st wNetConfig; memset(&wNetConfig, 0x0, sizeof(network_InitTypeDef_adv_st)); mico_rtos_lock_mutex(&inContext->flashContentInRam_mutex); strncpy((char*)wNetConfig.ap_info.ssid, inContext->flashContentInRam.micoSystemConfig.ssid, maxSsidLen); memcpy(wNetConfig.ap_info.bssid, inContext->flashContentInRam.micoSystemConfig.bssid, 6); wNetConfig.ap_info.channel = inContext->flashContentInRam.micoSystemConfig.channel; wNetConfig.ap_info.security = inContext->flashContentInRam.micoSystemConfig.security; memcpy(wNetConfig.key, inContext->flashContentInRam.micoSystemConfig.key, maxKeyLen); wNetConfig.key_len = inContext->flashContentInRam.micoSystemConfig.keyLength; wNetConfig.dhcpMode = inContext->flashContentInRam.micoSystemConfig.dhcpEnable; strncpy((char*)wNetConfig.local_ip_addr, inContext->flashContentInRam.micoSystemConfig.localIp, maxIpLen); strncpy((char*)wNetConfig.net_mask, inContext->flashContentInRam.micoSystemConfig.netMask, maxIpLen); strncpy((char*)wNetConfig.gateway_ip_addr, inContext->flashContentInRam.micoSystemConfig.gateWay, maxIpLen); strncpy((char*)wNetConfig.dnsServer_ip_addr, inContext->flashContentInRam.micoSystemConfig.dnsServer, maxIpLen); wNetConfig.wifi_retry_interval = 100; mico_rtos_unlock_mutex(&inContext->flashContentInRam_mutex); StartAdvNetwork(&wNetConfig); easylink_log("Connect to %s.....\r\n", wNetConfig.ap_info.ssid); }
void _easylinkStartSoftAp( mico_Context_t * const inContext) { OSStatus err; easylink_log_trace(); network_InitTypeDef_st wNetConfig; memset(&wNetConfig, 0, sizeof(network_InitTypeDef_st)); wNetConfig.wifi_mode = Soft_AP; snprintf(wNetConfig.wifi_ssid, 32, "MXCHIP_%c%c%c%c%c%c", inContext->micoStatus.mac[9], inContext->micoStatus.mac[10], \ inContext->micoStatus.mac[12], inContext->micoStatus.mac[13], inContext->micoStatus.mac[15], inContext->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"); strcpy((char*)wNetConfig.address_pool_start, "10.10.10.10"); strcpy((char*)wNetConfig.address_pool_end, "10.10.10.177"); wNetConfig.dhcpMode = DHCP_Server; StartNetwork(&wNetConfig); easylink_log("Establish soft ap: %s.....", wNetConfig.wifi_ssid); if(inContext->flashContentInRam.micoSystemConfig.bonjourEnable == true){ err = MICOStartBonjourService( Soft_AP , inContext ); require_noerr(err, exit); } if(inContext->flashContentInRam.micoSystemConfig.configServerEnable == true){ err = MICOStartConfigServer ( inContext ); require_noerr(err, exit); } ConfigSoftApWillStart( inContext ); exit: return; }
void easylink_thread(void *inContext) { OSStatus err = kNoErr; mico_Context_t *Context = inContext; fd_set readfds; struct timeval_t t; int reConnCount = 0; easylink_log_trace(); require_action(easylink_sem, threadexit, err = kNotPreparedErr); if(Context->flashContentInRam.micoSystemConfig.easyLinkEnable != false){ OpenEasylink2_withdata(EasyLink_TimeOut); easylink_log("Start easylink"); mico_rtos_get_semaphore(&easylink_sem, MICO_WAIT_FOREVER); if(EasylinkFailed == false) _easylinkConnectWiFi(Context); else{ _easylinkStartSoftAp(Context); mico_rtos_delete_thread(NULL); return; } }else{ mico_rtos_lock_mutex(&Context->flashContentInRam_mutex); Context->flashContentInRam.micoSystemConfig.easyLinkEnable = true; MICOUpdateConfiguration(Context); mico_rtos_unlock_mutex(&Context->flashContentInRam_mutex); _easylinkConnectWiFi_fast(Context); } err = mico_rtos_get_semaphore(&easylink_sem, ConnectFTC_Timeout); require_noerr(err, reboot); httpHeader = HTTPHeaderCreate(); require_action( httpHeader, threadexit, err = kNoMemoryErr ); HTTPHeaderClear( httpHeader ); t.tv_sec = 100; t.tv_usec = 0; while(1){ if(easylinkClient_fd == -1){ err = _connectFTCServer(inContext, &easylinkClient_fd); require_noerr(err, Reconn); }else{ FD_ZERO(&readfds); FD_SET(easylinkClient_fd, &readfds); err = select(1, &readfds, NULL, NULL, &t); if(FD_ISSET(easylinkClient_fd, &readfds)){ err = SocketReadHTTPHeader( easylinkClient_fd, httpHeader ); switch ( err ) { case kNoErr: // Read the rest of the HTTP body if necessary err = SocketReadHTTPBody( easylinkClient_fd, httpHeader ); require_noerr(err, Reconn); PrintHTTPHeader(httpHeader); // Call the HTTPServer owner back with the acquired HTTP header err = _FTCRespondInComingMessage( easylinkClient_fd, httpHeader, Context ); require_noerr( err, Reconn ); // Reuse HTTPHeader HTTPHeaderClear( httpHeader ); break; case EWOULDBLOCK: // NO-OP, keep reading break; case kNoSpaceErr: easylink_log("ERROR: Cannot fit HTTPHeader."); goto Reconn; break; case kConnectionErr: // NOTE: kConnectionErr from SocketReadHTTPHeader means it's closed easylink_log("ERROR: Connection closed."); goto threadexit; //goto Reconn; break; default: easylink_log("ERROR: HTTP Header parse internal error: %d", err); goto Reconn; } } } continue; Reconn: HTTPHeaderClear( httpHeader ); SocketClose(&easylinkClient_fd); easylinkClient_fd = -1; require(reConnCount < 6, threadexit); reConnCount++; sleep(5); } /*Module is ignored by FTC server, */ threadexit: ConfigWillStop( Context ); _cleanEasyLinkResource( Context ); /*Roll back to previous settings (if it has) and reboot*/ mico_rtos_lock_mutex(&Context->flashContentInRam_mutex); if(Context->flashContentInRam.micoSystemConfig.configured != unConfigured){ Context->flashContentInRam.micoSystemConfig.configured = allConfigured; MICOUpdateConfiguration( Context ); PlatformSoftReboot(); } mico_rtos_unlock_mutex(&Context->flashContentInRam_mutex); wifi_power_down(); mico_rtos_delete_thread( NULL ); return; /*SSID or Password is not correct, module cannot connect to wlan, so reboot and enter EasyLink again*/ reboot: ConfigWillStop( Context ); PlatformSoftReboot(); return; }
OSStatus _FTCRespondInComingMessage(int fd, HTTPHeader_t* inHeader, mico_Context_t * const inContext) { OSStatus err = kUnknownErr; const char * value; size_t valueSize; easylink_log_trace(); switch(inHeader->statusCode){ case kStatusAccept: easylink_log("Easylink server accepted!"); err = kNoErr; goto exit; case kStatusOK: easylink_log("Easylink server respond status OK!"); err = HTTPGetHeaderField( inHeader->buf, inHeader->len, "Content-Type", NULL, NULL, &value, &valueSize, NULL ); require_noerr(err, exit); if( strnicmpx( value, valueSize, kMIMEType_JSON ) == 0 ){ easylink_log("Receive JSON config data!"); err = ConfigIncommingJsonMessage( inHeader->extraDataPtr, inContext); inContext->flashContentInRam.micoSystemConfig.configured = allConfigured; err = MICOUpdateConfiguration(inContext); SocketClose(&fd); inContext->micoStatus.sys_state = eState_Software_Reset; require(inContext->micoStatus.sys_state_change_sem, exit); mico_rtos_set_semaphore(&inContext->micoStatus.sys_state_change_sem); mico_thread_sleep(MICO_WAIT_FOREVER); } #ifdef MICO_FLASH_FOR_UPDATE else if(strnicmpx( value, valueSize, kMIMEType_MXCHIP_OTA ) == 0){ easylink_log("Receive OTA data!"); mico_rtos_lock_mutex(&inContext->flashContentInRam_mutex); memset(&inContext->flashContentInRam.bootTable, 0, sizeof(boot_table_t)); inContext->flashContentInRam.bootTable.length = inHeader->contentLength; inContext->flashContentInRam.bootTable.start_address = UPDATE_START_ADDRESS; inContext->flashContentInRam.bootTable.type = 'A'; inContext->flashContentInRam.bootTable.upgrade_type = 'U'; inContext->flashContentInRam.micoSystemConfig.easyLinkByPass = EASYLINK_BYPASS; MICOUpdateConfiguration(inContext); mico_rtos_unlock_mutex(&inContext->flashContentInRam_mutex); SocketClose(&fd); inContext->micoStatus.sys_state = eState_Software_Reset; require(inContext->micoStatus.sys_state_change_sem, exit); mico_rtos_set_semaphore(&inContext->micoStatus.sys_state_change_sem); mico_thread_sleep(MICO_WAIT_FOREVER); } #endif else{ return kUnsupportedDataErr; } err = kNoErr; goto exit; default: goto exit; } exit: return err; }
void easylink_thread(void *inContext) { OSStatus err = kNoErr; mico_Context_t *Context = inContext; fd_set readfds; int reConnCount = 0; int clientFdIsSet; easylink_log_trace(); require_action(easylink_sem, threadexit, err = kNotPreparedErr); if(Context->flashContentInRam.micoSystemConfig.easyLinkByPass == EASYLINK_BYPASS){ Context->flashContentInRam.micoSystemConfig.easyLinkByPass = EASYLINK_BYPASS_NO; MICOUpdateConfiguration(Context); _easylinkConnectWiFi_fast(Context); }else if(Context->flashContentInRam.micoSystemConfig.easyLinkByPass == EASYLINK_SOFT_AP_BYPASS){ ConfigWillStop( Context ); _easylinkStartSoftAp(Context); mico_rtos_delete_thread(NULL); return; }else{ #ifdef EasyLink_Plus easylink_log("Start easylink plus mode"); micoWlanStartEasyLinkPlus(EasyLink_TimeOut/1000); #else easylink_log("Start easylink V2"); micoWlanStartEasyLink(EasyLink_TimeOut/1000); #endif mico_rtos_get_semaphore(&easylink_sem, MICO_WAIT_FOREVER); if(EasylinkFailed == false) _easylinkConnectWiFi(Context); else{ msleep(20); _cleanEasyLinkResource( Context ); ConfigWillStop( Context ); _easylinkStartSoftAp(Context); mico_rtos_delete_thread(NULL); return; } } err = mico_rtos_get_semaphore(&easylink_sem, EasyLink_ConnectWlan_Timeout); require_noerr(err, reboot); httpHeader = HTTPHeaderCreate(); require_action( httpHeader, threadexit, err = kNoMemoryErr ); HTTPHeaderClear( httpHeader ); while(1){ if(easylinkClient_fd == -1){ err = _connectFTCServer(inContext, &easylinkClient_fd); require_noerr(err, Reconn); }else{ FD_ZERO(&readfds); FD_SET(easylinkClient_fd, &readfds); if(httpHeader->len == 0){ err = select(1, &readfds, NULL, NULL, NULL); require(err>=1, threadexit); clientFdIsSet = FD_ISSET(easylinkClient_fd, &readfds); } if(clientFdIsSet||httpHeader->len){ err = SocketReadHTTPHeader( easylinkClient_fd, httpHeader ); switch ( err ) { case kNoErr: // Read the rest of the HTTP body if necessary do{ err = SocketReadHTTPBody( easylinkClient_fd, httpHeader ); require_noerr(err, Reconn); PrintHTTPHeader(httpHeader); // Call the HTTPServer owner back with the acquired HTTP header err = _FTCRespondInComingMessage( easylinkClient_fd, httpHeader, Context ); require_noerr( err, Reconn ); if(httpHeader->contentLength == 0) break; } while( httpHeader->chunkedData == true || httpHeader->dataEndedbyClose == true); // Reuse HTTPHeader HTTPHeaderClear( httpHeader ); break; case EWOULDBLOCK: // NO-OP, keep reading break; case kNoSpaceErr: easylink_log("ERROR: Cannot fit HTTPHeader."); goto Reconn; case kConnectionErr: // NOTE: kConnectionErr from SocketReadHTTPHeader means it's closed easylink_log("ERROR: Connection closed."); /*Roll back to previous settings (if it has) and reboot*/ if(Context->flashContentInRam.micoSystemConfig.configured == wLanUnConfigured ){ Context->flashContentInRam.micoSystemConfig.configured = allConfigured; MICOUpdateConfiguration( Context ); MicoSystemReboot(); }else{ micoWlanPowerOff(); msleep(20); } goto threadexit; default: easylink_log("ERROR: HTTP Header parse internal error: %d", err); goto Reconn; } } } continue; Reconn: HTTPHeaderClear( httpHeader ); SocketClose(&easylinkClient_fd); easylinkClient_fd = -1; require(reConnCount < 6, reboot); reConnCount++; sleep(5); } /*Module is ignored by FTC server, */ threadexit: _cleanEasyLinkResource( Context ); ConfigWillStop( Context ); mico_rtos_delete_thread( NULL ); return; /*SSID or Password is not correct, module cannot connect to wlan, so reboot and enter EasyLink again*/ reboot: MicoSystemReboot(); return; }