Contiki-NG
ble-hal-cc26xx.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017, Graz University of Technology
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
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28  * OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 /**
32  * \file
33  * BLE radio hardware abstraction implementation for the TI CC26XX controller
34  *
35  * \author
36  * Michael Spoerk <michael.spoerk@tugraz.at>
37  */
38 /*---------------------------------------------------------------------------*/
39 
40 #include "lpm.h"
41 
42 #include "sys/rtimer.h"
43 #include "sys/process.h"
44 
45 #include "os/dev/ble-hal.h"
46 #include "dev/oscillators.h"
47 
48 #include "ble-addr.h"
49 
50 #include "net/netstack.h"
51 #include "net/packetbuf.h"
52 
53 #include "rf_data_entry.h"
54 #include "rf-core/rf-core.h"
55 #include "rf_ble_cmd.h"
56 #include "lib/random.h"
57 
58 #include "ioc.h"
59 #include "ti-lib.h"
60 #include "inc/hw_types.h"
61 #include "inc/hw_rfc_dbell.h"
62 
63 #include <string.h>
64 
66 /*---------------------------------------------------------------------------*/
67 #include "sys/log.h"
68 #define LOG_MODULE "BLE-RADIO"
69 #define LOG_LEVEL LOG_LEVEL_MAIN
70 /*---------------------------------------------------------------------------*/
71 #define CMD_GET_STATUS(X) (((rfc_radioOp_t *)X)->status)
72 #define RX_ENTRY_STATUS(X) (((rfc_dataEntry_t *)X)->status)
73 #define RX_ENTRY_LENGTH(X) (((rfc_dataEntry_t *)X)->length)
74 #define RX_ENTRY_TYPE(X) (((rfc_dataEntry_t *)X)->config.type)
75 #define RX_ENTRY_NEXT_ENTRY(X) (((rfc_dataEntry_t *)X)->pNextEntry)
76 #define RX_ENTRY_DATA_LENGTH(X) ((X)[8])
77 #define RX_ENTRY_DATA_PTR(X) (&(X)[9])
78 #define TX_ENTRY_STATUS(X) RX_ENTRY_STATUS(X)
79 #define TX_ENTRY_LENGTH(X) RX_ENTRY_LENGTH(X)
80 #define TX_ENTRY_TYPE(X) RX_ENTRY_TYPE(X)
81 #define TX_ENTRY_NEXT_ENTRY(X) RX_ENTRY_NEXT_ENTRY(X)
82 #define TX_ENTRY_FRAME_TYPE(X) ((X)[8])
83 #define TX_ENTRY_DATA_PTR(X) (&(X)[9])
84 /*---------------------------------------------------------------------------*/
85 /* LPM */
86 /*---------------------------------------------------------------------------*/
87 static uint8_t
88 request(void)
89 {
90  if(rf_core_is_accessible()) {
91  return LPM_MODE_SLEEP;
92  }
93 
94  return LPM_MODE_MAX_SUPPORTED;
95 }
96 /*---------------------------------------------------------------------------*/
97 LPM_MODULE(cc26xx_ble_lpm_module, request, NULL, NULL, LPM_DOMAIN_NONE);
98 /*---------------------------------------------------------------------------*/
99 /* timing utilities */
100 #define TIME_UNIT_MS 1000 /* 1000 times per second */
101 #define TIME_UNIT_0_625_MS 1600 /* 1600 times per second */
102 #define TIME_UNIT_1_25_MS 800 /* 800 times per second */
103 #define TIME_UNIT_10_MS 100 /* 100 times per second */
104 #define TIME_UNIT_RF_CORE 4000000 /* runs at 4 MHz */
105 #define TIME_UNIT_RTIMER RTIMER_SECOND
106 
107 rtimer_clock_t
108 ticks_from_unit(uint32_t value, uint32_t unit)
109 {
110  double temp = (((double)value) / unit) * RTIMER_SECOND;
111  return (rtimer_clock_t)temp;
112 }
113 uint32_t
114 ticks_to_unit(rtimer_clock_t value, uint32_t unit)
115 {
116  double temp = (((double)value) / RTIMER_SECOND) * unit;
117  return (uint32_t)temp;
118 }
119 /*---------------------------------------------------------------------------*/
120 #define CMD_BUFFER_SIZE 24
121 #define PARAM_BUFFER_SIZE 36
122 #define OUTPUT_BUFFER_SIZE 24
123 /*---------------------------------------------------------------------------*/
124 /* ADVERTISING data structures */
125 #define ADV_RX_BUFFERS_OVERHEAD 8
126 #define ADV_RX_BUFFERS_DATA_LEN 60
127 #define ADV_RX_BUFFERS_LEN (ADV_RX_BUFFERS_OVERHEAD + ADV_RX_BUFFERS_DATA_LEN)
128 #define ADV_RX_BUFFERS_NUM 2
129 
130 #define ADV_PREPROCESSING_TIME_TICKS 65
131 
132 typedef struct {
133  /* PARAMETER */
134  uint16_t adv_interval;
135  ble_adv_type_t adv_type;
136  ble_addr_type_t own_addr_type;
137  uint8_t channel_map;
138  uint8_t adv_data_len;
139  uint8_t adv_data[BLE_ADV_DATA_LEN];
140  uint8_t scan_rsp_data_len;
141  uint8_t scan_rsp_data[BLE_ADV_DATA_LEN];
142  /* STATE information */
143  uint8_t active;
144  rtimer_clock_t start_rt;
145  struct rtimer timer;
146  /* utility */
147  uint8_t cmd_buf[CMD_BUFFER_SIZE];
148  uint8_t param_buf[PARAM_BUFFER_SIZE];
149  uint8_t output_buf[OUTPUT_BUFFER_SIZE];
150  dataQueue_t rx_queue;
151  uint8_t rx_buffers[ADV_RX_BUFFERS_NUM][ADV_RX_BUFFERS_LEN];
152  uint8_t *rx_queue_current;
153 } ble_adv_param_t;
154 
155 static ble_adv_param_t adv_param;
156 static void advertising_event(struct rtimer *t, void *ptr);
157 /*---------------------------------------------------------------------------*/
158 /* CONNECTION data structures */
159 #define BLE_MODE_MAX_CONNECTIONS 1
160 
161 /* maximum packet length that is transmitted during a single connection event*/
162 #ifdef BLE_MODE_CONF_CONN_MAX_PACKET_SIZE
163 #define BLE_MODE_CONN_MAX_PACKET_SIZE BLE_MODE_CONF_CONN_MAX_PACKET_SIZE
164 #else
165 #define BLE_MODE_CONN_MAX_PACKET_SIZE 256
166 #endif
167 
168 #define CONN_BLE_BUFFER_SIZE 27 /* maximum size of the data buffer */
169 
170 #define CONN_RX_BUFFERS_OVERHEAD 8
171 #define CONN_RX_BUFFERS_DATA_LEN 60
172 #define CONN_RX_BUFFERS_LEN (CONN_RX_BUFFERS_OVERHEAD + CONN_RX_BUFFERS_DATA_LEN)
173 #define CONN_RX_BUFFERS_NUM 12
174 
175 /* custom status used for tx buffers */
176 #define DATA_ENTRY_FREE 5
177 #define DATA_ENTRY_QUEUED 6
178 
179 #define CONN_TX_BUFFERS_OVERHEAD 9
180 #define CONN_TX_BUFFERS_DATA_LEN 27
181 #define CONN_TX_BUFFERS_LEN (CONN_TX_BUFFERS_OVERHEAD + CONN_TX_BUFFERS_DATA_LEN)
182 #define CONN_TX_BUFFERS_NUM 12
183 
184 #define CONN_WIN_SIZE 1
185 #define CONN_WIN_OFFSET 20
186 
187 #define CONN_EVENT_LATENCY_THRESHOLD 10
188 #define CONN_WINDOW_WIDENING_TICKS 30 /* appr. 0.46 ms */
189 #define CONN_PREPROCESSING_TIME_TICKS 100 /* 1.5 ms */
190 
191 #define CONN_UPDATE_DELAY 6
192 
193 typedef struct {
194  /* PARAMETER */
195  uint8_t peer_address[BLE_ADDR_SIZE];
196  uint32_t access_address;
197  uint8_t crc_init_0;
198  uint8_t crc_init_1;
199  uint8_t crc_init_2;
200  uint8_t win_size;
201  uint16_t win_offset;
202  uint16_t interval;
203  uint16_t latency;
204  uint16_t timeout;
205  uint64_t channel_map;
206  uint8_t num_used_channels;
207  uint8_t hop;
208  uint8_t sca;
209  rtimer_clock_t timestamp_rt;
210  /* STATE information */
211  uint8_t active;
212  uint16_t counter;
213  uint8_t unmapped_channel;
214  uint8_t mapped_channel;
215  rtimer_clock_t start_rt;
216  uint16_t conn_handle;
217  struct rtimer timer;
218  /* utility */
219  uint8_t cmd_buf[CMD_BUFFER_SIZE];
220  uint8_t param_buf[PARAM_BUFFER_SIZE];
221  uint8_t output_buf[OUTPUT_BUFFER_SIZE];
222  dataQueue_t rx_queue;
223  uint8_t rx_buffers[CONN_RX_BUFFERS_NUM][CONN_RX_BUFFERS_LEN];
224  uint8_t *rx_queue_current;
225  dataQueue_t tx_queue;
226  uint8_t tx_buffers[CONN_TX_BUFFERS_NUM][CONN_TX_BUFFERS_LEN];
227  uint8_t tx_buffers_sent;
228  uint16_t skipped_events;
229  /* channel map update */
230  uint64_t channel_update_channel_map;
231  uint16_t channel_update_counter;
232  uint8_t channel_update_num_used_channels;
233  /* connection parameter update */
234  uint8_t conn_update_win_size;
235  uint16_t conn_update_win_offset;
236  uint16_t conn_update_interval;
237  uint16_t conn_update_latency;
238  uint16_t conn_update_timeout;
239  uint16_t conn_update_counter;
240 } ble_conn_param_t;
241 
242 static ble_conn_param_t conn_param[BLE_MODE_MAX_CONNECTIONS];
243 
244 static uint16_t conn_counter = 0;
245 
246 static void connection_event_slave(struct rtimer *t, void *ptr);
247 /*---------------------------------------------------------------------------*/
248 PROCESS(ble_hal_conn_rx_process, "BLE/CC26xx connection RX process");
249 process_event_t rx_data_event;
250 /*---------------------------------------------------------------------------*/
251 static void
252 setup_buffers(void)
253 {
254  uint8_t conn_count;
255  ble_conn_param_t *conn;
256  uint8_t i;
257  rfc_dataEntry_t *entry;
258 
259  /* setup advertisement RX buffer (circular buffer) */
260  memset(&adv_param, 0x00, sizeof(ble_adv_param_t));
261  memset(&adv_param.rx_queue, 0x00, sizeof(adv_param.rx_queue));
262  adv_param.rx_queue.pCurrEntry = adv_param.rx_buffers[0];
263  adv_param.rx_queue.pLastEntry = NULL;
264  adv_param.rx_queue_current = adv_param.rx_buffers[0];
265  for(i = 0; i < ADV_RX_BUFFERS_NUM; i++) {
266  memset(&adv_param.rx_buffers[i], 0x00, ADV_RX_BUFFERS_LEN);
267  entry = (rfc_dataEntry_t *)adv_param.rx_buffers[i];
268  entry->pNextEntry = adv_param.rx_buffers[(i + 1) % ADV_RX_BUFFERS_NUM];
269  entry->config.lenSz = 1;
270  entry->length = ADV_RX_BUFFERS_DATA_LEN;
271  }
272 
273  memset(conn_param, 0x00, sizeof(ble_conn_param_t) * BLE_MODE_MAX_CONNECTIONS);
274  for(conn_count = 0; conn_count < BLE_MODE_MAX_CONNECTIONS; conn_count++) {
275  /* setup connection RX buffer (circular buffer) */
276  conn = &conn_param[conn_count];
277  memset(&conn->rx_queue, 0x00, sizeof(conn->rx_queue));
278  conn->rx_queue.pCurrEntry = conn->rx_buffers[0];
279  conn->rx_queue.pLastEntry = NULL;
280  conn->rx_queue_current = conn->rx_buffers[0];
281 
282  for(i = 0; i < CONN_RX_BUFFERS_NUM; i++) {
283  memset(&conn->rx_buffers[i], 0x00, CONN_RX_BUFFERS_LEN);
284  entry = (rfc_dataEntry_t *)conn->rx_buffers[i];
285  entry->pNextEntry = conn->rx_buffers[(i + 1) % CONN_RX_BUFFERS_NUM];
286  entry->config.lenSz = 1;
287  entry->length = CONN_RX_BUFFERS_DATA_LEN;
288  }
289 
290  /* setup connection TX buffer (buffers are added on demand to the queue) */
291  memset(&conn->tx_queue, 0x00, sizeof(conn->tx_queue));
292  conn->tx_queue.pCurrEntry = NULL;
293  conn->tx_queue.pLastEntry = NULL;
294 
295  for(i = 0; i < CONN_TX_BUFFERS_NUM; i++) {
296  memset(&conn->tx_buffers[i], 0x00, CONN_TX_BUFFERS_LEN);
297  entry = (rfc_dataEntry_t *)conn->tx_buffers[i];
298  entry->config.lenSz = 1;
299  entry->status = DATA_ENTRY_FREE;
300  }
301  }
302 }
303 /*---------------------------------------------------------------------------*/
304 static ble_conn_param_t *
305 get_connection_for_handle(uint8_t conn_handle)
306 {
307  uint8_t i;
308  for(i = 0; i < BLE_MODE_MAX_CONNECTIONS; i++) {
309  if(conn_param[i].conn_handle == conn_handle) {
310  return &conn_param[i];
311  }
312  }
313  return NULL;
314 }
315 /*---------------------------------------------------------------------------*/
316 static uint8_t *
317 tx_queue_get_buffer(ble_conn_param_t *param)
318 {
319  uint8_t i;
320  rfc_dataEntry_t *entry;
321  for(i = 0; i < CONN_TX_BUFFERS_NUM; i++) {
322  entry = (rfc_dataEntry_t *)param->tx_buffers[i];
323  if(entry->status == DATA_ENTRY_FREE) {
324  return (uint8_t *)entry;
325  }
326  }
327  return NULL;
328 }
329 /*---------------------------------------------------------------------------*/
330 static uint16_t
331 tx_queue_count_free_buffers(ble_conn_param_t *param)
332 {
333  uint16_t i;
334  uint16_t free_bufs = 0;
335  for(i = 0; i < CONN_TX_BUFFERS_NUM; i++) {
336  if(TX_ENTRY_STATUS(param->tx_buffers[i]) == DATA_ENTRY_FREE) {
337  free_bufs++;
338  }
339  }
340  return free_bufs;
341 }
342 /*---------------------------------------------------------------------------*/
343 static uint8_t
344 tx_queue_data_to_transmit(ble_conn_param_t *param)
345 {
346  uint16_t i;
347  for(i = 0; i < CONN_TX_BUFFERS_NUM; i++) {
348  if(TX_ENTRY_STATUS(param->tx_buffers[i]) == DATA_ENTRY_QUEUED) {
349  return 1;
350  }
351  }
352  return 0;
353 }
354 /*---------------------------------------------------------------------------*/
355 ble_result_t
356 on(void)
357 {
359  if(!rf_core_is_accessible()) {
360  /* boot the rf core */
361  if(rf_core_boot() != RF_CORE_CMD_OK) {
362  LOG_ERR("ble_controller_reset() could not boot rf-core\n");
363  return BLE_RESULT_ERROR;
364  }
365 
368 
369  if(rf_ble_cmd_setup_ble_mode() != RF_BLE_CMD_OK) {
370  LOG_ERR("could not setup rf-core to BLE mode\n");
371  return BLE_RESULT_ERROR;
372  }
373  }
374  return BLE_RESULT_OK;
375 }
376 /*---------------------------------------------------------------------------*/
377 void
378 off(void)
379 {
382 }
383 /*---------------------------------------------------------------------------*/
384 static ble_result_t
385 reset(void)
386 {
387  LOG_INFO("maximum connections: %4d\n", BLE_MODE_MAX_CONNECTIONS);
388  LOG_INFO("max. packet length: %4d\n", BLE_MODE_CONN_MAX_PACKET_SIZE);
389  lpm_register_module(&cc26xx_ble_lpm_module);
391  setup_buffers();
392  if(on() != BLE_RESULT_OK) {
393  return BLE_RESULT_ERROR;
394  }
395  off();
396  if(!process_is_running(&ble_hal_conn_rx_process)) {
397  rx_data_event = process_alloc_event();
398  process_start(&ble_hal_conn_rx_process, NULL);
399  }
400  return BLE_RESULT_OK;
401 }
402 /*---------------------------------------------------------------------------*/
403 static ble_result_t
404 read_bd_addr(uint8_t *addr)
405 {
406  ble_addr_cpy_to(addr);
407  return BLE_RESULT_OK;
408 }
409 /*---------------------------------------------------------------------------*/
410 static ble_result_t
411 read_buffer_size(unsigned int *buf_len, unsigned int *num_buf)
412 {
413  uint16_t i;
414  uint16_t ll_buffers = CONN_TX_BUFFERS_NUM;
415  uint16_t packet_buffers;
416  uint16_t buffer_size;
417  for(i = 0; i < conn_counter; i++) {
418  ll_buffers = MIN(ll_buffers, tx_queue_count_free_buffers(&conn_param[i]));
419  }
420  packet_buffers = ll_buffers / (BLE_MODE_CONN_MAX_PACKET_SIZE / CONN_BLE_BUFFER_SIZE);
421  buffer_size = BLE_MODE_CONN_MAX_PACKET_SIZE;
422  memcpy(buf_len, &buffer_size, 2);
423  memcpy(num_buf, &packet_buffers, 2);
424  return BLE_RESULT_OK;
425 }
426 /*---------------------------------------------------------------------------*/
427 static ble_result_t
428 set_adv_param(unsigned int adv_int, ble_adv_type_t type,
429  ble_addr_type_t own_type, unsigned short adv_map)
430 {
431  adv_param.adv_interval = adv_int;
432  adv_param.adv_type = type;
433  adv_param.own_addr_type = own_type;
434  adv_param.channel_map = adv_map;
435 
436  LOG_INFO("advertising parameter: interval: %4d, channels: %2d\n",
437  adv_param.adv_interval, adv_param.channel_map);
438 
439  LOG_DBG("interval: %16u (ms)\n", adv_param.adv_interval);
440  LOG_DBG("type: %16u\n", adv_param.adv_type);
441  LOG_DBG("addr_type:%16u\n", adv_param.own_addr_type);
442  LOG_DBG("channels: %16u\n", adv_param.channel_map);
443 
444  return BLE_RESULT_OK;
445 }
446 /*---------------------------------------------------------------------------*/
447 static ble_result_t
448 read_adv_channel_tx_power(short *power)
449 {
450  return BLE_RESULT_NOT_SUPPORTED;
451 }
452 /*---------------------------------------------------------------------------*/
453 static ble_result_t
454 set_adv_data(unsigned short data_len, char *data)
455 {
456  if(data_len > BLE_ADV_DATA_LEN) {
457  LOG_WARN("BLE-HAL: adv_data too long\n");
458  return BLE_RESULT_INVALID_PARAM;
459  }
460  adv_param.adv_data_len = data_len;
461  memcpy(adv_param.adv_data, data, data_len);
462  return BLE_RESULT_OK;
463 }
464 /*---------------------------------------------------------------------------*/
465 static ble_result_t
466 set_scan_resp_data(unsigned short data_len, char *data)
467 {
468  if(data_len > BLE_SCAN_RESP_DATA_LEN) {
469  LOG_WARN("BLE-HAL: scan_resp_data too long\n");
470  return BLE_RESULT_INVALID_PARAM;
471  }
472  adv_param.scan_rsp_data_len = data_len;
473  memcpy(adv_param.scan_rsp_data, data, data_len);
474  return BLE_RESULT_OK;
475 }
476 /*---------------------------------------------------------------------------*/
477 static ble_result_t
478 set_adv_enable(unsigned short enable)
479 {
480  uint32_t now = RTIMER_NOW();
481  if((enable) && (!adv_param.active)) {
482  adv_param.start_rt = now + ticks_from_unit(adv_param.adv_interval,
483  TIME_UNIT_1_25_MS);
484  rtimer_set(&adv_param.timer, adv_param.start_rt,
485  0, advertising_event, (void *)&adv_param);
486  }
487  return BLE_RESULT_OK;
488 }
489 /*---------------------------------------------------------------------------*/
490 static ble_result_t
491 send_frame(ble_conn_param_t *conn, uint8_t *data, uint8_t data_len, uint8_t frame_type)
492 {
493  uint8_t *tx_buffer = tx_queue_get_buffer(conn);
494  if(tx_buffer == NULL) {
495  LOG_WARN("BLE-HAL: send_frame: no TX buffer available (conn_handle: 0x%04X)\n", conn->conn_handle);
496  return BLE_RESULT_ERROR;
497  }
498  if(data_len > CONN_BLE_BUFFER_SIZE) {
499  LOG_WARN("BLE-HAL: send_frame: data too long (%d bytes)\n", data_len);
500  return BLE_RESULT_ERROR;
501  }
502 
503  memcpy(TX_ENTRY_DATA_PTR(tx_buffer), data, data_len);
504  TX_ENTRY_LENGTH(tx_buffer) = data_len + 1;
505  TX_ENTRY_STATUS(tx_buffer) = DATA_ENTRY_QUEUED;
506  TX_ENTRY_FRAME_TYPE(tx_buffer) = frame_type;
507  return BLE_RESULT_OK;
508 }
509 /*---------------------------------------------------------------------------*/
510 static ble_result_t
511 connection_update(unsigned int connection_handle, unsigned int conn_interval,
512  unsigned int conn_latency, unsigned int supervision_timeout)
513 {
514  uint8_t len = 0;
515  uint8_t data[24];
516  ble_conn_param_t *conn = get_connection_for_handle(connection_handle);
517 
518  if(conn == NULL) {
519  return BLE_RESULT_ERROR;
520  }
521 
522  LOG_INFO("connection_update: handle: 0x%04X, interval: %4d, latency: %2d, timeout: %4d\n",
523  connection_handle, conn_interval, conn_latency, supervision_timeout);
524 #if UIP_CONF_ROUTER
525  uint16_t instant = conn->counter + CONN_UPDATE_DELAY;
526  /* prepare connection update packet */
527  data[0] = BLE_LL_CONN_UPDATE_REQ;
528  data[1] = conn->win_size;
529  data[2] = 0;
530  data[3] = 0;
531  memcpy(&data[4], &conn_interval, 2);
532  memcpy(&data[6], &conn_latency, 2);
533  memcpy(&data[8], &supervision_timeout, 2);
534  memcpy(&data[10], &instant, 2);
535  len = 12;
536  /* set new connection */
537  conn->conn_update_win_size = conn->win_size;
538  conn->conn_update_interval = conn_interval;
539  conn->conn_update_latency = conn_latency;
540  conn->conn_update_timeout = supervision_timeout;
541  conn->conn_update_counter = instant;
542 
543  if(send_frame(conn, data, len, BLE_DATA_PDU_LLID_CONTROL) != BLE_RESULT_OK) {
544  LOG_ERR("connection_update: send frame was NOT successful\n");
545  return BLE_RESULT_ERROR;
546  }
547 #else
548  data[0] = BLE_LL_CONN_PARAM_REQ;
549  memcpy(&data[1], &conn_interval, 2); /* interval min */
550  memcpy(&data[3], &conn_interval, 2); /* interval max */
551  memcpy(&data[5], &conn_latency, 2); /* latency */
552  memcpy(&data[7], &supervision_timeout, 2); /* supervision timeout */
553  memcpy(&data[9], &conn_interval, 1); /* preferred periodicity */
554  memcpy(&data[10], &conn->counter, 2); /* referenc conn event count */
555  memset(&data[12], 0xFF, 12); /* offset 0 to 5 */
556  len = 24;
557 
558  if(send_frame(conn, data, len, BLE_DATA_PDU_LLID_CONTROL) != BLE_RESULT_OK) {
559  LOG_ERR("connection_update: send frame was NOT successful\n");
560  return BLE_RESULT_ERROR;
561  }
562 #endif
563  return BLE_RESULT_OK;
564 }
565 /*---------------------------------------------------------------------------*/
566 static ble_result_t
567 send(void *buf, unsigned short buf_len)
568 {
569  uint16_t loop_data;
570  uint16_t loop_conn;
571  ble_conn_param_t *conn;
572  uint8_t *data;
573  uint16_t data_len;
574  linkaddr_t dest_addr;
575  linkaddr_t conn_addr;
576  uint8_t result;
577 
578  linkaddr_copy(&dest_addr, packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
579 
580  LOG_DBG("ble-hal: sending %d bytes\n", buf_len);
581 
582  for(loop_conn = 0; loop_conn < conn_counter; loop_conn++) {
583  conn = &conn_param[loop_conn];
584  ble_addr_to_eui64(conn_addr.u8, conn->peer_address);
585  if((linkaddr_cmp(&dest_addr, &linkaddr_null) != 0) || (linkaddr_cmp(&dest_addr, &conn_addr) != 0)) {
586  for(loop_data = 0; loop_data < buf_len; loop_data += CONN_BLE_BUFFER_SIZE) {
587  data = &((uint8_t *)buf)[loop_data];
588  data_len = MIN((buf_len - loop_data), CONN_BLE_BUFFER_SIZE);
589  if(loop_data == 0) {
590  result = send_frame(conn, data, data_len, BLE_DATA_PDU_LLID_DATA_MESSAGE);
591  } else {
592  result = send_frame(conn, data, data_len, BLE_DATA_PDU_LLID_DATA_FRAGMENT);
593  }
594  if(result != BLE_RESULT_OK) {
595  LOG_WARN("ble-hal: send was unsuccessful\n");
596  return result;
597  }
598  }
599  }
600  }
601  return BLE_RESULT_OK;
602 }
603 /*---------------------------------------------------------------------------*/
604 static ble_result_t
605 read_connection_interval(unsigned int conn_handle, unsigned int *conn_interval)
606 {
607  ble_conn_param_t *conn = get_connection_for_handle(conn_handle);
608  if(conn == NULL) {
609  memset(conn_interval, 0x00, sizeof(uint16_t));
610  return BLE_RESULT_ERROR;
611  }
612  memcpy(conn_interval, &conn->interval, sizeof(uint16_t));
613  return BLE_RESULT_OK;
614 }
615 /*---------------------------------------------------------------------------*/
616 const struct ble_hal_driver ble_hal =
617 {
618  reset,
619  read_bd_addr,
623  set_adv_data,
626  NULL,
627  NULL,
628  NULL,
629  NULL,
631  NULL,
632  send,
633  NULL,
634  read_connection_interval
635 };
636 /*---------------------------------------------------------------------------*/
637 static void
638 advertising_rx(ble_adv_param_t *param)
639 {
640  uint8_t i;
641  uint8_t offset = 14;
642  uint8_t *rx_data;
643  ble_conn_param_t *c_param = &conn_param[0];
644  rtimer_clock_t wakeup;
645 
646  while(RX_ENTRY_STATUS(param->rx_queue_current) == DATA_ENTRY_FINISHED) {
647  rx_data = RX_ENTRY_DATA_PTR(param->rx_queue_current);
648 
649  if(CMD_GET_STATUS(param->cmd_buf) == RF_CORE_RADIO_OP_STATUS_BLE_DONE_CONNECT) {
650  /* parsing connection parameter */
651  for(i = 0; i < BLE_ADDR_SIZE; i++) {
652  c_param->peer_address[i] = rx_data[BLE_ADDR_SIZE + 1 - i];
653  }
654  memcpy(&c_param->access_address, &rx_data[offset], 4);
655  memcpy(&c_param->crc_init_0, &rx_data[offset + 4], 1);
656  memcpy(&c_param->crc_init_1, &rx_data[offset + 5], 1);
657  memcpy(&c_param->crc_init_2, &rx_data[offset + 6], 1);
658  memcpy(&c_param->win_size, &rx_data[offset + 7], 1);
659  memcpy(&c_param->win_offset, &rx_data[offset + 8], 2);
660  memcpy(&c_param->interval, &rx_data[offset + 10], 2);
661  memcpy(&c_param->latency, &rx_data[offset + 12], 2);
662  memcpy(&c_param->timeout, &rx_data[offset + 14], 2);
663  memcpy(&c_param->channel_map, &rx_data[offset + 16], 5);
664  memcpy(&c_param->hop, &rx_data[offset + 21], 1);
665  memcpy(&c_param->sca, &rx_data[offset + 21], 1);
666  memcpy(&c_param->timestamp_rt, &rx_data[offset + 24], 4);
667 
668  /* convert all received timing values to rtimer ticks */
669 
670  c_param->timestamp_rt = ticks_from_unit(c_param->timestamp_rt, TIME_UNIT_RF_CORE);
671  c_param->hop = c_param->hop & 0x1F;
672  c_param->sca = (c_param->sca >> 5) & 0x07;
673 
674  LOG_INFO("connection created: conn_int: %4u, latency: %3u, channel_map: %8llX\n",
675  c_param->interval, c_param->latency, c_param->channel_map);
676 
677  LOG_DBG("access address: 0x%08lX\n", c_param->access_address);
678  LOG_DBG("crc0: 0x%02X\n", c_param->crc_init_0);
679  LOG_DBG("crc1: 0x%02X\n", c_param->crc_init_1);
680  LOG_DBG("crc2: 0x%02X\n", c_param->crc_init_2);
681  LOG_DBG("win_size: %4u\n", c_param->win_size);
682  LOG_DBG("win_offset: %4u\n", c_param->win_offset);
683  LOG_DBG("interval: %4u\n", c_param->interval);
684  LOG_DBG("latency: %4u\n", c_param->latency);
685  LOG_DBG("timeout: %4u\n", c_param->timeout);
686  LOG_DBG("channel_map: %llX\n", c_param->channel_map);
687 
688  /* calculate the first anchor point
689  * (add an interval, because we skip the first connection event ) */
690  wakeup = c_param->timestamp_rt + ticks_from_unit(c_param->win_offset, TIME_UNIT_1_25_MS) - CONN_WINDOW_WIDENING_TICKS;
691  wakeup += ticks_from_unit(c_param->interval, TIME_UNIT_1_25_MS) - CONN_PREPROCESSING_TIME_TICKS;
692  rtimer_set(&c_param->timer, wakeup, 0, connection_event_slave, (void *)c_param);
693 
694  /* initialization for the connection */
695  c_param->counter = 0;
696  c_param->unmapped_channel = 0;
697  c_param->conn_handle = conn_counter;
698  c_param->active = 1;
699  conn_counter++;
700  LOG_INFO("BLE-HAL: connection (0x%04X) created\n", c_param->conn_handle);
701  }
702 
703  /* free current entry (clear BLE data length & reset status) */
704  RX_ENTRY_DATA_LENGTH(param->rx_queue_current) = 0;
705  RX_ENTRY_STATUS(param->rx_queue_current) = DATA_ENTRY_PENDING;
706  param->rx_queue_current = RX_ENTRY_NEXT_ENTRY(param->rx_queue_current);
707  }
708 }
709 /*---------------------------------------------------------------------------*/
710 static void
711 advertising_event(struct rtimer *t, void *ptr)
712 {
713  ble_adv_param_t *param = (ble_adv_param_t *)ptr;
714  uint32_t wakeup;
715 
716  if(on() != BLE_RESULT_OK) {
717  LOG_ERR("BLE-HAL: advertising event: could not enable rf core\n");
718  return;
719  }
720 
721  rf_ble_cmd_create_adv_params(param->param_buf, &param->rx_queue,
722  param->adv_data_len, param->adv_data,
723  param->scan_rsp_data_len, param->scan_rsp_data,
724  param->own_addr_type, (uint8_t *)BLE_ADDR_LOCATION);
725 
726  /* advertising on advertisement channel 1*/
727  if(param->channel_map & BLE_ADV_CHANNEL_1_MASK) {
728  rf_ble_cmd_create_adv_cmd(param->cmd_buf, BLE_ADV_CHANNEL_1,
729  param->param_buf, param->output_buf);
730  rf_ble_cmd_send(param->cmd_buf);
731  rf_ble_cmd_wait(param->cmd_buf);
732  }
733 
734  off();
735  advertising_rx(param);
736 
737  if(conn_param[0].active == 1) {
738  LOG_INFO("stop advertising\n");
739  return;
740  }
741 
742  param->start_rt = param->start_rt + ticks_from_unit(param->adv_interval, TIME_UNIT_MS);
743  wakeup = adv_param.start_rt - ADV_PREPROCESSING_TIME_TICKS;
744  rtimer_set(&param->timer, wakeup, 0, advertising_event, (void *)param);
745 }
746 /*---------------------------------------------------------------------------*/
747 static void
748 update_data_channel(ble_conn_param_t *param)
749 {
750  uint8_t i;
751  uint8_t j;
752  uint8_t remap_index;
753  /* perform the data channel selection according to BLE standard */
754 
755  /* calculate unmapped channel*/
756  param->unmapped_channel = (param->unmapped_channel + param->hop) % (BLE_DATA_CHANNEL_MAX + 1);
757 
758  /* map the calculated channel */
759  if(param->channel_map & (1ULL << param->unmapped_channel)) {
760  /* channel is marked as used */
761  param->mapped_channel = param->unmapped_channel;
762  } else {
763  remap_index = param->unmapped_channel % param->num_used_channels;
764  j = 0;
765  for(i = 0; i < (BLE_DATA_CHANNEL_MAX + 1); i++) {
766  if(param->channel_map & (1ULL << i)) {
767  if(j == remap_index) {
768  param->mapped_channel = i;
769  }
770  j++;
771  }
772  }
773  }
774 }
775 /*---------------------------------------------------------------------------*/
776 static void
777 process_ll_ctrl_msg(ble_conn_param_t *conn, uint8_t input_len, uint8_t *input, uint8_t *output_len, uint8_t *output)
778 {
779  uint8_t op_code = input[0];
780  uint16_t interval;
781  uint16_t latency;
782  uint16_t timeout;
783  uint64_t channel_map = 0;
784  uint16_t instant = 0;
785  uint8_t i;
786 
787  if(op_code == BLE_LL_CONN_UPDATE_REQ) {
788  LOG_INFO("BLE-HAL: connection update request received\n");
789  memcpy(&conn->conn_update_win_size, &input[1], 1);
790  memcpy(&conn->conn_update_win_offset, &input[2], 2);
791  memcpy(&conn->conn_update_interval, &input[4], 2);
792  memcpy(&conn->conn_update_latency, &input[6], 2);
793  memcpy(&conn->conn_update_timeout, &input[8], 2);
794  memcpy(&conn->conn_update_counter, &input[10], 2);
795  } else if(op_code == BLE_LL_CHANNEL_MAP_REQ) {
796  LOG_INFO("BLE-HAL: channel map update received\n");
797  memcpy(&channel_map, &input[1], 5);
798  memcpy(&instant, &input[6], 2);
799 
800  conn->channel_update_channel_map = channel_map;
801  conn->channel_update_counter = instant;
802  conn->channel_update_num_used_channels = 0;
803  for(i = 0; i <= BLE_DATA_CHANNEL_MAX; i++) {
804  if(channel_map & (1ULL << i)) {
805  conn->channel_update_num_used_channels++;
806  }
807  }
808  } else if(op_code == BLE_LL_FEATURE_REQ) {
809  LOG_INFO("BLE-HAL: feature request received\n");
810  output[0] = BLE_LL_FEATURE_RSP;
811  memset(&output[1], 0x00, 8);
812  *output_len = 9;
813  } else if(op_code == BLE_LL_VERSION_IND) {
814  LOG_INFO("BLE-HAL: version request received\n");
815  output[0] = BLE_LL_VERSION_IND;
816  output[1] = 7;
817  memset(&output[2], 0xAA, 4);
818  *output_len = 6;
819  } else if(op_code == BLE_LL_CONN_PARAM_REQ) {
820  LOG_INFO("BLE-HAL: connection parameter request received\n");
821  memcpy(&interval, &input[1], 2); /* use interval min */
822  memcpy(&latency, &input[5], 2);
823  memcpy(&timeout, &input[7], 2);
824  connection_update(conn->conn_handle, interval, latency, timeout);
825  } else {
826  LOG_WARN("BLE-HAL: unknown LL control code: %02X\n", op_code);
827  }
828 }
829 /*---------------------------------------------------------------------------*/
830 static void
831 connection_rx(ble_conn_param_t *param)
832 {
833  uint8_t header_offset = 2;
834  uint8_t *rx_data;
835  uint16_t len;
836  uint8_t channel;
837  uint8_t frame_type;
838  uint8_t more_data;
839  uint8_t rssi;
840  linkaddr_t sender_addr;
841  rfc_bleMasterSlaveOutput_t *out_buf = (rfc_bleMasterSlaveOutput_t *)param->output_buf;
842 
843  uint8_t output_len = 0;
844  uint8_t output[26];
845 
846  while(RX_ENTRY_STATUS(param->rx_queue_current) == DATA_ENTRY_FINISHED) {
847  rx_data = RX_ENTRY_DATA_PTR(param->rx_queue_current);
848  len = RX_ENTRY_DATA_LENGTH(param->rx_queue_current) - 6 - 2; /* last 8 bytes are status, timestamp, ... */
849  channel = (rx_data[len + 3] & 0x3F);
850  frame_type = rx_data[0] & 0x03;
851  more_data = (rx_data[0] & 0x10) >> 4;
852 
853  if(frame_type == BLE_DATA_PDU_LLID_CONTROL) {
854  process_ll_ctrl_msg(param, (len - header_offset), &rx_data[header_offset], &output_len, output);
855  if(output_len > 0) {
856  send_frame(param, output, output_len, BLE_DATA_PDU_LLID_CONTROL);
857  }
858  } else if(frame_type == BLE_DATA_PDU_LLID_DATA_MESSAGE) {
859  packetbuf_clear();
860  memcpy(packetbuf_dataptr(), &rx_data[header_offset], len);
862  rssi = out_buf->lastRssi;
863  ble_addr_to_eui64(sender_addr.u8, param->peer_address);
864  packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
865  packetbuf_set_attr(PACKETBUF_ATTR_CHANNEL, channel);
866  packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &linkaddr_node_addr);
867  packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &sender_addr);
868  packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME_BLE_RX_EVENT);
869  if((!more_data) || (len < CONN_BLE_BUFFER_SIZE)) {
870  NETSTACK_MAC.input();
871  }
872  } else if(frame_type == BLE_DATA_PDU_LLID_DATA_FRAGMENT) {
873  memcpy((packetbuf_dataptr() + packetbuf_datalen()), &rx_data[header_offset], len);
875  if((!more_data) || (len < CONN_BLE_BUFFER_SIZE)) {
876  NETSTACK_MAC.input();
877  }
878  }
879 
880  /* free current entry (clear BLE data length & reset status) */
881  RX_ENTRY_DATA_LENGTH(param->rx_queue_current) = 0;
882  RX_ENTRY_STATUS(param->rx_queue_current) = DATA_ENTRY_PENDING;
883  param->rx_queue_current = RX_ENTRY_NEXT_ENTRY(param->rx_queue_current);
884  }
885 }
886 /*---------------------------------------------------------------------------*/
887 static void
888 connection_event_slave(struct rtimer *t, void *ptr)
889 {
890 
891  ble_conn_param_t *conn = (ble_conn_param_t *)ptr;
892  rfc_bleMasterSlaveOutput_t *output = (rfc_bleMasterSlaveOutput_t *)conn->output_buf;
893  uint8_t first_packet = 0;
894  rtimer_clock_t wakeup;
895  uint8_t i;
896  uint8_t tx_data = tx_queue_data_to_transmit(conn);
897 
898  if(conn->counter == 0) {
899  /* the slave skips connection event 0, because it is usually too early */
900  conn->start_rt = conn->timestamp_rt + ticks_from_unit(conn->win_offset, TIME_UNIT_1_25_MS) - CONN_WINDOW_WIDENING_TICKS;
901  update_data_channel(conn);
902  first_packet = 1;
903  }
904  conn->counter++;
905 
906  /* connection timing */
907  if(conn->counter == conn->conn_update_counter) {
908  conn->start_rt += ticks_from_unit(conn->interval + conn->conn_update_win_offset, TIME_UNIT_1_25_MS);
909 
910  conn->win_size = conn->conn_update_win_size;
911  conn->win_offset = conn->conn_update_win_offset;
912  conn->interval = conn->conn_update_interval;
913  conn->latency = conn->conn_update_latency;
914  conn->timeout = conn->conn_update_timeout;
915  conn->conn_update_win_size = 0;
916  conn->conn_update_win_offset = 0;
917  conn->conn_update_interval = 0;
918  conn->conn_update_latency = 0;
919  conn->conn_update_timeout = 0;
920  } else if(output->pktStatus.bTimeStampValid) {
921  conn->start_rt = ticks_from_unit(output->timeStamp, TIME_UNIT_RF_CORE) +
922  ticks_from_unit(conn->interval, TIME_UNIT_1_25_MS) - CONN_WINDOW_WIDENING_TICKS;
923  } else {
924  conn->start_rt += ticks_from_unit(conn->interval, TIME_UNIT_1_25_MS);
925  }
926 
927  /* connection channel */
928  if(conn->channel_update_counter == conn->counter) {
929  conn->channel_map = conn->channel_update_channel_map;
930  conn->num_used_channels = conn->channel_update_num_used_channels;
931  conn->channel_update_counter = 0;
932  conn->channel_update_channel_map = 0;
933  conn->channel_update_num_used_channels = 0;
934  }
935  update_data_channel(conn);
936 
937  if(tx_data || (conn->skipped_events >= conn->latency) || (conn->counter < CONN_EVENT_LATENCY_THRESHOLD)) {
938  /* participating in the connection event */
939  conn->skipped_events = 0;
940  rf_ble_cmd_create_slave_params(conn->param_buf, &conn->rx_queue, &conn->tx_queue, conn->access_address,
941  conn->crc_init_0, conn->crc_init_1, conn->crc_init_2,
942  ticks_to_unit(ticks_from_unit(conn->win_size, TIME_UNIT_1_25_MS), TIME_UNIT_RF_CORE),
943  ticks_to_unit(CONN_WINDOW_WIDENING_TICKS, TIME_UNIT_RF_CORE), first_packet);
944 
945  rf_ble_cmd_create_slave_cmd(conn->cmd_buf, conn->mapped_channel, conn->param_buf, conn->output_buf,
946  ticks_to_unit(conn->start_rt, TIME_UNIT_RF_CORE));
947 
948  if(on() != BLE_RESULT_OK) {
949  LOG_ERR("connection_event: could not enable radio core\n");
950  return;
951  }
952 
953  /* append TX buffers */
954  for(i = 0; i < CONN_TX_BUFFERS_NUM; i++) {
955  if(TX_ENTRY_STATUS(conn->tx_buffers[i]) == DATA_ENTRY_QUEUED) {
956  TX_ENTRY_STATUS(conn->tx_buffers[i]) = DATA_ENTRY_PENDING;
957  rf_ble_cmd_add_data_queue_entry(&conn->tx_queue, conn->tx_buffers[i]);
958  }
959  }
960  rf_ble_cmd_send(conn->cmd_buf);
961  rf_ble_cmd_wait(conn->cmd_buf);
962  off();
963 
964  if(CMD_GET_STATUS(conn->cmd_buf) != RF_CORE_RADIO_OP_STATUS_BLE_DONE_OK) {
965  LOG_DBG("command status: 0x%04X; connection event counter: %d, channel: %d\n",
966  CMD_GET_STATUS(conn->cmd_buf), conn->counter, conn->mapped_channel);
967  }
968 
969  /* free finished TX buffers */
970  for(i = 0; i < CONN_TX_BUFFERS_NUM; i++) {
971  if(TX_ENTRY_STATUS(conn->tx_buffers[i]) == DATA_ENTRY_FINISHED) {
972  TX_ENTRY_STATUS(conn->tx_buffers[i]) = DATA_ENTRY_FREE;
973  TX_ENTRY_LENGTH(conn->tx_buffers[i]) = 0;
974  TX_ENTRY_NEXT_ENTRY(conn->tx_buffers[i]) = NULL;
975  }
976  }
977  } else {
978  /* skipping connection event */
979  conn->skipped_events++;
980  output->pktStatus.bTimeStampValid = 0;
981  }
982  wakeup = conn->start_rt + ticks_from_unit(conn->interval, TIME_UNIT_1_25_MS) - CONN_PREPROCESSING_TIME_TICKS;
983  rtimer_set(&conn->timer, wakeup, 0, connection_event_slave, ptr);
984  process_post(&ble_hal_conn_rx_process, rx_data_event, ptr);
985 }
986 /*---------------------------------------------------------------------------*/
987 PROCESS_THREAD(ble_hal_conn_rx_process, ev, data) {
988  ble_conn_param_t *conn = (ble_conn_param_t *)data;
989  rfc_bleMasterSlaveOutput_t *output = (rfc_bleMasterSlaveOutput_t *)conn->output_buf;
990  uint8_t tx_buffers_sent;
991  PROCESS_BEGIN();
992  LOG_DBG("BLE-HAL: conn rx process start\n");
993 
994  while(1) {
995  PROCESS_WAIT_EVENT_UNTIL(ev == rx_data_event);
996  /* notify upper layers (L2CAP) when TX buffers were successfully transmitted */
997  tx_buffers_sent = output->nTxEntryDone - conn->tx_buffers_sent;
998  if(tx_buffers_sent != 0) {
999  conn->tx_buffers_sent = output->nTxEntryDone;
1001  packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME_BLE_TX_EVENT);
1002  NETSTACK_MAC.input();
1003  }
1004 
1005  /* handle RX buffers */
1006  connection_rx(conn);
1007 
1008  /* generate an event if the connection parameter were updated */
1009  if(conn->counter == conn->conn_update_counter) {
1011  packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME_BLE_CONNECTION_UPDATED);
1012  NETSTACK_MAC.input();
1013  }
1014  }
1015 
1016  PROCESS_END();
1017 }
void oscillators_request_hf_xosc(void)
Requests the HF XOSC as the source for the HF clock, but does not perform the actual switch...
Definition: oscillators.c:94
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
Definition: packetbuf.c:143
ble_result_t(* reset)(void)
Resets the BLE controller.
Definition: ble-hal.h:254
int rtimer_set(struct rtimer *rtimer, rtimer_clock_t time, rtimer_clock_t duration, rtimer_callback_t func, void *ptr)
Post a real-time task.
Definition: rtimer.c:67
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
Representation of a real-time task.
Definition: rtimer.h:109
void rf_core_setup_interrupts(bool poll_mode)
Setup RF core interrupts.
Definition: rf-core.c:449
Header file with macros which rename TI CC26xxware functions.
void packetbuf_clear(void)
Clear and reset the packetbuf.
Definition: packetbuf.c:75
void rf_ble_cmd_create_adv_params(uint8_t *param, dataQueue_t *rx_queue, uint8_t adv_data_len, uint8_t *adv_data, uint8_t scan_resp_data_len, uint8_t *scan_resp_data, ble_addr_type_t own_addr_type, uint8_t *own_addr)
Creates BLE radio command parameters that are used to enable BLE advertisement on the radio core...
Definition: rf-ble-cmd.c:136
int process_is_running(struct process *p)
Check if a process is running.
Definition: process.c:383
ble_result_t(* set_adv_enable)(unsigned short enable)
Enables/disables advertising.
Definition: ble-hal.h:318
static uip_ds6_addr_t * addr
Pointer to a nbr cache entry.
Definition: uip-nd6.c:115
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
void ble_addr_to_eui64(uint8_t *dst, uint8_t *src)
Copy the node&#39;s BLE address to a destination memory area and converts it into a EUI64 address in the ...
Definition: ble-addr.c:58
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
void rf_core_power_down()
Disable RFCORE clock domain in the MCU VD and turn off the RFCORE PD.
Definition: rf-core.c:347
The structure of a ble radio controller driver in Contiki.
Definition: ble-hal.h:247
#define PROCESS_WAIT_EVENT_UNTIL(c)
Wait for an event to be posted to the process, with an extra condition.
Definition: process.h:157
Header file with declarations for the I/O Control module.
uint8_t rf_core_set_modesel()
Initialise RF APIs in the RF core.
Definition: rf-core.c:385
ble_result_t(* read_adv_channel_tx_power)(short *power)
Reads the used power on the advertisement channels.
Definition: ble-hal.h:293
unsigned short rf_ble_cmd_send(uint8_t *command)
Sends a BLE radio command to the radio.
Definition: rf-ble-cmd.c:72
Header file for the CC13xx/CC26xx RF core driver.
A timer.
Definition: timer.h:82
const linkaddr_t linkaddr_null
The null link-layer address.
static uint8_t output(const linkaddr_t *localdest)
Take an IP packet and format it to be sent on an 802.15.4 network using 6lowpan.
Definition: sicslowpan.c:1549
BLE commands for the TI CC26xx BLE radio.
Driver for the retrieval of an BLE address from flash.
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
Definition: packetbuf.c:155
linkaddr_t linkaddr_node_addr
The link-layer address of the node.
Definition: linkaddr.c:48
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:158
Header file for the CC13xx/CC26xx oscillator control.
unsigned short rf_ble_cmd_setup_ble_mode(void)
Initializes the radio core to be used as a BLE radio.
Definition: rf-ble-cmd.c:98
void oscillators_switch_to_hf_rc(void)
Switches MF and HF clock source to be the HF RC OSC.
Definition: oscillators.c:134
void(* input)(void)
Callback for getting notified of incoming packet.
Definition: mac.h:72
int(* send)(const void *payload, unsigned short payload_len)
Prepare & transmit a packet.
Definition: radio.h:248
hardware abstraction for a BLE controller
void rf_ble_cmd_create_slave_params(uint8_t *params, dataQueue_t *rx_queue, dataQueue_t *tx_queue, uint32_t access_address, uint8_t crc_init_0, uint8_t crc_init_1, uint8_t crc_init_2, uint32_t win_size, uint32_t window_widening, uint8_t first_packet)
Creates BLE radio command parameters that are used to setup a single BLE connection event on the radi...
Definition: rf-ble-cmd.c:187
int(* off)(void)
Turn the radio off.
Definition: radio.h:267
ble_result_t(* set_adv_data)(unsigned short data_len, char *data)
Sets the advertising data.
Definition: ble-hal.h:301
Header file for the real-time timer module.
ble_result_t(* set_adv_param)(unsigned int adv_interval, ble_adv_type_t type, ble_addr_type_t own_addr_type, unsigned short adv_channel_map)
Sets the parameter for advertising.
Definition: ble-hal.h:283
Header file for the Contiki process interface.
ble_result_t(* read_bd_addr)(uint8_t *addr)
Reads the static BLE device address.
Definition: ble-hal.h:261
ble_result_t(* read_buffer_size)(unsigned int *buf_len, unsigned int *num_buf)
Reads the size of the data buffers.
Definition: ble-hal.h:269
unsigned short rf_ble_cmd_wait(uint8_t *command)
Waits for a running BLE radio command to be finished.
Definition: rf-ble-cmd.c:86
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a link-layer address.
Definition: linkaddr.c:63
process_event_t process_alloc_event(void)
Allocate a global event number.
Definition: process.c:93
unsigned short rf_ble_cmd_add_data_queue_entry(dataQueue_t *q, uint8_t *e)
Adds a data buffer to a BLE transmission queue.
Definition: rf-ble-cmd.c:236
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two link-layer addresses.
Definition: linkaddr.c:69
uint8_t rf_core_is_accessible()
Check whether the RF core is accessible.
Definition: rf-core.c:120
void ble_addr_cpy_to(uint8_t *dst)
Copy the node&#39;s factory BLE address to a destination memory area.
Definition: ble-addr.c:47
void oscillators_switch_to_hf_xosc(void)
Performs the switch to the XOSC.
Definition: oscillators.c:116
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
Definition: process.c:322
Header file for the Packet buffer (packetbuf) management
void rf_ble_cmd_create_slave_cmd(uint8_t *cmd, uint8_t channel, uint8_t *params, uint8_t *output, uint32_t start_time)
Creates a BLE radio command structure that sets up a single BLE connection event when sent to the rad...
Definition: rf-ble-cmd.c:168
#define LPM_MODULE(n, m, s, w, l)
Declare a variable to be used in order to get notifications from LPM.
Definition: lpm.h:92
Include file for the Contiki low-layer network stack (NETSTACK)
PROCESS_THREAD(cc2538_rf_process, ev, data)
Implementation of the cc2538 RF driver process.
Definition: cc2538-rf.c:1008
Header file for the logging system
uint8_t rf_core_boot()
Boot the RF Core.
Definition: rf-core.c:408
static void input(void)
Process a received 6lowpan packet.
Definition: sicslowpan.c:1777
void rf_ble_cmd_create_adv_cmd(uint8_t *command, uint8_t channel, uint8_t *param, uint8_t *output)
Creates a BLE radio command structure that enables BLE advertisement when sent to the radio core...
Definition: rf-ble-cmd.c:120
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
Definition: packetbuf.c:136
ble_result_t(* connection_update)(unsigned int connection_handle, unsigned int conn_interval, unsigned int conn_latency, unsigned int supervision_timeout)
Updates the connection parameters.
Definition: ble-hal.h:382
int(* on)(void)
Turn the radio on.
Definition: radio.h:264
void process_start(struct process *p, process_data_t data)
Start a process.
Definition: process.c:99
void lpm_register_module(lpm_registered_module_t *module)
Register a module for LPM notifications.
Definition: lpm.c:537
ble_result_t(* set_scan_resp_data)(unsigned short data_len, char *data)
Sets the scan response data.
Definition: ble-hal.h:310