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 /**
30 * @file This file implements spinel property encoding and decoding functions.
31 */
32
33 #include "lib/spinel/spinel_prop_codec.hpp"
34 #include "common/code_utils.hpp"
35
36 namespace ot {
37 namespace Spinel {
38
39 template <>
EncodeDnssd(Encoder & aEncoder,const otPlatDnssdHost & aObj,otPlatDnssdRequestId aRequestId,otPlatDnssdRegisterCallback aCallback)40 otError EncodeDnssd<otPlatDnssdHost>(Encoder &aEncoder,
41 const otPlatDnssdHost &aObj,
42 otPlatDnssdRequestId aRequestId,
43 otPlatDnssdRegisterCallback aCallback)
44 {
45 otError error = OT_ERROR_NONE;
46
47 SuccessOrExit(error = aEncoder.WriteUintPacked(SPINEL_PROP_DNSSD_HOST));
48 SuccessOrExit(error = aEncoder.WriteUtf8(aObj.mHostName == nullptr ? "" : aObj.mHostName));
49 SuccessOrExit(error = aEncoder.WriteUint16(aObj.mAddressesLength));
50 for (uint16_t i = 0; i < aObj.mAddressesLength; i++)
51 {
52 SuccessOrExit(error = aEncoder.WriteIp6Address(aObj.mAddresses[i]));
53 }
54 SuccessOrExit(error = aEncoder.WriteUint32(aRequestId));
55 SuccessOrExit(error = aEncoder.WriteData(reinterpret_cast<const uint8_t *>(&aCallback), sizeof(aCallback)));
56
57 exit:
58 return error;
59 }
60
61 template <>
EncodeDnssd(Encoder & aEncoder,const otPlatDnssdService & aObj,otPlatDnssdRequestId aRequestId,otPlatDnssdRegisterCallback aCallback)62 otError EncodeDnssd<otPlatDnssdService>(Encoder &aEncoder,
63 const otPlatDnssdService &aObj,
64 otPlatDnssdRequestId aRequestId,
65 otPlatDnssdRegisterCallback aCallback)
66 {
67 otError error = OT_ERROR_NONE;
68
69 SuccessOrExit(error = aEncoder.WriteUintPacked(SPINEL_PROP_DNSSD_SERVICE));
70 SuccessOrExit(error = aEncoder.WriteUtf8(aObj.mHostName == nullptr ? "" : aObj.mHostName));
71 SuccessOrExit(error = aEncoder.WriteUtf8(aObj.mServiceInstance == nullptr ? "" : aObj.mServiceInstance));
72 SuccessOrExit(error = aEncoder.WriteUtf8(aObj.mServiceType == nullptr ? "" : aObj.mServiceType));
73 SuccessOrExit(error = aEncoder.OpenStruct());
74 for (uint16_t i = 0; i < aObj.mSubTypeLabelsLength; i++)
75 {
76 SuccessOrExit(error = aEncoder.WriteUtf8(aObj.mSubTypeLabels[i]));
77 }
78 SuccessOrExit(error = aEncoder.CloseStruct());
79 SuccessOrExit(error = aEncoder.WriteDataWithLen(aObj.mTxtData, aObj.mTxtDataLength));
80 SuccessOrExit(error = aEncoder.WriteUint16(aObj.mPort));
81 SuccessOrExit(error = aEncoder.WriteUint16(aObj.mPriority));
82 SuccessOrExit(error = aEncoder.WriteUint16(aObj.mWeight));
83 SuccessOrExit(error = aEncoder.WriteUint32(aObj.mTtl));
84 SuccessOrExit(error = aEncoder.WriteUint32(aRequestId));
85 SuccessOrExit(error = aEncoder.WriteData(reinterpret_cast<const uint8_t *>(&aCallback), sizeof(aCallback)));
86
87 exit:
88 return error;
89 }
90
91 template <>
EncodeDnssd(Encoder & aEncoder,const otPlatDnssdKey & aObj,otPlatDnssdRequestId aRequestId,otPlatDnssdRegisterCallback aCallback)92 otError EncodeDnssd<otPlatDnssdKey>(Encoder &aEncoder,
93 const otPlatDnssdKey &aObj,
94 otPlatDnssdRequestId aRequestId,
95 otPlatDnssdRegisterCallback aCallback)
96 {
97 otError error = OT_ERROR_NONE;
98
99 SuccessOrExit(error = aEncoder.WriteUintPacked(SPINEL_PROP_DNSSD_KEY_RECORD));
100 SuccessOrExit(error = aEncoder.WriteUtf8(aObj.mName == nullptr ? "" : aObj.mName));
101 SuccessOrExit(error = aEncoder.OpenStruct());
102 if (aObj.mServiceType != nullptr)
103 {
104 SuccessOrExit(error = aEncoder.WriteUtf8(aObj.mServiceType));
105 }
106 SuccessOrExit(error = aEncoder.CloseStruct());
107 SuccessOrExit(error = aEncoder.WriteDataWithLen(aObj.mKeyData, aObj.mKeyDataLength));
108 SuccessOrExit(error = aEncoder.WriteUint16(aObj.mClass));
109 SuccessOrExit(error = aEncoder.WriteUint32(aObj.mTtl));
110 SuccessOrExit(error = aEncoder.WriteUint32(aRequestId));
111 SuccessOrExit(error = aEncoder.WriteData(reinterpret_cast<const uint8_t *>(&aCallback), sizeof(aCallback)));
112
113 exit:
114 return error;
115 }
116
DecodeDnssdHost(Decoder & aDecoder,otPlatDnssdHost & aHost,otPlatDnssdRequestId & aRequestId,const uint8_t * & aCallbackData,uint16_t & aCallbackDataLen)117 otError DecodeDnssdHost(Decoder &aDecoder,
118 otPlatDnssdHost &aHost,
119 otPlatDnssdRequestId &aRequestId,
120 const uint8_t *&aCallbackData,
121 uint16_t &aCallbackDataLen)
122 {
123 otError error = OT_ERROR_NONE;
124
125 SuccessOrExit(error = aDecoder.ReadUtf8(aHost.mHostName));
126 SuccessOrExit(error = aDecoder.ReadUint16(aHost.mAddressesLength));
127 SuccessOrExit(error = aDecoder.ReadIp6Address(aHost.mAddresses));
128 SuccessOrExit(error = aDecoder.ReadUint32(aRequestId));
129 SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
130
131 exit:
132 return error;
133 }
134
DecodeDnssdService(Decoder & aDecoder,otPlatDnssdService & aService,const char ** aSubTypeLabels,uint16_t & aSubTypeLabelsCount,otPlatDnssdRequestId & aRequestId,const uint8_t * & aCallbackData,uint16_t & aCallbackDataLen)135 otError DecodeDnssdService(Decoder &aDecoder,
136 otPlatDnssdService &aService,
137 const char **aSubTypeLabels,
138 uint16_t &aSubTypeLabelsCount,
139 otPlatDnssdRequestId &aRequestId,
140 const uint8_t *&aCallbackData,
141 uint16_t &aCallbackDataLen)
142 {
143 otError error = OT_ERROR_NONE;
144 uint8_t index = 0;
145
146 SuccessOrExit(error = aDecoder.ReadUtf8(aService.mHostName));
147 SuccessOrExit(error = aDecoder.ReadUtf8(aService.mServiceInstance));
148 SuccessOrExit(error = aDecoder.ReadUtf8(aService.mServiceType));
149 SuccessOrExit(error = aDecoder.OpenStruct());
150 while (!aDecoder.IsAllReadInStruct())
151 {
152 VerifyOrExit(index < aSubTypeLabelsCount, error = OT_ERROR_NO_BUFS);
153 SuccessOrExit(error = aDecoder.ReadUtf8(aSubTypeLabels[index]));
154 index++;
155 }
156 aSubTypeLabelsCount = index;
157 SuccessOrExit(error = aDecoder.CloseStruct());
158 SuccessOrExit(error = aDecoder.ReadDataWithLen(aService.mTxtData, aService.mTxtDataLength));
159 SuccessOrExit(error = aDecoder.ReadUint16(aService.mPort));
160 SuccessOrExit(error = aDecoder.ReadUint16(aService.mPriority));
161 SuccessOrExit(error = aDecoder.ReadUint16(aService.mWeight));
162 SuccessOrExit(error = aDecoder.ReadUint32(aService.mTtl));
163 SuccessOrExit(error = aDecoder.ReadUint32(aRequestId));
164 SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
165
166 exit:
167 return error;
168 }
169
DecodeDnssdKey(Decoder & aDecoder,otPlatDnssdKey & aKey,otPlatDnssdRequestId & aRequestId,const uint8_t * & aCallbackData,uint16_t & aCallbackDataLen)170 otError DecodeDnssdKey(Decoder &aDecoder,
171 otPlatDnssdKey &aKey,
172 otPlatDnssdRequestId &aRequestId,
173 const uint8_t *&aCallbackData,
174 uint16_t &aCallbackDataLen)
175 {
176 otError error = OT_ERROR_NONE;
177
178 SuccessOrExit(error = aDecoder.ReadUtf8(aKey.mName));
179 SuccessOrExit(error = aDecoder.OpenStruct());
180 if (!aDecoder.IsAllReadInStruct())
181 {
182 SuccessOrExit(error = aDecoder.ReadUtf8(aKey.mServiceType));
183 }
184 else
185 {
186 aKey.mServiceType = nullptr;
187 }
188 SuccessOrExit(error = aDecoder.CloseStruct());
189 SuccessOrExit(error = aDecoder.ReadDataWithLen(aKey.mKeyData, aKey.mKeyDataLength));
190 SuccessOrExit(error = aDecoder.ReadUint16(aKey.mClass));
191 SuccessOrExit(error = aDecoder.ReadUint32(aKey.mTtl));
192 SuccessOrExit(error = aDecoder.ReadUint32(aRequestId));
193 SuccessOrExit(error = aDecoder.ReadData(aCallbackData, aCallbackDataLen));
194
195 exit:
196 return error;
197 }
198
199 } // namespace Spinel
200 } // namespace ot
201