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 <openthread/platform/alarm-milli.h>
30
31 #include "nexus_node.hpp"
32 #include "nexus_settings.hpp"
33
34 namespace ot {
35 namespace Nexus {
36
37 //---------------------------------------------------------------------------------------------------------------------
38 // otPlatSettings APIs
39
40 extern "C" {
41
otPlatSettingsInit(otInstance *,const uint16_t *,uint16_t)42 void otPlatSettingsInit(otInstance *, const uint16_t *, uint16_t) {}
otPlatSettingsDeinit(otInstance *)43 void otPlatSettingsDeinit(otInstance *) {}
44
otPlatSettingsGet(otInstance * aInstance,uint16_t aKey,int aIndex,uint8_t * aValue,uint16_t * aValueLength)45 otError otPlatSettingsGet(otInstance *aInstance, uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength)
46 {
47 return AsNode(aInstance).mSettings.Get(aKey, aIndex, aValue, aValueLength);
48 }
49
otPlatSettingsSet(otInstance * aInstance,uint16_t aKey,const uint8_t * aValue,uint16_t aValueLength)50 otError otPlatSettingsSet(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
51 {
52 return AsNode(aInstance).mSettings.SetOrAdd(Settings::kSet, aKey, aValue, aValueLength);
53 }
54
otPlatSettingsAdd(otInstance * aInstance,uint16_t aKey,const uint8_t * aValue,uint16_t aValueLength)55 otError otPlatSettingsAdd(otInstance *aInstance, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
56 {
57 return AsNode(aInstance).mSettings.SetOrAdd(Settings::kAdd, aKey, aValue, aValueLength);
58 }
59
otPlatSettingsDelete(otInstance * aInstance,uint16_t aKey,int aIndex)60 otError otPlatSettingsDelete(otInstance *aInstance, uint16_t aKey, int aIndex)
61 {
62 return AsNode(aInstance).mSettings.Delete(aKey, aIndex);
63 }
64
otPlatSettingsWipe(otInstance * aInstance)65 void otPlatSettingsWipe(otInstance *aInstance) { AsNode(aInstance).mSettings.Wipe(); }
66
67 } // extern "C"
68
69 //---------------------------------------------------------------------------------------------------------------------
70 // Settings
71
Get(uint16_t aKey,int aIndex,uint8_t * aValue,uint16_t * aValueLength) const72 Error Settings::Get(uint16_t aKey, int aIndex, uint8_t *aValue, uint16_t *aValueLength) const
73 {
74 Error error = kErrorNone;
75 const Entry *entry;
76 const Entry::Value *value;
77 IndexMatcher IndexMatcher(aIndex);
78
79 entry = mEntries.FindMatching(aKey);
80 VerifyOrExit(entry != nullptr, error = kErrorNotFound);
81
82 value = entry->mValues.FindMatching(IndexMatcher);
83 VerifyOrExit(value != nullptr, error = kErrorNotFound);
84
85 if (aValueLength != nullptr)
86 {
87 uint16_t size = *aValueLength;
88 uint16_t length = value->mData.GetLength();
89
90 *aValueLength = length;
91
92 if (aValue != nullptr)
93 {
94 memcpy(aValue, value->mData.GetBytes(), Min(size, length));
95 }
96 }
97
98 exit:
99 return error;
100 }
101
SetOrAdd(SetAddMode aMode,uint16_t aKey,const uint8_t * aValue,uint16_t aValueLength)102 Error Settings::SetOrAdd(SetAddMode aMode, uint16_t aKey, const uint8_t *aValue, uint16_t aValueLength)
103 {
104 Entry *entry;
105 Entry::Value *value;
106
107 entry = mEntries.FindMatching(aKey);
108
109 if (entry == nullptr)
110 {
111 entry = Settings::Entry::Allocate();
112 VerifyOrQuit(entry != nullptr);
113 entry->mKey = aKey;
114 mEntries.Push(*entry);
115 }
116
117 value = Entry::Value::Allocate();
118 VerifyOrQuit(value != nullptr);
119 SuccessOrQuit(value->mData.SetFrom(aValue, aValueLength));
120
121 if (aMode == kSet)
122 {
123 entry->mValues.Clear();
124 }
125
126 entry->mValues.Push(*value);
127
128 return kErrorNone;
129 }
130
Delete(uint16_t aKey,int aIndex)131 Error Settings::Delete(uint16_t aKey, int aIndex)
132 {
133 Error error = kErrorNone;
134 Entry *entry;
135 Entry::Value *preValue;
136
137 entry = mEntries.FindMatching(aKey);
138 VerifyOrExit(entry != nullptr, error = kErrorNotFound);
139
140 if (aIndex < 0)
141 {
142 mEntries.RemoveMatching(aKey);
143 }
144 else
145 {
146 IndexMatcher indexMatcher(aIndex);
147 OwnedPtr<Entry::Value> valuePtr;
148
149 valuePtr = entry->mValues.RemoveMatching(indexMatcher);
150 VerifyOrExit(valuePtr != nullptr, error = kErrorNotFound);
151 }
152
153 exit:
154 return error;
155 }
156
Wipe(void)157 void Settings::Wipe(void) { mEntries.Clear(); }
158
159 } // namespace Nexus
160 } // namespace ot
161