Host library for controlling a WiConnect enabled Wi-Fi module.

Dependents:   wiconnect-ota_example wiconnect-web_setup_example wiconnect-test-console wiconnect-tcp_server_example ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NetworkJoin.cpp Source File

NetworkJoin.cpp

00001 /**
00002  * ACKme WiConnect Host Library is licensed under the BSD licence: 
00003  * 
00004  * Copyright (c)2014 ACKme Networks.
00005  * All rights reserved. 
00006  * 
00007  * Redistribution and use in source and binary forms, with or without modification, 
00008  * are permitted provided that the following conditions are met: 
00009  * 
00010  * 1. Redistributions of source code must retain the above copyright notice, 
00011  * this list of conditions and the following disclaimer. 
00012  * 2. Redistributions in binary form must reproduce the above copyright notice, 
00013  * this list of conditions and the following disclaimer in the documentation 
00014  * and/or other materials provided with the distribution. 
00015  * 3. The name of the author may not be used to endorse or promote products 
00016  * derived from this software without specific prior written permission. 
00017  * 
00018  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED 
00019  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
00020  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
00021  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00022  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
00023  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
00026  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
00027  * OF SUCH DAMAGE.
00028  */
00029 #include "Wiconnect.h"
00030 #include "internal/common.h"
00031 
00032 /*************************************************************************************************/
00033 WiconnectResult NetworkInterface::join(const char* ssid, const char *password, const Callback &completeHandler_)
00034 {
00035     WiconnectResult result = WICONNECT_ERROR;
00036 
00037     enum
00038     {
00039         FS_SET_SSID,
00040         FS_SET_PASSWORD,
00041         FS_NETWORK_UP,
00042         FS_GET_STATUS
00043     };
00044 
00045     CHECK_CALLBACK_AVAILABLE(completeHandler_);
00046 
00047     CHECK_OTHER_COMMAND_EXECUTING();
00048 
00049     if(wiconnect->internalProcessingState == FS_SET_SSID)
00050     {
00051         if(ssid == NULL ||
00052            WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("set wlan.ssid %s", ssid)))
00053         {
00054             wiconnect->internalProcessingState = FS_SET_PASSWORD;
00055         }
00056     }
00057 
00058     if(wiconnect->internalProcessingState == FS_SET_PASSWORD)
00059     {
00060         if(password == NULL || *password == 0 ||
00061            WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("set wlan.passkey %s", password)))
00062         {
00063             wiconnect->internalProcessingState = FS_NETWORK_UP;
00064         }
00065     }
00066 
00067     if(wiconnect->internalProcessingState == FS_NETWORK_UP)
00068     {
00069         if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("network_up")))
00070         {
00071             if(!completeHandler_.isValid())
00072             {
00073                 wiconnect->internalProcessingState = FS_GET_STATUS;
00074             }
00075 #ifdef WICONNECT_ASYNC_TIMER_ENABLED
00076             else
00077             {
00078                 monitorTimer.stop();
00079                 completeHandler = completeHandler_;
00080                 monitorTimer.start(this, &NetworkInterface::joinStatusMonitor, 1000);
00081             }
00082 #endif
00083         }
00084     }
00085 
00086     if(wiconnect->internalProcessingState == FS_GET_STATUS)
00087     {
00088 #define MAX_JOIN_TIME 30000
00089         TimeoutTimer timeout;
00090 
00091         status_loop:
00092         if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get wlan.join.result")))
00093         {
00094             int32_t status;
00095             if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&status)))
00096             {
00097                 if((NetworkJoinResult)status == NETWORK_JOIN_RESULT_JOINING)
00098                 {
00099                     if(timeout.timedOut(MAX_JOIN_TIME))
00100                     {
00101                         result = WICONNECT_TIMEOUT;
00102                     }
00103                     else if(!wiconnect->nonBlocking)
00104                     {
00105                         goto status_loop;
00106                     }
00107                     else
00108                     {
00109                         result = WICONNECT_PROCESSING;
00110                     }
00111                 }
00112                 else
00113                 {
00114                     result = ((NetworkJoinResult)status == NETWORK_JOIN_RESULT_SUCCESS) ? WICONNECT_SUCCESS : WICONNECT_NOT_CONNECTED;
00115                 }
00116             }
00117         }
00118     }
00119 
00120     CHECK_CLEANUP_COMMAND();
00121 
00122     return result;
00123 }
00124 
00125 
00126 
00127 /*************************************************************************************************/
00128 WiconnectResult NetworkInterface::leave()
00129 {
00130     WiconnectResult result;
00131 
00132     CHECK_OTHER_COMMAND_EXECUTING();
00133 
00134 #ifdef WICONNECT_ASYNC_TIMER_ENABLED
00135     monitorTimer.stop();
00136 #endif
00137     result = wiconnect->sendCommand("network_down");
00138 
00139     CHECK_CLEANUP_COMMAND();
00140 
00141     return result;
00142 }
00143 
00144 
00145 /*************************************************************************************************/
00146 WiconnectResult NetworkInterface::getNetworkStatus(NetworkStatus *statusPtr)
00147 {
00148     WiconnectResult result;
00149 
00150     CHECK_OTHER_COMMAND_EXECUTING();
00151 
00152     if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get network.status")))
00153     {
00154         int32_t status;
00155         if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&status)))
00156         {
00157             if(status != NETWORK_STATUS_DOWN)
00158             {
00159 #ifdef WICONNECT_ASYNC_TIMER_ENABLED
00160                 monitorTimer.stop();
00161 #endif
00162             }
00163             *statusPtr = (NetworkStatus)status;
00164         }
00165     }
00166 
00167     CHECK_CLEANUP_COMMAND();
00168 
00169     return result;
00170 }
00171 
00172 /*************************************************************************************************/
00173 WiconnectResult NetworkInterface::getNetworkJoinResult(NetworkJoinResult *joinResultPtr)
00174 {
00175     WiconnectResult result;
00176 
00177     CHECK_OTHER_COMMAND_EXECUTING();
00178 
00179     if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get wlan.join.result")))
00180     {
00181         int32_t status;
00182         if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&status)))
00183         {
00184             if(status != NETWORK_JOIN_RESULT_JOINING)
00185             {
00186 #ifdef WICONNECT_ASYNC_TIMER_ENABLED
00187                 monitorTimer.stop();
00188 #endif
00189             }
00190             *joinResultPtr = (NetworkJoinResult)status;
00191         }
00192     }
00193 
00194     CHECK_CLEANUP_COMMAND();
00195 
00196     return result;
00197 }
00198 
00199 #ifdef WICONNECT_ASYNC_TIMER_ENABLED
00200 
00201 
00202 /*************************************************************************************************/
00203 // this is called every 1s by the monitorTimer
00204 void NetworkInterface::joinStatusMonitor()
00205 {
00206     static char responseBuffer[4];
00207     static uint8_t cmdBuffer[sizeof(QueuedCommand)];
00208     QueuedCommand *cmd = (QueuedCommand*)cmdBuffer;
00209 
00210     monitorTimer.stop();
00211 
00212    *cmd = QueuedCommand(sizeof(responseBuffer), responseBuffer, "get wlan.join.result");
00213 
00214     wiconnect->enqueueCommand(cmd, Callback(this, &NetworkInterface::joinStatusCheckCallback));
00215 }
00216 
00217 /*************************************************************************************************/
00218 // this is called on the completion of the 'get'wlan.join.result' command above
00219 void NetworkInterface::joinStatusCheckCallback(WiconnectResult result, void *arg1, void *arg2)
00220 {
00221     bool isComplete = false;
00222     NetworkJoinResult joinResult = NETWORK_JOIN_RESULT_NONE;
00223 
00224     QueuedCommand *cmd = (QueuedCommand*)arg1;
00225 
00226     if(result == WICONNECT_SUCCESS)
00227     {
00228         int32_t status;
00229         if(!StringUtil::strToInt32(cmd->responseBuffer, &status))
00230         {
00231             result = WICONNECT_RESPONSE_PARSE_ERROR;
00232         }
00233         else if((NetworkJoinResult)status != NETWORK_JOIN_RESULT_JOINING)
00234         {
00235             isComplete = true;
00236             joinResult = (NetworkJoinResult)status;
00237             result = (joinResult == NETWORK_JOIN_RESULT_SUCCESS) ? WICONNECT_SUCCESS : WICONNECT_NOT_CONNECTED;
00238         }
00239     }
00240 
00241     if(isComplete || result != WICONNECT_SUCCESS)
00242     {
00243         completeHandler.call(result, (void*)joinResult, NULL);
00244     }
00245     else
00246     {
00247         monitorTimer.start(this, &NetworkInterface::joinStatusMonitor, 1000);
00248     }
00249 }
00250 
00251 #endif