xref: /aosp_15_r20/external/openthread/src/cli/cli_tcat.cpp (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker /*
2*cfb92d14SAndroid Build Coastguard Worker  *  Copyright (c) 2023, The OpenThread Authors.
3*cfb92d14SAndroid Build Coastguard Worker  *  All rights reserved.
4*cfb92d14SAndroid Build Coastguard Worker  *
5*cfb92d14SAndroid Build Coastguard Worker  *  Redistribution and use in source and binary forms, with or without
6*cfb92d14SAndroid Build Coastguard Worker  *  modification, are permitted provided that the following conditions are met:
7*cfb92d14SAndroid Build Coastguard Worker  *  1. Redistributions of source code must retain the above copyright
8*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer.
9*cfb92d14SAndroid Build Coastguard Worker  *  2. Redistributions in binary form must reproduce the above copyright
10*cfb92d14SAndroid Build Coastguard Worker  *     notice, this list of conditions and the following disclaimer in the
11*cfb92d14SAndroid Build Coastguard Worker  *     documentation and/or other materials provided with the distribution.
12*cfb92d14SAndroid Build Coastguard Worker  *  3. Neither the name of the copyright holder nor the
13*cfb92d14SAndroid Build Coastguard Worker  *     names of its contributors may be used to endorse or promote products
14*cfb92d14SAndroid Build Coastguard Worker  *     derived from this software without specific prior written permission.
15*cfb92d14SAndroid Build Coastguard Worker  *
16*cfb92d14SAndroid Build Coastguard Worker  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*cfb92d14SAndroid Build Coastguard Worker  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*cfb92d14SAndroid Build Coastguard Worker  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*cfb92d14SAndroid Build Coastguard Worker  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*cfb92d14SAndroid Build Coastguard Worker  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*cfb92d14SAndroid Build Coastguard Worker  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*cfb92d14SAndroid Build Coastguard Worker  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*cfb92d14SAndroid Build Coastguard Worker  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*cfb92d14SAndroid Build Coastguard Worker  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*cfb92d14SAndroid Build Coastguard Worker  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*cfb92d14SAndroid Build Coastguard Worker  *  POSSIBILITY OF SUCH DAMAGE.
27*cfb92d14SAndroid Build Coastguard Worker  */
28*cfb92d14SAndroid Build Coastguard Worker 
29*cfb92d14SAndroid Build Coastguard Worker #include "openthread-core-config.h"
30*cfb92d14SAndroid Build Coastguard Worker 
31*cfb92d14SAndroid Build Coastguard Worker #include "cli/cli_utils.hpp"
32*cfb92d14SAndroid Build Coastguard Worker 
33*cfb92d14SAndroid Build Coastguard Worker #include "cli/cli_tcat.hpp"
34*cfb92d14SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
35*cfb92d14SAndroid Build Coastguard Worker #include "common/error.hpp"
36*cfb92d14SAndroid Build Coastguard Worker 
37*cfb92d14SAndroid Build Coastguard Worker #include <openthread/ble_secure.h>
38*cfb92d14SAndroid Build Coastguard Worker 
39*cfb92d14SAndroid Build Coastguard Worker #include <mbedtls/oid.h>
40*cfb92d14SAndroid Build Coastguard Worker #include <openthread/error.h>
41*cfb92d14SAndroid Build Coastguard Worker #include <openthread/tcat.h>
42*cfb92d14SAndroid Build Coastguard Worker #include <openthread/platform/ble.h>
43*cfb92d14SAndroid Build Coastguard Worker 
44*cfb92d14SAndroid Build Coastguard Worker #if OPENTHREAD_CONFIG_BLE_TCAT_ENABLE && OPENTHREAD_CONFIG_CLI_BLE_SECURE_ENABLE
45*cfb92d14SAndroid Build Coastguard Worker 
46*cfb92d14SAndroid Build Coastguard Worker // DeviceCert1 default identity for TCAT certification testing.
47*cfb92d14SAndroid Build Coastguard Worker // WARNING: storage of private keys in code or program memory MUST NOT be used in production.
48*cfb92d14SAndroid Build Coastguard Worker // The below code is for testing purposes only. For production, secure key storage must be
49*cfb92d14SAndroid Build Coastguard Worker // used to store private keys.
50*cfb92d14SAndroid Build Coastguard Worker #define OT_CLI_TCAT_X509_CERT                                            \
51*cfb92d14SAndroid Build Coastguard Worker     "-----BEGIN CERTIFICATE-----\n"                                      \
52*cfb92d14SAndroid Build Coastguard Worker     "MIIB6TCCAZCgAwIBAgICNekwCgYIKoZIzj0EAwIwcTEmMCQGA1UEAwwdVGhyZWFk\n" \
53*cfb92d14SAndroid Build Coastguard Worker     "IENlcnRpZmljYXRpb24gRGV2aWNlQ0ExGTAXBgNVBAoMEFRocmVhZCBHcm91cCBJ\n" \
54*cfb92d14SAndroid Build Coastguard Worker     "bmMxEjAQBgNVBAcMCVNhbiBSYW1vbjELMAkGA1UECAwCQ0ExCzAJBgNVBAYTAlVT\n" \
55*cfb92d14SAndroid Build Coastguard Worker     "MCAXDTI0MDUwNzA5Mzk0NVoYDzI5OTkxMjMxMDkzOTQ1WjA8MSEwHwYDVQQDDBhU\n" \
56*cfb92d14SAndroid Build Coastguard Worker     "Q0FUIEV4YW1wbGUgRGV2aWNlQ2VydDExFzAVBgNVBAUTDjQ3MjMtOTgzMy0wMDAx\n" \
57*cfb92d14SAndroid Build Coastguard Worker     "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE11h/4vKZXVXv+1GDZo066spItloT\n" \
58*cfb92d14SAndroid Build Coastguard Worker     "dpCi0bux0jvpQSHLdQBIc+40zVCxMDRUvbX//vJKGsSJKOVUlCojQ2wIdqNLMEkw\n" \
59*cfb92d14SAndroid Build Coastguard Worker     "HwYDVR0jBBgwFoAUX6sbKWiIodS0MaiGYefnZlnt+BkwEAYJKwYBBAGC3yoCBAMC\n" \
60*cfb92d14SAndroid Build Coastguard Worker     "AQUwFAYJKwYBBAGC3yoDBAcEBSABAQEBMAoGCCqGSM49BAMCA0cAMEQCIHWu+Rd1\n" \
61*cfb92d14SAndroid Build Coastguard Worker     "VRlzrD8KbuyJcJFTXh2sQ9UIrFIA7+4e/GVcAiAVBdGqTxbt3TGkBBllpafAUB2/\n" \
62*cfb92d14SAndroid Build Coastguard Worker     "s0GJj7E33oblqy5eHQ==\n"                                             \
63*cfb92d14SAndroid Build Coastguard Worker     "-----END CERTIFICATE-----\n"
64*cfb92d14SAndroid Build Coastguard Worker 
65*cfb92d14SAndroid Build Coastguard Worker #define OT_CLI_TCAT_PRIV_KEY                                             \
66*cfb92d14SAndroid Build Coastguard Worker     "-----BEGIN EC PRIVATE KEY-----\n"                                   \
67*cfb92d14SAndroid Build Coastguard Worker     "MHcCAQEEIIqKM1QTlNaquV74W6Viz/ggXoLqlPOP6LagSyaFO3oUoAoGCCqGSM49\n" \
68*cfb92d14SAndroid Build Coastguard Worker     "AwEHoUQDQgAE11h/4vKZXVXv+1GDZo066spItloTdpCi0bux0jvpQSHLdQBIc+40\n" \
69*cfb92d14SAndroid Build Coastguard Worker     "zVCxMDRUvbX//vJKGsSJKOVUlCojQ2wIdg==\n"                             \
70*cfb92d14SAndroid Build Coastguard Worker     "-----END EC PRIVATE KEY-----\n"
71*cfb92d14SAndroid Build Coastguard Worker 
72*cfb92d14SAndroid Build Coastguard Worker #define OT_CLI_TCAT_TRUSTED_ROOT_CERTIFICATE                             \
73*cfb92d14SAndroid Build Coastguard Worker     "-----BEGIN CERTIFICATE-----\n"                                      \
74*cfb92d14SAndroid Build Coastguard Worker     "MIICOzCCAeGgAwIBAgIJAKOc2hehOGoBMAoGCCqGSM49BAMCMHExJjAkBgNVBAMM\n" \
75*cfb92d14SAndroid Build Coastguard Worker     "HVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJlYWQg\n" \
76*cfb92d14SAndroid Build Coastguard Worker     "R3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQswCQYD\n" \
77*cfb92d14SAndroid Build Coastguard Worker     "VQQGEwJVUzAeFw0yNDA1MDMyMDAyMThaFw00NDA0MjgyMDAyMThaMHExJjAkBgNV\n" \
78*cfb92d14SAndroid Build Coastguard Worker     "BAMMHVRocmVhZCBDZXJ0aWZpY2F0aW9uIERldmljZUNBMRkwFwYDVQQKDBBUaHJl\n" \
79*cfb92d14SAndroid Build Coastguard Worker     "YWQgR3JvdXAgSW5jMRIwEAYDVQQHDAlTYW4gUmFtb24xCzAJBgNVBAgMAkNBMQsw\n" \
80*cfb92d14SAndroid Build Coastguard Worker     "CQYDVQQGEwJVUzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGy850VBIPTkN3oL\n" \
81*cfb92d14SAndroid Build Coastguard Worker     "x++zIUsZk2k26w4fuieFz9oNvjdb5W14+Yf3mvGWsl4NHyLxqhmamVAR4h7zWRlZ\n" \
82*cfb92d14SAndroid Build Coastguard Worker     "0XyMVpKjYjBgMB4GA1UdEQQXMBWBE3RvbUB0aHJlYWRncm91cC5vcmcwDgYDVR0P\n" \
83*cfb92d14SAndroid Build Coastguard Worker     "AQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFF+rGyloiKHUtDGo\n" \
84*cfb92d14SAndroid Build Coastguard Worker     "hmHn52ZZ7fgZMAoGCCqGSM49BAMCA0gAMEUCIQCTq1qjPZs9fAJB6ppTXs588Pnu\n" \
85*cfb92d14SAndroid Build Coastguard Worker     "eVFOwC8bd//D99KiHAIgU84kwFHIyDvFqu6y+u1hFqBGsiuTmKwZ2PHhVe/xK1k=\n" \
86*cfb92d14SAndroid Build Coastguard Worker     "-----END CERTIFICATE-----\n"
87*cfb92d14SAndroid Build Coastguard Worker 
88*cfb92d14SAndroid Build Coastguard Worker namespace ot {
89*cfb92d14SAndroid Build Coastguard Worker 
90*cfb92d14SAndroid Build Coastguard Worker namespace Cli {
91*cfb92d14SAndroid Build Coastguard Worker 
92*cfb92d14SAndroid Build Coastguard Worker otTcatAdvertisedDeviceId sAdvertisedDeviceIds[OT_TCAT_DEVICE_ID_MAX];
93*cfb92d14SAndroid Build Coastguard Worker otTcatGeneralDeviceId    sGeneralDeviceId;
94*cfb92d14SAndroid Build Coastguard Worker 
95*cfb92d14SAndroid Build Coastguard Worker const char kPskdVendor[] = "JJJJJJ";
96*cfb92d14SAndroid Build Coastguard Worker const char kUrl[]        = "dummy_url";
97*cfb92d14SAndroid Build Coastguard Worker 
IsDeviceIdSet(void)98*cfb92d14SAndroid Build Coastguard Worker static bool IsDeviceIdSet(void)
99*cfb92d14SAndroid Build Coastguard Worker {
100*cfb92d14SAndroid Build Coastguard Worker     bool ret = false;
101*cfb92d14SAndroid Build Coastguard Worker     for (const otTcatAdvertisedDeviceId &vendorDeviceId : sAdvertisedDeviceIds)
102*cfb92d14SAndroid Build Coastguard Worker     {
103*cfb92d14SAndroid Build Coastguard Worker         if (vendorDeviceId.mDeviceIdType != OT_TCAT_DEVICE_ID_EMPTY)
104*cfb92d14SAndroid Build Coastguard Worker         {
105*cfb92d14SAndroid Build Coastguard Worker             ExitNow(ret = true);
106*cfb92d14SAndroid Build Coastguard Worker         }
107*cfb92d14SAndroid Build Coastguard Worker     }
108*cfb92d14SAndroid Build Coastguard Worker exit:
109*cfb92d14SAndroid Build Coastguard Worker     return ret;
110*cfb92d14SAndroid Build Coastguard Worker }
111*cfb92d14SAndroid Build Coastguard Worker 
HandleBleSecureReceive(otInstance * aInstance,const otMessage * aMessage,int32_t aOffset,otTcatApplicationProtocol aTcatApplicationProtocol,const char * aServiceName,void * aContext)112*cfb92d14SAndroid Build Coastguard Worker static void HandleBleSecureReceive(otInstance               *aInstance,
113*cfb92d14SAndroid Build Coastguard Worker                                    const otMessage          *aMessage,
114*cfb92d14SAndroid Build Coastguard Worker                                    int32_t                   aOffset,
115*cfb92d14SAndroid Build Coastguard Worker                                    otTcatApplicationProtocol aTcatApplicationProtocol,
116*cfb92d14SAndroid Build Coastguard Worker                                    const char               *aServiceName,
117*cfb92d14SAndroid Build Coastguard Worker                                    void                     *aContext)
118*cfb92d14SAndroid Build Coastguard Worker {
119*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aContext);
120*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aTcatApplicationProtocol);
121*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aServiceName);
122*cfb92d14SAndroid Build Coastguard Worker 
123*cfb92d14SAndroid Build Coastguard Worker     static constexpr int     kTextMaxLen   = 100;
124*cfb92d14SAndroid Build Coastguard Worker     static constexpr uint8_t kBufPrefixLen = 5;
125*cfb92d14SAndroid Build Coastguard Worker 
126*cfb92d14SAndroid Build Coastguard Worker     uint16_t nLen;
127*cfb92d14SAndroid Build Coastguard Worker     uint8_t  buf[kTextMaxLen];
128*cfb92d14SAndroid Build Coastguard Worker 
129*cfb92d14SAndroid Build Coastguard Worker     nLen =
130*cfb92d14SAndroid Build Coastguard Worker         otMessageRead(aMessage, static_cast<uint16_t>(aOffset), buf + kBufPrefixLen, sizeof(buf) - kBufPrefixLen - 1);
131*cfb92d14SAndroid Build Coastguard Worker 
132*cfb92d14SAndroid Build Coastguard Worker     memcpy(buf, "RECV:", kBufPrefixLen);
133*cfb92d14SAndroid Build Coastguard Worker 
134*cfb92d14SAndroid Build Coastguard Worker     buf[nLen + kBufPrefixLen] = 0;
135*cfb92d14SAndroid Build Coastguard Worker 
136*cfb92d14SAndroid Build Coastguard Worker     IgnoreReturnValue(otBleSecureSendApplicationTlv(aInstance, buf, (uint16_t)strlen((char *)buf)));
137*cfb92d14SAndroid Build Coastguard Worker     IgnoreReturnValue(otBleSecureFlush(aInstance));
138*cfb92d14SAndroid Build Coastguard Worker }
139*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])140*cfb92d14SAndroid Build Coastguard Worker template <> otError Tcat::Process<Cmd("advid")>(Arg aArgs[])
141*cfb92d14SAndroid Build Coastguard Worker {
142*cfb92d14SAndroid Build Coastguard Worker     otError                  error = OT_ERROR_NONE;
143*cfb92d14SAndroid Build Coastguard Worker     otTcatAdvertisedDeviceId devId;
144*cfb92d14SAndroid Build Coastguard Worker     static const char *const kVendorIdTypes[] = {"clear", "oui24", "oui36", "discriminator", "ianapen"};
145*cfb92d14SAndroid Build Coastguard Worker 
146*cfb92d14SAndroid Build Coastguard Worker     mVendorInfo.mAdvertisedDeviceIds = sAdvertisedDeviceIds;
147*cfb92d14SAndroid Build Coastguard Worker 
148*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty())
149*cfb92d14SAndroid Build Coastguard Worker     {
150*cfb92d14SAndroid Build Coastguard Worker         if (mVendorInfo.mAdvertisedDeviceIds[0].mDeviceIdType != OT_TCAT_DEVICE_ID_EMPTY)
151*cfb92d14SAndroid Build Coastguard Worker         {
152*cfb92d14SAndroid Build Coastguard Worker             OutputLine("Set advertisedIds:");
153*cfb92d14SAndroid Build Coastguard Worker             for (size_t i = 0; mVendorInfo.mAdvertisedDeviceIds[i].mDeviceIdType != OT_TCAT_DEVICE_ID_EMPTY; i++)
154*cfb92d14SAndroid Build Coastguard Worker             {
155*cfb92d14SAndroid Build Coastguard Worker                 OutputFormat("type %s, value: ", kVendorIdTypes[mVendorInfo.mAdvertisedDeviceIds[i].mDeviceIdType]);
156*cfb92d14SAndroid Build Coastguard Worker                 OutputBytesLine(const_cast<uint8_t *>(mVendorInfo.mAdvertisedDeviceIds[i].mDeviceId),
157*cfb92d14SAndroid Build Coastguard Worker                                 mVendorInfo.mAdvertisedDeviceIds[i].mDeviceIdLen);
158*cfb92d14SAndroid Build Coastguard Worker             }
159*cfb92d14SAndroid Build Coastguard Worker         }
160*cfb92d14SAndroid Build Coastguard Worker         ExitNow();
161*cfb92d14SAndroid Build Coastguard Worker     }
162*cfb92d14SAndroid Build Coastguard Worker 
163*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0] == kVendorIdTypes[OT_TCAT_DEVICE_ID_OUI24])
164*cfb92d14SAndroid Build Coastguard Worker     {
165*cfb92d14SAndroid Build Coastguard Worker         devId.mDeviceIdType = OT_TCAT_DEVICE_ID_OUI24;
166*cfb92d14SAndroid Build Coastguard Worker     }
167*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == kVendorIdTypes[OT_TCAT_DEVICE_ID_OUI36])
168*cfb92d14SAndroid Build Coastguard Worker     {
169*cfb92d14SAndroid Build Coastguard Worker         devId.mDeviceIdType = OT_TCAT_DEVICE_ID_OUI36;
170*cfb92d14SAndroid Build Coastguard Worker     }
171*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == kVendorIdTypes[OT_TCAT_DEVICE_ID_DISCRIMINATOR])
172*cfb92d14SAndroid Build Coastguard Worker     {
173*cfb92d14SAndroid Build Coastguard Worker         devId.mDeviceIdType = OT_TCAT_DEVICE_ID_DISCRIMINATOR;
174*cfb92d14SAndroid Build Coastguard Worker     }
175*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == kVendorIdTypes[OT_TCAT_DEVICE_ID_IANAPEN])
176*cfb92d14SAndroid Build Coastguard Worker     {
177*cfb92d14SAndroid Build Coastguard Worker         devId.mDeviceIdType = OT_TCAT_DEVICE_ID_IANAPEN;
178*cfb92d14SAndroid Build Coastguard Worker     }
179*cfb92d14SAndroid Build Coastguard Worker     else if (aArgs[0] == kVendorIdTypes[OT_TCAT_DEVICE_ID_EMPTY])
180*cfb92d14SAndroid Build Coastguard Worker     {
181*cfb92d14SAndroid Build Coastguard Worker         for (otTcatAdvertisedDeviceId &vendorDeviceId : sAdvertisedDeviceIds)
182*cfb92d14SAndroid Build Coastguard Worker         {
183*cfb92d14SAndroid Build Coastguard Worker             vendorDeviceId.mDeviceIdType = OT_TCAT_DEVICE_ID_EMPTY;
184*cfb92d14SAndroid Build Coastguard Worker             vendorDeviceId.mDeviceIdLen  = 0;
185*cfb92d14SAndroid Build Coastguard Worker         }
186*cfb92d14SAndroid Build Coastguard Worker         ExitNow();
187*cfb92d14SAndroid Build Coastguard Worker     }
188*cfb92d14SAndroid Build Coastguard Worker     else
189*cfb92d14SAndroid Build Coastguard Worker     {
190*cfb92d14SAndroid Build Coastguard Worker         ExitNow(error = OT_ERROR_INVALID_ARGS);
191*cfb92d14SAndroid Build Coastguard Worker     }
192*cfb92d14SAndroid Build Coastguard Worker 
193*cfb92d14SAndroid Build Coastguard Worker     if (!aArgs[1].IsEmpty() && aArgs[1].GetLength() < (OT_TCAT_MAX_ADVERTISED_DEVICEID_SIZE * 2 + 1))
194*cfb92d14SAndroid Build Coastguard Worker     {
195*cfb92d14SAndroid Build Coastguard Worker         devId.mDeviceIdLen = OT_TCAT_MAX_ADVERTISED_DEVICEID_SIZE;
196*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = aArgs[1].ParseAsHexString(devId.mDeviceIdLen, devId.mDeviceId));
197*cfb92d14SAndroid Build Coastguard Worker         for (otTcatAdvertisedDeviceId &vendorDeviceId : sAdvertisedDeviceIds)
198*cfb92d14SAndroid Build Coastguard Worker         {
199*cfb92d14SAndroid Build Coastguard Worker             if (vendorDeviceId.mDeviceIdType == devId.mDeviceIdType ||
200*cfb92d14SAndroid Build Coastguard Worker                 vendorDeviceId.mDeviceIdType == OT_TCAT_DEVICE_ID_EMPTY)
201*cfb92d14SAndroid Build Coastguard Worker             {
202*cfb92d14SAndroid Build Coastguard Worker                 vendorDeviceId = devId;
203*cfb92d14SAndroid Build Coastguard Worker                 break;
204*cfb92d14SAndroid Build Coastguard Worker             }
205*cfb92d14SAndroid Build Coastguard Worker         }
206*cfb92d14SAndroid Build Coastguard Worker     }
207*cfb92d14SAndroid Build Coastguard Worker     else
208*cfb92d14SAndroid Build Coastguard Worker     {
209*cfb92d14SAndroid Build Coastguard Worker         ExitNow(error = OT_ERROR_INVALID_ARGS);
210*cfb92d14SAndroid Build Coastguard Worker     }
211*cfb92d14SAndroid Build Coastguard Worker exit:
212*cfb92d14SAndroid Build Coastguard Worker     return error;
213*cfb92d14SAndroid Build Coastguard Worker }
214*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])215*cfb92d14SAndroid Build Coastguard Worker template <> otError Tcat::Process<Cmd("devid")>(Arg aArgs[])
216*cfb92d14SAndroid Build Coastguard Worker {
217*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
218*cfb92d14SAndroid Build Coastguard Worker 
219*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty())
220*cfb92d14SAndroid Build Coastguard Worker     {
221*cfb92d14SAndroid Build Coastguard Worker         if (sGeneralDeviceId.mDeviceIdLen != 0)
222*cfb92d14SAndroid Build Coastguard Worker         {
223*cfb92d14SAndroid Build Coastguard Worker             OutputLine("TCAT DeviceId:");
224*cfb92d14SAndroid Build Coastguard Worker             OutputBytesLine(sGeneralDeviceId.mDeviceId, sGeneralDeviceId.mDeviceIdLen);
225*cfb92d14SAndroid Build Coastguard Worker         }
226*cfb92d14SAndroid Build Coastguard Worker         ExitNow();
227*cfb92d14SAndroid Build Coastguard Worker     }
228*cfb92d14SAndroid Build Coastguard Worker 
229*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0] == "clear")
230*cfb92d14SAndroid Build Coastguard Worker     {
231*cfb92d14SAndroid Build Coastguard Worker         ClearAllBytes(sGeneralDeviceId);
232*cfb92d14SAndroid Build Coastguard Worker     }
233*cfb92d14SAndroid Build Coastguard Worker     else
234*cfb92d14SAndroid Build Coastguard Worker     {
235*cfb92d14SAndroid Build Coastguard Worker         VerifyOrExit(aArgs[0].GetLength() < (OT_TCAT_MAX_DEVICEID_SIZE * 2 + 1), error = OT_ERROR_INVALID_ARGS);
236*cfb92d14SAndroid Build Coastguard Worker         sGeneralDeviceId.mDeviceIdLen = OT_TCAT_MAX_DEVICEID_SIZE;
237*cfb92d14SAndroid Build Coastguard Worker         SuccessOrExit(error = aArgs[0].ParseAsHexString(sGeneralDeviceId.mDeviceIdLen, sGeneralDeviceId.mDeviceId));
238*cfb92d14SAndroid Build Coastguard Worker     }
239*cfb92d14SAndroid Build Coastguard Worker 
240*cfb92d14SAndroid Build Coastguard Worker exit:
241*cfb92d14SAndroid Build Coastguard Worker     return error;
242*cfb92d14SAndroid Build Coastguard Worker }
243*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])244*cfb92d14SAndroid Build Coastguard Worker template <> otError Tcat::Process<Cmd("start")>(Arg aArgs[])
245*cfb92d14SAndroid Build Coastguard Worker {
246*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aArgs);
247*cfb92d14SAndroid Build Coastguard Worker 
248*cfb92d14SAndroid Build Coastguard Worker     otError error = OT_ERROR_NONE;
249*cfb92d14SAndroid Build Coastguard Worker 
250*cfb92d14SAndroid Build Coastguard Worker     ClearAllBytes(mVendorInfo);
251*cfb92d14SAndroid Build Coastguard Worker     mVendorInfo.mPskdString      = kPskdVendor;
252*cfb92d14SAndroid Build Coastguard Worker     mVendorInfo.mProvisioningUrl = kUrl;
253*cfb92d14SAndroid Build Coastguard Worker 
254*cfb92d14SAndroid Build Coastguard Worker     if (IsDeviceIdSet())
255*cfb92d14SAndroid Build Coastguard Worker     {
256*cfb92d14SAndroid Build Coastguard Worker         mVendorInfo.mAdvertisedDeviceIds = sAdvertisedDeviceIds;
257*cfb92d14SAndroid Build Coastguard Worker     }
258*cfb92d14SAndroid Build Coastguard Worker 
259*cfb92d14SAndroid Build Coastguard Worker     if (sGeneralDeviceId.mDeviceIdLen != 0)
260*cfb92d14SAndroid Build Coastguard Worker     {
261*cfb92d14SAndroid Build Coastguard Worker         mVendorInfo.mGeneralDeviceId = &sGeneralDeviceId;
262*cfb92d14SAndroid Build Coastguard Worker     }
263*cfb92d14SAndroid Build Coastguard Worker 
264*cfb92d14SAndroid Build Coastguard Worker     otBleSecureSetCertificate(GetInstancePtr(), reinterpret_cast<const uint8_t *>(OT_CLI_TCAT_X509_CERT),
265*cfb92d14SAndroid Build Coastguard Worker                               sizeof(OT_CLI_TCAT_X509_CERT), reinterpret_cast<const uint8_t *>(OT_CLI_TCAT_PRIV_KEY),
266*cfb92d14SAndroid Build Coastguard Worker                               sizeof(OT_CLI_TCAT_PRIV_KEY));
267*cfb92d14SAndroid Build Coastguard Worker 
268*cfb92d14SAndroid Build Coastguard Worker     otBleSecureSetCaCertificateChain(GetInstancePtr(),
269*cfb92d14SAndroid Build Coastguard Worker                                      reinterpret_cast<const uint8_t *>(OT_CLI_TCAT_TRUSTED_ROOT_CERTIFICATE),
270*cfb92d14SAndroid Build Coastguard Worker                                      sizeof(OT_CLI_TCAT_TRUSTED_ROOT_CERTIFICATE));
271*cfb92d14SAndroid Build Coastguard Worker 
272*cfb92d14SAndroid Build Coastguard Worker     otBleSecureSetSslAuthMode(GetInstancePtr(), true);
273*cfb92d14SAndroid Build Coastguard Worker 
274*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otBleSecureSetTcatVendorInfo(GetInstancePtr(), &mVendorInfo));
275*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otBleSecureStart(GetInstancePtr(), nullptr, HandleBleSecureReceive, true, nullptr));
276*cfb92d14SAndroid Build Coastguard Worker     SuccessOrExit(error = otBleSecureTcatStart(GetInstancePtr(), nullptr));
277*cfb92d14SAndroid Build Coastguard Worker 
278*cfb92d14SAndroid Build Coastguard Worker exit:
279*cfb92d14SAndroid Build Coastguard Worker     return error;
280*cfb92d14SAndroid Build Coastguard Worker }
281*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])282*cfb92d14SAndroid Build Coastguard Worker template <> otError Tcat::Process<Cmd("stop")>(Arg aArgs[])
283*cfb92d14SAndroid Build Coastguard Worker {
284*cfb92d14SAndroid Build Coastguard Worker     OT_UNUSED_VARIABLE(aArgs);
285*cfb92d14SAndroid Build Coastguard Worker 
286*cfb92d14SAndroid Build Coastguard Worker     otBleSecureStop(GetInstancePtr());
287*cfb92d14SAndroid Build Coastguard Worker 
288*cfb92d14SAndroid Build Coastguard Worker     return OT_ERROR_NONE;
289*cfb92d14SAndroid Build Coastguard Worker }
290*cfb92d14SAndroid Build Coastguard Worker 
Process(Arg aArgs[])291*cfb92d14SAndroid Build Coastguard Worker otError Tcat::Process(Arg aArgs[])
292*cfb92d14SAndroid Build Coastguard Worker {
293*cfb92d14SAndroid Build Coastguard Worker #define CmdEntry(aCommandString)                            \
294*cfb92d14SAndroid Build Coastguard Worker     {                                                       \
295*cfb92d14SAndroid Build Coastguard Worker         aCommandString, &Tcat::Process<Cmd(aCommandString)> \
296*cfb92d14SAndroid Build Coastguard Worker     }
297*cfb92d14SAndroid Build Coastguard Worker 
298*cfb92d14SAndroid Build Coastguard Worker     static constexpr Command kCommands[] = {CmdEntry("advid"), CmdEntry("devid"), CmdEntry("start"), CmdEntry("stop")};
299*cfb92d14SAndroid Build Coastguard Worker 
300*cfb92d14SAndroid Build Coastguard Worker     static_assert(BinarySearch::IsSorted(kCommands), "kCommands is not sorted");
301*cfb92d14SAndroid Build Coastguard Worker 
302*cfb92d14SAndroid Build Coastguard Worker #undef CmdEntry
303*cfb92d14SAndroid Build Coastguard Worker 
304*cfb92d14SAndroid Build Coastguard Worker     otError        error = OT_ERROR_NONE;
305*cfb92d14SAndroid Build Coastguard Worker     const Command *command;
306*cfb92d14SAndroid Build Coastguard Worker 
307*cfb92d14SAndroid Build Coastguard Worker     if (aArgs[0].IsEmpty() || (aArgs[0] == "help"))
308*cfb92d14SAndroid Build Coastguard Worker     {
309*cfb92d14SAndroid Build Coastguard Worker         OutputCommandTable(kCommands);
310*cfb92d14SAndroid Build Coastguard Worker         ExitNow(error = aArgs[0].IsEmpty() ? error : OT_ERROR_NONE);
311*cfb92d14SAndroid Build Coastguard Worker     }
312*cfb92d14SAndroid Build Coastguard Worker 
313*cfb92d14SAndroid Build Coastguard Worker     command = BinarySearch::Find(aArgs[0].GetCString(), kCommands);
314*cfb92d14SAndroid Build Coastguard Worker     VerifyOrExit(command != nullptr);
315*cfb92d14SAndroid Build Coastguard Worker 
316*cfb92d14SAndroid Build Coastguard Worker     error = (this->*command->mHandler)(aArgs + 1);
317*cfb92d14SAndroid Build Coastguard Worker 
318*cfb92d14SAndroid Build Coastguard Worker exit:
319*cfb92d14SAndroid Build Coastguard Worker     return error;
320*cfb92d14SAndroid Build Coastguard Worker }
321*cfb92d14SAndroid Build Coastguard Worker 
322*cfb92d14SAndroid Build Coastguard Worker } // namespace Cli
323*cfb92d14SAndroid Build Coastguard Worker } // namespace ot
324*cfb92d14SAndroid Build Coastguard Worker #endif // OPENTHREAD_CONFIG_BLE_TCAT_ENABLE && OPENTHREAD_CONFIG_CLI_BLE_SECURE_ENABLE
325