I have a given IP address as an array like uint8_t ip[4] = {10, 101, 1, 1};
How to use in SocketAddress?
Is there a way to convert to a string ?
Hello Stefan,
I’m afraid there in such Mbed function but you can try this:
char str[4 * 3 + 3 + 1]; // 4 * 3 digits + 3 dots + 1 terminating NULL char
const char* ipToString(char* str, uint8_t ip[4])
{
uint8_t i = 0;
uint8_t j = 0;
for (i = 0; i < 3; i++) {
j += sprintf(&str[j], "%d", ip[i]);
str[j++] = '.';
}
j += sprintf(&str[j], "%d", ip[i]);
str[j] = '\0';
return str;
}
If you’re using sprintf, why not just write:
char str[16];
sprintf(&str, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
SocketAddress ip_addr(str);
SocketAddress has a constructor that takes the address bytes and address type:
https://os.mbed.com/docs/mbed-os/v5.15/mbed-os-api-doxy/class_socket_address.html#a799e9df7fd000b33efebad45a9cb513f
So, what does it actually mean: “Raw IP address in big-endian order”
There are several variations, of which the binary types seem to be: nsapi_addr_t and const void *
The nsapi_addr_t contains an array of 16 bytes (I guess to cater for IPv6?), so are the octets just represented in binary fashion eg: 0xFF, 0xFF, 0xFF, 0xFF => 255 255 255 255? (dots are assumed?).
Can the const void * version be declared simply as: 0xFFFFFFFF for the above example?
Of course Chris, your sprintf
is much simpler Thank you for that! And I was wrong also about the missing Mbed built-in function. Thank you Johannes for the info! So it seems that Stefan can create a SocketAddress
by passing his IP address to the constructor:
uint8_t ip[4] = {10, 101, 1, 1};
SocketAddress sockAddr(ip, NSAPI_IPv4); // optional third parameter 'port' defaults to 0
This does not work when using set_network(). I get an error message
no suitable conversion function from “SocketAddress” to “const char *” exists
#include <mbed.h>
#include "EthernetInterface.h"
EthernetInterface eth;
uint8_t ip[4] = {10, 101, 1, 201};
uint8_t subnet[4] = {255, 255, 0, 0};
uint8_t gateway[4] = {0, 0, 0, 0};
SocketAddress IP(ip, NSAPI_IPv4);
SocketAddress SUBNET(subnet, NSAPI_IPv4);
SocketAddress GATEWAY(gateway, NSAPI_IPv4);
int main() {
eth.set_network(IP, SUBNET, GATEWAY);
eth.connect();
while(1) {
}
}
with mbed-os 5.15 it works. There is a constructor that takes ‘const &SocketAddress’ as arguments.
And a
printf("IP: %s\nsubnet: %s\ngateway: %s\n", IP.get_ip_address(), SUBNET.get_ip_address(), GATEWAY.get_ip_address());
is also printing the correct addresses.
And using get_default_instance() is more versatile for different network interfaces:
(using DHCP, but can be set also to fixed IP):
// Connect to the network with the default networking interface
// if you use WiFi: see mbed_app.json for the credentials
NetworkInterface* network = NetworkInterface::get_default_instance();
if (!network) {
printf("Cannot connect to the network, see serial output\n");
return 1;
}
nsapi_error_t connect_status = network->connect();
if (connect_status != NSAPI_ERROR_OK) {
printf("Failed to connect to network (%d)\n", connect_status);
return 2;
} else {
SocketAddress socketAddress;
network->get_ip_address(&socketAddress);
printf("my IP is: %s\n", socketAddress.get_ip_address());
}
tried with sprintf, also an error message:
no suitable conversion function from “SocketAddress” to “const char *” exists
#include <mbed.h>
#include "EthernetInterface.h"
EthernetInterface eth;
const uint8_t ip[4] = {10, 101, 1, 201};
const uint8_t subnet[4] = {255, 255, 0, 0};
const uint8_t gateway[4] = {0, 0, 0, 0};
//SocketAddress IP(ip, NSAPI_IPv4);
//SocketAddress SUBNET(subnet, NSAPI_IPv4);
//SocketAddress GATEWAY(gateway, NSAPI_IPv4);
int main() {
char ipAddress[16];
sprintf(ipAddress, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
SocketAddress IP(ipAddress);
char subnetMask[16];
sprintf(subnetMask, "%d.%d.%d.%d", subnet[0], subnet[1], subnet[2], subnet[3]);
SocketAddress SUBNET(subnetMask);
char gatewayAddress[16];
sprintf(gatewayAddress, "%d.%d.%d.%d", gateway[0], gateway[1], gateway[2], gateway[3]);
SocketAddress GATEWAY(gatewayAddress);
eth.set_network(IP, SUBNET, GATEWAY);
eth.connect();
while(1) {
}
}
set_network
takes const SocketAddress&
arguments.
Try either this :
#include <mbed.h>
#include "EthernetInterface.h"
EthernetInterface eth;
uint8_t ip[4] = {10, 101, 1, 201};
uint8_t subnet[4] = {255, 255, 0, 0};
uint8_t gateway[4] = {0, 0, 0, 0};
const SocketAddress IP(ip, NSAPI_IPv4);
const SocketAddress SUBNET(subnet, NSAPI_IPv4);
const SocketAddress GATEWAY(gateway, NSAPI_IPv4);
int main() {
eth.set_network(IP, SUBNET, GATEWAY);
eth.connect();
while(1) {
}
}
or this:
#include <mbed.h>
#include "EthernetInterface.h"
EthernetInterface eth;
uint8_t ip[4] = {10, 101, 1, 201};
uint8_t subnet[4] = {255, 255, 0, 0};
uint8_t gateway[4] = {0, 0, 0, 0};
SocketAddress IP(ip, NSAPI_IPv4);
SocketAddress SUBNET(subnet, NSAPI_IPv4);
SocketAddress GATEWAY(gateway, NSAPI_IPv4);
int main() {
eth.set_network((const SocketAddress&)IP, (const SocketAddress&)SUBNET, (const SocketAddress&)GATEWAY);
eth.connect();
while(1) {
}
}
yes, it looks like the SocketAddress arguments are introduced with mbed-os 5.15. The string based functions are deprecated, so I would upgrade the mbed-os.
The typecast is not necessary.
that was the same, only a different way to construct the SocketAddress.
eth.set_network("10.101.1.201", "255.255.0.0", "0.0.0.0");
should work also, but again, this is depracted and not recommended with newer mbed-os versions. The SocketAddress is a better abstraction for handling IPv4/IPv6.
In the moment I work with platformIO and they use the mbed version 5.14, so I have to wait because online compiler doesn’t work in the moment (macOS Catalina with Safari).
ok, so half-way to the future is still to use SocketAddress with the string based ip address, then it can be changed later by simply removing the ‘.get_ip_address()’:
eth.set_network(IP.get_ip_address(), SUBNET.get_ip_address(), GATEWAY.get_ip_address())
or maybe try using Mbed-studio, should run also on a MacOS.