1 /*
2  * This file is part of the MicroPython project, http://micropython.org/
3  *
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2016 - 2018 Glenn Ruben Bakke
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  */
26 
27 #if BLUETOOTH_SD
28 
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdbool.h>
32 
33 #include "py/runtime.h"
34 #include "ble_drv.h"
35 #include "nrf_sdm.h"
36 #include "ble_gap.h"
37 #include "ble.h" // sd_ble_uuid_encode
38 #include "drivers/flash.h"
39 #include "mphalport.h"
40 
41 
42 #if MICROPY_HW_USB_CDC
43 #include "usb_cdc.h"
44 #endif
45 
46 #define BLE_DRIVER_VERBOSE 0
47 
48 #if BLE_DRIVER_VERBOSE
49   #define BLE_DRIVER_LOG printf
50 #else
51   #define BLE_DRIVER_LOG(...)
52 #endif
53 
54 #define BLE_ADV_LENGTH_FIELD_SIZE   1
55 #define BLE_ADV_AD_TYPE_FIELD_SIZE  1
56 #define BLE_AD_TYPE_FLAGS_DATA_SIZE 1
57 
58 #define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
59 #define UNIT_0_625_MS (625)
60 #define UNIT_10_MS    (10000)
61 #define APP_CFG_NON_CONN_ADV_TIMEOUT 0 // Disable timeout.
62 #define NON_CONNECTABLE_ADV_INTERVAL MSEC_TO_UNITS(100, UNIT_0_625_MS)
63 
64 #define BLE_MIN_CONN_INTERVAL        MSEC_TO_UNITS(12, UNIT_0_625_MS)
65 #define BLE_MAX_CONN_INTERVAL        MSEC_TO_UNITS(12, UNIT_0_625_MS)
66 #define BLE_SLAVE_LATENCY            0
67 #define BLE_CONN_SUP_TIMEOUT         MSEC_TO_UNITS(4000, UNIT_10_MS)
68 
69 #if (BLUETOOTH_SD == 110)
70   #define MAX_TX_IN_PROGRESS         (6)
71 #else
72   #define MAX_TX_IN_PROGRESS         (10)
73 #endif
74 #if !defined(GATT_MTU_SIZE_DEFAULT) && defined(BLE_GATT_ATT_MTU_DEFAULT)
75   #define GATT_MTU_SIZE_DEFAULT BLE_GATT_ATT_MTU_DEFAULT
76 #endif
77 
78 #define SD_TEST_OR_ENABLE() \
79 if (ble_drv_stack_enabled() == 0) { \
80     (void)ble_drv_stack_enable(); \
81 }
82 
83 static volatile bool m_adv_in_progress;
84 static volatile uint8_t m_tx_in_progress;
85 
86 static ble_drv_gap_evt_callback_t          gap_event_handler;
87 static ble_drv_gatts_evt_callback_t        gatts_event_handler;
88 
89 static mp_obj_t mp_gap_observer;
90 static mp_obj_t mp_gatts_observer;
91 
92 #if (BLUETOOTH_SD == 132) || (BLUETOOTH_SD == 140)
93 static volatile bool m_primary_service_found;
94 static volatile bool m_characteristic_found;
95 static volatile bool m_write_done;
96 
97 static volatile ble_drv_adv_evt_callback_t          adv_event_handler;
98 static volatile ble_drv_gattc_evt_callback_t        gattc_event_handler;
99 static volatile ble_drv_disc_add_service_callback_t disc_add_service_handler;
100 static volatile ble_drv_disc_add_char_callback_t    disc_add_char_handler;
101 static volatile ble_drv_gattc_char_data_callback_t  gattc_char_data_handle;
102 
103 static mp_obj_t mp_adv_observer;
104 static mp_obj_t mp_gattc_observer;
105 static mp_obj_t mp_gattc_disc_service_observer;
106 static mp_obj_t mp_gattc_disc_char_observer;
107 static mp_obj_t mp_gattc_char_data_observer;
108 #endif
109 
110 #if (BLUETOOTH_SD == 132) || (BLUETOOTH_SD == 140)
111 #include "nrf_nvic.h"
112 #define BLE_GAP_ADV_MAX_SIZE 31
113 #define BLE_DRV_CONN_CONFIG_TAG 1
114 
115 static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
116 static uint8_t m_scan_buffer[BLE_GAP_SCAN_BUFFER_MIN];
117 
118 nrf_nvic_state_t nrf_nvic_state = {{0}, 0};
119 #endif
120 
121 #if (BLUETOOTH_SD == 110)
softdevice_assert_handler(uint32_t pc,uint16_t line_number,const uint8_t * p_file_name)122 void softdevice_assert_handler(uint32_t pc, uint16_t line_number, const uint8_t * p_file_name) {
123     BLE_DRIVER_LOG("ERROR: SoftDevice assert!!!");
124 }
125 #else
softdevice_assert_handler(uint32_t id,uint32_t pc,uint32_t info)126 void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) {
127     BLE_DRIVER_LOG("ERROR: SoftDevice assert!!!");
128 }
129 #endif
130 
ble_drv_stack_enable(void)131 uint32_t ble_drv_stack_enable(void) {
132     m_adv_in_progress = false;
133     m_tx_in_progress  = 0;
134 
135 #if (BLUETOOTH_SD == 110)
136   #if BLUETOOTH_LFCLK_RC
137     uint32_t err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_RC_250_PPM_250MS_CALIBRATION,
138                                              softdevice_assert_handler);
139   #else
140     uint32_t err_code = sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM,
141                                              softdevice_assert_handler);
142   #endif // BLUETOOTH_LFCLK_RC
143 #endif // (BLUETOOTH_SD == 110)
144 
145 #if (BLUETOOTH_SD == 132) || (BLUETOOTH_SD == 140)
146   #if BLUETOOTH_LFCLK_RC
147     nrf_clock_lf_cfg_t clock_config = {
148         .source = NRF_CLOCK_LF_SRC_RC,
149         .rc_ctiv = 16,
150         .rc_temp_ctiv = 2,
151         .accuracy = NRF_CLOCK_LF_ACCURACY_250_PPM
152     };
153   #else
154     nrf_clock_lf_cfg_t clock_config = {
155         .source = NRF_CLOCK_LF_SRC_XTAL,
156         .rc_ctiv = 0,
157         .rc_temp_ctiv = 0,
158         .accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM
159     };
160   #endif // BLUETOOTH_LFCLK_RC
161 
162     uint32_t err_code = sd_softdevice_enable(&clock_config,
163                                              softdevice_assert_handler);
164 #endif // (BLUETOOTH_SD == 132) || (BLUETOOTH_SD == 140)
165 
166     BLE_DRIVER_LOG("SoftDevice enable status: " UINT_FMT "\n", (uint16_t)err_code);
167 
168     err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn);
169 
170     BLE_DRIVER_LOG("IRQ enable status: " UINT_FMT "\n", (uint16_t)err_code);
171 
172 #if (BLUETOOTH_SD == 110)
173     ble_enable_params_t ble_enable_params;
174     memset(&ble_enable_params, 0x00, sizeof(ble_enable_params));
175     ble_enable_params.gatts_enable_params.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT;
176     ble_enable_params.gatts_enable_params.service_changed  = 0;
177 #else
178     ble_cfg_t ble_conf;
179     uint32_t app_ram_start_cfg = 0x200039c0;
180     ble_conf.conn_cfg.conn_cfg_tag                     = BLE_DRV_CONN_CONFIG_TAG;
181     ble_conf.conn_cfg.params.gap_conn_cfg.conn_count   = 2;
182     ble_conf.conn_cfg.params.gap_conn_cfg.event_length = 3;
183     err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_conf, app_ram_start_cfg);
184 
185     BLE_DRIVER_LOG("BLE_CONN_CFG_GAP status: " UINT_FMT "\n", (uint16_t)err_code);
186 
187     memset(&ble_conf, 0, sizeof(ble_conf));
188 
189     ble_conf.gap_cfg.role_count_cfg.periph_role_count   = 1;
190     ble_conf.gap_cfg.role_count_cfg.central_role_count  = 1;
191     ble_conf.gap_cfg.role_count_cfg.central_sec_count   = 0;
192     err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_conf, app_ram_start_cfg);
193 
194     BLE_DRIVER_LOG("BLE_GAP_CFG_ROLE_COUNT status: " UINT_FMT "\n", (uint16_t)err_code);
195 
196     memset(&ble_conf, 0, sizeof(ble_conf));
197     ble_conf.conn_cfg.conn_cfg_tag                            = BLE_DRV_CONN_CONFIG_TAG;
198     ble_conf.conn_cfg.params.gatts_conn_cfg.hvn_tx_queue_size = MAX_TX_IN_PROGRESS;
199     err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTS, &ble_conf, app_ram_start_cfg);
200 
201     BLE_DRIVER_LOG("BLE_CONN_CFG_GATTS status: " UINT_FMT "\n", (uint16_t)err_code);
202 #endif
203 
204 #if (BLUETOOTH_SD == 110)
205     err_code = sd_ble_enable(&ble_enable_params);
206 #else
207     uint32_t app_ram_start = 0x200039c0;
208     err_code = sd_ble_enable(&app_ram_start); // 8K SD headroom from linker script.
209     BLE_DRIVER_LOG("BLE ram size: " UINT_FMT "\n", (uint16_t)app_ram_start);
210 #endif
211 
212     BLE_DRIVER_LOG("BLE enable status: " UINT_FMT "\n", (uint16_t)err_code);
213 
214     // set up security mode
215     ble_gap_conn_params_t   gap_conn_params;
216     ble_gap_conn_sec_mode_t sec_mode;
217 
218     BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
219 
220     const char device_name[] = "micr";
221 
222     if ((err_code = sd_ble_gap_device_name_set(&sec_mode,
223                                                (const uint8_t *)device_name,
224                                                 strlen(device_name))) != 0) {
225         mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't apply GAP parameters"));
226     }
227 
228     // set connection parameters
229     memset(&gap_conn_params, 0, sizeof(gap_conn_params));
230 
231     gap_conn_params.min_conn_interval = BLE_MIN_CONN_INTERVAL;
232     gap_conn_params.max_conn_interval = BLE_MAX_CONN_INTERVAL;
233     gap_conn_params.slave_latency     = BLE_SLAVE_LATENCY;
234     gap_conn_params.conn_sup_timeout  = BLE_CONN_SUP_TIMEOUT;
235 
236     if (sd_ble_gap_ppcp_set(&gap_conn_params) != 0) {
237         mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't set PPCP parameters"));
238     }
239 
240     return err_code;
241 }
242 
ble_drv_stack_disable(void)243 void ble_drv_stack_disable(void) {
244     sd_softdevice_disable();
245 }
246 
ble_drv_stack_enabled(void)247 uint8_t ble_drv_stack_enabled(void) {
248     uint8_t is_enabled;
249     uint32_t err_code = sd_softdevice_is_enabled(&is_enabled);
250     (void)err_code;
251 
252     BLE_DRIVER_LOG("Is enabled status: " UINT_FMT "\n", (uint16_t)err_code);
253 
254     return is_enabled;
255 }
256 
ble_drv_address_get(ble_drv_addr_t * p_addr)257 void ble_drv_address_get(ble_drv_addr_t * p_addr) {
258     SD_TEST_OR_ENABLE();
259 
260     ble_gap_addr_t local_ble_addr;
261 #if (BLUETOOTH_SD == 110)
262     uint32_t err_code = sd_ble_gap_address_get(&local_ble_addr);
263 #else
264     uint32_t err_code = sd_ble_gap_addr_get(&local_ble_addr);
265 #endif
266 
267     if (err_code != 0) {
268         mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't query for the device address"));
269     }
270 
271     BLE_DRIVER_LOG("ble address, type: " HEX2_FMT ", " \
272                    "address: " HEX2_FMT ":" HEX2_FMT ":" HEX2_FMT ":" \
273                                HEX2_FMT ":" HEX2_FMT ":" HEX2_FMT "\n", \
274                    local_ble_addr.addr_type, \
275                    local_ble_addr.addr[5], local_ble_addr.addr[4], local_ble_addr.addr[3], \
276                    local_ble_addr.addr[2], local_ble_addr.addr[1], local_ble_addr.addr[0]);
277 
278     p_addr->addr_type = local_ble_addr.addr_type;
279     memcpy(p_addr->addr, local_ble_addr.addr, 6);
280 }
281 
ble_drv_uuid_add_vs(uint8_t * p_uuid,uint8_t * idx)282 bool ble_drv_uuid_add_vs(uint8_t * p_uuid, uint8_t * idx) {
283     SD_TEST_OR_ENABLE();
284 
285     if (sd_ble_uuid_vs_add((ble_uuid128_t const *)p_uuid, idx) != 0) {
286         mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't add Vendor Specific 128-bit UUID"));
287     }
288 
289     return true;
290 }
291 
ble_drv_service_add(ubluepy_service_obj_t * p_service_obj)292 bool ble_drv_service_add(ubluepy_service_obj_t * p_service_obj) {
293     SD_TEST_OR_ENABLE();
294 
295     if (p_service_obj->p_uuid->type > BLE_UUID_TYPE_BLE) {
296 
297         ble_uuid_t uuid;
298         uuid.type  = p_service_obj->p_uuid->uuid_vs_idx;
299         uuid.uuid  = p_service_obj->p_uuid->value[0];
300         uuid.uuid += p_service_obj->p_uuid->value[1] << 8;
301 
302         if (sd_ble_gatts_service_add(p_service_obj->type,
303                                      &uuid,
304                                      &p_service_obj->handle) != 0) {
305             mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't add Service"));
306         }
307     } else if (p_service_obj->p_uuid->type == BLE_UUID_TYPE_BLE) {
308         BLE_DRIVER_LOG("adding service\n");
309 
310         ble_uuid_t uuid;
311         uuid.type  = p_service_obj->p_uuid->type;
312         uuid.uuid  = p_service_obj->p_uuid->value[0];
313         uuid.uuid += p_service_obj->p_uuid->value[1] << 8;
314 
315         if (sd_ble_gatts_service_add(p_service_obj->type,
316                                      &uuid,
317                                      &p_service_obj->handle) != 0) {
318             mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't add Service"));
319         }
320     }
321     return true;
322 }
323 
ble_drv_characteristic_add(ubluepy_characteristic_obj_t * p_char_obj)324 bool ble_drv_characteristic_add(ubluepy_characteristic_obj_t * p_char_obj) {
325     ble_gatts_char_md_t char_md;
326     ble_gatts_attr_md_t cccd_md;
327     ble_gatts_attr_t    attr_char_value;
328     ble_uuid_t          uuid;
329     ble_gatts_attr_md_t attr_md;
330 
331     memset(&char_md, 0, sizeof(char_md));
332 
333     char_md.char_props.broadcast      = (p_char_obj->props & UBLUEPY_PROP_BROADCAST) ? 1 : 0;
334     char_md.char_props.read           = (p_char_obj->props & UBLUEPY_PROP_READ) ? 1 : 0;
335     char_md.char_props.write_wo_resp  = (p_char_obj->props & UBLUEPY_PROP_WRITE_WO_RESP) ? 1 : 0;
336     char_md.char_props.write          = (p_char_obj->props & UBLUEPY_PROP_WRITE) ? 1 : 0;
337     char_md.char_props.notify         = (p_char_obj->props & UBLUEPY_PROP_NOTIFY) ? 1 : 0;
338     char_md.char_props.indicate       = (p_char_obj->props & UBLUEPY_PROP_INDICATE) ? 1 : 0;
339 #if 0
340     char_md.char_props.auth_signed_wr = (p_char_obj->props & UBLUEPY_PROP_NOTIFY) ? 1 : 0;
341 #endif
342 
343 
344     char_md.p_char_user_desc  = NULL;
345     char_md.p_char_pf         = NULL;
346     char_md.p_user_desc_md    = NULL;
347     char_md.p_sccd_md         = NULL;
348 
349     // if cccd
350     if (p_char_obj->attrs & UBLUEPY_ATTR_CCCD) {
351         memset(&cccd_md, 0, sizeof(cccd_md));
352         BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
353         BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
354         cccd_md.vloc = BLE_GATTS_VLOC_STACK;
355         char_md.p_cccd_md = &cccd_md;
356     } else {
357         char_md.p_cccd_md = NULL;
358     }
359 
360     uuid.type  = p_char_obj->p_uuid->type;
361     uuid.uuid  = p_char_obj->p_uuid->value[0];
362     uuid.uuid += p_char_obj->p_uuid->value[1] << 8;
363 
364     memset(&attr_md, 0, sizeof(attr_md));
365 
366     BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
367     BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
368 
369     attr_md.vloc    = BLE_GATTS_VLOC_STACK;
370     attr_md.rd_auth = 0;
371     attr_md.wr_auth = 0;
372     attr_md.vlen    = 1;
373 
374     memset(&attr_char_value, 0, sizeof(attr_char_value));
375 
376     attr_char_value.p_uuid    = &uuid;
377     attr_char_value.p_attr_md = &attr_md;
378     attr_char_value.init_len  = sizeof(uint8_t);
379     attr_char_value.init_offs = 0;
380     attr_char_value.max_len   = (GATT_MTU_SIZE_DEFAULT - 3);
381 
382     ble_gatts_char_handles_t handles;
383 
384     if (sd_ble_gatts_characteristic_add(p_char_obj->service_handle,
385                                         &char_md,
386                                         &attr_char_value,
387                                         &handles) != 0) {
388         mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't add Characteristic"));
389     }
390 
391     // apply handles to object instance
392     p_char_obj->handle           = handles.value_handle;
393     p_char_obj->user_desc_handle = handles.user_desc_handle;
394     p_char_obj->cccd_handle      = handles.cccd_handle;
395     p_char_obj->sccd_handle      = handles.sccd_handle;
396 
397     return true;
398 }
399 
ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params)400 bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) {
401     SD_TEST_OR_ENABLE();
402 
403     uint8_t byte_pos = 0;
404 
405     static uint8_t adv_data[BLE_GAP_ADV_MAX_SIZE];
406 
407     if (p_adv_params->device_name_len > 0) {
408         ble_gap_conn_sec_mode_t sec_mode;
409 
410         BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
411 
412         if (sd_ble_gap_device_name_set(&sec_mode,
413                                        p_adv_params->p_device_name,
414                                        p_adv_params->device_name_len) != 0) {
415             mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't apply device name in the stack"));
416         }
417 
418         BLE_DRIVER_LOG("Device name applied\n");
419 
420         adv_data[byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + p_adv_params->device_name_len);
421         byte_pos += BLE_ADV_LENGTH_FIELD_SIZE;
422         adv_data[byte_pos] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
423         byte_pos += BLE_ADV_AD_TYPE_FIELD_SIZE;
424         memcpy(&adv_data[byte_pos], p_adv_params->p_device_name, p_adv_params->device_name_len);
425         // increment position counter to see if it fits, and in case more content should
426         // follow in this adv packet.
427         byte_pos += p_adv_params->device_name_len;
428     }
429 
430     // Add FLAGS only if manually controlled data has not been used.
431     if (p_adv_params->data_len == 0) {
432         // set flags, default to disc mode
433         adv_data[byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + BLE_AD_TYPE_FLAGS_DATA_SIZE);
434         byte_pos += BLE_ADV_LENGTH_FIELD_SIZE;
435         adv_data[byte_pos] = BLE_GAP_AD_TYPE_FLAGS;
436         byte_pos += BLE_AD_TYPE_FLAGS_DATA_SIZE;
437         adv_data[byte_pos] = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
438         byte_pos += 1;
439     }
440 
441     if (p_adv_params->num_of_services > 0) {
442 
443         bool type_16bit_present  = false;
444         bool type_128bit_present = false;
445 
446         for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) {
447             ubluepy_service_obj_t * p_service = (ubluepy_service_obj_t *)p_adv_params->p_services[i];
448             if (p_service->p_uuid->type == UBLUEPY_UUID_16_BIT) {
449                 type_16bit_present = true;
450             }
451 
452             if (p_service->p_uuid->type == UBLUEPY_UUID_128_BIT) {
453                 type_128bit_present = true;
454             }
455         }
456 
457         if (type_16bit_present) {
458             uint8_t size_byte_pos = byte_pos;
459 
460             // skip length byte for now, apply total length post calculation
461             byte_pos += BLE_ADV_LENGTH_FIELD_SIZE;
462 
463             adv_data[byte_pos] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE;
464             byte_pos += BLE_ADV_AD_TYPE_FIELD_SIZE;
465 
466             uint8_t uuid_total_size = 0;
467             uint8_t encoded_size    = 0;
468 
469             for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) {
470                 ubluepy_service_obj_t * p_service = (ubluepy_service_obj_t *)p_adv_params->p_services[i];
471 
472                 ble_uuid_t uuid;
473                 uuid.type  = p_service->p_uuid->type;
474                 uuid.uuid  = p_service->p_uuid->value[0];
475                 uuid.uuid += p_service->p_uuid->value[1] << 8;
476                 // calculate total size of uuids
477                 if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) {
478                     mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't encode UUID, to check length"));
479                 }
480 
481                 // do encoding into the adv buffer
482                 if (sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]) != 0) {
483                     mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't encode UUID into advertisment packet"));
484                 }
485 
486                 BLE_DRIVER_LOG("encoded uuid for service %u: ", 0);
487                 for (uint8_t j = 0; j < encoded_size; j++) {
488                     BLE_DRIVER_LOG(HEX2_FMT " ", adv_data[byte_pos + j]);
489                 }
490                 BLE_DRIVER_LOG("\n");
491 
492                 uuid_total_size += encoded_size; // size of entry
493                 byte_pos        += encoded_size; // relative to adv data packet
494                 BLE_DRIVER_LOG("ADV: uuid size: %u, type: %u, uuid: %x%x, vs_idx: %u\n",
495                        encoded_size, p_service->p_uuid->type,
496                        p_service->p_uuid->value[1],
497                        p_service->p_uuid->value[0],
498                        p_service->p_uuid->uuid_vs_idx);
499             }
500 
501             adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size);
502         }
503 
504         if (type_128bit_present) {
505             uint8_t size_byte_pos = byte_pos;
506 
507             // skip length byte for now, apply total length post calculation
508             byte_pos += BLE_ADV_LENGTH_FIELD_SIZE;
509 
510             adv_data[byte_pos] = BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE;
511             byte_pos += BLE_ADV_AD_TYPE_FIELD_SIZE;
512 
513             uint8_t uuid_total_size = 0;
514             uint8_t encoded_size    = 0;
515 
516             for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) {
517                 ubluepy_service_obj_t * p_service = (ubluepy_service_obj_t *)p_adv_params->p_services[i];
518 
519                 ble_uuid_t uuid;
520                 uuid.type  = p_service->p_uuid->uuid_vs_idx;
521                 uuid.uuid  = p_service->p_uuid->value[0];
522                 uuid.uuid += p_service->p_uuid->value[1] << 8;
523 
524                 // calculate total size of uuids
525                 if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) {
526                     mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't encode UUID, to check length"));
527                 }
528 
529                 // do encoding into the adv buffer
530                 if (sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]) != 0) {
531                     mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't encode UUID into advertisment packet"));
532                 }
533 
534                 BLE_DRIVER_LOG("encoded uuid for service %u: ", 0);
535                 for (uint8_t j = 0; j < encoded_size; j++) {
536                     BLE_DRIVER_LOG(HEX2_FMT " ", adv_data[byte_pos + j]);
537                 }
538                 BLE_DRIVER_LOG("\n");
539 
540                 uuid_total_size += encoded_size; // size of entry
541                 byte_pos        += encoded_size; // relative to adv data packet
542                 BLE_DRIVER_LOG("ADV: uuid size: %u, type: %x%x, uuid: %u, vs_idx: %u\n",
543                        encoded_size, p_service->p_uuid->type,
544                        p_service->p_uuid->value[1],
545                        p_service->p_uuid->value[0],
546                        p_service->p_uuid->uuid_vs_idx);
547             }
548 
549             adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size);
550         }
551     }
552 
553     if ((p_adv_params->data_len > 0) && (p_adv_params->p_data != NULL)) {
554         if (p_adv_params->data_len + byte_pos > BLE_GAP_ADV_MAX_SIZE) {
555             mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("can't fit data into advertisment packet"));
556         }
557 
558         memcpy(adv_data, p_adv_params->p_data, p_adv_params->data_len);
559         byte_pos += p_adv_params->data_len;
560     }
561 
562     // scan response data not set
563     uint32_t err_code;
564 #if (BLUETOOTH_SD == 132) || (BLUETOOTH_SD == 140)
565     const ble_gap_adv_data_t m_adv_data = {
566         .adv_data.p_data      = adv_data,
567         .adv_data.len         = byte_pos,
568         .scan_rsp_data.p_data = NULL,
569         .scan_rsp_data.len    = 0
570     };
571 #endif
572 
573     static ble_gap_adv_params_t m_adv_params;
574     memset(&m_adv_params, 0, sizeof(m_adv_params));
575 
576     // initialize advertising params
577     if (p_adv_params->connectable) {
578 #if (BLUETOOTH_SD == 110)
579         m_adv_params.type             = BLE_GAP_ADV_TYPE_ADV_IND;
580 #else
581         m_adv_params.properties.type  = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
582 #endif
583     } else {
584 #if (BLUETOOTH_SD == 110)
585         m_adv_params.type             = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND;
586 #else
587         m_adv_params.properties.type  = BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED;
588 #endif
589     }
590 
591 #if (BLUETOOTH_SD == 110)
592     m_adv_params.fp                          = BLE_GAP_ADV_FP_ANY;
593     m_adv_params.timeout                     = 0;                                   // infinite advertisment
594 #else
595     m_adv_params.properties.anonymous        = 0;
596     m_adv_params.properties.include_tx_power = 0;
597     m_adv_params.filter_policy               = 0;
598     m_adv_params.max_adv_evts                = 0; // infinite advertisment
599     m_adv_params.primary_phy                 = BLE_GAP_PHY_AUTO;
600     m_adv_params.secondary_phy               = BLE_GAP_PHY_AUTO;
601     m_adv_params.scan_req_notification       = 0; // Do not raise scan request notifications when scanned.
602 #endif
603     m_adv_params.p_peer_addr                 = NULL;                                // undirected advertisement
604     m_adv_params.interval                    = MSEC_TO_UNITS(100, UNIT_0_625_MS);   // approx 8 ms
605 
606 #if (BLUETOOTH_SD == 110)
607     if ((err_code = sd_ble_gap_adv_data_set(adv_data, byte_pos, NULL, 0)) != 0) {
608         mp_raise_msg_varg(&mp_type_OSError,
609             MP_ERROR_TEXT("Can not apply advertisment data. status: 0x" HEX2_FMT), (uint16_t)err_code);
610     }
611 #else
612     if ((err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params)) != 0) {
613         mp_raise_msg_varg(&mp_type_OSError,
614             MP_ERROR_TEXT("Can not apply advertisment data. status: 0x" HEX2_FMT), (uint16_t)err_code);
615     }
616 #endif
617     BLE_DRIVER_LOG("Set Adv data size: " UINT_FMT "\n", byte_pos);
618 
619     ble_drv_advertise_stop();
620 
621 #if (BLUETOOTH_SD == 110)
622     err_code = sd_ble_gap_adv_start(&m_adv_params);
623 #else
624     uint8_t conf_tag = BLE_DRV_CONN_CONFIG_TAG; // Could also be set to tag from sd_ble_cfg_set
625     err_code = sd_ble_gap_adv_start(m_adv_handle, conf_tag);
626 #endif
627     if (err_code != 0) {
628         mp_raise_msg_varg(&mp_type_OSError,
629             MP_ERROR_TEXT("Can not start advertisment. status: 0x" HEX2_FMT), (uint16_t)err_code);
630     }
631 
632     m_adv_in_progress = true;
633 
634     return true;
635 }
636 
ble_drv_advertise_stop(void)637 void ble_drv_advertise_stop(void) {
638     if (m_adv_in_progress == true) {
639         uint32_t err_code;
640 
641 #if (BLUETOOTH_SD == 110)
642         if ((err_code = sd_ble_gap_adv_stop()) != 0) {
643             mp_raise_msg_varg(&mp_type_OSError,
644                 MP_ERROR_TEXT("Can not stop advertisment. status: 0x" HEX2_FMT), (uint16_t)err_code);
645         }
646 #else
647         if ((err_code = sd_ble_gap_adv_stop(m_adv_handle)) != 0) {
648             mp_raise_msg_varg(&mp_type_OSError,
649                 MP_ERROR_TEXT("Can not stop advertisment. status: 0x" HEX2_FMT), (uint16_t)err_code);
650         }
651 #endif
652     }
653     m_adv_in_progress = false;
654 }
655 
ble_drv_attr_s_read(uint16_t conn_handle,uint16_t handle,uint16_t len,uint8_t * p_data)656 void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data) {
657     ble_gatts_value_t gatts_value;
658     memset(&gatts_value, 0, sizeof(gatts_value));
659 
660     gatts_value.len     = len;
661     gatts_value.offset  = 0;
662     gatts_value.p_value = p_data;
663 
664     uint32_t err_code = sd_ble_gatts_value_get(conn_handle,
665                                                handle,
666                                                &gatts_value);
667     if (err_code != 0) {
668         mp_raise_msg_varg(&mp_type_OSError,
669             MP_ERROR_TEXT("Can not read attribute value. status: 0x" HEX2_FMT), (uint16_t)err_code);
670     }
671 
672 }
673 
ble_drv_attr_s_write(uint16_t conn_handle,uint16_t handle,uint16_t len,uint8_t * p_data)674 void ble_drv_attr_s_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data) {
675     ble_gatts_value_t gatts_value;
676     memset(&gatts_value, 0, sizeof(gatts_value));
677 
678     gatts_value.len     = len;
679     gatts_value.offset  = 0;
680     gatts_value.p_value = p_data;
681 
682     uint32_t err_code = sd_ble_gatts_value_set(conn_handle, handle, &gatts_value);
683 
684     if (err_code != 0) {
685         mp_raise_msg_varg(&mp_type_OSError,
686             MP_ERROR_TEXT("Can not write attribute value. status: 0x" HEX2_FMT), (uint16_t)err_code);
687     }
688 }
689 
ble_drv_attr_s_notify(uint16_t conn_handle,uint16_t handle,uint16_t len,uint8_t * p_data)690 void ble_drv_attr_s_notify(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data) {
691     uint16_t               hvx_len = len;
692     ble_gatts_hvx_params_t hvx_params;
693 
694     memset(&hvx_params, 0, sizeof(hvx_params));
695 
696     hvx_params.handle = handle;
697     hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
698     hvx_params.offset = 0;
699     hvx_params.p_len  = &hvx_len;
700     hvx_params.p_data = p_data;
701 
702     while (m_tx_in_progress > MAX_TX_IN_PROGRESS) {
703         ;
704     }
705 
706     BLE_DRIVER_LOG("Request TX, m_tx_in_progress: %u\n", m_tx_in_progress);
707     uint32_t err_code;
708     if ((err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params)) != 0) {
709         mp_raise_msg_varg(&mp_type_OSError,
710             MP_ERROR_TEXT("Can not notify attribute value. status: 0x" HEX2_FMT), (uint16_t)err_code);
711     }
712     m_tx_in_progress++;
713     BLE_DRIVER_LOG("Queued TX, m_tx_in_progress: %u\n", m_tx_in_progress);
714 }
715 
ble_drv_gap_event_handler_set(mp_obj_t obj,ble_drv_gap_evt_callback_t evt_handler)716 void ble_drv_gap_event_handler_set(mp_obj_t obj, ble_drv_gap_evt_callback_t evt_handler) {
717     mp_gap_observer = obj;
718     gap_event_handler = evt_handler;
719 }
720 
ble_drv_gatts_event_handler_set(mp_obj_t obj,ble_drv_gatts_evt_callback_t evt_handler)721 void ble_drv_gatts_event_handler_set(mp_obj_t obj, ble_drv_gatts_evt_callback_t evt_handler) {
722     mp_gatts_observer = obj;
723     gatts_event_handler = evt_handler;
724 }
725 
726 #if (BLUETOOTH_SD == 132) || (BLUETOOTH_SD == 140)
727 
ble_drv_gattc_event_handler_set(mp_obj_t obj,ble_drv_gattc_evt_callback_t evt_handler)728 void ble_drv_gattc_event_handler_set(mp_obj_t obj, ble_drv_gattc_evt_callback_t evt_handler) {
729     mp_gattc_observer = obj;
730     gattc_event_handler = evt_handler;
731 }
732 
ble_drv_adv_report_handler_set(mp_obj_t obj,ble_drv_adv_evt_callback_t evt_handler)733 void ble_drv_adv_report_handler_set(mp_obj_t obj, ble_drv_adv_evt_callback_t evt_handler) {
734     mp_adv_observer = obj;
735     adv_event_handler = evt_handler;
736 }
737 
738 
ble_drv_attr_c_read(uint16_t conn_handle,uint16_t handle,mp_obj_t obj,ble_drv_gattc_char_data_callback_t cb)739 void ble_drv_attr_c_read(uint16_t conn_handle, uint16_t handle, mp_obj_t obj, ble_drv_gattc_char_data_callback_t cb) {
740 
741     mp_gattc_char_data_observer = obj;
742     gattc_char_data_handle = cb;
743 
744     uint32_t err_code = sd_ble_gattc_read(conn_handle,
745                                           handle,
746                                           0);
747     if (err_code != 0) {
748         mp_raise_msg_varg(&mp_type_OSError,
749             MP_ERROR_TEXT("Can not read attribute value. status: 0x" HEX2_FMT), (uint16_t)err_code);
750     }
751 
752     while (gattc_char_data_handle != NULL) {
753         ;
754     }
755 }
756 
ble_drv_attr_c_write(uint16_t conn_handle,uint16_t handle,uint16_t len,uint8_t * p_data,bool w_response)757 void ble_drv_attr_c_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data, bool w_response) {
758 
759     ble_gattc_write_params_t write_params;
760 
761     if (w_response) {
762             write_params.write_op = BLE_GATT_OP_WRITE_REQ;
763     } else {
764         write_params.write_op = BLE_GATT_OP_WRITE_CMD;
765     }
766 
767     write_params.flags    = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL;
768     write_params.handle   = handle;
769     write_params.offset   = 0;
770     write_params.len      = len;
771     write_params.p_value  = p_data;
772 
773     m_write_done = !w_response;
774 
775     uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params);
776 
777     if (err_code != 0) {
778         mp_raise_msg_varg(&mp_type_OSError,
779             MP_ERROR_TEXT("Can not write attribute value. status: 0x" HEX2_FMT), (uint16_t)err_code);
780     }
781 
782     while (m_write_done != true) {
783         ;
784     }
785 }
786 
ble_drv_scan_start(bool cont)787 void ble_drv_scan_start(bool cont) {
788     SD_TEST_OR_ENABLE();
789 
790     ble_gap_scan_params_t scan_params;
791     memset(&scan_params, 0, sizeof(ble_gap_scan_params_t));
792     scan_params.extended = 0;
793     scan_params.active   = 1;
794     scan_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS);
795     scan_params.window   = MSEC_TO_UNITS(100, UNIT_0_625_MS);
796     scan_params.timeout  = 0; // Infinite
797 
798     ble_data_t scan_buffer = {
799         .p_data = m_scan_buffer,
800         .len    = BLE_GAP_SCAN_BUFFER_MIN
801     };
802 
803     uint32_t err_code;
804     ble_gap_scan_params_t * p_scan_params = &scan_params;
805     if (cont) {
806         p_scan_params = NULL;
807     }
808     if ((err_code = sd_ble_gap_scan_start(p_scan_params, &scan_buffer)) != 0) {
809         mp_raise_msg_varg(&mp_type_OSError,
810             MP_ERROR_TEXT("Can not start scanning. status: 0x" HEX2_FMT), (uint16_t)err_code);
811     }
812 }
813 
ble_drv_scan_stop(void)814 void ble_drv_scan_stop(void) {
815     sd_ble_gap_scan_stop();
816 }
817 
ble_drv_connect(uint8_t * p_addr,uint8_t addr_type)818 void ble_drv_connect(uint8_t * p_addr, uint8_t addr_type) {
819     SD_TEST_OR_ENABLE();
820 
821     ble_gap_scan_params_t scan_params;
822     memset(&scan_params, 0, sizeof(ble_gap_scan_params_t));
823     scan_params.extended = 0;
824     scan_params.active   = 1;
825     scan_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS);
826     scan_params.window   = MSEC_TO_UNITS(100, UNIT_0_625_MS);
827     scan_params.timeout  = 0; // infinite
828 
829     ble_gap_addr_t addr;
830     memset(&addr, 0, sizeof(addr));
831 
832     addr.addr_type = addr_type;
833     memcpy(addr.addr, p_addr, 6);
834 
835     BLE_DRIVER_LOG("GAP CONNECTING: "HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT", type: %d\n",
836                    addr.addr[0], addr.addr[1], addr.addr[2], addr.addr[3], addr.addr[4], addr.addr[5], addr.addr_type);
837 
838     ble_gap_conn_params_t conn_params;
839 
840     // set connection parameters
841     memset(&conn_params, 0, sizeof(conn_params));
842 
843     conn_params.min_conn_interval = BLE_MIN_CONN_INTERVAL;
844     conn_params.max_conn_interval = BLE_MAX_CONN_INTERVAL;
845     conn_params.slave_latency     = BLE_SLAVE_LATENCY;
846     conn_params.conn_sup_timeout  = BLE_CONN_SUP_TIMEOUT;
847 
848     uint8_t conn_tag = BLE_DRV_CONN_CONFIG_TAG;
849 
850     uint32_t err_code;
851     if ((err_code = sd_ble_gap_connect(&addr,
852                                        &scan_params,
853                                        &conn_params,
854                                        conn_tag)) != 0) {
855         mp_raise_msg_varg(&mp_type_OSError,
856             MP_ERROR_TEXT("Can not connect. status: 0x" HEX2_FMT), (uint16_t)err_code);
857     }
858 }
859 
ble_drv_discover_services(mp_obj_t obj,uint16_t conn_handle,uint16_t start_handle,ble_drv_disc_add_service_callback_t cb)860 bool ble_drv_discover_services(mp_obj_t obj, uint16_t conn_handle, uint16_t start_handle, ble_drv_disc_add_service_callback_t cb) {
861     BLE_DRIVER_LOG("Discover primary services. Conn handle: 0x" HEX2_FMT "\n",
862                    conn_handle);
863 
864     mp_gattc_disc_service_observer = obj;
865     disc_add_service_handler = cb;
866 
867     m_primary_service_found = false;
868 
869     uint32_t err_code;
870     err_code = sd_ble_gattc_primary_services_discover(conn_handle,
871                                                       start_handle,
872                                                       NULL);
873     if (err_code != 0) {
874         return false;
875     }
876 
877     // busy loop until last service has been iterated
878     while (disc_add_service_handler != NULL) {
879         ;
880     }
881 
882     if (m_primary_service_found) {
883         return true;
884     } else {
885         return false;
886     }
887 }
888 
ble_drv_discover_characteristic(mp_obj_t obj,uint16_t conn_handle,uint16_t start_handle,uint16_t end_handle,ble_drv_disc_add_char_callback_t cb)889 bool ble_drv_discover_characteristic(mp_obj_t obj,
890                                      uint16_t conn_handle,
891                                      uint16_t start_handle,
892                                      uint16_t end_handle,
893                                      ble_drv_disc_add_char_callback_t cb) {
894     BLE_DRIVER_LOG("Discover characteristicts. Conn handle: 0x" HEX2_FMT "\n",
895                    conn_handle);
896 
897     mp_gattc_disc_char_observer = obj;
898     disc_add_char_handler = cb;
899 
900     ble_gattc_handle_range_t handle_range;
901     handle_range.start_handle = start_handle;
902     handle_range.end_handle   = end_handle;
903 
904     m_characteristic_found = false;
905 
906     uint32_t err_code;
907     err_code = sd_ble_gattc_characteristics_discover(conn_handle, &handle_range);
908     if (err_code != 0) {
909         return false;
910     }
911 
912     // busy loop until last service has been iterated
913     while (disc_add_char_handler != NULL) {
914         ;
915     }
916 
917     if (m_characteristic_found) {
918         return true;
919     } else {
920         return false;
921     }
922 }
923 
ble_drv_discover_descriptors(void)924 void ble_drv_discover_descriptors(void) {
925 
926 }
927 
928 #endif // (BLUETOOTH_SD == 132) || (BLUETOOTH_SD == 140)
929 
sd_evt_handler(uint32_t evt_id)930 static void sd_evt_handler(uint32_t evt_id) {
931     switch (evt_id) {
932 #if MICROPY_HW_ENABLE_INTERNAL_FLASH_STORAGE || MICROPY_MBFS
933         case NRF_EVT_FLASH_OPERATION_SUCCESS:
934             flash_operation_finished(FLASH_STATE_SUCCESS);
935             break;
936         case NRF_EVT_FLASH_OPERATION_ERROR:
937             flash_operation_finished(FLASH_STATE_ERROR);
938             break;
939 #endif
940         default:
941             // unhandled event!
942             break;
943     }
944 #if MICROPY_HW_USB_CDC
945     // Farward SOC events to USB CDC driver.
946     usb_cdc_sd_event_handler(evt_id);
947 #endif
948 }
949 
ble_evt_handler(ble_evt_t * p_ble_evt)950 static void ble_evt_handler(ble_evt_t * p_ble_evt) {
951 // S132 event ranges.
952 // Common 0x01 -> 0x0F
953 // GAP    0x10 -> 0x2F
954 // GATTC  0x30 -> 0x4F
955 // GATTS  0x50 -> 0x6F
956 // L2CAP  0x70 -> 0x8F
957     switch (p_ble_evt->header.evt_id) {
958         case BLE_GAP_EVT_CONNECTED:
959             BLE_DRIVER_LOG("GAP CONNECT\n");
960             m_adv_in_progress = false;
961             gap_event_handler(mp_gap_observer, p_ble_evt->header.evt_id, p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->header.evt_len - (2 * sizeof(uint16_t)), NULL);
962 
963             ble_gap_conn_params_t conn_params;
964             (void)sd_ble_gap_ppcp_get(&conn_params);
965             (void)sd_ble_gap_conn_param_update(p_ble_evt->evt.gap_evt.conn_handle, &conn_params);
966             break;
967 
968         case BLE_GAP_EVT_DISCONNECTED:
969             BLE_DRIVER_LOG("GAP DISCONNECT\n");
970             gap_event_handler(mp_gap_observer, p_ble_evt->header.evt_id, p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->header.evt_len - (2 * sizeof(uint16_t)), NULL);
971             break;
972 
973         case BLE_GATTS_EVT_HVC:
974             gatts_event_handler(mp_gatts_observer, p_ble_evt->header.evt_id, p_ble_evt->evt.gatts_evt.params.hvc.handle, p_ble_evt->header.evt_len - (2 * sizeof(uint16_t)), NULL);
975             break;
976 
977         case BLE_GATTS_EVT_WRITE:
978             BLE_DRIVER_LOG("GATTS write\n");
979 
980             uint16_t  handle   = p_ble_evt->evt.gatts_evt.params.write.handle;
981             uint16_t  data_len = p_ble_evt->evt.gatts_evt.params.write.len;
982             uint8_t * p_data   = &p_ble_evt->evt.gatts_evt.params.write.data[0];
983 
984             gatts_event_handler(mp_gatts_observer, p_ble_evt->header.evt_id, handle, data_len, p_data);
985             break;
986 
987         case BLE_GAP_EVT_CONN_PARAM_UPDATE:
988             BLE_DRIVER_LOG("GAP CONN PARAM UPDATE\n");
989             break;
990 
991         case BLE_GATTS_EVT_SYS_ATTR_MISSING:
992             // No system attributes have been stored.
993             (void)sd_ble_gatts_sys_attr_set(p_ble_evt->evt.gatts_evt.conn_handle, NULL, 0, 0);
994             break;
995 
996 #if (BLUETOOTH_SD == 132) || (BLUETOOTH_SD == 140)
997         case BLE_GATTS_EVT_HVN_TX_COMPLETE:
998 #else
999         case BLE_EVT_TX_COMPLETE:
1000 #endif
1001             BLE_DRIVER_LOG("BLE EVT TX COMPLETE\n");
1002 #if (BLUETOOTH_SD == 132) || (BLUETOOTH_SD == 140)
1003             BLE_DRIVER_LOG("HVN_TX_COMPLETE, count: %u\n", p_ble_evt->evt.gatts_evt.params.hvn_tx_complete.count);
1004             m_tx_in_progress -= p_ble_evt->evt.gatts_evt.params.hvn_tx_complete.count;
1005             BLE_DRIVER_LOG("TX_COMPLETE, m_tx_in_progress: %u\n", m_tx_in_progress);
1006 #else
1007             BLE_DRIVER_LOG("TX_COMPLETE, count: %u\n", p_ble_evt->evt.common_evt.params.tx_complete.count);
1008             m_tx_in_progress -= p_ble_evt->evt.common_evt.params.tx_complete.count;
1009             BLE_DRIVER_LOG("TX_COMPLETE, m_tx_in_progress: %u\n", m_tx_in_progress);
1010 #endif
1011             break;
1012 
1013         case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
1014             BLE_DRIVER_LOG("BLE EVT SEC PARAMS REQUEST\n");
1015             // pairing not supported
1016             (void)sd_ble_gap_sec_params_reply(p_ble_evt->evt.gatts_evt.conn_handle,
1017                                               BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP,
1018                                               NULL, NULL);
1019             break;
1020 
1021 #if (BLUETOOTH_SD == 132) || (BLUETOOTH_SD == 140)
1022         case BLE_GAP_EVT_ADV_REPORT:
1023             BLE_DRIVER_LOG("BLE EVT ADV REPORT\n");
1024             ble_drv_adv_data_t adv_data = {
1025                 .p_peer_addr  = p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr,
1026                 .addr_type    = p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr_type,
1027                 .is_scan_resp = p_ble_evt->evt.gap_evt.params.adv_report.type.scan_response,
1028                 .rssi         = p_ble_evt->evt.gap_evt.params.adv_report.rssi,
1029                 .data_len     = p_ble_evt->evt.gap_evt.params.adv_report.data.len,
1030                 .p_data       = p_ble_evt->evt.gap_evt.params.adv_report.data.p_data,
1031 //              .adv_type     =
1032             };
1033             // TODO: Fix unsafe callback to possible undefined callback...
1034             adv_event_handler(mp_adv_observer,
1035                               p_ble_evt->header.evt_id,
1036                               &adv_data);
1037             break;
1038 
1039         case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
1040             BLE_DRIVER_LOG("BLE EVT CONN PARAM UPDATE REQUEST\n");
1041 
1042             (void)sd_ble_gap_conn_param_update(p_ble_evt->evt.gap_evt.conn_handle,
1043                                                &p_ble_evt->evt.gap_evt.params.conn_param_update_request.conn_params);
1044             break;
1045 
1046         case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
1047             BLE_DRIVER_LOG("BLE EVT PRIMARY SERVICE DISCOVERY RESPONSE\n");
1048             BLE_DRIVER_LOG(">>> service count: %d\n", p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count);
1049 
1050             for (uint16_t i = 0; i < p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count; i++) {
1051                 ble_gattc_service_t * p_service = &p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i];
1052 
1053                 ble_drv_service_data_t service;
1054                 service.uuid_type    = p_service->uuid.type;
1055                 service.uuid         = p_service->uuid.uuid;
1056                 service.start_handle = p_service->handle_range.start_handle;
1057                 service.end_handle   = p_service->handle_range.end_handle;
1058 
1059                 disc_add_service_handler(mp_gattc_disc_service_observer, &service);
1060             }
1061 
1062             if (p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count > 0) {
1063                 m_primary_service_found = true;
1064             }
1065 
1066             // mark end of service discovery
1067             disc_add_service_handler = NULL;
1068 
1069             break;
1070 
1071         case BLE_GATTC_EVT_CHAR_DISC_RSP:
1072             BLE_DRIVER_LOG("BLE EVT CHAR DISCOVERY RESPONSE\n");
1073             BLE_DRIVER_LOG(">>> characteristic count: %d\n", p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count);
1074 
1075             for (uint16_t i = 0; i < p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count; i++) {
1076                 ble_gattc_char_t * p_char = &p_ble_evt->evt.gattc_evt.params.char_disc_rsp.chars[i];
1077 
1078                 ble_drv_char_data_t char_data;
1079                 char_data.uuid_type    = p_char->uuid.type;
1080                 char_data.uuid         = p_char->uuid.uuid;
1081                 char_data.decl_handle  = p_char->handle_decl;
1082                 char_data.value_handle = p_char->handle_value;
1083 
1084                 char_data.props  = (p_char->char_props.broadcast) ? UBLUEPY_PROP_BROADCAST : 0;
1085                 char_data.props |= (p_char->char_props.read) ? UBLUEPY_PROP_READ : 0;
1086                 char_data.props |= (p_char->char_props.write_wo_resp) ? UBLUEPY_PROP_WRITE_WO_RESP : 0;
1087                 char_data.props |= (p_char->char_props.write) ? UBLUEPY_PROP_WRITE : 0;
1088                 char_data.props |= (p_char->char_props.notify) ? UBLUEPY_PROP_NOTIFY : 0;
1089                 char_data.props |= (p_char->char_props.indicate) ? UBLUEPY_PROP_INDICATE : 0;
1090             #if 0
1091                 char_data.props |= (p_char->char_props.auth_signed_wr) ? UBLUEPY_PROP_NOTIFY : 0;
1092             #endif
1093 
1094                 disc_add_char_handler(mp_gattc_disc_char_observer, &char_data);
1095             }
1096 
1097             if (p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count > 0) {
1098                 m_characteristic_found = true;
1099             }
1100 
1101             // mark end of characteristic discovery
1102             disc_add_char_handler = NULL;
1103 
1104             break;
1105 
1106         case BLE_GATTC_EVT_READ_RSP:
1107             BLE_DRIVER_LOG("BLE EVT READ RESPONSE, offset: 0x"HEX2_FMT", length: 0x"HEX2_FMT"\n",
1108                            p_ble_evt->evt.gattc_evt.params.read_rsp.offset,
1109                            p_ble_evt->evt.gattc_evt.params.read_rsp.len);
1110 
1111             gattc_char_data_handle(mp_gattc_char_data_observer,
1112                                    p_ble_evt->evt.gattc_evt.params.read_rsp.len,
1113                                    p_ble_evt->evt.gattc_evt.params.read_rsp.data);
1114 
1115             // mark end of read
1116             gattc_char_data_handle = NULL;
1117 
1118             break;
1119 
1120         case BLE_GATTC_EVT_WRITE_RSP:
1121             BLE_DRIVER_LOG("BLE EVT WRITE RESPONSE\n");
1122             m_write_done = true;
1123             break;
1124 
1125         case BLE_GATTC_EVT_HVX:
1126             BLE_DRIVER_LOG("BLE EVT HVX RESPONSE\n");
1127             break;
1128 
1129         case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
1130             BLE_DRIVER_LOG("GATTS EVT EXCHANGE MTU REQUEST\n");
1131             (void)sd_ble_gatts_exchange_mtu_reply(p_ble_evt->evt.gatts_evt.conn_handle, 23); // MAX MTU size
1132             break;
1133 
1134         case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
1135             BLE_DRIVER_LOG("BLE GAP EVT DATA LENGTH UPDATE REQUEST\n");
1136             sd_ble_gap_data_length_update(p_ble_evt->evt.gap_evt.conn_handle, NULL, NULL);
1137             break;
1138 
1139 #endif // (BLUETOOTH_SD == 132) || (BLUETOOTH_SD == 140)
1140 
1141         default:
1142             BLE_DRIVER_LOG(">>> unhandled evt: 0x" HEX2_FMT "\n", p_ble_evt->header.evt_id);
1143             break;
1144     }
1145 }
1146 
1147 static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (GATT_MTU_SIZE_DEFAULT)] __attribute__ ((aligned (4)));
1148 
1149 #ifdef NRF51
SWI2_IRQHandler(void)1150 void SWI2_IRQHandler(void) {
1151 #else
1152 void SWI2_EGU2_IRQHandler(void) {
1153 #endif
1154 
1155     uint32_t evt_id;
1156     while (sd_evt_get(&evt_id) != NRF_ERROR_NOT_FOUND) {
1157         sd_evt_handler(evt_id);
1158     }
1159 
1160     while (1) {
1161         uint16_t evt_len  = sizeof(m_ble_evt_buf);
1162         uint32_t err_code = sd_ble_evt_get(m_ble_evt_buf, &evt_len);
1163         if (err_code != NRF_SUCCESS) {
1164             // Possible error conditions:
1165             //  * NRF_ERROR_NOT_FOUND: no events left, break
1166             //  * NRF_ERROR_DATA_SIZE: retry with a bigger data buffer
1167             //    (currently not handled, TODO)
1168             //  * NRF_ERROR_INVALID_ADDR: pointer is not aligned, should
1169             //    not happen.
1170             // In all cases, it's best to simply stop now.
1171             if (err_code == NRF_ERROR_DATA_SIZE) {
1172                 BLE_DRIVER_LOG("NRF_ERROR_DATA_SIZE\n");
1173             }
1174             break;
1175         }
1176         ble_evt_handler((ble_evt_t *)m_ble_evt_buf);
1177     }
1178 }
1179 
1180 #endif // BLUETOOTH_SD
1181