1 /*
2  *    Copyright (c) 2018, 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" AND
17  *    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  *    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20  *    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  *    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  *    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  *    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 /**
29  * @file
30  *   This file implements general thread device required Spinel interface to the OpenThread stack.
31  */
32 
33 #include "ncp_base.hpp"
34 
35 namespace ot {
36 namespace Ncp {
37 
AreHandlerEntriesSorted(const HandlerEntry * aHandlerEntries,size_t aSize)38 constexpr bool NcpBase::AreHandlerEntriesSorted(const HandlerEntry *aHandlerEntries, size_t aSize)
39 {
40     return aSize < 2 ? true
41                      : ((aHandlerEntries[aSize - 1].mKey > aHandlerEntries[aSize - 2].mKey) &&
42                         AreHandlerEntriesSorted(aHandlerEntries, aSize - 1));
43 }
44 
FindGetPropertyHandler(spinel_prop_key_t aKey)45 NcpBase::PropertyHandler NcpBase::FindGetPropertyHandler(spinel_prop_key_t aKey)
46 {
47 #define OT_NCP_GET_HANDLER_ENTRY(aPropertyName)                   \
48     {                                                             \
49         aPropertyName, &NcpBase::HandlePropertyGet<aPropertyName> \
50     }
51 
52     constexpr static HandlerEntry sHandlerEntries[] = {
53         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_LAST_STATUS),
54         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PROTOCOL_VERSION),
55         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NCP_VERSION),
56         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_INTERFACE_TYPE),
57         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_VENDOR_ID),
58         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CAPS),
59         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_INTERFACE_COUNT),
60         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_POWER_STATE),
61         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_HWADDR),
62         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_LOCK),
63         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_HOST_POWER_STATE),
64         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MCU_POWER_STATE),
65         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PHY_ENABLED),
66         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PHY_CHAN),
67         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PHY_CHAN_SUPPORTED),
68         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PHY_FREQ),
69         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PHY_CCA_THRESHOLD),
70         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PHY_TX_POWER),
71         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PHY_RSSI),
72         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PHY_RX_SENSITIVITY),
73 #if OPENTHREAD_MTD || OPENTHREAD_FTD
74         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PHY_PCAP_ENABLED),
75 #endif
76         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PHY_CHAN_PREFERRED),
77         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PHY_FEM_LNA_GAIN),
78         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_PHY_REGION_CODE),
79         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_SCAN_STATE),
80         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_SCAN_MASK),
81         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_SCAN_PERIOD),
82         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_15_4_LADDR),
83         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_15_4_SADDR),
84         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_15_4_PANID),
85         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_RAW_STREAM_ENABLED),
86         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_PROMISCUOUS_MODE),
87 #if OPENTHREAD_MTD || OPENTHREAD_FTD
88         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_DATA_POLL_PERIOD),
89         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NET_SAVED),
90         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NET_IF_UP),
91         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NET_STACK_UP),
92         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NET_ROLE),
93         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NET_NETWORK_NAME),
94         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NET_XPANID),
95         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NET_NETWORK_KEY),
96         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER),
97         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NET_PARTITION_ID),
98         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING),
99         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME),
100 #if OPENTHREAD_FTD
101         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NET_PSKC),
102 #endif
103         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_LEADER_ADDR),
104         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_PARENT),
105 #if OPENTHREAD_FTD
106         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_CHILD_TABLE),
107 #endif
108         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_LEADER_RID),
109 #if OPENTHREAD_FTD
110         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_LEADER_WEIGHT),
111         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT),
112 #endif
113 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
114         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_NETWORK_DATA),
115 #endif
116         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_NETWORK_DATA_VERSION),
117 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
118         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_STABLE_NETWORK_DATA),
119 #endif
120         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_STABLE_NETWORK_DATA_VERSION),
121         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ON_MESH_NETS),
122         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_OFF_MESH_ROUTES),
123         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ASSISTING_PORTS),
124         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE),
125         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_MODE),
126         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_IPV6_LL_ADDR),
127         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_IPV6_ML_ADDR),
128         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_IPV6_ML_PREFIX),
129         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_IPV6_ADDRESS_TABLE),
130         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_IPV6_ROUTE_TABLE),
131         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD),
132         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE),
133         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD_MODE),
134 #if OPENTHREAD_CONFIG_JOINER_ENABLE
135         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_JOINER_STATE),
136 #endif
137 #if OPENTHREAD_FTD
138 #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
139         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_STATE),
140         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS),
141         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_PROVISIONING_URL),
142         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_SESSION_ID),
143 #endif
144 #endif // OPENTHREAD_FTD
145 #if OPENTHREAD_CONFIG_JOINER_ENABLE
146         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_JOINER_DISCERNER),
147 #endif
148 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
149         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE),
150         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SERVER_SERVICES),
151 #endif
152         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SERVER_LEADER_SERVICES),
153 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
154 #if OPENTHREAD_RADIO
155         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_RCP_API_VERSION),
156         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_RCP_MIN_HOST_API_VERSION),
157 #endif
158 #if OPENTHREAD_MTD || OPENTHREAD_FTD
159         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_PKT_TOTAL),
160         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_PKT_ACK_REQ),
161         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_PKT_ACKED),
162         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_PKT_NO_ACK_REQ),
163         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_PKT_DATA),
164         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_PKT_DATA_POLL),
165         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_PKT_BEACON),
166         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_PKT_BEACON_REQ),
167         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_PKT_OTHER),
168         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_PKT_RETRY),
169         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_ERR_CCA),
170         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_PKT_UNICAST),
171         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_PKT_BROADCAST),
172         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_ERR_ABORT),
173         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_PKT_TOTAL),
174         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_PKT_DATA),
175         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_PKT_DATA_POLL),
176         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_PKT_BEACON),
177         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_PKT_BEACON_REQ),
178         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_PKT_OTHER),
179         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_PKT_FILT_WL),
180         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_PKT_FILT_DA),
181         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_ERR_EMPTY),
182         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_ERR_UKWN_NBR),
183         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_ERR_NVLD_SADDR),
184         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_ERR_SECURITY),
185         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_ERR_BAD_FCS),
186         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_ERR_OTHER),
187         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_PKT_DUP),
188         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_PKT_UNICAST),
189         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_PKT_BROADCAST),
190         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_IP_SEC_TOTAL),
191         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_IP_INSEC_TOTAL),
192         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_IP_DROPPED),
193         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_IP_SEC_TOTAL),
194         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_IP_INSEC_TOTAL),
195         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_IP_DROPPED),
196         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_TX_SPINEL_TOTAL),
197         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_SPINEL_TOTAL),
198         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RX_SPINEL_ERR),
199         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_IP_TX_SUCCESS),
200         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_IP_RX_SUCCESS),
201         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_IP_TX_FAILURE),
202         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_IP_RX_FAILURE),
203         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MSG_BUFFER_COUNTERS),
204         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_ALL_MAC_COUNTERS),
205         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_MLE_COUNTERS),
206         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_ALL_IP_COUNTERS),
207 #if OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE
208         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CNTR_MAC_RETRY_HISTOGRAM),
209 #endif
210 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
211 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
212         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_RCP_TIMESTAMP),
213 #endif
214 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
215         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_RCP_CSL_ACCURACY),
216 #endif
217 #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
218         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_RCP_CSL_UNCERTAINTY),
219 #endif
220 #if OPENTHREAD_MTD || OPENTHREAD_FTD
221         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_UNSOL_UPDATE_FILTER),
222         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_UNSOL_UPDATE_LIST),
223 #if OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
224         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_JAM_DETECT_ENABLE),
225         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_JAM_DETECTED),
226         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD),
227         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_JAM_DETECT_WINDOW),
228         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_JAM_DETECT_BUSY),
229         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_JAM_DETECT_HISTORY_BITMAP),
230 #endif
231 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
232         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_INTERVAL),
233         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MONITOR_RSSI_THRESHOLD),
234         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_WINDOW),
235         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MONITOR_SAMPLE_COUNT),
236         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MONITOR_CHANNEL_OCCUPANCY),
237 #endif
238 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
239 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
240         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_RADIO_CAPS),
241 #endif
242 #if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
243         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_RADIO_COEX_METRICS),
244         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_RADIO_COEX_ENABLE),
245 #endif
246 #if OPENTHREAD_MTD || OPENTHREAD_FTD
247 #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
248         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_ALLOWLIST),
249         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_ALLOWLIST_ENABLED),
250         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_EXTENDED_ADDR),
251 #endif
252 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
253 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
254         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_SRC_MATCH_ENABLED),
255 #endif
256 #if OPENTHREAD_MTD || OPENTHREAD_FTD
257 #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
258         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_DENYLIST),
259         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_DENYLIST_ENABLED),
260         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_FIXED_RSS),
261 #endif
262         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_CCA_FAILURE_RATE),
263         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_MAX_RETRY_NUMBER_DIRECT),
264 #if OPENTHREAD_FTD
265         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_MAC_MAX_RETRY_NUMBER_INDIRECT),
266 #endif
267         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_CHILD_TIMEOUT),
268         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_RLOC16),
269 #if OPENTHREAD_FTD
270         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ROUTER_UPGRADE_THRESHOLD),
271         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY),
272         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_NETWORK_ID_TIMEOUT),
273 #endif
274         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU),
275 #if OPENTHREAD_FTD
276         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED),
277         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD),
278         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER),
279         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID),
280 #endif
281         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_NEIGHBOR_TABLE),
282 #if OPENTHREAD_FTD
283         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_CHILD_COUNT_MAX),
284 #endif
285         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_LEADER_NETWORK_DATA),
286         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_STABLE_LEADER_NETWORK_DATA),
287 #if OPENTHREAD_FTD
288 #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
289         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_COMMISSIONER_ENABLED),
290 #endif
291 #endif
292         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_DISCOVERY_SCAN_JOINER_FLAG),
293         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING),
294         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_DISCOVERY_SCAN_PANID),
295 #if OPENTHREAD_FTD
296 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
297         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_STEERING_DATA),
298 #endif
299         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ROUTER_TABLE),
300 #endif // OPENTHREAD_FTD
301         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ACTIVE_DATASET),
302         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_PENDING_DATASET),
303 #if OPENTHREAD_FTD
304         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_CHILD_TABLE_ADDRESSES),
305 #endif
306         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_NEIGHBOR_TABLE_ERROR_RATES),
307 #if OPENTHREAD_FTD
308         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ADDRESS_CACHE_TABLE),
309         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_NEW_DATASET),
310 #endif
311 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
312         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_CSL_PERIOD),
313         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_CSL_TIMEOUT),
314         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_CSL_CHANNEL),
315 #endif
316 #if OPENTHREAD_FTD
317 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
318         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_DOMAIN_NAME),
319 #endif
320 #if OPENTHREAD_CONFIG_DUA_ENABLE
321         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_DUA_ID),
322 #endif
323 #endif // OPENTHREAD_FTD
324 #if (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
325         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_PRIMARY),
326 #endif
327 #if OPENTHREAD_FTD
328 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
329         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_STATE),
330         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_CONFIG),
331         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_REGISTRATION_JITTER),
332 #endif
333 #if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE
334         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL),
335         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_DELAY),
336         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_SUPPORTED_CHANNELS),
337         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_FAVORED_CHANNELS),
338         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_CHANNEL_SELECT),
339         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_ENABLED),
340         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL),
341 #endif
342 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
343         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_THREAD_NETWORK_TIME),
344         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_TIME_SYNC_PERIOD),
345         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_TIME_SYNC_XTAL_THRESHOLD),
346 #endif
347         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHILD_SUPERVISION_INTERVAL),
348         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_CHILD_SUPERVISION_CHECK_TIMEOUT),
349 #endif // OPENTHREAD_FTD
350 #if OPENTHREAD_PLATFORM_POSIX
351         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_RCP_VERSION),
352 #endif
353 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
354         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SLAAC_ENABLED),
355 #endif
356         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SUPPORTED_RADIO_LINKS),
357 #if OPENTHREAD_CONFIG_MULTI_RADIO
358         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_NEIGHBOR_TABLE_MULTI_RADIO_INFO),
359 #endif
360 #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
361         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_LEASE_INTERVAL),
362         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_KEY_LEASE_INTERVAL),
363         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_INFO),
364         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_NAME),
365         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_ADDRESSES),
366         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_SERVICES),
367 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
368         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_SERVICE_KEY_ENABLED),
369 #endif
370 #endif
371 
372 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
373         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_DEBUG_TEST_ASSERT),
374         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_DEBUG_NCP_LOG_LEVEL),
375         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_DEBUG_TEST_WATCHDOG),
376         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_DEBUG_LOG_TIMESTAMP_BASE),
377 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD)
378         OT_NCP_GET_HANDLER_ENTRY(SPINEL_PROP_DEBUG_TREL_TEST_MODE_ENABLE),
379 #endif
380     };
381 
382 #undef OT_NCP_GET_HANDLER_ENTRY
383 
384     static_assert(AreHandlerEntriesSorted(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries)),
385                   "NCP property getter entries not sorted!");
386 
387     return FindPropertyHandler(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries), aKey);
388 }
389 
FindSetPropertyHandler(spinel_prop_key_t aKey)390 NcpBase::PropertyHandler NcpBase::FindSetPropertyHandler(spinel_prop_key_t aKey)
391 {
392 #define OT_NCP_SET_HANDLER_ENTRY(aPropertyName)                   \
393     {                                                             \
394         aPropertyName, &NcpBase::HandlePropertySet<aPropertyName> \
395     }
396 
397     constexpr static HandlerEntry sHandlerEntries[] = {
398         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_POWER_STATE),
399 #if OPENTHREAD_CONFIG_NCP_ENABLE_MCU_POWER_STATE_CONTROL
400         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MCU_POWER_STATE),
401 #endif
402 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
403         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_PHY_ENABLED),
404 #endif
405         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_PHY_CHAN),
406 #if OPENTHREAD_MTD || OPENTHREAD_FTD
407         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_PHY_CHAN_SUPPORTED),
408 #endif
409         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_PHY_CCA_THRESHOLD),
410         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_PHY_TX_POWER),
411 #if OPENTHREAD_MTD || OPENTHREAD_FTD
412         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_PHY_PCAP_ENABLED),
413 #endif
414         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_PHY_FEM_LNA_GAIN),
415         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_PHY_CHAN_MAX_POWER),
416         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_PHY_REGION_CODE),
417 #if OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
418         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_PHY_CALIBRATED_POWER),
419         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_PHY_CHAN_TARGET_POWER),
420 #endif
421         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_SCAN_STATE),
422         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_SCAN_MASK),
423         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_SCAN_PERIOD),
424         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_15_4_LADDR),
425 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
426         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_15_4_SADDR),
427 #endif
428         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_15_4_PANID),
429         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_RAW_STREAM_ENABLED),
430         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_PROMISCUOUS_MODE),
431 #if OPENTHREAD_MTD || OPENTHREAD_FTD
432         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_DATA_POLL_PERIOD),
433         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_NET_IF_UP),
434         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_NET_STACK_UP),
435         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_NET_ROLE),
436         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_NET_NETWORK_NAME),
437         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_NET_XPANID),
438         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_NET_NETWORK_KEY),
439         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_NET_KEY_SEQUENCE_COUNTER),
440 #if OPENTHREAD_FTD
441 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
442         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_NET_PARTITION_ID),
443 #endif
444 #endif
445         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_NET_REQUIRE_JOIN_EXISTING),
446         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_NET_KEY_SWITCH_GUARDTIME),
447 #if OPENTHREAD_FTD
448         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_NET_PSKC),
449         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_LOCAL_LEADER_WEIGHT),
450 #endif
451         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ASSISTING_PORTS),
452 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
453         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ALLOW_LOCAL_NET_DATA_CHANGE),
454 #endif
455         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_MODE),
456         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_IPV6_ML_PREFIX),
457         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD),
458         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_IPV6_ICMP_PING_OFFLOAD_MODE),
459         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_STREAM_NET),
460         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_STREAM_NET_INSECURE),
461 #if OPENTHREAD_CONFIG_JOINER_ENABLE
462         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_JOINER_COMMISSIONING),
463 #endif
464 #if OPENTHREAD_FTD
465 #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
466         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_STATE),
467         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_PROVISIONING_URL),
468 #endif
469 #endif // OPENTHREAD_FTD
470 #if OPENTHREAD_CONFIG_JOINER_ENABLE
471         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_JOINER_DISCERNER),
472 #endif
473 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
474         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SERVER_ALLOW_LOCAL_DATA_CHANGE),
475 #endif
476         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CNTR_RESET),
477         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CNTR_ALL_MAC_COUNTERS),
478         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CNTR_MLE_COUNTERS),
479         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CNTR_ALL_IP_COUNTERS),
480 #if OPENTHREAD_CONFIG_MAC_RETRY_SUCCESS_HISTOGRAM_ENABLE
481         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CNTR_MAC_RETRY_HISTOGRAM),
482 #endif
483 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
484 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
485         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_RCP_MAC_KEY),
486         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_RCP_MAC_FRAME_COUNTER),
487 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE
488         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_RCP_ENH_ACK_PROBING),
489 #endif
490 #endif // OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
491 #if OPENTHREAD_MTD || OPENTHREAD_FTD
492         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_UNSOL_UPDATE_FILTER),
493 #if OPENTHREAD_CONFIG_JAM_DETECTION_ENABLE
494         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_JAM_DETECT_ENABLE),
495         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_JAM_DETECT_RSSI_THRESHOLD),
496         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_JAM_DETECT_WINDOW),
497         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_JAM_DETECT_BUSY),
498 #endif
499 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
500 
501 #if OPENTHREAD_CONFIG_PLATFORM_RADIO_COEX_ENABLE
502         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_RADIO_COEX_ENABLE),
503 #endif
504 #if OPENTHREAD_MTD || OPENTHREAD_FTD
505 #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
506         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_ALLOWLIST),
507         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_ALLOWLIST_ENABLED),
508 #endif
509 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
510 
511 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
512         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_SRC_MATCH_ENABLED),
513         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES),
514         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES),
515 #endif
516 
517 #if OPENTHREAD_MTD || OPENTHREAD_FTD
518 #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
519         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_DENYLIST),
520         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_DENYLIST_ENABLED),
521         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_FIXED_RSS),
522 #endif
523         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_MAX_RETRY_NUMBER_DIRECT),
524 #if OPENTHREAD_FTD
525         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MAC_MAX_RETRY_NUMBER_INDIRECT),
526 #endif
527         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_CHILD_TIMEOUT),
528 #if OPENTHREAD_FTD
529         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ROUTER_UPGRADE_THRESHOLD),
530         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_CONTEXT_REUSE_DELAY),
531         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_NETWORK_ID_TIMEOUT),
532 #endif
533         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_RLOC16_DEBUG_PASSTHRU),
534 #if OPENTHREAD_FTD
535         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ROUTER_ROLE_ENABLED),
536         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ROUTER_DOWNGRADE_THRESHOLD),
537         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ROUTER_SELECTION_JITTER),
538         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_PREFERRED_ROUTER_ID),
539         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_CHILD_COUNT_MAX),
540 #endif
541         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_DISCOVERY_SCAN_JOINER_FLAG),
542         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_DISCOVERY_SCAN_ENABLE_FILTERING),
543         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_DISCOVERY_SCAN_PANID),
544 #if OPENTHREAD_FTD
545 #if OPENTHREAD_CONFIG_MLE_STEERING_DATA_SET_OOB_ENABLE
546         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_STEERING_DATA),
547 #endif
548 #endif
549         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_ACTIVE_DATASET),
550         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_PENDING_DATASET),
551         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_MGMT_SET_ACTIVE_DATASET),
552         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_MGMT_SET_PENDING_DATASET),
553 #if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
554         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_UDP_FORWARD_STREAM),
555 #endif
556         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_MGMT_GET_ACTIVE_DATASET),
557         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_MGMT_GET_PENDING_DATASET),
558 #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
559         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_CSL_PERIOD),
560         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_CSL_TIMEOUT),
561         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_CSL_CHANNEL),
562 #endif
563 #if OPENTHREAD_FTD && (OPENTHREAD_CONFIG_THREAD_VERSION >= OT_THREAD_VERSION_1_2)
564         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_DOMAIN_NAME),
565 #endif
566 #if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
567         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_LINK_METRICS_QUERY),
568         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_LINK_METRICS_PROBE),
569         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_LINK_METRICS_MGMT_ENH_ACK),
570         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_LINK_METRICS_MGMT_FORWARD),
571 #endif
572 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_TMF_PROXY_MLR_ENABLE && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
573         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_MLR_REQUEST),
574 #endif
575 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_DUA_ENABLE
576         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_DUA_ID),
577 #endif
578 #if OPENTHREAD_FTD
579 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
580         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_STATE),
581         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_CONFIG),
582         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_REGISTER),
583         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_THREAD_BACKBONE_ROUTER_LOCAL_REGISTRATION_JITTER),
584 #endif
585 #if OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
586         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_ANNOUNCE_BEGIN),
587         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_ENERGY_SCAN),
588         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_PAN_ID_QUERY),
589         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_MGMT_GET),
590         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_MGMT_SET),
591 #endif
592 #if OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE
593         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_NEW_CHANNEL),
594         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_DELAY),
595         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_SUPPORTED_CHANNELS),
596         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_FAVORED_CHANNELS),
597 #if OPENTHREAD_CONFIG_CHANNEL_MONITOR_ENABLE
598         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_CHANNEL_SELECT),
599 #endif
600         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_ENABLED),
601         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CHANNEL_MANAGER_AUTO_SELECT_INTERVAL),
602 #endif // OPENTHREAD_CONFIG_CHANNEL_MANAGER_ENABLE
603 #if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
604         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_TIME_SYNC_PERIOD),
605         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_TIME_SYNC_XTAL_THRESHOLD),
606 #endif
607         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CHILD_SUPERVISION_INTERVAL),
608         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_CHILD_SUPERVISION_CHECK_TIMEOUT),
609 #endif // OPENTHREAD_FTD
610 #if OPENTHREAD_CONFIG_IP6_SLAAC_ENABLE
611         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SLAAC_ENABLED),
612 #endif
613 #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
614         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_START),
615         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_LEASE_INTERVAL),
616         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_KEY_LEASE_INTERVAL),
617         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_NAME),
618         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_ADDRESSES),
619         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_REMOVE),
620         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_HOST_SERVICES_CLEAR),
621 #if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
622         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_SERVICE_KEY_ENABLED),
623 #endif
624 #endif
625 #endif // OPENTHREAD_MTD || OPENTHREAD_FTD
626 #if OPENTHREAD_CONFIG_LOG_LEVEL_DYNAMIC_ENABLE
627         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_DEBUG_NCP_LOG_LEVEL),
628 #endif
629         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_DEBUG_LOG_TIMESTAMP_BASE),
630 #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE && (OPENTHREAD_FTD || OPENTHREAD_MTD)
631         OT_NCP_SET_HANDLER_ENTRY(SPINEL_PROP_DEBUG_TREL_TEST_MODE_ENABLE),
632 #endif
633     };
634 
635 #undef OT_NCP_SET_HANDLER_ENTRY
636 
637     static_assert(AreHandlerEntriesSorted(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries)),
638                   "NCP property setter entries not sorted!");
639 
640     return FindPropertyHandler(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries), aKey);
641 }
642 
FindInsertPropertyHandler(spinel_prop_key_t aKey)643 NcpBase::PropertyHandler NcpBase::FindInsertPropertyHandler(spinel_prop_key_t aKey)
644 {
645 #define OT_NCP_INSERT_HANDLER_ENTRY(aPropertyName)                   \
646     {                                                                \
647         aPropertyName, &NcpBase::HandlePropertyInsert<aPropertyName> \
648     }
649 
650     constexpr static HandlerEntry sHandlerEntries[] = {
651 #if OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE
652         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_PHY_CALIBRATED_POWER),
653 #endif
654 #if OPENTHREAD_MTD || OPENTHREAD_FTD
655 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
656         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_THREAD_ON_MESH_NETS),
657         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_THREAD_OFF_MESH_ROUTES),
658 #endif
659         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_THREAD_ASSISTING_PORTS),
660         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_IPV6_ADDRESS_TABLE),
661         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE),
662 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
663         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS),
664 #endif
665 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
666         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_SERVER_SERVICES),
667 #endif
668 #endif // #if OPENTHREAD_MTD || OPENTHREAD_FTD
669         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_UNSOL_UPDATE_FILTER),
670 #if (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
671         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_MAC_ALLOWLIST),
672 #endif
673 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
674         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES),
675         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES),
676 #endif
677 #if (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
678         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_MAC_DENYLIST),
679         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_MAC_FIXED_RSS),
680 #endif
681 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
682         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_THREAD_JOINERS),
683 #endif
684 #if OPENTHREAD_FTD || OPENTHREAD_MTD
685 #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
686         OT_NCP_INSERT_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_SERVICES),
687 #endif
688 #endif
689     };
690 
691 #undef OT_NCP_INSERT_HANDLER_ENTRY
692 
693     static_assert(AreHandlerEntriesSorted(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries)),
694                   "NCP property setter entries not sorted!");
695 
696     return FindPropertyHandler(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries), aKey);
697 }
698 
FindRemovePropertyHandler(spinel_prop_key_t aKey)699 NcpBase::PropertyHandler NcpBase::FindRemovePropertyHandler(spinel_prop_key_t aKey)
700 {
701 #define OT_NCP_REMOVE_HANDLER_ENTRY(aPropertyName)                   \
702     {                                                                \
703         aPropertyName, &NcpBase::HandlePropertyRemove<aPropertyName> \
704     }
705 
706     constexpr static HandlerEntry sHandlerEntries[] = {
707 #if OPENTHREAD_MTD || OPENTHREAD_FTD
708 #if OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE
709         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_THREAD_ON_MESH_NETS),
710         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_THREAD_OFF_MESH_ROUTES),
711 #endif
712         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_THREAD_ASSISTING_PORTS),
713         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_IPV6_ADDRESS_TABLE),
714         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_IPV6_MULTICAST_ADDRESS_TABLE),
715 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_COMMISSIONER_ENABLE
716         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_MESHCOP_COMMISSIONER_JOINERS),
717 #endif
718 #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE
719         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_SERVER_SERVICES),
720 #endif
721 #endif // #if OPENTHREAD_MTD || OPENTHREAD_FTD
722         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_UNSOL_UPDATE_FILTER),
723 #if (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
724         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_MAC_ALLOWLIST),
725 #endif
726 #if OPENTHREAD_RADIO || OPENTHREAD_CONFIG_LINK_RAW_ENABLE
727         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_MAC_SRC_MATCH_SHORT_ADDRESSES),
728         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_MAC_SRC_MATCH_EXTENDED_ADDRESSES),
729 #endif
730 #if (OPENTHREAD_MTD || OPENTHREAD_FTD) && OPENTHREAD_CONFIG_MAC_FILTER_ENABLE
731         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_MAC_DENYLIST),
732         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_MAC_FIXED_RSS),
733 #endif
734 #if OPENTHREAD_FTD
735         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_THREAD_ACTIVE_ROUTER_IDS),
736 #endif
737 #if OPENTHREAD_FTD || OPENTHREAD_MTD
738 #if OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE
739         OT_NCP_REMOVE_HANDLER_ENTRY(SPINEL_PROP_SRP_CLIENT_SERVICES),
740 #endif
741 #endif
742     };
743 
744 #undef OT_NCP_REMOVE_HANDLER_ENTRY
745 
746     static_assert(AreHandlerEntriesSorted(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries)),
747                   "NCP property setter entries not sorted!");
748 
749     return FindPropertyHandler(sHandlerEntries, OT_ARRAY_LENGTH(sHandlerEntries), aKey);
750 }
751 
FindPropertyHandler(const HandlerEntry * aHandlerEntries,size_t aSize,spinel_prop_key_t aKey)752 NcpBase::PropertyHandler NcpBase::FindPropertyHandler(const HandlerEntry *aHandlerEntries,
753                                                       size_t              aSize,
754                                                       spinel_prop_key_t   aKey)
755 {
756     size_t l = 0;
757 
758     OT_ASSERT(aSize > 0);
759 
760     for (size_t r = aSize - 1; l < r;)
761     {
762         size_t m = (l + r) / 2;
763 
764         if (aHandlerEntries[m].mKey < aKey)
765         {
766             l = m + 1;
767         }
768         else
769         {
770             r = m;
771         }
772     }
773 
774     return aHandlerEntries[l].mKey == aKey ? aHandlerEntries[l].mHandler : nullptr;
775 }
776 
777 } // namespace Ncp
778 } // namespace ot
779