• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2024, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <string.h>
30 
31 #include "test_util.hpp"
32 #include "lib/spinel/spinel_prop_codec.hpp"
33 
34 namespace ot {
35 namespace Spinel {
36 
DnssdFakeCallback(otInstance * aInstance,otPlatDnssdRequestId aRequestId,otError aError)37 static void DnssdFakeCallback(otInstance *aInstance, otPlatDnssdRequestId aRequestId, otError aError)
38 {
39     OT_UNUSED_VARIABLE(aInstance);
40     OT_UNUSED_VARIABLE(aRequestId);
41     OT_UNUSED_VARIABLE(aError);
42 }
43 
TestDnssd(void)44 void TestDnssd(void)
45 {
46     constexpr uint16_t kMaxSpinelBufferSize = 2048;
47     uint8_t            buf[kMaxSpinelBufferSize];
48     uint16_t           len;
49     Spinel::Buffer     ncpBuffer(buf, kMaxSpinelBufferSize);
50     Spinel::Encoder    encoder(ncpBuffer);
51     Spinel::Decoder    decoder;
52     uint8_t            header;
53     unsigned int       command;
54     unsigned int       propKey;
55     otError            error = OT_ERROR_NONE;
56 
57     // Test DnssdHost encoding and decoding
58     otPlatDnssdHost dnssdHostEncode;
59     otPlatDnssdHost dnssdHostDecode;
60     otIp6Address    dnssdHostAddrs[] = {
61            {0xfd, 0x2a, 0xc3, 0x0c, 0x87, 0xd3, 0x00, 0x01, 0xed, 0x1c, 0x0c, 0x91, 0xcc, 0xb6, 0x57, 0x8b},
62     };
63     otPlatDnssdRequestId requestId;
64     const uint8_t       *callbackData;
65     uint16_t             callbackDataLen;
66     dnssdHostEncode.mHostName        = "ot-host1";
67     dnssdHostEncode.mAddresses       = dnssdHostAddrs;
68     dnssdHostEncode.mAddressesLength = 1;
69 
70     SuccessOrQuit(error = encoder.BeginFrame(SPINEL_HEADER_FLAG, SPINEL_CMD_PROP_VALUE_INSERTED));
71     SuccessOrQuit(error = EncodeDnssd(encoder, dnssdHostEncode, 1 /* aRequestId */, DnssdFakeCallback));
72     SuccessOrQuit(error = encoder.EndFrame());
73     SuccessOrQuit(ncpBuffer.OutFrameBegin());
74     len = ncpBuffer.OutFrameGetLength();
75     VerifyOrQuit(ncpBuffer.OutFrameRead(len, buf) == len);
76 
77     decoder.Init(buf, len);
78     SuccessOrQuit(error = decoder.ReadUint8(header));
79     VerifyOrQuit(header == SPINEL_HEADER_FLAG);
80     SuccessOrQuit(error = decoder.ReadUintPacked(command));
81     VerifyOrQuit(command == SPINEL_CMD_PROP_VALUE_INSERTED);
82     SuccessOrQuit(error = decoder.ReadUintPacked(propKey));
83     VerifyOrQuit(static_cast<spinel_prop_key_t>(propKey) == SPINEL_PROP_DNSSD_HOST);
84     SuccessOrQuit(error = DecodeDnssdHost(decoder, dnssdHostDecode, requestId, callbackData, callbackDataLen));
85     VerifyOrQuit(strcmp(dnssdHostDecode.mHostName, dnssdHostEncode.mHostName) == 0);
86     VerifyOrQuit(dnssdHostDecode.mAddressesLength == dnssdHostEncode.mAddressesLength);
87     VerifyOrQuit(memcmp(dnssdHostDecode.mAddresses, dnssdHostEncode.mAddresses,
88                         dnssdHostDecode.mAddressesLength * sizeof(otIp6Address)) == 0);
89     VerifyOrQuit(requestId == 1);
90     VerifyOrQuit(callbackDataLen == sizeof(otPlatDnssdRegisterCallback));
91     VerifyOrQuit(*reinterpret_cast<const otPlatDnssdRegisterCallback *>(callbackData) == DnssdFakeCallback);
92 
93     // Test DnssdService encoding and decoding
94     otPlatDnssdService dnssdServiceEncode;
95     otPlatDnssdService dnssdServiceDecode;
96     const char        *dnssdSubType[]       = {"cat", "dog", "fish"};
97     const uint8_t      txtData[]            = {0x01, 0x02, 0x03, 0x04};
98     dnssdServiceEncode.mHostName            = "ot-host2";
99     dnssdServiceEncode.mServiceInstance     = "ot-service";
100     dnssdServiceEncode.mServiceType         = "";
101     dnssdServiceEncode.mSubTypeLabels       = dnssdSubType;
102     dnssdServiceEncode.mSubTypeLabelsLength = sizeof(dnssdSubType) / sizeof(dnssdSubType[0]);
103     dnssdServiceEncode.mTxtData             = txtData;
104     dnssdServiceEncode.mTxtDataLength       = sizeof(txtData);
105     dnssdServiceEncode.mPort                = 1234;
106     dnssdServiceEncode.mPriority            = 567;
107     dnssdServiceEncode.mWeight              = 890;
108     dnssdServiceEncode.mTtl                 = 9999;
109 
110     ncpBuffer.Clear();
111     SuccessOrQuit(error = encoder.BeginFrame(SPINEL_HEADER_FLAG, SPINEL_CMD_PROP_VALUE_INSERTED));
112     SuccessOrQuit(error = EncodeDnssd(encoder, dnssdServiceEncode, 2 /* aRequestId */, DnssdFakeCallback));
113     SuccessOrQuit(error = encoder.EndFrame());
114     SuccessOrQuit(ncpBuffer.OutFrameBegin());
115     len = ncpBuffer.OutFrameGetLength();
116     VerifyOrQuit(ncpBuffer.OutFrameRead(len, buf) == len);
117 
118     decoder.Init(buf, len);
119     SuccessOrQuit(error = decoder.ReadUint8(header));
120     VerifyOrQuit(header == SPINEL_HEADER_FLAG);
121     SuccessOrQuit(error = decoder.ReadUintPacked(command));
122     VerifyOrQuit(command == SPINEL_CMD_PROP_VALUE_INSERTED);
123     SuccessOrQuit(error = decoder.ReadUintPacked(propKey));
124     VerifyOrQuit(static_cast<spinel_prop_key_t>(propKey) == SPINEL_PROP_DNSSD_SERVICE);
125     const char *dnssdSubTypeDecode[] = {nullptr, nullptr, nullptr};
126     uint16_t    dnssdSubTypeCount    = sizeof(dnssdSubTypeDecode) / sizeof(dnssdSubTypeDecode[0]);
127     SuccessOrQuit(error = DecodeDnssdService(decoder, dnssdServiceDecode, dnssdSubTypeDecode, dnssdSubTypeCount,
128                                              requestId, callbackData, callbackDataLen));
129     VerifyOrQuit(strcmp(dnssdServiceDecode.mHostName, dnssdServiceEncode.mHostName) == 0);
130     VerifyOrQuit(strcmp(dnssdServiceDecode.mServiceInstance, dnssdServiceEncode.mServiceInstance) == 0);
131     VerifyOrQuit(strcmp(dnssdServiceDecode.mServiceType, dnssdServiceEncode.mServiceType) == 0);
132     VerifyOrQuit(dnssdServiceDecode.mPort == dnssdServiceEncode.mPort);
133     VerifyOrQuit(dnssdServiceDecode.mPriority == dnssdServiceEncode.mPriority);
134     VerifyOrQuit(dnssdServiceDecode.mWeight == dnssdServiceEncode.mWeight);
135     VerifyOrQuit(dnssdServiceDecode.mTtl == dnssdServiceEncode.mTtl);
136     VerifyOrQuit(dnssdSubTypeCount == sizeof(dnssdSubType) / sizeof(dnssdSubType[0]));
137     for (uint16_t i = 0; i < dnssdSubTypeCount; i++)
138     {
139         VerifyOrQuit(strcmp(dnssdSubTypeDecode[i], dnssdSubType[i]) == 0);
140     }
141     VerifyOrQuit(requestId == 2);
142     VerifyOrQuit(callbackDataLen == sizeof(otPlatDnssdRegisterCallback));
143     VerifyOrQuit(*reinterpret_cast<const otPlatDnssdRegisterCallback *>(callbackData) == DnssdFakeCallback);
144 
145     // Test DnssdKey encoding and decoding
146     otPlatDnssdKey dnssdKeyEncode;
147     otPlatDnssdKey dnssdKeyDecode;
148     const uint8_t  keyData[]      = {0x05, 0x06, 0x07, 0x08};
149     dnssdKeyEncode.mName          = "ot-key";
150     dnssdKeyEncode.mServiceType   = nullptr;
151     dnssdKeyEncode.mKeyData       = keyData;
152     dnssdKeyEncode.mKeyDataLength = sizeof(keyData);
153     dnssdKeyEncode.mClass         = 123;
154     dnssdKeyEncode.mTtl           = 888;
155 
156     ncpBuffer.Clear();
157     SuccessOrQuit(error = encoder.BeginFrame(SPINEL_HEADER_FLAG, SPINEL_CMD_PROP_VALUE_INSERTED));
158     SuccessOrQuit(error = EncodeDnssd(encoder, dnssdKeyEncode, 3 /* aRequestId */, DnssdFakeCallback));
159     SuccessOrQuit(error = encoder.EndFrame());
160     SuccessOrQuit(ncpBuffer.OutFrameBegin());
161     len = ncpBuffer.OutFrameGetLength();
162     VerifyOrQuit(ncpBuffer.OutFrameRead(len, buf) == len);
163 
164     decoder.Init(buf, len);
165     SuccessOrQuit(error = decoder.ReadUint8(header));
166     VerifyOrQuit(header == SPINEL_HEADER_FLAG);
167     SuccessOrQuit(error = decoder.ReadUintPacked(command));
168     VerifyOrQuit(command == SPINEL_CMD_PROP_VALUE_INSERTED);
169     SuccessOrQuit(error = decoder.ReadUintPacked(propKey));
170     VerifyOrQuit(static_cast<spinel_prop_key_t>(propKey) == SPINEL_PROP_DNSSD_KEY_RECORD);
171     SuccessOrQuit(error = DecodeDnssdKey(decoder, dnssdKeyDecode, requestId, callbackData, callbackDataLen));
172     VerifyOrQuit(strcmp(dnssdKeyDecode.mName, dnssdKeyEncode.mName) == 0);
173     VerifyOrQuit(dnssdKeyDecode.mServiceType == dnssdKeyEncode.mServiceType);
174     VerifyOrQuit(dnssdKeyDecode.mKeyDataLength == dnssdKeyEncode.mKeyDataLength);
175     VerifyOrQuit(memcmp(dnssdKeyDecode.mKeyData, dnssdKeyEncode.mKeyData, dnssdKeyDecode.mKeyDataLength) == 0);
176     VerifyOrQuit(dnssdKeyDecode.mClass == dnssdKeyEncode.mClass);
177     VerifyOrQuit(dnssdKeyDecode.mTtl == dnssdKeyEncode.mTtl);
178     VerifyOrQuit(requestId == 3);
179     VerifyOrQuit(callbackDataLen == sizeof(otPlatDnssdRegisterCallback));
180     VerifyOrQuit(*reinterpret_cast<const otPlatDnssdRegisterCallback *>(callbackData) == DnssdFakeCallback);
181 }
182 
183 } // namespace Spinel
184 } // namespace ot
185 
main(void)186 int main(void)
187 {
188     ot::Spinel::TestDnssd();
189     printf("\nAll tests passed.\n");
190     return 0;
191 }
192