mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #12522 from artokin/network_interface_property_api
Add property API to InternetSocketpull/12884/head
commit
58c0259dd6
|
@ -185,6 +185,18 @@ TEST_F(TestInternetSocket, modify_multicast_group)
|
||||||
EXPECT_EQ(socket->leave_multicast_group(a), NSAPI_ERROR_UNSUPPORTED);
|
EXPECT_EQ(socket->leave_multicast_group(a), NSAPI_ERROR_UNSUPPORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(TestInternetSocket, network_property)
|
||||||
|
{
|
||||||
|
SocketAddress a("fd00:db8::ff", 1024);
|
||||||
|
uint32_t rtt_estimate;
|
||||||
|
uint16_t stagger_min, stagger_max, stagger_rand;
|
||||||
|
stack.return_value = NSAPI_ERROR_OK;
|
||||||
|
socket->open(&stack);
|
||||||
|
EXPECT_EQ(socket->get_rtt_estimate_to_address(a, &rtt_estimate), NSAPI_ERROR_UNSUPPORTED);
|
||||||
|
EXPECT_EQ(socket->get_rtt_estimate_to_address(a, NULL), NSAPI_ERROR_PARAMETER);
|
||||||
|
EXPECT_EQ(socket->get_stagger_estimate_to_address(a, 1, &stagger_min, &stagger_max, &stagger_rand), NSAPI_ERROR_UNSUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
// set_blocking and set_timeout are tested within TCPSocket.
|
// set_blocking and set_timeout are tested within TCPSocket.
|
||||||
|
|
||||||
TEST_F(TestInternetSocket, bind_no_socket)
|
TEST_F(TestInternetSocket, bind_no_socket)
|
||||||
|
|
|
@ -838,18 +838,58 @@ nsapi_error_t Nanostack::setsockopt(void *handle, int level, int optname, const
|
||||||
nsapi_error_t Nanostack::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen)
|
nsapi_error_t Nanostack::getsockopt(void *handle, int level, int optname, void *optval, unsigned *optlen)
|
||||||
{
|
{
|
||||||
NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
|
NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
|
||||||
|
|
||||||
if (handle == NULL) {
|
if (handle == NULL) {
|
||||||
MBED_ASSERT(false);
|
MBED_ASSERT(false);
|
||||||
return NSAPI_ERROR_NO_SOCKET;
|
return NSAPI_ERROR_NO_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
NanostackLockGuard lock;
|
NanostackLockGuard lock;
|
||||||
|
// pointers to Mbed OS structures
|
||||||
|
nsapi_latency_req_t *ns_latency_r = static_cast<nsapi_latency_req_t *>(optval);
|
||||||
|
nsapi_stagger_req_t *ns_stagger_r = static_cast<nsapi_stagger_req_t *>(optval);
|
||||||
|
// Nanostack internal structures
|
||||||
|
ns_ipv6_latency_t nanostack_latency;
|
||||||
|
ns_ipv6_stagger_t nanostack_stagger;
|
||||||
|
int nanostack_optname = optname;
|
||||||
|
|
||||||
|
void *ns_option_value = optval;
|
||||||
|
|
||||||
|
if (level == NSAPI_SOCKET) {
|
||||||
|
if (optname == NSAPI_LATENCY) {
|
||||||
|
if (*optlen < sizeof(nsapi_latency_req_t)) {
|
||||||
|
return NSAPI_ERROR_PARAMETER;
|
||||||
|
}
|
||||||
|
// Adjust to Nanostack namespace
|
||||||
|
level = SOCKET_IPPROTO_IPV6;
|
||||||
|
nanostack_optname = SOCKET_LATENCY;
|
||||||
|
memcpy(nanostack_latency.dest_addr, ns_latency_r->addr, 16);
|
||||||
|
ns_option_value = &nanostack_latency;
|
||||||
|
} else if (optname == NSAPI_STAGGER) {
|
||||||
|
if (*optlen < sizeof(nsapi_stagger_req_t)) {
|
||||||
|
return NSAPI_ERROR_PARAMETER;
|
||||||
|
}
|
||||||
|
// Adjust to Nanostack namespace
|
||||||
|
level = SOCKET_IPPROTO_IPV6;
|
||||||
|
nanostack_optname = SOCKET_STAGGER;
|
||||||
|
memcpy(nanostack_stagger.dest_addr, ns_stagger_r->addr, 16);
|
||||||
|
nanostack_stagger.data_amount = ns_stagger_r->data_amount;
|
||||||
|
ns_option_value = &nanostack_stagger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t optlen16 = *optlen;
|
uint16_t optlen16 = *optlen;
|
||||||
|
|
||||||
int retcode = ::socket_getsockopt(socket->socket_id, level, optname, optval, &optlen16);
|
int retcode = ::socket_getsockopt(socket->socket_id, level, nanostack_optname, ns_option_value, &optlen16);
|
||||||
if (retcode == 0) {
|
if (retcode == 0) {
|
||||||
*optlen = optlen16;
|
*optlen = optlen16;
|
||||||
|
if (optname == NSAPI_LATENCY) {
|
||||||
|
ns_latency_r->latency = nanostack_latency.latency;
|
||||||
|
} else if (optname == NSAPI_STAGGER) {
|
||||||
|
ns_stagger_r->stagger_min = nanostack_stagger.stagger_min;
|
||||||
|
ns_stagger_r->stagger_max = nanostack_stagger.stagger_max;
|
||||||
|
ns_stagger_r->stagger_rand = nanostack_stagger.stagger_rand;
|
||||||
|
}
|
||||||
return NSAPI_ERROR_OK;
|
return NSAPI_ERROR_OK;
|
||||||
} else if (retcode == -2) {
|
} else if (retcode == -2) {
|
||||||
return NSAPI_ERROR_UNSUPPORTED;
|
return NSAPI_ERROR_UNSUPPORTED;
|
||||||
|
|
|
@ -114,6 +114,54 @@ int InternetSocket::leave_multicast_group(const SocketAddress &address)
|
||||||
return modify_multicast_group(address, NSAPI_DROP_MEMBERSHIP);
|
return modify_multicast_group(address, NSAPI_DROP_MEMBERSHIP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int InternetSocket::get_rtt_estimate_to_address(const SocketAddress &address, uint32_t *rtt_estimate)
|
||||||
|
{
|
||||||
|
nsapi_error_t ret;
|
||||||
|
nsapi_latency_req_t ns_api_latency_req;
|
||||||
|
unsigned opt_len = sizeof(nsapi_latency_req_t);
|
||||||
|
|
||||||
|
if (!rtt_estimate) {
|
||||||
|
return NSAPI_ERROR_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up address
|
||||||
|
memcpy(ns_api_latency_req.addr, address.get_ip_bytes(), 16);
|
||||||
|
|
||||||
|
ret = this->getsockopt(NSAPI_SOCKET, NSAPI_LATENCY, &ns_api_latency_req, &opt_len);
|
||||||
|
if (ret == NSAPI_ERROR_OK) {
|
||||||
|
// success, latency found. Convert to RTT.
|
||||||
|
*rtt_estimate = ns_api_latency_req.latency * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
nsapi_error_t ret;
|
||||||
|
nsapi_stagger_req_t nsapi_stagger;
|
||||||
|
unsigned opt_len = sizeof(nsapi_stagger_req_t);
|
||||||
|
|
||||||
|
// Set up address
|
||||||
|
memcpy(nsapi_stagger.addr, address.get_ip_bytes(), 16);
|
||||||
|
nsapi_stagger.data_amount = data_amount;
|
||||||
|
|
||||||
|
ret = this->getsockopt(NSAPI_SOCKET, NSAPI_STAGGER, &nsapi_stagger, &opt_len);
|
||||||
|
if (ret == NSAPI_ERROR_OK) {
|
||||||
|
// success, stagger found
|
||||||
|
if (stagger_min) {
|
||||||
|
*stagger_min = nsapi_stagger.stagger_min;
|
||||||
|
}
|
||||||
|
if (stagger_max) {
|
||||||
|
*stagger_max = nsapi_stagger.stagger_max;
|
||||||
|
}
|
||||||
|
if (stagger_rand) {
|
||||||
|
*stagger_rand = nsapi_stagger.stagger_rand;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
nsapi_error_t InternetSocket::bind(uint16_t port)
|
nsapi_error_t InternetSocket::bind(uint16_t port)
|
||||||
{
|
{
|
||||||
|
|
|
@ -86,6 +86,35 @@ public:
|
||||||
*/
|
*/
|
||||||
int leave_multicast_group(const SocketAddress &address);
|
int leave_multicast_group(const SocketAddress &address);
|
||||||
|
|
||||||
|
/** Get estimated round trip time to destination address.
|
||||||
|
*
|
||||||
|
* Use estimated round trip time to adjust application retry timers to work in networks
|
||||||
|
* that have low data rate and high latency.
|
||||||
|
*
|
||||||
|
* @param address Destination address to use in rtt estimate.
|
||||||
|
* @param rtt_estimate Returned round trip time value in milliseconds.
|
||||||
|
* @return NSAPI_ERROR_OK on success.
|
||||||
|
* @return NSAPI_ERROR_PARAMETER if the provided pointer is invalid.
|
||||||
|
* @return negative error code on other failures (@see InternetSocket::getsockopt).
|
||||||
|
*/
|
||||||
|
int get_rtt_estimate_to_address(const SocketAddress &address, uint32_t *rtt_estimate);
|
||||||
|
|
||||||
|
/** Get estimated stagger value.
|
||||||
|
*
|
||||||
|
* Stagger value is a time that application should wait before using heavy network operations after connecting to network.
|
||||||
|
* Purpose of staggering is to avoid network congestion that may happen in low bandwith networks if multiple
|
||||||
|
* applications simultaneously start heavy network usage after joining to the network.
|
||||||
|
*
|
||||||
|
* @param address Destination added used to estimate stagger value.
|
||||||
|
* @param data_amount Amount of bytes to transfer in kilobytes.
|
||||||
|
* @param stagger_min Minimum stagger value in seconds.
|
||||||
|
* @param stagger_max Maximum stagger value in seconds.
|
||||||
|
* @param stagger_rand Randomized stagger value between stagger_min and stagger_max in seconds.
|
||||||
|
* @return NSAPI_ERROR_OK on success.
|
||||||
|
* @return negative error code on other failures (@see InternetSocket::getsockopt).
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
/** Bind the socket to a port on which to receive data.
|
/** Bind the socket to a port on which to receive data.
|
||||||
*
|
*
|
||||||
* @param port Local port to bind.
|
* @param port Local port to bind.
|
||||||
|
|
|
@ -270,6 +270,8 @@ typedef enum nsapi_socket_option {
|
||||||
NSAPI_ADD_MEMBERSHIP, /*!< Add membership to multicast address */
|
NSAPI_ADD_MEMBERSHIP, /*!< Add membership to multicast address */
|
||||||
NSAPI_DROP_MEMBERSHIP, /*!< Drop membership to multicast address */
|
NSAPI_DROP_MEMBERSHIP, /*!< Drop membership to multicast address */
|
||||||
NSAPI_BIND_TO_DEVICE, /*!< Bind socket network interface name*/
|
NSAPI_BIND_TO_DEVICE, /*!< Bind socket network interface name*/
|
||||||
|
NSAPI_LATENCY, /*!< Read estimated latency to destination */
|
||||||
|
NSAPI_STAGGER, /*!< Read estimated stagger value to destination */
|
||||||
} nsapi_socket_option_t;
|
} nsapi_socket_option_t;
|
||||||
|
|
||||||
typedef enum nsapi_tlssocket_level {
|
typedef enum nsapi_tlssocket_level {
|
||||||
|
@ -340,6 +342,23 @@ typedef struct nsapi_ip_mreq {
|
||||||
nsapi_addr_t imr_interface; /* local IP address of interface */
|
nsapi_addr_t imr_interface; /* local IP address of interface */
|
||||||
} nsapi_ip_mreq_t;
|
} nsapi_ip_mreq_t;
|
||||||
|
|
||||||
|
/** nsapi_latency_req structure
|
||||||
|
*/
|
||||||
|
typedef struct nsapi_latency_req {
|
||||||
|
uint8_t addr[16]; /* [IN] Destination address to estimate latency */
|
||||||
|
uint32_t latency; /* [OUT] Latency value */
|
||||||
|
} nsapi_latency_req_t;
|
||||||
|
|
||||||
|
/** nsapi_stagger_req structure
|
||||||
|
*/
|
||||||
|
typedef struct nsapi_stagger_req {
|
||||||
|
uint8_t addr[16]; /* [IN] Destination address to estimate stagger */
|
||||||
|
uint16_t data_amount; /* [IN] Amount of data to be sent in kilobytes */
|
||||||
|
uint16_t stagger_min; /* [OUT] Minimum stagger value in seconds */
|
||||||
|
uint16_t stagger_max; /* [OUT] Maximum stagger value in seconds */
|
||||||
|
uint16_t stagger_rand; /* [OUT] Randomized stagger value in seconds */
|
||||||
|
} nsapi_stagger_req_t;
|
||||||
|
|
||||||
/** nsapi_stack_api structure
|
/** nsapi_stack_api structure
|
||||||
*
|
*
|
||||||
* Common api structure for network stack operations. A network stack
|
* Common api structure for network stack operations. A network stack
|
||||||
|
|
Loading…
Reference in New Issue