Skip to content

Commit

Permalink
[tcat][ble] fixes to connection state mgmt and Disconnect cmd; commen…
Browse files Browse the repository at this point in the history
…ts updated/corrected.
  • Loading branch information
EskoDijk committed Aug 16, 2024
1 parent 93e8381 commit 44af046
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 40 deletions.
2 changes: 1 addition & 1 deletion include/openthread/platform/ble.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ extern void otPlatBleGapOnDisconnected(otInstance *aInstance, uint16_t aConnecti
* Disconnects BLE connection.
*
* The BLE device shall use the Remote User Terminated Connection (0x13) reason
* code when disconnecting from the peer BLE device..
* code when disconnecting from the peer BLE device.
*
* @param[in] aInstance The OpenThread instance structure.
*
Expand Down
4 changes: 4 additions & 0 deletions src/core/meshcop/tcat_agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,7 @@ Error TcatAgent::HandleSingleTlv(const Message &aIncomingMessage, Message &aOutg
{
case kTlvDisconnect:
error = kErrorAbort;
response = true; // true - to avoid response-with-status being sent.
break;

case kTlvSetActiveOperationalDataset:
Expand All @@ -410,16 +411,19 @@ Error TcatAgent::HandleSingleTlv(const Message &aIncomingMessage, Message &aOutg
response = true;
error = kErrorNone;
break;

case kTlvDecommission:
error = HandleDecomission();
break;

case kTlvPing:
error = HandlePing(aIncomingMessage, aOutgoingMessage, offset, length);
if (error == kErrorNone)
{
response = true;
}
break;

default:
error = kErrorInvalidCommand;
}
Expand Down
27 changes: 13 additions & 14 deletions src/core/meshcop/tcat_agent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,28 +271,28 @@ class TcatAgent : public InstanceLocator, private NonCopyable
};

/**
* Initializes the Joiner object.
* Initializes the TCAT agent object.
*
* @param[in] aInstance A reference to the OpenThread instance.
*
*/
explicit TcatAgent(Instance &aInstance);

/**
* Enables the TCAT protocol.
* Enables the TCAT agent.
*
* @param[in] aAppDataReceiveCallback A pointer to a function that is called when the user data is received.
* @param[in] aHandler A pointer to a function that is called when the join operation completes.
* @param[in] aContext A context pointer.
*
* @retval kErrorNone Successfully started the TCAT agent.
* @retval kErrorInvalidArgs The aVendorInfo is invalid.
* @retval kErrorNone Successfully started the TCAT agent.
* @retval kErrorFailed Failed to start due to missing vendor info.
*
*/
Error Start(AppDataReceiveCallback aAppDataReceiveCallback, JoinCallback aHandler, void *aContext);

/**
* Stops the TCAT protocol.
* Stops the TCAT agent.
*
*/
void Stop(void);
Expand All @@ -317,31 +317,31 @@ class TcatAgent : public InstanceLocator, private NonCopyable
/**
* Indicates whether or not the TCAT agent is connected.
*
* @retval TRUE The TCAT agent is connected.
* @retval TRUE The TCAT agent is connected with a TCAT commissioner.
* @retval FALSE The TCAT agent is not connected.
*
*/
bool IsConnected(void) const { return mState == kStateConnected; }

/**
* Indicates whether or not a command class is authorized.
* Indicates whether or not a TCAT command class is authorized for use.
*
* @param[in] aCommandClass Command class to subject for authorization check.
* @param[in] aCommandClass Command class to subject to authorization check.
*
* @retval TRUE The command class is authorized.
* @retval FALSE The command class is not authorized.
* @retval TRUE The command class is authorized for use by the present TCAT commissioner.
* @retval FALSE The command class is not authorized for use.
*
*/
bool IsCommandClassAuthorized(CommandClass aCommandClass) const;

/**
* Gets TCAT advertisement data.
*
* @param[out] aLen Advertisement length.
* @param[out] aLen Advertisement data length (up to OT_TCAT_ADVERTISEMENT_MAX_LEN).
* @param[out] aAdvertisementData Advertisement data.
*
* @retval kErrorNone Successfully started the TCAT agent.
* @retval kErrorInvalidArgs The aVendorInfo is invalid or provided incorrect parameters.
* @retval kErrorNone Successfully retrieved the TCAT advertisement data.
* @retval kErrorInvalidArgs The data could not be retrieved, or aAdvertisementData is null.
*
*/
Error GetAdvertisementData(uint16_t &aLen, uint8_t *aAdvertisementData);
Expand All @@ -362,7 +362,6 @@ class TcatAgent : public InstanceLocator, private NonCopyable
bool CanProcessTlv(uint8_t aTlvType) const;
CommandClass GetCommandClass(uint8_t aTlvType) const;

static constexpr uint16_t kJoinerUdpPort = OPENTHREAD_CONFIG_JOINER_UDP_PORT;
static constexpr uint16_t kPingPayloadMaxLength = 512;

JoinerPskd mJoinerPskd;
Expand Down
20 changes: 10 additions & 10 deletions src/core/radio/ble_secure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,21 +330,19 @@ void BleSecure::HandleTlsConnected(bool aConnected)
{
if (aConnected)
{
Error err;

if (mReceivedMessage == nullptr)
{
mReceivedMessage = Get<MessagePool>().Allocate(Message::kTypeBle);
}
err = mTcatAgent.Connected(mTls);

if (mTcatAgent.IsEnabled())
if (err != kErrorNone)
{
Error err = mTcatAgent.Connected(mTls);

if (err != kErrorNone)
{
mTls.Close();
LogWarn("Rejected TCAT Commissioner, error: %s", ErrorToString(err));
ExitNow();
}
mTls.Disconnect(); // must not use Close(), so that next Commissioner can connect
LogWarn("Rejected TCAT Commissioner, error: %s", ErrorToString(err));
ExitNow();
}
}
else
Expand Down Expand Up @@ -449,8 +447,10 @@ void BleSecure::HandleTlsReceive(uint8_t *aBuf, uint16_t aLength)

if (error == kErrorAbort)
{
// kErrorAbort indicates that a Disconnect command TLV has been received.
Disconnect();
Stop();
// BleSecure is not stopped here, it must remain active in advertising state and
// must be ready to receive a next TCAT commissioner.
ExitNow();
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/core/radio/ble_secure.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,13 @@ class BleSecure : public InstanceLocator, private NonCopyable
bool IsTcatEnabled(void) const { return mTcatAgent.IsEnabled(); }

/**
* Indicates whether or not a TCAT command class is authorized.
* Indicates whether or not a TCAT command class is authorized for use.
*
* @param[in] aInstance A pointer to an OpenThread instance.
* @param[in] aCommandClass A command class to check.
* @param[in] aCommandClass A command class to subject to authorization check.
*
* @retval TRUE The command class is authorized.
* @retval FALSE The command class is not authorized.
* @retval TRUE The command class is authorized for use by the present TCAT commissioner.
* @retval FALSE The command class is not authorized for use.
*
*/
bool IsCommandClassAuthorized(CommandClass aCommandClass) const
Expand Down
6 changes: 3 additions & 3 deletions tools/tcat_ble_client/bbtc.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@ async def main():
while True:
user_input = await loop.run_in_executor(None, lambda: input('> '))
if user_input.lower() == 'exit':
print('Disconnecting...')
if ble_sstream is not None:
await ble_sstream.close()
break
try:
result: CommandResult = await cli.evaluate_input(user_input)
Expand All @@ -113,6 +110,9 @@ async def main():
except Exception as e:
logger.error(e)

print('Disconnecting...')
if ble_sstream is not None:
await ble_sstream.close()

async def get_device_by_args(args):
device = None
Expand Down
1 change: 1 addition & 0 deletions tools/tcat_ble_client/ble/ble_stream_secure.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ async def send_with_resp(self, bytes):

async def close(self):
if self.ssl_object.session is not None:
logger.debug('sending Disconnect command TLV')
data = TLV(TcatTLVType.DISCONNECT.value, bytes()).to_bytes()
await self.send(data)

Expand Down
18 changes: 12 additions & 6 deletions tools/tcat_ble_client/ble/udp_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,31 @@

import logging
import socket
import select

logger = logging.getLogger(__name__)


class UdpStream:
BASE_PORT = 10000
MAX_SERVER_TIMEOUT_SEC = 10

def __init__(self, address, node_id):
self.__receive_buffer = b''
self.__last_recv_time = None
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.socket.setblocking(False)
self.address = (address, self.BASE_PORT + node_id)

async def send(self, data):
logger.debug(f'sending {data}')
self.socket.sendto(data, self.address)
return len(data)
logger.debug(f'sending {len(data)} bytes: {data}')
return self.socket.sendto(data, self.address)

async def recv(self, bufsize):
message = self.socket.recv(bufsize)
logger.debug(f'retrieved {message}')
return message
ready = select.select([self.socket], [], [], self.MAX_SERVER_TIMEOUT_SEC)
if ready[0]:
data = self.socket.recv(bufsize)
logger.debug(f'received {len(data)} bytes: {data}')
return data
else:
raise Exception('simulation UdpStream recv timeout - likely, TCAT is stopped on TCAT Device')
4 changes: 2 additions & 2 deletions tools/tcat_ble_client/cli/base_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,15 @@ async def execute_default(self, args, context):
data = TLV(TcatTLVType.PING.value, to_send).to_bytes()
elapsed_time = time()
response = await bless.send_with_resp(data)
elapsed_time = time() - elapsed_time
elapsed_time = 1e3 * (time() - elapsed_time)
if not response:
return

tlv_response = TLV.from_bytes(response)
if tlv_response.value != to_send:
print("Received malformed response.")

print(f"Roundtrip time {elapsed_time} s.")
print(f"Roundtrip time: {elapsed_time} ms")

return CommandResultTLV(tlv_response)

Expand Down

0 comments on commit 44af046

Please sign in to comment.