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

Committer:
dan_ackme
Date:
Thu Oct 23 15:16:06 2014 -0700
Revision:
26:8067e3d463d3
Parent:
17:7268f365676b
Child:
27:b63f5a9cdefa
Added 'updateFirmware' and 'networkGetJoinResult' api methods
Various bug fixes
Updated documentation

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dan_ackme 26:8067e3d463d3 1 /**
dan_ackme 26:8067e3d463d3 2 * ACKme WiConnect Host Library is licensed under the BSD licence:
dan_ackme 26:8067e3d463d3 3 *
dan_ackme 26:8067e3d463d3 4 * Copyright (c)2014 ACKme Networks.
dan_ackme 26:8067e3d463d3 5 * All rights reserved.
dan_ackme 26:8067e3d463d3 6 *
dan_ackme 26:8067e3d463d3 7 * Redistribution and use in source and binary forms, with or without modification,
dan_ackme 26:8067e3d463d3 8 * are permitted provided that the following conditions are met:
dan_ackme 26:8067e3d463d3 9 *
dan_ackme 26:8067e3d463d3 10 * 1. Redistributions of source code must retain the above copyright notice,
dan_ackme 26:8067e3d463d3 11 * this list of conditions and the following disclaimer.
dan_ackme 26:8067e3d463d3 12 * 2. Redistributions in binary form must reproduce the above copyright notice,
dan_ackme 26:8067e3d463d3 13 * this list of conditions and the following disclaimer in the documentation
dan_ackme 26:8067e3d463d3 14 * and/or other materials provided with the distribution.
dan_ackme 26:8067e3d463d3 15 * 3. The name of the author may not be used to endorse or promote products
dan_ackme 26:8067e3d463d3 16 * derived from this software without specific prior written permission.
dan_ackme 26:8067e3d463d3 17 *
dan_ackme 26:8067e3d463d3 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED
dan_ackme 26:8067e3d463d3 19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
dan_ackme 26:8067e3d463d3 20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
dan_ackme 26:8067e3d463d3 21 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
dan_ackme 26:8067e3d463d3 22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
dan_ackme 26:8067e3d463d3 23 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
dan_ackme 26:8067e3d463d3 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
dan_ackme 26:8067e3d463d3 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
dan_ackme 26:8067e3d463d3 26 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
dan_ackme 26:8067e3d463d3 27 * OF SUCH DAMAGE.
dan_ackme 0:ea85c4bb5e1f 28 */
dan_ackme 0:ea85c4bb5e1f 29 #include "Wiconnect.h"
dan_ackme 0:ea85c4bb5e1f 30 #include "internal/common.h"
dan_ackme 0:ea85c4bb5e1f 31
dan_ackme 0:ea85c4bb5e1f 32 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 33 WiconnectResult NetworkInterface::join(const char* ssid, const char *password, const Callback &completeHandler_)
dan_ackme 0:ea85c4bb5e1f 34 {
dan_ackme 2:05e20e184e7e 35 WiconnectResult result = WICONNECT_ERROR;
dan_ackme 0:ea85c4bb5e1f 36
dan_ackme 0:ea85c4bb5e1f 37 enum
dan_ackme 0:ea85c4bb5e1f 38 {
dan_ackme 0:ea85c4bb5e1f 39 FS_SET_SSID,
dan_ackme 0:ea85c4bb5e1f 40 FS_SET_PASSWORD,
dan_ackme 26:8067e3d463d3 41 FS_NETWORK_UP,
dan_ackme 17:7268f365676b 42 FS_GET_STATUS
dan_ackme 0:ea85c4bb5e1f 43 };
dan_ackme 0:ea85c4bb5e1f 44
dan_ackme 26:8067e3d463d3 45 CHECK_CALLBACK_AVAILABLE(completeHandler_);
dan_ackme 17:7268f365676b 46
dan_ackme 0:ea85c4bb5e1f 47 CHECK_OTHER_COMMAND_EXECUTING();
dan_ackme 0:ea85c4bb5e1f 48
dan_ackme 0:ea85c4bb5e1f 49 if(wiconnect->internalProcessingState == FS_SET_SSID)
dan_ackme 0:ea85c4bb5e1f 50 {
dan_ackme 0:ea85c4bb5e1f 51 if(ssid == NULL ||
dan_ackme 0:ea85c4bb5e1f 52 WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("set wlan.ssid %s", ssid)))
dan_ackme 0:ea85c4bb5e1f 53 {
dan_ackme 0:ea85c4bb5e1f 54 wiconnect->internalProcessingState = FS_SET_PASSWORD;
dan_ackme 0:ea85c4bb5e1f 55 }
dan_ackme 0:ea85c4bb5e1f 56 }
dan_ackme 0:ea85c4bb5e1f 57
dan_ackme 0:ea85c4bb5e1f 58 if(wiconnect->internalProcessingState == FS_SET_PASSWORD)
dan_ackme 0:ea85c4bb5e1f 59 {
dan_ackme 26:8067e3d463d3 60 if(password == NULL || *password == 0 ||
dan_ackme 0:ea85c4bb5e1f 61 WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("set wlan.passkey %s", password)))
dan_ackme 0:ea85c4bb5e1f 62 {
dan_ackme 0:ea85c4bb5e1f 63 wiconnect->internalProcessingState = FS_NETWORK_UP;
dan_ackme 0:ea85c4bb5e1f 64 }
dan_ackme 0:ea85c4bb5e1f 65 }
dan_ackme 0:ea85c4bb5e1f 66
dan_ackme 0:ea85c4bb5e1f 67 if(wiconnect->internalProcessingState == FS_NETWORK_UP)
dan_ackme 0:ea85c4bb5e1f 68 {
dan_ackme 0:ea85c4bb5e1f 69 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("network_up")))
dan_ackme 26:8067e3d463d3 70 {
dan_ackme 26:8067e3d463d3 71 if(!completeHandler_.isValid())
dan_ackme 26:8067e3d463d3 72 {
dan_ackme 26:8067e3d463d3 73 wiconnect->internalProcessingState = FS_GET_STATUS;
dan_ackme 17:7268f365676b 74 }
dan_ackme 26:8067e3d463d3 75 #ifdef WICONNECT_ASYNC_TIMER_ENABLED
dan_ackme 17:7268f365676b 76 else
dan_ackme 0:ea85c4bb5e1f 77 {
dan_ackme 11:ea484e1b7fc4 78 monitorTimer.stop();
dan_ackme 11:ea484e1b7fc4 79 completeHandler = completeHandler_;
dan_ackme 11:ea484e1b7fc4 80 monitorTimer.start(this, &NetworkInterface::joinStatusMonitor, 1000);
dan_ackme 0:ea85c4bb5e1f 81 }
dan_ackme 0:ea85c4bb5e1f 82 #endif
dan_ackme 0:ea85c4bb5e1f 83 }
dan_ackme 26:8067e3d463d3 84 }
dan_ackme 26:8067e3d463d3 85
dan_ackme 26:8067e3d463d3 86 if(wiconnect->internalProcessingState == FS_GET_STATUS)
dan_ackme 26:8067e3d463d3 87 {
dan_ackme 26:8067e3d463d3 88 #define MAX_JOIN_TIME 30000
dan_ackme 26:8067e3d463d3 89 TimeoutTimer timeout;
dan_ackme 26:8067e3d463d3 90
dan_ackme 26:8067e3d463d3 91 status_loop:
dan_ackme 26:8067e3d463d3 92 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get wlan.join.result")))
dan_ackme 26:8067e3d463d3 93 {
dan_ackme 26:8067e3d463d3 94 int32_t status;
dan_ackme 26:8067e3d463d3 95 if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&status)))
dan_ackme 26:8067e3d463d3 96 {
dan_ackme 26:8067e3d463d3 97 if((NetworkJoinResult)status == NETWORK_JOIN_RESULT_JOINING)
dan_ackme 26:8067e3d463d3 98 {
dan_ackme 26:8067e3d463d3 99 if(timeout.timedOut(MAX_JOIN_TIME))
dan_ackme 26:8067e3d463d3 100 {
dan_ackme 26:8067e3d463d3 101 result = WICONNECT_TIMEOUT;
dan_ackme 26:8067e3d463d3 102 }
dan_ackme 26:8067e3d463d3 103 else if(!wiconnect->nonBlocking)
dan_ackme 26:8067e3d463d3 104 {
dan_ackme 26:8067e3d463d3 105 goto status_loop;
dan_ackme 26:8067e3d463d3 106 }
dan_ackme 26:8067e3d463d3 107 else
dan_ackme 26:8067e3d463d3 108 {
dan_ackme 26:8067e3d463d3 109 result = WICONNECT_PROCESSING;
dan_ackme 26:8067e3d463d3 110 }
dan_ackme 26:8067e3d463d3 111 }
dan_ackme 26:8067e3d463d3 112 else
dan_ackme 26:8067e3d463d3 113 {
dan_ackme 26:8067e3d463d3 114 result = ((NetworkJoinResult)status == NETWORK_JOIN_RESULT_SUCCESS) ? WICONNECT_SUCCESS : WICONNECT_NOT_CONNECTED;
dan_ackme 26:8067e3d463d3 115 }
dan_ackme 26:8067e3d463d3 116 }
dan_ackme 26:8067e3d463d3 117 }
dan_ackme 0:ea85c4bb5e1f 118 }
dan_ackme 0:ea85c4bb5e1f 119
dan_ackme 0:ea85c4bb5e1f 120 CHECK_CLEANUP_COMMAND();
dan_ackme 0:ea85c4bb5e1f 121
dan_ackme 0:ea85c4bb5e1f 122 return result;
dan_ackme 0:ea85c4bb5e1f 123 }
dan_ackme 0:ea85c4bb5e1f 124
dan_ackme 0:ea85c4bb5e1f 125
dan_ackme 0:ea85c4bb5e1f 126
dan_ackme 0:ea85c4bb5e1f 127 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 128 WiconnectResult NetworkInterface::leave()
dan_ackme 0:ea85c4bb5e1f 129 {
dan_ackme 0:ea85c4bb5e1f 130 WiconnectResult result;
dan_ackme 0:ea85c4bb5e1f 131
dan_ackme 0:ea85c4bb5e1f 132 CHECK_OTHER_COMMAND_EXECUTING();
dan_ackme 0:ea85c4bb5e1f 133
dan_ackme 0:ea85c4bb5e1f 134 #ifdef WICONNECT_ASYNC_TIMER_ENABLED
dan_ackme 0:ea85c4bb5e1f 135 monitorTimer.stop();
dan_ackme 0:ea85c4bb5e1f 136 #endif
dan_ackme 0:ea85c4bb5e1f 137 result = wiconnect->sendCommand("network_down");
dan_ackme 0:ea85c4bb5e1f 138
dan_ackme 0:ea85c4bb5e1f 139 CHECK_CLEANUP_COMMAND();
dan_ackme 0:ea85c4bb5e1f 140
dan_ackme 0:ea85c4bb5e1f 141 return result;
dan_ackme 0:ea85c4bb5e1f 142 }
dan_ackme 0:ea85c4bb5e1f 143
dan_ackme 0:ea85c4bb5e1f 144
dan_ackme 0:ea85c4bb5e1f 145 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 146 WiconnectResult NetworkInterface::getNetworkStatus(NetworkStatus *statusPtr)
dan_ackme 0:ea85c4bb5e1f 147 {
dan_ackme 0:ea85c4bb5e1f 148 WiconnectResult result;
dan_ackme 0:ea85c4bb5e1f 149
dan_ackme 0:ea85c4bb5e1f 150 CHECK_OTHER_COMMAND_EXECUTING();
dan_ackme 0:ea85c4bb5e1f 151
dan_ackme 0:ea85c4bb5e1f 152 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get network.status")))
dan_ackme 0:ea85c4bb5e1f 153 {
dan_ackme 0:ea85c4bb5e1f 154 int32_t status;
dan_ackme 0:ea85c4bb5e1f 155 if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&status)))
dan_ackme 0:ea85c4bb5e1f 156 {
dan_ackme 13:2b51f5267c92 157 if(status != NETWORK_STATUS_DOWN)
dan_ackme 13:2b51f5267c92 158 {
dan_ackme 13:2b51f5267c92 159 #ifdef WICONNECT_ASYNC_TIMER_ENABLED
dan_ackme 13:2b51f5267c92 160 monitorTimer.stop();
dan_ackme 13:2b51f5267c92 161 #endif
dan_ackme 13:2b51f5267c92 162 }
dan_ackme 0:ea85c4bb5e1f 163 *statusPtr = (NetworkStatus)status;
dan_ackme 0:ea85c4bb5e1f 164 }
dan_ackme 0:ea85c4bb5e1f 165 }
dan_ackme 0:ea85c4bb5e1f 166
dan_ackme 0:ea85c4bb5e1f 167 CHECK_CLEANUP_COMMAND();
dan_ackme 0:ea85c4bb5e1f 168
dan_ackme 0:ea85c4bb5e1f 169 return result;
dan_ackme 0:ea85c4bb5e1f 170 }
dan_ackme 0:ea85c4bb5e1f 171
dan_ackme 26:8067e3d463d3 172 /*************************************************************************************************/
dan_ackme 26:8067e3d463d3 173 WiconnectResult NetworkInterface::getNetworkJoinResult(NetworkJoinResult *joinResultPtr)
dan_ackme 26:8067e3d463d3 174 {
dan_ackme 26:8067e3d463d3 175 WiconnectResult result;
dan_ackme 26:8067e3d463d3 176
dan_ackme 26:8067e3d463d3 177 CHECK_OTHER_COMMAND_EXECUTING();
dan_ackme 26:8067e3d463d3 178
dan_ackme 26:8067e3d463d3 179 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get wlan.join.result")))
dan_ackme 26:8067e3d463d3 180 {
dan_ackme 26:8067e3d463d3 181 int32_t status;
dan_ackme 26:8067e3d463d3 182 if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&status)))
dan_ackme 26:8067e3d463d3 183 {
dan_ackme 26:8067e3d463d3 184 if(status != NETWORK_JOIN_RESULT_JOINING)
dan_ackme 26:8067e3d463d3 185 {
dan_ackme 26:8067e3d463d3 186 #ifdef WICONNECT_ASYNC_TIMER_ENABLED
dan_ackme 26:8067e3d463d3 187 monitorTimer.stop();
dan_ackme 26:8067e3d463d3 188 #endif
dan_ackme 26:8067e3d463d3 189 }
dan_ackme 26:8067e3d463d3 190 *joinResultPtr = (NetworkJoinResult)status;
dan_ackme 26:8067e3d463d3 191 }
dan_ackme 26:8067e3d463d3 192 }
dan_ackme 26:8067e3d463d3 193
dan_ackme 26:8067e3d463d3 194 CHECK_CLEANUP_COMMAND();
dan_ackme 26:8067e3d463d3 195
dan_ackme 26:8067e3d463d3 196 return result;
dan_ackme 26:8067e3d463d3 197 }
dan_ackme 0:ea85c4bb5e1f 198
dan_ackme 0:ea85c4bb5e1f 199 #ifdef WICONNECT_ASYNC_TIMER_ENABLED
dan_ackme 0:ea85c4bb5e1f 200
dan_ackme 7:41d456a65f14 201
dan_ackme 0:ea85c4bb5e1f 202 /*************************************************************************************************/
dan_ackme 0:ea85c4bb5e1f 203 // this is called every 1s by the monitorTimer
dan_ackme 0:ea85c4bb5e1f 204 void NetworkInterface::joinStatusMonitor()
dan_ackme 0:ea85c4bb5e1f 205 {
dan_ackme 8:1fad4ca6c6a4 206 static char responseBuffer[4];
dan_ackme 8:1fad4ca6c6a4 207 static uint8_t cmdBuffer[sizeof(QueuedCommand)];
dan_ackme 8:1fad4ca6c6a4 208 QueuedCommand *cmd = (QueuedCommand*)cmdBuffer;
dan_ackme 6:8a87a59d0d21 209
dan_ackme 0:ea85c4bb5e1f 210 monitorTimer.stop();
dan_ackme 6:8a87a59d0d21 211
dan_ackme 26:8067e3d463d3 212 *cmd = QueuedCommand(sizeof(responseBuffer), responseBuffer, "get wlan.join.result");
dan_ackme 6:8a87a59d0d21 213
dan_ackme 6:8a87a59d0d21 214 wiconnect->enqueueCommand(cmd, Callback(this, &NetworkInterface::joinStatusCheckCallback));
dan_ackme 0:ea85c4bb5e1f 215 }
dan_ackme 0:ea85c4bb5e1f 216
dan_ackme 0:ea85c4bb5e1f 217 /*************************************************************************************************/
dan_ackme 26:8067e3d463d3 218 // this is called on the completion of the 'get'wlan.join.result' command above
dan_ackme 0:ea85c4bb5e1f 219 void NetworkInterface::joinStatusCheckCallback(WiconnectResult result, void *arg1, void *arg2)
dan_ackme 0:ea85c4bb5e1f 220 {
dan_ackme 26:8067e3d463d3 221 bool isComplete = false;
dan_ackme 26:8067e3d463d3 222 NetworkJoinResult joinResult = NETWORK_JOIN_RESULT_NONE;
dan_ackme 0:ea85c4bb5e1f 223
dan_ackme 0:ea85c4bb5e1f 224 QueuedCommand *cmd = (QueuedCommand*)arg1;
dan_ackme 0:ea85c4bb5e1f 225
dan_ackme 0:ea85c4bb5e1f 226 if(result == WICONNECT_SUCCESS)
dan_ackme 0:ea85c4bb5e1f 227 {
dan_ackme 0:ea85c4bb5e1f 228 int32_t status;
dan_ackme 0:ea85c4bb5e1f 229 if(!StringUtil::strToInt32(cmd->responseBuffer, &status))
dan_ackme 0:ea85c4bb5e1f 230 {
dan_ackme 0:ea85c4bb5e1f 231 result = WICONNECT_RESPONSE_PARSE_ERROR;
dan_ackme 0:ea85c4bb5e1f 232 }
dan_ackme 26:8067e3d463d3 233 else if((NetworkJoinResult)status != NETWORK_JOIN_RESULT_JOINING)
dan_ackme 0:ea85c4bb5e1f 234 {
dan_ackme 26:8067e3d463d3 235 isComplete = true;
dan_ackme 26:8067e3d463d3 236 joinResult = (NetworkJoinResult)status;
dan_ackme 26:8067e3d463d3 237 result = (joinResult == NETWORK_JOIN_RESULT_SUCCESS) ? WICONNECT_SUCCESS : WICONNECT_NOT_CONNECTED;
dan_ackme 0:ea85c4bb5e1f 238 }
dan_ackme 0:ea85c4bb5e1f 239 }
dan_ackme 0:ea85c4bb5e1f 240
dan_ackme 26:8067e3d463d3 241 if(isComplete || result != WICONNECT_SUCCESS)
dan_ackme 0:ea85c4bb5e1f 242 {
dan_ackme 26:8067e3d463d3 243 completeHandler.call(result, (void*)joinResult, NULL);
dan_ackme 0:ea85c4bb5e1f 244 }
dan_ackme 0:ea85c4bb5e1f 245 else
dan_ackme 0:ea85c4bb5e1f 246 {
dan_ackme 0:ea85c4bb5e1f 247 monitorTimer.start(this, &NetworkInterface::joinStatusMonitor, 1000);
dan_ackme 0:ea85c4bb5e1f 248 }
dan_ackme 0:ea85c4bb5e1f 249 }
dan_ackme 0:ea85c4bb5e1f 250
dan_ackme 0:ea85c4bb5e1f 251 #endif