Skip to content

Commit 58c0259

Browse files
authored
Merge pull request #12522 from artokin/network_interface_property_api
Add property API to InternetSocket
2 parents c904e22 + f39da5e commit 58c0259

File tree

5 files changed

+150
-2
lines changed

5 files changed

+150
-2
lines changed

UNITTESTS/features/netsocket/InternetSocket/test_InternetSocket.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,18 @@ TEST_F(TestInternetSocket, modify_multicast_group)
185185
EXPECT_EQ(socket->leave_multicast_group(a), NSAPI_ERROR_UNSUPPORTED);
186186
}
187187

188+
TEST_F(TestInternetSocket, network_property)
189+
{
190+
SocketAddress a("fd00:db8::ff", 1024);
191+
uint32_t rtt_estimate;
192+
uint16_t stagger_min, stagger_max, stagger_rand;
193+
stack.return_value = NSAPI_ERROR_OK;
194+
socket->open(&stack);
195+
EXPECT_EQ(socket->get_rtt_estimate_to_address(a, &rtt_estimate), NSAPI_ERROR_UNSUPPORTED);
196+
EXPECT_EQ(socket->get_rtt_estimate_to_address(a, NULL), NSAPI_ERROR_PARAMETER);
197+
EXPECT_EQ(socket->get_stagger_estimate_to_address(a, 1, &stagger_min, &stagger_max, &stagger_rand), NSAPI_ERROR_UNSUPPORTED);
198+
}
199+
188200
// set_blocking and set_timeout are tested within TCPSocket.
189201

190202
TEST_F(TestInternetSocket, bind_no_socket)

features/nanostack/nanostack-interface/Nanostack.cpp

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,18 +838,58 @@ nsapi_error_t Nanostack::setsockopt(void *handle, int level, int optname, const
838838
nsapi_error_t Nanostack::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen)
839839
{
840840
NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
841+
841842
if (handle == NULL) {
842843
MBED_ASSERT(false);
843844
return NSAPI_ERROR_NO_SOCKET;
844845
}
845846

846847
NanostackLockGuard lock;
848+
// pointers to Mbed OS structures
849+
nsapi_latency_req_t *ns_latency_r = static_cast<nsapi_latency_req_t *>(optval);
850+
nsapi_stagger_req_t *ns_stagger_r = static_cast<nsapi_stagger_req_t *>(optval);
851+
// Nanostack internal structures
852+
ns_ipv6_latency_t nanostack_latency;
853+
ns_ipv6_stagger_t nanostack_stagger;
854+
int nanostack_optname = optname;
855+
856+
void *ns_option_value = optval;
857+
858+
if (level == NSAPI_SOCKET) {
859+
if (optname == NSAPI_LATENCY) {
860+
if (*optlen < sizeof(nsapi_latency_req_t)) {
861+
return NSAPI_ERROR_PARAMETER;
862+
}
863+
// Adjust to Nanostack namespace
864+
level = SOCKET_IPPROTO_IPV6;
865+
nanostack_optname = SOCKET_LATENCY;
866+
memcpy(nanostack_latency.dest_addr, ns_latency_r->addr, 16);
867+
ns_option_value = &nanostack_latency;
868+
} else if (optname == NSAPI_STAGGER) {
869+
if (*optlen < sizeof(nsapi_stagger_req_t)) {
870+
return NSAPI_ERROR_PARAMETER;
871+
}
872+
// Adjust to Nanostack namespace
873+
level = SOCKET_IPPROTO_IPV6;
874+
nanostack_optname = SOCKET_STAGGER;
875+
memcpy(nanostack_stagger.dest_addr, ns_stagger_r->addr, 16);
876+
nanostack_stagger.data_amount = ns_stagger_r->data_amount;
877+
ns_option_value = &nanostack_stagger;
878+
}
879+
}
847880

848881
uint16_t optlen16 = *optlen;
849882

850-
int retcode = ::socket_getsockopt(socket->socket_id, level, optname, optval, &optlen16);
883+
int retcode = ::socket_getsockopt(socket->socket_id, level, nanostack_optname, ns_option_value, &optlen16);
851884
if (retcode == 0) {
852885
*optlen = optlen16;
886+
if (optname == NSAPI_LATENCY) {
887+
ns_latency_r->latency = nanostack_latency.latency;
888+
} else if (optname == NSAPI_STAGGER) {
889+
ns_stagger_r->stagger_min = nanostack_stagger.stagger_min;
890+
ns_stagger_r->stagger_max = nanostack_stagger.stagger_max;
891+
ns_stagger_r->stagger_rand = nanostack_stagger.stagger_rand;
892+
}
853893
return NSAPI_ERROR_OK;
854894
} else if (retcode == -2) {
855895
return NSAPI_ERROR_UNSUPPORTED;

features/netsocket/InternetSocket.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,54 @@ int InternetSocket::leave_multicast_group(const SocketAddress &address)
114114
return modify_multicast_group(address, NSAPI_DROP_MEMBERSHIP);
115115
}
116116

117+
int InternetSocket::get_rtt_estimate_to_address(const SocketAddress &address, uint32_t *rtt_estimate)
118+
{
119+
nsapi_error_t ret;
120+
nsapi_latency_req_t ns_api_latency_req;
121+
unsigned opt_len = sizeof(nsapi_latency_req_t);
122+
123+
if (!rtt_estimate) {
124+
return NSAPI_ERROR_PARAMETER;
125+
}
126+
127+
// Set up address
128+
memcpy(ns_api_latency_req.addr, address.get_ip_bytes(), 16);
129+
130+
ret = this->getsockopt(NSAPI_SOCKET, NSAPI_LATENCY, &ns_api_latency_req, &opt_len);
131+
if (ret == NSAPI_ERROR_OK) {
132+
// success, latency found. Convert to RTT.
133+
*rtt_estimate = ns_api_latency_req.latency * 2;
134+
}
135+
136+
return ret;
137+
}
138+
139+
int InternetSocket::get_stagger_estimate_to_address(const SocketAddress &address, uint16_t data_amount, uint16_t *stagger_min, uint16_t *stagger_max, uint16_t *stagger_rand)
140+
{
141+
nsapi_error_t ret;
142+
nsapi_stagger_req_t nsapi_stagger;
143+
unsigned opt_len = sizeof(nsapi_stagger_req_t);
144+
145+
// Set up address
146+
memcpy(nsapi_stagger.addr, address.get_ip_bytes(), 16);
147+
nsapi_stagger.data_amount = data_amount;
148+
149+
ret = this->getsockopt(NSAPI_SOCKET, NSAPI_STAGGER, &nsapi_stagger, &opt_len);
150+
if (ret == NSAPI_ERROR_OK) {
151+
// success, stagger found
152+
if (stagger_min) {
153+
*stagger_min = nsapi_stagger.stagger_min;
154+
}
155+
if (stagger_max) {
156+
*stagger_max = nsapi_stagger.stagger_max;
157+
}
158+
if (stagger_rand) {
159+
*stagger_rand = nsapi_stagger.stagger_rand;
160+
}
161+
}
162+
163+
return ret;
164+
}
117165

118166
nsapi_error_t InternetSocket::bind(uint16_t port)
119167
{

features/netsocket/InternetSocket.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,35 @@ class InternetSocket : public Socket {
8686
*/
8787
int leave_multicast_group(const SocketAddress &address);
8888

89+
/** Get estimated round trip time to destination address.
90+
*
91+
* Use estimated round trip time to adjust application retry timers to work in networks
92+
* that have low data rate and high latency.
93+
*
94+
* @param address Destination address to use in rtt estimate.
95+
* @param rtt_estimate Returned round trip time value in milliseconds.
96+
* @return NSAPI_ERROR_OK on success.
97+
* @return NSAPI_ERROR_PARAMETER if the provided pointer is invalid.
98+
* @return negative error code on other failures (@see InternetSocket::getsockopt).
99+
*/
100+
int get_rtt_estimate_to_address(const SocketAddress &address, uint32_t *rtt_estimate);
101+
102+
/** Get estimated stagger value.
103+
*
104+
* Stagger value is a time that application should wait before using heavy network operations after connecting to network.
105+
* Purpose of staggering is to avoid network congestion that may happen in low bandwith networks if multiple
106+
* applications simultaneously start heavy network usage after joining to the network.
107+
*
108+
* @param address Destination added used to estimate stagger value.
109+
* @param data_amount Amount of bytes to transfer in kilobytes.
110+
* @param stagger_min Minimum stagger value in seconds.
111+
* @param stagger_max Maximum stagger value in seconds.
112+
* @param stagger_rand Randomized stagger value between stagger_min and stagger_max in seconds.
113+
* @return NSAPI_ERROR_OK on success.
114+
* @return negative error code on other failures (@see InternetSocket::getsockopt).
115+
*/
116+
int get_stagger_estimate_to_address(const SocketAddress &address, uint16_t data_amount, uint16_t *stagger_min, uint16_t *stagger_max, uint16_t *stagger_rand);
117+
89118
/** Bind the socket to a port on which to receive data.
90119
*
91120
* @param port Local port to bind.

features/netsocket/nsapi_types.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,9 @@ typedef enum nsapi_socket_option {
269269
NSAPI_RCVBUF, /*!< Sets recv buffer size */
270270
NSAPI_ADD_MEMBERSHIP, /*!< Add membership to multicast address */
271271
NSAPI_DROP_MEMBERSHIP, /*!< Drop membership to multicast address */
272-
NSAPI_BIND_TO_DEVICE, /*!< Bind socket network interface name*/
272+
NSAPI_BIND_TO_DEVICE, /*!< Bind socket network interface name*/
273+
NSAPI_LATENCY, /*!< Read estimated latency to destination */
274+
NSAPI_STAGGER, /*!< Read estimated stagger value to destination */
273275
} nsapi_socket_option_t;
274276

275277
typedef enum nsapi_tlssocket_level {
@@ -340,6 +342,23 @@ typedef struct nsapi_ip_mreq {
340342
nsapi_addr_t imr_interface; /* local IP address of interface */
341343
} nsapi_ip_mreq_t;
342344

345+
/** nsapi_latency_req structure
346+
*/
347+
typedef struct nsapi_latency_req {
348+
uint8_t addr[16]; /* [IN] Destination address to estimate latency */
349+
uint32_t latency; /* [OUT] Latency value */
350+
} nsapi_latency_req_t;
351+
352+
/** nsapi_stagger_req structure
353+
*/
354+
typedef struct nsapi_stagger_req {
355+
uint8_t addr[16]; /* [IN] Destination address to estimate stagger */
356+
uint16_t data_amount; /* [IN] Amount of data to be sent in kilobytes */
357+
uint16_t stagger_min; /* [OUT] Minimum stagger value in seconds */
358+
uint16_t stagger_max; /* [OUT] Maximum stagger value in seconds */
359+
uint16_t stagger_rand; /* [OUT] Randomized stagger value in seconds */
360+
} nsapi_stagger_req_t;
361+
343362
/** nsapi_stack_api structure
344363
*
345364
* Common api structure for network stack operations. A network stack

0 commit comments

Comments
 (0)