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

Revision:
0:ea85c4bb5e1f
Child:
1:6ec9998427ad
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/internal/network/NetworkInterface.cpp	Mon Aug 11 09:58:24 2014 +0000
@@ -0,0 +1,493 @@
+/*
+ * Copyright 2014, ACKme Networks
+ * All Rights Reserved.
+ *
+ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of ACKme Networks;
+ * 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 ACKme Networks.
+ */
+
+
+#include "Wiconnect.h"
+#include "internal/common.h"
+#include "StringUtil.h"
+
+
+#define IPV4_FORMAT "%d.%d.%d.%d"
+#define IPV4_ARGS(ip) \
+    (int)( (ip)        & 0xff), \
+    (int)(((ip) >>  8) & 0xff), \
+    (int)(((ip) >> 16) & 0xff), \
+    (int)(((ip) >> 24) & 0xff)
+
+
+
+/*************************************************************************************************/
+NetworkInterface::NetworkInterface(Wiconnect *wiconnect_)
+{
+    wiconnect = wiconnect_;
+}
+
+/*************************************************************************************************/
+WiconnectResult NetworkInterface::ping(const char *domain, uint32_t *timeMsPtr)
+{
+    WiconnectResult result;
+
+    CHECK_OTHER_COMMAND_EXECUTING();
+
+    if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(completeHandler, "ping %s",  (domain == NULL) ? "-g" : domain)) &&
+            timeMsPtr != NULL)
+    {
+        if(sscanf(wiconnect->internalBuffer, "Ping reply in %ums", timeMsPtr) != 1)
+        {
+            result = WICONNECT_RESPONSE_PARSE_ERROR;
+        }
+    }
+
+    CHECK_CLEANUP_COMMAND();
+
+    return result;
+}
+
+/*************************************************************************************************/
+WiconnectResult NetworkInterface::lookup(const char *domain, uint32_t *ipAddressPtr)
+{
+    WiconnectResult result;
+
+    CHECK_OTHER_COMMAND_EXECUTING();
+
+    if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("nlo %s", domain)))
+    {
+        if(!NetworkInterface::strToIp(wiconnect->internalBuffer, ipAddressPtr))
+        {
+            result = WICONNECT_RESPONSE_PARSE_ERROR;
+        }
+    }
+
+    CHECK_CLEANUP_COMMAND();
+
+    return result;
+}
+
+/*************************************************************************************************/
+WiconnectResult NetworkInterface::setDhcpEnabled(bool enabled)
+{
+    WiconnectResult result;
+
+    CHECK_OTHER_COMMAND_EXECUTING();
+
+    result = wiconnect->sendCommand(CMD_SET_NETWORK_DHCP, enabled);
+
+    CHECK_CLEANUP_COMMAND();
+
+    return result;
+}
+
+/*************************************************************************************************/
+WiconnectResult NetworkInterface::getDhcpEnabled(bool *enabledPtr)
+{
+    WiconnectResult result;
+
+    CHECK_OTHER_COMMAND_EXECUTING();
+
+    if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get network.dhcp")))
+    {
+        int32_t enabled;
+        if(WICONNECT_SUCCEEDED(result, wiconnect->responseToInt32(&enabled)))
+        {
+            *enabledPtr = (bool)enabled;
+        }
+    }
+
+    CHECK_CLEANUP_COMMAND();
+
+    return result;
+}
+
+/*************************************************************************************************/
+WiconnectResult NetworkInterface::setIpSettings(uint32_t ip, uint32_t netmask, uint32_t gateway)
+{
+    WiconnectResult result;
+
+    enum
+    {
+        FS_SET_IP,
+        FS_SET_NETMASK,
+        FS_SET_GATEWAY
+    };
+
+    CHECK_OTHER_COMMAND_EXECUTING();
+
+    if(wiconnect->internalProcessingState == FS_SET_IP)
+    {
+        if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(CMD_SET_STATIC_IP, IPV4_ARGS(ip))))
+        {
+            wiconnect->internalProcessingState = FS_SET_NETMASK;
+        }
+    }
+
+    if(wiconnect->internalProcessingState == FS_SET_NETMASK)
+    {
+        if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(CMD_SET_STATIC_NETMASK, IPV4_ARGS(netmask))))
+        {
+            wiconnect->internalProcessingState = FS_SET_GATEWAY;
+        }
+    }
+
+    if(wiconnect->internalProcessingState == FS_SET_GATEWAY)
+    {
+        if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand(CMD_SET_STATIC_GATEWAY, IPV4_ARGS(gateway))))
+        {
+        }
+    }
+
+    CHECK_CLEANUP_COMMAND();
+
+    return result;
+}
+
+/*************************************************************************************************/
+WiconnectResult NetworkInterface::setIpSettings(const char* ipStr, const char* netmaskStr, const char* gatewayStr)
+{
+    uint32_t ip, nm, gw;
+
+    if( !NetworkInterface::strToIp(ipStr, &ip) ||
+        !NetworkInterface::strToIp(netmaskStr, &nm) ||
+        !NetworkInterface::strToIp(gatewayStr, &gw))
+    {
+        return WICONNECT_ERROR;
+    }
+    return setIpSettings(ip, nm, gw);
+}
+
+/*************************************************************************************************/
+WiconnectResult NetworkInterface::getIpSettings(uint32_t *ip, uint32_t *netmask, uint32_t *gateway)
+{
+    WiconnectResult result;
+
+    enum
+    {
+        FS_GET_IP,
+        FS_GET_NETMASK,
+        FS_GET_GATEWAY
+    };
+
+    CHECK_OTHER_COMMAND_EXECUTING();
+
+    if(wiconnect->internalProcessingState == FS_GET_IP)
+    {
+        if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get network.ip")))
+        {
+            if(!NetworkInterface::strToIp(wiconnect->internalBuffer, ip))
+            {
+                result = WICONNECT_RESPONSE_PARSE_ERROR;
+                wiconnect->internalProcessingState = FS_GET_NETMASK;
+            }
+        }
+    }
+
+    if(wiconnect->internalProcessingState == FS_GET_NETMASK)
+    {
+        if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get network.netmask")))
+        {
+            if(!NetworkInterface::strToIp(wiconnect->internalBuffer, netmask))
+            {
+                result = WICONNECT_RESPONSE_PARSE_ERROR;
+                wiconnect->internalProcessingState = FS_GET_GATEWAY;
+            }
+        }
+    }
+
+    if(wiconnect->internalProcessingState == FS_GET_GATEWAY)
+    {
+        if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("get network.gateway")))
+        {
+            if(!NetworkInterface::strToIp(wiconnect->internalBuffer, gateway))
+            {
+                result = WICONNECT_RESPONSE_PARSE_ERROR;
+            }
+        }
+    }
+
+    CHECK_CLEANUP_COMMAND();
+
+    return result;
+}
+/*************************************************************************************************/
+WiconnectResult NetworkInterface::getSignalStrength(NetworkSignalStrength *signalStrengthPtr)
+{
+    WiconnectResult result;
+    int32_t rssi_dbm;
+
+    CHECK_OTHER_COMMAND_EXECUTING();
+
+    if(WICONNECT_SUCCEEDED(result, wiconnect->sendCommand("rssi")))
+    {
+        if(!WICONNECT_FAILED(result, wiconnect->responseToInt32(&rssi_dbm)))
+        {
+            *signalStrengthPtr = NetworkInterface::rssiToSignalStrength(rssi_dbm);
+        }
+    }
+
+    if(result == WICONNECT_CMD_RESPONSE_ERROR)
+    {
+        *signalStrengthPtr = NETWORK_RSSI_UNKNOWN;
+        result = WICONNECT_SUCCESS;
+    }
+
+    CHECK_CLEANUP_COMMAND();
+
+    return result;
+}
+
+
+//-----------------------------------------------------------------------------------------------
+
+
+/*************************************************************************************************/
+bool NetworkInterface::strToIp(const char *str, uint32_t *intPtr)
+{
+    if (!intPtr)
+    {
+        return false;
+    }
+    int temp[4];
+
+    if(sscanf(str, "%d.%d.%d.%d", &temp[0], &temp[1], &temp[2], &temp[3] ) != 4)
+    {
+        return false;
+    }
+    else if(temp[0] > 255 || temp[1] > 255 || temp[2] > 255 || temp[3] > 255)
+    {
+        return false;
+    }
+    *intPtr = (uint32_t)temp[3] << 24 | temp[2] << 16 | temp[1] << 8 | temp[0];
+
+    return true;
+}
+
+/*************************************************************************************************/
+const char* NetworkInterface::ipToStr(uint32_t ip, char *ipStrBuffer)
+{
+    SET_STR_BUFFER(ipStrBuffer, 16);
+    sprintf(ptr, IPV4_FORMAT, IPV4_ARGS(ip));
+    return ptr;
+}
+
+/*************************************************************************************************/
+const char* NetworkInterface::networkStatusToStr(NetworkStatus status)
+{
+    switch(status)
+    {
+    case NETWORK_STATUS_DOWN:
+        return "Down";
+    case NETWORK_STATUS_WIFI_ONLY:
+        return "WiFi Only";
+    case NETWORK_STATUS_UP:
+        return "Up";
+    default:
+        return "Unknown";
+    }
+}
+
+/*************************************************************************************************/
+const char* NetworkInterface::signalStrengthToStr(NetworkSignalStrength signalStrenth)
+{
+    switch(signalStrenth)
+    {
+    case NETWORK_RSSI_EXCELLENT:
+        return "Excellent";
+    case NETWORK_RSSI_VERY_GOOD:
+        return "Very Good";
+    case NETWORK_RSSI_GOOD:
+        return "Good";
+    case NETWORK_RSSI_POOR:
+        return "Poor";
+    case NETWORK_RSSI_VERY_POOR:
+        return "Very Poor";
+    case NETWORK_RSSI_UNKNOWN:
+    default:
+        return "Unknown";
+    }
+}
+
+/*************************************************************************************************/
+NetworkSignalStrength NetworkInterface::rssiToSignalStrength(int rssi_dbm)
+{
+    if(rssi_dbm > -20)
+    {
+        return NETWORK_RSSI_EXCELLENT;
+    }
+    else if(rssi_dbm > -35)
+    {
+        return NETWORK_RSSI_VERY_GOOD;
+    }
+    else if(rssi_dbm > -50)
+    {
+        return NETWORK_RSSI_GOOD;
+    }
+    else if(rssi_dbm > -70)
+    {
+        return NETWORK_RSSI_POOR;
+    }
+    else
+    {
+        return NETWORK_RSSI_VERY_POOR;
+    }
+}
+
+
+typedef struct
+{
+    const char* key;
+    NetworkSecurity value;
+} NetworkSecurityTableEntry;
+
+static const NetworkSecurityTableEntry networkSecurityTable[] = {
+        {"Auto",       NETWORK_SECURITY_UNKNOWN},
+        {"Open",       NETWORK_SECURITY_OPEN},
+        {"Unknown",    NETWORK_SECURITY_UNKNOWN},
+        {"WEP",        NETWORK_SECURITY_WEP_PSK},
+        {"WPA-AES",    NETWORK_SECURITY_WPA_AES_PSK},
+        {"WPA-TKIP",   NETWORK_SECURITY_WPA_TKIP_PSK},
+        {"WPA2-AES",   NETWORK_SECURITY_WPA2_AES_PSK},
+        {"WPA2-Mixed", NETWORK_SECURITY_WPA2_MIXED_PSK},
+        {"WPA2-TKIP",  NETWORK_SECURITY_WPA2_TKIP_PSK},
+};
+
+
+/*************************************************************************************************/
+NetworkSecurity NetworkInterface::strToNetworkSecurity(const char *str)
+{
+    const NetworkSecurityTableEntry *end = &networkSecurityTable[ARRAY_COUNT(networkSecurityTable)];
+
+    for(const NetworkSecurityTableEntry *e = networkSecurityTable; e < end; ++e)
+    {
+        if(StringUtil::strcasecmp(e->key, str) == 0)
+        {
+            return e->value;
+        }
+    }
+    return NETWORK_SECURITY_UNKNOWN;
+}
+
+/*************************************************************************************************/
+const char* NetworkInterface::networkSecurityToStr(NetworkSecurity security)
+{
+    const NetworkSecurityTableEntry *end = &networkSecurityTable[ARRAY_COUNT(networkSecurityTable)];
+
+    for(const NetworkSecurityTableEntry *e = networkSecurityTable; e < end; ++e)
+    {
+        if(e->value == security)
+        {
+            return e->key;
+        }
+    }
+    return "Unknown";
+}
+
+/*************************************************************************************************/
+bool NetworkInterface::strToSsid(const char *str, Ssid *ssid)
+{
+#define ESCAPE_CHARACTER_DELIMITER '\\'
+#define HEX_ESCAPE_CHARACTER 'x'
+    int c;
+    uint8_t *ssidPtr = ssid->val;
+    int ssidLen = 0;
+
+    while((c = (int)(*str++)) != 0)
+    {
+        if(c == ESCAPE_CHARACTER_DELIMITER)
+        {
+            if(*str == HEX_ESCAPE_CHARACTER)
+            {
+                c = StringUtil::hexToInt(str+1);
+                if(c == -1)
+                    return false;
+                str += 3;
+            }
+            else
+            {
+                return false;
+            }
+        }
+        if(ssidLen >= sizeof(ssid->val))
+            return false;
+        ++ssidLen;
+        *ssidPtr++ = (uint8_t)c;
+    }
+
+    ssid->len = ssidLen;
+
+    return true;
+}
+
+/*************************************************************************************************/
+const char* NetworkInterface::ssidToStr(const Ssid *ssid, char *ssidStrBuffer)
+{
+    SET_STR_BUFFER(ssidStrBuffer, sizeof(SsidStrBuffer));
+    const char *src = (const char*)ssid->val;
+    int len = ssid->len;
+
+    while(len--)
+    {
+        if(*src >= 0x20 && *src <= 0x7E)
+        {
+            *ptr++ = *src;
+        }
+        else
+        {
+            ptr += sprintf(ptr, "\\x%02X", (*src) & 0xff);
+        }
+        ++src;
+    }
+    *ptr = 0;
+    return buf;
+}
+
+/*************************************************************************************************/
+bool NetworkInterface::strToMacAddress(const char *str, MacAddress *macAddress)
+{
+    const char* strPtr = str;
+    uint8_t *macPtr = (uint8_t*)macAddress->octet;
+
+    for(int count = 0; count < 6; ++count)
+    {
+        if(count < 5)
+        {
+            const char *idx = strchr(strPtr, ':');
+            if(idx == NULL)
+            {
+                return false;
+            }
+        }
+        int num = StringUtil::hexToInt(strPtr);
+        if(num == -1)
+        {
+            return false;
+        }
+        *macPtr++ = (uint8_t)num;
+        strPtr += 3;
+    }
+
+    return true;
+}
+
+/*************************************************************************************************/
+const char* NetworkInterface::macAddressToStr(const MacAddress *macAddress, char *macStrBuffer)
+{
+    SET_STR_BUFFER(macStrBuffer, sizeof(MacAddressStrBuffer));
+    const uint8_t *mac = macAddress->octet;
+
+    sprintf(ptr, "%02X:%02X:%02X:%02X:%02X:%02X",
+            (unsigned int)mac[0],
+            (unsigned int)mac[1],
+            (unsigned int)mac[2],
+            (unsigned int)mac[3],
+            (unsigned int)mac[4],
+            (unsigned int)mac[5]);
+
+    return ptr;
+}
+