1 /*
2 * Copyright (c) 2020, 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
31 * This file includes definitions for Thread URIs.
32 */
33
34 #include "uri_paths.hpp"
35
36 #include "common/binary_search.hpp"
37 #include "common/debug.hpp"
38 #include "common/string.hpp"
39
40 #include <string.h>
41
42 namespace ot {
43
44 namespace UriList {
45
46 struct Entry
47 {
48 const char *mPath;
49
AreInOrderot::UriList::Entry50 constexpr static bool AreInOrder(const Entry &aFirst, const Entry &aSecond)
51 {
52 return AreStringsInOrder(aFirst.mPath, aSecond.mPath);
53 }
54
Compareot::UriList::Entry55 int Compare(const char *aPath) const { return strcmp(aPath, mPath); }
56 };
57
58 // The list of URI paths (MUST be sorted alphabetically)
59 static constexpr Entry kEntries[] = {
60 {"a/ae"}, // (0) kUriAddressError
61 {"a/an"}, // (1) kUriAddressNotify
62 {"a/aq"}, // (2) kUriAddressQuery
63 {"a/ar"}, // (3) kUriAddressRelease
64 {"a/as"}, // (4) kUriAddressSolicit
65 {"a/sd"}, // (5) kUriServerData
66 {"a/yl"}, // (6) kUriAnycastLocate
67 {"b/ba"}, // (7) kUriBackboneAnswer
68 {"b/bmr"}, // (8) kUriBackboneMlr
69 {"b/bq"}, // (9) kUriBackboneQuery
70 {"c/ab"}, // (10) kUriAnnounceBegin
71 {"c/ag"}, // (11) kUriActiveGet
72 {"c/as"}, // (12) kUriActiveSet
73 {"c/ca"}, // (13) kUriCommissionerKeepAlive
74 {"c/cg"}, // (14) kUriCommissionerGet
75 {"c/cp"}, // (15) kUriCommissionerPetition
76 {"c/cs"}, // (16) kUriCommissionerSet
77 {"c/dc"}, // (17) kUriDatasetChanged
78 {"c/er"}, // (18) kUriEnergyReport
79 {"c/es"}, // (19) kUriEnergyScan
80 {"c/je"}, // (20) kUriJoinerEntrust
81 {"c/jf"}, // (21) kUriJoinerFinalize
82 {"c/la"}, // (22) kUriLeaderKeepAlive
83 {"c/lp"}, // (23) kUriLeaderPetition
84 {"c/pc"}, // (24) kUriPanIdConflict
85 {"c/pg"}, // (25) kUriPendingGet
86 {"c/pq"}, // (26) kUriPanIdQuery
87 {"c/ps"}, // (27) kUriPendingSet
88 {"c/rx"}, // (28) kUriRelayRx
89 {"c/tx"}, // (29) kUriRelayTx
90 {"c/ur"}, // (30) kUriProxyRx
91 {"c/ut"}, // (31) kUriProxyTx
92 {"d/da"}, // (32) kUriDiagnosticGetAnswer
93 {"d/dg"}, // (33) kUriDiagnosticGetRequest
94 {"d/dq"}, // (34) kUriDiagnosticGetQuery
95 {"d/dr"}, // (35) kUriDiagnosticReset
96 {"n/dn"}, // (36) kUriDuaRegistrationNotify
97 {"n/dr"}, // (37) kUriDuaRegistrationRequest
98 {"n/mr"}, // (38) kUriMlr
99 };
100
101 static_assert(BinarySearch::IsSorted(kEntries), "kEntries is not sorted");
102
103 static_assert(0 == kUriAddressError, "kUriAddressError (`a/ae`) is invalid");
104 static_assert(1 == kUriAddressNotify, "kUriAddressNotify (`a/an`) is invalid");
105 static_assert(2 == kUriAddressQuery, "kUriAddressQuery (`a/aq`) is invalid");
106 static_assert(3 == kUriAddressRelease, "kUriAddressRelease (`a/ar`) is invalid");
107 static_assert(4 == kUriAddressSolicit, "kUriAddressSolicit (`a/as`) is invalid");
108 static_assert(5 == kUriServerData, "kUriServerData (`a/sd`) is invalid");
109 static_assert(6 == kUriAnycastLocate, "kUriAnycastLocate (`a/yl`) is invalid");
110 static_assert(7 == kUriBackboneAnswer, "kUriBackboneAnswer (`b/ba`) is invalid");
111 static_assert(8 == kUriBackboneMlr, "kUriBackboneMlr (`b/bmr`) is invalid");
112 static_assert(9 == kUriBackboneQuery, "kUriBackboneQuery (`b/bq`) is invalid");
113 static_assert(10 == kUriAnnounceBegin, "kUriAnnounceBegin (`c/ab`) is invalid");
114 static_assert(11 == kUriActiveGet, "kUriActiveGet (`c/ag`) is invalid");
115 static_assert(12 == kUriActiveSet, "kUriActiveSet (`c/as`) is invalid");
116 static_assert(13 == kUriCommissionerKeepAlive, "kUriCommissionerKeepAlive (`c/ca`) is invalid");
117 static_assert(14 == kUriCommissionerGet, "kUriCommissionerGet (`c/cg`) is invalid");
118 static_assert(15 == kUriCommissionerPetition, "kUriCommissionerPetition (`c/cp`) is invalid");
119 static_assert(16 == kUriCommissionerSet, "kUriCommissionerSet (`c/cs`) is invalid");
120 static_assert(17 == kUriDatasetChanged, "kUriDatasetChanged (`c/dc`) is invalid");
121 static_assert(18 == kUriEnergyReport, "kUriEnergyReport (`c/er`) is invalid");
122 static_assert(19 == kUriEnergyScan, "kUriEnergyScan (`c/es`) is invalid");
123 static_assert(20 == kUriJoinerEntrust, "kUriJoinerEntrust (`c/je`) is invalid");
124 static_assert(21 == kUriJoinerFinalize, "kUriJoinerFinalize (`c/jf`) is invalid");
125 static_assert(22 == kUriLeaderKeepAlive, "kUriLeaderKeepAlive (`c/la`) is invalid");
126 static_assert(23 == kUriLeaderPetition, "kUriLeaderPetition (`c/lp`) is invalid");
127 static_assert(24 == kUriPanIdConflict, "kUriPanIdConflict (`c/pc`) is invalid");
128 static_assert(25 == kUriPendingGet, "kUriPendingGet (`c/pg`) is invalid");
129 static_assert(26 == kUriPanIdQuery, "kUriPanIdQuery (`c/pq`) is invalid");
130 static_assert(27 == kUriPendingSet, "kUriPendingSet (`c/ps`) is invalid");
131 static_assert(28 == kUriRelayRx, "kUriRelayRx (`c/rx`) is invalid");
132 static_assert(29 == kUriRelayTx, "kUriRelayTx (`c/tx`) is invalid");
133 static_assert(30 == kUriProxyRx, "kUriProxyRx (`c/ur`) is invalid");
134 static_assert(31 == kUriProxyTx, "kUriProxyTx (`c/ut`) is invalid");
135 static_assert(32 == kUriDiagnosticGetAnswer, "kUriDiagnosticGetAnswer (`d/da`) is invalid");
136 static_assert(33 == kUriDiagnosticGetRequest, "kUriDiagnosticGetRequest (`d/dg`) is invalid");
137 static_assert(34 == kUriDiagnosticGetQuery, "kUriDiagnosticGetQuery (`d/dq`) is invalid");
138 static_assert(35 == kUriDiagnosticReset, "kUriDiagnosticReset (`d/dr`) is invalid");
139 static_assert(36 == kUriDuaRegistrationNotify, "kUriDuaRegistrationNotify (`n/dn`) is invalid");
140 static_assert(37 == kUriDuaRegistrationRequest, "kUriDuaRegistrationRequest (`n/dr`) is invalid");
141 static_assert(38 == kUriMlr, "kUriMlr (`n/mr`) is invalid");
142
143 } // namespace UriList
144
PathForUri(Uri aUri)145 const char *PathForUri(Uri aUri)
146 {
147 OT_ASSERT(aUri != kUriUnknown);
148
149 return UriList::kEntries[aUri].mPath;
150 }
151
UriFromPath(const char * aPath)152 Uri UriFromPath(const char *aPath)
153 {
154 Uri uri = kUriUnknown;
155 const UriList::Entry *entry = BinarySearch::Find(aPath, UriList::kEntries);
156
157 VerifyOrExit(entry != nullptr);
158 uri = static_cast<Uri>(entry - UriList::kEntries);
159
160 exit:
161 return uri;
162 }
163
UriToString(void)164 template <> const char *UriToString<kUriAddressError>(void) { return "AddressError"; }
UriToString(void)165 template <> const char *UriToString<kUriAddressNotify>(void) { return "AddressNotify"; }
UriToString(void)166 template <> const char *UriToString<kUriAddressQuery>(void) { return "AddressQuery"; }
UriToString(void)167 template <> const char *UriToString<kUriAddressRelease>(void) { return "AddressRelease"; }
UriToString(void)168 template <> const char *UriToString<kUriAddressSolicit>(void) { return "AddressSolicit"; }
UriToString(void)169 template <> const char *UriToString<kUriServerData>(void) { return "ServerData"; }
UriToString(void)170 template <> const char *UriToString<kUriAnycastLocate>(void) { return "AnycastLocate"; }
UriToString(void)171 template <> const char *UriToString<kUriBackboneAnswer>(void) { return "BackboneAnswer"; }
UriToString(void)172 template <> const char *UriToString<kUriBackboneMlr>(void) { return "BackboneMlr"; }
UriToString(void)173 template <> const char *UriToString<kUriBackboneQuery>(void) { return "BackboneQuery"; }
UriToString(void)174 template <> const char *UriToString<kUriAnnounceBegin>(void) { return "AnnounceBegin"; }
UriToString(void)175 template <> const char *UriToString<kUriActiveGet>(void) { return "ActiveGet"; }
UriToString(void)176 template <> const char *UriToString<kUriActiveSet>(void) { return "ActiveSet"; }
UriToString(void)177 template <> const char *UriToString<kUriCommissionerKeepAlive>(void) { return "CommissionerKeepAlive"; }
UriToString(void)178 template <> const char *UriToString<kUriCommissionerGet>(void) { return "CommissionerGet"; }
UriToString(void)179 template <> const char *UriToString<kUriCommissionerPetition>(void) { return "CommissionerPetition"; }
UriToString(void)180 template <> const char *UriToString<kUriCommissionerSet>(void) { return "CommissionerSet"; }
UriToString(void)181 template <> const char *UriToString<kUriDatasetChanged>(void) { return "DatasetChanged"; }
UriToString(void)182 template <> const char *UriToString<kUriEnergyReport>(void) { return "EnergyReport"; }
UriToString(void)183 template <> const char *UriToString<kUriEnergyScan>(void) { return "EnergyScan"; }
UriToString(void)184 template <> const char *UriToString<kUriJoinerEntrust>(void) { return "JoinerEntrust"; }
UriToString(void)185 template <> const char *UriToString<kUriJoinerFinalize>(void) { return "JoinerFinalize"; }
UriToString(void)186 template <> const char *UriToString<kUriLeaderKeepAlive>(void) { return "LeaderKeepAlive"; }
UriToString(void)187 template <> const char *UriToString<kUriLeaderPetition>(void) { return "LeaderPetition"; }
UriToString(void)188 template <> const char *UriToString<kUriPanIdConflict>(void) { return "PanIdConflict"; }
UriToString(void)189 template <> const char *UriToString<kUriPendingGet>(void) { return "PendingGet"; }
UriToString(void)190 template <> const char *UriToString<kUriPanIdQuery>(void) { return "PanIdQuery"; }
UriToString(void)191 template <> const char *UriToString<kUriPendingSet>(void) { return "PendingSet"; }
UriToString(void)192 template <> const char *UriToString<kUriRelayRx>(void) { return "RelayRx"; }
UriToString(void)193 template <> const char *UriToString<kUriRelayTx>(void) { return "RelayTx"; }
UriToString(void)194 template <> const char *UriToString<kUriProxyRx>(void) { return "ProxyRx"; }
UriToString(void)195 template <> const char *UriToString<kUriProxyTx>(void) { return "ProxyTx"; }
UriToString(void)196 template <> const char *UriToString<kUriDiagnosticGetAnswer>(void) { return "DiagGetAnswer"; }
UriToString(void)197 template <> const char *UriToString<kUriDiagnosticGetRequest>(void) { return "DiagGetRequest"; }
UriToString(void)198 template <> const char *UriToString<kUriDiagnosticGetQuery>(void) { return "DiagGetQuery"; }
UriToString(void)199 template <> const char *UriToString<kUriDiagnosticReset>(void) { return "DiagReset"; }
UriToString(void)200 template <> const char *UriToString<kUriDuaRegistrationNotify>(void) { return "DuaRegNotify"; }
UriToString(void)201 template <> const char *UriToString<kUriDuaRegistrationRequest>(void) { return "DuaRegRequest"; }
UriToString(void)202 template <> const char *UriToString<kUriMlr>(void) { return "Mlr"; }
203
204 } // namespace ot
205