Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: wiconnect-ota_example wiconnect-web_setup_example wiconnect-test-console wiconnect-tcp_server_example ... more
internal/network/NetworkInterface.cpp
- Committer:
- dan_ackme
- Date:
- 2014-10-23
- Revision:
- 26:8067e3d463d3
- Parent:
- 17:7268f365676b
- Child:
- 27:b63f5a9cdefa
File content as of revision 26:8067e3d463d3:
/**
* ACKme WiConnect Host Library is licensed under the BSD licence:
*
* Copyright (c)2014 ACKme Networks.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#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.enabled")))
{
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 = WICONNECT_ERROR;
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 = WICONNECT_ERROR;
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;
}
else
{
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;
}
else
{
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;
}
/*************************************************************************************************/
const char* NetworkInterface::getIpAddress(char *ipStrBuffer)
{
SET_STR_BUFFER(ipStrBuffer, 17);
if(wiconnect->nonBlocking)
{
return "Err";
}
if(wiconnect->sendCommand(ptr, 17, "get network.ip") != WICONNECT_SUCCESS)
{
strcpy(ptr, "0.0.0.0");
}
return ptr;
}
//-----------------------------------------------------------------------------------------------
/*************************************************************************************************/
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, 17);
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::networkJoinResultToStr(NetworkJoinResult joinResult)
{
switch(joinResult)
{
case NETWORK_JOIN_RESULT_NONE:
return "None";
case NETWORK_JOIN_RESULT_SUCCESS:
return "Success";
case NETWORK_JOIN_RESULT_JOINING:
return "Joining";
case NETWORK_JOIN_RESULT_NO_SSID:
return "No SSID";
case NETWORK_JOIN_RESULT_NO_PASSWORD:
return "No Password";
case NETWORK_JOIN_RESULT_BAD_SECURITY:
return "Bad Security Setting";
case NETWORK_JOIN_RESULT_NOT_FOUND:
return "Network Not Found";
case NETWORK_JOIN_RESULT_FAILED:
return "Failed";
case NETWORK_JOIN_RESULT_ABORTED:
return "Aborted";
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;
char *buf = ptr;
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;
}
AMW006-A02