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