summaryrefslogtreecommitdiff
path: root/shared-bindings
diff options
context:
space:
mode:
authorScott Shawcroft <scott@tannewt.org>2018-11-07 12:03:46 -0800
committerGitHub <noreply@github.com>2018-11-07 12:03:46 -0800
commitd08747d374057b24803b429bbf6474a2e4dcea5c (patch)
treec3bfee81668dbd842039c178222fda9df77a9b76 /shared-bindings
parent283e07254e9eb50e52d6f07b7ac177feeef02d83 (diff)
parent64d457dad9bb3843ee468136022996ecb91a98df (diff)
Merge pull request #1319 from dhalbert/origin/arturo182_bleio_pr_1289
Resubmit PR #1289, "WIP: bleio rewrite" by @arturo182
Diffstat (limited to 'shared-bindings')
-rw-r--r--shared-bindings/bleio/Adapter.c15
-rw-r--r--shared-bindings/bleio/Adapter.h4
-rw-r--r--shared-bindings/bleio/Address.c167
-rw-r--r--shared-bindings/bleio/Address.h34
-rw-r--r--shared-bindings/bleio/AddressType.c99
-rw-r--r--shared-bindings/bleio/AddressType.h50
-rw-r--r--shared-bindings/bleio/AdvertisementData.c90
-rw-r--r--shared-bindings/bleio/AdvertisementData.h34
-rw-r--r--shared-bindings/bleio/Characteristic.c332
-rw-r--r--shared-bindings/bleio/Characteristic.h38
-rw-r--r--shared-bindings/bleio/Descriptor.c171
-rw-r--r--shared-bindings/bleio/Descriptor.h40
-rw-r--r--shared-bindings/bleio/Device.c357
-rw-r--r--shared-bindings/bleio/Device.h42
-rw-r--r--shared-bindings/bleio/ScanEntry.c308
-rw-r--r--shared-bindings/bleio/ScanEntry.h35
-rw-r--r--shared-bindings/bleio/Scanner.c162
-rw-r--r--shared-bindings/bleio/Scanner.h39
-rw-r--r--shared-bindings/bleio/Service.c170
-rw-r--r--shared-bindings/bleio/Service.h37
-rw-r--r--shared-bindings/bleio/UUID.c146
-rw-r--r--shared-bindings/bleio/UUID.h39
-rw-r--r--shared-bindings/bleio/UUIDType.c75
-rw-r--r--shared-bindings/bleio/UUIDType.h46
-rw-r--r--shared-bindings/bleio/__init__.c42
25 files changed, 2557 insertions, 15 deletions
diff --git a/shared-bindings/bleio/Adapter.c b/shared-bindings/bleio/Adapter.c
index bfe87071d..d9449d3ab 100644
--- a/shared-bindings/bleio/Adapter.c
+++ b/shared-bindings/bleio/Adapter.c
@@ -25,6 +25,7 @@
*/
#include "py/objproperty.h"
+#include "shared-bindings/bleio/Address.h"
#include "shared-bindings/bleio/Adapter.h"
//| .. currentmodule:: bleio
@@ -57,8 +58,6 @@
//| MAC address of the BLE adapter. (read-only)
//|
-#define BLE_ADDRESS_LEN 17
-
STATIC mp_obj_t bleio_adapter_get_enabled(mp_obj_t self) {
return mp_obj_new_bool(common_hal_bleio_adapter_get_enabled());
}
@@ -81,16 +80,12 @@ const mp_obj_property_t bleio_adapter_enabled_obj = {
};
STATIC mp_obj_t bleio_adapter_get_address(mp_obj_t self) {
- vstr_t vstr;
- vstr_init(&vstr, BLE_ADDRESS_LEN);
-
- common_hal_bleio_adapter_get_address(&vstr);
-
- const mp_obj_t mac_str = mp_obj_new_str(vstr.buf, vstr.len);
+ mp_obj_t obj = bleio_address_type.make_new(&bleio_address_type, 1, 0, mp_const_none);
+ bleio_address_obj_t *address = MP_OBJ_TO_PTR(obj);
- vstr_clear(&vstr);
+ common_hal_bleio_adapter_get_address(address);
- return mac_str;
+ return obj;
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_address_obj, bleio_adapter_get_address);
diff --git a/shared-bindings/bleio/Adapter.h b/shared-bindings/bleio/Adapter.h
index 6c5d56948..fe3886e59 100644
--- a/shared-bindings/bleio/Adapter.h
+++ b/shared-bindings/bleio/Adapter.h
@@ -27,12 +27,12 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H
-#include "py/obj.h"
+#include "shared-module/bleio/Address.h"
const mp_obj_type_t bleio_adapter_type;
extern bool common_hal_bleio_adapter_get_enabled(void);
extern void common_hal_bleio_adapter_set_enabled(bool enabled);
-extern void common_hal_bleio_adapter_get_address(vstr_t *address);
+extern void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H
diff --git a/shared-bindings/bleio/Address.c b/shared-bindings/bleio/Address.c
new file mode 100644
index 000000000..ec23ff207
--- /dev/null
+++ b/shared-bindings/bleio/Address.c
@@ -0,0 +1,167 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include "py/objproperty.h"
+#include "py/objstr.h"
+#include "py/runtime.h"
+#include "shared-bindings/bleio/Address.h"
+#include "shared-module/bleio/Address.h"
+
+#define ADDRESS_LONG_LEN 17 // XX:XX:XX:XX:XX:XX
+#define ADDRESS_SHORT_LEN 12 // XXXXXXXXXXXX
+
+//| .. currentmodule:: bleio
+//|
+//| :class:`Address` -- BLE address
+//| =========================================================
+//|
+//| Encapsulates the address of a BLE device.
+//|
+
+//| .. class:: Address(address)
+//|
+//| Create a new Address object encapsulating the address value.
+//| The value itself can be one of:
+//|
+//| - a `str` value in the format of 'XXXXXXXXXXXX' or 'XX:XX:XX:XX:XX'
+//| - a `bytes` or `bytearray` containing 6 bytes
+//| - another Address object
+//|
+//| :param address: The address to encapsulate
+//|
+
+//| .. attribute:: type
+//|
+//| The address type. One of:
+//|
+//| - `bleio.AddressType.PUBLIC`
+//| - `bleio.AddressType.RANDOM_STATIC`
+//| - `bleio.AddressType.RANDOM_PRIVATE_RESOLVABLE`
+//| - `bleio.AddressType.RANDOM_PRIVATE_NON_RESOLVABLE`
+//|
+STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
+ mp_arg_check_num(n_args, n_kw, 1, 1, true);
+ bleio_address_obj_t *self = m_new_obj(bleio_address_obj_t);
+ self->base.type = &bleio_address_type;
+ self->type = ADDRESS_PUBLIC;
+
+ mp_map_t kw_args;
+ mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
+
+ enum { ARG_address };
+ static const mp_arg_t allowed_args[] = {
+ { ARG_address, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ const mp_obj_t address = args[ARG_address].u_obj;
+
+ if (MP_OBJ_IS_STR(address)) {
+ GET_STR_DATA_LEN(address, str_data, str_len);
+ const bool is_long = (str_len == ADDRESS_LONG_LEN);
+ const bool is_short = (str_len == ADDRESS_SHORT_LEN);
+
+ if (is_long || is_short) {
+ size_t i = str_len - 1;
+ for (size_t b = 0; b < BLEIO_ADDRESS_BYTES; ++b) {
+ self->value[b] = unichar_xdigit_value(str_data[i]) |
+ unichar_xdigit_value(str_data[i - 1]) << 4;
+
+ i -= is_long ? 3 : 2;
+ }
+ } else {
+ mp_raise_ValueError(translate("Wrong address length"));
+ }
+ } else if (MP_OBJ_IS_TYPE(address, &mp_type_bytearray) || MP_OBJ_IS_TYPE(address, &mp_type_bytes)) {
+ mp_buffer_info_t buf_info;
+ mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ);
+ if (buf_info.len != BLEIO_ADDRESS_BYTES) {
+ mp_raise_ValueError(translate("Wrong number of bytes provided"));
+ }
+
+ for (size_t b = 0; b < BLEIO_ADDRESS_BYTES; ++b) {
+ self->value[BLEIO_ADDRESS_BYTES - b - 1] = ((uint8_t*)buf_info.buf)[b];
+ }
+ } else if (MP_OBJ_IS_TYPE(address, &bleio_address_type)) {
+ // deep copy
+ bleio_address_obj_t *other = MP_OBJ_TO_PTR(address);
+ self->type = other->type;
+ memcpy(self->value, other->value, BLEIO_ADDRESS_BYTES);
+ }
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+STATIC void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ mp_printf(print, "Address('"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT"')",
+ self->value[5], self->value[4], self->value[3],
+ self->value[2], self->value[1], self->value[0]);
+}
+
+STATIC mp_obj_t bleio_address_get_type(mp_obj_t self_in) {
+ bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ if (self->type == ADDRESS_PUBLIC) {
+ return (mp_obj_t)&bleio_addresstype_public_obj;
+ } else if (self->type == ADDRESS_RANDOM_STATIC) {
+ return (mp_obj_t)&bleio_addresstype_random_static_obj;
+ } else if (self->type == ADDRESS_RANDOM_PRIVATE_RESOLVABLE) {
+ return (mp_obj_t)&bleio_addresstype_random_private_resolvable_obj;
+ } else if (self->type == ADDRESS_RANDOM_PRIVATE_NON_RESOLVABLE) {
+ return (mp_obj_t)&bleio_addresstype_random_private_non_resolvable_obj;
+ }
+
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_address_get_type_obj, bleio_address_get_type);
+
+const mp_obj_property_t bleio_address_type_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&bleio_address_get_type_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+STATIC const mp_rom_map_elem_t bleio_address_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_address_type_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(bleio_address_locals_dict, bleio_address_locals_dict_table);
+
+const mp_obj_type_t bleio_address_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Address,
+ .print = bleio_address_print,
+ .make_new = bleio_address_make_new,
+ .locals_dict = (mp_obj_dict_t*)&bleio_address_locals_dict
+};
diff --git a/shared-bindings/bleio/Address.h b/shared-bindings/bleio/Address.h
new file mode 100644
index 000000000..9c9e20968
--- /dev/null
+++ b/shared-bindings/bleio/Address.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H
+
+#include "py/objtype.h"
+
+extern const mp_obj_type_t bleio_address_type;
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H
diff --git a/shared-bindings/bleio/AddressType.c b/shared-bindings/bleio/AddressType.c
new file mode 100644
index 000000000..cf2151c94
--- /dev/null
+++ b/shared-bindings/bleio/AddressType.c
@@ -0,0 +1,99 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-bindings/bleio/AddressType.h"
+
+//| .. currentmodule:: bleio
+//|
+//| :class:`AddressType` -- defines the type of a BLE address
+//| =============================================================
+//|
+//| .. class:: bleio.AddressType
+//|
+//| Enum-like class to define the type of a BLE address, see also `bleio.Address`.
+//|
+//| .. data:: PUBLIC
+//|
+//| The address is public
+//|
+//| .. data:: RANDOM_STATIC
+//|
+//| The address is random static
+//|
+//| .. data:: RANDOM_PRIVATE_RESOLVABLE
+//|
+//| The address is random private resolvable
+//|
+//| .. data:: RANDOM_PRIVATE_NON_RESOLVABLE
+//|
+//| The address is private non-resolvable
+//|
+const mp_obj_type_t bleio_addresstype_type;
+
+const bleio_addresstype_obj_t bleio_addresstype_public_obj = {
+ { &bleio_addresstype_type },
+};
+
+const bleio_addresstype_obj_t bleio_addresstype_random_static_obj = {
+ { &bleio_addresstype_type },
+};
+
+const bleio_addresstype_obj_t bleio_addresstype_random_private_resolvable_obj = {
+ { &bleio_addresstype_type },
+};
+
+const bleio_addresstype_obj_t bleio_addresstype_random_private_non_resolvable_obj = {
+ { &bleio_addresstype_type },
+};
+
+STATIC const mp_rom_map_elem_t bleio_addresstype_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_PUBLIC), MP_ROM_PTR(&bleio_addresstype_public_obj) },
+ { MP_ROM_QSTR(MP_QSTR_RANDOM_STATIC), MP_ROM_PTR(&bleio_addresstype_random_static_obj) },
+ { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_RESOLVABLE), MP_ROM_PTR(&bleio_addresstype_random_private_resolvable_obj) },
+ { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE), MP_ROM_PTR(&bleio_addresstype_random_private_non_resolvable_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(bleio_addresstype_locals_dict, bleio_addresstype_locals_dict_table);
+
+STATIC void bleio_addresstype_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ qstr type = MP_QSTR_PUBLIC;
+
+ if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_static_obj)) {
+ type = MP_QSTR_RANDOM_STATIC;
+ } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_private_resolvable_obj)) {
+ type = MP_QSTR_RANDOM_PRIVATE_RESOLVABLE;
+ } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_private_non_resolvable_obj)) {
+ type = MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE;
+ }
+
+ mp_printf(print, "%q.%q.%q", MP_QSTR_bleio, MP_QSTR_AddressType, type);
+}
+
+const mp_obj_type_t bleio_addresstype_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_AddressType,
+ .print = bleio_addresstype_print,
+ .locals_dict = (mp_obj_t)&bleio_addresstype_locals_dict,
+};
diff --git a/shared-bindings/bleio/AddressType.h b/shared-bindings/bleio/AddressType.h
new file mode 100644
index 000000000..e69caffab
--- /dev/null
+++ b/shared-bindings/bleio/AddressType.h
@@ -0,0 +1,50 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H
+
+#include "py/obj.h"
+
+typedef enum {
+ ADDRESS_PUBLIC,
+ ADDRESS_RANDOM_STATIC,
+ ADDRESS_RANDOM_PRIVATE_RESOLVABLE,
+ ADDRESS_RANDOM_PRIVATE_NON_RESOLVABLE
+} bleio_address_type_t;
+
+extern const mp_obj_type_t bleio_addresstype_type;
+
+typedef struct {
+ mp_obj_base_t base;
+} bleio_addresstype_obj_t;
+
+extern const bleio_addresstype_obj_t bleio_addresstype_public_obj;
+extern const bleio_addresstype_obj_t bleio_addresstype_random_static_obj;
+extern const bleio_addresstype_obj_t bleio_addresstype_random_private_resolvable_obj;
+extern const bleio_addresstype_obj_t bleio_addresstype_random_private_non_resolvable_obj;
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H
diff --git a/shared-bindings/bleio/AdvertisementData.c b/shared-bindings/bleio/AdvertisementData.c
new file mode 100644
index 000000000..9cfdd74e9
--- /dev/null
+++ b/shared-bindings/bleio/AdvertisementData.c
@@ -0,0 +1,90 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/obj.h"
+#include "shared-module/bleio/AdvertisementData.h"
+
+//| .. currentmodule:: bleio
+//|
+//| :class:`AdvertisementData` -- data used during BLE advertising
+//| ==============================================================
+//|
+//| Represents the data to be broadcast during BLE advertising.
+//|
+
+STATIC const mp_rom_map_elem_t bleio_advertisementdata_locals_dict_table[] = {
+ // Static variables
+ { MP_ROM_QSTR(MP_QSTR_FLAGS), MP_ROM_INT(AdFlags) },
+ { MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_16BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf16BitServiceClassUUIDs) },
+ { MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_16BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf16BitServiceClassUUIDs) },
+ { MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_32BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf32BitServiceClassUUIDs) },
+ { MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_32BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf32BitServiceClassUUIDs) },
+ { MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_128BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf128BitServiceClassUUIDs) },
+ { MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_128BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf128BitServiceClassUUIDs) },
+ { MP_ROM_QSTR(MP_QSTR_SHORTENED_LOCAL_NAME), MP_ROM_INT(AdShortenedLocalName) },
+ { MP_ROM_QSTR(MP_QSTR_COMPLETE_LOCAL_NAME), MP_ROM_INT(AdCompleteLocalName) },
+ { MP_ROM_QSTR(MP_QSTR_TX_POWER_LEVEL), MP_ROM_INT(AdTxPowerLevel) },
+ { MP_ROM_QSTR(MP_QSTR_CLASS_OF_DEVICE), MP_ROM_INT(AdClassOfDevice) },
+ { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_HASH_C), MP_ROM_INT(AdSimplePairingHashC) },
+ { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_RANDOMIZER_R), MP_ROM_INT(AdSimplePairingRandomizerR) },
+ { MP_ROM_QSTR(MP_QSTR_SECURITY_MANAGER_TK_VALUE), MP_ROM_INT(AdSecurityManagerTKValue) },
+ { MP_ROM_QSTR(MP_QSTR_SECURITY_MANAGER_OOB_FLAGS), MP_ROM_INT(AdSecurityManagerOOBFlags) },
+ { MP_ROM_QSTR(MP_QSTR_SLAVE_CONNECTION_INTERVAL_RANGE), MP_ROM_INT(AdSlaveConnectionIntervalRange) },
+ { MP_ROM_QSTR(MP_QSTR_LIST_OF_16BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf16BitServiceSolicitationUUIDs) },
+ { MP_ROM_QSTR(MP_QSTR_LIST_OF_128BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf128BitServiceSolicitationUUIDs) },
+ { MP_ROM_QSTR(MP_QSTR_SERVICE_DATA), MP_ROM_INT(AdServiceData) },
+ { MP_ROM_QSTR(MP_QSTR_PUBLIC_TARGET_ADDRESS), MP_ROM_INT(AdPublicTargetAddress) },
+ { MP_ROM_QSTR(MP_QSTR_RANDOM_TARGET_ADDRESS), MP_ROM_INT(AdRandomTargetAddress) },
+ { MP_ROM_QSTR(MP_QSTR_APPEARANCE), MP_ROM_INT(AdAppearance) },
+ { MP_ROM_QSTR(MP_QSTR_ADVERTISING_INTERNAL), MP_ROM_INT(AdAdvertisingInterval) },
+ { MP_ROM_QSTR(MP_QSTR_LE_BLUETOOTH_DEVICE_ADDRESS), MP_ROM_INT(AdLEBluetoothDeviceAddress) },
+ { MP_ROM_QSTR(MP_QSTR_LE_ROLE), MP_ROM_INT(AdLERole) },
+ { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_HASH_C256), MP_ROM_INT(AdSimplePairingHashC256) },
+ { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_RANDOMIZER_R256), MP_ROM_INT(AdSimplePairingRandomizerR256) },
+ { MP_ROM_QSTR(MP_QSTR_LIST_OF_32BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf32BitServiceSolicitationUUIDs) },
+ { MP_ROM_QSTR(MP_QSTR_SERVICE_DATA_32BIT_UUID), MP_ROM_INT(AdServiceData32BitUUID) },
+ { MP_ROM_QSTR(MP_QSTR_SERVICE_DATA_128BIT_UUID), MP_ROM_INT(AdServiceData128BitUUID) },
+ { MP_ROM_QSTR(MP_QSTR_LE_SECURE_CONNECTIONS_CONFIRMATION_VALUE), MP_ROM_INT(AdLESecureConnectionsConfirmationValue) },
+ { MP_ROM_QSTR(MP_QSTR_LE_SECURE_CONNECTIONS_RANDOM_VALUE), MP_ROM_INT(AdLESecureConnectionsRandomValue) },
+ { MP_ROM_QSTR(MP_QSTR_URI), MP_ROM_INT(AdURI) },
+ { MP_ROM_QSTR(MP_QSTR_INDOOR_POSITIONING), MP_ROM_INT(AdIndoorPositioning) },
+ { MP_ROM_QSTR(MP_QSTR_TRANSPORT_DISCOVERY_DATA), MP_ROM_INT(AdTransportDiscoveryData) },
+ { MP_ROM_QSTR(MP_QSTR_LE_SUPPORTED_FEATURES), MP_ROM_INT(AdLESupportedFeatures) },
+ { MP_ROM_QSTR(MP_QSTR_CHANNEL_MAP_UPDATE_INDICATION), MP_ROM_INT(AdChannelMapUpdateIndication) },
+ { MP_ROM_QSTR(MP_QSTR_PB_ADV), MP_ROM_INT(AdPBADV) },
+ { MP_ROM_QSTR(MP_QSTR_MESH_MESSAGE), MP_ROM_INT(AdMeshMessage) },
+ { MP_ROM_QSTR(MP_QSTR_MESH_BEACON), MP_ROM_INT(AdMeshBeacon) },
+ { MP_ROM_QSTR(MP_QSTR_3D_INFORMATION_DATA), MP_ROM_INT(Ad3DInformationData) },
+ { MP_ROM_QSTR(MP_QSTR_MANUFACTURER_SPECIFIC_DATA), MP_ROM_INT(AdManufacturerSpecificData) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(bleio_advertisementdata_locals_dict, bleio_advertisementdata_locals_dict_table);
+
+const mp_obj_type_t bleio_advertisementdata_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_AdvertisementData,
+ .locals_dict = (mp_obj_dict_t*)&bleio_advertisementdata_locals_dict
+};
diff --git a/shared-bindings/bleio/AdvertisementData.h b/shared-bindings/bleio/AdvertisementData.h
new file mode 100644
index 000000000..05b5a2c8d
--- /dev/null
+++ b/shared-bindings/bleio/AdvertisementData.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADVERTISEMENTDATA_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADVERTISEMENTDATA_H
+
+#include "py/obj.h"
+
+extern const mp_obj_type_t bleio_advertisementdata_type;
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADVERTISEMENTDATA_H
diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c
new file mode 100644
index 000000000..369f3f991
--- /dev/null
+++ b/shared-bindings/bleio/Characteristic.c
@@ -0,0 +1,332 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "shared-bindings/bleio/Characteristic.h"
+#include "shared-bindings/bleio/UUID.h"
+
+//| .. currentmodule:: bleio
+//|
+//| :class:`Characteristic` -- BLE service characteristic
+//| =========================================================
+//|
+//| Stores information about a BLE service characteristic and allows to read
+//| and write the characteristic's value.
+//|
+
+//| .. class:: Characteristic(uuid)
+//|
+//| Create a new Characteristic object identified by the specified UUID.
+//|
+//| :param bleio.UUID uuid: The uuid of the characteristic
+//|
+
+//| .. attribute:: broadcast
+//|
+//| A `bool` specifying if the characteristic allows broadcasting its value.
+//|
+
+//| .. attribute:: indicate
+//|
+//| A `bool` specifying if the characteristic allows indicating its value.
+//|
+
+//| .. attribute:: notify
+//|
+//| A `bool` specifying if the characteristic allows notifying its value.
+//|
+
+//| .. attribute:: read
+//|
+//| A `bool` specifying if the characteristic allows reading its value.
+//|
+
+//| .. attribute:: uuid
+//|
+//| The UUID of this characteristic. (read-only)
+//|
+
+//| .. attribute:: value
+//|
+//| The value of this characteristic. The value can be written to if the `write` property allows it.
+//| If the `read` property allows it, the value can be read. If the `notify` property is set, writting
+//| to the value will generate a BLE notification.
+//|
+
+//| .. attribute:: write
+//|
+//| A `bool` specifying if the characteristic allows writting to its value.
+//|
+
+//| .. attribute:: write_no_resp
+//|
+//| A `bool` specifying if the characteristic allows writting to its value without response.
+//|
+STATIC void bleio_characteristic_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ mp_printf(print, "Characteristic(uuid: 0x"HEX2_FMT""HEX2_FMT" handle: 0x" HEX2_FMT ")",
+ self->uuid->value[1], self->uuid->value[0], self->handle);
+}
+
+STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
+ mp_arg_check_num(n_args, n_kw, 1, 1, true);
+ bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t);
+ self->base.type = &bleio_characteristic_type;
+ self->service = NULL;
+ self->value_data = NULL;
+
+ mp_map_t kw_args;
+ mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
+
+ enum { ARG_uuid };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_uuid, MP_ARG_REQUIRED| MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ const mp_obj_t uuid = args[ARG_uuid].u_obj;
+
+ if (uuid == mp_const_none) {
+ return MP_OBJ_FROM_PTR(self);
+ }
+
+ if (MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) {
+ self->uuid = MP_OBJ_TO_PTR(uuid);
+ } else {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
+ translate("Invalid UUID parameter")));
+ }
+
+ common_hal_bleio_characteristic_construct(self);
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+STATIC mp_obj_t bleio_characteristic_get_broadcast(mp_obj_t self_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(self->props.broadcast);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_broadcast_obj, bleio_characteristic_get_broadcast);
+
+STATIC mp_obj_t bleio_characteristic_set_broadcast(mp_obj_t self_in, mp_obj_t broadcast_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ self->props.broadcast = mp_obj_is_true(broadcast_in);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_broadcast_obj, bleio_characteristic_set_broadcast);
+
+const mp_obj_property_t bleio_characteristic_broadcast_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_characteristic_get_broadcast_obj,
+ (mp_obj_t)&bleio_characteristic_set_broadcast_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t bleio_characteristic_get_indicate(mp_obj_t self_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(self->props.indicate);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_indicate_obj, bleio_characteristic_get_indicate);
+
+STATIC mp_obj_t bleio_characteristic_set_indicate(mp_obj_t self_in, mp_obj_t indicate_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ self->props.indicate = mp_obj_is_true(indicate_in);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_indicate_obj, bleio_characteristic_set_indicate);
+
+const mp_obj_property_t bleio_characteristic_indicate_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_characteristic_get_indicate_obj,
+ (mp_obj_t)&bleio_characteristic_set_indicate_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t bleio_characteristic_get_notify(mp_obj_t self_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(self->props.notify);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_notify_obj, bleio_characteristic_get_notify);
+
+STATIC mp_obj_t bleio_characteristic_set_notify(mp_obj_t self_in, mp_obj_t notify_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ self->props.notify = mp_obj_is_true(notify_in);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_notify_obj, bleio_characteristic_set_notify);
+
+const mp_obj_property_t bleio_characteristic_notify_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_characteristic_get_notify_obj,
+ (mp_obj_t)&bleio_characteristic_set_notify_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t bleio_characteristic_get_read(mp_obj_t self_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(self->props.read);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_read_obj, bleio_characteristic_get_read);
+
+STATIC mp_obj_t bleio_characteristic_set_read(mp_obj_t self_in, mp_obj_t read_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ self->props.read = mp_obj_is_true(read_in);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_read_obj, bleio_characteristic_set_read);
+
+const mp_obj_property_t bleio_characteristic_read_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_characteristic_get_read_obj,
+ (mp_obj_t)&bleio_characteristic_set_read_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t bleio_characteristic_get_write(mp_obj_t self_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(self->props.write);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_obj, bleio_characteristic_get_write);
+
+STATIC mp_obj_t bleio_characteristic_set_write(mp_obj_t self_in, mp_obj_t write_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ self->props.write = mp_obj_is_true(write_in);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_write_obj, bleio_characteristic_set_write);
+
+const mp_obj_property_t bleio_characteristic_write_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_characteristic_get_write_obj,
+ (mp_obj_t)&bleio_characteristic_set_write_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t bleio_characteristic_get_write_wo_resp(mp_obj_t self_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(self->props.write_wo_resp);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_wo_resp_obj, bleio_characteristic_get_write_wo_resp);
+
+STATIC mp_obj_t bleio_characteristic_set_write_wo_resp(mp_obj_t self_in, mp_obj_t write_wo_resp_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ self->props.write_wo_resp = mp_obj_is_true(write_wo_resp_in);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_write_wo_resp_obj, bleio_characteristic_set_write_wo_resp);
+
+const mp_obj_property_t bleio_characteristic_write_wo_resp_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_characteristic_get_write_wo_resp_obj,
+ (mp_obj_t)&bleio_characteristic_set_write_wo_resp_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t bleio_characteristic_get_uuid(mp_obj_t self_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return MP_OBJ_FROM_PTR(self->uuid);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_uuid_obj, bleio_characteristic_get_uuid);
+
+const mp_obj_property_t bleio_characteristic_uuid_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_characteristic_get_uuid_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t bleio_characteristic_get_value(mp_obj_t self_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ common_hal_bleio_characteristic_read_value(self);
+
+ return self->value_data;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_value_obj, bleio_characteristic_get_value);
+
+STATIC mp_obj_t bleio_characteristic_set_value(mp_obj_t self_in, mp_obj_t value_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(value_in, &bufinfo, MP_BUFFER_READ);
+
+ common_hal_bleio_characteristic_write_value(self, &bufinfo);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_value_obj, bleio_characteristic_set_value);
+
+const mp_obj_property_t bleio_characteristic_value_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_characteristic_get_value_obj,
+ (mp_obj_t)&bleio_characteristic_set_value_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC const mp_rom_map_elem_t bleio_characteristic_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_broadcast), MP_ROM_PTR(&bleio_characteristic_broadcast_obj) },
+ { MP_ROM_QSTR(MP_QSTR_indicate), MP_ROM_PTR(&bleio_characteristic_indicate_obj) },
+ { MP_ROM_QSTR(MP_QSTR_notify), MP_ROM_PTR(&bleio_characteristic_notify_obj) },
+ { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&bleio_characteristic_read_obj) },
+ { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_characteristic_uuid_obj) },
+ { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&bleio_characteristic_value_obj) },
+ { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&bleio_characteristic_write_obj) },
+ { MP_ROM_QSTR(MP_QSTR_write_wo_resp), MP_ROM_PTR(&bleio_characteristic_write_wo_resp_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(bleio_characteristic_locals_dict, bleio_characteristic_locals_dict_table);
+
+const mp_obj_type_t bleio_characteristic_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Characteristic,
+ .print = bleio_characteristic_print,
+ .make_new = bleio_characteristic_make_new,
+ .locals_dict = (mp_obj_dict_t*)&bleio_characteristic_locals_dict
+};
diff --git a/shared-bindings/bleio/Characteristic.h b/shared-bindings/bleio/Characteristic.h
new file mode 100644
index 000000000..0e99e97cc
--- /dev/null
+++ b/shared-bindings/bleio/Characteristic.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H
+
+#include "shared-module/bleio/Characteristic.h"
+
+extern const mp_obj_type_t bleio_characteristic_type;
+
+extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self);
+extern void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self);
+extern void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H
diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c
new file mode 100644
index 000000000..df32a00e7
--- /dev/null
+++ b/shared-bindings/bleio/Descriptor.c
@@ -0,0 +1,171 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "shared-bindings/bleio/Descriptor.h"
+#include "shared-bindings/bleio/UUID.h"
+
+enum {
+ DescriptorUuidCharacteristicExtendedProperties = 0x2900,
+ DescriptorUuidCharacteristicUserDescription = 0x2901,
+ DescriptorUuidClientCharacteristicConfiguration = 0x2902,
+ DescriptorUuidServerCharacteristicConfiguration = 0x2903,
+ DescriptorUuidCharacteristicPresentationFormat = 0x2904,
+ DescriptorUuidCharacteristicAggregateFormat = 0x2905,
+ DescriptorUuidValidRange = 0x2906,
+ DescriptorUuidExternalReportReference = 0x2907,
+ DescriptorUuidReportReference = 0x2908,
+ DescriptorUuidNumberOfDigitals = 0x2909,
+ DescriptorUuidValueTriggerSetting = 0x290A,
+ DescriptorUuidEnvironmentalSensingConfiguration = 0x290B,
+ DescriptorUuidEnvironmentalSensingMeasurement = 0x290C,
+ DescriptorUuidEnvironmentalSensingTriggerSetting = 0x290D,
+ DescriptorUuidTimeTriggerSetting = 0x290E,
+};
+
+//| .. currentmodule:: bleio
+//|
+//| :class:`Descriptor` -- BLE descriptor
+//| =========================================================
+//|
+//| Stores information about a BLE descriptor.
+//| Descriptors are encapsulated by BLE characteristics and provide contextual
+//| information about the characteristic.
+//|
+
+//| .. class:: Descriptor(uuid)
+//|
+//| Create a new descriptor object with the UUID uuid.
+//| The value can be either of type `bleio.UUID` or any value allowed by the `bleio.UUID` constructor.
+
+//| .. attribute:: handle
+//|
+//| The descriptor handle. (read-only)
+//|
+
+//| .. attribute:: uuid
+//|
+//| The descriptor uuid. (read-only)
+//|
+STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
+ mp_arg_check_num(n_args, n_kw, 0, 1, true);
+ bleio_descriptor_obj_t *self = m_new_obj(bleio_descriptor_obj_t);
+ self->base.type = type;
+
+ mp_map_t kw_args;
+ mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
+
+ enum { ARG_uuid };
+ static const mp_arg_t allowed_args[] = {
+ { ARG_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ const mp_obj_t uuid_arg = args[ARG_uuid].u_obj;
+
+ bleio_uuid_obj_t *uuid;
+ if (MP_OBJ_IS_TYPE(uuid_arg, &bleio_uuid_type)) {
+ uuid = MP_OBJ_TO_PTR(uuid_arg);
+ } else {
+ uuid = MP_OBJ_TO_PTR(bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &uuid_arg));
+ }
+
+ common_hal_bleio_descriptor_construct(self, uuid);
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+STATIC void bleio_descriptor_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ common_hal_bleio_descriptor_print(self, print);
+}
+
+STATIC mp_obj_t bleio_descriptor_get_handle(mp_obj_t self_in) {
+ bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_int(common_hal_bleio_descriptor_get_handle(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_handle_obj, bleio_descriptor_get_handle);
+
+const mp_obj_property_t bleio_descriptor_handle_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&bleio_descriptor_get_handle_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+STATIC mp_obj_t bleio_descriptor_get_uuid(mp_obj_t self_in) {
+ bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ const mp_obj_t uuid = mp_obj_new_int(common_hal_bleio_descriptor_get_uuid(self));
+
+ return bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &uuid);
+}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_uuid_obj, bleio_descriptor_get_uuid);
+
+const mp_obj_property_t bleio_descriptor_uuid_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&bleio_descriptor_get_uuid_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+STATIC const mp_rom_map_elem_t bleio_descriptor_locals_dict_table[] = {
+ // Properties
+ { MP_ROM_QSTR(MP_QSTR_handle), MP_ROM_PTR(&bleio_descriptor_handle_obj) },
+ { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_descriptor_uuid_obj) },
+
+ // Static variables
+ { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_EXTENDED_PROPERTIES), MP_ROM_INT(DescriptorUuidCharacteristicExtendedProperties) },
+ { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_USER_DESCRIPTION), MP_ROM_INT(DescriptorUuidCharacteristicUserDescription) },
+ { MP_ROM_QSTR(MP_QSTR_CLIENT_CHARACTERISTIC_CONFIGURATION), MP_ROM_INT(DescriptorUuidClientCharacteristicConfiguration) },
+ { MP_ROM_QSTR(MP_QSTR_SERVER_CHARACTERISTIC_CONFIGURATION), MP_ROM_INT(DescriptorUuidServerCharacteristicConfiguration) },
+ { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_PRESENTATION_FORMAT), MP_ROM_INT(DescriptorUuidCharacteristicPresentationFormat) },
+ { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_AGGREGATE_FORMAT), MP_ROM_INT(DescriptorUuidCharacteristicAggregateFormat) },
+ { MP_ROM_QSTR(MP_QSTR_VALID_RANGE), MP_ROM_INT(DescriptorUuidValidRange) },
+ { MP_ROM_QSTR(MP_QSTR_EXTERNAL_REPORT_REFERENCE), MP_ROM_INT(DescriptorUuidExternalReportReference) },
+ { MP_ROM_QSTR(MP_QSTR_REPORT_REFERENCE), MP_ROM_INT(DescriptorUuidReportReference) },
+ { MP_ROM_QSTR(MP_QSTR_NUMBER_OF_DIGITALS), MP_ROM_INT(DescriptorUuidNumberOfDigitals) },
+ { MP_ROM_QSTR(MP_QSTR_VALUE_TRIGGER_SETTING), MP_ROM_INT(DescriptorUuidValueTriggerSetting) },
+ { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_CONFIGURATION), MP_ROM_INT(DescriptorUuidEnvironmentalSensingConfiguration) },
+ { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_MEASUREMENT ), MP_ROM_INT(DescriptorUuidEnvironmentalSensingMeasurement) },
+ { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_TRIGGER_SETTING), MP_ROM_INT(DescriptorUuidEnvironmentalSensingTriggerSetting) },
+ { MP_ROM_QSTR(MP_QSTR_TIME_TRIGGER_SETTING), MP_ROM_INT(DescriptorUuidTimeTriggerSetting) }
+};
+
+STATIC MP_DEFINE_CONST_DICT(bleio_descriptor_locals_dict, bleio_descriptor_locals_dict_table);
+
+const mp_obj_type_t bleio_descriptor_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Descriptor,
+ .print = bleio_descriptor_print,
+ .make_new = bleio_descriptor_make_new,
+ .locals_dict = (mp_obj_dict_t*)&bleio_descriptor_locals_dict
+};
diff --git a/shared-bindings/bleio/Descriptor.h b/shared-bindings/bleio/Descriptor.h
new file mode 100644
index 000000000..85310d304
--- /dev/null
+++ b/shared-bindings/bleio/Descriptor.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H
+
+#include "common-hal/bleio/Descriptor.h"
+#include "common-hal/bleio/UUID.h"
+
+extern const mp_obj_type_t bleio_descriptor_type;
+
+extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid);
+extern void common_hal_bleio_descriptor_print(bleio_descriptor_obj_t *self, const mp_print_t *print);
+extern mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self);
+extern mp_int_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H
diff --git a/shared-bindings/bleio/Device.c b/shared-bindings/bleio/Device.c
new file mode 100644
index 000000000..94834ef7c
--- /dev/null
+++ b/shared-bindings/bleio/Device.c
@@ -0,0 +1,357 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+
+#include "ble_drv.h"
+#include "py/objarray.h"
+#include "py/objproperty.h"
+#include "py/objstr.h"
+#include "py/runtime.h"
+#include "shared-bindings/bleio/Adapter.h"
+#include "shared-bindings/bleio/AddressType.h"
+#include "shared-bindings/bleio/Characteristic.h"
+#include "shared-bindings/bleio/Device.h"
+#include "shared-bindings/bleio/Service.h"
+#include "shared-bindings/bleio/UUID.h"
+#include "shared-module/bleio/AdvertisementData.h"
+#include "shared-module/bleio/Device.h"
+#include "shared-module/bleio/ScanEntry.h"
+
+//| .. currentmodule:: bleio
+//|
+//| :class:`Device` -- BLE device
+//| =========================================================
+//|
+//| Provides access a to BLE device, either in a Peripheral or Central role.
+//| When a device is created without any parameter passed to the constructor,
+//| it will be set to the Peripheral role. If a address is passed, the device
+//| will be a Central. For a Peripheral you can set the `name`, add services
+//| via `add_service` and then start and stop advertising via `start_advertising`
+//| and `stop_advertising`. For the Central, you can `bleio.Device.connect` and `bleio.Device.disconnect`
+//| to the device, once a connection is established, the device's services can
+//| be accessed using `services`.
+//|
+//| Usage::
+//|
+//| import bleio
+//|
+//| # Peripheral
+//| periph = bleio.Device()
+//|
+//| serv = bleio.Service(bleio.UUID(0x180f))
+//| p.add_service(serv)
+//|
+//| chara = bleio.Characteristic(bleio.UUID(0x2919))
+//| chara.read = True
+//| chara.notify = True
+//| serv.add_characteristic(chara)
+//|
+//| periph.start_advertising()
+//|
+//| # Central
+//| scanner = bleio.Scanner()
+//| entries = scanner.scan(2500)
+//|
+//| my_entry = None
+//| for entry in entries:
+//| if entry.name is not None and entry.name == 'MyDevice':
+//| my_entry = entry
+//| break
+//|
+//| central = bleio.Device(my_entry.address)
+//| central.connect()
+//|
+
+//| .. class:: Device(address=None, scan_entry=None)
+//|
+//| Create a new Device object. If the `address` or :py:data:`scan_entry` parameters are not `None`,
+//| the role is set to Central, otherwise it's set to Peripheral.
+//|
+//| :param bleio.Address address: The address of the device to connect to
+//| :param bleio.ScanEntry scan_entry: The scan entry returned from `bleio.Scanner`
+//|
+
+//| .. attribute:: name
+//|
+//| For the Peripheral role, this property can be used to read and write the device's name.
+//| For the Central role, this property will equal the name of the remote device, if one was
+//| advertised by the device. In the Central role this property is read-only.
+//|
+
+//| .. attribute:: services
+//|
+//| A `list` of `bleio.Service` that are offered by this device. (read-only)
+//| For a Peripheral device, this list will contain services added using `add_service`,
+//| for a Central, this list will be empty until a connection is established, at which point
+//| it will be filled with the remote device's services.
+//|
+
+//| .. method:: add_service(service)
+//|
+//| Appends the :py:data:`service` to the list of this devices's services.
+//| This method can only be called for Peripheral devices.
+//|
+//| :param bleio.Service service: the service to append
+//|
+
+//| .. method:: connect()
+//|
+//| Attempts a connection to the remote device. If the connection is successful,
+//| the device's services are available via `services`.
+//| This method can only be called for Central devices.
+//|
+
+//| .. method:: disconnect()
+//|
+//| Disconnects from the remote device.
+//| This method can only be called for Central devices.
+//|
+
+//| .. method:: start_advertising(connectable=True)
+//|
+//| Starts advertising the device. The device's name and
+//| services are put into the advertisement packets.
+//| If :py:data:`connectable` is `True` then other devices are allowed to conncet to this device.
+//| This method can only be called for Peripheral devices.
+//|
+
+//| .. method:: stop_advertising()
+//|
+//| Disconnects from the remote device.
+//| This method can only be called for Peripheral devices.
+//|
+
+// TODO: Add unique MAC address part to name
+static const char default_name[] = "CIRCUITPY";
+
+STATIC void bleio_device_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ mp_printf(print, "Device(role: %s)", self->is_peripheral ? "Peripheral" : "Central");
+}
+
+STATIC mp_obj_t bleio_device_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
+ mp_arg_check_num(n_args, n_kw, 0, 1, true);
+ bleio_device_obj_t *self = m_new_obj(bleio_device_obj_t);
+ self->base.type = &bleio_device_type;
+ self->service_list = mp_obj_new_list(0, NULL);
+ self->notif_handler = mp_const_none;
+ self->conn_handler = mp_const_none;
+ self->conn_handle = 0xFFFF;
+ self->is_peripheral = true;
+
+ mp_map_t kw_args;
+ mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
+
+ enum { ARG_address, ARG_scan_entry };
+ static const mp_arg_t allowed_args[] = {
+ { ARG_address, MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_scan_entry, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ const mp_obj_t address_obj = args[ARG_address].u_obj;
+ const mp_obj_t scan_entry_obj = args[ARG_scan_entry].u_obj;
+
+ if (address_obj != mp_const_none) {
+ bleio_address_obj_t *address = MP_OBJ_TO_PTR(address_obj);
+
+ self->is_peripheral = false;
+ self->address.type = address->type;
+ memcpy(self->address.value, address->value, BLEIO_ADDRESS_BYTES);
+ } else if (scan_entry_obj != mp_const_none) {
+ bleio_scanentry_obj_t *scan_entry = MP_OBJ_TO_PTR(scan_entry_obj);
+
+ self->is_peripheral = false;
+ self->address.type = scan_entry->address.type;
+ memcpy(self->address.value, scan_entry->address.value, BLEIO_ADDRESS_BYTES);
+ } else {
+ self->name = mp_obj_new_str(default_name, strlen(default_name));
+ common_hal_bleio_adapter_get_address(&self->address);
+ }
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+STATIC mp_obj_t bleio_device_add_service(mp_obj_t self_in, mp_obj_t service_in) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_in);
+
+ if (!self->is_peripheral) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
+ translate("Can't add services in Central mode")));
+ }
+
+ service->device = self;
+
+ mp_obj_list_append(self->service_list, service);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_device_add_service_obj, bleio_device_add_service);
+
+STATIC mp_obj_t bleio_device_connect(mp_obj_t self_in) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ if (self->is_peripheral) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
+ translate("Can't connect in Peripheral mode")));
+ }
+
+ common_hal_bleio_device_connect(self);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_connect_obj, bleio_device_connect);
+
+STATIC mp_obj_t bleio_device_disconnect(mp_obj_t self_in) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ common_hal_bleio_device_disconnect(self);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_disconnect_obj, bleio_device_disconnect);
+
+STATIC mp_obj_t bleio_device_get_name(mp_obj_t self_in) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return self->name;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_get_name_obj, bleio_device_get_name);
+
+static mp_obj_t bleio_device_set_name(mp_obj_t self_in, mp_obj_t value) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ if (!self->is_peripheral) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
+ translate("Can't change the name in Central mode")));
+ }
+
+ self->name = value;
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_device_set_name_obj, bleio_device_set_name);
+
+const mp_obj_property_t bleio_device_name_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_device_get_name_obj,
+ (mp_obj_t)&bleio_device_set_name_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t bleio_device_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ if (!self->is_peripheral) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
+ translate("Can't advertise in Central mode")));
+ }
+
+ enum { ARG_connectable, ARG_data };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
+ { MP_QSTR_data, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ };
+
+ 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(allowed_args), allowed_args, args);
+
+ mp_buffer_info_t bufinfo = { 0 };
+ if (args[ARG_data].u_obj != mp_const_none) {
+ mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ);
+ }
+
+ const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list);
+ for (size_t i = 0; i < service_list->len; ++i) {
+ bleio_service_obj_t *service = service_list->items[i];
+ if (service->handle == 0xFFFF) {
+ common_hal_bleio_device_add_service(self, service);
+ }
+ }
+
+ common_hal_bleio_device_start_advertising(self, args[ARG_connectable].u_bool, &bufinfo);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_device_start_advertising_obj, 0, bleio_device_start_advertising);
+
+STATIC mp_obj_t bleio_device_stop_advertising(mp_obj_t self_in) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ if (!self->is_peripheral) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
+ translate("Can't advertise in Central mode")));
+ }
+
+ common_hal_bleio_device_stop_advertising(self);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_stop_advertising_obj, bleio_device_stop_advertising);
+
+STATIC mp_obj_t bleio_device_get_services(mp_obj_t self_in) {
+ bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return self->service_list;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_get_services_obj, bleio_device_get_services);
+
+const mp_obj_property_t bleio_device_services_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_device_get_services_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC const mp_rom_map_elem_t bleio_device_locals_dict_table[] = {
+ // Methods
+ { MP_ROM_QSTR(MP_QSTR_add_service), MP_ROM_PTR(&bleio_device_add_service_obj) },
+ { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_device_connect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_device_disconnect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_device_start_advertising_obj) },
+ { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_device_stop_advertising_obj) },
+
+ // Properties
+ { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_device_name_obj) },
+ { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_device_services_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(bleio_device_locals_dict, bleio_device_locals_dict_table);
+
+const mp_obj_type_t bleio_device_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Device,
+ .print = bleio_device_print,
+ .make_new = bleio_device_make_new,
+ .locals_dict = (mp_obj_dict_t*)&bleio_device_locals_dict
+};
diff --git a/shared-bindings/bleio/Device.h b/shared-bindings/bleio/Device.h
new file mode 100644
index 000000000..aebf1d639
--- /dev/null
+++ b/shared-bindings/bleio/Device.h
@@ -0,0 +1,42 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H
+
+#include "shared-module/bleio/AdvertisementData.h"
+#include "shared-module/bleio/Device.h"
+#include "shared-module/bleio/Service.h"
+
+extern const mp_obj_type_t bleio_device_type;
+
+extern void common_hal_bleio_device_add_service(bleio_device_obj_t *device, bleio_service_obj_t *service);
+extern void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bool connectable, mp_buffer_info_t *raw_data);
+extern void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device);
+extern void common_hal_bleio_device_connect(bleio_device_obj_t *device);
+extern void common_hal_bleio_device_disconnect(bleio_device_obj_t *device);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H
diff --git a/shared-bindings/bleio/ScanEntry.c b/shared-bindings/bleio/ScanEntry.c
new file mode 100644
index 000000000..e452c7267
--- /dev/null
+++ b/shared-bindings/bleio/ScanEntry.c
@@ -0,0 +1,308 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+
+#include "py/objarray.h"
+#include "py/objproperty.h"
+#include "py/objstr.h"
+#include "py/objtuple.h"
+#include "shared-bindings/bleio/Address.h"
+#include "shared-bindings/bleio/ScanEntry.h"
+#include "shared-bindings/bleio/UUID.h"
+#include "shared-module/bleio/AdvertisementData.h"
+#include "shared-module/bleio/ScanEntry.h"
+
+//| .. currentmodule:: bleio
+//|
+//| :class:`ScanEntry` -- BLE scan response entry
+//| =========================================================
+//|
+//| Encapsulates information about a device that was received as a
+//| response to a BLE scan request.
+//|
+
+//| .. attribute:: address
+//|
+//| The address of the device. (read-only)
+//| This attribute is of type `bleio.Address`.
+//|
+
+//| .. attribute:: manufacturer_specific_data
+//|
+//| The manufacturer-specific data present in the advertisement packet. (read-only)
+//|
+
+//| .. attribute:: name
+//|
+//| The name of the device. (read-only)
+//| This attribute might be `None` if the data was missing from the advertisement packet.
+//|
+
+//| .. attribute:: raw_data
+//|
+//| All the advertisement data present in the packet. (read-only)
+//|
+
+//| .. attribute:: rssi
+//|
+//| The signal strength of the device at the time of the scan. (read-only)
+//|
+
+//| .. attribute:: service_uuids
+//|
+//| The address of the device. (read-only)
+//| This attribute is a list of `bleio.UUID`.
+//| This attribute might be empty or incomplete, depending on the advertisement packet.
+//| Currently only 16-bit UUIDS are listed.
+//|
+
+//| .. attribute:: tx_power_level
+//|
+//| The transmit power level of the device. (read-only)
+//| This attribute might be `None` if the data was missing from the advertisement packet.
+//|
+static uint8_t find_data_item(mp_obj_array_t *data_in, uint8_t type, uint8_t **data_out) {
+ uint16_t i = 0;
+ while (i < data_in->len) {
+ const uint8_t item_len = ((uint8_t*)data_in->items)[i];
+ const uint8_t item_type = ((uint8_t*)data_in->items)[i + 1];
+ if (item_type != type) {
+ i += (item_len + 1);
+ continue;
+ }
+
+ *data_out = &((uint8_t*)data_in->items)[i + 2];
+
+ return item_len;
+ }
+
+ return 0;
+}
+
+STATIC mp_obj_t scanentry_get_name(mp_obj_t self_in);
+
+STATIC void bleio_scanentry_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_scanentry_obj_t *self = (bleio_scanentry_obj_t *)self_in;
+ mp_printf(print, "ScanEntry(address: "HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT"",
+ self->address.value[5], self->address.value[4], self->address.value[3],
+ self->address.value[1], self->address.value[1], self->address.value[0]);
+
+ const mp_obj_t name_obj = scanentry_get_name(self_in);
+ if (name_obj != mp_const_none) {
+ mp_obj_str_t *str = MP_OBJ_TO_PTR(name_obj);
+ mp_printf(print, " name: %s", str->data);
+ }
+
+ mp_print_str(print, ")");
+}
+
+STATIC mp_obj_t bleio_scanentry_get_address(mp_obj_t self_in) {
+ bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ mp_obj_t obj = bleio_address_type.make_new(&bleio_address_type, 1, 0, (mp_obj_t)&mp_const_none_obj);
+ bleio_address_obj_t *address = MP_OBJ_TO_PTR(obj);
+
+ address->type = self->address.type;
+ memcpy(address->value, self->address.value, BLEIO_ADDRESS_BYTES);
+
+ return obj;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_address_obj, bleio_scanentry_get_address);
+
+const mp_obj_property_t bleio_scanentry_address_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bluepy_scanentry_get_address_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t scanentry_get_manufacturer_specific_data(mp_obj_t self_in) {
+ bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data);
+ uint8_t *manuf_data;
+
+ const uint8_t manuf_data_len = find_data_item(data, AdManufacturerSpecificData, &manuf_data);
+ if (manuf_data_len == 0) {
+ return mp_const_none;
+ }
+
+ return mp_obj_new_bytearray_by_ref(manuf_data_len, manuf_data);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_manufacturer_specific_data_obj, scanentry_get_manufacturer_specific_data);
+
+const mp_obj_property_t bleio_scanentry_manufacturer_specific_data_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&scanentry_get_manufacturer_specific_data_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t scanentry_get_name(mp_obj_t self_in) {
+ bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data);
+ uint8_t *name;
+
+ // Try for Complete but settle for Shortened
+ uint8_t name_len = find_data_item(data, AdCompleteLocalName, &name);
+ if (name_len == 0) {
+ name_len = find_data_item(data, AdShortenedLocalName, &name);
+ }
+
+ if (name_len == 0) {
+ return mp_const_none;
+ }
+
+ return mp_obj_new_str((const char*)name, name_len - 1);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_name_obj, scanentry_get_name);
+
+const mp_obj_property_t bleio_scanentry_name_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bluepy_scanentry_get_name_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t scanentry_get_raw_data(mp_obj_t self_in) {
+ bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ mp_obj_t entries = mp_obj_new_list(0, NULL);
+
+ mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data);
+
+ uint16_t i = 0;
+ while (i < data->len) {
+ mp_obj_tuple_t *entry = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
+
+ const uint8_t item_len = ((uint8_t*)data->items)[i];
+ const uint8_t item_type = ((uint8_t*)data->items)[i + 1];
+
+ entry->items[0] = MP_OBJ_NEW_SMALL_INT(item_type);
+ entry->items[1] = mp_obj_new_bytearray(item_len - 1, &((uint8_t*)data->items)[i + 2]);
+ mp_obj_list_append(entries, MP_OBJ_FROM_PTR(entry));
+
+ i += (item_len + 1);
+ }
+
+ return entries;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_raw_data_obj, scanentry_get_raw_data);
+
+const mp_obj_property_t bleio_scanentry_raw_data_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_scanentry_get_raw_data_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t scanentry_get_rssi(mp_obj_t self_in) {
+ bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_int(self->rssi);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_rssi_obj, scanentry_get_rssi);
+
+const mp_obj_property_t bleio_scanentry_rssi_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bluepy_scanentry_get_rssi_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t scanentry_get_service_uuids(mp_obj_t self_in) {
+ bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data);
+ uint8_t *uuids;
+
+ // Try for Complete but settle for Incomplete
+ uint8_t uuids_len = find_data_item(data, AdCompleteListOf16BitServiceClassUUIDs, &uuids);
+ if (uuids_len == 0) {
+ uuids_len = find_data_item(data, AdIncompleteListOf16BitServiceClassUUIDs, &uuids);
+ }
+
+ mp_obj_t entries = mp_obj_new_list(0, NULL);
+ for (size_t i = 0; i < uuids_len / sizeof(uint16_t); ++i) {
+ const mp_obj_t uuid_int = mp_obj_new_int(uuids[sizeof(uint16_t) * i] | (uuids[sizeof(uint16_t) * i + 1] << 8));
+ const mp_obj_t uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &uuid_int);
+
+ mp_obj_list_append(entries, uuid_obj);
+ }
+
+ // TODO: 32-bit UUIDs
+ // TODO: 128-bit UUIDs
+
+ return entries;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_service_uuids_obj, scanentry_get_service_uuids);
+
+const mp_obj_property_t bleio_scanentry_service_uuids_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&scanentry_get_service_uuids_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t scanentry_get_tx_power_level(mp_obj_t self_in) {
+ bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data);
+ uint8_t *tx_power;
+
+ const uint8_t tx_power_len = find_data_item(data, AdTxPowerLevel, &tx_power);
+ if (tx_power_len == 0) {
+ return mp_const_none;
+ }
+
+ return mp_obj_new_int((int8_t)(*tx_power));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_tx_power_level_obj, scanentry_get_tx_power_level);
+
+const mp_obj_property_t bleio_scanentry_tx_power_level_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&scanentry_get_tx_power_level_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC const mp_rom_map_elem_t bleio_scanentry_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_scanentry_address_obj) },
+ { MP_ROM_QSTR(MP_QSTR_manufacturer_specific_data), MP_ROM_PTR(&bleio_scanentry_manufacturer_specific_data_obj) },
+ { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_scanentry_name_obj) },
+ { MP_ROM_QSTR(MP_QSTR_raw_data), MP_ROM_PTR(&bleio_scanentry_raw_data_obj) },
+ { MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&bleio_scanentry_rssi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_service_uuids), MP_ROM_PTR(&bleio_scanentry_service_uuids_obj) },
+ { MP_ROM_QSTR(MP_QSTR_tx_power_level), MP_ROM_PTR(&bleio_scanentry_tx_power_level_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(bleio_scanentry_locals_dict, bleio_scanentry_locals_dict_table);
+
+const mp_obj_type_t bleio_scanentry_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_ScanEntry,
+ .print = bleio_scanentry_print,
+ .locals_dict = (mp_obj_dict_t*)&bleio_scanentry_locals_dict
+};
diff --git a/shared-bindings/bleio/ScanEntry.h b/shared-bindings/bleio/ScanEntry.h
new file mode 100644
index 000000000..2b44ba3f4
--- /dev/null
+++ b/shared-bindings/bleio/ScanEntry.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H
+
+#include "py/obj.h"
+
+extern const mp_obj_type_t bleio_scanentry_type;
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H
diff --git a/shared-bindings/bleio/Scanner.c b/shared-bindings/bleio/Scanner.c
new file mode 100644
index 000000000..5d19778f6
--- /dev/null
+++ b/shared-bindings/bleio/Scanner.c
@@ -0,0 +1,162 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/objproperty.h"
+#include "shared-bindings/bleio/ScanEntry.h"
+#include "shared-bindings/bleio/Scanner.h"
+
+#define DEFAULT_INTERVAL 100
+#define DEFAULT_WINDOW 100
+
+//| .. currentmodule:: bleio
+//|
+//| :class:`Scanner` -- scan for nearby BLE devices
+//| =========================================================
+//|
+//| Allows scanning for nearby BLE devices.
+//|
+//| Usage::
+//|
+//| import bleio
+//| scanner = bleio.Scanner()
+//| entries = scanner.scan(2500)
+//| print(entries)
+//|
+
+//| .. class:: Scanner()
+//|
+//| Create a new Scanner object.
+//|
+
+//| .. attribute:: interval
+//|
+//| The interval (in ms) between the start of two consecutive scan windows.
+//| Allowed values are between 10ms and 10.24 sec.
+//|
+
+//| .. attribute:: window
+//|
+//| The duration (in ms) in which a single BLE channel is scanned.
+//| Allowed values are between 10ms and 10.24 sec.
+//|
+
+//| .. method:: scan(timeout)
+//|
+//| Performs a BLE scan.
+//|
+//| :param int timeout: the scan timeout in ms
+//| :returns: advertising packets found
+//| :rtype: list of :py:class:`bleio.ScanEntry`
+//|
+STATIC void bleio_scanner_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ mp_printf(print, "Scanner(interval: %d window: %d)", self->interval, self->window);
+}
+
+STATIC mp_obj_t bleio_scanner_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
+ bleio_scanner_obj_t *self = m_new_obj(bleio_scanner_obj_t);
+ self->base.type = type;
+
+ self->interval = DEFAULT_INTERVAL;
+ self->window = DEFAULT_WINDOW;
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+STATIC mp_obj_t bleio_scanner_get_interval(mp_obj_t self_in) {
+ bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_int(self->interval);
+}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanner_get_interval_obj, bleio_scanner_get_interval);
+
+static mp_obj_t bleio_scanner_set_interval(mp_obj_t self_in, mp_obj_t value) {
+ bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ self->interval = mp_obj_get_int(value);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_scanner_set_interval_obj, bleio_scanner_set_interval);
+
+const mp_obj_property_t bleio_scanner_interval_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_scanner_get_interval_obj,
+ (mp_obj_t)&bleio_scanner_set_interval_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t scanner_scan(mp_obj_t self_in, mp_obj_t timeout_in) {
+ bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ const mp_int_t timeout = mp_obj_get_int(timeout_in);
+
+ self->adv_reports = mp_obj_new_list(0, NULL);
+
+ common_hal_bleio_scanner_scan(self, timeout);
+
+ return self->adv_reports;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_scanner_scan_obj, scanner_scan);
+
+STATIC mp_obj_t bleio_scanner_get_window(mp_obj_t self_in) {
+ bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_int(self->window);
+}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanner_get_window_obj, bleio_scanner_get_window);
+
+static mp_obj_t bleio_scanner_set_window(mp_obj_t self_in, mp_obj_t value) {
+ bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ self->window = mp_obj_get_int(value);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_scanner_set_window_obj, bleio_scanner_set_window);
+
+const mp_obj_property_t bleio_scanner_window_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_scanner_get_window_obj,
+ (mp_obj_t)&bleio_scanner_set_window_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC const mp_rom_map_elem_t bleio_scanner_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_interval), MP_ROM_PTR(&bleio_scanner_interval_obj) },
+ { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&bleio_scanner_scan_obj) },
+ { MP_ROM_QSTR(MP_QSTR_window), MP_ROM_PTR(&bleio_scanner_window_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(bleio_scanner_locals_dict, bleio_scanner_locals_dict_table);
+
+const mp_obj_type_t bleio_scanner_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Scanner,
+ .print = bleio_scanner_print,
+ .make_new = bleio_scanner_make_new,
+ .locals_dict = (mp_obj_dict_t*)&bleio_scanner_locals_dict
+};
diff --git a/shared-bindings/bleio/Scanner.h b/shared-bindings/bleio/Scanner.h
new file mode 100644
index 000000000..9bd071747
--- /dev/null
+++ b/shared-bindings/bleio/Scanner.h
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H
+
+#include "py/objtype.h"
+#include "shared-module/bleio/Scanner.h"
+
+extern const mp_obj_type_t bleio_scanner_type;
+
+extern void common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_int_t timeout);
+extern void common_hal_bleio_scanner_stop(bleio_scanner_obj_t *self);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H
diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c
new file mode 100644
index 000000000..2d09cbc3c
--- /dev/null
+++ b/shared-bindings/bleio/Service.c
@@ -0,0 +1,170 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "shared-bindings/bleio/Service.h"
+#include "shared-bindings/bleio/UUID.h"
+
+//| .. currentmodule:: bleio
+//|
+//| :class:`Service` -- BLE service
+//| =========================================================
+//|
+//| Stores information about a BLE service and its characteristics.
+//|
+
+//| .. class:: Service(uuid, secondary=False)
+//|
+//| Create a new Service object identified by the specified UUID.
+//| To mark the service as secondary, pass `True` as :py:data:`secondary`.
+//|
+//| :param bleio.UUID uuid: The uuid of the service
+//| :param bool secondary: If the service is a secondary one
+//|
+
+//| .. method:: add_characteristic(characteristic)
+//|
+//| Appends the :py:data:`characteristic` to the list of this service's characteristics.
+//|
+//| :param bleio.Characteristic characteristic: the characteristic to append
+//|
+
+//| .. attribute:: characteristics
+//|
+//| A `list` of `bleio.Characteristic` that are offered by this service. (read-only)
+//|
+
+//| .. attribute:: uuid
+//|
+//| The UUID of this service. (read-only)
+//|
+STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ mp_printf(print, "Service(uuid: 0x"HEX2_FMT""HEX2_FMT")",
+ self->uuid->value[1], self->uuid->value[0]);
+}
+
+STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
+ mp_arg_check_num(n_args, n_kw, 1, 1, true);
+ bleio_service_obj_t *self = m_new_obj(bleio_service_obj_t);
+ self->base.type = &bleio_service_type;
+ self->device = NULL;
+ self->char_list = mp_obj_new_list(0, NULL);
+ self->handle = 0xFFFF;
+
+ mp_map_t kw_args;
+ mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
+
+ enum { ARG_uuid, ARG_secondary };
+ static const mp_arg_t allowed_args[] = {
+ { ARG_uuid, MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_secondary, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ self->is_secondary = args[ARG_secondary].u_bool;
+
+ const mp_obj_t uuid = args[ARG_uuid].u_obj;
+
+ if (uuid == mp_const_none) {
+ return MP_OBJ_FROM_PTR(self);
+ }
+
+ if (MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) {
+ self->uuid = MP_OBJ_TO_PTR(uuid);
+ } else {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
+ translate("Invalid UUID parameter")));
+ }
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+STATIC mp_obj_t bleio_service_add_characteristic(mp_obj_t self_in, mp_obj_t characteristic_in) {
+ bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(characteristic_in);
+
+ if (self->uuid->type == UUID_TYPE_128BIT) {
+ characteristic->uuid->type = UUID_TYPE_128BIT;
+ characteristic->uuid->uuid_vs_idx = self->uuid->uuid_vs_idx;
+ }
+
+ characteristic->service = self;
+
+ mp_obj_list_append(self->char_list, characteristic);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_service_add_characteristic_obj, bleio_service_add_characteristic);
+
+STATIC mp_obj_t bleio_service_get_characteristics(mp_obj_t self_in) {
+ bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return self->char_list;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_characteristics_obj, bleio_service_get_characteristics);
+
+const mp_obj_property_t bleio_service_characteristics_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_service_get_characteristics_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC mp_obj_t bleio_service_get_uuid(mp_obj_t self_in) {
+ bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return MP_OBJ_FROM_PTR(self->uuid);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_uuid_obj, bleio_service_get_uuid);
+
+const mp_obj_property_t bleio_service_uuid_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_service_get_uuid_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC const mp_rom_map_elem_t bleio_service_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_add_characteristic), MP_ROM_PTR(&bleio_service_add_characteristic_obj) },
+ { MP_ROM_QSTR(MP_QSTR_characteristics), MP_ROM_PTR(&bleio_service_characteristics_obj) },
+ { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_service_uuid_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(bleio_service_locals_dict, bleio_service_locals_dict_table);
+
+const mp_obj_type_t bleio_service_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Service,
+ .print = bleio_service_print,
+ .make_new = bleio_service_make_new,
+ .locals_dict = (mp_obj_dict_t*)&bleio_service_locals_dict
+};
diff --git a/shared-bindings/bleio/Service.h b/shared-bindings/bleio/Service.h
new file mode 100644
index 000000000..77c751829
--- /dev/null
+++ b/shared-bindings/bleio/Service.h
@@ -0,0 +1,37 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
+
+#include "shared-module/bleio/Characteristic.h"
+#include "shared-module/bleio/Service.h"
+
+const mp_obj_type_t bleio_service_type;
+
+extern void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c
new file mode 100644
index 000000000..7cef9a26f
--- /dev/null
+++ b/shared-bindings/bleio/UUID.c
@@ -0,0 +1,146 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Glenn Ruben Bakke
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "shared-bindings/bleio/UUID.h"
+
+//| .. currentmodule:: bleio
+//|
+//| :class:`UUID` -- BLE UUID
+//| =========================================================
+//|
+//| Encapsulates both 16-bit and 128-bit UUIDs. Can be used for services,
+//| characteristics, descriptors and more.
+//|
+
+//| .. class:: UUID(uuid)
+//|
+//| Create a new UUID object encapsulating the uuid value.
+//| The value itself can be one of:
+//|
+//| - a `int` value in range of 0 to 0xFFFF
+//| - a `str` value in the format of '0xXXXX' for 16-bit or 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' for 128-bit
+//|
+//| :param int/str uuid: The uuid to encapsulate
+//|
+
+//| .. method:: __len__()
+//|
+//| Returns the uuid length in bits
+//|
+//| This allows you to:
+//|
+//| uuid = bleio.UUID(0x1801)
+//| print(len(uuid))
+//|
+
+//| .. attribute:: type
+//|
+//| The UUID type. One of:
+//|
+//| - `bleio.UUIDType.TYPE_16BIT`
+//| - `bleio.UUIDType.TYPE_128BIT`
+//|
+STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) {
+ mp_arg_check_num(n_args, n_kw, 1, 1, true);
+ bleio_uuid_obj_t *self = m_new_obj(bleio_uuid_obj_t);
+ self->base.type = &bleio_uuid_type;
+
+ mp_map_t kw_args;
+ mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args);
+
+ enum { ARG_uuid };
+ static const mp_arg_t allowed_args[] = {
+ { ARG_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ const mp_obj_t uuid = args[ARG_uuid].u_obj;
+
+ common_hal_bleio_uuid_construct(self, &uuid);
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+STATIC mp_obj_t bleio_uuid_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
+ bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ const bleio_uuid_type_t type = common_hal_bleio_uuid_get_type(self);
+ const uint8_t len = (type == UUID_TYPE_16BIT) ? 16 : 128;
+ switch (op) {
+ case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0);
+ case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len);
+ default: return MP_OBJ_NULL; // op not supported
+ }
+}
+
+STATIC void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ common_hal_bleio_uuid_print(self, print);
+}
+
+STATIC mp_obj_t bleio_uuid_get_type(mp_obj_t self_in) {
+ bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ const bleio_uuid_type_t type = common_hal_bleio_uuid_get_type(self);
+ if (type == UUID_TYPE_16BIT) {
+ return (mp_obj_t)&bleio_uuidtype_16bit_obj;
+ }
+
+ if (type == UUID_TYPE_128BIT) {
+ return (mp_obj_t)&bleio_uuidtype_128bit_obj;
+ }
+
+ return (mp_obj_t)&mp_const_none_obj;
+}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_type_obj, bleio_uuid_get_type);
+
+const mp_obj_property_t bleio_uuid_type_obj = {
+ .base.type = &mp_type_property,
+ .proxy = {(mp_obj_t)&bleio_uuid_get_type_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj},
+};
+
+STATIC const mp_rom_map_elem_t bleio_uuid_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_uuid_type_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(bleio_uuid_locals_dict, bleio_uuid_locals_dict_table);
+
+const mp_obj_type_t bleio_uuid_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_UUID,
+ .print = bleio_uuid_print,
+ .make_new = bleio_uuid_make_new,
+ .unary_op = bleio_uuid_unary_op,
+ .locals_dict = (mp_obj_dict_t*)&bleio_uuid_locals_dict
+};
diff --git a/shared-bindings/bleio/UUID.h b/shared-bindings/bleio/UUID.h
new file mode 100644
index 000000000..d6fcbac1b
--- /dev/null
+++ b/shared-bindings/bleio/UUID.h
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H
+
+#include "common-hal/bleio/UUID.h"
+#include "shared-bindings/bleio/UUIDType.h"
+
+extern const mp_obj_type_t bleio_uuid_type;
+
+extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, const mp_obj_t *uuid);
+extern void common_hal_bleio_uuid_print(bleio_uuid_obj_t *self, const mp_print_t *print);
+extern bleio_uuid_type_t common_hal_bleio_uuid_get_type(bleio_uuid_obj_t *self);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H
diff --git a/shared-bindings/bleio/UUIDType.c b/shared-bindings/bleio/UUIDType.c
new file mode 100644
index 000000000..e36d1f06d
--- /dev/null
+++ b/shared-bindings/bleio/UUIDType.c
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-bindings/bleio/UUIDType.h"
+
+//| .. currentmodule:: bleio
+//|
+//| :class:`UUIDType` -- defines the type of a BLE UUID
+//| =============================================================
+//|
+//| .. class:: bleio.UUIDType
+//|
+//| Enum-like class to define the type of a BLE UUID.
+//|
+//| .. data:: TYPE_16BIT
+//|
+//| The UUID is 16-bit
+//|
+//| .. data:: TYPE_128BIT
+//|
+//| The UUID is 128-bit
+//|
+const mp_obj_type_t bleio_uuidtype_type;
+
+const bleio_uuidtype_obj_t bleio_uuidtype_16bit_obj = {
+ { &bleio_uuidtype_type },
+};
+
+const bleio_uuidtype_obj_t bleio_uuidtype_128bit_obj = {
+ { &bleio_uuidtype_type },
+};
+
+STATIC const mp_rom_map_elem_t bleio_uuidtype_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_TYPE_16BIT), MP_ROM_PTR(&bleio_uuidtype_16bit_obj) },
+ { MP_ROM_QSTR(MP_QSTR_TYPE_128BIT), MP_ROM_PTR(&bleio_uuidtype_128bit_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(bleio_uuidtype_locals_dict, bleio_uuidtype_locals_dict_table);
+
+STATIC void bleio_uuidtype_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ qstr type = MP_QSTR_TYPE_128BIT;
+ if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_uuidtype_16bit_obj)) {
+ type = MP_QSTR_TYPE_16BIT;
+ }
+ mp_printf(print, "%q.%q.%q", MP_QSTR_bleio, MP_QSTR_UUIDType, type);
+}
+
+const mp_obj_type_t bleio_uuidtype_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_UUIDType,
+ .print = bleio_uuidtype_print,
+ .locals_dict = (mp_obj_t)&bleio_uuidtype_locals_dict,
+};
diff --git a/shared-bindings/bleio/UUIDType.h b/shared-bindings/bleio/UUIDType.h
new file mode 100644
index 000000000..87bbf9b53
--- /dev/null
+++ b/shared-bindings/bleio/UUIDType.h
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUIDTYPE_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUIDTYPE_H
+
+#include "py/obj.h"
+
+typedef enum {
+ UUID_TYPE_16BIT,
+ UUID_TYPE_128BIT
+} bleio_uuid_type_t;
+
+extern const mp_obj_type_t bleio_uuidtype_type;
+
+typedef struct {
+ mp_obj_base_t base;
+} bleio_uuidtype_obj_t;
+
+extern const bleio_uuidtype_obj_t bleio_uuidtype_16bit_obj;
+extern const bleio_uuidtype_obj_t bleio_uuidtype_128bit_obj;
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUIDTYPE_H
diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c
index 475fb395a..98099422c 100644
--- a/shared-bindings/bleio/__init__.c
+++ b/shared-bindings/bleio/__init__.c
@@ -25,8 +25,18 @@
* THE SOFTWARE.
*/
-#include "py/obj.h"
#include "shared-bindings/bleio/__init__.h"
+#include "shared-bindings/bleio/Address.h"
+#include "shared-bindings/bleio/AddressType.h"
+#include "shared-bindings/bleio/AdvertisementData.h"
+#include "shared-bindings/bleio/Characteristic.h"
+#include "shared-bindings/bleio/Descriptor.h"
+#include "shared-bindings/bleio/Device.h"
+#include "shared-bindings/bleio/ScanEntry.h"
+#include "shared-bindings/bleio/Scanner.h"
+#include "shared-bindings/bleio/Service.h"
+#include "shared-bindings/bleio/UUID.h"
+#include "shared-bindings/bleio/UUIDType.h"
//| :mod:`bleio` --- Bluetooth Low Energy functionality
//| ================================================================
@@ -42,7 +52,18 @@
//| .. toctree::
//| :maxdepth: 3
//|
+//| Address
+//| AddressType
+//| AdvertisementData
//| Adapter
+//| Characteristic
+//| Descriptor
+//| Device
+//| ScanEntry
+//| Scanner
+//| Service
+//| UUID
+//| UUIDType
//|
//| .. attribute:: adapter
//|
@@ -52,8 +73,23 @@
//|
STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = {
- { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) },
- { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) },
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) },
+ { MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) },
+ { MP_ROM_QSTR(MP_QSTR_AdvertisementData), MP_ROM_PTR(&bleio_advertisementdata_type) },
+ { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) },
+ { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) },
+ { MP_ROM_QSTR(MP_QSTR_Device), MP_ROM_PTR(&bleio_device_type) },
+ { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) },
+ { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) },
+ { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) },
+ { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) },
+
+ // Properties
+ { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) },
+
+ // Enum-like Classes.
+ { MP_ROM_QSTR(MP_QSTR_AddressType), MP_ROM_PTR(&bleio_addresstype_type) },
+ { MP_ROM_QSTR(MP_QSTR_UUIDType), MP_ROM_PTR(&bleio_uuidtype_type) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table);