Skip to content

Commit e5e315e

Browse files
authored
Merge pull request #13936 from artokin/mac_address_set_get_mbed_os_master
Network interface MAC address set/get
2 parents e2777c2 + 671dec5 commit e5e315e

File tree

17 files changed

+180
-16
lines changed

17 files changed

+180
-16
lines changed

UNITTESTS/stubs/NetworkInterface_stub.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ const char *NetworkInterface::get_mac_address()
2626
return 0;
2727
}
2828

29+
nsapi_error_t NetworkInterface::set_mac_address(uint8_t *mac_addr, nsapi_size_t addr_len)
30+
{
31+
return NSAPI_ERROR_UNSUPPORTED;
32+
}
33+
2934
nsapi_error_t NetworkInterface::get_ip_address(SocketAddress *)
3035
{
3136
return NSAPI_ERROR_UNSUPPORTED;

connectivity/nanostack/include/nanostack-interface/Nanostack.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class Nanostack : public OnboardNetworkStack, private mbed::NonCopyable<Nanostac
4141

4242
/* Implement OnboardNetworkStack method */
4343
nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out) override;
44+
nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, const uint8_t *mac_addr) override;
4445

4546
/* Local variant with stronger typing and manual address specification */
4647
nsapi_error_t add_ethernet_interface(EMAC &emac, bool default_if, Nanostack::EthernetInterface **interface_out, const uint8_t *mac_addr = NULL);
@@ -74,7 +75,7 @@ class Nanostack : public OnboardNetworkStack, private mbed::NonCopyable<Nanostac
7475
* @param interface_name Network interface name
7576
* @return NSAPI_ERROR_OK on success, negative error code on failure.
7677
*/
77-
virtual nsapi_error_t gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version, const char *interface_name);
78+
virtual nsapi_error_t gethostbyname(const char *name, SocketAddress *address, nsapi_version_t version, const char *interface_name) override;
7879

7980
/** Translate a hostname to an IP address (asynchronous) using network interface name.
8081
*
@@ -98,7 +99,7 @@ class Nanostack : public OnboardNetworkStack, private mbed::NonCopyable<Nanostac
9899
* a positive unique id that represents the hostname translation operation
99100
* and can be passed to cancel.
100101
*/
101-
virtual nsapi_value_or_error_t gethostbyname_async(const char *name, hostbyname_cb_t callback, nsapi_version_t version, const char *interface_name);
102+
virtual nsapi_value_or_error_t gethostbyname_async(const char *name, hostbyname_cb_t callback, nsapi_version_t version, const char *interface_name) override;
102103

103104
/** Get a domain name server from a list of servers to query
104105
*
@@ -107,9 +108,10 @@ class Nanostack : public OnboardNetworkStack, private mbed::NonCopyable<Nanostac
107108
*
108109
* @param index Index of the DNS server, starts from zero
109110
* @param address Destination for the host address
111+
* @param interface_name Network interface name
110112
* @return 0 on success, negative error code on failure
111113
*/
112-
virtual nsapi_error_t get_dns_server(int index, SocketAddress *address, const char *interface_name);
114+
virtual nsapi_error_t get_dns_server(int index, SocketAddress *address, const char *interface_name) override;
113115

114116
/** Opens a socket
115117
*

connectivity/nanostack/mbed-mesh-api/mbed-mesh-api/MeshInterfaceNanostack.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,13 @@
2626
class Nanostack::Interface : public OnboardNetworkStack::Interface, private mbed::NonCopyable<Nanostack::Interface> {
2727
public:
2828
nsapi_error_t get_ip_address(SocketAddress *address) final;
29-
char *get_mac_address(char *buf, nsapi_size_t buflen) final;
29+
char *get_mac_address(char *buf, nsapi_size_t buflen) override;
30+
nsapi_error_t set_mac_address(uint8_t *buf, nsapi_size_t buflen);
3031
nsapi_error_t get_netmask(SocketAddress *address) final;
3132
nsapi_error_t get_gateway(SocketAddress *address) override;
3233
void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb) final;
3334
nsapi_connection_status_t get_connection_status() const final;
34-
35-
void get_mac_address(uint8_t *buf) const
36-
{
37-
NanostackMACPhy *phy = interface_phy.nanostack_mac_phy();
38-
if (phy) {
39-
phy->get_mac_address(buf);
40-
}
41-
}
35+
virtual void get_mac_address(uint8_t *buf) const;
4236

4337
/**
4438
* \brief Callback from C-layer
@@ -109,6 +103,9 @@ class InterfaceNanostack : public virtual NetworkInterface {
109103
*/
110104
const char *get_mac_address() override;
111105

106+
/** @copydoc NetworkInterface::set_mac_address */
107+
nsapi_error_t set_mac_address(uint8_t *mac_addr, nsapi_size_t addr_len) override;
108+
112109
/** Register callback for status reporting
113110
*
114111
* The specified status callback function will be called on status changes

connectivity/nanostack/mbed-mesh-api/mbed-mesh-api/NanostackEthernetInterface.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,10 @@ class Nanostack::EthernetInterface final : public Nanostack::Interface {
2828
nsapi_ip_stack_t stack = DEFAULT_STACK,
2929
bool blocking = true) override;
3030
nsapi_error_t bringdown() override;
31+
void get_mac_address(uint8_t *buf);
32+
char *get_mac_address(char *buf, nsapi_size_t buflen) override;
3133

32-
char *get_interface_name(char *buf);
34+
char *get_interface_name(char *buf) override;
3335
private:
3436
friend class Nanostack;
3537
friend class NanostackEthernetInterface;

connectivity/nanostack/mbed-mesh-api/mbed-mesh-api/NanostackPPPInterface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class Nanostack::PPPInterface final : public Nanostack::Interface {
3232
typedef mbed::Callback<void (uint8_t up, int8_t device_id)> link_state_cb_t;
3333
void set_link_state_changed_callback(link_state_cb_t link_state_cb);
3434

35-
char *get_interface_name(char *buf);
35+
char *get_interface_name(char *buf) override;
3636
private:
3737
friend class Nanostack;
3838
PPPInterface(NanostackPPPPhy &phy) : Interface(phy) {}

connectivity/nanostack/mbed-mesh-api/source/MeshInterfaceNanostack.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,27 @@ char *Nanostack::Interface::get_mac_address(char *buf, nsapi_size_t buflen)
4848
}
4949
}
5050

51+
nsapi_error_t Nanostack::Interface::set_mac_address(uint8_t *buf, nsapi_size_t buflen)
52+
{
53+
if (buflen != 8) {
54+
/* Provided MAC is too short */
55+
return NSAPI_ERROR_PARAMETER;
56+
}
57+
58+
if (_device_id >= 0) {
59+
/* device is already registered, can't set MAC address anymore */
60+
return NSAPI_ERROR_BUSY;
61+
}
62+
63+
NanostackMACPhy *phy = interface_phy.nanostack_mac_phy();
64+
if (phy) {
65+
phy->set_mac_address(buf);
66+
return NSAPI_ERROR_OK;
67+
}
68+
69+
return NSAPI_ERROR_UNSUPPORTED;
70+
}
71+
5172
nsapi_error_t Nanostack::Interface::get_netmask(SocketAddress *address)
5273
{
5374
return NSAPI_ERROR_UNSUPPORTED;
@@ -63,6 +84,14 @@ nsapi_connection_status_t Nanostack::Interface::get_connection_status() const
6384
return _connect_status;
6485
}
6586

87+
void Nanostack::Interface::get_mac_address(uint8_t *buf) const
88+
{
89+
NanostackMACPhy *phy = interface_phy.nanostack_mac_phy();
90+
if (phy) {
91+
phy->get_mac_address(buf);
92+
}
93+
}
94+
6695
void Nanostack::Interface::attach(
6796
mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
6897
{
@@ -197,6 +226,11 @@ const char *InterfaceNanostack::get_mac_address()
197226
return NULL;
198227
}
199228

229+
nsapi_error_t InterfaceNanostack::set_mac_address(uint8_t *mac_addr, nsapi_size_t addr_len)
230+
{
231+
return _interface->set_mac_address(mac_addr, addr_len);
232+
}
233+
200234
nsapi_connection_status_t InterfaceNanostack::get_connection_status() const
201235
{
202236
if (_interface) {

connectivity/nanostack/mbed-mesh-api/source/NanostackEMACInterface.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,14 @@ nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, Nan
222222
*interface_out = interface;
223223

224224
return NSAPI_ERROR_OK;
225+
}
225226

227+
nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out, const uint8_t *mac_addr)
228+
{
229+
Nanostack::EthernetInterface *interface;
230+
nsapi_error_t err = add_ethernet_interface(emac, default_if, &interface, mac_addr);
231+
*interface_out = interface;
232+
return err;
226233
}
227234

228235
nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out)
@@ -231,4 +238,4 @@ nsapi_error_t Nanostack::add_ethernet_interface(EMAC &emac, bool default_if, Onb
231238
nsapi_error_t err = add_ethernet_interface(emac, default_if, &interface);
232239
*interface_out = interface;
233240
return err;
234-
}
241+
}

connectivity/nanostack/mbed-mesh-api/source/NanostackEthernetInterface.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,26 @@ char *Nanostack::EthernetInterface::get_interface_name(char *buf)
132132
sprintf(buf, "ETH%d", interface_id);
133133
return buf;
134134
};
135+
136+
void Nanostack::EthernetInterface::get_mac_address(uint8_t *buf)
137+
{
138+
if (!buf) {
139+
return;
140+
}
141+
142+
get_phy().get_mac_address(buf);
143+
}
144+
145+
char *Nanostack::EthernetInterface::get_mac_address(char *buf, nsapi_size_t buflen)
146+
{
147+
uint8_t mac_buf[NSAPI_MAC_BYTES] = {0};
148+
149+
if (!buf || buflen < NSAPI_MAC_SIZE) {
150+
return NULL;
151+
}
152+
153+
get_phy().get_mac_address(mac_buf);
154+
155+
snprintf(buf, buflen, "%02x:%02x:%02x:%02x:%02x:%02x", mac_buf[0], mac_buf[1], mac_buf[2], mac_buf[3], mac_buf[4], mac_buf[5]);
156+
return buf;
157+
}

connectivity/netsocket/include/netsocket/EMACInterface.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ class EMACInterface : public virtual NetworkInterface {
8686
/** @copydoc NetworkInterface::get_mac_address */
8787
const char *get_mac_address() override;
8888

89+
/** @copydoc NetworkInterface::set_mac_address */
90+
nsapi_error_t set_mac_address(uint8_t *mac_addr, nsapi_size_t addr_len) override;
91+
8992
/** @copydoc NetworkInterface::get_ip_address */
9093
nsapi_error_t get_ip_address(SocketAddress *address) override;
9194

@@ -143,10 +146,12 @@ class EMACInterface : public virtual NetworkInterface {
143146
OnboardNetworkStack::Interface *_interface = nullptr;
144147
bool _dhcp = true;
145148
bool _blocking = true;
149+
bool _hw_mac_addr_set = false;
146150
char _mac_address[NSAPI_MAC_SIZE];
147151
char _ip_address[NSAPI_IPv6_SIZE] {};
148152
char _netmask[NSAPI_IPv4_SIZE] {};
149153
char _gateway[NSAPI_IPv4_SIZE] {};
154+
uint8_t _hw_mac_addr[NSAPI_MAC_BYTES] {};
150155
mbed::Callback<void(nsapi_event_t, intptr_t)> _connection_status_cb;
151156
};
152157

connectivity/netsocket/include/netsocket/NetworkInterface.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,31 @@ class NetworkInterface: public DNS {
101101
*/
102102
virtual const char *get_mac_address();
103103

104+
/** Set the MAC address to the interface.
105+
*
106+
* Set the provided MAC address on the network interface. The address must
107+
* be unique globally. The address must be set before calling the interface
108+
* connect() method.
109+
*
110+
* Not all interfaces are supporting MAC address set and an error is not returned
111+
* for this method call. Verify the changed MAC address by checking packet
112+
* captures from the used network interface.
113+
*
114+
* 6-byte EUI-48 MAC addresses are used for Ethernet while Mesh interface is
115+
* using 8-byte EUI-64 address.
116+
*
117+
* More information about obtaining MAC address can be found from:
118+
* https://standards.ieee.org/products-services/regauth/index.html
119+
*
120+
* @param mac_addr Buffer containing the MAC address in hexadecimal format.
121+
* @param addr_len Length of provided buffer in bytes (6 or 8)
122+
* @retval NSAPI_ERROR_OK on success
123+
* @retval NSAPI_ERROR_UNSUPPORTED if this feature is not supported
124+
* @retval NSAPI_ERROR_PARAMETER if address is not valid
125+
* @retval NSAPI_ERROR_BUSY if address can't be set.
126+
*/
127+
virtual nsapi_error_t set_mac_address(uint8_t *mac_addr, nsapi_size_t addr_len);
128+
104129
/** Get the local IP address
105130
*
106131
* @param address SocketAddress representation of the local IP address

0 commit comments

Comments
 (0)