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
NetworkInterface.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 00030 #include "Wiconnect.h" 00031 #include "internal/common.h" 00032 #include "api/StringUtil.h" 00033 00034 00035 #define IPV4_FORMAT "%u.%u.%u.%u" 00036 #define IPV4_ARGS(ip) \ 00037 (int)(((ip) >> 0) & 0xff), \ 00038 (int)(((ip) >> 8) & 0xff), \ 00039 (int)(((ip) >> 16) & 0xff), \ 00040 (int)(((ip) >> 24) & 0xff) 00041 00042 00043 00044 /*************************************************************************************************/ 00045 NetworkInterface::NetworkInterface(Wiconnect *wiconnect_) 00046 { 00047 wiconnect = wiconnect_; 00048 } 00049 00050 /*************************************************************************************************/ 00051 WiconnectResult NetworkInterface::ping(const char *domain, uint32_t *timeMsPtr) 00052 { 00053 WiconnectResult result; 00054 00055 CHECK_OTHER_COMMAND_EXECUTING(); 00056 00057 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("ping %s", (domain == NULL) ? "-g" : domain)) && 00058 timeMsPtr != NULL) 00059 { 00060 if(sscanf(wiconnect->internalBuffer, "Ping reply in %ums", (unsigned int*)timeMsPtr) != 1) 00061 { 00062 result = WICONNECT_RESPONSE_PARSE_ERROR; 00063 } 00064 } 00065 00066 CHECK_CLEANUP_COMMAND(); 00067 00068 return result; 00069 } 00070 00071 /*************************************************************************************************/ 00072 WiconnectResult NetworkInterface::lookup(const char *domain, uint32_t *ipAddressPtr) 00073 { 00074 WiconnectResult result; 00075 00076 CHECK_OTHER_COMMAND_EXECUTING(); 00077 00078 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("nlo %s", domain))) 00079 { 00080 if(!NetworkInterface::strToIp(wiconnect->internalBuffer, ipAddressPtr)) 00081 { 00082 result = WICONNECT_RESPONSE_PARSE_ERROR; 00083 } 00084 } 00085 00086 CHECK_CLEANUP_COMMAND(); 00087 00088 return result; 00089 } 00090 00091 /*************************************************************************************************/ 00092 WiconnectResult NetworkInterface::setDhcpEnabled(bool enabled) 00093 { 00094 WiconnectResult result; 00095 00096 CHECK_OTHER_COMMAND_EXECUTING(); 00097 00098 result = wiconnect->sendCommand(CMD_SET_NETWORK_DHCP, enabled); 00099 00100 CHECK_CLEANUP_COMMAND(); 00101 00102 return result; 00103 } 00104 00105 /*************************************************************************************************/ 00106 WiconnectResult NetworkInterface::getDhcpEnabled(bool *enabledPtr) 00107 { 00108 WiconnectResult result; 00109 00110 CHECK_OTHER_COMMAND_EXECUTING(); 00111 00112 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get network.dhcp.enabled"))) 00113 { 00114 int32_t enabled; 00115 if(WICONNECT_SUCCEEDED(result, wiconnect->responseToInt32(&enabled))) 00116 { 00117 *enabledPtr = (bool)enabled; 00118 } 00119 } 00120 00121 CHECK_CLEANUP_COMMAND(); 00122 00123 return result; 00124 } 00125 00126 /*************************************************************************************************/ 00127 WiconnectResult NetworkInterface::setIpSettings(uint32_t ip, uint32_t netmask, uint32_t gateway) 00128 { 00129 WiconnectResult result = WICONNECT_ERROR; 00130 00131 enum 00132 { 00133 FS_SET_IP, 00134 FS_SET_NETMASK, 00135 FS_SET_GATEWAY 00136 }; 00137 00138 CHECK_OTHER_COMMAND_EXECUTING(); 00139 00140 if(wiconnect->internalProcessingState == FS_SET_IP) 00141 { 00142 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(CMD_SET_STATIC_IP, IPV4_ARGS(ip)))) 00143 { 00144 wiconnect->internalProcessingState = FS_SET_NETMASK; 00145 } 00146 } 00147 00148 if(wiconnect->internalProcessingState == FS_SET_NETMASK) 00149 { 00150 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(CMD_SET_STATIC_NETMASK, IPV4_ARGS(netmask)))) 00151 { 00152 wiconnect->internalProcessingState = FS_SET_GATEWAY; 00153 } 00154 } 00155 00156 if(wiconnect->internalProcessingState == FS_SET_GATEWAY) 00157 { 00158 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(CMD_SET_STATIC_GATEWAY, IPV4_ARGS(gateway)))) 00159 { 00160 } 00161 } 00162 00163 CHECK_CLEANUP_COMMAND(); 00164 00165 return result; 00166 } 00167 00168 /*************************************************************************************************/ 00169 WiconnectResult NetworkInterface::setIpSettings(const char* ipStr, const char* netmaskStr, const char* gatewayStr) 00170 { 00171 uint32_t ip, nm, gw; 00172 00173 if( !NetworkInterface::strToIp(ipStr, &ip) || 00174 !NetworkInterface::strToIp(netmaskStr, &nm) || 00175 !NetworkInterface::strToIp(gatewayStr, &gw)) 00176 { 00177 return WICONNECT_ERROR; 00178 } 00179 return setIpSettings(ip, nm, gw); 00180 } 00181 00182 /*************************************************************************************************/ 00183 WiconnectResult NetworkInterface::getIpSettings(uint32_t *ip, uint32_t *netmask, uint32_t *gateway) 00184 { 00185 WiconnectResult result = WICONNECT_ERROR; 00186 00187 enum 00188 { 00189 FS_GET_IP, 00190 FS_GET_NETMASK, 00191 FS_GET_GATEWAY 00192 }; 00193 00194 CHECK_OTHER_COMMAND_EXECUTING(); 00195 00196 if(wiconnect->internalProcessingState == FS_GET_IP) 00197 { 00198 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get network.ip"))) 00199 { 00200 if(!NetworkInterface::strToIp(wiconnect->internalBuffer, ip)) 00201 { 00202 result = WICONNECT_RESPONSE_PARSE_ERROR; 00203 } 00204 else 00205 { 00206 wiconnect->internalProcessingState = FS_GET_NETMASK; 00207 } 00208 } 00209 } 00210 00211 if(wiconnect->internalProcessingState == FS_GET_NETMASK) 00212 { 00213 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get network.netmask"))) 00214 { 00215 if(!NetworkInterface::strToIp(wiconnect->internalBuffer, netmask)) 00216 { 00217 result = WICONNECT_RESPONSE_PARSE_ERROR; 00218 } 00219 else 00220 { 00221 wiconnect->internalProcessingState = FS_GET_GATEWAY; 00222 } 00223 } 00224 } 00225 00226 if(wiconnect->internalProcessingState == FS_GET_GATEWAY) 00227 { 00228 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get network.gateway"))) 00229 { 00230 if(!NetworkInterface::strToIp(wiconnect->internalBuffer, gateway)) 00231 { 00232 result = WICONNECT_RESPONSE_PARSE_ERROR; 00233 } 00234 } 00235 } 00236 00237 CHECK_CLEANUP_COMMAND(); 00238 00239 return result; 00240 } 00241 00242 /*************************************************************************************************/ 00243 WiconnectResult NetworkInterface::setDnsAddress(uint32_t dnsAddress) 00244 { 00245 WiconnectResult result; 00246 00247 CHECK_OTHER_COMMAND_EXECUTING(); 00248 00249 result = wiconnect->sendCommand("set static.dns %d.%d.%d.%d", IPV4_ARGS(dnsAddress)); 00250 00251 CHECK_CLEANUP_COMMAND(); 00252 00253 return result; 00254 } 00255 00256 /*************************************************************************************************/ 00257 WiconnectResult NetworkInterface::getDnsAddress(uint32_t *dnsAddress) 00258 { 00259 WiconnectResult result; 00260 00261 CHECK_OTHER_COMMAND_EXECUTING(); 00262 00263 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get static.dns"))) 00264 { 00265 if(!NetworkInterface::strToIp(wiconnect->internalBuffer, dnsAddress)) 00266 { 00267 result = WICONNECT_RESPONSE_PARSE_ERROR; 00268 } 00269 } 00270 00271 CHECK_CLEANUP_COMMAND(); 00272 00273 return result; 00274 } 00275 00276 /*************************************************************************************************/ 00277 WiconnectResult NetworkInterface::getRssi(int32_t *rssiPtr) 00278 { 00279 WiconnectResult result; 00280 00281 CHECK_OTHER_COMMAND_EXECUTING(); 00282 00283 *rssiPtr = -999; 00284 00285 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("rssi"))) 00286 { 00287 result = wiconnect->responseToInt32(rssiPtr); 00288 } 00289 00290 CHECK_CLEANUP_COMMAND(); 00291 00292 return result; 00293 } 00294 00295 /*************************************************************************************************/ 00296 WiconnectResult NetworkInterface::getSignalStrength(NetworkSignalStrength *signalStrengthPtr) 00297 { 00298 WiconnectResult result; 00299 int32_t rssiDbm; 00300 00301 if(WICONNECT_SUCCEEDED(result, getRssi(&rssiDbm))) 00302 { 00303 *signalStrengthPtr = NetworkInterface::rssiToSignalStrength(rssiDbm); 00304 } 00305 else if(result == WICONNECT_CMD_RESPONSE_ERROR) 00306 { 00307 *signalStrengthPtr = NETWORK_RSSI_UNKNOWN; 00308 result = WICONNECT_SUCCESS; 00309 } 00310 00311 return result; 00312 } 00313 00314 /*************************************************************************************************/ 00315 WiconnectResult NetworkInterface::getMacAddress(MacAddress *macAddress) 00316 { 00317 WiconnectResult result; 00318 00319 CHECK_OTHER_COMMAND_EXECUTING(); 00320 00321 if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get wlan.mac"))) 00322 { 00323 if(!Wiconnect::strToMacAddress(wiconnect->internalBuffer, macAddress)) 00324 { 00325 result = WICONNECT_RESPONSE_PARSE_ERROR; 00326 } 00327 } 00328 00329 CHECK_CLEANUP_COMMAND(); 00330 00331 return result; 00332 } 00333 00334 00335 /*************************************************************************************************/ 00336 const char* NetworkInterface::getIpAddress(char *ipStrBuffer) 00337 { 00338 SET_STR_BUFFER(ipStrBuffer, 17); 00339 00340 if(wiconnect->nonBlocking) 00341 { 00342 return "Err"; 00343 } 00344 00345 if(wiconnect->sendCommand(ptr, 17, "get network.ip") != WICONNECT_SUCCESS) 00346 { 00347 strcpy(ptr, "0.0.0.0"); 00348 } 00349 00350 return ptr; 00351 } 00352 00353 00354 //----------------------------------------------------------------------------------------------- 00355 00356 00357 /*************************************************************************************************/ 00358 bool NetworkInterface::strToIp(const char *str, uint32_t *intPtr) 00359 { 00360 if (!intPtr) 00361 { 00362 return false; 00363 } 00364 uint32_t ip = 0; 00365 int i; 00366 const char *tok; 00367 00368 for(i = 0; i < 4; ++i, str = tok) 00369 { 00370 uint8_t nibble; 00371 char buf[4]; 00372 00373 tok = strchr(str, '.'); 00374 if(tok == NULL) 00375 { 00376 if(i < 3) 00377 { 00378 return false; 00379 } 00380 strcpy(buf, str); 00381 } 00382 else 00383 { 00384 strncpy(buf, str, tok - str); 00385 ++tok; 00386 } 00387 00388 if(!StringUtil::strToUint8(buf, &nibble)) 00389 { 00390 return false; 00391 } 00392 ip |= (((uint32_t)nibble) << 24); 00393 if(i < 3) 00394 { 00395 ip = (ip >> 8UL); 00396 } 00397 } 00398 00399 if(i != 4) 00400 { 00401 return false; 00402 } 00403 00404 *intPtr = ip; 00405 00406 return true; 00407 } 00408 00409 /*************************************************************************************************/ 00410 const char* NetworkInterface::ipToStr(uint32_t ip, char *ipStrBuffer) 00411 { 00412 SET_STR_BUFFER(ipStrBuffer, 17); 00413 00414 sprintf(ptr, IPV4_FORMAT, IPV4_ARGS(ip)); 00415 return ptr; 00416 } 00417 00418 /*************************************************************************************************/ 00419 const char* NetworkInterface::networkStatusToStr(NetworkStatus status) 00420 { 00421 switch(status) 00422 { 00423 case NETWORK_STATUS_DOWN: 00424 return "Down"; 00425 case NETWORK_STATUS_WIFI_ONLY: 00426 return "WiFi Only"; 00427 case NETWORK_STATUS_UP: 00428 return "Up"; 00429 default: 00430 return "Unknown"; 00431 } 00432 } 00433 00434 /*************************************************************************************************/ 00435 const char* NetworkInterface::networkJoinResultToStr(NetworkJoinResult joinResult) 00436 { 00437 switch(joinResult) 00438 { 00439 case NETWORK_JOIN_RESULT_NONE: 00440 return "None"; 00441 case NETWORK_JOIN_RESULT_SUCCESS: 00442 return "Success"; 00443 case NETWORK_JOIN_RESULT_JOINING: 00444 return "Joining"; 00445 case NETWORK_JOIN_RESULT_NO_SSID: 00446 return "No SSID"; 00447 case NETWORK_JOIN_RESULT_NO_PASSWORD: 00448 return "No Password"; 00449 case NETWORK_JOIN_RESULT_BAD_SECURITY: 00450 return "Bad Security Setting"; 00451 case NETWORK_JOIN_RESULT_NOT_FOUND: 00452 return "Network Not Found"; 00453 case NETWORK_JOIN_RESULT_FAILED: 00454 return "Failed"; 00455 case NETWORK_JOIN_RESULT_ABORTED: 00456 return "Aborted"; 00457 default: 00458 return "Unknown"; 00459 } 00460 } 00461 00462 00463 /*************************************************************************************************/ 00464 const char* NetworkInterface::signalStrengthToStr(NetworkSignalStrength signalStrenth) 00465 { 00466 switch(signalStrenth) 00467 { 00468 case NETWORK_RSSI_EXCELLENT: 00469 return "Excellent"; 00470 case NETWORK_RSSI_VERY_GOOD: 00471 return "Very Good"; 00472 case NETWORK_RSSI_GOOD: 00473 return "Good"; 00474 case NETWORK_RSSI_POOR: 00475 return "Poor"; 00476 case NETWORK_RSSI_VERY_POOR: 00477 return "Very Poor"; 00478 case NETWORK_RSSI_UNKNOWN: 00479 default: 00480 return "Unknown"; 00481 } 00482 } 00483 00484 /*************************************************************************************************/ 00485 NetworkSignalStrength NetworkInterface::rssiToSignalStrength(int rssi_dbm) 00486 { 00487 if(rssi_dbm > -20) 00488 { 00489 return NETWORK_RSSI_EXCELLENT; 00490 } 00491 else if(rssi_dbm > -35) 00492 { 00493 return NETWORK_RSSI_VERY_GOOD; 00494 } 00495 else if(rssi_dbm > -50) 00496 { 00497 return NETWORK_RSSI_GOOD; 00498 } 00499 else if(rssi_dbm > -70) 00500 { 00501 return NETWORK_RSSI_POOR; 00502 } 00503 else 00504 { 00505 return NETWORK_RSSI_VERY_POOR; 00506 } 00507 } 00508 00509 00510 typedef struct 00511 { 00512 const char* key; 00513 NetworkSecurity value; 00514 } NetworkSecurityTableEntry; 00515 00516 static const NetworkSecurityTableEntry networkSecurityTable[] = { 00517 {"Auto", NETWORK_SECURITY_UNKNOWN}, 00518 {"Open", NETWORK_SECURITY_OPEN}, 00519 {"Unknown", NETWORK_SECURITY_UNKNOWN}, 00520 {"WEP", NETWORK_SECURITY_WEP_PSK}, 00521 {"WPA-AES", NETWORK_SECURITY_WPA_AES_PSK}, 00522 {"WPA-TKIP", NETWORK_SECURITY_WPA_TKIP_PSK}, 00523 {"WPA2-AES", NETWORK_SECURITY_WPA2_AES_PSK}, 00524 {"WPA2-Mixed", NETWORK_SECURITY_WPA2_MIXED_PSK}, 00525 {"WPA2-TKIP", NETWORK_SECURITY_WPA2_TKIP_PSK}, 00526 }; 00527 00528 00529 /*************************************************************************************************/ 00530 NetworkSecurity NetworkInterface::strToNetworkSecurity(const char *str) 00531 { 00532 const NetworkSecurityTableEntry *end = &networkSecurityTable[ARRAY_COUNT(networkSecurityTable)]; 00533 00534 for(const NetworkSecurityTableEntry *e = networkSecurityTable; e < end; ++e) 00535 { 00536 if(StringUtil::strcasecmp(e->key, str) == 0) 00537 { 00538 return e->value; 00539 } 00540 } 00541 return NETWORK_SECURITY_UNKNOWN; 00542 } 00543 00544 /*************************************************************************************************/ 00545 const char* NetworkInterface::networkSecurityToStr(NetworkSecurity security) 00546 { 00547 const NetworkSecurityTableEntry *end = &networkSecurityTable[ARRAY_COUNT(networkSecurityTable)]; 00548 00549 for(const NetworkSecurityTableEntry *e = networkSecurityTable; e < end; ++e) 00550 { 00551 if(e->value == security) 00552 { 00553 return e->key; 00554 } 00555 } 00556 return "Unknown"; 00557 } 00558 00559 /*************************************************************************************************/ 00560 bool NetworkInterface::strToSsid(const char *str, Ssid *ssid) 00561 { 00562 #define ESCAPE_CHARACTER_DELIMITER '\\' 00563 #define HEX_ESCAPE_CHARACTER 'x' 00564 int c; 00565 uint8_t *ssidPtr = ssid->val; 00566 uint32_t ssidLen = 0; 00567 00568 while((c = (int)(*str++)) != 0) 00569 { 00570 if(c == ESCAPE_CHARACTER_DELIMITER) 00571 { 00572 if(*str == HEX_ESCAPE_CHARACTER) 00573 { 00574 c = StringUtil::hexToInt(str+1); 00575 if(c == -1) 00576 return false; 00577 str += 3; 00578 } 00579 else 00580 { 00581 return false; 00582 } 00583 } 00584 if(ssidLen >= sizeof(ssid->val)) 00585 return false; 00586 ++ssidLen; 00587 *ssidPtr++ = (uint8_t)c; 00588 } 00589 00590 ssid->len = ssidLen; 00591 00592 return true; 00593 } 00594 00595 /*************************************************************************************************/ 00596 const char* NetworkInterface::ssidToStr(const Ssid *ssid, char *ssidStrBuffer) 00597 { 00598 SET_STR_BUFFER(ssidStrBuffer, sizeof(SsidStrBuffer)); 00599 const char *src = (const char*)ssid->val; 00600 int len = ssid->len; 00601 char *buf = ptr; 00602 00603 while(len--) 00604 { 00605 if(*src >= 0x20 && *src <= 0x7E) 00606 { 00607 *ptr++ = *src; 00608 } 00609 else 00610 { 00611 ptr += sprintf(ptr, "\\x%02X", (*src) & 0xff); 00612 } 00613 ++src; 00614 } 00615 *ptr = 0; 00616 return buf; 00617 } 00618 00619 /*************************************************************************************************/ 00620 bool NetworkInterface::strToMacAddress(const char *str, MacAddress *macAddress) 00621 { 00622 const char* strPtr = str; 00623 uint8_t *macPtr = (uint8_t*)macAddress->octet; 00624 00625 for(int count = 0; count < 6; ++count) 00626 { 00627 if(count < 5) 00628 { 00629 const char *idx = strchr(strPtr, ':'); 00630 if(idx == NULL) 00631 { 00632 return false; 00633 } 00634 } 00635 int num = StringUtil::hexToInt(strPtr); 00636 if(num == -1) 00637 { 00638 return false; 00639 } 00640 *macPtr++ = (uint8_t)num; 00641 strPtr += 3; 00642 } 00643 00644 return true; 00645 } 00646 00647 /*************************************************************************************************/ 00648 const char* NetworkInterface::macAddressToStr(const MacAddress *macAddress, char *macStrBuffer) 00649 { 00650 SET_STR_BUFFER(macStrBuffer, sizeof(MacAddressStrBuffer)); 00651 const uint8_t *mac = macAddress->octet; 00652 00653 sprintf(ptr, "%02X:%02X:%02X:%02X:%02X:%02X", 00654 (unsigned int)mac[0], 00655 (unsigned int)mac[1], 00656 (unsigned int)mac[2], 00657 (unsigned int)mac[3], 00658 (unsigned int)mac[4], 00659 (unsigned int)mac[5]); 00660 00661 return ptr; 00662 }
Generated on Tue Jul 12 2022 17:35:58 by 1.7.2