Coverage Report

Created: 2025-10-10 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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__) */