• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2022, 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 implements Network Name management.
32  */
33 
34 #include "network_name.hpp"
35 
36 #include "instance/instance.hpp"
37 
38 namespace ot {
39 namespace MeshCoP {
40 
CopyTo(char * aBuffer,uint8_t aMaxSize) const41 uint8_t NameData::CopyTo(char *aBuffer, uint8_t aMaxSize) const
42 {
43     MutableData<kWithUint8Length> destData;
44 
45     destData.Init(aBuffer, aMaxSize);
46     destData.ClearBytes();
47     IgnoreError(destData.CopyBytesFrom(*this));
48 
49     return destData.GetLength();
50 }
51 
GetAsData(void) const52 NameData NetworkName::GetAsData(void) const
53 {
54     return NameData(m8, static_cast<uint8_t>(StringLength(m8, kMaxSize + 1)));
55 }
56 
Set(const char * aNameString)57 Error NetworkName::Set(const char *aNameString)
58 {
59     // When setting `NetworkName` from a string, we treat it as `NameData`
60     // with `kMaxSize + 1` chars. `NetworkName::Set(data)` will look
61     // for null char in the data (within its given size) to calculate
62     // the name's length and ensure that the name fits in `kMaxSize`
63     // chars. The `+ 1` ensures that a `aNameString` with length
64     // longer than `kMaxSize` is correctly rejected (returning error
65     // `kErrorInvalidArgs`).
66     // Additionally, no minimum length is verified in order to ensure
67     // backwards compatibility with previous versions that allowed
68     // a zero-length name.
69 
70     Error    error;
71     NameData data(aNameString, kMaxSize + 1);
72 
73     VerifyOrExit(IsValidUtf8String(aNameString), error = kErrorInvalidArgs);
74 
75     error = Set(data);
76 
77 exit:
78     return error;
79 }
80 
Set(const NameData & aNameData)81 Error NetworkName::Set(const NameData &aNameData)
82 {
83     Error    error  = kErrorNone;
84     NameData data   = aNameData;
85     uint8_t  newLen = static_cast<uint8_t>(StringLength(data.GetBuffer(), data.GetLength()));
86 
87     VerifyOrExit(newLen <= kMaxSize, error = kErrorInvalidArgs);
88 
89     data.SetLength(newLen);
90 
91     // Ensure the new name does not match the current one.
92     if (data.MatchesBytesIn(m8) && m8[newLen] == '\0')
93     {
94         ExitNow(error = kErrorAlready);
95     }
96 
97     data.CopyBytesTo(m8);
98     m8[newLen] = '\0';
99 
100 exit:
101     return error;
102 }
103 
operator ==(const NetworkName & aOther) const104 bool NetworkName::operator==(const NetworkName &aOther) const { return GetAsData() == aOther.GetAsData(); }
105 
NetworkNameManager(Instance & aInstance)106 NetworkNameManager::NetworkNameManager(Instance &aInstance)
107     : InstanceLocator(aInstance)
108 {
109     IgnoreError(SetNetworkName(NetworkName::kNetworkNameInit));
110 
111 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
112     IgnoreError(SetDomainName(NetworkName::kDomainNameInit));
113 #endif
114 }
115 
SetNetworkName(const char * aNameString)116 Error NetworkNameManager::SetNetworkName(const char *aNameString)
117 {
118     return SignalNetworkNameChange(mNetworkName.Set(aNameString));
119 }
120 
SetNetworkName(const NameData & aNameData)121 Error NetworkNameManager::SetNetworkName(const NameData &aNameData)
122 {
123     return SignalNetworkNameChange(mNetworkName.Set(aNameData));
124 }
125 
SignalNetworkNameChange(Error aError)126 Error NetworkNameManager::SignalNetworkNameChange(Error aError)
127 {
128     switch (aError)
129     {
130     case kErrorNone:
131         Get<Notifier>().Signal(kEventThreadNetworkNameChanged);
132         break;
133 
134     case kErrorAlready:
135         Get<Notifier>().SignalIfFirst(kEventThreadNetworkNameChanged);
136         aError = kErrorNone;
137         break;
138 
139     default:
140         break;
141     }
142 
143     return aError;
144 }
145 
146 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
SetDomainName(const char * aNameString)147 Error NetworkNameManager::SetDomainName(const char *aNameString)
148 {
149     Error error = mDomainName.Set(aNameString);
150 
151     return (error == kErrorAlready) ? kErrorNone : error;
152 }
153 
SetDomainName(const NameData & aNameData)154 Error NetworkNameManager::SetDomainName(const NameData &aNameData)
155 {
156     Error error = mDomainName.Set(aNameData);
157 
158     return (error == kErrorAlready) ? kErrorNone : error;
159 }
160 
IsDefaultDomainNameSet(void) const161 bool NetworkNameManager::IsDefaultDomainNameSet(void) const
162 {
163     return StringMatch(mDomainName.GetAsCString(), NetworkName::kDomainNameInit);
164 }
165 #endif // (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
166 
167 } // namespace MeshCoP
168 } // namespace ot
169