Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions docs/library/network.Bluetooth.rst
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,36 @@ Methods

bluetooth.set_advertisement(name="advert", manufacturer_data="lopy_v1")

.. method:: bluetooth.set_pin(new_pin)

Sets a new pin code which clients can use to bond with this device. Only works when Bluetooth was initialized with ``secure=True``.

When the pin code is changed, all client bondings are removed, except for the currently connected client if any.

Arguments:

- ``pin`` is the 6 digit (0-9) pin code as an integer.

Example::

from network import Bluetooth

bluetooth = Bluetooth(secure=True, pin=123456)
bluetooth.set_advertisement(name='LoPy', service_uuid=b'1234567890123456')
bluetooth.advertise(True)

service = bluetooth.service(uuid=b'7890123456789012')
characteristic = service.characteristic(uuid=b'3456789012345678')

def char_cb(chr)
events = chr.events()
if events & Bluetooth.CHAR_WRITE_EVENT:
new_pin = int(chr.value())
print("Setting PIN to {}".format(new_pin))
bluetooth.set_pin(new_pin)

characteristic.callback(trigger=Bluetooth.CHAR_WRITE_EVENT, handler=char_cb)

.. method:: bluetooth.advertise([Enable])

Start or stop sending advertisements. The ``.set_advertisement()`` method must have been called prior to this one. ::
Expand Down Expand Up @@ -289,6 +319,17 @@ Constants

Characteristic properties (bit values that can be combined)

.. data:: PERM_READ
PERM_READ_ENCRYPTED
PERM_READ_ENC_MITM
PERM_WRITE
PERM_WRITE_ENCRYPTED
PERM_WRITE_ENC_MITM
PERM_WRITE_SIGNED
PERM_WRITE_SIGNED_MITM

Characteristic permissions (bit values that can be combined)

.. data:: Bluetooth.CHAR_READ_EVENT
Bluetooth.CHAR_WRITE_EVENT
Bluetooth.NEW_ADV_EVENT
Expand Down
179 changes: 87 additions & 92 deletions esp32/mods/modbt.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@
#define MOD_BT_GATTS_CLOSE_EVT (0x0400)
#define MOD_BT_NVS_NAMESPACE "BT_NVS"
#define MOD_BT_HASH_SIZE (20)
#define MOD_BT_PIN_LENGTH (6)

/******************************************************************************
DEFINE PRIVATE TYPES
Expand All @@ -103,6 +102,7 @@ typedef struct {
bool advertising;
bool controller_active;
bool secure;
bool privacy;
} bt_obj_t;

typedef struct {
Expand Down Expand Up @@ -247,16 +247,6 @@ static esp_ble_adv_params_t bt_adv_params = {
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};

static esp_ble_adv_params_t bt_adv_params_sec = {
.adv_int_min = 0x100,
.adv_int_max = 0x100,
.adv_type = ADV_TYPE_IND,
.own_addr_type = BLE_ADDR_TYPE_RANDOM,
.channel_map = ADV_CHNL_ALL,
.adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY,
};


static bool mod_bt_allow_resume_deinit;
static uint16_t mod_bt_gatts_mtu_restore = 0;
static bool mod_bt_is_conn_restore_available;
Expand Down Expand Up @@ -416,11 +406,7 @@ void bt_resume(bool reconnect)

/* See if there was an averstisment active before Sleep */
if(bt_obj.advertising) {
if (!bt_obj.secure){
esp_ble_gap_start_advertising(&bt_adv_params);
} else {
esp_ble_gap_start_advertising(&bt_adv_params_sec);
}
esp_ble_gap_start_advertising(&bt_adv_params);
}
}

Expand Down Expand Up @@ -472,22 +458,6 @@ static void create_hash(uint32_t pin, uint8_t *h_value)
mbedtls_sha1_free(&sha1_context);
}

static bool is_pin_valid(uint32_t pin)
{
int digits = 0;

while(pin != 0)
{
digits++;
pin /= 10;
}

if (digits != MOD_BT_PIN_LENGTH){
return false;
}

return true;
}
Comment on lines -475 to -490
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a problem that length of pin is not inspected anymore. If pin can start with 0, and we store it in an integer, we cannot check the length. I have tested the commit and expreienced the following:

Initiated instance with bluetooth = Bluetooth(secure=True, pin=1234) on LoPy4, without getting any error (intended because of the deleted code snippet), and tried to bond from a phone, using nRF Connect. Using 1234 pin code, connection cannot be created, instead, with 001234, it was OK.

There was no other issue with any 6 digit pin codes (i.e. 050399 or 000001), and pin longer than 6 digits still gives an error (i.e. 1234567).

Do we want to:

  1. Ignore pins starting with zero (official version)
  2. Handle pins starting with zeros, but doesn't check pin minimal length? (this commit)
  3. Handle both length, and enable pin starting with zero? (new implementation, I think we cannot check length, as we represent pin as int -> 001 == 000001).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is intentional and as expected. As a direct result of the BLE implementation using an integer type to represent the passkey the leading zero's may be omitted in the calling Python code, but the resulting passkey will always be 6 digits. From the Bluetooth Core specification:

[...] the Bluetooth passkey is a 6-digit numerical value. It is represented as integer value in the range 0x00000000 – 0x000F423F (000000 to 999999).

Note that this is also documented in the additional documentation for the user-facing set_pin() method.

static bool pin_changed(uint32_t new_pin)
{
bool ret = false;
Expand Down Expand Up @@ -517,29 +487,42 @@ static bool pin_changed(uint32_t new_pin)
return ret;
}

static void remove_all_bonded_devices(void)
static void remove_bonded_devices(void)
{
int dev_num = esp_ble_get_bond_device_num();

esp_ble_bond_dev_t *dev_list = heap_caps_malloc(sizeof(esp_ble_bond_dev_t) * dev_num, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
esp_ble_get_bond_device_list(&dev_num, dev_list);
for (int i = 0; i < dev_num; i++) {
if (bt_obj.gatts_conn_id >= 0 && memcmp((void *) dev_list[i].bd_addr, (void *) bt_obj.client_bda, sizeof(esp_bd_addr_t)) == 0) {
continue;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a see correctly, the aim of this part is to not remove bond with device which is currently connected.

I tested this part, and bond won't be removed between LoPy4 and connected peripheral, but as you disconnect, can't be reconnect and rebond to LoPy4 anymore, I could not seen its advertisement anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was tested and confirmed to work as expected on a LoPy4, FiPy and GPy, and we are seeing advertisements in the raw traffic. The sending of advertisements is not handled by this part of the code, so I'm not sure what causes the issue in your test but it seems like it wouldn't be related to the changes in these lines.

Copy link
Contributor

@knagymate knagymate Feb 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I have also tested, and I am sure that the problem is not coming from your changes, It is also an issue without it. I have tested with LoPy4 and nRF Connect on my Android, and it both cases, I experience that:

  1. Connect to LoPY4
  2. Modify secured characteristics
  3. Bonding devices
  4. Set new pin
  5. Disconnect (with your change) or Automatically disconnected (withhout the change)
  6. Advertisement disappears (with manual bluetooth.advertise(True) it can be seen again)

So I recommended to add esp_ble_gap_start_advertising(&bt_adv_params); at the end of remove_bonded_devices() function.

esp_ble_remove_bond_device(dev_list[i].bd_addr);
}

free(dev_list);
}

static void set_secure_parameters(uint32_t passKey){
static void set_pin(uint32_t new_pin)
{
if (!bt_obj.secure) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Cannot set PIN when secure is not set"));
}

if (pin_changed(passKey)) {
remove_all_bonded_devices();
if (new_pin > 999999) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Only 6 digit (0-9) pins are allowed"));
}

uint32_t passkey = passKey;
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t));

esp_ble_auth_req_t auth_req = ESP_LE_AUTH_REQ_SC_MITM_BOND;

if (pin_changed(new_pin)) {
remove_bonded_devices();
}

uint32_t passkey = new_pin;
esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t));
}

static void set_secure_parameters(bool secure_connections) {
esp_ble_auth_req_t auth_req = secure_connections ? ESP_LE_AUTH_REQ_SC_MITM_BOND : ESP_LE_AUTH_BOND;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Further review needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes to these lines are for of the new secure_connections parameter described in the pull request's description.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thank you for improvement, we will add secure_connections.

esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t));

esp_ble_io_cap_t iocap = ESP_IO_CAP_OUT;
Expand Down Expand Up @@ -640,11 +623,6 @@ static void gap_events_handler (esp_gap_ble_cb_event_t event, esp_ble_gap_cb_par
xQueueSend(xGattsQueue, (void *)&gatts_event, (TickType_t)0);
break;
}
case ESP_GAP_BLE_NC_REQ_EVT:
case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: {
printf("BLE paring passkey : %d\n", param->ble_security.key_notif.passkey);
break;
}
Comment on lines -644 to -647
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to inform the user about the BLE paring passkey on REPL, or is it just a remaining debug signal?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the changes in this pull request makes the passkey configurable from MicroPython, there was no need for this debugging print statement to remain. The updated documentation explains how a Bluetooth PIN may be set.

case ESP_GAP_BLE_SEC_REQ_EVT: {
if (bt_obj.secure){
esp_ble_gap_security_rsp(param->ble_security.ble_req.bd_addr, true);
Expand Down Expand Up @@ -691,7 +669,7 @@ static void gattc_events_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc
status = p_data->reg.status;
bt_obj.gattc_if = gattc_if;
if (bt_obj.secure){
esp_ble_gap_config_local_privacy(true);
esp_ble_gap_config_local_privacy(bt_obj.privacy);
}
break;
case ESP_GATTC_OPEN_EVT:
Expand Down Expand Up @@ -855,7 +833,7 @@ static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_
case ESP_GATTS_REG_EVT:
bt_obj.gatts_if = gatts_if;
if (bt_obj.secure){
esp_ble_gap_config_local_privacy(true);
esp_ble_gap_config_local_privacy(bt_obj.privacy);
}
break;
case ESP_GATTS_READ_EVT: {
Expand Down Expand Up @@ -905,12 +883,6 @@ static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_
if (char_obj->trigger & MOD_BT_GATTS_SUBSCRIBE_EVT) {
mp_irq_queue_interrupt(gatts_char_callback_handler, char_obj);
}

if (value == 0x0001) { // notifications enabled
bt_gatts_char_obj_t *char_obj = (bt_gatts_char_obj_t *)attr_obj->parent;
// the size of value[] needs to be less than MTU size
esp_ble_gatts_send_indicate(gatts_if, param->write.conn_id, char_obj->attr_obj.handle, char_obj->attr_obj.value_len, char_obj->attr_obj.value, false);
}
Comment on lines -909 to -913
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know why it is removed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines should be kept to send notifications in case of WRITE events when enabled.

}
}
esp_ble_gatts_send_response(gatts_if, p->write.conn_id, p->write.trans_id, ESP_GATT_OK, NULL);
Expand Down Expand Up @@ -963,20 +935,13 @@ static void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_
if (bt_obj.trigger & MOD_BT_GATTS_CONN_EVT) {
mp_irq_queue_interrupt(bluetooth_callback_handler, (void *)&bt_obj);
}
if (bt_obj.secure){
esp_ble_set_encryption(p->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_MITM);
}
Comment on lines -966 to -968
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is okay anyways, esp_ble_set_encryption(p->connect.remote_bda, ESP_BLE_SEC_ENCRYPT_MITM) instruction causes that a bonding request is sent to master, when slave tries to just connect. As @DvdGiessen mentioned:

A secure connection will be established as soon as an encrypted characteristic is touched, meaning that by setting permissions it is possible to specify unencrypted characteristics which may be accessed without pairing. By default the permissions are set to encrypted if security is enabled, this was not changed and thus everything will function exactly the same.

This modification is OK.

}
break;
case ESP_GATTS_DISCONNECT_EVT:
bt_obj.gatts_conn_id = -1;
xEventGroupClearBits(bt_event_group, MOD_BT_GATTS_MTU_EVT);
if (bt_obj.advertising) {
if (!bt_obj.secure){
esp_ble_gap_start_advertising(&bt_adv_params);
} else {
esp_ble_gap_start_advertising(&bt_adv_params_sec);
}
esp_ble_gap_start_advertising(&bt_adv_params);
}
bt_obj.events |= MOD_BT_GATTS_DISCONN_EVT;
xEventGroupSetBits(bt_event_group, MOD_BT_GATTS_DISCONN_EVT);
Expand Down Expand Up @@ -1028,7 +993,7 @@ static mp_obj_t bt_init_helper(bt_obj_t *self, const mp_arg_val_t *args) {
esp_ble_gatts_app_register(MOD_BT_SERVER_APP_ID);

//set MTU
uint16_t mtu = args[5].u_int;
uint16_t mtu = args[7].u_int;
if(mtu > BT_MTU_SIZE_MAX)
{
esp_ble_gatt_set_local_mtu(BT_MTU_SIZE_MAX);
Expand Down Expand Up @@ -1075,24 +1040,29 @@ static mp_obj_t bt_init_helper(bt_obj_t *self, const mp_arg_val_t *args) {
if (args[3].u_bool){
bt_obj.secure = true;

uint32_t passKey = args[4].u_int;
if (!is_pin_valid(passKey)){
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Only 6 digit (0-9) pins are allowed"));
}
set_secure_parameters(passKey);
// modified default advertisement parameters for secure
bt_adv_params.adv_int_min = 0x100;
bt_adv_params.adv_int_max = 0x100;
bt_adv_params.own_addr_type = args[5].u_bool ? BLE_ADDR_TYPE_RANDOM : BLE_ADDR_TYPE_PUBLIC;

set_pin(args[4].u_int);
bt_obj.privacy = args[5].u_bool;
set_secure_parameters(args[6].u_bool);
}

return mp_const_none;
}

STATIC const mp_arg_t bt_init_args[] = {
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = E_BT_STACK_MODE_BLE} },
{ MP_QSTR_antenna, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_modem_sleep, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_secure, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
{ MP_QSTR_pin, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 123456} },
{ MP_QSTR_mtu, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = BT_MTU_SIZE_MAX} },
{ MP_QSTR_id, MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = E_BT_STACK_MODE_BLE} },
{ MP_QSTR_antenna, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_modem_sleep, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_secure, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
{ MP_QSTR_pin, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 123456} },
{ MP_QSTR_privacy, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
{ MP_QSTR_secure_connections, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
{ MP_QSTR_mtu, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = BT_MTU_SIZE_MAX} },

};
STATIC mp_obj_t bt_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *all_args) {
Expand Down Expand Up @@ -1445,35 +1415,47 @@ static mp_obj_t modbt_connect(mp_obj_t addr)

STATIC mp_obj_t bt_set_advertisement_params (mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with original code is that if we call bt_set_advertisement_params() with keyword argument(s), than unmentioned bt_adv_params will be reinitiated, which is probably not the intended behaviour of the function.

Example with original code:

  1. Calling bt_set_advertisement_params(adv_int_max = 128)
    • bt_adv_params.adv_int_min = 32
    • bt_adv_params.adv_int_max = 128
  2. Calling bt_set_advertisement_params(adv_int_min = 16)
    • bt_adv_params.adv_int_min = 16
    • bt_adv_params.adv_int_max = 64 <- adv_int_max is reinitialized

Example with new code:

  1. Calling bt_set_advertisement_params(adv_int_max = 128)
    • bt_adv_params.adv_int_min = 32
    • bt_adv_params.adv_int_max = 128
  2. Calling bt_set_advertisement_params(adv_int_min = 16)
    • bt_adv_params.adv_int_min = 16
    • bt_adv_params.adv_int_max = 128 <- adv_int_max remains the same

The behaviour is tested on LoPy4, I suggest to accept all the modifications inside bt_set_advertisement_params() function definition.

static const mp_arg_t allowed_args[] = {
{ MP_QSTR_adv_int_min, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0x20} },
{ MP_QSTR_adv_int_max, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0x40} },
{ MP_QSTR_adv_type, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = ADV_TYPE_IND} },
{ MP_QSTR_own_addr_type, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = BLE_ADDR_TYPE_PUBLIC} },
{ MP_QSTR_channel_map, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = ADV_CHNL_ALL} },
{ MP_QSTR_adv_filter_policy, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY} },
{ MP_QSTR_adv_int_min, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_adv_int_max, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_adv_type, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_own_addr_type, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_channel_map, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_adv_filter_policy, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
};

// parse args
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(args), allowed_args, args);

// adv_int_min
bt_adv_params.adv_int_min = (uint16_t)args[0].u_int;
if (args[0].u_obj != MP_OBJ_NULL) {
bt_adv_params.adv_int_min = (uint16_t) mp_obj_get_int(args[0].u_obj);
}

// adv_int_max
bt_adv_params.adv_int_max = (uint16_t)args[1].u_int;
if (args[1].u_obj != MP_OBJ_NULL) {
bt_adv_params.adv_int_max = (uint16_t) mp_obj_get_int(args[1].u_obj);
}

// adv_type
bt_adv_params.adv_type = (esp_ble_adv_type_t)args[2].u_int;
if (args[2].u_obj != MP_OBJ_NULL) {
bt_adv_params.adv_type = (esp_ble_adv_type_t) mp_obj_get_int(args[2].u_obj);
}

// own_addr_type
bt_adv_params.own_addr_type = (esp_ble_addr_type_t)args[3].u_int;
if (args[3].u_obj != MP_OBJ_NULL) {
bt_adv_params.own_addr_type = (esp_ble_addr_type_t) mp_obj_get_int(args[3].u_obj);
}

// channel_map
bt_adv_params.channel_map = (esp_ble_adv_channel_t)args[4].u_int;
if (args[4].u_obj != MP_OBJ_NULL) {
bt_adv_params.channel_map = (esp_ble_adv_channel_t) mp_obj_get_int(args[4].u_obj);
}

// adv_filter_policy
bt_adv_params.adv_filter_policy = (esp_ble_adv_filter_t)args[5].u_int;
if (args[5].u_obj != MP_OBJ_NULL) {
bt_adv_params.adv_filter_policy = (esp_ble_adv_filter_t) mp_obj_get_int(args[5].u_obj);
}

return mp_const_none;
}
Expand Down Expand Up @@ -1606,15 +1588,18 @@ STATIC mp_obj_t bt_set_advertisement_raw(mp_obj_t self_in, mp_obj_t raw_data) {
STATIC MP_DEFINE_CONST_FUN_OBJ_2(bt_set_advertisement_raw_obj, bt_set_advertisement_raw);


STATIC mp_obj_t bt_set_pin(mp_obj_t self_in, mp_obj_t arg) {
set_pin(mp_obj_get_int(arg));
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(bt_set_pin_obj, bt_set_pin);


STATIC mp_obj_t bt_advertise(mp_obj_t self_in, mp_obj_t enable) {
if (mp_obj_is_true(enable)) {
// some sensible time to wait for the advertisement configuration to complete
mp_hal_delay_ms(50);
if (!bt_obj.secure){
esp_ble_gap_start_advertising(&bt_adv_params);
} else {
esp_ble_gap_start_advertising(&bt_adv_params_sec);
}
esp_ble_gap_start_advertising(&bt_adv_params);
bt_obj.advertising = true;
} else {
esp_ble_gap_stop_advertising();
Expand Down Expand Up @@ -2056,6 +2041,7 @@ STATIC const mp_map_elem_t bt_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_advertisement_params),(mp_obj_t)&bt_set_advertisement_params_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_advertisement), (mp_obj_t)&bt_set_advertisement_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_advertisement_raw), (mp_obj_t)&bt_set_advertisement_raw_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_set_pin), (mp_obj_t)&bt_set_pin_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_advertise), (mp_obj_t)&bt_advertise_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_service), (mp_obj_t)&bt_service_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_callback), (mp_obj_t)&bt_callback_obj },
Expand Down Expand Up @@ -2109,6 +2095,15 @@ STATIC const mp_map_elem_t bt_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_PROP_AUTH), MP_OBJ_NEW_SMALL_INT(ESP_GATT_CHAR_PROP_BIT_AUTH) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_PROP_EXT_PROP), MP_OBJ_NEW_SMALL_INT(ESP_GATT_CHAR_PROP_BIT_EXT_PROP) },

{ MP_OBJ_NEW_QSTR(MP_QSTR_PERM_READ), MP_OBJ_NEW_SMALL_INT(ESP_GATT_PERM_READ) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_PERM_READ_ENCRYPTED), MP_OBJ_NEW_SMALL_INT(ESP_GATT_PERM_READ_ENCRYPTED) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_PERM_READ_ENC_MITM), MP_OBJ_NEW_SMALL_INT(ESP_GATT_PERM_READ_ENC_MITM) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_PERM_WRITE), MP_OBJ_NEW_SMALL_INT(ESP_GATT_PERM_WRITE) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_PERM_WRITE_ENCRYPTED), MP_OBJ_NEW_SMALL_INT(ESP_GATT_PERM_WRITE_ENCRYPTED) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_PERM_WRITE_ENC_MITM), MP_OBJ_NEW_SMALL_INT(ESP_GATT_PERM_WRITE_ENC_MITM) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_PERM_WRITE_SIGNED), MP_OBJ_NEW_SMALL_INT(ESP_GATT_PERM_WRITE_SIGNED) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_PERM_WRITE_SIGNED_MITM), MP_OBJ_NEW_SMALL_INT(ESP_GATT_PERM_WRITE_SIGNED_MITM) },

// Defined at https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
{ MP_OBJ_NEW_QSTR(MP_QSTR_CHAR_CONFIG_NOTIFY), MP_OBJ_NEW_SMALL_INT(1 << 0) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_CHAR_CONFIG_INDICATE), MP_OBJ_NEW_SMALL_INT(1 << 1) },
Expand Down