Statistics
| Branch: | Tag: | Revision:

mongoose / examples / nRF52 / http / bleconfig.c @ eaef5bd1

History | View | Annotate | Download (12.5 KB)

1

    
2
/* clang-format off */
3

    
4
#include <stdbool.h>
5
#include <stdint.h>
6
#include "boards.h"
7
#include "sdk_config.h"
8
#include "app_timer_appsh.h"
9
#include "app_scheduler.h"
10
#include "app_button.h"
11
#include "nordic_common.h"
12
#include "softdevice_handler_appsh.h"
13
#include "ble_advdata.h"
14
#include "ble_srv_common.h"
15
#include "ble_ipsp.h"
16
#include "ble_6lowpan.h"
17
#include "mem_manager.h"
18
#include "app_trace.h"
19

    
20
/*
21
 * arm-none-eabi-gcc has BYTE_ORDER already defined, so in order to avoid
22
 * warnings in lwip, we have to undefine it
23
 *
24
 * TODO: Check if in the future versions of nRF5 SDK that changes.
25
 *       Current version of nRF51 SDK: 0.8.0
26
 *                          nRF5 SDK:  0.9.0
27
 */
28
#undef BYTE_ORDER
29
#include "lwip/init.h"
30
#include "lwip/inet6.h"
31
#include "lwip/ip6.h"
32
#include "lwip/ip6_addr.h"
33
#include "lwip/netif.h"
34
/*lint -save -e607 */
35
#include "lwip/tcp.h"
36
/*lint -restore */
37
#include "lwip/timers.h"
38
#include "nrf_platform_port.h"
39
#include "app_util_platform.h"
40
#include "iot_timer.h"
41
#include "ipv6_medium.h"
42
#include "SEGGER_RTT.h"
43
#include "myboard.h"
44

    
45
#define SCHED_MAX_EVENT_DATA_SIZE           128                                                     /**< Maximum size of scheduler events. */
46
#define SCHED_QUEUE_SIZE                    12                                                      /**< Maximum number of events in the scheduler queue. */
47

    
48
#ifdef COMMISSIONING_ENABLED
49
#define ERASE_BUTTON_PIN_NO                 BSP_BUTTON_3                                            /**< Button used to erase commissioning settings. */
50
#endif // COMMISSIONING_ENABLED
51

    
52
#define APP_TIMER_OP_QUEUE_SIZE             5
53
#define LWIP_SYS_TICK_MS                    100                                                     /**< Interval for timer used as trigger to send. */
54
#define LED_BLINK_INTERVAL_MS               300                                                     /**< LED blinking interval. */
55

    
56
#define MAX_LENGTH_FILENAME                 128                                                     /**< Max length of filename to copy for the debug error handler. */
57

    
58
#define APPL_LOG                            app_trace_log                                           /**< Macro for logging application messages on UART, in case ENABLE_DEBUG_LOG_SUPPORT is not defined, no logging occurs. */
59
#define APPL_DUMP                           app_trace_dump                                          /**< Macro for dumping application data on UART, in case ENABLE_DEBUG_LOG_SUPPORT is not defined, no logging occurs. */
60

    
61
#define TCP_SERVER_PORT                     9000                                                    /**< TCP server listen port number. */
62
#define TCP_DATA_SIZE                       8                                                       /**< UDP Data size sent on remote. */
63

    
64
typedef enum
65
{
66
  TCP_STATE_IDLE,
67
  TCP_STATE_REQUEST_CONNECTION,
68
  TCP_STATE_CONNECTED,
69
  TCP_STATE_DATA_TX_IN_PROGRESS,
70
  TCP_STATE_DISCONNECTED
71
}tcp_state_t;
72

    
73
APP_TIMER_DEF(m_iot_timer_tick_src_id);                                                             /**< System Timer used to service CoAP and LWIP periodically. */
74
eui64_t                                     eui64_local_iid;                                        /**< Local EUI64 value that is used as the IID for*/
75
static ipv6_medium_instance_t               m_ipv6_medium;
76
static tcp_state_t                          m_tcp_state;                                            /**< TCP State information. */
77

    
78
#ifdef COMMISSIONING_ENABLED
79
static bool                                 m_power_off_on_failure = false;
80
static bool                                 m_identity_mode_active;
81
#endif // COMMISSIONING_ENABLED
82

    
83
/**@brief Function to handle interface up event. */
84
void nrf_driver_interface_up(void)
85
{
86
#ifdef COMMISSIONING_ENABLED
87
  commissioning_joining_mode_timer_ctrl(JOINING_MODE_TIMER_STOP_RESET);
88
#endif // COMMISSIONING_ENABLED
89

    
90
  APPL_LOG ("[APPL]: IPv6 interface up.\r\n");
91

    
92
  sys_check_timeouts();
93

    
94
  m_tcp_state = TCP_STATE_REQUEST_CONNECTION;
95

    
96
  LEDS_OFF(LED_ONE);
97
  LEDS_ON(LED_TWO);
98
}
99

    
100

    
101
/**@brief Function to handle interface down event. */
102
void nrf_driver_interface_down(void)
103
{
104
#ifdef COMMISSIONING_ENABLED
105
  commissioning_joining_mode_timer_ctrl(JOINING_MODE_TIMER_START);
106
#endif // COMMISSIONING_ENABLED
107

    
108
  APPL_LOG ("[APPL]: IPv6 interface down.\r\n");
109

    
110
  LEDS_OFF((DISPLAY_LED_0 | DISPLAY_LED_1 | DISPLAY_LED_2 | DISPLAY_LED_3));
111
  LEDS_ON(LED_ONE);
112

    
113
  m_tcp_state = TCP_STATE_DISCONNECTED;
114
}
115

    
116
/**@brief Timer callback used for periodic servicing of LwIP protocol timers.
117
 *
118
 * @details Timer callback used for periodic servicing of LwIP protocol timers.
119
 *
120
 * @param[in]   p_context   Pointer used for passing context. No context used in this application.
121
 */
122
static void system_timer_callback(iot_timer_time_in_ms_t wall_clock_value)
123
{
124
  UNUSED_VARIABLE(wall_clock_value);
125
  sys_check_timeouts();
126
}
127

    
128
/**@brief Function for starting connectable mode.
129
*/
130
static void connectable_mode_enter(void)
131
{
132
  uint32_t err_code = ipv6_medium_connectable_mode_enter(m_ipv6_medium.ipv6_medium_instance_id);
133
  APP_ERROR_CHECK(err_code);
134

    
135
  APPL_LOG("[APPL]: Physical layer in connectable mode.\r\n");
136
  LEDS_OFF(LED_TWO);
137
  LEDS_ON(LED_ONE);
138
}
139

    
140
/**@brief Function for updating the wall clock of the IoT Timer module.
141
*/
142
static void iot_timer_tick_callback(void * p_context)
143
{
144
  UNUSED_VARIABLE(p_context);
145

    
146
  uint32_t err_code = iot_timer_update();
147
  APP_ERROR_CHECK(err_code);
148
}
149

    
150
/**@brief Function for the LEDs initialization.
151
 *
152
 * @details Initializes all LEDs used by this application.
153
 */
154
static void leds_init(void)
155
{
156
  // Configure application LED pins.
157
  LEDS_CONFIGURE(ALL_APP_LED);
158

    
159
  // Turn off all LED on initialization.
160
  LEDS_OFF(ALL_APP_LED);
161
}
162

    
163
#ifdef COMMISSIONING_ENABLED
164
/**@brief Timer callback used for controlling board LEDs to represent application state.
165
 *
166
 */
167
static void blink_timeout_handler(iot_timer_time_in_ms_t wall_clock_value)
168
{
169
  UNUSED_PARAMETER(wall_clock_value);
170
  static bool id_mode_previously_enabled;
171

    
172
  if ((id_mode_previously_enabled == false) && (m_identity_mode_active == true))
173
  {
174
    LEDS_OFF(LED_THREE | LED_FOUR);
175
  }
176

    
177
  if ((id_mode_previously_enabled == true) && (m_identity_mode_active == true))
178
  {
179
    LEDS_INVERT(LED_THREE | LED_FOUR);
180
  }
181

    
182
  if ((id_mode_previously_enabled == true) && (m_identity_mode_active == false))
183
  {
184
    LEDS_OFF(LED_THREE | LED_FOUR);
185
  }
186

    
187
  id_mode_previously_enabled = m_identity_mode_active;
188
}
189
#endif // COMMISSIONING_ENABLED
190

    
191
/**@brief Function for the Timer initialization.
192
 *
193
 * @details Initializes the timer module. This creates and starts application timers.
194
 */
195
static void timers_init(void)
196
{
197
  uint32_t err_code;
198

    
199
  // Initialize timer module.
200
  APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
201

    
202
  // Create a sys timer.
203
  err_code = app_timer_create(&m_iot_timer_tick_src_id,
204
      APP_TIMER_MODE_REPEATED,
205
      iot_timer_tick_callback);
206
  APP_ERROR_CHECK(err_code);
207
}
208

    
209

    
210
/**@brief Function for initializing the IoT Timer. */
211
static void iot_timer_init(void)
212
{
213
  uint32_t err_code;
214

    
215
  static const iot_timer_client_t list_of_clients[] =
216
  {
217
    {system_timer_callback,   LWIP_SYS_TICK_MS},
218
#ifdef COMMISSIONING_ENABLED
219
    {blink_timeout_handler,   LED_BLINK_INTERVAL_MS},
220
    {commissioning_time_tick, SEC_TO_MILLISEC(COMMISSIONING_TICK_INTERVAL_SEC)}
221
#endif // COMMISSIONING_ENABLED
222
  };
223

    
224
  // The list of IoT Timer clients is declared as a constant.
225
  static const iot_timer_clients_list_t iot_timer_clients =
226
  {
227
    (sizeof(list_of_clients) / sizeof(iot_timer_client_t)),
228
    &(list_of_clients[0]),
229
  };
230

    
231
  // Passing the list of clients to the IoT Timer module.
232
  err_code = iot_timer_client_list_set(&iot_timer_clients);
233
  APP_ERROR_CHECK(err_code);
234

    
235
  // Starting the app timer instance that is the tick source for the IoT Timer.
236
  err_code = app_timer_start(m_iot_timer_tick_src_id, \
237
      APP_TIMER_TICKS(IOT_TIMER_RESOLUTION_IN_MS, APP_TIMER_PRESCALER), \
238
      NULL);
239
  APP_ERROR_CHECK(err_code);
240
}
241

    
242
/**@brief Function for initializing IP stack.
243
 *
244
 * @details Initialize the IP Stack and its driver.
245
 */
246
static void ip_stack_init(void)
247
{
248
  uint32_t err_code;
249

    
250
  err_code = ipv6_medium_eui64_get(m_ipv6_medium.ipv6_medium_instance_id, \
251
      &eui64_local_iid);
252
  APP_ERROR_CHECK(err_code);
253

    
254
  err_code = nrf_mem_init();
255
  APP_ERROR_CHECK(err_code);
256

    
257
  //Initialize LwIP stack.
258
  lwip_init();
259

    
260
  //Initialize LwIP stack driver.
261
  err_code = nrf_driver_init();
262
  APP_ERROR_CHECK(err_code);
263
}
264

    
265
#ifdef COMMISSIONING_ENABLED
266
/**@brief Function for handling button events.
267
 *
268
 * @param[in]   pin_no         The pin number of the button pressed.
269
 * @param[in]   button_action  The action performed on button.
270
 */
271
static void button_event_handler(uint8_t pin_no, uint8_t button_action)
272
{
273
  if ((button_action == APP_BUTTON_PUSH) && (pin_no == ERASE_BUTTON_PIN_NO))
274
  {
275
    APPL_LOG("[APPL]: Erasing all commissioning settings from persistent storage... \r\n");
276
    commissioning_settings_clear();
277
    return;
278
  }
279
  return;
280
}
281

    
282

    
283
/**@brief Function for the Button initialization.
284
 *
285
 * @details Initializes all Buttons used by this application.
286
 */
287
static void buttons_init(void)
288
{
289
  uint32_t err_code;
290

    
291
  static app_button_cfg_t buttons[] =
292
  {
293
#ifdef COMMISSIONING_ENABLED
294
    {ERASE_BUTTON_PIN_NO, false, BUTTON_PULL, button_event_handler}
295
#endif // COMMISSIONING_ENABLED
296
  };
297

    
298
#define BUTTON_DETECTION_DELAY APP_TIMER_TICKS(50, APP_TIMER_PRESCALER)
299

    
300
  err_code = app_button_init(buttons, \
301
      sizeof(buttons) / sizeof(buttons[0]), \
302
      BUTTON_DETECTION_DELAY);
303
  APP_ERROR_CHECK(err_code);
304

    
305
  err_code = app_button_enable();
306
  APP_ERROR_CHECK(err_code);
307
}
308
#endif // COMMISSIONING_ENABLED
309

    
310
/**@brief Function for the Event Scheduler initialization.
311
*/
312
static void scheduler_init(void)
313
{
314
  APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
315
}
316

    
317
static void on_ipv6_medium_evt(ipv6_medium_evt_t * p_ipv6_medium_evt)
318
{
319
  switch (p_ipv6_medium_evt->ipv6_medium_evt_id)
320
  {
321
    case IPV6_MEDIUM_EVT_CONN_UP:
322
      {
323
        APPL_LOG("[APPL]: Physical layer: connected.\r\n");
324
        LEDS_OFF(LED_ONE);
325
        LEDS_ON(LED_TWO);
326
        break;
327
      }
328
    case IPV6_MEDIUM_EVT_CONN_DOWN:
329
      {
330
        APPL_LOG("[APPL]: Physical layer: disconnected.\r\n");
331
        connectable_mode_enter();
332
        break;
333
      }
334
    default:
335
      {
336
        break;
337
      }
338
  }
339
}
340

    
341

    
342
static void on_ipv6_medium_error(ipv6_medium_error_t * p_ipv6_medium_error)
343
{
344
  // Do something.
345
}
346

    
347
#ifdef COMMISSIONING_ENABLED
348
void commissioning_id_mode_cb(mode_control_cmd_t control_command)
349
{
350
  switch (control_command)
351
  {
352
    case CMD_IDENTITY_MODE_ENTER:
353
      {
354
        LEDS_OFF(LED_THREE | LED_FOUR);
355
        m_identity_mode_active = true;
356

    
357
        break;
358
      }
359
    case CMD_IDENTITY_MODE_EXIT:
360
      {
361
        m_identity_mode_active = false;
362
        LEDS_OFF((LED_THREE | LED_FOUR));
363

    
364
        break;
365
      }
366
    default:
367
      {
368

    
369
        break;
370
      }
371
  }
372
}
373

    
374

    
375
void commissioning_power_off_cb(bool power_off_on_failure)
376
{
377
  m_power_off_on_failure = power_off_on_failure;
378

    
379
  APPL_LOG("[APPL]: Commissioning: do power_off on failure: %s.\r\n", \
380
      m_power_off_on_failure ? "true" : "false");
381
}
382
#endif // COMMISSIONING_ENABLED
383

    
384
void bleconfig_init(void) {
385
  uint32_t err_code;
386

    
387
  //Initialize.
388
  app_trace_init();
389
  leds_init();
390
  timers_init();
391
  iot_timer_init();
392

    
393
#ifdef COMMISSIONING_ENABLED
394
  err_code = pstorage_init();
395
  APP_ERROR_CHECK(err_code);
396

    
397
  buttons_init();
398
#endif // COMMISSIONING_ENABLED
399

    
400
  static ipv6_medium_init_params_t ipv6_medium_init_params;
401
  memset(&ipv6_medium_init_params, 0x00, sizeof(ipv6_medium_init_params));
402
  ipv6_medium_init_params.ipv6_medium_evt_handler    = on_ipv6_medium_evt;
403
  ipv6_medium_init_params.ipv6_medium_error_handler  = on_ipv6_medium_error;
404
  ipv6_medium_init_params.use_scheduler              = true;
405
#ifdef COMMISSIONING_ENABLED
406
  ipv6_medium_init_params.commissioning_id_mode_cb   = commissioning_id_mode_cb;
407
  ipv6_medium_init_params.commissioning_power_off_cb = commissioning_power_off_cb;
408
#endif // COMMISSIONING_ENABLED
409

    
410
  err_code = ipv6_medium_init(&ipv6_medium_init_params, \
411
      IPV6_MEDIUM_ID_BLE,       \
412
      &m_ipv6_medium);
413
  APP_ERROR_CHECK(err_code);
414

    
415
  eui48_t ipv6_medium_eui48;
416
  err_code = ipv6_medium_eui48_get(m_ipv6_medium.ipv6_medium_instance_id, \
417
      &ipv6_medium_eui48);
418

    
419
  ipv6_medium_eui48.identifier[EUI_48_SIZE - 1] = 0x00;
420

    
421
  err_code = ipv6_medium_eui48_set(m_ipv6_medium.ipv6_medium_instance_id, \
422
      &ipv6_medium_eui48);
423
  APP_ERROR_CHECK(err_code);
424

    
425
  ip_stack_init();
426
  scheduler_init();
427

    
428
  //Start execution.
429
  connectable_mode_enter();
430

    
431
  APPL_LOG("BLE init done\n");
432
}
433

    
434
void bleconfig_poll(void) {
435
  //Execute event schedule.
436
  app_sched_execute();
437
  sys_check_timeouts();
438
}
439