/src/wpantund/src/ncp-spinel/SpinelNCPInstance.h
Line | Count | Source |
1 | | /* |
2 | | * |
3 | | * Copyright (c) 2016 Nest Labs, Inc. |
4 | | * All rights reserved. |
5 | | * |
6 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
7 | | * you may not use this file except in compliance with the License. |
8 | | * You may obtain a copy of the License at |
9 | | * |
10 | | * http://www.apache.org/licenses/LICENSE-2.0 |
11 | | * |
12 | | * Unless required by applicable law or agreed to in writing, software |
13 | | * distributed under the License is distributed on an "AS IS" BASIS, |
14 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
15 | | * See the License for the specific language governing permissions and |
16 | | * limitations under the License. |
17 | | * |
18 | | */ |
19 | | |
20 | | #ifndef __wpantund__SpinelNCPInstance__ |
21 | | #define __wpantund__SpinelNCPInstance__ |
22 | | |
23 | | #include "NCPInstanceBase.h" |
24 | | #include "SpinelNCPControlInterface.h" |
25 | | #include "SpinelNCPThreadDataset.h" |
26 | | #include "SpinelNCPTaskSendCommand.h" |
27 | | #include "nlpt.h" |
28 | | #include "SocketWrapper.h" |
29 | | #include "SocketAsyncOp.h" |
30 | | #include "ValueMap.h" |
31 | | |
32 | | #include <queue> |
33 | | #include <set> |
34 | | #include <map> |
35 | | #include <errno.h> |
36 | | #include "spinel.h" |
37 | | |
38 | | #include "SpinelNCPVendorCustom.h" |
39 | | |
40 | | WPANTUND_DECLARE_NCPINSTANCE_PLUGIN(spinel, SpinelNCPInstance); |
41 | | |
42 | 2.96M | #define EVENT_NCP_MARKER 0xAB000000 |
43 | 38.1k | #define EVENT_NCP(x) ((x)|EVENT_NCP_MARKER) |
44 | | #define IS_EVENT_FROM_NCP(x) (((x)&~0xFFFFFF) == EVENT_NCP_MARKER) |
45 | | |
46 | | |
47 | 2.75M | #define EVENT_NCP_RESET (0xFF0000|EVENT_NCP_MARKER) |
48 | 144k | #define EVENT_NCP_PROP_VALUE_IS (0xFF0001|EVENT_NCP_MARKER) |
49 | 22.4k | #define EVENT_NCP_PROP_VALUE_INSERTED (0xFF0002|EVENT_NCP_MARKER) |
50 | 798 | #define EVENT_NCP_PROP_VALUE_REMOVED (0xFF0003|EVENT_NCP_MARKER) |
51 | | |
52 | | #define NCP_FRAMING_OVERHEAD 3 |
53 | | |
54 | 43.9k | #define CONTROL_REQUIRE_EMPTY_OUTBOUND_BUFFER_WITHIN(seconds, error_label) do { \ |
55 | 43.9k | EH_WAIT_UNTIL_WITH_TIMEOUT(seconds, (GetInstance(this)->mOutboundBufferLen <= 0) && GetInstance(this)->mOutboundCallback.empty()); \ |
56 | 43.9k | require_string(!eh_did_timeout, error_label, "Timed out while waiting " # seconds " seconds for empty outbound buffer"); \ |
57 | 43.8k | } while (0) |
58 | | |
59 | 43.1k | #define CONTROL_REQUIRE_OUTBOUND_BUFFER_FLUSHED_WITHIN(seconds, error_label) do { \ |
60 | 43.1k | static const int ___crsw_send_finished = 0xFF000000 | __LINE__; \ |
61 | 43.1k | static const int ___crsw_send_failed = 0xFE000000 | __LINE__; \ |
62 | 43.1k | __ASSERT_MACROS_check(GetInstance(this)->mOutboundCallback.empty()); \ |
63 | 43.1k | require(GetInstance(this)->mOutboundBufferLen > 0, error_label); \ |
64 | 43.1k | GetInstance(this)->mOutboundCallback = CALLBACK_FUNC_SPLIT( \ |
65 | 43.1k | boost::bind(&NCPInstanceBase::process_event_helper, GetInstance(this), ___crsw_send_finished), \ |
66 | 43.1k | boost::bind(&NCPInstanceBase::process_event_helper, GetInstance(this), ___crsw_send_failed) \ |
67 | 43.1k | ); \ |
68 | 43.1k | GetInstance(this)->mOutboundBuffer[0] = mLastHeader; \ |
69 | 43.1k | EH_WAIT_UNTIL_WITH_TIMEOUT(seconds, (event == ___crsw_send_finished) || (event == ___crsw_send_failed)); \ |
70 | 43.1k | require_string(!eh_did_timeout, error_label, "Timed out while trying to send command"); \ |
71 | 43.0k | require_string(event == ___crsw_send_finished, error_label, "Failure while trying to send command"); \ |
72 | 42.9k | } while (0) |
73 | | |
74 | 43.9k | #define CONTROL_REQUIRE_PREP_TO_SEND_COMMAND_WITHIN(timeout, error_label) do { \ |
75 | 43.9k | CONTROL_REQUIRE_EMPTY_OUTBOUND_BUFFER_WITHIN(timeout, error_label); \ |
76 | 43.9k | GetInstance(this)->mLastTID = SPINEL_GET_NEXT_TID(GetInstance(this)->mLastTID); \ |
77 | 43.1k | mLastHeader = (SPINEL_HEADER_FLAG | SPINEL_HEADER_IID_0 | (GetInstance(this)->mLastTID << SPINEL_HEADER_TID_SHIFT)); \ |
78 | 43.1k | } while (false) |
79 | | |
80 | 38.2k | #define CONTROL_REQUIRE_COMMAND_RESPONSE_WITHIN(timeout, error_label) do { \ |
81 | 38.2k | EH_REQUIRE_WITHIN( \ |
82 | 38.2k | timeout, \ |
83 | 38.2k | IS_EVENT_FROM_NCP(event) && GetInstance(this)->mInboundHeader == mLastHeader, \ |
84 | 38.2k | error_label \ |
85 | 38.2k | ); \ |
86 | 38.2k | } while (false) |
87 | | |
88 | | namespace nl { |
89 | | namespace wpantund { |
90 | | |
91 | | class SpinelNCPTask; |
92 | | class SpinelNCPControlInterface; |
93 | | |
94 | | class SpinelNCPInstance : public NCPInstanceBase { |
95 | | friend class SpinelNCPControlInterface; |
96 | | friend class SpinelNCPTask; |
97 | | friend class SpinelNCPTaskDeepSleep; |
98 | | friend class SpinelNCPTaskWake; |
99 | | friend class SpinelNCPTaskJoin; |
100 | | friend class SpinelNCPTaskForm; |
101 | | friend class SpinelNCPTaskScan; |
102 | | friend class SpinelNCPTaskLeave; |
103 | | friend class SpinelNCPTaskPeek; |
104 | | friend class SpinelNCPTaskHostDidWake; |
105 | | friend class SpinelNCPTaskSendCommand; |
106 | | friend class SpinelNCPTaskGetNetworkTopology; |
107 | | friend class SpinelNCPTaskGetMsgBufferCounters; |
108 | | friend class SpinelNCPTaskJoinerCommissioning; |
109 | | friend class SpinelNCPTaskJoinerAttach; |
110 | | friend class SpinelNCPVendorCustom; |
111 | | |
112 | | public: |
113 | | |
114 | | enum DriverState { |
115 | | INITIALIZING, |
116 | | INITIALIZING_WAITING_FOR_RESET, |
117 | | NORMAL_OPERATION |
118 | | }; |
119 | | |
120 | | public: |
121 | | SpinelNCPInstance(const Settings& settings = Settings()); |
122 | | |
123 | | virtual ~SpinelNCPInstance(); |
124 | | |
125 | | virtual SpinelNCPControlInterface& get_control_interface(); |
126 | | |
127 | | virtual int vprocess_event(int event, va_list args); |
128 | | |
129 | | |
130 | | protected: |
131 | | virtual char ncp_to_driver_pump(); |
132 | | virtual char driver_to_ncp_pump(); |
133 | | |
134 | | void start_new_task(const boost::shared_ptr<SpinelNCPTask> &task); |
135 | | |
136 | | virtual bool is_busy(void); |
137 | | |
138 | | protected: |
139 | | |
140 | | int vprocess_init(int event, va_list args); |
141 | | int vprocess_disabled(int event, va_list args); |
142 | | int vprocess_associated(int event, va_list args); |
143 | | int vprocess_resume(int event, va_list args); |
144 | | int vprocess_offline(int event, va_list args); |
145 | | |
146 | | void handle_ncp_spinel_callback(unsigned int command, const uint8_t* cmd_data_ptr, spinel_size_t cmd_data_len); |
147 | | void handle_ncp_spinel_value_is(spinel_prop_key_t key, const uint8_t* value_data_ptr, spinel_size_t value_data_len); |
148 | | void handle_ncp_spinel_value_inserted(spinel_prop_key_t key, const uint8_t* value_data_ptr, spinel_size_t value_data_len); |
149 | | void handle_ncp_spinel_value_removed(spinel_prop_key_t key, const uint8_t* value_data_ptr, spinel_size_t value_data_len); |
150 | | void handle_ncp_state_change(NCPState new_ncp_state, NCPState old_ncp_state); |
151 | | |
152 | | void handle_ncp_log_stream(const uint8_t* data_ptr, int data_len); |
153 | | void handle_ncp_spinel_value_is_ON_MESH_NETS(const uint8_t* value_data_ptr, spinel_size_t value_data_len); |
154 | | void handle_ncp_spinel_value_is_OFF_MESH_ROUTES(const uint8_t* value_data_ptr, spinel_size_t value_data_len); |
155 | | void handle_ncp_spinel_value_is_SERVICES(const uint8_t* data_ptr, spinel_size_t value_data_len); |
156 | | |
157 | | bool should_filter_address(const struct in6_addr &address, uint8_t prefix_len); |
158 | | void filter_addresses(void); |
159 | | |
160 | | virtual void add_unicast_address_on_ncp(const struct in6_addr &addr, uint8_t prefix_len, |
161 | | CallbackWithStatus cb); |
162 | | virtual void remove_unicast_address_on_ncp(const struct in6_addr& addr, uint8_t prefix_len, |
163 | | CallbackWithStatus cb); |
164 | | |
165 | | virtual void add_multicast_address_on_ncp(const struct in6_addr &addr, CallbackWithStatus cb); |
166 | | virtual void remove_multicast_address_on_ncp(const struct in6_addr &addr, CallbackWithStatus cb); |
167 | | |
168 | | virtual void add_service_on_ncp(uint32_t enterprise_number, const Data& service_data, bool stable, |
169 | | const Data& server_data, CallbackWithStatus cb); |
170 | | |
171 | | virtual void remove_service_on_ncp(uint32_t enterprise_number, const Data& service_data, CallbackWithStatus cb); |
172 | | |
173 | | virtual void add_on_mesh_prefix_on_ncp(const struct in6_addr &addr, uint8_t prefix_len, uint16_t flags, bool stable, |
174 | | CallbackWithStatus cb); |
175 | | virtual void remove_on_mesh_prefix_on_ncp(const struct in6_addr &addr, uint8_t prefix_len, uint16_t flags, |
176 | | bool stable, CallbackWithStatus cb); |
177 | | |
178 | | virtual void add_route_on_ncp(const struct in6_addr &route, uint8_t prefix_len, RoutePreference preference, |
179 | | bool stable, CallbackWithStatus cb); |
180 | | virtual void remove_route_on_ncp(const struct in6_addr &route, uint8_t prefix_len, RoutePreference preference, |
181 | | bool stable, CallbackWithStatus cb); |
182 | | |
183 | | static RoutePreference convert_flags_to_route_preference(uint8_t flags); |
184 | | static uint8_t convert_route_preference_to_flags(RoutePreference priority); |
185 | | |
186 | | private: |
187 | | enum SpinelFrameOrigin { |
188 | | kDriverToNCP, |
189 | | kNCPToDriver, |
190 | | }; |
191 | | |
192 | | void log_spinel_frame(SpinelFrameOrigin origin, const uint8_t *frame_ptr, spinel_size_t frame_len); |
193 | | |
194 | | private: |
195 | | void update_node_type(NodeType node_type); |
196 | | void update_link_local_address(struct in6_addr *addr); |
197 | | void update_mesh_local_address(struct in6_addr *addr); |
198 | | void update_mesh_local_prefix(struct in6_addr *addr); |
199 | | |
200 | | private: |
201 | | void get_dataset_command_help(std::list<std::string> &list); |
202 | | int unpack_and_set_local_dataset(const uint8_t *data_in, spinel_size_t data_len); |
203 | | void perform_dataset_command(const std::string& command, CallbackWithStatus cb); |
204 | | |
205 | | public: |
206 | | static bool setup_property_supported_by_class(const std::string& prop_name); |
207 | | |
208 | | virtual std::set<std::string> get_supported_property_keys(void) const; |
209 | | |
210 | | private: |
211 | | typedef SpinelNCPTaskSendCommand::ReplyUnpacker ReplyUnpacker; |
212 | | |
213 | | void get_spinel_prop(CallbackWithStatusArg1 cb, spinel_prop_key_t prop_key, const std::string &reply_format); |
214 | | void get_spinel_prop_with_unpacker(CallbackWithStatusArg1 cb, spinel_prop_key_t prop_key, ReplyUnpacker unpacker); |
215 | | |
216 | | void check_capability_prop_get(CallbackWithStatusArg1 cb, const std::string &prop_name, unsigned int capability, |
217 | | PropGetHandler handler); |
218 | | |
219 | | void register_get_handler(const char *prop_name, PropGetHandler handler); |
220 | | void register_get_handler_capability(const char *prop_name, unsigned int capability, PropGetHandler handler); |
221 | | |
222 | | void register_get_handler_spinel_simple(const char *prop_name, spinel_prop_key_t prop_key, |
223 | | const char *reply_format); |
224 | | void register_get_handler_spinel_unpacker(const char *prop_name, spinel_prop_key_t prop_key, |
225 | | ReplyUnpacker unpacker); |
226 | | void register_get_handler_capability_spinel_simple(const char *prop_name, unsigned int capability, |
227 | | spinel_prop_key_t prop_key, const char *reply_format); |
228 | | void register_get_handler_capability_spinel_unpacker(const char *prop_name, unsigned int capability, |
229 | | spinel_prop_key_t prop_key, ReplyUnpacker unpacker); |
230 | | |
231 | | void regsiter_all_get_handlers(void); |
232 | | |
233 | | void get_prop_ConfigNCPDriverName(CallbackWithStatusArg1 cb); |
234 | | void get_prop_NCPCapabilities(CallbackWithStatusArg1 cb); |
235 | | void get_prop_NetworkIsCommissioned(CallbackWithStatusArg1 cb); |
236 | | void get_prop_ThreadRouterID(CallbackWithStatusArg1 cb); |
237 | | void get_prop_ThreadConfigFilterRLOCAddresses(CallbackWithStatusArg1 cb); |
238 | | void get_prop_ThreadConfigFilterALOCAddresses(CallbackWithStatusArg1 cb); |
239 | | void get_prop_JoinerDiscernerBitLength(CallbackWithStatusArg1 cb); |
240 | | void get_prop_CommissionerEnergyScanResult(CallbackWithStatusArg1 cb); |
241 | | void get_prop_CommissionerPanIdConflictResult(CallbackWithStatusArg1 cb); |
242 | | void get_prop_IPv6MeshLocalPrefix(CallbackWithStatusArg1 cb); |
243 | | void get_prop_IPv6MeshLocalAddress(CallbackWithStatusArg1 cb); |
244 | | void get_prop_IPv6LinkLocalAddress(CallbackWithStatusArg1 cb); |
245 | | void get_prop_LinkMetricsQueryResult(CallbackWithStatusArg1 cb); |
246 | | void get_prop_LinkMetricsMgmtResponse(CallbackWithStatusArg1 cb); |
247 | | void get_prop_LinkMetricsLastEnhAckIe(CallbackWithStatusArg1 cb); |
248 | | void get_prop_MulticastListenerRegistrationResponse(CallbackWithStatusArg1 cb); |
249 | | void get_prop_ThreadChildTable(CallbackWithStatusArg1 cb); |
250 | | void get_prop_ThreadChildTableAsValMap(CallbackWithStatusArg1 cb); |
251 | | void get_prop_ThreadChildTableAddresses(CallbackWithStatusArg1 cb); |
252 | | void get_prop_ThreadNeighborTable(CallbackWithStatusArg1 cb); |
253 | | void get_prop_ThreadNeighborTableAsValMap(CallbackWithStatusArg1 cb); |
254 | | void get_prop_ThreadNeighborTableErrorRates(CallbackWithStatusArg1 cb); |
255 | | void get_prop_ThreadNeighborTableErrorRatesAsValMap(CallbackWithStatusArg1 cb); |
256 | | void get_prop_ThreadRouterTable(CallbackWithStatusArg1 cb); |
257 | | void get_prop_ThreadRouterTableAsValMap(CallbackWithStatusArg1 cb); |
258 | | void get_prop_OpenThreadMsgBufferCounters(CallbackWithStatusArg1 cb); |
259 | | void get_prop_OpenThreadMsgBufferCountersAsString(CallbackWithStatusArg1 cb); |
260 | | void get_prop_OpenThreadSteeringDataSetWhenJoinable(CallbackWithStatusArg1 cb); |
261 | | void get_prop_OpenThreadSteeringDataAddress(CallbackWithStatusArg1 cb); |
262 | | void get_prop_DatasetActiveTimestamp(CallbackWithStatusArg1 cb); |
263 | | void get_prop_DatasetPendingTimestamp(CallbackWithStatusArg1 cb); |
264 | | void get_prop_DatasetMasterKey(CallbackWithStatusArg1 cb); |
265 | | void get_prop_DatasetNetworkName(CallbackWithStatusArg1 cb); |
266 | | void get_prop_DatasetExtendedPanId(CallbackWithStatusArg1 cb); |
267 | | void get_prop_DatasetMeshLocalPrefix(CallbackWithStatusArg1 cb); |
268 | | void get_prop_DatasetDelay(CallbackWithStatusArg1 cb); |
269 | | void get_prop_DatasetPanId(CallbackWithStatusArg1 cb); |
270 | | void get_prop_DatasetChannel(CallbackWithStatusArg1 cb); |
271 | | void get_prop_DatasetPSKc(CallbackWithStatusArg1 cb); |
272 | | void get_prop_DatasetChannelMaskPage0(CallbackWithStatusArg1 cb); |
273 | | void get_prop_DatasetSecPolicyKeyRotation(CallbackWithStatusArg1 cb); |
274 | | void get_prop_DatasetSecPolicyFlags(CallbackWithStatusArg1 cb); |
275 | | void get_prop_DatasetRawTlvs(CallbackWithStatusArg1 cb); |
276 | | void get_prop_DatasetDestIpAddress(CallbackWithStatusArg1 cb); |
277 | | void get_prop_DatasetAllFileds(CallbackWithStatusArg1 cb); |
278 | | void get_prop_DatasetAllFiledsAsValMap(CallbackWithStatusArg1 cb); |
279 | | void get_prop_DatasetCommand(CallbackWithStatusArg1 cb); |
280 | | void get_prop_DaemonTickleOnHostDidWake(CallbackWithStatusArg1 cb); |
281 | | void get_prop_POSIXAppRCPVersionCached(CallbackWithStatusArg1 cb); |
282 | | void get_prop_MACFilterFixedRssi(CallbackWithStatusArg1 cb); |
283 | | |
284 | | private: |
285 | | typedef boost::function<int(const boost::any&, boost::any&)> ValueConverter; |
286 | | |
287 | | void set_spinel_prop(const boost::any &value, CallbackWithStatus cb, spinel_prop_key_t prop_key, char pack_type, |
288 | | unsigned int capability = 0, bool save_in_settings = false, const std::string &prop_name = std::string()); |
289 | | |
290 | | static void convert_value_prop_set(const boost::any &value, CallbackWithStatus cb, const std::string &prop_name, |
291 | | ValueConverter converter, PropUpdateHandler handler); |
292 | | |
293 | | void register_set_handler(const char *prop_name, PropUpdateHandler handler, |
294 | | ValueConverter converter = ValueConverter()); |
295 | | void register_set_handler_spinel(const char *prop_name, spinel_prop_key_t prop_key, char pack_type, |
296 | | ValueConverter converter = ValueConverter()); |
297 | | void register_set_handler_spinel_persist(const char *prop_name, spinel_prop_key_t prop_key, char pack_type, |
298 | | ValueConverter converter = ValueConverter()); |
299 | | void register_set_handler_capability_spinel(const char *prop_name, unsigned int capability, |
300 | | spinel_prop_key_t prop_key, char pack_type, ValueConverter converter = ValueConverter()); |
301 | | void register_set_handler_capability_spinel_persist(const char *prop_name, unsigned int capability, |
302 | | spinel_prop_key_t prop_key, char pack_type, ValueConverter converter = ValueConverter()); |
303 | | |
304 | | void regsiter_all_set_handlers(void); |
305 | | |
306 | | static int convert_value_NCPMCUPowerState(const boost::any &value, boost::any &value_out); |
307 | | static int convert_value_channel_mask(const boost::any &value, boost::any &value_out); |
308 | | static int convert_value_counter_reset(const boost::any &value, boost::any &value_out); |
309 | | static int convert_value_CommissionerState(const boost::any &value, boost::any &value_out); |
310 | | static int convert_value_dua_interface_identifier(const boost::any &value, boost::any &value_out); |
311 | | static int convert_value_BackboneRouterState(const boost::any &value, boost::any &value_out); |
312 | | static int convert_value_BackboneRouterRegister(const boost::any &value, boost::any &value_out); |
313 | | |
314 | | void set_prop_NetworkKey(const boost::any &value, CallbackWithStatus cb); |
315 | | void set_prop_InterfaceUp(const boost::any &value, CallbackWithStatus cb); |
316 | | void set_prop_NetworkXPANID(const boost::any &value, CallbackWithStatus cb); |
317 | | void set_prop_IPv6MeshLocalPrefix(const boost::any &value, CallbackWithStatus cb); |
318 | | void set_prop_ThreadConfigFilterRLOCAddresses(const boost::any &value, CallbackWithStatus cb); |
319 | | void set_prop_ThreadConfigFilterALOCAddresses(const boost::any &value, CallbackWithStatus cb); |
320 | | void set_prop_OpenThreadSteeringDataSetWhenJoinable(const boost::any &value, CallbackWithStatus cb); |
321 | | void set_prop_OpenThreadSteeringDataAddress(const boost::any &value, CallbackWithStatus cb); |
322 | | void set_prop_TmfProxyStream(const boost::any &value, CallbackWithStatus cb); |
323 | | void set_prop_UdpForwardStream(const boost::any &value, CallbackWithStatus cb); |
324 | | void set_prop_DatasetActiveTimestamp(const boost::any &value, CallbackWithStatus cb); |
325 | | void set_prop_DatasetPendingTimestamp(const boost::any &value, CallbackWithStatus cb); |
326 | | void set_prop_DatasetMasterKey(const boost::any &value, CallbackWithStatus cb); |
327 | | void set_prop_DatasetNetworkName(const boost::any &value, CallbackWithStatus cb); |
328 | | void set_prop_DatasetExtendedPanId(const boost::any &value, CallbackWithStatus cb); |
329 | | void set_prop_DatasetMeshLocalPrefix(const boost::any &value, CallbackWithStatus cb); |
330 | | void set_prop_DatasetDelay(const boost::any &value, CallbackWithStatus cb); |
331 | | void set_prop_DatasetPanId(const boost::any &value, CallbackWithStatus cb); |
332 | | void set_prop_DatasetChannel(const boost::any &value, CallbackWithStatus cb); |
333 | | void set_prop_DatasetPSKc(const boost::any &value, CallbackWithStatus cb); |
334 | | void set_prop_DatasetChannelMaskPage0(const boost::any &value, CallbackWithStatus cb); |
335 | | void set_prop_DatasetSecPolicyKeyRotation(const boost::any &value, CallbackWithStatus cb); |
336 | | void set_prop_DatasetSecPolicyFlags(const boost::any &value, CallbackWithStatus cb); |
337 | | void set_prop_DatasetRawTlvs(const boost::any &value, CallbackWithStatus cb); |
338 | | void set_prop_DatasetDestIpAddress(const boost::any &value, CallbackWithStatus cb); |
339 | | void set_prop_DatasetCommand(const boost::any &value, CallbackWithStatus cb); |
340 | | void set_prop_DaemonTickleOnHostDidWake(const boost::any &value, CallbackWithStatus cb); |
341 | | void set_prop_MACFilterFixedRssi(const boost::any &value, CallbackWithStatus cb); |
342 | | void set_prop_JoinerDiscernerBitLength(const boost::any &value, CallbackWithStatus cb); |
343 | | void set_prop_JoinerDiscernerValue(const boost::any &value, CallbackWithStatus cb); |
344 | | |
345 | | private: |
346 | | void check_capability_prop_update(const boost::any &value, CallbackWithStatus cb, const std::string &prop_name, |
347 | | unsigned int capability, PropUpdateHandler handler); |
348 | | |
349 | | void register_insert_handler(const char *prop_name, PropUpdateHandler handler); |
350 | | void register_insert_handler_capability(const char *prop_name, unsigned int capability, PropUpdateHandler handler); |
351 | | |
352 | | void regsiter_all_insert_handlers(void); |
353 | | |
354 | | void insert_prop_MACAllowlistEntries(const boost::any &value, CallbackWithStatus cb); |
355 | | void insert_prop_MACDenylistEntries(const boost::any &value, CallbackWithStatus cb); |
356 | | void insert_prop_MACFilterEntries(const boost::any &value, CallbackWithStatus cb); |
357 | | |
358 | | private: |
359 | | void register_remove_handler(const char *prop_name, PropUpdateHandler handler); |
360 | | void register_remove_handler_capability(const char *prop_name, unsigned int capability, PropUpdateHandler handler); |
361 | | |
362 | | void regsiter_all_remove_handlers(void); |
363 | | |
364 | | void remove_prop_MACAllowlistEntries(const boost::any &value, CallbackWithStatus cb); |
365 | | void remove_prop_MACDenylistEntries(const boost::any &value, CallbackWithStatus cb); |
366 | | void remove_prop_MACFilterEntries(const boost::any &value, CallbackWithStatus cb); |
367 | | |
368 | | public: |
369 | | |
370 | | virtual void property_get_value(const std::string& key, CallbackWithStatusArg1 cb); |
371 | | |
372 | | virtual void property_set_value(const std::string& key, const boost::any& value, CallbackWithStatus cb); |
373 | | |
374 | | virtual void property_insert_value(const std::string& key, const boost::any& value, CallbackWithStatus cb); |
375 | | |
376 | | virtual void property_remove_value(const std::string& key, const boost::any& value, CallbackWithStatus cb); |
377 | | |
378 | | |
379 | | public: |
380 | | virtual cms_t get_ms_to_next_event(void); |
381 | | |
382 | | virtual void reset_tasks(wpantund_status_t status = kWPANTUNDStatus_Canceled); |
383 | | |
384 | | static void handle_ncp_debug_stream(const uint8_t* data_ptr, int data_len); |
385 | | |
386 | | static std::string thread_mode_to_string(uint8_t mode); |
387 | | |
388 | | uint8_t get_thread_mode(void); |
389 | | |
390 | | virtual void process(void); |
391 | | |
392 | | private: |
393 | | struct SettingsEntry |
394 | | { |
395 | | public: |
396 | | SettingsEntry(const Data &command = Data(), unsigned int capability = 0) : |
397 | 808 | mSpinelCommand(command), |
398 | 808 | mCapability(capability) |
399 | 808 | { |
400 | 808 | } |
401 | | |
402 | | Data mSpinelCommand; |
403 | | unsigned int mCapability; |
404 | | }; |
405 | | |
406 | | /* Map from property key to setting entry |
407 | | * |
408 | | * The map contains all parameters/properties that are retained and |
409 | | * restored when NCP gets initialized. |
410 | | * |
411 | | * `Setting entry` contains an optional capability value and an associated |
412 | | * spinel command. |
413 | | * |
414 | | * If the `capability` is present in the list of NCP capabilities , then |
415 | | * the associated spinel command is sent to NCP after initialization. |
416 | | */ |
417 | | typedef std::map<std::string, SettingsEntry> SettingsMap; |
418 | | |
419 | | private: |
420 | | enum { |
421 | | kMaxCommissionerEnergyScanResultEntries = 64, |
422 | | kMaxCommissionerPanIdConflictResultEntries = 64, |
423 | | }; |
424 | | |
425 | | SpinelNCPControlInterface mControlInterface; |
426 | | |
427 | | uint8_t mLastTID; |
428 | | |
429 | | uint8_t mLastHeader; |
430 | | |
431 | | uint8_t mInboundFrame[SPINEL_FRAME_BUFFER_SIZE]; |
432 | | uint8_t mInboundHeader; |
433 | | spinel_size_t mInboundFrameSize; |
434 | | uint8_t mInboundFrameDataType; |
435 | | const uint8_t* mInboundFrameDataPtr; |
436 | | spinel_size_t mInboundFrameDataLen; |
437 | | uint16_t mInboundFrameHDLCCRC; |
438 | | |
439 | | uint8_t mOutboundBufferHeader[3]; |
440 | | uint8_t mOutboundBuffer[SPINEL_FRAME_BUFFER_SIZE]; |
441 | | uint8_t mOutboundBufferType; |
442 | | spinel_ssize_t mOutboundBufferLen; |
443 | | spinel_ssize_t mOutboundBufferSent; |
444 | | uint8_t mOutboundBufferEscaped[SPINEL_FRAME_BUFFER_SIZE*2]; |
445 | | spinel_ssize_t mOutboundBufferEscapedLen; |
446 | | boost::function<void(int)> mOutboundCallback; |
447 | | |
448 | | int mTXPower; |
449 | | uint8_t mThreadMode; |
450 | | bool mIsCommissioned; |
451 | | bool mFilterRLOCAddresses; |
452 | | bool mFilterALOCAddresses; |
453 | | bool mTickleOnHostDidWake; |
454 | | std::string mRcpVersion; |
455 | | |
456 | | std::set<unsigned int> mCapabilities; |
457 | | |
458 | | bool mSetSteeringDataWhenJoinable; |
459 | | uint8_t mSteeringDataAddress[8]; |
460 | | |
461 | | ThreadDataset mLocalDataset; |
462 | | |
463 | | SettingsMap mSettings; |
464 | | SettingsMap::iterator mSettingsIter; |
465 | | |
466 | | DriverState mDriverState; |
467 | | |
468 | | // Protothreads and related state |
469 | | PT mSleepPT; |
470 | | PT mSubPT; |
471 | | |
472 | | int mSubPTIndex; |
473 | | |
474 | | Data mNetworkPSKc; |
475 | | Data mNetworkKey; |
476 | | uint32_t mNetworkKeyIndex; |
477 | | uint32_t mSupportedChannelMask; |
478 | | uint32_t mPreferredChannelMask; |
479 | | bool mXPANIDWasExplicitlySet; |
480 | | uint8_t mChannelManagerNewChannel; |
481 | | int8_t mMacFilterFixedRssi; |
482 | | |
483 | | uint8_t mJoinerDiscernerBitLength; |
484 | | std::list<ValueMap> mCommissionerEnergyScanResult; |
485 | | std::list<ValueMap> mCommissionerPanIdConflictResult; |
486 | | |
487 | | ValueMap mLinkMetricsQueryResult; |
488 | | ValueMap mLinkMetricsMgmtResponse; |
489 | | ValueMap mLinkMetricsLastEnhAckIe; |
490 | | |
491 | | ValueMap mMulticastListenerRegistrationResponse; |
492 | | |
493 | | bool mResetIsExpected; |
494 | | |
495 | | bool mIsPcapInProgress; |
496 | | |
497 | | // Task management |
498 | | std::list<boost::shared_ptr<SpinelNCPTask> > mTaskQueue; |
499 | | |
500 | | // The vendor custom class needs to |
501 | | // remain as the last thing in this class. |
502 | | SpinelNCPVendorCustom mVendorCustom; |
503 | | }; // class SpinelNCPInstance |
504 | | |
505 | | extern class SpinelNCPInstance* gNCPInstance; |
506 | | |
507 | | template<class C> |
508 | | inline SpinelNCPInstance* GetInstance(C *x) |
509 | 245k | { |
510 | 245k | return x->mInstance; |
511 | 245k | } nl::wpantund::SpinelNCPInstance* nl::wpantund::GetInstance<nl::wpantund::SpinelNCPTask>(nl::wpantund::SpinelNCPTask*) Line | Count | Source | 509 | 186k | { | 510 | 186k | return x->mInstance; | 511 | 186k | } |
nl::wpantund::SpinelNCPInstance* nl::wpantund::GetInstance<nl::wpantund::SpinelNCPTaskWake>(nl::wpantund::SpinelNCPTaskWake*) Line | Count | Source | 509 | 59.0k | { | 510 | 59.0k | return x->mInstance; | 511 | 59.0k | } |
|
512 | | |
513 | | template<> |
514 | | inline SpinelNCPInstance* GetInstance<SpinelNCPInstance>(SpinelNCPInstance *x) |
515 | 444k | { |
516 | 444k | return x; |
517 | 444k | } |
518 | | |
519 | | template<class C> |
520 | | inline nl::wpantund::SpinelNCPControlInterface* GetInterface(C *x) |
521 | | { |
522 | | return x->mInterface; |
523 | | } |
524 | | |
525 | | template<> |
526 | | inline nl::wpantund::SpinelNCPControlInterface* GetInterface<nl::wpantund::SpinelNCPControlInterface>(nl::wpantund::SpinelNCPControlInterface *x) |
527 | 0 | { |
528 | 0 | return x; |
529 | 0 | } |
530 | | |
531 | | bool ncp_event_matches_header_from_args(int event, va_list args, uint8_t last_header); |
532 | | |
533 | | int peek_ncp_callback_status(int event, va_list args); |
534 | | |
535 | | int spinel_status_to_wpantund_status(int spinel_status); |
536 | | |
537 | | }; // namespace wpantund |
538 | | }; // namespace nl |
539 | | |
540 | | #endif /* defined(__wpantund__SpinelNCPInstance__) */ |