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);
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
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)
|
||||
{
|
||||
NanostackSocket *socket = static_cast<NanostackSocket *>(handle);
|
||||
|
||||
if (handle == NULL) {
|
||||
MBED_ASSERT(false);
|
||||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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) {
|
||||
*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;
|
||||
} else if (retcode == -2) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
|
|
|
@ -114,6 +114,54 @@ int InternetSocket::leave_multicast_group(const SocketAddress &address)
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -86,6 +86,35 @@ public:
|
|||
*/
|
||||
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.
|
||||
*
|
||||
* @param port Local port to bind.
|
||||
|
|
|
@ -269,7 +269,9 @@ typedef enum nsapi_socket_option {
|
|||
NSAPI_RCVBUF, /*!< Sets recv buffer size */
|
||||
NSAPI_ADD_MEMBERSHIP, /*!< Add 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;
|
||||
|
||||
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_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
|
||||
*
|
||||
* Common api structure for network stack operations. A network stack
|
||||
|
|
Loading…
Reference in New Issue