[cli] allow binding CLI udp socket to unspecified interface (#6761)

This commit is contained in:
Simon Lin
2021-08-09 19:49:18 -07:00
committed by GitHub
parent d559147595
commit 15584dcda3
10 changed files with 69 additions and 32 deletions
+1 -1
View File
@@ -53,7 +53,7 @@ extern "C" {
* @note This number versions both OpenThread platform and user APIs.
*
*/
#define OPENTHREAD_API_VERSION (143)
#define OPENTHREAD_API_VERSION (144)
/**
* @addtogroup api-instance
-11
View File
@@ -41,17 +41,6 @@
extern "C" {
#endif
/**
* This enumeration defines the OpenThread network interface identifiers.
*
*/
typedef enum otNetifIdentifier
{
OT_NETIF_UNSPECIFIED = 0, ///< Unspecified network interface.
OT_NETIF_THREAD, ///< The Thread interface.
OT_NETIF_BACKBONE, ///< The Backbone interface.
} otNetifIdentifier;
/**
* This function initializes the UDP socket by platform.
*
+13 -1
View File
@@ -130,6 +130,17 @@ typedef struct otUdpSocket
struct otUdpSocket *mNext; ///< A pointer to the next UDP socket (internal use only).
} otUdpSocket;
/**
* This enumeration defines the OpenThread network interface identifiers.
*
*/
typedef enum otNetifIdentifier
{
OT_NETIF_UNSPECIFIED = 0, ///< Unspecified network interface.
OT_NETIF_THREAD, ///< The Thread interface.
OT_NETIF_BACKBONE, ///< The Backbone interface.
} otNetifIdentifier;
/**
* Allocate a new message buffer for sending a UDP message.
*
@@ -189,12 +200,13 @@ otError otUdpClose(otInstance *aInstance, otUdpSocket *aSocket);
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aSocket A pointer to a UDP socket structure.
* @param[in] aSockName A pointer to an IPv6 socket address structure.
* @param[in] aNetif The network interface to bind.
*
* @retval OT_ERROR_NONE Bind operation was successful.
* @retval OT_ERROR_FAILED Failed to bind UDP socket.
*
*/
otError otUdpBind(otInstance *aInstance, otUdpSocket *aSocket, const otSockAddr *aSockName);
otError otUdpBind(otInstance *aInstance, otUdpSocket *aSocket, const otSockAddr *aSockName, otNetifIdentifier aNetif);
/**
* Connect a UDP/IPv6 socket.
+10 -2
View File
@@ -39,7 +39,7 @@ On node 1, you should see a print out similar to below:
## Command List
- [help](#help)
- [bind](#bind-ip-port)
- [bind](#bind-netif-ip-port)
- [close](#close)
- [connect](#connect-ip-port)
- [linksecurity](#linksecurity)
@@ -63,16 +63,24 @@ send
Done
```
### bind \<ip\> \<port\>
### bind [netif] \<ip\> \<port\>
Assigns a name (i.e. IPv6 address and port) to the example socket.
- netif: the network interface to bind to.
- not specified: Thread network interface.
- `-u`: unspecified network interface.
- `-b`: Backbone network interface.
- ip: the IPv6 address or the unspecified IPv6 address (`::`).
- port: the UDP port
```bash
> udp bind :: 1234
Done
> udp bind -u :: 1234
Done
> udp bind -b :: 1234
Done
```
### close
+15 -3
View File
@@ -65,14 +65,26 @@ otError UdpExample::ProcessHelp(Arg aArgs[])
otError UdpExample::ProcessBind(Arg aArgs[])
{
otError error;
otSockAddr sockaddr;
otError error;
otSockAddr sockaddr;
otNetifIdentifier netif = OT_NETIF_THREAD;
if (aArgs[0] == "-u")
{
netif = OT_NETIF_UNSPECIFIED;
aArgs++;
}
else if (aArgs[0] == "-b")
{
netif = OT_NETIF_BACKBONE;
aArgs++;
}
SuccessOrExit(error = aArgs[0].ParseAsIp6Address(sockaddr.mAddress));
SuccessOrExit(error = aArgs[1].ParseAsUint16(sockaddr.mPort));
VerifyOrExit(aArgs[2].IsEmpty(), error = OT_ERROR_INVALID_ARGS);
error = otUdpBind(mInterpreter.mInstance, &mSocket, &sockaddr);
error = otUdpBind(mInterpreter.mInstance, &mSocket, &sockaddr, netif);
exit:
return error;
+2 -2
View File
@@ -70,12 +70,12 @@ otError otUdpClose(otInstance *aInstance, otUdpSocket *aSocket)
return instance.Get<Ip6::Udp>().Close(*static_cast<Ip6::Udp::SocketHandle *>(aSocket));
}
otError otUdpBind(otInstance *aInstance, otUdpSocket *aSocket, const otSockAddr *aSockName)
otError otUdpBind(otInstance *aInstance, otUdpSocket *aSocket, const otSockAddr *aSockName, otNetifIdentifier aNetif)
{
Instance &instance = *static_cast<Instance *>(aInstance);
return instance.Get<Ip6::Udp>().Bind(*static_cast<Ip6::Udp::SocketHandle *>(aSocket),
*static_cast<const Ip6::SockAddr *>(aSockName), OT_NETIF_THREAD);
*static_cast<const Ip6::SockAddr *>(aSockName), aNetif);
}
otError otUdpConnect(otInstance *aInstance, otUdpSocket *aSocket, const otSockAddr *aSockName)
+3 -2
View File
@@ -36,7 +36,7 @@ from .otci import \
connect_ncp_sim, \
connect_cmd_handler, \
connect_otbr_ssh
from .types import Rloc16, ChildId
from .types import Rloc16, ChildId, NetifIdentifier
_connectors = [
'connect_cli_sim',
@@ -46,4 +46,5 @@ _connectors = [
'connect_cmd_handler',
]
__all__ = ['OTCI', 'errors', 'Rloc16', 'ChildId', 'THREAD_VERSION_1_1', 'THREAD_VERSION_1_2'] + _connectors
__all__ = ['OTCI', 'errors', 'Rloc16', 'ChildId', 'NetifIdentifer', 'THREAD_VERSION_1_1', 'THREAD_VERSION_1_2'
] + _connectors
+9 -3
View File
@@ -37,7 +37,7 @@ from .command_handlers import OTCommandHandler, OtCliCommandRunner, OtbrSshComma
from .connectors import Simulator
from .errors import UnexpectedCommandOutput, ExpectLineTimeoutError, CommandError, InvalidArgumentsError
from .types import ChildId, Rloc16, Ip6Addr, ThreadState, PartitionId, DeviceMode, RouterId, SecurityPolicy, Ip6Prefix, \
RouterTableEntry
RouterTableEntry, NetifIdentifier
from .utils import match_line, constant_property
@@ -2121,13 +2121,19 @@ class OTCI(object):
"""Opens the example socket."""
self.execute_command('udp close')
def udp_bind(self, ip: str, port: int):
def udp_bind(self, ip: str, port: int, netif: NetifIdentifier = NetifIdentifier.THERAD):
"""Assigns a name (i.e. IPv6 address and port) to the example socket.
:param ip: the IPv6 address or the unspecified IPv6 address (::).
:param port: the UDP port
"""
self.execute_command(f'udp bind {ip} {port}')
bindarg = ''
if netif == NetifIdentifier.UNSPECIFIED:
bindarg += ' -u'
elif netif == NetifIdentifier.BACKBONE:
bindarg += ' -b'
self.execute_command(f'udp bind{bindarg} {ip} {port}')
def udp_connect(self, ip: str, port: int):
"""Specifies the peer with which the socket is to be associated.
+7
View File
@@ -52,6 +52,13 @@ class PartitionId(int):
pass
class NetifIdentifier(int):
"""Represents a network interface identifier."""
UNSPECIFIED = 0
THERAD = 1
BACKBONE = 2
class DeviceMode(str):
"""Represents a device mode."""
+9 -7
View File
@@ -36,6 +36,7 @@ import unittest
import otci
from otci import OTCI
from otci.errors import CommandError
from otci import NetifIdentifier
logging.basicConfig(level=logging.DEBUG)
@@ -303,13 +304,14 @@ class TestOTCI(unittest.TestCase):
leader.wait(1)
leader.coap_stop()
leader.udp_open()
leader.udp_bind("::", 1234)
leader.udp_send(leader.get_ipaddr_rloc(), 1234, text='hello')
leader.udp_send(leader.get_ipaddr_rloc(), 1234, random_bytes=3)
leader.udp_send(leader.get_ipaddr_rloc(), 1234, hex='112233')
leader.wait(1)
leader.udp_close()
for netif in (NetifIdentifier.THERAD, NetifIdentifier.UNSPECIFIED, NetifIdentifier.BACKBONE):
leader.udp_open()
leader.udp_bind("::", 1234, netif=netif)
leader.udp_send(leader.get_ipaddr_rloc(), 1234, text='hello')
leader.udp_send(leader.get_ipaddr_rloc(), 1234, random_bytes=3)
leader.udp_send(leader.get_ipaddr_rloc(), 1234, hex='112233')
leader.wait(1)
leader.udp_close()
logging.info('dataset: %r', leader.get_dataset())
logging.info('dataset active: %r', leader.get_dataset('active'))