summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Shawcroft <scott@adafruit.com>2019-08-16 14:50:00 -0700
committerGitHub <noreply@github.com>2019-08-16 14:50:00 -0700
commit85d7398476687a3abdbb142d79b8302ac43ef760 (patch)
tree076af19d9c4d25bdb37d5dd563db0e10884c7b7f
parentd244f7e070efd27bc0904bcb712ebafda332cffb (diff)
parent630c92392abef67b0e6f81c98316dea93d3b2376 (diff)
Merge pull request #2066 from dhalbert/ble-pairing
BLE: more features
-rw-r--r--locale/ID.po72
-rw-r--r--locale/circuitpython.pot72
-rw-r--r--locale/de_DE.po72
-rw-r--r--locale/en_US.po72
-rw-r--r--locale/en_x_pirate.po72
-rw-r--r--locale/es.po75
-rw-r--r--locale/fil.po72
-rw-r--r--locale/fr.po75
-rw-r--r--locale/it_IT.po72
-rw-r--r--locale/pl.po75
-rw-r--r--locale/pt_BR.po72
-rw-r--r--locale/zh_Latn_pinyin.po80
-rw-r--r--ports/nrf/boards/make-pins.py208
-rw-r--r--ports/nrf/common-hal/bleio/Adapter.c41
-rw-r--r--ports/nrf/common-hal/bleio/Attribute.c60
-rw-r--r--ports/nrf/common-hal/bleio/Attribute.h (renamed from shared-module/bleio/__init__.h)14
-rw-r--r--ports/nrf/common-hal/bleio/Central.c344
-rw-r--r--ports/nrf/common-hal/bleio/Central.h5
-rw-r--r--ports/nrf/common-hal/bleio/Characteristic.c264
-rw-r--r--ports/nrf/common-hal/bleio/Characteristic.h10
-rw-r--r--ports/nrf/common-hal/bleio/CharacteristicBuffer.c2
-rw-r--r--ports/nrf/common-hal/bleio/Descriptor.c111
-rw-r--r--ports/nrf/common-hal/bleio/Descriptor.h11
-rw-r--r--ports/nrf/common-hal/bleio/Peripheral.c106
-rw-r--r--ports/nrf/common-hal/bleio/Peripheral.h15
-rw-r--r--ports/nrf/common-hal/bleio/Service.c101
-rw-r--r--ports/nrf/common-hal/bleio/Service.h2
-rw-r--r--ports/nrf/common-hal/bleio/__init__.c451
-rw-r--r--ports/nrf/common-hal/bleio/__init__.h8
-rw-r--r--ports/nrf/nrfx_config.h1
-rw-r--r--ports/nrf/peripherals/nrf/timers.c2
-rw-r--r--py/circuitpy_defns.mk11
-rw-r--r--py/obj.h1
-rw-r--r--py/objlist.c5
-rw-r--r--py/objstr.c6
-rw-r--r--py/objstr.h3
-rw-r--r--shared-bindings/bleio/Adapter.c36
-rw-r--r--shared-bindings/bleio/Adapter.h3
-rw-r--r--shared-bindings/bleio/Address.c47
-rw-r--r--shared-bindings/bleio/Attribute.c94
-rw-r--r--shared-bindings/bleio/Attribute.h38
-rw-r--r--shared-bindings/bleio/Central.c98
-rw-r--r--shared-bindings/bleio/Central.h5
-rw-r--r--shared-bindings/bleio/Characteristic.c265
-rw-r--r--shared-bindings/bleio/Characteristic.h4
-rw-r--r--shared-bindings/bleio/Descriptor.c145
-rw-r--r--shared-bindings/bleio/Descriptor.h27
-rw-r--r--shared-bindings/bleio/Peripheral.c102
-rw-r--r--shared-bindings/bleio/Peripheral.h5
-rw-r--r--shared-bindings/bleio/Service.c25
-rw-r--r--shared-bindings/bleio/Service.h1
-rw-r--r--shared-bindings/bleio/__init__.c38
-rw-r--r--shared-bindings/bleio/__init__.h16
-rw-r--r--shared-bindings/time/__init__.c21
-rw-r--r--shared-module/bleio/Attribute.c46
-rw-r--r--shared-module/bleio/Attribute.h41
-rw-r--r--shared-module/bleio/Characteristic.h21
-rw-r--r--supervisor/shared/usb/usb.c5
58 files changed, 2422 insertions, 1324 deletions
diff --git a/locale/ID.po b/locale/ID.po
index e8fdf3595..438dca55f 100644
--- a/locale/ID.po
+++ b/locale/ID.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-08-05 17:52-0700\n"
+"POT-Creation-Date: 2019-08-15 21:44-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -364,7 +364,7 @@ msgid "Can not use dotstar with %s"
msgstr ""
#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "Can't set CCCD for local Characteristic"
+msgid "Can't set CCCD on local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -433,6 +433,10 @@ msgstr ""
msgid "Characteristic already in use by another Service."
msgstr ""
+#: shared-bindings/bleio/Service.c
+msgid "Characteristic is already attached to a Service"
+msgstr ""
+
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
msgstr ""
@@ -508,6 +512,10 @@ msgstr ""
msgid "Data too large for advertisement packet"
msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment"
+#: shared-bindings/bleio/Characteristic.c
+msgid "Descriptor is already attached to a Characteristic"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr ""
@@ -602,7 +610,7 @@ msgstr ""
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX"
-#: ports/nrf/common-hal/bleio/Central.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy
msgid "Failed to discover services"
msgstr "Gagal untuk menemukan layanan, status: 0x%08lX"
@@ -622,17 +630,22 @@ msgstr "Gagal untuk mendapatkan status softdevice, error: 0x%08lX"
msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+msgid "Failed to pair"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Characteristic.c
#, fuzzy, c-format
msgid "Failed to read CCCD value, err 0x%04x"
msgstr "Gagal untuk membaca nilai atribut, status: 0x%08lX"
#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to read gatts value, err 0x%04x"
msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX"
@@ -662,6 +675,11 @@ msgstr "Gagal untuk memulai advertisement, status: 0x%08lX"
msgid "Failed to start connecting, error 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to start pairing, error 0x%04x"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Scanner.c
#, fuzzy, c-format
msgid "Failed to start scanning, err 0x%04x"
@@ -677,12 +695,12 @@ msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX"
msgid "Failed to write CCCD, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Gagal untuk menulis nilai atribut, status: 0x%08lX"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to write gatts value, err 0x%04x"
msgstr "Gagal untuk menulis nilai gatts, status: 0x%08lX"
@@ -828,10 +846,18 @@ msgstr "Pin-pin tidak valid"
msgid "Invalid polarity"
msgstr ""
+#: shared-bindings/bleio/Characteristic.c
+msgid "Invalid properties"
+msgstr ""
+
#: shared-bindings/microcontroller/__init__.c
msgid "Invalid run mode."
msgstr ""
+#: shared-module/bleio/Attribute.c
+msgid "Invalid security_mode"
+msgstr ""
+
#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr ""
@@ -950,8 +976,9 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/bleio/Peripheral.c
#, fuzzy
msgid "Not connected"
msgstr "Tidak dapat menyambungkan ke AP"
@@ -1289,6 +1316,19 @@ msgstr ""
msgid "Unsupported pull value."
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Value length required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length != required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length > max_length"
+msgstr ""
+
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
msgstr ""
@@ -1388,10 +1428,6 @@ msgstr ""
msgid "attributes not supported yet"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "bad GATT role"
-msgstr ""
-
#: py/builtinevex.c
msgid "bad compile mode"
msgstr "mode compile buruk"
@@ -1709,6 +1745,10 @@ msgstr ""
msgid "default 'except' must be last"
msgstr "'except' standar harus terakhir"
+#: shared-bindings/bleio/Characteristic.c
+msgid "descriptors includes an object that is not a Descriptors"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
@@ -2048,6 +2088,12 @@ msgstr ""
msgid "math domain error"
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+#, c-format
+msgid "max_length must be 0-%d when fixed_length is %s"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr ""
@@ -2147,8 +2193,8 @@ msgstr ""
msgid "non-Service found in services"
msgstr ""
-#: ports/nrf/common-hal/bleio/Central.c
-msgid "non-UUID found in service_uuids"
+#: ports/nrf/common-hal/bleio/__init__.c
+msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
#: py/compile.c
diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot
index a2e66cc5d..8cfbcfe85 100644
--- a/locale/circuitpython.pot
+++ b/locale/circuitpython.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-08-05 17:52-0700\n"
+"POT-Creation-Date: 2019-08-15 21:44-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -359,7 +359,7 @@ msgid "Can not use dotstar with %s"
msgstr ""
#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "Can't set CCCD for local Characteristic"
+msgid "Can't set CCCD on local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -423,6 +423,10 @@ msgstr ""
msgid "Characteristic already in use by another Service."
msgstr ""
+#: shared-bindings/bleio/Service.c
+msgid "Characteristic is already attached to a Service"
+msgstr ""
+
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
msgstr ""
@@ -497,6 +501,10 @@ msgstr ""
msgid "Data too large for advertisement packet"
msgstr ""
+#: shared-bindings/bleio/Characteristic.c
+msgid "Descriptor is already attached to a Characteristic"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr ""
@@ -590,7 +598,7 @@ msgstr ""
msgid "Failed to continue scanning, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Central.c
+#: ports/nrf/common-hal/bleio/__init__.c
msgid "Failed to discover services"
msgstr ""
@@ -607,17 +615,22 @@ msgstr ""
msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+msgid "Failed to pair"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Characteristic.c
#, c-format
msgid "Failed to read CCCD value, err 0x%04x"
msgstr ""
#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to read gatts value, err 0x%04x"
msgstr ""
@@ -647,6 +660,11 @@ msgstr ""
msgid "Failed to start connecting, error 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to start pairing, error 0x%04x"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Scanner.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
@@ -662,12 +680,12 @@ msgstr ""
msgid "Failed to write CCCD, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to write gatts value, err 0x%04x"
msgstr ""
@@ -813,10 +831,18 @@ msgstr ""
msgid "Invalid polarity"
msgstr ""
+#: shared-bindings/bleio/Characteristic.c
+msgid "Invalid properties"
+msgstr ""
+
#: shared-bindings/microcontroller/__init__.c
msgid "Invalid run mode."
msgstr ""
+#: shared-module/bleio/Attribute.c
+msgid "Invalid security_mode"
+msgstr ""
+
#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr ""
@@ -935,8 +961,9 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/bleio/Peripheral.c
msgid "Not connected"
msgstr ""
@@ -1265,6 +1292,19 @@ msgstr ""
msgid "Unsupported pull value."
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Value length required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length != required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length > max_length"
+msgstr ""
+
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
msgstr ""
@@ -1355,10 +1395,6 @@ msgstr ""
msgid "attributes not supported yet"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "bad GATT role"
-msgstr ""
-
#: py/builtinevex.c
msgid "bad compile mode"
msgstr ""
@@ -1675,6 +1711,10 @@ msgstr ""
msgid "default 'except' must be last"
msgstr ""
+#: shared-bindings/bleio/Characteristic.c
+msgid "descriptors includes an object that is not a Descriptors"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
@@ -2014,6 +2054,12 @@ msgstr ""
msgid "math domain error"
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+#, c-format
+msgid "max_length must be 0-%d when fixed_length is %s"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr ""
@@ -2112,8 +2158,8 @@ msgstr ""
msgid "non-Service found in services"
msgstr ""
-#: ports/nrf/common-hal/bleio/Central.c
-msgid "non-UUID found in service_uuids"
+#: ports/nrf/common-hal/bleio/__init__.c
+msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
#: py/compile.c
diff --git a/locale/de_DE.po b/locale/de_DE.po
index 3037a5369..7551b1e6d 100644
--- a/locale/de_DE.po
+++ b/locale/de_DE.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-08-05 17:52-0700\n"
+"POT-Creation-Date: 2019-08-15 21:44-0400\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: Pascal Deneaux\n"
"Language-Team: Sebastian Plamauer, Pascal Deneaux\n"
@@ -363,7 +363,7 @@ msgid "Can not use dotstar with %s"
msgstr "Kann dotstar nicht mit %s verwenden"
#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "Can't set CCCD for local Characteristic"
+msgid "Can't set CCCD on local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -427,6 +427,10 @@ msgstr "Characteristic UUID stimmt nicht mit der Service-UUID überein"
msgid "Characteristic already in use by another Service."
msgstr "Characteristic wird bereits von einem anderen Dienst verwendet."
+#: shared-bindings/bleio/Service.c
+msgid "Characteristic is already attached to a Service"
+msgstr ""
+
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
msgstr "Schreiben von CharacteristicBuffer ist nicht vorgesehen"
@@ -501,6 +505,10 @@ msgstr ""
msgid "Data too large for advertisement packet"
msgstr "Zu vielen Daten für das advertisement packet"
+#: shared-bindings/bleio/Characteristic.c
+msgid "Descriptor is already attached to a Characteristic"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr "Die Zielkapazität ist kleiner als destination_length."
@@ -594,7 +602,7 @@ msgstr ""
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Der Scanvorgang kann nicht fortgesetzt werden. Status: 0x%04x"
-#: ports/nrf/common-hal/bleio/Central.c
+#: ports/nrf/common-hal/bleio/__init__.c
msgid "Failed to discover services"
msgstr "Es konnten keine Dienste gefunden werden"
@@ -611,17 +619,22 @@ msgstr "Fehler beim Abrufen des Softdevice-Status"
msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+msgid "Failed to pair"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Characteristic.c
#, c-format
msgid "Failed to read CCCD value, err 0x%04x"
msgstr "Kann CCCD value nicht lesen. Status: 0x%04x"
#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to read gatts value, err 0x%04x"
msgstr "gatts value konnte nicht gelesen werden. Status: 0x%04x"
@@ -651,6 +664,11 @@ msgstr "Kann advertisement nicht starten. Status: 0x%04x"
msgid "Failed to start connecting, error 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to start pairing, error 0x%04x"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Scanner.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
@@ -666,12 +684,12 @@ msgstr "Kann advertisement nicht stoppen. Status: 0x%04x"
msgid "Failed to write CCCD, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Kann den Attributwert nicht schreiben. Status: 0x%04x"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to write gatts value, err 0x%04x"
msgstr "gatts value konnte nicht geschrieben werden. Status: 0x%04x"
@@ -819,10 +837,18 @@ msgstr "Ungültige Pins"
msgid "Invalid polarity"
msgstr "Ungültige Polarität"
+#: shared-bindings/bleio/Characteristic.c
+msgid "Invalid properties"
+msgstr ""
+
#: shared-bindings/microcontroller/__init__.c
msgid "Invalid run mode."
msgstr "Ungültiger Ausführungsmodus"
+#: shared-module/bleio/Attribute.c
+msgid "Invalid security_mode"
+msgstr ""
+
#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr "Ungültige Anzahl von Stimmen"
@@ -948,8 +974,9 @@ msgstr "Kein Speicherplatz auf Gerät"
msgid "No such file/directory"
msgstr "Keine solche Datei/Verzeichnis"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/bleio/Peripheral.c
msgid "Not connected"
msgstr "Nicht verbunden"
@@ -1296,6 +1323,19 @@ msgstr "Nicht unterstützte Operation"
msgid "Unsupported pull value."
msgstr "Nicht unterstützter Pull-Wert"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Value length required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length != required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length > max_length"
+msgstr ""
+
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
msgstr "Viper-Funktionen unterstützen derzeit nicht mehr als 4 Argumente"
@@ -1395,10 +1435,6 @@ msgstr "Array/Bytes auf der rechten Seite erforderlich"
msgid "attributes not supported yet"
msgstr "Attribute werden noch nicht unterstützt"
-#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "bad GATT role"
-msgstr ""
-
#: py/builtinevex.c
msgid "bad compile mode"
msgstr ""
@@ -1715,6 +1751,10 @@ msgstr ""
msgid "default 'except' must be last"
msgstr "Die Standart-Ausnahmebehandlung muss als letztes sein"
+#: shared-bindings/bleio/Characteristic.c
+msgid "descriptors includes an object that is not a Descriptors"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
@@ -2061,6 +2101,12 @@ msgstr "map buffer zu klein"
msgid "math domain error"
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+#, c-format
+msgid "max_length must be 0-%d when fixed_length is %s"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "maximale Rekursionstiefe überschritten"
@@ -2159,8 +2205,8 @@ msgstr ""
msgid "non-Service found in services"
msgstr ""
-#: ports/nrf/common-hal/bleio/Central.c
-msgid "non-UUID found in service_uuids"
+#: ports/nrf/common-hal/bleio/__init__.c
+msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
#: py/compile.c
diff --git a/locale/en_US.po b/locale/en_US.po
index 6d15af4dd..fd176c869 100644
--- a/locale/en_US.po
+++ b/locale/en_US.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-08-05 17:52-0700\n"
+"POT-Creation-Date: 2019-08-15 21:44-0400\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -359,7 +359,7 @@ msgid "Can not use dotstar with %s"
msgstr ""
#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "Can't set CCCD for local Characteristic"
+msgid "Can't set CCCD on local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -423,6 +423,10 @@ msgstr ""
msgid "Characteristic already in use by another Service."
msgstr ""
+#: shared-bindings/bleio/Service.c
+msgid "Characteristic is already attached to a Service"
+msgstr ""
+
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
msgstr ""
@@ -497,6 +501,10 @@ msgstr ""
msgid "Data too large for advertisement packet"
msgstr ""
+#: shared-bindings/bleio/Characteristic.c
+msgid "Descriptor is already attached to a Characteristic"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr ""
@@ -590,7 +598,7 @@ msgstr ""
msgid "Failed to continue scanning, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Central.c
+#: ports/nrf/common-hal/bleio/__init__.c
msgid "Failed to discover services"
msgstr ""
@@ -607,17 +615,22 @@ msgstr ""
msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+msgid "Failed to pair"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Characteristic.c
#, c-format
msgid "Failed to read CCCD value, err 0x%04x"
msgstr ""
#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to read gatts value, err 0x%04x"
msgstr ""
@@ -647,6 +660,11 @@ msgstr ""
msgid "Failed to start connecting, error 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to start pairing, error 0x%04x"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Scanner.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
@@ -662,12 +680,12 @@ msgstr ""
msgid "Failed to write CCCD, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to write gatts value, err 0x%04x"
msgstr ""
@@ -813,10 +831,18 @@ msgstr ""
msgid "Invalid polarity"
msgstr ""
+#: shared-bindings/bleio/Characteristic.c
+msgid "Invalid properties"
+msgstr ""
+
#: shared-bindings/microcontroller/__init__.c
msgid "Invalid run mode."
msgstr ""
+#: shared-module/bleio/Attribute.c
+msgid "Invalid security_mode"
+msgstr ""
+
#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr ""
@@ -935,8 +961,9 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/bleio/Peripheral.c
msgid "Not connected"
msgstr ""
@@ -1265,6 +1292,19 @@ msgstr ""
msgid "Unsupported pull value."
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Value length required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length != required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length > max_length"
+msgstr ""
+
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
msgstr ""
@@ -1355,10 +1395,6 @@ msgstr ""
msgid "attributes not supported yet"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "bad GATT role"
-msgstr ""
-
#: py/builtinevex.c
msgid "bad compile mode"
msgstr ""
@@ -1675,6 +1711,10 @@ msgstr ""
msgid "default 'except' must be last"
msgstr ""
+#: shared-bindings/bleio/Characteristic.c
+msgid "descriptors includes an object that is not a Descriptors"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
@@ -2014,6 +2054,12 @@ msgstr ""
msgid "math domain error"
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+#, c-format
+msgid "max_length must be 0-%d when fixed_length is %s"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr ""
@@ -2112,8 +2158,8 @@ msgstr ""
msgid "non-Service found in services"
msgstr ""
-#: ports/nrf/common-hal/bleio/Central.c
-msgid "non-UUID found in service_uuids"
+#: ports/nrf/common-hal/bleio/__init__.c
+msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
#: py/compile.c
diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po
index 57bb45380..f0aa99293 100644
--- a/locale/en_x_pirate.po
+++ b/locale/en_x_pirate.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-08-05 17:52-0700\n"
+"POT-Creation-Date: 2019-08-15 21:44-0400\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: @sommersoft, @MrCertainly\n"
@@ -363,7 +363,7 @@ msgid "Can not use dotstar with %s"
msgstr ""
#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "Can't set CCCD for local Characteristic"
+msgid "Can't set CCCD on local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -427,6 +427,10 @@ msgstr ""
msgid "Characteristic already in use by another Service."
msgstr ""
+#: shared-bindings/bleio/Service.c
+msgid "Characteristic is already attached to a Service"
+msgstr ""
+
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
msgstr ""
@@ -501,6 +505,10 @@ msgstr ""
msgid "Data too large for advertisement packet"
msgstr ""
+#: shared-bindings/bleio/Characteristic.c
+msgid "Descriptor is already attached to a Characteristic"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr ""
@@ -594,7 +602,7 @@ msgstr ""
msgid "Failed to continue scanning, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Central.c
+#: ports/nrf/common-hal/bleio/__init__.c
msgid "Failed to discover services"
msgstr ""
@@ -611,17 +619,22 @@ msgstr ""
msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+msgid "Failed to pair"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Characteristic.c
#, c-format
msgid "Failed to read CCCD value, err 0x%04x"
msgstr ""
#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to read gatts value, err 0x%04x"
msgstr ""
@@ -651,6 +664,11 @@ msgstr ""
msgid "Failed to start connecting, error 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to start pairing, error 0x%04x"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Scanner.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
@@ -666,12 +684,12 @@ msgstr ""
msgid "Failed to write CCCD, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to write gatts value, err 0x%04x"
msgstr ""
@@ -817,10 +835,18 @@ msgstr ""
msgid "Invalid polarity"
msgstr ""
+#: shared-bindings/bleio/Characteristic.c
+msgid "Invalid properties"
+msgstr ""
+
#: shared-bindings/microcontroller/__init__.c
msgid "Invalid run mode."
msgstr ""
+#: shared-module/bleio/Attribute.c
+msgid "Invalid security_mode"
+msgstr ""
+
#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr ""
@@ -939,8 +965,9 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/bleio/Peripheral.c
msgid "Not connected"
msgstr ""
@@ -1269,6 +1296,19 @@ msgstr ""
msgid "Unsupported pull value."
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Value length required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length != required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length > max_length"
+msgstr ""
+
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
msgstr ""
@@ -1359,10 +1399,6 @@ msgstr ""
msgid "attributes not supported yet"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "bad GATT role"
-msgstr ""
-
#: py/builtinevex.c
msgid "bad compile mode"
msgstr ""
@@ -1679,6 +1715,10 @@ msgstr ""
msgid "default 'except' must be last"
msgstr ""
+#: shared-bindings/bleio/Characteristic.c
+msgid "descriptors includes an object that is not a Descriptors"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
@@ -2018,6 +2058,12 @@ msgstr ""
msgid "math domain error"
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+#, c-format
+msgid "max_length must be 0-%d when fixed_length is %s"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr ""
@@ -2116,8 +2162,8 @@ msgstr ""
msgid "non-Service found in services"
msgstr ""
-#: ports/nrf/common-hal/bleio/Central.c
-msgid "non-UUID found in service_uuids"
+#: ports/nrf/common-hal/bleio/__init__.c
+msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
#: py/compile.c
diff --git a/locale/es.po b/locale/es.po
index a3ffe5799..c90be4e02 100644
--- a/locale/es.po
+++ b/locale/es.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-07-31 16:30-0500\n"
+"POT-Creation-Date: 2019-08-15 21:44-0400\n"
"PO-Revision-Date: 2018-08-24 22:56-0500\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -367,7 +367,7 @@ msgid "Can not use dotstar with %s"
msgstr "No se puede usar dotstar con %s"
#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "Can't set CCCD for local Characteristic"
+msgid "Can't set CCCD on local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -431,6 +431,10 @@ msgstr "Características UUID no concide con el Service UUID"
msgid "Characteristic already in use by another Service."
msgstr "Características ya esta en uso por otro Serivice"
+#: shared-bindings/bleio/Service.c
+msgid "Characteristic is already attached to a Service"
+msgstr ""
+
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
msgstr "CharateristicBuffer escritura no proporcionada"
@@ -505,6 +509,10 @@ msgstr "Trozo de datos debe seguir fmt chunk"
msgid "Data too large for advertisement packet"
msgstr "Data es muy grande para el paquete de advertisement."
+#: shared-bindings/bleio/Characteristic.c
+msgid "Descriptor is already attached to a Characteristic"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr "Capacidad de destino es mas pequeña que destination_length."
@@ -598,7 +606,7 @@ msgstr ""
msgid "Failed to continue scanning, err 0x%04x"
msgstr "No se puede iniciar el escaneo. err: 0x%02x"
-#: ports/nrf/common-hal/bleio/Central.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy
msgid "Failed to discover services"
msgstr "No se puede descubrir servicios"
@@ -616,17 +624,22 @@ msgstr "No se puede obtener el estado del softdevice"
msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr "Error al notificar o indicar el valor del atributo, err 0x%04x"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+msgid "Failed to pair"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Characteristic.c
#, c-format
msgid "Failed to read CCCD value, err 0x%04x"
msgstr "No se puede leer el valor del atributo. err 0x%02x"
#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr "Error al leer valor del atributo, err 0x%04"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to read gatts value, err 0x%04x"
msgstr "No se puede escribir el valor del atributo. status: 0x%02x"
@@ -656,6 +669,11 @@ msgstr "No se puede inicar el anuncio. err: 0x%04x"
msgid "Failed to start connecting, error 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to start pairing, error 0x%04x"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Scanner.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
@@ -671,12 +689,12 @@ msgstr "No se puede detener el anuncio. err: 0x%04x"
msgid "Failed to write CCCD, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "No se puede escribir el valor del atributo. err: 0x%04x"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to write gatts value, err 0x%04x"
msgstr "No se puede escribir el valor del atributo. err: 0x%04x"
@@ -824,10 +842,18 @@ msgstr "pines inválidos"
msgid "Invalid polarity"
msgstr "Polaridad inválida"
+#: shared-bindings/bleio/Characteristic.c
+msgid "Invalid properties"
+msgstr ""
+
#: shared-bindings/microcontroller/__init__.c
msgid "Invalid run mode."
msgstr "Modo de ejecución inválido."
+#: shared-module/bleio/Attribute.c
+msgid "Invalid security_mode"
+msgstr ""
+
#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr "Cuenta de voces inválida"
@@ -950,8 +976,9 @@ msgstr "No queda espacio en el dispositivo"
msgid "No such file/directory"
msgstr "No existe el archivo/directorio"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/bleio/Peripheral.c
msgid "Not connected"
msgstr "No conectado"
@@ -1306,6 +1333,19 @@ msgstr "Operación no soportada"
msgid "Unsupported pull value."
msgstr "valor pull no soportado."
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Value length required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length != required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length > max_length"
+msgstr ""
+
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
msgstr "funciones Viper actualmente no soportan más de 4 argumentos."
@@ -1404,10 +1444,6 @@ msgstr "array/bytes requeridos en el lado derecho"
msgid "attributes not supported yet"
msgstr "atributos aún no soportados"
-#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "bad GATT role"
-msgstr "mal GATT role"
-
#: py/builtinevex.c
msgid "bad compile mode"
msgstr "modo de compilación erroneo"
@@ -1729,6 +1765,10 @@ msgstr "números decimales no soportados"
msgid "default 'except' must be last"
msgstr "'except' por defecto deberia estar de último"
+#: shared-bindings/bleio/Characteristic.c
+msgid "descriptors includes an object that is not a Descriptors"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
@@ -2073,6 +2113,12 @@ msgstr "map buffer muy pequeño"
msgid "math domain error"
msgstr "error de dominio matemático"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+#, c-format
+msgid "max_length must be 0-%d when fixed_length is %s"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "profundidad máxima de recursión excedida"
@@ -2171,8 +2217,8 @@ msgstr "no hay tal atributo"
msgid "non-Service found in services"
msgstr ""
-#: ports/nrf/common-hal/bleio/Central.c
-msgid "non-UUID found in service_uuids"
+#: ports/nrf/common-hal/bleio/__init__.c
+msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
#: py/compile.c
@@ -2866,6 +2912,9 @@ msgstr "paso cero"
#~ msgstr ""
#~ "Usa esptool para borrar la flash y vuelve a cargar Python en su lugar"
+#~ msgid "bad GATT role"
+#~ msgstr "mal GATT role"
+
#~ msgid "buffer too long"
#~ msgstr "buffer demasiado largo"
diff --git a/locale/fil.po b/locale/fil.po
index f83429882..d2535cc38 100644
--- a/locale/fil.po
+++ b/locale/fil.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-07-31 16:30-0500\n"
+"POT-Creation-Date: 2019-08-15 21:44-0400\n"
"PO-Revision-Date: 2018-12-20 22:15-0800\n"
"Last-Translator: Timothy <me@timothygarcia.ca>\n"
"Language-Team: fil\n"
@@ -366,7 +366,7 @@ msgid "Can not use dotstar with %s"
msgstr ""
#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "Can't set CCCD for local Characteristic"
+msgid "Can't set CCCD on local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -431,6 +431,10 @@ msgstr ""
msgid "Characteristic already in use by another Service."
msgstr ""
+#: shared-bindings/bleio/Service.c
+msgid "Characteristic is already attached to a Service"
+msgstr ""
+
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
msgstr ""
@@ -508,6 +512,10 @@ msgstr "Dapat sunurin ng Data chunk ang fmt chunk"
msgid "Data too large for advertisement packet"
msgstr "Hindi makasya ang data sa loob ng advertisement packet"
+#: shared-bindings/bleio/Characteristic.c
+msgid "Descriptor is already attached to a Characteristic"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr ""
@@ -605,7 +613,7 @@ msgstr ""
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX"
-#: ports/nrf/common-hal/bleio/Central.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy
msgid "Failed to discover services"
msgstr "Nabigo sa pagdiscover ng services, status: 0x%08lX"
@@ -625,17 +633,22 @@ msgstr "Nabigo sa pagkuha ng softdevice state, error: 0x%08lX"
msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+msgid "Failed to pair"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Characteristic.c
#, fuzzy, c-format
msgid "Failed to read CCCD value, err 0x%04x"
msgstr "Hindi mabasa ang value ng attribute, status: 0x%08lX"
#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to read gatts value, err 0x%04x"
msgstr "Hindi maisulat ang gatts value, status: 0x%08lX"
@@ -665,6 +678,11 @@ msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX"
msgid "Failed to start connecting, error 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to start pairing, error 0x%04x"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Scanner.c
#, fuzzy, c-format
msgid "Failed to start scanning, err 0x%04x"
@@ -680,12 +698,12 @@ msgstr "Hindi mahinto ang advertisement, status: 0x%08lX"
msgid "Failed to write CCCD, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Hindi maisulat ang attribute value, status: 0x%08lX"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to write gatts value, err 0x%04x"
msgstr "Hindi maisulat ang gatts value, status: 0x%08lX"
@@ -833,10 +851,18 @@ msgstr "Mali ang pins"
msgid "Invalid polarity"
msgstr "Mali ang polarity"
+#: shared-bindings/bleio/Characteristic.c
+msgid "Invalid properties"
+msgstr ""
+
#: shared-bindings/microcontroller/__init__.c
msgid "Invalid run mode."
msgstr "Mali ang run mode."
+#: shared-module/bleio/Attribute.c
+msgid "Invalid security_mode"
+msgstr ""
+
#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr "Maling bilang ng voice"
@@ -959,8 +985,9 @@ msgstr ""
msgid "No such file/directory"
msgstr "Walang file/directory"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/bleio/Peripheral.c
#, fuzzy
msgid "Not connected"
msgstr "Hindi maka connect sa AP"
@@ -1310,6 +1337,19 @@ msgstr "Hindi sinusuportahang operasyon"
msgid "Unsupported pull value."
msgstr "Hindi suportado ang pull value."
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Value length required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length != required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length > max_length"
+msgstr ""
+
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
msgstr ""
@@ -1408,10 +1448,6 @@ msgstr "array/bytes kinakailangan sa kanang bahagi"
msgid "attributes not supported yet"
msgstr "attributes hindi sinusuportahan"
-#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "bad GATT role"
-msgstr ""
-
#: py/builtinevex.c
msgid "bad compile mode"
msgstr "masamang mode ng compile"
@@ -1735,6 +1771,10 @@ msgstr "decimal numbers hindi sinusuportahan"
msgid "default 'except' must be last"
msgstr "default 'except' ay dapat sa huli"
+#: shared-bindings/bleio/Characteristic.c
+msgid "descriptors includes an object that is not a Descriptors"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
@@ -2084,6 +2124,12 @@ msgstr "masyadong maliit ang buffer map"
msgid "math domain error"
msgstr "may pagkakamali sa math domain"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+#, c-format
+msgid "max_length must be 0-%d when fixed_length is %s"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "lumagpas ang maximum recursion depth"
@@ -2183,8 +2229,8 @@ msgstr "walang ganoon na attribute"
msgid "non-Service found in services"
msgstr ""
-#: ports/nrf/common-hal/bleio/Central.c
-msgid "non-UUID found in service_uuids"
+#: ports/nrf/common-hal/bleio/__init__.c
+msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
#: py/compile.c
diff --git a/locale/fr.po b/locale/fr.po
index 07355526f..999d8c4f0 100644
--- a/locale/fr.po
+++ b/locale/fr.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-07-31 16:30-0500\n"
+"POT-Creation-Date: 2019-08-15 21:44-0400\n"
"PO-Revision-Date: 2019-04-14 20:05+0100\n"
"Last-Translator: Pierrick Couturier <arofarn@arofarn.info>\n"
"Language-Team: fr\n"
@@ -371,7 +371,7 @@ msgid "Can not use dotstar with %s"
msgstr "Impossible d'utiliser 'dotstar' avec %s"
#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "Can't set CCCD for local Characteristic"
+msgid "Can't set CCCD on local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -437,6 +437,10 @@ msgstr "L'UUID de 'Characteristic' ne correspond pas à l'UUID du Service"
msgid "Characteristic already in use by another Service."
msgstr "'Characteristic' déjà en utilisation par un autre service"
+#: shared-bindings/bleio/Service.c
+msgid "Characteristic is already attached to a Service"
+msgstr ""
+
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
msgstr "Ecriture sur 'CharacteristicBuffer' non fournie"
@@ -513,6 +517,10 @@ msgstr "Un bloc de données doit suivre un bloc de format"
msgid "Data too large for advertisement packet"
msgstr "Données trop volumineuses pour un paquet de diffusion"
+#: shared-bindings/bleio/Characteristic.c
+msgid "Descriptor is already attached to a Characteristic"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr "La capacité de destination est plus petite que 'destination_length'."
@@ -609,7 +617,7 @@ msgstr ""
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Impossible de poursuivre le scan, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Central.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy
msgid "Failed to discover services"
msgstr "Echec de la découverte de services"
@@ -630,17 +638,22 @@ msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr ""
"Impossible de notifier ou d'indiquer la valeur de l'attribut, err 0x%04x"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+msgid "Failed to pair"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Characteristic.c
#, fuzzy, c-format
msgid "Failed to read CCCD value, err 0x%04x"
msgstr "Impossible de lire la valeur 'CCCD', err 0x%04x"
#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr "Impossible de lire la valeur de l'attribut, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to read gatts value, err 0x%04x"
msgstr "Impossible de lire la valeur de 'gatts', err 0x%04x"
@@ -670,6 +683,11 @@ msgstr "Impossible de commencer à diffuser, err 0x%04x"
msgid "Failed to start connecting, error 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to start pairing, error 0x%04x"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Scanner.c
#, fuzzy, c-format
msgid "Failed to start scanning, err 0x%04x"
@@ -685,12 +703,12 @@ msgstr "Echec de l'arrêt de diffusion, err 0x%04x"
msgid "Failed to write CCCD, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Impossible d'écrire la valeur de l'attribut, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to write gatts value, err 0x%04x"
msgstr "Impossible d'écrire la valeur de 'gatts', err 0x%04x"
@@ -841,10 +859,18 @@ msgstr "Broches invalides"
msgid "Invalid polarity"
msgstr "Polarité invalide"
+#: shared-bindings/bleio/Characteristic.c
+msgid "Invalid properties"
+msgstr ""
+
#: shared-bindings/microcontroller/__init__.c
msgid "Invalid run mode."
msgstr "Mode de lancement invalide."
+#: shared-module/bleio/Attribute.c
+msgid "Invalid security_mode"
+msgstr ""
+
#: shared-bindings/audiocore/Mixer.c
#, fuzzy
msgid "Invalid voice count"
@@ -968,8 +994,9 @@ msgstr "Il n'y a plus d'espace libre sur le périphérique"
msgid "No such file/directory"
msgstr "Fichier/dossier introuvable"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/bleio/Peripheral.c
#, fuzzy
msgid "Not connected"
msgstr "Non connecté"
@@ -1335,6 +1362,19 @@ msgstr "Opération non supportée"
msgid "Unsupported pull value."
msgstr "Valeur de tirage 'pull' non supportée."
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Value length required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length != required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length > max_length"
+msgstr ""
+
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
msgstr ""
@@ -1433,10 +1473,6 @@ msgstr "tableau/octets requis à droite"
msgid "attributes not supported yet"
msgstr "attribut pas encore supporté"
-#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "bad GATT role"
-msgstr "mauvais rôle GATT"
-
#: py/builtinevex.c
msgid "bad compile mode"
msgstr "mauvais mode de compilation"
@@ -1771,6 +1807,10 @@ msgstr "nombres décimaux non supportés"
msgid "default 'except' must be last"
msgstr "l''except' par défaut doit être en dernier"
+#: shared-bindings/bleio/Characteristic.c
+msgid "descriptors includes an object that is not a Descriptors"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
@@ -2117,6 +2157,12 @@ msgstr "tampon trop petit"
msgid "math domain error"
msgstr "erreur de domaine math"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+#, c-format
+msgid "max_length must be 0-%d when fixed_length is %s"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "profondeur maximale de récursivité dépassée"
@@ -2217,8 +2263,8 @@ msgstr "pas de tel attribut"
msgid "non-Service found in services"
msgstr ""
-#: ports/nrf/common-hal/bleio/Central.c
-msgid "non-UUID found in service_uuids"
+#: ports/nrf/common-hal/bleio/__init__.c
+msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
#: py/compile.c
@@ -2917,6 +2963,9 @@ msgstr "'step' nul"
#~ msgstr ""
#~ "Utilisez 'esptool' pour effacer la flash et recharger Python à la place"
+#~ msgid "bad GATT role"
+#~ msgstr "mauvais rôle GATT"
+
#~ msgid "buffer too long"
#~ msgstr "tampon trop long"
diff --git a/locale/it_IT.po b/locale/it_IT.po
index 4360cd221..411c9125a 100644
--- a/locale/it_IT.po
+++ b/locale/it_IT.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-07-31 16:30-0500\n"
+"POT-Creation-Date: 2019-08-15 21:44-0400\n"
"PO-Revision-Date: 2018-10-02 16:27+0200\n"
"Last-Translator: Enrico Paganin <enrico.paganin@mail.com>\n"
"Language-Team: \n"
@@ -366,7 +366,7 @@ msgid "Can not use dotstar with %s"
msgstr "dotstar non può essere usato con %s"
#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "Can't set CCCD for local Characteristic"
+msgid "Can't set CCCD on local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -432,6 +432,10 @@ msgstr "caratteristico UUID non assomiglia servizio UUID"
msgid "Characteristic already in use by another Service."
msgstr "caratteristico già usato da un altro servizio"
+#: shared-bindings/bleio/Service.c
+msgid "Characteristic is already attached to a Service"
+msgstr ""
+
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
msgstr "CharacteristicBuffer scritura non dato"
@@ -509,6 +513,10 @@ msgstr ""
msgid "Data too large for advertisement packet"
msgstr "Impossibile inserire dati nel pacchetto di advertisement."
+#: shared-bindings/bleio/Characteristic.c
+msgid "Descriptor is already attached to a Characteristic"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr "La capacità di destinazione è più piccola di destination_length."
@@ -605,7 +613,7 @@ msgstr ""
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Impossible iniziare la scansione. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Central.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy
msgid "Failed to discover services"
msgstr "Impossibile fermare advertisement. status: 0x%02x"
@@ -624,17 +632,22 @@ msgstr "Impossibile fermare advertisement. status: 0x%02x"
msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr "Notificamento o indicazione di attribute value fallito, err 0x%04x"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+msgid "Failed to pair"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Characteristic.c
#, fuzzy, c-format
msgid "Failed to read CCCD value, err 0x%04x"
msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr "Tentative leggere attribute value fallito, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to read gatts value, err 0x%04x"
msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x"
@@ -664,6 +677,11 @@ msgstr "Impossibile avviare advertisement. status: 0x%02x"
msgid "Failed to start connecting, error 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to start pairing, error 0x%04x"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Scanner.c
#, fuzzy, c-format
msgid "Failed to start scanning, err 0x%04x"
@@ -679,12 +697,12 @@ msgstr "Impossibile fermare advertisement. status: 0x%02x"
msgid "Failed to write CCCD, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to write gatts value, err 0x%04x"
msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x"
@@ -834,10 +852,18 @@ msgstr "Pin non validi"
msgid "Invalid polarity"
msgstr "Polarità non valida"
+#: shared-bindings/bleio/Characteristic.c
+msgid "Invalid properties"
+msgstr ""
+
#: shared-bindings/microcontroller/__init__.c
msgid "Invalid run mode."
msgstr "Modalità di esecuzione non valida."
+#: shared-module/bleio/Attribute.c
+msgid "Invalid security_mode"
+msgstr ""
+
#: shared-bindings/audiocore/Mixer.c
#, fuzzy
msgid "Invalid voice count"
@@ -958,8 +984,9 @@ msgstr "Non che spazio sul dispositivo"
msgid "No such file/directory"
msgstr "Nessun file/directory esistente"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/bleio/Peripheral.c
#, fuzzy
msgid "Not connected"
msgstr "Impossible connettersi all'AP"
@@ -1309,6 +1336,19 @@ msgstr "Operazione non supportata"
msgid "Unsupported pull value."
msgstr "Valore di pull non supportato."
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Value length required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length != required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length > max_length"
+msgstr ""
+
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
msgstr "Le funzioni Viper non supportano più di 4 argomenti al momento"
@@ -1402,10 +1442,6 @@ msgstr ""
msgid "attributes not supported yet"
msgstr "attributi non ancora supportati"
-#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "bad GATT role"
-msgstr ""
-
#: py/builtinevex.c
msgid "bad compile mode"
msgstr ""
@@ -1728,6 +1764,10 @@ msgstr "numeri decimali non supportati"
msgid "default 'except' must be last"
msgstr "'except' predefinito deve essere ultimo"
+#: shared-bindings/bleio/Characteristic.c
+msgid "descriptors includes an object that is not a Descriptors"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
@@ -2077,6 +2117,12 @@ msgstr "map buffer troppo piccolo"
msgid "math domain error"
msgstr "errore di dominio matematico"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+#, c-format
+msgid "max_length must be 0-%d when fixed_length is %s"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "profondità massima di ricorsione superata"
@@ -2177,8 +2223,8 @@ msgstr "attributo inesistente"
msgid "non-Service found in services"
msgstr ""
-#: ports/nrf/common-hal/bleio/Central.c
-msgid "non-UUID found in service_uuids"
+#: ports/nrf/common-hal/bleio/__init__.c
+msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
#: py/compile.c
diff --git a/locale/pl.po b/locale/pl.po
index 0a38aa914..caa5df76d 100644
--- a/locale/pl.po
+++ b/locale/pl.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-08-05 17:52-0700\n"
+"POT-Creation-Date: 2019-08-15 21:44-0400\n"
"PO-Revision-Date: 2019-03-19 18:37-0700\n"
"Last-Translator: Radomir Dopieralski <circuitpython@sheep.art.pl>\n"
"Language-Team: pl\n"
@@ -362,7 +362,7 @@ msgid "Can not use dotstar with %s"
msgstr "Nie można używać dotstar z %s"
#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "Can't set CCCD for local Characteristic"
+msgid "Can't set CCCD on local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -426,6 +426,10 @@ msgstr "UUID charakterystyki inny niż UUID serwisu"
msgid "Characteristic already in use by another Service."
msgstr "Charakterystyka w użyciu w innym serwisie"
+#: shared-bindings/bleio/Service.c
+msgid "Characteristic is already attached to a Service"
+msgstr ""
+
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
msgstr "Pisanie do CharacteristicBuffer niewspierane"
@@ -500,6 +504,10 @@ msgstr "Fragment danych musi następować po fragmencie fmt"
msgid "Data too large for advertisement packet"
msgstr "Zbyt dużo danych pakietu rozgłoszeniowego"
+#: shared-bindings/bleio/Characteristic.c
+msgid "Descriptor is already attached to a Characteristic"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr "Pojemność celu mniejsza od destination_length."
@@ -593,7 +601,7 @@ msgstr ""
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Nie udała się kontynuacja skanowania, błąd 0x%04x"
-#: ports/nrf/common-hal/bleio/Central.c
+#: ports/nrf/common-hal/bleio/__init__.c
msgid "Failed to discover services"
msgstr "Nie udało się odkryć serwisów"
@@ -610,17 +618,22 @@ msgstr "Nie udało się odczytać stanu softdevice"
msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr "Nie udało się powiadomić o wartości atrybutu, błąd 0x%04x"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+msgid "Failed to pair"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Characteristic.c
#, c-format
msgid "Failed to read CCCD value, err 0x%04x"
msgstr "Nie udało się odczytać CCCD, błąd 0x%04x"
#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr "Nie udało się odczytać wartości atrybutu, błąd 0x%04x"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to read gatts value, err 0x%04x"
msgstr "Nie udało się odczytać gatts, błąd 0x%04x"
@@ -650,6 +663,11 @@ msgstr "Nie udało się rozpocząć rozgłaszania, błąd 0x%04x"
msgid "Failed to start connecting, error 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to start pairing, error 0x%04x"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Scanner.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
@@ -665,12 +683,12 @@ msgstr "Nie udało się zatrzymać rozgłaszania, błąd 0x%04x"
msgid "Failed to write CCCD, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Nie udało się zapisać atrybutu, błąd 0x%04x"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to write gatts value, err 0x%04x"
msgstr "Nie udało się zapisać gatts, błąd 0x%04x"
@@ -818,10 +836,18 @@ msgstr "Złe nóżki"
msgid "Invalid polarity"
msgstr "Zła polaryzacja"
+#: shared-bindings/bleio/Characteristic.c
+msgid "Invalid properties"
+msgstr ""
+
#: shared-bindings/microcontroller/__init__.c
msgid "Invalid run mode."
msgstr "Zły tryb uruchomienia"
+#: shared-module/bleio/Attribute.c
+msgid "Invalid security_mode"
+msgstr ""
+
#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr "Zła liczba głosów"
@@ -945,8 +971,9 @@ msgstr "Brak miejsca"
msgid "No such file/directory"
msgstr "Brak pliku/katalogu"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/bleio/Peripheral.c
msgid "Not connected"
msgstr "Nie podłączono"
@@ -1285,6 +1312,19 @@ msgstr "Zła operacja"
msgid "Unsupported pull value."
msgstr "Zła wartość podciągnięcia."
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Value length required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length != required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length > max_length"
+msgstr ""
+
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
msgstr "Funkcje Viper nie obsługują obecnie więcej niż 4 argumentów"
@@ -1379,10 +1419,6 @@ msgstr "tablica/bytes wymagane po prawej stronie"
msgid "attributes not supported yet"
msgstr "atrybuty nie są jeszcze obsługiwane"
-#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "bad GATT role"
-msgstr "zła rola GATT"
-
#: py/builtinevex.c
msgid "bad compile mode"
msgstr "zły tryb kompilacji"
@@ -1699,6 +1735,10 @@ msgstr "liczby dziesiętne nieobsługiwane"
msgid "default 'except' must be last"
msgstr "domyślny 'except' musi być ostatni"
+#: shared-bindings/bleio/Characteristic.c
+msgid "descriptors includes an object that is not a Descriptors"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
@@ -2039,6 +2079,12 @@ msgstr "bufor mapy zbyt mały"
msgid "math domain error"
msgstr "błąd domeny"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+#, c-format
+msgid "max_length must be 0-%d when fixed_length is %s"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "przekroczono dozwoloną głębokość rekurencji"
@@ -2137,8 +2183,8 @@ msgstr "nie ma takiego atrybutu"
msgid "non-Service found in services"
msgstr ""
-#: ports/nrf/common-hal/bleio/Central.c
-msgid "non-UUID found in service_uuids"
+#: ports/nrf/common-hal/bleio/__init__.c
+msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
#: py/compile.c
@@ -2708,6 +2754,9 @@ msgstr "zerowy krok"
#~ msgid "UUID integer value not in range 0 to 0xffff"
#~ msgstr "Wartość UUID poza zakresem 0 do 0xffff"
+#~ msgid "bad GATT role"
+#~ msgstr "zła rola GATT"
+
#~ msgid "interval not in range 0.0020 to 10.24"
#~ msgstr "przedział poza zakresem 0.0020 do 10.24"
diff --git a/locale/pt_BR.po b/locale/pt_BR.po
index defeb3e44..79a83d2f6 100644
--- a/locale/pt_BR.po
+++ b/locale/pt_BR.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-07-31 16:30-0500\n"
+"POT-Creation-Date: 2019-08-15 21:44-0400\n"
"PO-Revision-Date: 2018-10-02 21:14-0000\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -363,7 +363,7 @@ msgid "Can not use dotstar with %s"
msgstr ""
#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "Can't set CCCD for local Characteristic"
+msgid "Can't set CCCD on local Characteristic"
msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
@@ -428,6 +428,10 @@ msgstr ""
msgid "Characteristic already in use by another Service."
msgstr ""
+#: shared-bindings/bleio/Service.c
+msgid "Characteristic is already attached to a Service"
+msgstr ""
+
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
msgstr ""
@@ -504,6 +508,10 @@ msgstr "Pedaço de dados deve seguir o pedaço de cortes"
msgid "Data too large for advertisement packet"
msgstr "Não é possível ajustar dados no pacote de anúncios."
+#: shared-bindings/bleio/Characteristic.c
+msgid "Descriptor is already attached to a Characteristic"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr ""
@@ -600,7 +608,7 @@ msgstr ""
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Central.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy
msgid "Failed to discover services"
msgstr "Não pode parar propaganda. status: 0x%02x"
@@ -619,17 +627,22 @@ msgstr "Não pode parar propaganda. status: 0x%02x"
msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+msgid "Failed to pair"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Characteristic.c
#, fuzzy, c-format
msgid "Failed to read CCCD value, err 0x%04x"
msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to read gatts value, err 0x%04x"
msgstr "Não é possível gravar o valor do atributo. status: 0x%02x"
@@ -659,6 +672,11 @@ msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
msgid "Failed to start connecting, error 0x%04x"
msgstr ""
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to start pairing, error 0x%04x"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Scanner.c
#, fuzzy, c-format
msgid "Failed to start scanning, err 0x%04x"
@@ -674,12 +692,12 @@ msgstr "Não pode parar propaganda. status: 0x%02x"
msgid "Failed to write CCCD, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Não é possível gravar o valor do atributo. status: 0x%02x"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to write gatts value, err 0x%04x"
msgstr "Não é possível gravar o valor do atributo. status: 0x%02x"
@@ -827,10 +845,18 @@ msgstr "Pinos inválidos"
msgid "Invalid polarity"
msgstr ""
+#: shared-bindings/bleio/Characteristic.c
+msgid "Invalid properties"
+msgstr ""
+
#: shared-bindings/microcontroller/__init__.c
msgid "Invalid run mode."
msgstr ""
+#: shared-module/bleio/Attribute.c
+msgid "Invalid security_mode"
+msgstr ""
+
#: shared-bindings/audiocore/Mixer.c
#, fuzzy
msgid "Invalid voice count"
@@ -950,8 +976,9 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/bleio/Peripheral.c
#, fuzzy
msgid "Not connected"
msgstr "Não é possível conectar-se ao AP"
@@ -1286,6 +1313,19 @@ msgstr ""
msgid "Unsupported pull value."
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Value length required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length != required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length > max_length"
+msgstr ""
+
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
msgstr ""
@@ -1376,10 +1416,6 @@ msgstr ""
msgid "attributes not supported yet"
msgstr "atributos ainda não suportados"
-#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "bad GATT role"
-msgstr ""
-
#: py/builtinevex.c
msgid "bad compile mode"
msgstr ""
@@ -1699,6 +1735,10 @@ msgstr ""
msgid "default 'except' must be last"
msgstr ""
+#: shared-bindings/bleio/Characteristic.c
+msgid "descriptors includes an object that is not a Descriptors"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
@@ -2039,6 +2079,12 @@ msgstr ""
msgid "math domain error"
msgstr ""
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+#, c-format
+msgid "max_length must be 0-%d when fixed_length is %s"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr ""
@@ -2138,8 +2184,8 @@ msgstr ""
msgid "non-Service found in services"
msgstr ""
-#: ports/nrf/common-hal/bleio/Central.c
-msgid "non-UUID found in service_uuids"
+#: ports/nrf/common-hal/bleio/__init__.c
+msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
#: py/compile.c
diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po
index c0537202c..a42f8bae4 100644
--- a/locale/zh_Latn_pinyin.po
+++ b/locale/zh_Latn_pinyin.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: circuitpython-cn\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2019-08-05 17:52-0700\n"
+"POT-Creation-Date: 2019-08-15 21:44-0400\n"
"PO-Revision-Date: 2019-04-13 10:10-0700\n"
"Last-Translator: hexthat\n"
"Language-Team: Chinese Hanyu Pinyin\n"
@@ -363,8 +363,8 @@ msgid "Can not use dotstar with %s"
msgstr "Wúfǎ yǔ dotstar yīqǐ shǐyòng %s"
#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "Can't set CCCD for local Characteristic"
-msgstr "Wúfǎ wéi běndì tèzhēng shèzhì CCCD"
+msgid "Can't set CCCD on local Characteristic"
+msgstr ""
#: shared-bindings/displayio/Bitmap.c shared-bindings/pulseio/PulseIn.c
msgid "Cannot delete values"
@@ -427,6 +427,10 @@ msgstr "Zìfú UUID bù fúhé fúwù UUID"
msgid "Characteristic already in use by another Service."
msgstr "Qítā fúwù bùmén yǐ shǐyòng de gōngnéng."
+#: shared-bindings/bleio/Service.c
+msgid "Characteristic is already attached to a Service"
+msgstr ""
+
#: shared-bindings/bleio/CharacteristicBuffer.c
msgid "CharacteristicBuffer writing not provided"
msgstr "Wèi tígōng zìfú huǎncún xiě rù"
@@ -501,6 +505,10 @@ msgstr "Shùjù kuài bìxū zūnxún fmt qū kuài"
msgid "Data too large for advertisement packet"
msgstr "Guǎnggào bāo de shùjù tài dà"
+#: shared-bindings/bleio/Characteristic.c
+msgid "Descriptor is already attached to a Characteristic"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid "Destination capacity is smaller than destination_length."
msgstr "Mùbiāo róngliàng xiǎoyú mùdì de_chángdù."
@@ -594,7 +602,7 @@ msgstr "Liánjiē shībài: Chāoshí"
msgid "Failed to continue scanning, err 0x%04x"
msgstr "Jìxù sǎomiáo shībài, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Central.c
+#: ports/nrf/common-hal/bleio/__init__.c
msgid "Failed to discover services"
msgstr "Fāxiàn fúwù shībài"
@@ -611,17 +619,22 @@ msgstr "Wúfǎ huòdé ruǎnjiàn shèbèi zhuàngtài"
msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr "Wúfǎ tōngzhī huò xiǎnshì shǔxìng zhí, err 0x%04x"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+msgid "Failed to pair"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Characteristic.c
#, c-format
msgid "Failed to read CCCD value, err 0x%04x"
msgstr "Dòu qǔ CCCD zhí, err 0x%04x shībài"
#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr "Dòu qǔ shǔxìng zhí shībài, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to read gatts value, err 0x%04x"
msgstr "Wúfǎ dòu qǔ gatts zhí, err 0x%04x"
@@ -651,6 +664,11 @@ msgstr "Qǐdòng guǎnggào shībài, err 0x%04x"
msgid "Failed to start connecting, error 0x%04x"
msgstr "Wúfǎ kāishǐ liánjiē, cuòwù 0x%04x"
+#: ports/nrf/common-hal/bleio/Peripheral.c
+#, c-format
+msgid "Failed to start pairing, error 0x%04x"
+msgstr ""
+
#: ports/nrf/common-hal/bleio/Scanner.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
@@ -666,12 +684,12 @@ msgstr "Wúfǎ tíngzhǐ guǎnggào, err 0x%04x"
msgid "Failed to write CCCD, err 0x%04x"
msgstr "Wúfǎ xiě rù CCCD, cuòwù 0x%04x"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to write attribute value, err 0x%04x"
msgstr "Xiě rù shǔxìng zhí shībài, err 0x%04x"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c
#, c-format
msgid "Failed to write gatts value, err 0x%04x"
msgstr "Xiě rù gatts zhí,err 0x%04x shībài"
@@ -819,10 +837,18 @@ msgstr "Wúxiào de yǐn jiǎo"
msgid "Invalid polarity"
msgstr "Wúxiào liǎng jí zhí"
+#: shared-bindings/bleio/Characteristic.c
+msgid "Invalid properties"
+msgstr ""
+
#: shared-bindings/microcontroller/__init__.c
msgid "Invalid run mode."
msgstr "Wúxiào de yùnxíng móshì."
+#: shared-module/bleio/Attribute.c
+msgid "Invalid security_mode"
+msgstr ""
+
#: shared-bindings/audiocore/Mixer.c
msgid "Invalid voice count"
msgstr "Wúxiào de yǔyīn jìshù"
@@ -945,8 +971,9 @@ msgstr "Shèbèi shàng méiyǒu kònggé"
msgid "No such file/directory"
msgstr "Méiyǒu cǐ lèi wénjiàn/mùlù"
-#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/__init__.c shared-bindings/bleio/Central.c
#: shared-bindings/bleio/CharacteristicBuffer.c
+#: shared-bindings/bleio/Peripheral.c
msgid "Not connected"
msgstr "Wèi liánjiē"
@@ -1292,6 +1319,19 @@ msgstr "Bù zhīchí de cāozuò"
msgid "Unsupported pull value."
msgstr "Bù zhīchí de lādòng zhí."
+#: ports/nrf/common-hal/bleio/Characteristic.c
+msgid "Value length required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length != required fixed length"
+msgstr ""
+
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+msgid "Value length > max_length"
+msgstr ""
+
#: py/emitnative.c
msgid "Viper functions don't currently support more than 4 arguments"
msgstr "Viper hánshù mùqián bù zhīchí chāoguò 4 gè cānshù"
@@ -1389,10 +1429,6 @@ msgstr "yòu cè xūyào shùzǔ/zì jié"
msgid "attributes not supported yet"
msgstr "shǔxìng shàngwèi zhīchí"
-#: ports/nrf/common-hal/bleio/Characteristic.c
-msgid "bad GATT role"
-msgstr "zǒng xiédìng de bùliáng juésè"
-
#: py/builtinevex.c
msgid "bad compile mode"
msgstr "biānyì móshì cuòwù"
@@ -1711,6 +1747,10 @@ msgstr "bù zhīchí xiǎoshù shù"
msgid "default 'except' must be last"
msgstr "mòrèn 'except' bìxū shì zuìhòu yīgè"
+#: shared-bindings/bleio/Characteristic.c
+msgid "descriptors includes an object that is not a Descriptors"
+msgstr ""
+
#: shared-bindings/audiobusio/PDMIn.c
msgid ""
"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8"
@@ -2052,6 +2092,12 @@ msgstr "dìtú huǎnchōng qū tài xiǎo"
msgid "math domain error"
msgstr "shùxué yù cuòwù"
+#: ports/nrf/common-hal/bleio/Characteristic.c
+#: ports/nrf/common-hal/bleio/Descriptor.c
+#, c-format
+msgid "max_length must be 0-%d when fixed_length is %s"
+msgstr ""
+
#: py/runtime.c
msgid "maximum recursion depth exceeded"
msgstr "chāochū zuìdà dìguī shēndù"
@@ -2151,8 +2197,8 @@ msgstr "méiyǒu cǐ shǔxìng"
msgid "non-Service found in services"
msgstr ""
-#: ports/nrf/common-hal/bleio/Central.c
-msgid "non-UUID found in service_uuids"
+#: ports/nrf/common-hal/bleio/__init__.c
+msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
#: py/compile.c
@@ -2674,6 +2720,9 @@ msgstr "líng bù"
#~ msgid "Can't connect in Peripheral mode"
#~ msgstr "Wúfǎ zài biānyuán móshì zhōng liánjiē"
+#~ msgid "Can't set CCCD for local Characteristic"
+#~ msgstr "Wúfǎ wéi běndì tèzhēng shèzhì CCCD"
+
#~ msgid "Data too large for the advertisement packet"
#~ msgstr "Guǎnggào bāo de shùjù tài dà"
@@ -2734,6 +2783,9 @@ msgstr "líng bù"
#~ msgid "UUID integer value not in range 0 to 0xffff"
#~ msgstr "UUID zhěngshù zhí bùzài fànwéi 0 zhì 0xffff"
+#~ msgid "bad GATT role"
+#~ msgstr "zǒng xiédìng de bùliáng juésè"
+
#~ msgid "expected a DigitalInOut"
#~ msgstr "qídài de DigitalInOut"
diff --git a/ports/nrf/boards/make-pins.py b/ports/nrf/boards/make-pins.py
deleted file mode 100644
index d1cfd5b70..000000000
--- a/ports/nrf/boards/make-pins.py
+++ /dev/null
@@ -1,208 +0,0 @@
-#!/usr/bin/env python
-"""Creates the pin file for the nRF5."""
-
-from __future__ import print_function
-
-import argparse
-import sys
-import csv
-
-
-def parse_port_pin(name_str):
- """Parses a string and returns a (port-num, pin-num) tuple."""
- if len(name_str) < 4:
- raise ValueError("Expecting pin name to be at least 5 charcters.")
- if name_str[0] != 'P':
- raise ValueError("Expecting pin name to start with P")
- if name_str[1] not in ('0', '1'):
- raise ValueError("Expecting pin port to be in 0 or 1")
- port = ord(name_str[1]) - ord('0')
- pin_str = name_str[3:]
- if not pin_str.isdigit():
- raise ValueError("Expecting numeric pin number.")
- return (port, int(pin_str))
-
-
-class Pin(object):
- """Holds the information associated with a pin."""
-
- def __init__(self, port, pin):
- self.port = port
- self.pin = pin
- self.adc_channel = '0'
- self.board_pin = False
-
- def cpu_pin_name(self):
- return 'P{:d}_{:02d}'.format(self.port, self.pin)
-
- def is_board_pin(self):
- return self.board_pin
-
- def set_is_board_pin(self):
- self.board_pin = True
-
- def parse_adc(self, adc_str):
- if (adc_str[:3] != 'AIN'):
- return
- self.adc_channel = 'SAADC_CH_PSELP_PSELP_AnalogInput%d' % int(adc_str[3])
-
- def print(self):
- print('const pin_obj_t pin_{:s} = PIN({:s}, {:d}, {:d}, {:s});'.format(
- self.cpu_pin_name(), self.cpu_pin_name(),
- self.port, self.pin, self.adc_channel))
-
- def print_header(self, hdr_file):
- hdr_file.write('extern const pin_obj_t pin_{:s};\n'.
- format(self.cpu_pin_name()))
-
-
-class NamedPin(object):
-
- def __init__(self, name, pin):
- self._name = name
- self._pin = pin
-
- def pin(self):
- return self._pin
-
- def name(self):
- return self._name
-
-
-class Pins(object):
-
- def __init__(self):
- self.cpu_pins = [] # list of NamedPin objects
- self.board_pins = [] # list of NamedPin objects
-
- def find_pin(self, port_num, pin_num):
- for named_pin in self.cpu_pins:
- pin = named_pin.pin()
- if pin.port == port_num and pin.pin == pin_num:
- return pin
-
- def parse_af_file(self, filename):
- with open(filename, 'r') as csvfile:
- rows = csv.reader(csvfile)
- for row in rows:
- try:
- (port_num, pin_num) = parse_port_pin(row[0])
- except:
- continue
- pin = Pin(port_num, pin_num)
- if len(row) > 1:
- pin.parse_adc(row[1])
- self.cpu_pins.append(NamedPin(pin.cpu_pin_name(), pin))
-
- def parse_board_file(self, filename):
- with open(filename, 'r') as csvfile:
- rows = csv.reader(csvfile)
- for row in rows:
- try:
- (port_num, pin_num) = parse_port_pin(row[1])
- except:
- continue
- pin = self.find_pin(port_num, pin_num)
- if pin:
- pin.set_is_board_pin()
- self.board_pins.append(NamedPin(row[0], pin))
-
- def print_named(self, label, named_pins):
- print('')
- print('STATIC const mp_rom_map_elem_t {:s}_table[] = {{'.format(label))
- for named_pin in named_pins:
- pin = named_pin.pin()
- if pin.is_board_pin():
- print(' {{ MP_ROM_QSTR(MP_QSTR_{:s}), MP_ROM_PTR(&pin_{:s}) }},'.format(named_pin.name(), pin.cpu_pin_name()))
- print('};')
- print('MP_DEFINE_CONST_DICT({:s}, {:s}_table);'.format(label, label))
-
- def print(self):
- for named_pin in self.cpu_pins:
- pin = named_pin.pin()
- if pin.is_board_pin():
- pin.print()
- self.print_named('mcu_pin_globals', self.cpu_pins)
- self.print_named('board_module_globals', self.board_pins)
-
- def print_header(self, hdr_filename):
- with open(hdr_filename, 'wt') as hdr_file:
- for named_pin in self.cpu_pins:
- pin = named_pin.pin()
- if pin.is_board_pin():
- pin.print_header(hdr_file)
-
- def print_qstr(self, qstr_filename):
- with open(qstr_filename, 'wt') as qstr_file:
- qstr_set = set([])
- for named_pin in self.cpu_pins:
- pin = named_pin.pin()
- if pin.is_board_pin():
- qstr_set |= set([named_pin.name()])
- for named_pin in self.board_pins:
- qstr_set |= set([named_pin.name()])
- for qstr in sorted(qstr_set):
- print('Q({})'.format(qstr), file=qstr_file)
-
-
-def main():
- parser = argparse.ArgumentParser(
- prog="make-pins.py",
- usage="%(prog)s [options] [command]",
- description="Generate board specific pin file"
- )
- parser.add_argument(
- "-a", "--af",
- dest="af_filename",
- help="Specifies the alternate function file for the chip",
- default="nrf_af.csv"
- )
- parser.add_argument(
- "-b", "--board",
- dest="board_filename",
- help="Specifies the board file",
- )
- parser.add_argument(
- "-p", "--prefix",
- dest="prefix_filename",
- help="Specifies beginning portion of generated pins file",
- default="nrf52_prefix.c"
- )
- parser.add_argument(
- "-q", "--qstr",
- dest="qstr_filename",
- help="Specifies name of generated qstr header file",
- default="build/pins_qstr.h"
- )
- parser.add_argument(
- "-r", "--hdr",
- dest="hdr_filename",
- help="Specifies name of generated pin header file",
- default="build/pins.h"
- )
- args = parser.parse_args(sys.argv[1:])
-
- pins = Pins()
-
- print('// This file was automatically generated by make-pins.py')
- print('//')
- if args.af_filename:
- print('// --af {:s}'.format(args.af_filename))
- pins.parse_af_file(args.af_filename)
-
- if args.board_filename:
- print('// --board {:s}'.format(args.board_filename))
- pins.parse_board_file(args.board_filename)
-
- if args.prefix_filename:
- print('// --prefix {:s}'.format(args.prefix_filename))
- print('')
- with open(args.prefix_filename, 'r') as prefix_file:
- print(prefix_file.read())
- pins.print()
- pins.print_header(args.hdr_filename)
- pins.print_qstr(args.qstr_filename)
-
-
-if __name__ == "__main__":
- main()
diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/bleio/Adapter.c
index 9d0912930..936dfcb9b 100644
--- a/ports/nrf/common-hal/bleio/Adapter.c
+++ b/ports/nrf/common-hal/bleio/Adapter.c
@@ -34,10 +34,11 @@
#include "nrfx_power.h"
#include "nrf_nvic.h"
#include "nrf_sdm.h"
+#include "py/objstr.h"
#include "py/runtime.h"
-#include "shared-bindings/bleio/Adapter.h"
-
#include "supervisor/usb.h"
+#include "shared-bindings/bleio/Adapter.h"
+#include "shared-bindings/bleio/Address.h"
STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) {
mp_raise_msg_varg(&mp_type_AssertionError,
@@ -132,20 +133,42 @@ bool common_hal_bleio_adapter_get_enabled(void) {
return is_enabled;
}
-void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address) {
- ble_gap_addr_t local_address;
+void get_address(ble_gap_addr_t *address) {
uint32_t err_code;
common_hal_bleio_adapter_set_enabled(true);
- err_code = sd_ble_gap_addr_get(&local_address);
+ err_code = sd_ble_gap_addr_get(address);
if (err_code != NRF_SUCCESS) {
mp_raise_OSError_msg(translate("Failed to get local address"));
}
+}
+
+bleio_address_obj_t *common_hal_bleio_adapter_get_address(void) {
+ common_hal_bleio_adapter_set_enabled(true);
+
+ ble_gap_addr_t local_address;
+ get_address(&local_address);
+
+ bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t);
+ address->base.type = &bleio_address_type;
+
+ common_hal_bleio_address_construct(address, local_address.addr, local_address.addr_type);
+ return address;
+}
+
+mp_obj_t common_hal_bleio_adapter_get_default_name(void) {
+ common_hal_bleio_adapter_set_enabled(true);
+
+ ble_gap_addr_t local_address;
+ get_address(&local_address);
+
+ char name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0, 0 };
- address->type = local_address.addr_type;
+ name[sizeof(name) - 4] = nibble_to_hex_lower[local_address.addr[1] >> 4 & 0xf];
+ name[sizeof(name) - 3] = nibble_to_hex_lower[local_address.addr[1] & 0xf];
+ name[sizeof(name) - 2] = nibble_to_hex_lower[local_address.addr[0] >> 4 & 0xf];
+ name[sizeof(name) - 1] = nibble_to_hex_lower[local_address.addr[0] & 0xf];
- mp_buffer_info_t buf_info;
- mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ);
- memcpy(address->bytes, buf_info.buf, NUM_BLEIO_ADDRESS_BYTES);
+ return mp_obj_new_str(name, sizeof(name));
}
diff --git a/ports/nrf/common-hal/bleio/Attribute.c b/ports/nrf/common-hal/bleio/Attribute.c
new file mode 100644
index 000000000..fd1e7538d
--- /dev/null
+++ b/ports/nrf/common-hal/bleio/Attribute.c
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ *
+ * 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/Attribute.h"
+
+// Convert a bleio security mode to a ble_gap_conn_sec_mode_t setting.
+void bleio_attribute_gatts_set_security_mode(ble_gap_conn_sec_mode_t *perm, bleio_attribute_security_mode_t security_mode) {
+ switch (security_mode) {
+ case SECURITY_MODE_NO_ACCESS:
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(perm);
+ break;
+
+ case SECURITY_MODE_OPEN:
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(perm);
+ break;
+
+ case SECURITY_MODE_ENC_NO_MITM:
+ BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(perm);
+ break;
+
+ case SECURITY_MODE_ENC_WITH_MITM:
+ BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(perm);
+ break;
+
+ case SECURITY_MODE_LESC_ENC_WITH_MITM:
+ BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(perm);
+ break;
+
+ case SECURITY_MODE_SIGNED_NO_MITM:
+ BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(perm);
+ break;
+
+ case SECURITY_MODE_SIGNED_WITH_MITM:
+ BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(perm);
+ break;
+ }
+}
diff --git a/shared-module/bleio/__init__.h b/ports/nrf/common-hal/bleio/Attribute.h
index 07d148594..44c2fdfa1 100644
--- a/shared-module/bleio/__init__.h
+++ b/ports/nrf/common-hal/bleio/Attribute.h
@@ -24,15 +24,9 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H
-#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H
+#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ATTRIBUTE_H
+#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ATTRIBUTE_H
-typedef enum {
- GATT_ROLE_NONE,
- GATT_ROLE_SERVER,
- GATT_ROLE_CLIENT,
-} gatt_role_t;
+// Nothing yet.
-extern void bleio_reset(void);
-
-#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_INIT_H
+#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ATTRIBUTE_H
diff --git a/ports/nrf/common-hal/bleio/Central.c b/ports/nrf/common-hal/bleio/Central.c
index d90737411..d771437d6 100644
--- a/ports/nrf/common-hal/bleio/Central.c
+++ b/ports/nrf/common-hal/bleio/Central.c
@@ -34,217 +34,9 @@
#include "nrf_soc.h"
#include "py/objstr.h"
#include "py/runtime.h"
+#include "shared-bindings/bleio/__init__.h"
#include "shared-bindings/bleio/Adapter.h"
-#include "shared-bindings/bleio/Characteristic.h"
#include "shared-bindings/bleio/Central.h"
-#include "shared-bindings/bleio/Descriptor.h"
-#include "shared-bindings/bleio/Service.h"
-#include "shared-bindings/bleio/UUID.h"
-
-static bleio_service_obj_t *m_char_discovery_service;
-static bleio_characteristic_obj_t *m_desc_discovery_characteristic;
-
-static volatile bool m_discovery_in_process;
-static volatile bool m_discovery_successful;
-
-// service_uuid may be NULL, to discover all services.
-STATIC bool discover_next_services(bleio_central_obj_t *self, uint16_t start_handle, ble_uuid_t *service_uuid) {
- m_discovery_successful = false;
- m_discovery_in_process = true;
-
- uint32_t err_code = sd_ble_gattc_primary_services_discover(self->conn_handle, start_handle, service_uuid);
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to discover services"));
- }
-
- // Wait for a discovery event.
- while (m_discovery_in_process) {
- MICROPY_VM_HOOK_LOOP;
- }
- return m_discovery_successful;
-}
-
-STATIC bool discover_next_characteristics(bleio_central_obj_t *self, bleio_service_obj_t *service, uint16_t start_handle) {
- m_char_discovery_service = service;
-
- ble_gattc_handle_range_t handle_range;
- handle_range.start_handle = start_handle;
- handle_range.end_handle = service->end_handle;
-
- m_discovery_successful = false;
- m_discovery_in_process = true;
-
- uint32_t err_code = sd_ble_gattc_characteristics_discover(self->conn_handle, &handle_range);
- if (err_code != NRF_SUCCESS) {
- return false;
- }
-
- // Wait for a discovery event.
- while (m_discovery_in_process) {
- MICROPY_VM_HOOK_LOOP;
- }
- return m_discovery_successful;
-}
-
-STATIC bool discover_next_descriptors(bleio_central_obj_t *self, bleio_characteristic_obj_t *characteristic, uint16_t start_handle, uint16_t end_handle) {
- m_desc_discovery_characteristic = characteristic;
-
- ble_gattc_handle_range_t handle_range;
- handle_range.start_handle = start_handle;
- handle_range.end_handle = end_handle;
-
- m_discovery_successful = false;
- m_discovery_in_process = true;
-
- uint32_t err_code = sd_ble_gattc_descriptors_discover(self->conn_handle, &handle_range);
- if (err_code != NRF_SUCCESS) {
- return false;
- }
-
- // Wait for a discovery event.
- while (m_discovery_in_process) {
- MICROPY_VM_HOOK_LOOP;
- }
- return m_discovery_successful;
-}
-
-STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, bleio_central_obj_t *central) {
- for (size_t i = 0; i < response->count; ++i) {
- ble_gattc_service_t *gattc_service = &response->services[i];
-
- bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t);
- service->base.type = &bleio_service_type;
-
- // Initialize several fields at once.
- common_hal_bleio_service_construct(service, NULL, mp_obj_new_list(0, NULL), false);
-
- service->device = MP_OBJ_FROM_PTR(central);
- service->start_handle = gattc_service->handle_range.start_handle;
- service->end_handle = gattc_service->handle_range.end_handle;
- service->handle = gattc_service->handle_range.start_handle;
-
- if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
- // Known service UUID.
- bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t);
- uuid->base.type = &bleio_uuid_type;
- bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid);
- service->uuid = uuid;
- service->device = MP_OBJ_FROM_PTR(central);
- } else {
- // The discovery response contained a 128-bit UUID that has not yet been registered with the
- // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
- // For now, just set the UUID to NULL.
- service->uuid = NULL;
- }
-
- mp_obj_list_append(central->service_list, service);
- }
-
- if (response->count > 0) {
- m_discovery_successful = true;
- }
- m_discovery_in_process = false;
-}
-
-STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio_central_obj_t *central) {
- for (size_t i = 0; i < response->count; ++i) {
- ble_gattc_char_t *gattc_char = &response->chars[i];
-
- bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t);
- characteristic->base.type = &bleio_characteristic_type;
-
- characteristic->descriptor_list = mp_obj_new_list(0, NULL);
-
- bleio_uuid_obj_t *uuid = NULL;
-
- if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
- // Known characteristic UUID.
- uuid = m_new_obj(bleio_uuid_obj_t);
- uuid->base.type = &bleio_uuid_type;
- bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid);
- } else {
- // The discovery response contained a 128-bit UUID that has not yet been registered with the
- // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
- // For now, just leave the UUID as NULL.
- }
-
- bleio_characteristic_properties_t props;
-
- props.broadcast = gattc_char->char_props.broadcast;
- props.indicate = gattc_char->char_props.indicate;
- props.notify = gattc_char->char_props.notify;
- props.read = gattc_char->char_props.read;
- props.write = gattc_char->char_props.write;
- props.write_no_response = gattc_char->char_props.write_wo_resp;
-
- // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler.
- common_hal_bleio_characteristic_construct(characteristic, uuid, props, mp_obj_new_list(0, NULL));
- characteristic->handle = gattc_char->handle_value;
- characteristic->service = m_char_discovery_service;
-
- mp_obj_list_append(m_char_discovery_service->characteristic_list, MP_OBJ_FROM_PTR(characteristic));
- }
-
- if (response->count > 0) {
- m_discovery_successful = true;
- }
- m_discovery_in_process = false;
-}
-
-STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, bleio_central_obj_t *central) {
- for (size_t i = 0; i < response->count; ++i) {
- ble_gattc_desc_t *gattc_desc = &response->descs[i];
-
- // Remember handles for certain well-known descriptors.
- switch (gattc_desc->uuid.uuid) {
- case DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION:
- m_desc_discovery_characteristic->cccd_handle = gattc_desc->handle;
- break;
-
- case DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION:
- m_desc_discovery_characteristic->sccd_handle = gattc_desc->handle;
- break;
-
- case DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION:
- m_desc_discovery_characteristic->user_desc_handle = gattc_desc->handle;
- break;
-
- default:
- // TODO: sd_ble_gattc_descriptors_discover() can return things that are not descriptors,
- // so ignore those.
- // https://devzone.nordicsemi.com/f/nordic-q-a/49500/sd_ble_gattc_descriptors_discover-is-returning-attributes-that-are-not-descriptors
- break;
- }
-
- bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t);
- descriptor->base.type = &bleio_descriptor_type;
-
- bleio_uuid_obj_t *uuid = NULL;
-
- if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
- // Known descriptor UUID.
- uuid = m_new_obj(bleio_uuid_obj_t);
- uuid->base.type = &bleio_uuid_type;
- bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid);
- } else {
- // The discovery response contained a 128-bit UUID that has not yet been registered with the
- // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
- // For now, just leave the UUID as NULL.
- }
-
- common_hal_bleio_descriptor_construct(descriptor, uuid);
- descriptor->handle = gattc_desc->handle;
- descriptor->characteristic = m_desc_discovery_characteristic;
-
- mp_obj_list_append(m_desc_discovery_characteristic->descriptor_list, MP_OBJ_FROM_PTR(descriptor));
- }
-
- if (response->count > 0) {
- m_discovery_successful = true;
- }
- m_discovery_in_process = false;
-}
STATIC void central_on_ble_evt(ble_evt_t *ble_evt, void *central_in) {
bleio_central_obj_t *central = (bleio_central_obj_t*)central_in;
@@ -262,20 +54,6 @@ STATIC void central_on_ble_evt(ble_evt_t *ble_evt, void *central_in) {
case BLE_GAP_EVT_DISCONNECTED:
central->conn_handle = BLE_CONN_HANDLE_INVALID;
- m_discovery_successful = false;
- m_discovery_in_process = false;
- break;
-
- case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
- on_primary_srv_discovery_rsp(&ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp, central);
- break;
-
- case BLE_GATTC_EVT_CHAR_DISC_RSP:
- on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, central);
- break;
-
- case BLE_GATTC_EVT_DESC_DISC_RSP:
- on_desc_discovery_rsp(&ble_evt->evt.gattc_evt.params.desc_disc_rsp, central);
break;
case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
@@ -288,7 +66,6 @@ STATIC void central_on_ble_evt(ble_evt_t *ble_evt, void *central_in) {
sd_ble_gap_conn_param_update(central->conn_handle, &request->conn_params);
break;
}
-
default:
// For debugging.
// mp_printf(&mp_plat_print, "Unhandled central event: 0x%04x\n", ble_evt->header.evt_id);
@@ -299,12 +76,11 @@ STATIC void central_on_ble_evt(ble_evt_t *ble_evt, void *central_in) {
void common_hal_bleio_central_construct(bleio_central_obj_t *self) {
common_hal_bleio_adapter_set_enabled(true);
- self->service_list = mp_obj_new_list(0, NULL);
- self->gatt_role = GATT_ROLE_CLIENT;
+ self->remote_services_list = mp_obj_new_list(0, NULL);
self->conn_handle = BLE_CONN_HANDLE_INVALID;
}
-void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout, mp_obj_t service_uuids) {
+void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout) {
common_hal_bleio_adapter_set_enabled(true);
ble_drv_add_event_handler(central_on_ble_evt, self);
@@ -345,109 +121,6 @@ void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_o
if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
mp_raise_OSError_msg(translate("Failed to connect: timeout"));
}
-
- // Connection successful.
- // Now discover services on the remote peripheral.
-
- if (service_uuids == mp_const_none) {
-
- // List of service UUID's not given, so discover all available services.
-
- uint16_t next_service_start_handle = BLE_GATT_HANDLE_START;
-
- while (discover_next_services(self, next_service_start_handle, MP_OBJ_NULL)) {
- // discover_next_services() appends to service_list.
-
- // Get the most recently discovered service, and then ask for services
- // whose handles start after the last attribute handle inside that service.
- const bleio_service_obj_t *service =
- MP_OBJ_TO_PTR(self->service_list->items[self->service_list->len - 1]);
- next_service_start_handle = service->end_handle + 1;
- }
- } else {
- mp_obj_iter_buf_t iter_buf;
- mp_obj_t iterable = mp_getiter(service_uuids, &iter_buf);
- mp_obj_t uuid_obj;
- while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
- if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
- mp_raise_ValueError(translate("non-UUID found in service_uuids"));
- }
- bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj);
-
- ble_uuid_t nrf_uuid;
- bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nrf_uuid);
-
- // Service might or might not be discovered; that's ok. Caller has to check
- // Central.remote_services to find out.
- // We only need to call this once for each service to discover.
- discover_next_services(self, BLE_GATT_HANDLE_START, &nrf_uuid);
- }
- }
-
-
- for (size_t service_idx = 0; service_idx < self->service_list->len; ++service_idx) {
- bleio_service_obj_t *service = MP_OBJ_TO_PTR(self->service_list->items[service_idx]);
-
- // Skip the service if it had an unknown (unregistered) UUID.
- if (service->uuid == NULL) {
- continue;
- }
-
- uint16_t next_char_start_handle = service->start_handle;
-
- // Stop when we go past the end of the range of handles for this service or
- // discovery call returns nothing.
- // discover_next_characteristics() appends to the characteristic_list.
- while (next_char_start_handle <= service->end_handle &&
- discover_next_characteristics(self, service, next_char_start_handle)) {
-
-
- // Get the most recently discovered characteristic, and then ask for characteristics
- // whose handles start after the last attribute handle inside that characteristic.
- const bleio_characteristic_obj_t *characteristic =
- MP_OBJ_TO_PTR(service->characteristic_list->items[service->characteristic_list->len - 1]);
- next_char_start_handle = characteristic->handle + 1;
- }
-
- // Got characteristics for this service. Now discover descriptors for each characteristic.
- size_t char_list_len = service->characteristic_list->len;
- for (size_t char_idx = 0; char_idx < char_list_len; ++char_idx) {
- bleio_characteristic_obj_t *characteristic =
- MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx]);
- const bool last_characteristic = char_idx == char_list_len - 1;
- bleio_characteristic_obj_t *next_characteristic = last_characteristic
- ? NULL
- : MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx + 1]);
-
- // Skip the characteristic if it had an unknown (unregistered) UUID.
- if (characteristic->uuid == NULL) {
- continue;
- }
-
- uint16_t next_desc_start_handle = characteristic->handle + 1;
-
- // Don't run past the end of this service or the beginning of the next characteristic.
- uint16_t next_desc_end_handle = next_characteristic == NULL
- ? service->end_handle
- : next_characteristic->handle - 1;
-
- // Stop when we go past the end of the range of handles for this service or
- // discovery call returns nothing.
- // discover_next_descriptors() appends to the descriptor_list.
- while (next_desc_start_handle <= service->end_handle &&
- next_desc_start_handle < next_desc_end_handle &&
- discover_next_descriptors(self, characteristic,
- next_desc_start_handle, next_desc_end_handle)) {
-
- // Get the most recently discovered descriptor, and then ask for descriptors
- // whose handles start after that descriptor's handle.
- const bleio_descriptor_obj_t *descriptor =
- MP_OBJ_TO_PTR(characteristic->descriptor_list->items[characteristic->descriptor_list->len - 1]);
- next_desc_start_handle = descriptor->handle + 1;
- }
- }
-
- }
}
void common_hal_bleio_central_disconnect(bleio_central_obj_t *self) {
@@ -458,6 +131,15 @@ bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self) {
return self->conn_handle != BLE_CONN_HANDLE_INVALID;
}
+mp_obj_tuple_t *common_hal_bleio_central_discover_remote_services(bleio_central_obj_t *self, mp_obj_t service_uuids_whitelist) {
+ common_hal_bleio_device_discover_remote_services(MP_OBJ_FROM_PTR(self), service_uuids_whitelist);
+ // Convert to a tuple and then clear the list so the callee will take ownership.
+ mp_obj_tuple_t *services_tuple = mp_obj_new_tuple(self->remote_services_list->len,
+ self->remote_services_list->items);
+ mp_obj_list_clear(self->remote_services_list);
+ return services_tuple;
+}
+
mp_obj_list_t *common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self) {
- return self->service_list;
+ return self->remote_services_list;
}
diff --git a/ports/nrf/common-hal/bleio/Central.h b/ports/nrf/common-hal/bleio/Central.h
index ac1670088..b7a9050b8 100644
--- a/ports/nrf/common-hal/bleio/Central.h
+++ b/ports/nrf/common-hal/bleio/Central.h
@@ -31,15 +31,14 @@
#include <stdbool.h>
#include "py/objlist.h"
-#include "shared-module/bleio/__init__.h"
#include "shared-module/bleio/Address.h"
typedef struct {
mp_obj_base_t base;
- gatt_role_t gatt_role;
volatile bool waiting_to_connect;
volatile uint16_t conn_handle;
- mp_obj_list_t *service_list;
+ // Services discovered after connecting to a remote peripheral.
+ mp_obj_list_t *remote_services_list;
} bleio_central_obj_t;
#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CENTRAL_H
diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c
index 17417a5e6..f8b6ce06c 100644
--- a/ports/nrf/common-hal/bleio/Characteristic.c
+++ b/ports/nrf/common-hal/bleio/Characteristic.c
@@ -25,29 +25,23 @@
* THE SOFTWARE.
*/
-#include <string.h>
-#include <stdio.h>
-
-#include "ble_drv.h"
-#include "ble_gatts.h"
-#include "nrf_soc.h"
-
#include "py/runtime.h"
-#include "common-hal/bleio/__init__.h"
-#include "common-hal/bleio/Characteristic.h"
-STATIC volatile bleio_characteristic_obj_t *m_read_characteristic;
+#include "shared-bindings/bleio/__init__.h"
+#include "shared-bindings/bleio/Characteristic.h"
+#include "shared-bindings/bleio/Descriptor.h"
+#include "shared-bindings/bleio/Service.h"
-STATIC uint16_t get_cccd(bleio_characteristic_obj_t *characteristic) {
- const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
+static volatile bleio_characteristic_obj_t *m_read_characteristic;
+
+STATIC uint16_t characteristic_get_cccd(uint16_t cccd_handle, uint16_t conn_handle) {
uint16_t cccd;
ble_gatts_value_t value = {
.p_value = (uint8_t*) &cccd,
.len = 2,
};
- const uint32_t err_code = sd_ble_gatts_value_get(conn_handle, characteristic->cccd_handle, &value);
-
+ const uint32_t err_code = sd_ble_gatts_value_get(conn_handle, cccd_handle, &value);
if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING) {
// CCCD is not set, so say that neither Notify nor Indicate is enabled.
@@ -59,64 +53,39 @@ STATIC uint16_t get_cccd(bleio_characteristic_obj_t *characteristic) {
return cccd;
}
-STATIC void gatts_read(bleio_characteristic_obj_t *characteristic) {
- // This might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because
- // we can still read and write the local value.
- const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
-
- mp_buffer_info_t bufinfo;
- ble_gatts_value_t gatts_value = {
- .p_value = NULL,
- .len = 0,
- };
-
- // Read once to find out what size buffer we need, then read again to fill buffer.
-
- uint32_t err_code = sd_ble_gatts_value_get(conn_handle, characteristic->handle, &gatts_value);
- if (err_code == NRF_SUCCESS) {
- characteristic->value_data = mp_obj_new_bytearray_of_zeros(gatts_value.len);
- mp_get_buffer_raise(characteristic->value_data, &bufinfo, MP_BUFFER_WRITE);
- gatts_value.p_value = bufinfo.buf;
-
- // Read again, with the correct size of buffer.
- err_code = sd_ble_gatts_value_get(conn_handle, characteristic->handle, &gatts_value);
- }
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to read gatts value, err 0x%04x"), err_code);
- }
-}
-
+STATIC void characteristic_on_gattc_read_rsp_evt(ble_evt_t *ble_evt, void *param) {
+ switch (ble_evt->header.evt_id) {
-STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
- // This might be BLE_CONN_HANDLE_INVALID if we're not conected, but that's OK, because
- // we can still read and write the local value.
- const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
+ // More events may be handled later, so keep this as a switch.
- ble_gatts_value_t gatts_value = {
- .p_value = bufinfo->buf,
- .len = bufinfo->len,
- };
+ case BLE_GATTC_EVT_READ_RSP: {
+ ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp;
+ if (m_read_characteristic) {
+ m_read_characteristic->value = mp_obj_new_bytearray(response->len, response->data);
+ }
+ // Indicate to busy-wait loop that we've read the attribute value.
+ m_read_characteristic = NULL;
+ break;
+ }
- const uint32_t err_code = sd_ble_gatts_value_set(conn_handle, characteristic->handle, &gatts_value);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to write gatts value, err 0x%04x"), err_code);
+ default:
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id);
+ break;
}
}
-STATIC void gatts_notify_indicate(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo, uint16_t hvx_type) {
+STATIC void characteristic_gatts_notify_indicate(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, uint16_t hvx_type) {
uint16_t hvx_len = bufinfo->len;
ble_gatts_hvx_params_t hvx_params = {
- .handle = characteristic->handle,
+ .handle = handle,
.type = hvx_type,
.offset = 0,
.p_len = &hvx_len,
.p_data = bufinfo->buf,
};
- const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
-
while (1) {
const uint32_t err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params);
if (err_code == NRF_SUCCESS) {
@@ -132,21 +101,17 @@ STATIC void gatts_notify_indicate(bleio_characteristic_obj_t *characteristic, mp
// Some real error has occurred.
mp_raise_OSError_msg_varg(translate("Failed to notify or indicate attribute value, err 0x%04x"), err_code);
}
-
-}
-
-STATIC void check_connected(uint16_t conn_handle) {
- if (conn_handle == BLE_CONN_HANDLE_INVALID) {
- mp_raise_OSError_msg(translate("Not connected"));
- }
}
-STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) {
+STATIC void characteristic_gattc_read(bleio_characteristic_obj_t *characteristic) {
const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
- check_connected(conn_handle);
+ common_hal_bleio_check_connected(conn_handle);
+ // Set to NULL in event loop after event.
m_read_characteristic = characteristic;
+ ble_drv_add_event_handler(characteristic_on_gattc_read_rsp_evt, characteristic);
+
const uint32_t err_code = sd_ble_gattc_read(conn_handle, characteristic->handle, 0);
if (err_code != NRF_SUCCESS) {
mp_raise_OSError_msg_varg(translate("Failed to read attribute value, err 0x%04x"), err_code);
@@ -155,126 +120,102 @@ STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) {
while (m_read_characteristic != NULL) {
MICROPY_VM_HOOK_LOOP;
}
-}
-
-STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) {
- const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(characteristic->service->device);
- check_connected(conn_handle);
-
- ble_gattc_write_params_t write_params = {
- .write_op = characteristic->props.write_no_response ? BLE_GATT_OP_WRITE_CMD : BLE_GATT_OP_WRITE_REQ,
- .handle = characteristic->handle,
- .p_value = bufinfo->buf,
- .len = bufinfo->len,
- };
-
- while (1) {
- uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params);
- if (err_code == NRF_SUCCESS) {
- break;
- }
-
- // Write with response will return NRF_ERROR_BUSY if the response has not been received.
- // Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending.
- if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) {
- // We could wait for an event indicating the write is complete, but just retrying is easier.
- MICROPY_VM_HOOK_LOOP;
- continue;
- }
-
- // Some real error occurred.
- mp_raise_OSError_msg_varg(translate("Failed to write attribute value, err 0x%04x"), err_code);
- }
+ ble_drv_remove_event_handler(characteristic_on_gattc_read_rsp_evt, characteristic);
}
-STATIC void characteristic_on_ble_evt(ble_evt_t *ble_evt, void *param) {
- switch (ble_evt->header.evt_id) {
-
- // More events may be handled later, so keep this as a switch.
-
- case BLE_GATTC_EVT_READ_RSP: {
- ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp;
- m_read_characteristic->value_data = mp_obj_new_bytearray(response->len, response->data);
- // Indicate to busy-wait loop that we've read the characteristic.
- m_read_characteristic = NULL;
- break;
- }
-
- // For debugging.
- default:
- // mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id);
- break;
- }
-
-}
-
-void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, mp_obj_list_t *descriptor_list) {
- self->service = mp_const_none;
+void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_obj_list_t *descriptor_list) {
+ self->service = MP_OBJ_NULL;
self->uuid = uuid;
- self->value_data = mp_const_none;
+ self->value = mp_const_empty_bytes;
+ self->handle = BLE_GATT_HANDLE_INVALID;
self->props = props;
+ self->read_perm = read_perm;
+ self->write_perm = write_perm;
self->descriptor_list = descriptor_list;
- self->handle = BLE_GATT_HANDLE_INVALID;
- ble_drv_add_event_handler(characteristic_on_ble_evt, self);
+ const mp_int_t max_length_max = fixed_length ? BLE_GATTS_FIX_ATTR_LEN_MAX : BLE_GATTS_VAR_ATTR_LEN_MAX;
+ if (max_length < 0 || max_length > max_length_max) {
+ mp_raise_ValueError_varg(translate("max_length must be 0-%d when fixed_length is %s"),
+ max_length_max, fixed_length ? "True" : "False");
+ }
+ self->max_length = max_length;
+ self->fixed_length = fixed_length;
+
+ for (size_t descriptor_idx = 0; descriptor_idx < descriptor_list->len; ++descriptor_idx) {
+ bleio_descriptor_obj_t *descriptor =
+ MP_OBJ_TO_PTR(descriptor_list->items[descriptor_idx]);
+ descriptor->characteristic = self;
+ }
}
mp_obj_list_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self) {
return self->descriptor_list;
}
+bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_characteristic_obj_t *self) {
+ return self->service;
+}
+
mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self) {
- switch (common_hal_bleio_device_get_gatt_role(self->service->device)) {
- case GATT_ROLE_CLIENT:
- gattc_read(self);
- break;
-
- case GATT_ROLE_SERVER:
- gatts_read(self);
- break;
-
- default:
- mp_raise_RuntimeError(translate("bad GATT role"));
- break;
+ // Do GATT operations only if this characteristic has been added to a registered service.
+ if (self->handle != BLE_GATT_HANDLE_INVALID) {
+ uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device);
+ if (common_hal_bleio_service_get_is_remote(self->service)) {
+ // self->value is set by evt handler.
+ characteristic_gattc_read(self);
+ } else {
+ self->value = common_hal_bleio_gatts_read(self->handle, conn_handle);
+ }
}
- return self->value_data;
+ return self->value;
}
void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) {
- bool sent = false;
- uint16_t cccd = 0;
+ // Do GATT operations only if this characteristic has been added to a registered service.
+ if (self->handle != BLE_GATT_HANDLE_INVALID) {
+ uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device);
+
+ if (common_hal_bleio_service_get_is_remote(self->service)) {
+ // Last argument is true if write-no-reponse desired.
+ common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo,
+ (self->props & CHAR_PROP_WRITE_NO_RESPONSE));
+ } else {
+ if (self->fixed_length && bufinfo->len != self->max_length) {
+ mp_raise_ValueError(translate("Value length required fixed length"));
+ }
+ if (bufinfo->len > self->max_length) {
+ mp_raise_ValueError(translate("Value length > max_length"));
+ }
+
+ bool sent = false;
+ uint16_t cccd = 0;
- switch (common_hal_bleio_device_get_gatt_role(self->service->device)) {
- case GATT_ROLE_SERVER:
- if (self->props.notify || self->props.indicate) {
- cccd = get_cccd(self);
+ const bool notify = self->props & CHAR_PROP_NOTIFY;
+ const bool indicate = self->props & CHAR_PROP_INDICATE;
+ if (notify | indicate) {
+ cccd = characteristic_get_cccd(self->cccd_handle, conn_handle);
}
+
// It's possible that both notify and indicate are set.
- if (self->props.notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) {
- gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_NOTIFICATION);
+ if (notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) {
+ characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_NOTIFICATION);
sent = true;
}
- if (self->props.indicate && (cccd & BLE_GATT_HVX_INDICATION)) {
- gatts_notify_indicate(self, bufinfo, BLE_GATT_HVX_INDICATION);
+ if (indicate && (cccd & BLE_GATT_HVX_INDICATION)) {
+ characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_INDICATION);
sent = true;
}
+
if (!sent) {
- gatts_write(self, bufinfo);
+ common_hal_bleio_gatts_write(self->handle, conn_handle, bufinfo);
}
- break;
-
- case GATT_ROLE_CLIENT:
- gattc_write(self, bufinfo);
- break;
-
- default:
- mp_raise_RuntimeError(translate("bad GATT role"));
- break;
+ }
}
-}
+ self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len);
+}
bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self) {
return self->uuid;
@@ -289,18 +230,17 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self,
mp_raise_ValueError(translate("No CCCD for this Characteristic"));
}
- if (common_hal_bleio_device_get_gatt_role(self->service->device) != GATT_ROLE_CLIENT) {
- mp_raise_ValueError(translate("Can't set CCCD for local Characteristic"));
+ if (!common_hal_bleio_service_get_is_remote(self->service)) {
+ mp_raise_ValueError(translate("Can't set CCCD on local Characteristic"));
}
+ const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device);
+ common_hal_bleio_check_connected(conn_handle);
+
uint16_t cccd_value =
(notify ? BLE_GATT_HVX_NOTIFICATION : 0) |
(indicate ? BLE_GATT_HVX_INDICATION : 0);
- const uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->service->device);
- check_connected(conn_handle);
-
-
ble_gattc_write_params_t write_params = {
.write_op = BLE_GATT_OP_WRITE_REQ,
.handle = self->cccd_handle,
diff --git a/ports/nrf/common-hal/bleio/Characteristic.h b/ports/nrf/common-hal/bleio/Characteristic.h
index 7cb227596..fb6a4c6ce 100644
--- a/ports/nrf/common-hal/bleio/Characteristic.h
+++ b/ports/nrf/common-hal/bleio/Characteristic.h
@@ -28,17 +28,23 @@
#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H
#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H
+#include "shared-bindings/bleio/Attribute.h"
+#include "shared-module/bleio/Characteristic.h"
#include "common-hal/bleio/Service.h"
#include "common-hal/bleio/UUID.h"
-#include "shared-module/bleio/Characteristic.h"
typedef struct {
mp_obj_base_t base;
+ // Will be MP_OBJ_NULL before being assigned to a Service.
bleio_service_obj_t *service;
bleio_uuid_obj_t *uuid;
- volatile mp_obj_t value_data;
+ mp_obj_t value;
+ uint16_t max_length;
+ bool fixed_length;
uint16_t handle;
bleio_characteristic_properties_t props;
+ bleio_attribute_security_mode_t read_perm;
+ bleio_attribute_security_mode_t write_perm;
mp_obj_list_t *descriptor_list;
uint16_t user_desc_handle;
uint16_t cccd_handle;
diff --git a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/bleio/CharacteristicBuffer.c
index 59eaaf02b..a6d834d7d 100644
--- a/ports/nrf/common-hal/bleio/CharacteristicBuffer.c
+++ b/ports/nrf/common-hal/bleio/CharacteristicBuffer.c
@@ -37,7 +37,7 @@
#include "tick.h"
-#include "common-hal/bleio/__init__.h"
+#include "shared-bindings/bleio/__init__.h"
#include "common-hal/bleio/CharacteristicBuffer.h"
STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) {
diff --git a/ports/nrf/common-hal/bleio/Descriptor.c b/ports/nrf/common-hal/bleio/Descriptor.c
index 005af6eaa..2a2019277 100644
--- a/ports/nrf/common-hal/bleio/Descriptor.c
+++ b/ports/nrf/common-hal/bleio/Descriptor.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
* Copyright (c) 2016 Glenn Ruben Bakke
*
@@ -26,17 +26,116 @@
* THE SOFTWARE.
*/
-#include "common-hal/bleio/Descriptor.h"
+#include "py/runtime.h"
+
+#include "shared-bindings/bleio/__init__.h"
+#include "shared-bindings/bleio/Descriptor.h"
+#include "shared-bindings/bleio/Service.h"
#include "shared-bindings/bleio/UUID.h"
-void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid) {
+static volatile bleio_descriptor_obj_t *m_read_descriptor;
+
+void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length) {
+ self->characteristic = MP_OBJ_NULL;
self->uuid = uuid;
-}
+ self->value = mp_const_empty_bytes;
+ self->handle = BLE_GATT_HANDLE_INVALID;
+ self->read_perm = read_perm;
+ self->write_perm = write_perm;
-mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self) {
- return self->handle;
+ const mp_int_t max_length_max = fixed_length ? BLE_GATTS_FIX_ATTR_LEN_MAX : BLE_GATTS_VAR_ATTR_LEN_MAX;
+ if (max_length < 0 || max_length > max_length_max) {
+ mp_raise_ValueError_varg(translate("max_length must be 0-%d when fixed_length is %s"),
+ max_length_max, fixed_length ? "True" : "False");
+ }
+ self->max_length = max_length;
+ self->fixed_length = fixed_length;
}
bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) {
return self->uuid;
}
+
+bleio_characteristic_obj_t *common_hal_bleio_descriptor_get_characteristic(bleio_descriptor_obj_t *self) {
+ return self->characteristic;
+}
+
+STATIC void descriptor_on_gattc_read_rsp_evt(ble_evt_t *ble_evt, void *param) {
+ switch (ble_evt->header.evt_id) {
+
+ // More events may be handled later, so keep this as a switch.
+
+ case BLE_GATTC_EVT_READ_RSP: {
+ ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp;
+ if (m_read_descriptor) {
+ m_read_descriptor->value = mp_obj_new_bytearray(response->len, response->data);
+ }
+ // Indicate to busy-wait loop that we've read the attribute value.
+ m_read_descriptor = NULL;
+ break;
+ }
+
+ default:
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Unhandled descriptor event: 0x%04x\n", ble_evt->header.evt_id);
+ break;
+ }
+}
+
+STATIC void descriptor_gattc_read(bleio_descriptor_obj_t *descriptor) {
+ const uint16_t conn_handle =
+ common_hal_bleio_device_get_conn_handle(descriptor->characteristic->service->device);
+ common_hal_bleio_check_connected(conn_handle);
+
+ // Set to NULL in event loop after event.
+ m_read_descriptor = descriptor;
+
+ ble_drv_add_event_handler(descriptor_on_gattc_read_rsp_evt, descriptor);
+
+ const uint32_t err_code = sd_ble_gattc_read(conn_handle, descriptor->handle, 0);
+ if (err_code != NRF_SUCCESS) {
+ mp_raise_OSError_msg_varg(translate("Failed to read attribute value, err 0x%04x"), err_code);
+ }
+
+ while (m_read_descriptor != NULL) {
+ MICROPY_VM_HOOK_LOOP;
+ }
+
+ ble_drv_remove_event_handler(descriptor_on_gattc_read_rsp_evt, descriptor);
+}
+
+mp_obj_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self) {
+ // Do GATT operations only if this descriptor has been registered
+ if (self->handle != BLE_GATT_HANDLE_INVALID) {
+ if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) {
+ descriptor_gattc_read(self);
+ } else {
+ self->value = common_hal_bleio_gatts_read(
+ self->handle, common_hal_bleio_device_get_conn_handle(self->characteristic->service->device));
+ }
+ }
+
+ return self->value;
+}
+
+void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buffer_info_t *bufinfo) {
+ // Do GATT operations only if this descriptor has been registered.
+ if (self->handle != BLE_GATT_HANDLE_INVALID) {
+ uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(self->characteristic->service->device);
+ if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) {
+ // false means WRITE_REQ, not write-no-response
+ common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo, false);
+ } else {
+ if (self->fixed_length && bufinfo->len != self->max_length) {
+ mp_raise_ValueError(translate("Value length != required fixed length"));
+ }
+ if (bufinfo->len > self->max_length) {
+ mp_raise_ValueError(translate("Value length > max_length"));
+ }
+
+ common_hal_bleio_gatts_write(self->handle, conn_handle, bufinfo);
+ }
+ }
+
+ self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len);
+}
diff --git a/ports/nrf/common-hal/bleio/Descriptor.h b/ports/nrf/common-hal/bleio/Descriptor.h
index b7af6a42f..6db4d7be3 100644
--- a/ports/nrf/common-hal/bleio/Descriptor.h
+++ b/ports/nrf/common-hal/bleio/Descriptor.h
@@ -30,14 +30,21 @@
#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H
#include "py/obj.h"
-#include "common-hal/bleio/Characteristic.h"
+
+#include "shared-bindings/bleio/Characteristic.h"
#include "common-hal/bleio/UUID.h"
typedef struct {
mp_obj_base_t base;
- uint16_t handle;
+ // Will be MP_OBJ_NULL before being assigned to a Characteristic.
bleio_characteristic_obj_t *characteristic;
bleio_uuid_obj_t *uuid;
+ mp_obj_t value;
+ uint16_t max_length;
+ bool fixed_length;
+ uint16_t handle;
+ bleio_attribute_security_mode_t read_perm;
+ bleio_attribute_security_mode_t write_perm;
} bleio_descriptor_obj_t;
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H
diff --git a/ports/nrf/common-hal/bleio/Peripheral.c b/ports/nrf/common-hal/bleio/Peripheral.c
index 608bd1342..ed35516fc 100644
--- a/ports/nrf/common-hal/bleio/Peripheral.c
+++ b/ports/nrf/common-hal/bleio/Peripheral.c
@@ -36,12 +36,12 @@
#include "py/objlist.h"
#include "py/objstr.h"
#include "py/runtime.h"
+#include "shared-bindings/bleio/__init__.h"
#include "shared-bindings/bleio/Adapter.h"
#include "shared-bindings/bleio/Characteristic.h"
#include "shared-bindings/bleio/Peripheral.h"
#include "shared-bindings/bleio/Service.h"
#include "shared-bindings/bleio/UUID.h"
-#include "common-hal/bleio/Service.h"
#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS)
#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(300, UNIT_0_625_MS)
@@ -52,6 +52,19 @@
#define BLE_ADV_AD_TYPE_FIELD_SIZE 1
#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1
+static const ble_gap_sec_params_t pairing_sec_params = {
+ .bond = 0, // TODO: add bonding
+ .mitm = 0,
+ .lesc = 0,
+ .keypress = 0,
+ .oob = 0,
+ .io_caps = BLE_GAP_IO_CAPS_NONE,
+ .min_key_size = 7,
+ .max_key_size = 16,
+ .kdist_own = { .enc = 1, .id = 1},
+ .kdist_peer = { .enc = 1, .id = 1},
+};
+
STATIC void check_data_fit(size_t data_len) {
if (data_len > BLE_GAP_ADV_SET_DATA_SIZE_MAX) {
mp_raise_ValueError(translate("Data too large for advertisement packet"));
@@ -61,6 +74,9 @@ STATIC void check_data_fit(size_t data_len) {
STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
bleio_peripheral_obj_t *self = (bleio_peripheral_obj_t*)self_in;
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Peripheral event: 0x%04x\n", ble_evt->header.evt_id);
+
switch (ble_evt->header.evt_id) {
case BLE_GAP_EVT_CONNECTED: {
// Central has connected.
@@ -89,10 +105,6 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
// Someday may handle timeouts or limit reached.
break;
- case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
- sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
- break;
-
case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: {
ble_gap_evt_conn_param_update_request_t *request =
&ble_evt->evt.gap_evt.params.conn_param_update_request;
@@ -113,6 +125,47 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
break;
+ case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
+ sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_SUCCESS, &pairing_sec_params, NULL);
+ break;
+
+ case BLE_GAP_EVT_LESC_DHKEY_REQUEST:
+ // TODO for LESC pairing:
+ // sd_ble_gap_lesc_dhkey_reply(...);
+ break;
+
+ case BLE_GAP_EVT_AUTH_STATUS: {
+ // Pairing process completed
+ ble_gap_evt_auth_status_t* status = &ble_evt->evt.gap_evt.params.auth_status;
+ if (BLE_GAP_SEC_STATUS_SUCCESS == status->auth_status) {
+ // mp_printf(&mp_plat_print, "Pairing succeeded, status: 0x%04x\n", status->auth_status);
+ self->pair_status = PAIR_PAIRED;
+ } else {
+ // mp_printf(&mp_plat_print, "Pairing failed, status: 0x%04x\n", status->auth_status);
+ self->pair_status = PAIR_NOT_PAIRED;
+ }
+ break;
+ }
+
+ case BLE_GAP_EVT_CONN_SEC_UPDATE: {
+ ble_gap_conn_sec_t* conn_sec = &ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec;
+ if (conn_sec->sec_mode.sm <= 1 && conn_sec->sec_mode.lv <= 1) {
+ // Security setup did not succeed:
+ // mode 0, level 0 means no access
+ // mode 1, level 1 means open link
+ // mode >=1 and/or level >=1 means encryption is set up
+ self->pair_status = PAIR_NOT_PAIRED;
+ } else {
+ // TODO: see Bluefruit lib
+ // if ( !bond_load_cccd(_role, _conn_hdl, _ediv) ) {
+ // sd_ble_gatts_sys_attr_set(_conn_hdl, NULL, 0, 0);
+ // }
+ self->pair_status = PAIR_PAIRED;
+ }
+ break;
+ }
+
+
default:
// For debugging.
// mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id);
@@ -120,20 +173,22 @@ STATIC void peripheral_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
}
}
-void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_list_t *service_list, mp_obj_t name) {
+void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_list_t *services_list, mp_obj_t name) {
common_hal_bleio_adapter_set_enabled(true);
- self->service_list = service_list;
+ self->services_list = services_list;
+ // Used only for discovery when acting as a client.
+ self->remote_services_list = mp_obj_new_list(0, NULL);
self->name = name;
- self->gatt_role = GATT_ROLE_SERVER;
self->conn_handle = BLE_CONN_HANDLE_INVALID;
self->adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
+ self->pair_status = PAIR_NOT_PAIRED;
// Add all the services.
- for (size_t service_idx = 0; service_idx < service_list->len; ++service_idx) {
- bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[service_idx]);
+ for (size_t service_idx = 0; service_idx < services_list->len; ++service_idx) {
+ bleio_service_obj_t *service = MP_OBJ_TO_PTR(services_list->items[service_idx]);
service->device = MP_OBJ_FROM_PTR(self);
@@ -156,8 +211,8 @@ void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_
}
-mp_obj_list_t *common_hal_bleio_peripheral_get_service_list(bleio_peripheral_obj_t *self) {
- return self->service_list;
+mp_obj_list_t *common_hal_bleio_peripheral_get_services(bleio_peripheral_obj_t *self) {
+ return self->services_list;
}
bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self) {
@@ -247,3 +302,30 @@ void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *self)
void common_hal_bleio_peripheral_disconnect(bleio_peripheral_obj_t *self) {
sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
}
+
+mp_obj_tuple_t *common_hal_bleio_peripheral_discover_remote_services(bleio_peripheral_obj_t *self, mp_obj_t service_uuids_whitelist) {
+ common_hal_bleio_device_discover_remote_services(MP_OBJ_FROM_PTR(self), service_uuids_whitelist);
+ // Convert to a tuple and then clear the list so the callee will take ownership.
+ mp_obj_tuple_t *services_tuple = mp_obj_new_tuple(self->remote_services_list->len,
+ self->remote_services_list->items);
+ mp_obj_list_clear(self->remote_services_list);
+ return services_tuple;
+}
+
+void common_hal_bleio_peripheral_pair(bleio_peripheral_obj_t *self) {
+ self->pair_status = PAIR_WAITING;
+
+ uint32_t err_code = sd_ble_gap_authenticate(self->conn_handle, &pairing_sec_params);
+
+ if (err_code != NRF_SUCCESS) {
+ mp_raise_OSError_msg_varg(translate("Failed to start pairing, error 0x%04x"), err_code);
+ }
+
+ while (self->pair_status == PAIR_WAITING) {
+ MICROPY_VM_HOOK_LOOP;
+ }
+
+ if (self->pair_status == PAIR_NOT_PAIRED) {
+ mp_raise_OSError_msg(translate("Failed to pair"));
+ }
+}
diff --git a/ports/nrf/common-hal/bleio/Peripheral.h b/ports/nrf/common-hal/bleio/Peripheral.h
index 2a1251715..e75a1641a 100644
--- a/ports/nrf/common-hal/bleio/Peripheral.h
+++ b/ports/nrf/common-hal/bleio/Peripheral.h
@@ -35,22 +35,29 @@
#include "py/obj.h"
#include "py/objlist.h"
-#include "shared-module/bleio/__init__.h"
#include "shared-module/bleio/Address.h"
+typedef enum {
+ PAIR_NOT_PAIRED,
+ PAIR_WAITING,
+ PAIR_PAIRED,
+} pair_status_t;
+
typedef struct {
mp_obj_base_t base;
mp_obj_t name;
- gatt_role_t gatt_role;
volatile uint16_t conn_handle;
- mp_obj_list_t *service_list;
+ // Services provided by this peripheral.
+ mp_obj_list_t *services_list;
+ // Remote services discovered when this peripheral is acting as a client.
+ mp_obj_list_t *remote_services_list;
// The advertising data and scan response buffers are held by us, not by the SD, so we must
// maintain them and not change it. If we need to change the contents during advertising,
// there are tricks to get the SD to notice (see DevZone - TBS).
uint8_t* advertising_data;
uint8_t* scan_response_data;
uint8_t adv_handle;
-
+ pair_status_t pair_status;
} bleio_peripheral_obj_t;
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PERIPHERAL_H
diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c
index b6fcde827..a7a3a6db0 100644
--- a/ports/nrf/common-hal/bleio/Service.c
+++ b/ports/nrf/common-hal/bleio/Service.c
@@ -29,8 +29,8 @@
#include "ble.h"
#include "py/runtime.h"
#include "common-hal/bleio/__init__.h"
-#include "common-hal/bleio/Characteristic.h"
#include "shared-bindings/bleio/Characteristic.h"
+#include "shared-bindings/bleio/Descriptor.h"
#include "shared-bindings/bleio/Service.h"
#include "shared-bindings/bleio/Adapter.h"
@@ -39,6 +39,7 @@ void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_ob
self->handle = 0xFFFF;
self->uuid = uuid;
self->characteristic_list = characteristic_list;
+ self->is_remote = false;
self->is_secondary = is_secondary;
for (size_t characteristic_idx = 0; characteristic_idx < characteristic_list->len; ++characteristic_idx) {
@@ -46,7 +47,6 @@ void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_ob
MP_OBJ_TO_PTR(characteristic_list->items[characteristic_idx]);
characteristic->service = self;
}
-
}
bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self) {
@@ -57,6 +57,10 @@ mp_obj_list_t *common_hal_bleio_service_get_characteristic_list(bleio_service_ob
return self->characteristic_list;
}
+bool common_hal_bleio_service_get_is_remote(bleio_service_obj_t *self) {
+ return self->is_remote;
+}
+
bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self) {
return self->is_secondary;
}
@@ -68,13 +72,17 @@ void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self)
bleio_characteristic_obj_t *characteristic =
MP_OBJ_TO_PTR(self->characteristic_list->items[characteristic_idx]);
+ if (characteristic->handle != BLE_GATT_HANDLE_INVALID) {
+ mp_raise_ValueError(translate("Characteristic already in use by another Service."));
+ }
+
ble_gatts_char_md_t char_md = {
- .char_props.broadcast = characteristic->props.broadcast,
- .char_props.read = characteristic->props.read,
- .char_props.write_wo_resp = characteristic->props.write_no_response,
- .char_props.write = characteristic->props.write,
- .char_props.notify = characteristic->props.notify,
- .char_props.indicate = characteristic->props.indicate,
+ .char_props.broadcast = (characteristic->props & CHAR_PROP_BROADCAST) ? 1 : 0,
+ .char_props.read = (characteristic->props & CHAR_PROP_READ) ? 1 : 0,
+ .char_props.write_wo_resp = (characteristic->props & CHAR_PROP_WRITE_NO_RESPONSE) ? 1 : 0,
+ .char_props.write = (characteristic->props & CHAR_PROP_WRITE) ? 1 : 0,
+ .char_props.notify = (characteristic->props & CHAR_PROP_NOTIFY) ? 1 : 0,
+ .char_props.indicate = (characteristic->props & CHAR_PROP_INDICATE) ? 1 : 0,
};
ble_gatts_attr_md_t cccd_md = {
@@ -88,39 +96,74 @@ void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self)
char_md.p_cccd_md = &cccd_md;
}
- ble_uuid_t uuid;
- bleio_uuid_convert_to_nrf_ble_uuid(characteristic->uuid, &uuid);
+ ble_uuid_t char_uuid;
+ bleio_uuid_convert_to_nrf_ble_uuid(characteristic->uuid, &char_uuid);
- ble_gatts_attr_md_t attr_md = {
+ ble_gatts_attr_md_t char_attr_md = {
.vloc = BLE_GATTS_VLOC_STACK,
- .vlen = 1,
+ .vlen = !characteristic->fixed_length,
};
- BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
- BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&char_attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&char_attr_md.write_perm);
+
+ mp_buffer_info_t char_value_bufinfo;
+ mp_get_buffer_raise(characteristic->value, &char_value_bufinfo, MP_BUFFER_READ);
- ble_gatts_attr_t attr_char_value = {
- .p_uuid = &uuid,
- .p_attr_md = &attr_md,
- .init_len = sizeof(uint8_t),
- .max_len = GATT_MAX_DATA_LENGTH,
+ ble_gatts_attr_t char_attr = {
+ .p_uuid = &char_uuid,
+ .p_attr_md = &char_attr_md,
+ .init_len = char_value_bufinfo.len,
+ .p_value = char_value_bufinfo.buf,
+ .init_offs = 0,
+ .max_len = characteristic->max_length,
};
- ble_gatts_char_handles_t handles;
+ ble_gatts_char_handles_t char_handles;
uint32_t err_code;
- err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &attr_char_value, &handles);
+ err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &char_attr, &char_handles);
if (err_code != NRF_SUCCESS) {
mp_raise_OSError_msg_varg(translate("Failed to add characteristic, err 0x%04x"), err_code);
}
- if (characteristic->handle != BLE_GATT_HANDLE_INVALID) {
- mp_raise_ValueError(translate("Characteristic already in use by another Service."));
- }
+ characteristic->user_desc_handle = char_handles.user_desc_handle;
+ characteristic->cccd_handle = char_handles.cccd_handle;
+ characteristic->sccd_handle = char_handles.sccd_handle;
+ characteristic->handle = char_handles.value_handle;
- characteristic->user_desc_handle = handles.user_desc_handle;
- characteristic->cccd_handle = handles.cccd_handle;
- characteristic->sccd_handle = handles.sccd_handle;
- characteristic->handle = handles.value_handle;
- }
+ // Add the descriptors for this characteristic.
+ for (size_t descriptor_idx = 0; descriptor_idx < characteristic->descriptor_list->len; ++descriptor_idx) {
+ bleio_descriptor_obj_t *descriptor =
+ MP_OBJ_TO_PTR(characteristic->descriptor_list->items[descriptor_idx]);
+
+ ble_uuid_t desc_uuid;
+ bleio_uuid_convert_to_nrf_ble_uuid(descriptor->uuid, &desc_uuid);
+
+ ble_gatts_attr_md_t desc_attr_md = {
+ // Data passed is not in a permanent location and should be copied.
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .vlen = !descriptor->fixed_length,
+ };
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&desc_attr_md.write_perm);
+
+ mp_buffer_info_t desc_value_bufinfo;
+ mp_get_buffer_raise(descriptor->value, &desc_value_bufinfo, MP_BUFFER_READ);
+
+ ble_gatts_attr_t desc_attr = {
+ .p_uuid = &desc_uuid,
+ .p_attr_md = &desc_attr_md,
+ .init_len = desc_value_bufinfo.len,
+ .p_value = desc_value_bufinfo.buf,
+ .init_offs = 0,
+ .max_len = descriptor->max_length,
+ };
+
+ err_code = sd_ble_gatts_descriptor_add(characteristic->handle, &desc_attr, &descriptor->handle);
+
+ } // loop over descriptors
+
+ } // loop over characteristics
}
diff --git a/ports/nrf/common-hal/bleio/Service.h b/ports/nrf/common-hal/bleio/Service.h
index 583593fb8..03ac2bca8 100644
--- a/ports/nrf/common-hal/bleio/Service.h
+++ b/ports/nrf/common-hal/bleio/Service.h
@@ -35,6 +35,8 @@ typedef struct {
mp_obj_base_t base;
// Handle for this service.
uint16_t handle;
+ // True if created during discovery.
+ bool is_remote;
bool is_secondary;
bleio_uuid_obj_t *uuid;
// May be a Peripheral, Central, etc.
diff --git a/ports/nrf/common-hal/bleio/__init__.c b/ports/nrf/common-hal/bleio/__init__.c
index 2dba5780c..2e26ac07d 100644
--- a/ports/nrf/common-hal/bleio/__init__.c
+++ b/ports/nrf/common-hal/bleio/__init__.c
@@ -26,12 +26,24 @@
* THE SOFTWARE.
*/
+#include "py/runtime.h"
#include "shared-bindings/bleio/__init__.h"
#include "shared-bindings/bleio/Adapter.h"
#include "shared-bindings/bleio/Central.h"
+#include "shared-bindings/bleio/Characteristic.h"
+#include "shared-bindings/bleio/Descriptor.h"
#include "shared-bindings/bleio/Peripheral.h"
+#include "shared-bindings/bleio/Service.h"
+#include "shared-bindings/bleio/UUID.h"
+
#include "common-hal/bleio/__init__.h"
+static volatile bool m_discovery_in_process;
+static volatile bool m_discovery_successful;
+
+static bleio_service_obj_t *m_char_discovery_service;
+static bleio_characteristic_obj_t *m_desc_discovery_characteristic;
+
// Turn off BLE on a reset or reload.
void bleio_reset() {
if (common_hal_bleio_adapter_get_enabled()) {
@@ -47,13 +59,9 @@ const super_adapter_obj_t common_hal_bleio_adapter_obj = {
},
};
-gatt_role_t common_hal_bleio_device_get_gatt_role(mp_obj_t device) {
- if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) {
- return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->gatt_role;
- } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) {
- return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->gatt_role;
- } else {
- return GATT_ROLE_NONE;
+void common_hal_bleio_check_connected(uint16_t conn_handle) {
+ if (conn_handle == BLE_CONN_HANDLE_INVALID) {
+ mp_raise_OSError_msg(translate("Not connected"));
}
}
@@ -63,6 +71,433 @@ uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device) {
} else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) {
return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle;
} else {
- return 0;
+ return BLE_CONN_HANDLE_INVALID;
+ }
+}
+
+mp_obj_list_t *common_hal_bleio_device_get_remote_services_list(mp_obj_t device) {
+ if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) {
+ return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->remote_services_list;
+ } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) {
+ return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->remote_services_list;
+ } else {
+ return NULL;
+ }
+}
+
+// service_uuid may be NULL, to discover all services.
+STATIC bool discover_next_services(mp_obj_t device, uint16_t start_handle, ble_uuid_t *service_uuid) {
+ m_discovery_successful = false;
+ m_discovery_in_process = true;
+
+ uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(device);
+ uint32_t err_code = sd_ble_gattc_primary_services_discover(conn_handle, start_handle, service_uuid);
+
+ if (err_code != NRF_SUCCESS) {
+ mp_raise_OSError_msg(translate("Failed to discover services"));
+ }
+
+ // Wait for a discovery event.
+ while (m_discovery_in_process) {
+ MICROPY_VM_HOOK_LOOP;
+ }
+ return m_discovery_successful;
+}
+
+STATIC bool discover_next_characteristics(mp_obj_t device, bleio_service_obj_t *service, uint16_t start_handle) {
+ m_char_discovery_service = service;
+
+ ble_gattc_handle_range_t handle_range;
+ handle_range.start_handle = start_handle;
+ handle_range.end_handle = service->end_handle;
+
+ m_discovery_successful = false;
+ m_discovery_in_process = true;
+
+ uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(device);
+ uint32_t err_code = sd_ble_gattc_characteristics_discover(conn_handle, &handle_range);
+ if (err_code != NRF_SUCCESS) {
+ return false;
+ }
+
+ // Wait for a discovery event.
+ while (m_discovery_in_process) {
+ MICROPY_VM_HOOK_LOOP;
+ }
+ return m_discovery_successful;
+}
+
+STATIC bool discover_next_descriptors(mp_obj_t device, bleio_characteristic_obj_t *characteristic, uint16_t start_handle, uint16_t end_handle) {
+ m_desc_discovery_characteristic = characteristic;
+
+ ble_gattc_handle_range_t handle_range;
+ handle_range.start_handle = start_handle;
+ handle_range.end_handle = end_handle;
+
+ m_discovery_successful = false;
+ m_discovery_in_process = true;
+
+ uint16_t conn_handle = common_hal_bleio_device_get_conn_handle(device);
+ uint32_t err_code = sd_ble_gattc_descriptors_discover(conn_handle, &handle_range);
+ if (err_code != NRF_SUCCESS) {
+ return false;
}
+
+ // Wait for a discovery event.
+ while (m_discovery_in_process) {
+ MICROPY_VM_HOOK_LOOP;
+ }
+ return m_discovery_successful;
+}
+
+STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, mp_obj_t device) {
+ for (size_t i = 0; i < response->count; ++i) {
+ ble_gattc_service_t *gattc_service = &response->services[i];
+
+ bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t);
+ service->base.type = &bleio_service_type;
+
+ // Initialize several fields at once.
+ common_hal_bleio_service_construct(service, NULL, mp_obj_new_list(0, NULL), false);
+
+ service->device = device;
+ service->is_remote = true;
+ service->start_handle = gattc_service->handle_range.start_handle;
+ service->end_handle = gattc_service->handle_range.end_handle;
+ service->handle = gattc_service->handle_range.start_handle;
+
+ if (gattc_service->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
+ // Known service UUID.
+ bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t);
+ uuid->base.type = &bleio_uuid_type;
+ bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_service->uuid);
+ service->uuid = uuid;
+ } else {
+ // The discovery response contained a 128-bit UUID that has not yet been registered with the
+ // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
+ // For now, just set the UUID to NULL.
+ service->uuid = NULL;
+ }
+
+ mp_obj_list_append(common_hal_bleio_device_get_remote_services_list(device), service);
+ }
+
+ if (response->count > 0) {
+ m_discovery_successful = true;
+ }
+ m_discovery_in_process = false;
+}
+
+STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, mp_obj_t device) {
+ for (size_t i = 0; i < response->count; ++i) {
+ ble_gattc_char_t *gattc_char = &response->chars[i];
+
+ bleio_characteristic_obj_t *characteristic = m_new_obj(bleio_characteristic_obj_t);
+ characteristic->base.type = &bleio_characteristic_type;
+
+ bleio_uuid_obj_t *uuid = NULL;
+
+ if (gattc_char->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
+ // Known characteristic UUID.
+ uuid = m_new_obj(bleio_uuid_obj_t);
+ uuid->base.type = &bleio_uuid_type;
+ bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_char->uuid);
+ } else {
+ // The discovery response contained a 128-bit UUID that has not yet been registered with the
+ // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
+ // For now, just leave the UUID as NULL.
+ }
+
+ bleio_characteristic_properties_t props =
+ (gattc_char->char_props.broadcast ? CHAR_PROP_BROADCAST : 0) |
+ (gattc_char->char_props.indicate ? CHAR_PROP_INDICATE : 0) |
+ (gattc_char->char_props.notify ? CHAR_PROP_NOTIFY : 0) |
+ (gattc_char->char_props.read ? CHAR_PROP_READ : 0) |
+ (gattc_char->char_props.write ? CHAR_PROP_WRITE : 0) |
+ (gattc_char->char_props.write_wo_resp ? CHAR_PROP_WRITE_NO_RESPONSE : 0);
+
+ // Call common_hal_bleio_characteristic_construct() to initalize some fields and set up evt handler.
+ common_hal_bleio_characteristic_construct(
+ characteristic, uuid, props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN,
+ GATT_MAX_DATA_LENGTH, false, // max_length, fixed_length: values may not matter for gattc
+ mp_obj_new_list(0, NULL));
+ characteristic->handle = gattc_char->handle_value;
+ characteristic->service = m_char_discovery_service;
+
+ mp_obj_list_append(m_char_discovery_service->characteristic_list, MP_OBJ_FROM_PTR(characteristic));
+ }
+
+ if (response->count > 0) {
+ m_discovery_successful = true;
+ }
+ m_discovery_in_process = false;
+}
+
+STATIC void on_desc_discovery_rsp(ble_gattc_evt_desc_disc_rsp_t *response, mp_obj_t device) {
+ for (size_t i = 0; i < response->count; ++i) {
+ ble_gattc_desc_t *gattc_desc = &response->descs[i];
+
+ // Remember handles for certain well-known descriptors.
+ switch (gattc_desc->uuid.uuid) {
+ case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG:
+ m_desc_discovery_characteristic->cccd_handle = gattc_desc->handle;
+ break;
+
+ case BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG:
+ m_desc_discovery_characteristic->sccd_handle = gattc_desc->handle;
+ break;
+
+ case BLE_UUID_DESCRIPTOR_CHAR_USER_DESC:
+ m_desc_discovery_characteristic->user_desc_handle = gattc_desc->handle;
+ break;
+
+ default:
+ // TODO: sd_ble_gattc_descriptors_discover() can return things that are not descriptors,
+ // so ignore those.
+ // https://devzone.nordicsemi.com/f/nordic-q-a/49500/sd_ble_gattc_descriptors_discover-is-returning-attributes-that-are-not-descriptors
+ break;
+ }
+
+ bleio_descriptor_obj_t *descriptor = m_new_obj(bleio_descriptor_obj_t);
+ descriptor->base.type = &bleio_descriptor_type;
+
+ bleio_uuid_obj_t *uuid = NULL;
+
+ if (gattc_desc->uuid.type != BLE_UUID_TYPE_UNKNOWN) {
+ // Known descriptor UUID.
+ uuid = m_new_obj(bleio_uuid_obj_t);
+ uuid->base.type = &bleio_uuid_type;
+ bleio_uuid_construct_from_nrf_ble_uuid(uuid, &gattc_desc->uuid);
+ } else {
+ // The discovery response contained a 128-bit UUID that has not yet been registered with the
+ // softdevice via sd_ble_uuid_vs_add(). We need to fetch the 128-bit value and register it.
+ // For now, just leave the UUID as NULL.
+ }
+
+ common_hal_bleio_descriptor_construct(descriptor, uuid, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN,
+ GATT_MAX_DATA_LENGTH, false);
+ descriptor->handle = gattc_desc->handle;
+ descriptor->characteristic = m_desc_discovery_characteristic;
+
+ mp_obj_list_append(m_desc_discovery_characteristic->descriptor_list, MP_OBJ_FROM_PTR(descriptor));
+ }
+
+ if (response->count > 0) {
+ m_discovery_successful = true;
+ }
+ m_discovery_in_process = false;
+}
+
+STATIC void discovery_on_ble_evt(ble_evt_t *ble_evt, mp_obj_t device) {
+ switch (ble_evt->header.evt_id) {
+ case BLE_GAP_EVT_DISCONNECTED:
+ m_discovery_successful = false;
+ m_discovery_in_process = false;
+ break;
+
+ case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
+ on_primary_srv_discovery_rsp(&ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp, device);
+ break;
+
+ case BLE_GATTC_EVT_CHAR_DISC_RSP:
+ on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, device);
+ break;
+
+ case BLE_GATTC_EVT_DESC_DISC_RSP:
+ on_desc_discovery_rsp(&ble_evt->evt.gattc_evt.params.desc_disc_rsp, device);
+ break;
+
+ default:
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Unhandled discovery event: 0x%04x\n", ble_evt->header.evt_id);
+ break;
+ }
+}
+
+
+void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t service_uuids_whitelist) {
+ mp_obj_list_t *remote_services_list = common_hal_bleio_device_get_remote_services_list(device);
+
+ ble_drv_add_event_handler(discovery_on_ble_evt, device);
+
+ // Start over with an empty list.
+ mp_obj_list_clear(MP_OBJ_FROM_PTR(common_hal_bleio_device_get_remote_services_list(device)));
+
+ if (service_uuids_whitelist == mp_const_none) {
+ // List of service UUID's not given, so discover all available services.
+
+ uint16_t next_service_start_handle = BLE_GATT_HANDLE_START;
+
+ while (discover_next_services(device, next_service_start_handle, MP_OBJ_NULL)) {
+ // discover_next_services() appends to remote_services_list.
+
+ // Get the most recently discovered service, and then ask for services
+ // whose handles start after the last attribute handle inside that service.
+ const bleio_service_obj_t *service =
+ MP_OBJ_TO_PTR(remote_services_list->items[remote_services_list->len - 1]);
+ next_service_start_handle = service->end_handle + 1;
+ }
+ } else {
+ mp_obj_iter_buf_t iter_buf;
+ mp_obj_t iterable = mp_getiter(service_uuids_whitelist, &iter_buf);
+ mp_obj_t uuid_obj;
+ while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
+ if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
+ mp_raise_ValueError(translate("non-UUID found in service_uuids_whitelist"));
+ }
+ bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj);
+
+ ble_uuid_t nrf_uuid;
+ bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nrf_uuid);
+
+ // Service might or might not be discovered; that's ok. Caller has to check
+ // Central.remote_services to find out.
+ // We only need to call this once for each service to discover.
+ discover_next_services(device, BLE_GATT_HANDLE_START, &nrf_uuid);
+ }
+ }
+
+
+ for (size_t service_idx = 0; service_idx < remote_services_list->len; ++service_idx) {
+ bleio_service_obj_t *service = MP_OBJ_TO_PTR(remote_services_list->items[service_idx]);
+
+ // Skip the service if it had an unknown (unregistered) UUID.
+ if (service->uuid == NULL) {
+ continue;
+ }
+
+ uint16_t next_char_start_handle = service->start_handle;
+
+ // Stop when we go past the end of the range of handles for this service or
+ // discovery call returns nothing.
+ // discover_next_characteristics() appends to the characteristic_list.
+ while (next_char_start_handle <= service->end_handle &&
+ discover_next_characteristics(device, service, next_char_start_handle)) {
+
+
+ // Get the most recently discovered characteristic, and then ask for characteristics
+ // whose handles start after the last attribute handle inside that characteristic.
+ const bleio_characteristic_obj_t *characteristic =
+ MP_OBJ_TO_PTR(service->characteristic_list->items[service->characteristic_list->len - 1]);
+ next_char_start_handle = characteristic->handle + 1;
+ }
+
+ // Got characteristics for this service. Now discover descriptors for each characteristic.
+ size_t char_list_len = service->characteristic_list->len;
+ for (size_t char_idx = 0; char_idx < char_list_len; ++char_idx) {
+ bleio_characteristic_obj_t *characteristic =
+ MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx]);
+ const bool last_characteristic = char_idx == char_list_len - 1;
+ bleio_characteristic_obj_t *next_characteristic = last_characteristic
+ ? NULL
+ : MP_OBJ_TO_PTR(service->characteristic_list->items[char_idx + 1]);
+
+ // Skip the characteristic if it had an unknown (unregistered) UUID.
+ if (characteristic->uuid == NULL) {
+ continue;
+ }
+
+ uint16_t next_desc_start_handle = characteristic->handle + 1;
+
+ // Don't run past the end of this service or the beginning of the next characteristic.
+ uint16_t next_desc_end_handle = next_characteristic == NULL
+ ? service->end_handle
+ : next_characteristic->handle - 1;
+
+ // Stop when we go past the end of the range of handles for this service or
+ // discovery call returns nothing.
+ // discover_next_descriptors() appends to the descriptor_list.
+ while (next_desc_start_handle <= service->end_handle &&
+ next_desc_start_handle < next_desc_end_handle &&
+ discover_next_descriptors(device, characteristic,
+ next_desc_start_handle, next_desc_end_handle)) {
+
+ // Get the most recently discovered descriptor, and then ask for descriptors
+ // whose handles start after that descriptor's handle.
+ const bleio_descriptor_obj_t *descriptor =
+ MP_OBJ_TO_PTR(characteristic->descriptor_list->items[characteristic->descriptor_list->len - 1]);
+ next_desc_start_handle = descriptor->handle + 1;
+ }
+ }
+ }
+
+ // This event handler is no longer needed.
+ ble_drv_remove_event_handler(discovery_on_ble_evt, device);
+
+}
+
+// GATTS read of a Characteristic or Descriptor.
+mp_obj_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle) {
+ // conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because
+ // we can still read and write the local value.
+
+ mp_buffer_info_t bufinfo;
+ ble_gatts_value_t gatts_value = {
+ .p_value = NULL,
+ .len = 0,
+ };
+
+ // Read once to find out what size buffer we need, then read again to fill buffer.
+
+ mp_obj_t value = mp_const_none;
+ uint32_t err_code = sd_ble_gatts_value_get(conn_handle, handle, &gatts_value);
+ if (err_code == NRF_SUCCESS) {
+ value = mp_obj_new_bytearray_of_zeros(gatts_value.len);
+ mp_get_buffer_raise(value, &bufinfo, MP_BUFFER_WRITE);
+ gatts_value.p_value = bufinfo.buf;
+
+ // Read again, with the correct size of buffer.
+ err_code = sd_ble_gatts_value_get(conn_handle, handle, &gatts_value);
+ }
+
+ if (err_code != NRF_SUCCESS) {
+ mp_raise_OSError_msg_varg(translate("Failed to read gatts value, err 0x%04x"), err_code);
+ }
+
+ return value;
+}
+
+void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo) {
+ // conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because
+ // we can still read and write the local value.
+
+ ble_gatts_value_t gatts_value = {
+ .p_value = bufinfo->buf,
+ .len = bufinfo->len,
+ };
+
+ const uint32_t err_code = sd_ble_gatts_value_set(conn_handle, handle, &gatts_value);
+ if (err_code != NRF_SUCCESS) {
+ mp_raise_OSError_msg_varg(translate("Failed to write gatts value, err 0x%04x"), err_code);
+ }
+}
+
+void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response) {
+ common_hal_bleio_check_connected(conn_handle);
+
+ ble_gattc_write_params_t write_params = {
+ .write_op = write_no_response ? BLE_GATT_OP_WRITE_CMD: BLE_GATT_OP_WRITE_REQ,
+ .handle = handle,
+ .p_value = bufinfo->buf,
+ .len = bufinfo->len,
+ };
+
+ while (1) {
+ uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params);
+ if (err_code == NRF_SUCCESS) {
+ break;
+ }
+
+ // Write with response will return NRF_ERROR_BUSY if the response has not been received.
+ // Write without reponse will return NRF_ERROR_RESOURCES if too many writes are pending.
+ if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES) {
+ // We could wait for an event indicating the write is complete, but just retrying is easier.
+ MICROPY_VM_HOOK_LOOP;
+ continue;
+ }
+
+ // Some real error occurred.
+ mp_raise_OSError_msg_varg(translate("Failed to write attribute value, err 0x%04x"), err_code);
+ }
+
}
diff --git a/ports/nrf/common-hal/bleio/__init__.h b/ports/nrf/common-hal/bleio/__init__.h
index 0c46b631f..c0bba3799 100644
--- a/ports/nrf/common-hal/bleio/__init__.h
+++ b/ports/nrf/common-hal/bleio/__init__.h
@@ -27,16 +27,10 @@
#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H
#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H
-#include "shared-bindings/bleio/__init__.h"
-#include "shared-bindings/bleio/Adapter.h"
-
-#include "shared-module/bleio/__init__.h"
+void bleio_reset(void);
// We assume variable length data.
// 20 bytes max (23 - 3).
#define GATT_MAX_DATA_LENGTH (BLE_GATT_ATT_MTU_DEFAULT - 3)
-gatt_role_t common_hal_bleio_device_get_gatt_role(mp_obj_t device);
-uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device);
-
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H
diff --git a/ports/nrf/nrfx_config.h b/ports/nrf/nrfx_config.h
index a2b48065d..8fa6721e2 100644
--- a/ports/nrf/nrfx_config.h
+++ b/ports/nrf/nrfx_config.h
@@ -78,6 +78,7 @@
// TIMERS
#define NRFX_TIMER_ENABLED 1
// Don't enable TIMER0: it's used by the SoftDevice.
+#define NRFX_TIMER0_ENABLED 0
#define NRFX_TIMER1_ENABLED 1
#define NRFX_TIMER2_ENABLED 1
diff --git a/ports/nrf/peripherals/nrf/timers.c b/ports/nrf/peripherals/nrf/timers.c
index 7f7a003d3..88f3dd468 100644
--- a/ports/nrf/peripherals/nrf/timers.c
+++ b/ports/nrf/peripherals/nrf/timers.c
@@ -36,7 +36,7 @@
STATIC nrfx_timer_t nrfx_timers[] = {
#if NRFX_CHECK(NRFX_TIMER0_ENABLED)
- // Note that TIMER0 is reserved for use by the SoftDevice, so it should not usually be enabled.
+ #error NRFX_TIMER0_ENABLED should not be on: TIMER0 is used by the SoftDevice
NRFX_TIMER_INSTANCE(0),
#endif
#if NRFX_CHECK(NRFX_TIMER1_ENABLED)
diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk
index a6dde61da..d4733e338 100644
--- a/py/circuitpy_defns.mk
+++ b/py/circuitpy_defns.mk
@@ -232,6 +232,7 @@ $(filter $(SRC_PATTERNS), \
audioio/AudioOut.c \
bleio/__init__.c \
bleio/Adapter.c \
+ bleio/Attribute.c \
bleio/Central.c \
bleio/Characteristic.c \
bleio/CharacteristicBuffer.c \
@@ -281,6 +282,9 @@ $(filter $(SRC_PATTERNS), \
# All possible sources are listed here, and are filtered by SRC_PATTERNS.
SRC_BINDINGS_ENUMS = \
$(filter $(SRC_PATTERNS), \
+ bleio/Address.c \
+ bleio/Attribute.c \
+ bleio/ScanEntry.c \
digitalio/Direction.c \
digitalio/DriveMode.c \
digitalio/Pull.c \
@@ -294,12 +298,6 @@ SRC_BINDINGS_ENUMS += \
help.c \
util.c
-SRC_BINDINGS_ENUMS += \
-$(filter $(SRC_PATTERNS), \
- bleio/Address.c \
- bleio/ScanEntry.c \
-)
-
# All possible sources are listed here, and are filtered by SRC_PATTERNS.
SRC_SHARED_MODULE = \
$(filter $(SRC_PATTERNS), \
@@ -320,6 +318,7 @@ $(filter $(SRC_PATTERNS), \
bitbangio/__init__.c \
board/__init__.c \
bleio/Address.c \
+ bleio/Attribute.c \
bleio/ScanEntry.c \
busio/OneWire.c \
displayio/Bitmap.c \
diff --git a/py/obj.h b/py/obj.h
index 6eead377d..c719c2945 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -668,6 +668,7 @@ mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun);
mp_obj_t mp_obj_new_closure(mp_obj_t fun, size_t n_closed, const mp_obj_t *closed);
mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items);
mp_obj_t mp_obj_new_list(size_t n, mp_obj_t *items);
+mp_obj_t mp_obj_new_list_from_iter(mp_obj_t iterable);
mp_obj_t mp_obj_new_dict(size_t n_args);
mp_obj_t mp_obj_new_set(size_t n_args, mp_obj_t *items);
mp_obj_t mp_obj_new_slice(mp_obj_t start, mp_obj_t stop, mp_obj_t step);
diff --git a/py/objlist.c b/py/objlist.c
index 558c4c611..ea38e64e5 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -68,6 +68,11 @@ STATIC mp_obj_t list_extend_from_iter(mp_obj_t list, mp_obj_t iterable) {
return list;
}
+mp_obj_t mp_obj_new_list_from_iter(mp_obj_t iterable) {
+ mp_obj_t list = mp_obj_new_list(0, NULL);
+ return list_extend_from_iter(list, iterable);
+}
+
STATIC mp_obj_t list_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)type_in;
mp_arg_check_num(n_args, kw_args, 0, 1, false);
diff --git a/py/objstr.c b/py/objstr.c
index ebd11d5cc..afe11f00f 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -41,6 +41,12 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_
STATIC mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf);
STATIC NORETURN void bad_implicit_conversion(mp_obj_t self_in);
+const char nibble_to_hex_upper[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F'};
+
+const char nibble_to_hex_lower[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f'};
+
/******************************************************************************/
/* str */
diff --git a/py/objstr.h b/py/objstr.h
index 0efe62a80..61a11d0bd 100644
--- a/py/objstr.h
+++ b/py/objstr.h
@@ -77,6 +77,9 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s
mp_obj_t index, bool is_slice);
const byte *find_subbytes(const byte *haystack, size_t hlen, const byte *needle, size_t nlen, int direction);
+const char nibble_to_hex_upper[16];
+const char nibble_to_hex_lower[16];
+
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_encode_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_find_obj);
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(str_rfind_obj);
diff --git a/shared-bindings/bleio/Adapter.c b/shared-bindings/bleio/Adapter.c
index 7b8df5103..2bb7f3465 100644
--- a/shared-bindings/bleio/Adapter.c
+++ b/shared-bindings/bleio/Adapter.c
@@ -53,12 +53,6 @@
//|
//| State of the BLE adapter.
//|
-
-//| .. attribute:: adapter.address
-//|
-//| MAC address of the BLE adapter. (read-only)
-//|
-
STATIC mp_obj_t bleio_adapter_get_enabled(mp_obj_t self) {
return mp_obj_new_bool(common_hal_bleio_adapter_get_enabled());
}
@@ -80,13 +74,13 @@ const mp_obj_property_t bleio_adapter_enabled_obj = {
(mp_obj_t)&mp_const_none_obj },
};
+//| .. attribute:: adapter.address
+//|
+//| MAC address of the BLE adapter. (read-only)
+//|
STATIC mp_obj_t bleio_adapter_get_address(mp_obj_t self) {
- 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);
-
- common_hal_bleio_adapter_get_address(address);
+ return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_address());
- return obj;
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_address_obj, bleio_adapter_get_address);
@@ -97,9 +91,29 @@ const mp_obj_property_t bleio_adapter_address_obj = {
(mp_obj_t)&mp_const_none_obj },
};
+//| .. attribute:: adapter.default_name
+//|
+//| default_name of the BLE adapter. (read-only)
+//| The name is "CIRCUITPY" + the last four hex digits of ``adapter.address``,
+//| to make it easy to distinguish multiple CircuitPython boards.
+//|
+STATIC mp_obj_t bleio_adapter_get_default_name(mp_obj_t self) {
+ return common_hal_bleio_adapter_get_default_name();
+
+}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_default_name_obj, bleio_adapter_get_default_name);
+
+const mp_obj_property_t bleio_adapter_default_name_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_adapter_get_default_name_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
STATIC const mp_rom_map_elem_t bleio_adapter_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_enabled), MP_ROM_PTR(&bleio_adapter_enabled_obj) },
{ MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_adapter_address_obj) },
+ { MP_ROM_QSTR(MP_QSTR_default_name), MP_ROM_PTR(&bleio_adapter_default_name_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_adapter_locals_dict, bleio_adapter_locals_dict_table);
diff --git a/shared-bindings/bleio/Adapter.h b/shared-bindings/bleio/Adapter.h
index de9d1d6db..72382616c 100644
--- a/shared-bindings/bleio/Adapter.h
+++ b/shared-bindings/bleio/Adapter.h
@@ -34,6 +34,7 @@ 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(bleio_address_obj_t *address);
+extern bleio_address_obj_t *common_hal_bleio_adapter_get_address(void);
+extern mp_obj_t common_hal_bleio_adapter_get_default_name(void);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H
diff --git a/shared-bindings/bleio/Address.c b/shared-bindings/bleio/Address.c
index 37f01042c..baeb6d7c0 100644
--- a/shared-bindings/bleio/Address.c
+++ b/shared-bindings/bleio/Address.c
@@ -83,7 +83,21 @@ STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args,
//| .. attribute:: address_bytes
//|
-//| The bytes that make up the device address (read-only)
+//| The bytes that make up the device address (read-only).
+//|
+//| Note that the ``bytes`` object returned is in little-endian order:
+//| The least significant byte is ``address_bytes[0]``. So the address will
+//| appear to be reversed if you print the raw ``bytes`` object. If you print
+//| or use `str()` on the :py:class:`~bleio.Attribute` object itself, the address will be printed
+//| in the expected order. For example:
+//|
+//| .. code-block:: pycon
+//|
+//| >>> import bleio
+//| >>> bleio.adapter.address
+//| <Address c8:1d:f5:ed:a8:35>
+//| >>> bleio.adapter.address.address_bytes
+//| b'5\xa8\xed\xf5\x1d\xc8'
//|
STATIC mp_obj_t bleio_address_get_address_bytes(mp_obj_t self_in) {
bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -147,18 +161,13 @@ STATIC mp_obj_t bleio_address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_o
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);
- if (kind == PRINT_STR) {
- mp_buffer_info_t buf_info;
- mp_obj_t address_bytes = common_hal_bleio_address_get_address_bytes(self);
- mp_get_buffer_raise(address_bytes, &buf_info, MP_BUFFER_READ);
-
- const uint8_t *buf = (uint8_t *) buf_info.buf;
- mp_printf(print,
- "%02x:%02x:%02x:%02x:%02x:%02x",
- buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]);
- } else {
- mp_printf(print, "<Address>");
- }
+ mp_buffer_info_t buf_info;
+ mp_obj_t address_bytes = common_hal_bleio_address_get_address_bytes(self);
+ mp_get_buffer_raise(address_bytes, &buf_info, MP_BUFFER_READ);
+
+ const uint8_t *buf = (uint8_t *) buf_info.buf;
+ mp_printf(print, "<Address %02x:%02x:%02x:%02x:%02x:%02x>",
+ buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]);
}
//| .. data:: PUBLIC
@@ -179,13 +188,13 @@ STATIC void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_pr
//| A randomly generated address that changes on every connection.
//|
STATIC const mp_rom_map_elem_t bleio_address_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_address_bytes), MP_ROM_PTR(&bleio_address_address_bytes_obj) },
- { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_address_type_obj) },
+ { MP_ROM_QSTR(MP_QSTR_address_bytes), MP_ROM_PTR(&bleio_address_address_bytes_obj) },
+ { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_address_type_obj) },
// These match the BLE_GAP_ADDR_TYPES values used by the nRF library.
- { MP_ROM_QSTR(MP_QSTR_PUBLIC), MP_OBJ_NEW_SMALL_INT(0) },
- { MP_ROM_QSTR(MP_QSTR_RANDOM_STATIC), MP_OBJ_NEW_SMALL_INT(1) },
- { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_RESOLVABLE), MP_OBJ_NEW_SMALL_INT(2) },
- { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE), MP_OBJ_NEW_SMALL_INT(3) },
+ { MP_ROM_QSTR(MP_QSTR_PUBLIC), MP_ROM_INT(0) },
+ { MP_ROM_QSTR(MP_QSTR_RANDOM_STATIC), MP_ROM_INT(1) },
+ { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_RESOLVABLE), MP_ROM_INT(2) },
+ { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE), MP_ROM_INT(3) },
};
diff --git a/shared-bindings/bleio/Attribute.c b/shared-bindings/bleio/Attribute.c
new file mode 100644
index 000000000..2cc9ef6d0
--- /dev/null
+++ b/shared-bindings/bleio/Attribute.c
@@ -0,0 +1,94 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ *
+ * 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:`Attribute` -- BLE Attribute
+//| =========================================================
+//|
+//| Definitions associated with all BLE attributes: characteristics, descriptors, etc.
+//| :py:class:`~bleio.Attribute` is, notionally, a superclass of
+//| :py:class:`~Characteristic` and :py:class:`~Descriptor`,
+//| but is not defined as a Python superclass of those classes.
+//|
+//| .. class:: Attribute()
+//|
+//| You cannot create an instance of :py:class:`~bleio.Attribute`.
+//|
+
+STATIC const mp_rom_map_elem_t bleio_attribute_locals_dict_table[] = {
+
+//| .. data:: NO_ACCESS
+//|
+//| security mode: access not allowed
+//|
+//| .. data:: OPEN
+//|
+//| security_mode: no security (link is not encrypted)
+//|
+//| .. data:: ENCRYPT_NO_MITM
+//|
+//| security_mode: unauthenticated encryption, without man-in-the-middle protection
+//|
+//| .. data:: ENCRYPT_WITH_MITM
+//|
+//| security_mode: authenticated encryption, with man-in-the-middle protection
+//|
+//| .. data:: LESC_ENCRYPT_WITH_MITM
+//|
+//| security_mode: LESC encryption, with man-in-the-middle protection
+//|
+//| .. data:: SIGNED_NO_MITM
+//|
+//| security_mode: unauthenticated data signing, without man-in-the-middle protection
+//|
+//| .. data:: SIGNED_WITH_MITM
+//|
+//| security_mode: authenticated data signing, without man-in-the-middle protection
+//|
+ { MP_ROM_QSTR(MP_QSTR_NO_ACCESS), MP_ROM_INT(SECURITY_MODE_NO_ACCESS) },
+ { MP_ROM_QSTR(MP_QSTR_OPEN), MP_ROM_INT(SECURITY_MODE_OPEN) },
+ { MP_ROM_QSTR(MP_QSTR_ENCRYPT_NO_MITM), MP_ROM_INT(SECURITY_MODE_ENC_NO_MITM) },
+ { MP_ROM_QSTR(MP_QSTR_ENCRYPT_WITH_MITM), MP_ROM_INT(SECURITY_MODE_ENC_WITH_MITM) },
+ { MP_ROM_QSTR(MP_QSTR_LESC_ENCRYPT_WITH_MITM), MP_ROM_INT(SECURITY_MODE_LESC_ENC_WITH_MITM) },
+ { MP_ROM_QSTR(MP_QSTR_SIGNED_NO_MITM), MP_ROM_INT(SECURITY_MODE_SIGNED_NO_MITM) },
+ { MP_ROM_QSTR(MP_QSTR_SIGNED_WITH_MITM), MP_ROM_INT(SECURITY_MODE_SIGNED_WITH_MITM) },
+
+};
+STATIC MP_DEFINE_CONST_DICT(bleio_attribute_locals_dict, bleio_attribute_locals_dict_table);
+
+const mp_obj_type_t bleio_attribute_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Attribute,
+ .locals_dict = (mp_obj_dict_t*)&bleio_attribute_locals_dict,
+};
diff --git a/shared-bindings/bleio/Attribute.h b/shared-bindings/bleio/Attribute.h
new file mode 100644
index 000000000..06a6eb5a9
--- /dev/null
+++ b/shared-bindings/bleio/Attribute.h
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ *
+ * 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_ATTRIBUTE_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ATTRIBUTE_H
+
+#include "py/obj.h"
+
+#include "shared-module/bleio/Attribute.h"
+
+extern const mp_obj_type_t bleio_attribute_type;
+
+extern void common_hal_bleio_attribute_security_mode_check_valid(bleio_attribute_security_mode_t security_mode);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ATTRIBUTE_H
diff --git a/shared-bindings/bleio/Central.c b/shared-bindings/bleio/Central.c
index fc00bce5c..1fc455d8d 100644
--- a/shared-bindings/bleio/Central.c
+++ b/shared-bindings/bleio/Central.c
@@ -56,12 +56,16 @@
//|
//| my_entry = None
//| for entry in entries:
-//| if entry.name is not None and entry.name == 'MyPeripheral':
+//| if entry.name is not None and entry.name == 'InterestingPeripheral':
//| my_entry = entry
//| break
//|
-//| central = bleio.Central(my_entry.address)
-//| central.connect(10.0) # timeout after 10 seconds
+//| if not my_entry:
+//| raise Exception("'InterestingPeripheral' not found")
+//|
+//| central = bleio.Central()
+//| central.connect(my_entry.address, 10) # timeout after 10 seconds
+//| remote_services = central.discover_remote_services()
//|
//| .. class:: Central()
@@ -79,24 +83,11 @@ STATIC mp_obj_t bleio_central_make_new(const mp_obj_type_t *type, size_t n_args,
return MP_OBJ_FROM_PTR(self);
}
-//| .. method:: connect(address, timeout, *, service_uuids=None)
-//| Attempts a connection to the remote peripheral. If the connection is successful,
-//| Do BLE discovery for the listed services, to find their handles and characteristics.
-//| The attribute `remote_services` will contain a list of all discovered services.
+//| .. method:: connect(address, timeout, *, service_uuids_whitelist=None)
+//| Attempts a connection to the remote peripheral.
//|
//| :param bleio.Address address: The address of the peripheral to connect to
//| :param float/int timeout: Try to connect for timeout seconds.
-//| :param iterable service_uuids_whitelist: an iterable of :py:class:~`UUID` objects for the services
-//| provided by the peripheral that you want to use.
-//| The peripheral may provide more services, but services not listed are ignored.
-//| If a service in service_uuids is not found during discovery, it will not
-//| appear in `remote_services`.
-//|
-//| If service_uuids_whitelist is None, then all services will undergo discovery, which can be slow.
-//|
-//| If the service UUID is 128-bit, or its characteristic UUID's are 128-bit, you
-//| you must have already created a :py:class:~`UUID` object for that UUID in order for the
-//| service or characteristic to be discovered. (This restriction may be lifted in the future.)
//|
STATIC mp_obj_t bleio_central_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
bleio_central_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
@@ -105,7 +96,6 @@ STATIC mp_obj_t bleio_central_connect(mp_uint_t n_args, const mp_obj_t *pos_args
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_timeout, MP_ARG_REQUIRED | MP_ARG_OBJ },
- { MP_QSTR_service_uuids_whitelist, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -119,7 +109,7 @@ STATIC mp_obj_t bleio_central_connect(mp_uint_t n_args, const mp_obj_t *pos_args
mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
// common_hal_bleio_central_connect() will validate that services is an iterable or None.
- common_hal_bleio_central_connect(self, address, timeout, args[ARG_service_uuids_whitelist].u_obj);
+ common_hal_bleio_central_connect(self, address, timeout);
return mp_const_none;
}
@@ -139,6 +129,46 @@ STATIC mp_obj_t bleio_central_disconnect(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_disconnect_obj, bleio_central_disconnect);
+//| .. method:: discover_remote_services(service_uuids_whitelist=None)
+//| Do BLE discovery for all services or for the given service UUIDS,
+//| to find their handles and characteristics, and return the discovered services.
+//| `Peripheral.connected` must be True.
+//|
+//| :param iterable service_uuids_whitelist: an iterable of :py:class:~`UUID` objects for the services
+//| provided by the peripheral that you want to use.
+//| The peripheral may provide more services, but services not listed are ignored
+//| and will not be returned.
+//|
+//| If service_uuids_whitelist is None, then all services will undergo discovery, which can be slow.
+//|
+//| If the service UUID is 128-bit, or its characteristic UUID's are 128-bit, you
+//| you must have already created a :py:class:~`UUID` object for that UUID in order for the
+//| service or characteristic to be discovered. Creating the UUID causes the UUID to be registered
+//| for use. (This restriction may be lifted in the future.)
+//|
+//| :return: A tuple of services provided by the remote peripheral.
+//|
+STATIC mp_obj_t bleio_central_discover_remote_services(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_central_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_service_uuids_whitelist };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_service_uuids_whitelist, 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);
+
+ if (!common_hal_bleio_central_get_connected(self)) {
+ mp_raise_ValueError(translate("Not connected"));
+ }
+
+ return MP_OBJ_FROM_PTR(common_hal_bleio_central_discover_remote_services(
+ MP_OBJ_FROM_PTR(self),
+ args[ARG_service_uuids_whitelist].u_obj));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_central_discover_remote_services_obj, 1, bleio_central_discover_remote_services);
+
//| .. attribute:: connected
//|
//| True if connected to a remove peripheral.
@@ -157,36 +187,14 @@ const mp_obj_property_t bleio_central_connected_obj = {
(mp_obj_t)&mp_const_none_obj },
};
-
-//| .. attribute:: remote_services (read-only)
-//|
-//| A tuple of services provided by the remote peripheral.
-//| If the Central is not connected, an empty tuple will be returned.
-//|
-STATIC mp_obj_t bleio_central_get_remote_services(mp_obj_t self_in) {
- bleio_central_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- // Return list as a tuple so user won't be able to change it.
- mp_obj_list_t *service_list = common_hal_bleio_central_get_remote_services(self);
- return mp_obj_new_tuple(service_list->len, service_list->items);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_get_remote_services_obj, bleio_central_get_remote_services);
-
-const mp_obj_property_t bleio_central_remote_services_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_central_get_remote_services_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
STATIC const mp_rom_map_elem_t bleio_central_locals_dict_table[] = {
// Methods
- { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_central_connect_obj) },
- { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_central_disconnect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_central_connect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_central_disconnect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_discover_remote_services), MP_ROM_PTR(&bleio_central_discover_remote_services_obj) },
// Properties
{ MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_central_connected_obj) },
- { MP_ROM_QSTR(MP_QSTR_remote_services), MP_ROM_PTR(&bleio_central_remote_services_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_central_locals_dict, bleio_central_locals_dict_table);
diff --git a/shared-bindings/bleio/Central.h b/shared-bindings/bleio/Central.h
index 0e84037f9..cbc437087 100644
--- a/shared-bindings/bleio/Central.h
+++ b/shared-bindings/bleio/Central.h
@@ -28,15 +28,16 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
+#include "py/objtuple.h"
#include "common-hal/bleio/Central.h"
#include "common-hal/bleio/Service.h"
extern const mp_obj_type_t bleio_central_type;
extern void common_hal_bleio_central_construct(bleio_central_obj_t *self);
-extern void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout, mp_obj_t service_uuids);
+extern void common_hal_bleio_central_connect(bleio_central_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout);
extern void common_hal_bleio_central_disconnect(bleio_central_obj_t *self);
extern bool common_hal_bleio_central_get_connected(bleio_central_obj_t *self);
-extern mp_obj_list_t *common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self);
+extern mp_obj_tuple_t *common_hal_bleio_central_discover_remote_services(bleio_central_obj_t *self, mp_obj_t service_uuids_whitelist);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c
index 3bf0476ab..4894ad114 100644
--- a/shared-bindings/bleio/Characteristic.c
+++ b/shared-bindings/bleio/Characteristic.c
@@ -28,7 +28,9 @@
#include "py/objproperty.h"
#include "py/runtime.h"
+#include "shared-bindings/bleio/Attribute.h"
#include "shared-bindings/bleio/Characteristic.h"
+#include "shared-bindings/bleio/Descriptor.h"
#include "shared-bindings/bleio/UUID.h"
//| .. currentmodule:: bleio
@@ -40,30 +42,36 @@
//| and writing of the characteristic's value.
//|
//|
-//| .. class:: Characteristic(uuid, *, broadcast=False, indicate=False, notify=False, read=False, write=False, write_no_response=False)
+//| .. class:: Characteristic(uuid, *, properties=0, read_perm=`Attribute.OPEN`, write_perm=`Attribute.OPEN`, max_length=20, fixed_length=False, descriptors=None)
//|
//| Create a new Characteristic object identified by the specified UUID.
//|
//| :param bleio.UUID uuid: The uuid of the characteristic
-//| :param bool broadcast: Allowed in advertising packets
-//| :param bool indicate: Server will indicate to the client when the value is set and wait for a response
-//| :param bool notify: Server will notify the client when the value is set
-//| :param bool read: Clients may read this characteristic
-//| :param bool write: Clients may write this characteristic; a response will be sent back
-//| :param bool write_no_response: Clients may write this characteristic; no response will be sent back
+//| :param int properties: bitmask of these values bitwise-or'd together: `BROADCAST`, `INDICATE`,
+//| `NOTIFY`, `READ`, `WRITE`, `WRITE_NO_RESPONSE`
+//| :param int read_perm: Specifies whether the characteristic can be read by a client, and if so, which
+//| security mode is required. Must be one of the integer values `Attribute.NO_ACCESS`, `Attribute.OPEN`,
+//| `Attribute.ENCRYPT_NO_MITM`, `Attribute.ENCRYPT_WITH_MITM`, `Attribute.LESC_ENCRYPT_WITH_MITM`,
+//| `Attribute.SIGNED_NO_MITM`, or `Attribute.SIGNED_WITH_MITM`.
+//| :param int write_perm: Specifies whether the characteristic can be written by a client, and if so, which
+//| security mode is required. Values allowed are the same as ``read_perm``.
+//| :param int max_length: Maximum length in bytes of the characteristic value. The maximum allowed is
+//| is 512, or possibly 510 if ``fixed_length`` is False. The default, 20, is the maximum
+//| number of data bytes that fit in a single BLE 4.x ATT packet.
+//| :param bool fixed_length: True if the characteristic value is of fixed length.
+//| :param iterable descriptors: BLE descriptors for this characteristic.
//|
STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- enum {
- ARG_uuid, ARG_broadcast, ARG_indicate, ARG_notify, ARG_read, ARG_write, ARG_write_no_response,
- };
+ enum { ARG_uuid, ARG_properties, ARG_read_perm, ARG_write_perm,
+ ARG_max_length, ARG_fixed_length, ARG_descriptors };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = mp_const_none} },
- { MP_QSTR_broadcast, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} },
- { MP_QSTR_indicate, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} },
- { MP_QSTR_notify, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} },
- { MP_QSTR_read, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} },
- { MP_QSTR_write, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} },
- { MP_QSTR_write_no_response, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} },
+ { MP_QSTR_properties, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = 0} },
+ { MP_QSTR_read_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SECURITY_MODE_OPEN} },
+ { MP_QSTR_write_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SECURITY_MODE_OPEN} },
+ { MP_QSTR_max_length, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = 20} },
+ { MP_QSTR_fixed_length, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} },
+ { MP_QSTR_descriptors, MP_ARG_KW_ONLY| MP_ARG_OBJ, {.u_obj = mp_const_none} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -76,129 +84,69 @@ STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t
}
bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj);
- bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t);
- self->base.type = &bleio_characteristic_type;
-
- bleio_characteristic_properties_t properties;
-
- properties.broadcast = args[ARG_broadcast].u_bool;
- properties.indicate = args[ARG_indicate].u_bool;
- properties.notify = args[ARG_notify].u_bool;
- properties.read = args[ARG_read].u_bool;
- properties.write = args[ARG_write].u_bool;
- properties.write_no_response = args[ARG_write_no_response].u_bool;
-
- // Initialize, with an empty descriptor list.
- common_hal_bleio_characteristic_construct(self, uuid, properties, mp_obj_new_list(0, NULL));
-
- return MP_OBJ_FROM_PTR(self);
-}
-
-//| .. attribute:: broadcast
-//|
-//| A `bool` specifying if the characteristic allows broadcasting its value. (read-only)
-//|
-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(common_hal_bleio_characteristic_get_properties(self).broadcast);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_broadcast_obj, bleio_characteristic_get_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)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-//| .. attribute:: indicate
-//|
-//| A `bool` specifying if the characteristic allows indicating its value. (read-only)
-//|
-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(common_hal_bleio_characteristic_get_properties(self).indicate);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_indicate_obj, bleio_characteristic_get_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)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-//| .. attribute:: notify
-//|
-//| A `bool` specifying if the characteristic allows notifying its value. (read-only)
-//|
-STATIC mp_obj_t bleio_characteristic_get_notify(mp_obj_t self_in) {
- bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ const bleio_characteristic_properties_t properties = args[ARG_properties].u_int;
+ if (properties & ~CHAR_PROP_ALL) {
+ mp_raise_ValueError(translate("Invalid properties"));
+ }
- return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).notify);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_notify_obj, bleio_characteristic_get_notify);
+ const bleio_attribute_security_mode_t read_perm = args[ARG_read_perm].u_int;
+ common_hal_bleio_attribute_security_mode_check_valid(read_perm);
-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)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
+ const bleio_attribute_security_mode_t write_perm = args[ARG_write_perm].u_int;
+ common_hal_bleio_attribute_security_mode_check_valid(write_perm);
-//| .. attribute:: read
-//|
-//| A `bool` specifying if the characteristic allows reading its value. (read-only)
-//|
-STATIC mp_obj_t bleio_characteristic_get_read(mp_obj_t self_in) {
- bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_obj_t descriptors = args[ARG_descriptors].u_obj;
+ if (descriptors == mp_const_none) {
+ descriptors = mp_const_empty_tuple;
+ }
- return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).read);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_read_obj, bleio_characteristic_get_read);
+ bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t);
+ self->base.type = &bleio_characteristic_type;
-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)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
+ // Copy the descriptors list and validate its items.
+ mp_obj_t desc_list_obj = mp_obj_new_list(0, NULL);
+ mp_obj_list_t *desc_list = MP_OBJ_TO_PTR(desc_list_obj);
+
+ // If descriptors is not an iterable, an exception will be thrown.
+ mp_obj_iter_buf_t iter_buf;
+ mp_obj_t descriptors_iter = mp_getiter(descriptors, &iter_buf);
+
+ mp_obj_t descriptor_obj;
+ while ((descriptor_obj = mp_iternext(descriptors_iter)) != MP_OBJ_STOP_ITERATION) {
+ if (!MP_OBJ_IS_TYPE(descriptor_obj, &bleio_descriptor_type)) {
+ mp_raise_ValueError(translate("descriptors includes an object that is not a Descriptors"));
+ }
+ bleio_descriptor_obj_t *descriptor = MP_OBJ_TO_PTR(descriptor_obj);
+ if (common_hal_bleio_descriptor_get_characteristic(descriptor) != MP_OBJ_NULL) {
+ mp_raise_ValueError(translate("Descriptor is already attached to a Characteristic"));
+ }
+ mp_obj_list_append(desc_list_obj, descriptor_obj);
+ }
-//| .. attribute:: write
-//|
-//| A `bool` specifying if the characteristic allows writing to its value. (read-only)
-//|
-STATIC mp_obj_t bleio_characteristic_get_write(mp_obj_t self_in) {
- bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ // Range checking on max_length arg is done by the common_hal layer, because
+ // it may vary depending on underlying BLE implementation.
+ common_hal_bleio_characteristic_construct(self, uuid, properties,
+ read_perm, write_perm,
+ args[ARG_max_length].u_int, args[ARG_fixed_length].u_bool,
+ desc_list);
- return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).write);
+ return MP_OBJ_FROM_PTR(self);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_obj, bleio_characteristic_get_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)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-//| .. attribute:: write_no_response
+//| .. attribute:: properties
//|
-//| A `bool` specifying if the characteristic allows writing to its value without response. (read-only)
+//| An int bitmask representing which properties are set.
//|
-STATIC mp_obj_t bleio_characteristic_get_write_no_response(mp_obj_t self_in) {
+STATIC mp_obj_t bleio_characteristic_get_properties(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return mp_obj_new_bool(common_hal_bleio_characteristic_get_properties(self).write_no_response);
+ return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_characteristic_get_properties(self));
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_no_response_obj, bleio_characteristic_get_write_no_response);
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_properties_obj, bleio_characteristic_get_properties);
-const mp_obj_property_t bleio_characteristic_write_no_response_obj = {
+const mp_obj_property_t bleio_characteristic_properties_obj = {
.base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_characteristic_get_write_no_response_obj,
+ .proxy = { (mp_obj_t)&bleio_characteristic_get_properties_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj },
};
@@ -225,9 +173,7 @@ const mp_obj_property_t bleio_characteristic_uuid_obj = {
//| .. 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, writing
-//| to the value will generate a BLE notification.
+//| The value of this characteristic.
//|
STATIC mp_obj_t bleio_characteristic_get_value(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -274,6 +220,24 @@ const mp_obj_property_t bleio_characteristic_descriptors_obj = {
(mp_obj_t)&mp_const_none_obj },
};
+//| .. attribute:: service (read-only)
+//|
+//| The Service this Characteristic is a part of. None if not yet assigned to a Service.
+//|
+STATIC mp_obj_t bleio_characteristic_get_service(mp_obj_t self_in) {
+ bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return common_hal_bleio_characteristic_get_service(self);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_service_obj, bleio_characteristic_get_service);
+
+const mp_obj_property_t bleio_characteristic_service_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_characteristic_get_service_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
//| .. method:: set_cccd(*, notify=False, indicate=False)
//|
//| Set the remote characteristic's CCCD to enable or disable notification and indication.
@@ -301,16 +265,43 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_characteristic_set_cccd_obj, 1, bleio_ch
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_descriptors), MP_ROM_PTR(&bleio_characteristic_descriptors_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_set_cccd), MP_ROM_PTR(&bleio_characteristic_set_cccd_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_no_response), MP_ROM_PTR(&bleio_characteristic_write_no_response_obj) },
+ { MP_ROM_QSTR(MP_QSTR_properties), MP_ROM_PTR(&bleio_characteristic_get_properties) },
+ { MP_ROM_QSTR(MP_QSTR_set_cccd), MP_ROM_PTR(&bleio_characteristic_set_cccd_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) },
+
+ // Bitmask constants to represent properties
+//| .. data:: BROADCAST
+//|
+//| property: allowed in advertising packets
+//|
+//| .. data:: INDICATE
+//|
+//| property: server will indicate to the client when the value is set and wait for a response
+//|
+//| .. data:: NOTIFY
+//|
+//| property: server will notify the client when the value is set
+//|
+//| .. data:: READ
+//|
+//| property: clients may read this characteristic
+//|
+//| .. data:: WRITE
+//|
+//| property: clients may write this characteristic; a response will be sent back
+//|
+//| .. data:: WRITE_NO_RESPONSE
+//|
+//| property: clients may write this characteristic; no response will be sent back
+//|
+ { MP_ROM_QSTR(MP_QSTR_BROADCAST), MP_ROM_INT(CHAR_PROP_BROADCAST) },
+ { MP_ROM_QSTR(MP_QSTR_INDICATE), MP_ROM_INT(CHAR_PROP_INDICATE) },
+ { MP_ROM_QSTR(MP_QSTR_NOTIFY), MP_ROM_INT(CHAR_PROP_NOTIFY) },
+ { MP_ROM_QSTR(MP_QSTR_READ), MP_ROM_INT(CHAR_PROP_READ) },
+ { MP_ROM_QSTR(MP_QSTR_WRITE), MP_ROM_INT(CHAR_PROP_WRITE) },
+ { MP_ROM_QSTR(MP_QSTR_WRITE_NO_RESPONSE), MP_ROM_INT(CHAR_PROP_WRITE_NO_RESPONSE) },
+
};
STATIC MP_DEFINE_CONST_DICT(bleio_characteristic_locals_dict, bleio_characteristic_locals_dict_table);
@@ -330,5 +321,5 @@ const mp_obj_type_t bleio_characteristic_type = {
.name = MP_QSTR_Characteristic,
.make_new = bleio_characteristic_make_new,
.print = bleio_characteristic_print,
- .locals_dict = (mp_obj_dict_t*)&bleio_characteristic_locals_dict
+ .locals_dict = (mp_obj_dict_t*)&bleio_characteristic_locals_dict,
};
diff --git a/shared-bindings/bleio/Characteristic.h b/shared-bindings/bleio/Characteristic.h
index d450c42b4..87942c8e9 100644
--- a/shared-bindings/bleio/Characteristic.h
+++ b/shared-bindings/bleio/Characteristic.h
@@ -28,17 +28,19 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H
+#include "shared-bindings/bleio/Attribute.h"
#include "shared-module/bleio/Characteristic.h"
#include "common-hal/bleio/Characteristic.h"
extern const mp_obj_type_t bleio_characteristic_type;
-extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, mp_obj_list_t *descriptor_list);
+extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_uuid_obj_t *uuid, bleio_characteristic_properties_t props, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length, mp_obj_list_t *descriptor_list);
extern mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self);
extern void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo);
extern bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties(bleio_characteristic_obj_t *self);
extern bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self);
extern mp_obj_list_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self);
+extern bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_characteristic_obj_t *self);
extern void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H
diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c
index f2e5aa01d..d7c2a85c7 100644
--- a/shared-bindings/bleio/Descriptor.c
+++ b/shared-bindings/bleio/Descriptor.c
@@ -28,6 +28,7 @@
#include "py/objproperty.h"
#include "py/runtime.h"
+#include "shared-bindings/bleio/Attribute.h"
#include "shared-bindings/bleio/Descriptor.h"
#include "shared-bindings/bleio/UUID.h"
@@ -41,23 +42,30 @@
//| information about the characteristic.
//|
-//| .. class:: Descriptor(uuid)
+//| .. class:: Descriptor(uuid, *, read_perm=`Attribute.OPEN`, write_perm=`Attribute.OPEN`)
//|
-//| Create a new descriptor object with the UUID uuid.
-
-//| .. attribute:: handle
-//|
-//| The descriptor handle. (read-only)
-//|
-
-//| .. attribute:: uuid
+//| Create a new descriptor object with the UUID uuid
//|
-//| The descriptor uuid. (read-only)
+//| :param bleio.UUID uuid: The uuid of the descriptor
+//| :param int read_perm: Specifies whether the descriptor can be read by a client, and if so, which
+//| security mode is required. Must be one of the integer values `Attribute.NO_ACCESS`, `Attribute.OPEN`,
+//| `Attribute.ENCRYPT_NO_MITM`, `Attribute.ENCRYPT_WITH_MITM`, `Attribute.LESC_ENCRYPT_WITH_MITM`,
+//| `Attribute.SIGNED_NO_MITM`, or `Attribute.SIGNED_WITH_MITM`.
+//| :param int write_perm: Specifies whether the descriptor can be written by a client, and if so, which
+//| security mode is required. Values allowed are the same as ``read_perm``.
+//| :param int max_length: Maximum length in bytes of the characteristic value. The maximum allowed is
+//| is 512, or possibly 510 if ``fixed_length`` is False. The default, 20, is the maximum
+//| number of data bytes that fit in a single BLE 4.x ATT packet.
+//| :param bool fixed_length: True if the characteristic value is of fixed length.
//|
STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- enum { ARG_uuid };
+ enum { ARG_uuid, ARG_read_perm, ARG_write_perm, ARG_max_length, ARG_fixed_length };
static const mp_arg_t allowed_args[] = {
- { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_read_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SECURITY_MODE_OPEN } },
+ { MP_QSTR_write_perm, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = SECURITY_MODE_OPEN } },
+ { MP_QSTR_max_length, MP_ARG_KW_ONLY| MP_ARG_INT, {.u_int = 20} },
+ { MP_QSTR_fixed_length, MP_ARG_KW_ONLY| MP_ARG_BOOL, {.u_bool = false} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
@@ -69,28 +77,28 @@ STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_ar
mp_raise_ValueError(translate("Expected a UUID"));
}
+ const bleio_attribute_security_mode_t read_perm = args[ARG_read_perm].u_int;
+ common_hal_bleio_attribute_security_mode_check_valid(read_perm);
+
+ const bleio_attribute_security_mode_t write_perm = args[ARG_write_perm].u_int;
+ common_hal_bleio_attribute_security_mode_check_valid(write_perm);
+
bleio_descriptor_obj_t *self = m_new_obj(bleio_descriptor_obj_t);
self->base.type = type;
bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_arg);
- common_hal_bleio_descriptor_construct(self, uuid);
-
- return MP_OBJ_FROM_PTR(self);
-}
-STATIC mp_obj_t bleio_descriptor_get_handle(mp_obj_t self_in) {
- bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ // Range checking on max_length arg is done by the common_hal layer, because
+ // it may vary depending on underlying BLE implementation.
+ common_hal_bleio_descriptor_construct(self, uuid, read_perm, write_perm,
+ args[ARG_max_length].u_int, args[ARG_fixed_length].u_bool);
- return mp_obj_new_int(common_hal_bleio_descriptor_get_handle(self));
+ return MP_OBJ_FROM_PTR(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},
-};
+//| .. attribute:: uuid
+//|
+//| The descriptor uuid. (read-only)
+//|
STATIC mp_obj_t bleio_descriptor_get_uuid(mp_obj_t self_in) {
bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -106,56 +114,59 @@ const mp_obj_property_t bleio_descriptor_uuid_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(DESCRIPTOR_UUID_CHARACTERISTIC_EXTENDED_PROPERTIES) },
-
- { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_USER_DESCRIPTION),
- MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION) },
-
- { MP_ROM_QSTR(MP_QSTR_CLIENT_CHARACTERISTIC_CONFIGURATION),
- MP_ROM_INT(DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION) },
-
- { MP_ROM_QSTR(MP_QSTR_SERVER_CHARACTERISTIC_CONFIGURATION),
- MP_ROM_INT(DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION) },
-
- { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_PRESENTATION_FORMAT),
- MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_PRESENTATION_FORMAT) },
+//| .. attribute:: characteristic (read-only)
+//|
+//| The Characteristic this Descriptor is a part of. None if not yet assigned to a Characteristic.
+//|
+STATIC mp_obj_t bleio_descriptor_get_characteristic(mp_obj_t self_in) {
+ bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in);
- { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_AGGREGATE_FORMAT),
- MP_ROM_INT(DESCRIPTOR_UUID_CHARACTERISTIC_AGGREGATE_FORMAT) },
+ return common_hal_bleio_descriptor_get_characteristic(self);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_characteristic_obj, bleio_descriptor_get_characteristic);
- { MP_ROM_QSTR(MP_QSTR_VALID_RANGE),
- MP_ROM_INT(DESCRIPTOR_UUID_VALID_RANGE) },
+const mp_obj_property_t bleio_descriptor_characteristic_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_descriptor_get_characteristic_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
- { MP_ROM_QSTR(MP_QSTR_EXTERNAL_REPORT_REFERENCE),
- MP_ROM_INT(DESCRIPTOR_UUID_EXTERNAL_REPORT_REFERENCE) },
+//| .. attribute:: value
+//|
+//| The value of this descriptor.
+//|
+STATIC mp_obj_t bleio_descriptor_get_value(mp_obj_t self_in) {
+ bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in);
- { MP_ROM_QSTR(MP_QSTR_REPORT_REFERENCE),
- MP_ROM_INT(DESCRIPTOR_UUID_REPORT_REFERENCE) },
+ return common_hal_bleio_descriptor_get_value(self);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_value_obj, bleio_descriptor_get_value);
- { MP_ROM_QSTR(MP_QSTR_NUMBER_OF_DIGITALS),
- MP_ROM_INT(DESCRIPTOR_UUID_NUMBER_OF_DIGITALS) },
+STATIC mp_obj_t bleio_descriptor_set_value(mp_obj_t self_in, mp_obj_t value_in) {
+ bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in);
- { MP_ROM_QSTR(MP_QSTR_VALUE_TRIGGER_SETTING),
- MP_ROM_INT(DESCRIPTOR_UUID_VALUE_TRIGGER_SETTING) },
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(value_in, &bufinfo, MP_BUFFER_READ);
- { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_CONFIGURATION),
- MP_ROM_INT(DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_CONFIGURATION) },
+ common_hal_bleio_descriptor_set_value(self, &bufinfo);
- { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_MEASUREMENT ),
- MP_ROM_INT(DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_MEASUREMENT) },
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_descriptor_set_value_obj, bleio_descriptor_set_value);
- { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_TRIGGER_SETTING),
- MP_ROM_INT(DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_TRIGGER_SETTING) },
+const mp_obj_property_t bleio_descriptor_value_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_descriptor_get_value_obj,
+ (mp_obj_t)&bleio_descriptor_set_value_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
- { MP_ROM_QSTR(MP_QSTR_TIME_TRIGGER_SETTING),
- MP_ROM_INT(DESCRIPTOR_UUID_TIME_TRIGGER_SETTING) },
+STATIC const mp_rom_map_elem_t bleio_descriptor_locals_dict_table[] = {
+ // Properties
+ { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_descriptor_uuid_obj) },
+ { MP_ROM_QSTR(MP_QSTR_characteristic), MP_ROM_PTR(&bleio_descriptor_characteristic_obj) },
+ { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&bleio_descriptor_value_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_descriptor_locals_dict, bleio_descriptor_locals_dict_table);
diff --git a/shared-bindings/bleio/Descriptor.h b/shared-bindings/bleio/Descriptor.h
index fd11ea08c..430c0d0b6 100644
--- a/shared-bindings/bleio/Descriptor.h
+++ b/shared-bindings/bleio/Descriptor.h
@@ -28,31 +28,16 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H
+#include "shared-module/bleio/Attribute.h"
#include "common-hal/bleio/Descriptor.h"
#include "common-hal/bleio/UUID.h"
-enum {
- DESCRIPTOR_UUID_CHARACTERISTIC_EXTENDED_PROPERTIES = 0x2900,
- DESCRIPTOR_UUID_CHARACTERISTIC_USER_DESCRIPTION = 0x2901,
- DESCRIPTOR_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION = 0x2902,
- DESCRIPTOR_UUID_SERVER_CHARACTERISTIC_CONFIGURATION = 0x2903,
- DESCRIPTOR_UUID_CHARACTERISTIC_PRESENTATION_FORMAT = 0x2904,
- DESCRIPTOR_UUID_CHARACTERISTIC_AGGREGATE_FORMAT = 0x2905,
- DESCRIPTOR_UUID_VALID_RANGE = 0x2906,
- DESCRIPTOR_UUID_EXTERNAL_REPORT_REFERENCE = 0x2907,
- DESCRIPTOR_UUID_REPORT_REFERENCE = 0x2908,
- DESCRIPTOR_UUID_NUMBER_OF_DIGITALS = 0x2909,
- DESCRIPTOR_UUID_VALUE_TRIGGER_SETTING = 0x290A,
- DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_CONFIGURATION = 0x290B,
- DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_MEASUREMENT = 0x290C,
- DESCRIPTOR_UUID_ENVIRONMENTAL_SENSING_TRIGGER_SETTING = 0x290D,
- DESCRIPTOR_UUID_TIME_TRIGGER_SETTING = 0x290E,
-};
-
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 mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self);
-extern mp_obj_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self);
+extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid, bleio_attribute_security_mode_t read_perm, bleio_attribute_security_mode_t write_perm, mp_int_t max_length, bool fixed_length);
+extern bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self);
+extern bleio_characteristic_obj_t *common_hal_bleio_descriptor_get_characteristic(bleio_descriptor_obj_t *self);
+extern mp_obj_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self);
+extern void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buffer_info_t *bufinfo);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H
diff --git a/shared-bindings/bleio/Peripheral.c b/shared-bindings/bleio/Peripheral.c
index 570896d27..630e6ed36 100644
--- a/shared-bindings/bleio/Peripheral.c
+++ b/shared-bindings/bleio/Peripheral.c
@@ -44,8 +44,6 @@
#include "common-hal/bleio/Peripheral.h"
-static const char default_name[] = "CIRCUITPY";
-
#define ADV_INTERVAL_DEFAULT (1.0f)
#define ADV_INTERVAL_MIN (0.0020f)
#define ADV_INTERVAL_MIN_STRING "0.0020"
@@ -80,14 +78,14 @@ static const char default_name[] = "CIRCUITPY";
//| # Wait for connection.
//| pass
//|
-//| .. class:: Peripheral(services=(), \*, name='CIRCUITPY')
+//| .. class:: Peripheral(services=(), \*, name=None)
//|
//| Create a new Peripheral object.
//|
//| :param iterable services: the Service objects representing services available from this peripheral, if any.
//| A non-connectable peripheral will have no services.
-//| :param str name: The name used when advertising this peripheral. Use ``None`` when a name is not needed,
-//| such as when the peripheral is a beacon
+//| :param str name: The name used when advertising this peripheral. If name is None,
+//| bleio.adapter.default_name will be used.
//|
STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_services, ARG_name };
@@ -107,33 +105,30 @@ STATIC mp_obj_t bleio_peripheral_make_new(const mp_obj_type_t *type, size_t n_ar
self->base.type = &bleio_peripheral_type;
// Copy the services list and validate its items.
- mp_obj_t service_list_obj = mp_obj_new_list(0, NULL);
- mp_obj_list_t *service_list = MP_OBJ_FROM_PTR(service_list_obj);
+ mp_obj_t services_list_obj = mp_obj_new_list(0, NULL);
+ mp_obj_list_t *services_list = MP_OBJ_FROM_PTR(services_list_obj);
mp_obj_t service;
while ((service = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
if (!MP_OBJ_IS_TYPE(service, &bleio_service_type)) {
mp_raise_ValueError(translate("non-Service found in services"));
}
- mp_obj_list_append(service_list, service);
+ mp_obj_list_append(services_list, service);
}
- const mp_obj_t name = args[ARG_name].u_obj;
- mp_obj_t name_str;
+ mp_obj_t name = args[ARG_name].u_obj;
if (name == MP_OBJ_NULL || name == mp_const_none) {
- name_str = mp_obj_new_str(default_name, strlen(default_name));
- } else if (MP_OBJ_IS_STR(name)) {
- name_str = name;
- } else {
+ name = common_hal_bleio_adapter_get_default_name();
+ } else if (!MP_OBJ_IS_STR(name)) {
mp_raise_ValueError(translate("name must be a string"));
}
- common_hal_bleio_peripheral_construct(self, service_list, name_str);
+ common_hal_bleio_peripheral_construct(self, services_list, name);
return MP_OBJ_FROM_PTR(self);
}
-//| .. attribute:: connected
+//| .. attribute:: connected (read-only)
//|
//| True if connected to a BLE Central device.
//|
@@ -158,8 +153,8 @@ const mp_obj_property_t bleio_peripheral_connected_obj = {
STATIC mp_obj_t bleio_peripheral_get_services(mp_obj_t self_in) {
bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
// Return list as a tuple so user won't be able to change it.
- mp_obj_list_t *service_list = common_hal_bleio_peripheral_get_service_list(self);
- return mp_obj_new_tuple(service_list->len, service_list->items);
+ mp_obj_list_t *services_list = common_hal_bleio_peripheral_get_services(self);
+ return mp_obj_new_tuple(services_list->len, services_list->items);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_services_obj, bleio_peripheral_get_services);
@@ -265,16 +260,75 @@ STATIC mp_obj_t bleio_peripheral_disconnect(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_disconnect_obj, bleio_peripheral_disconnect);
+//| .. method:: discover_remote_services(service_uuids_whitelist=None)
+//| Do BLE discovery for all services or for the given service UUIDS,
+//| to find their handles and characteristics, and return the discovered services.
+//| `Peripheral.connected` must be True.
+//|
+//| :param iterable service_uuids_whitelist: an iterable of :py:class:~`UUID` objects for the services
+//| provided by the peripheral that you want to use.
+//| The peripheral may provide more services, but services not listed are ignored
+//| and will not be returned.
+//|
+//| If service_uuids_whitelist is None, then all services will undergo discovery, which can be slow.
+//|
+//| If the service UUID is 128-bit, or its characteristic UUID's are 128-bit, you
+//| you must have already created a :py:class:~`UUID` object for that UUID in order for the
+//| service or characteristic to be discovered. Creating the UUID causes the UUID to be registered
+//| for use. (This restriction may be lifted in the future.)
+//|
+//| Thought it is unusual for a peripheral to act as a BLE client, it can do so, and
+//| needs to be able to do discovery on its peer (a central).
+//| Examples include a peripheral accessing a central that provides Current Time Service,
+//| Apple Notification Center Service, or Battery Service.
+//|
+//| :return: A tuple of services provided by the remote central.
+//|
+STATIC mp_obj_t bleio_peripheral_discover_remote_services(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_service_uuids_whitelist };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_service_uuids_whitelist, 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);
+
+ if (!common_hal_bleio_peripheral_get_connected(self)) {
+ mp_raise_ValueError(translate("Not connected"));
+ }
+
+ return MP_OBJ_FROM_PTR(common_hal_bleio_peripheral_discover_remote_services(
+ MP_OBJ_FROM_PTR(self),
+ args[ARG_service_uuids_whitelist].u_obj));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_peripheral_discover_remote_services_obj, 1, bleio_peripheral_discover_remote_services);
+
+//| .. method:: pair()
+//|
+//| Request pairing with connected central.
+STATIC mp_obj_t bleio_peripheral_pair(mp_obj_t self_in) {
+ bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ common_hal_bleio_peripheral_pair(self);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_pair_obj, bleio_peripheral_pair);
+
STATIC const mp_rom_map_elem_t bleio_peripheral_locals_dict_table[] = {
// Methods
- { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_peripheral_start_advertising_obj) },
- { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_peripheral_stop_advertising_obj) },
- { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_peripheral_disconnect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_peripheral_start_advertising_obj) },
+ { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_peripheral_stop_advertising_obj) },
+ { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_peripheral_disconnect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_discover_remote_services), MP_ROM_PTR(&bleio_peripheral_discover_remote_services_obj) },
+ { MP_ROM_QSTR(MP_QSTR_pair) , MP_ROM_PTR(&bleio_peripheral_pair_obj) },
// Properties
- { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_peripheral_connected_obj) },
- { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_peripheral_name_obj) },
- { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_peripheral_services_obj) },
+ { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_peripheral_connected_obj) },
+ { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_peripheral_name_obj) },
+ { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_peripheral_services_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_peripheral_locals_dict, bleio_peripheral_locals_dict_table);
diff --git a/shared-bindings/bleio/Peripheral.h b/shared-bindings/bleio/Peripheral.h
index 846250a5f..597b65ce2 100644
--- a/shared-bindings/bleio/Peripheral.h
+++ b/shared-bindings/bleio/Peripheral.h
@@ -28,16 +28,19 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H
+#include "py/objtuple.h"
#include "common-hal/bleio/Peripheral.h"
extern const mp_obj_type_t bleio_peripheral_type;
extern void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_list_t *service_list, mp_obj_t name);
-extern mp_obj_list_t *common_hal_bleio_peripheral_get_service_list(bleio_peripheral_obj_t *self);
+extern mp_obj_list_t *common_hal_bleio_peripheral_get_services(bleio_peripheral_obj_t *self);
extern bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self);
extern mp_obj_t common_hal_bleio_peripheral_get_name(bleio_peripheral_obj_t *self);
extern void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *device, bool connectable, float interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo);
extern void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *device);
extern void common_hal_bleio_peripheral_disconnect(bleio_peripheral_obj_t *device);
+extern mp_obj_tuple_t *common_hal_bleio_peripheral_discover_remote_services(bleio_peripheral_obj_t *self, mp_obj_t service_uuids_whitelist);
+extern void common_hal_bleio_peripheral_pair(bleio_peripheral_obj_t *device);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H
diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c
index db0606991..6961b0b52 100644
--- a/shared-bindings/bleio/Service.c
+++ b/shared-bindings/bleio/Service.c
@@ -43,12 +43,16 @@
//| .. class:: Service(uuid, characteristics, *, 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 iterable characteristics: the Characteristic objects for this service
//| :param bool secondary: If the service is a secondary one
//|
+//| A Service may be remote (:py:data:`remote` is ``True``), but a remote Service
+//| cannot be constructed directly. It is created by `Central.discover_remote_services()`
+//| or `Peripheral.discover_remote_services()`.
STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_uuid, ARG_characteristics, ARG_secondary };
@@ -92,6 +96,9 @@ STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args,
// The descriptor base UUID doesn't match the characteristic base UUID.
mp_raise_ValueError(translate("Characteristic UUID doesn't match Service UUID"));
}
+ if (common_hal_bleio_characteristic_get_service(characteristic) != MP_OBJ_NULL) {
+ mp_raise_ValueError(translate("Characteristic is already attached to a Service"));
+ }
mp_obj_list_append(char_list_obj, characteristic_obj);
}
@@ -119,6 +126,24 @@ const mp_obj_property_t bleio_service_characteristics_obj = {
(mp_obj_t)&mp_const_none_obj },
};
+//| .. attribute:: remote
+//|
+//| True if this is a service provided by a remote device. (read-only)
+//|
+STATIC mp_obj_t bleio_service_get_remote(mp_obj_t self_in) {
+ bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(common_hal_bleio_service_get_is_remote(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_remote_obj, bleio_service_get_remote);
+
+const mp_obj_property_t bleio_service_remote_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_service_get_remote_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
//| .. attribute:: secondary
//|
//| True if this is a secondary service. (read-only)
diff --git a/shared-bindings/bleio/Service.h b/shared-bindings/bleio/Service.h
index f646c81a9..716c2e8a9 100644
--- a/shared-bindings/bleio/Service.h
+++ b/shared-bindings/bleio/Service.h
@@ -35,6 +35,7 @@ const mp_obj_type_t bleio_service_type;
extern void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, mp_obj_list_t *characteristic_list, bool is_secondary);
extern bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self);
extern mp_obj_list_t *common_hal_bleio_service_get_characteristic_list(bleio_service_obj_t *self);
+extern bool common_hal_bleio_service_get_is_remote(bleio_service_obj_t *self);
extern bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self);
extern void common_hal_bleio_service_add_all_characteristics(bleio_service_obj_t *self);
diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c
index ba3bae6c7..739f461a5 100644
--- a/shared-bindings/bleio/__init__.c
+++ b/shared-bindings/bleio/__init__.c
@@ -28,24 +28,30 @@
#include "shared-bindings/bleio/__init__.h"
#include "shared-bindings/bleio/Address.h"
+#include "shared-bindings/bleio/Attribute.h"
#include "shared-bindings/bleio/Central.h"
#include "shared-bindings/bleio/Characteristic.h"
#include "shared-bindings/bleio/CharacteristicBuffer.h"
-// #include "shared-bindings/bleio/Descriptor.h"
+#include "shared-bindings/bleio/Descriptor.h"
#include "shared-bindings/bleio/Peripheral.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"
-//| :mod:`bleio` --- Bluetooth Low Energy functionality
+//| :mod:`bleio` --- Bluetooth Low Energy (BLE) communication
//| ================================================================
//|
//| .. module:: bleio
//| :synopsis: Bluetooth Low Energy functionality
//| :platform: nRF
//|
-//| The `bleio` module contains methods for managing the BLE adapter.
+//| The `bleio` module provides necessary low-level functionality for communicating
+//| using Bluetooth Low Energy (BLE). We recommend you use `bleio` in conjunction
+//| with the `adafruit_ble <https://circuitpython.readthedocs.io/projects/ble/en/latest/>`_
+//| CircuitPython library, which builds on `bleio`, and
+//| provides higher-level convenience functionality, including predefined beacons, clients,
+//| servers.
//|
//| Libraries
//|
@@ -54,6 +60,7 @@
//|
//| Address
//| Adapter
+//| Attribute
//| Central
//| Characteristic
//| CharacteristicBuffer
@@ -72,20 +79,21 @@
//|
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_Address), MP_ROM_PTR(&bleio_address_type) },
- { MP_ROM_QSTR(MP_QSTR_Central), MP_ROM_PTR(&bleio_central_type) },
- { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) },
- { MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), MP_ROM_PTR(&bleio_characteristic_buffer_type) },
-// { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) },
- { MP_ROM_QSTR(MP_QSTR_Peripheral), MP_ROM_PTR(&bleio_peripheral_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) },
+ { 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_Attribute), MP_ROM_PTR(&bleio_attribute_type) },
+ { MP_ROM_QSTR(MP_QSTR_Central), MP_ROM_PTR(&bleio_central_type) },
+ { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) },
+ { MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), MP_ROM_PTR(&bleio_characteristic_buffer_type) },
+ { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) },
+ { MP_ROM_QSTR(MP_QSTR_Peripheral), MP_ROM_PTR(&bleio_peripheral_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) },
+ { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table);
diff --git a/shared-bindings/bleio/__init__.h b/shared-bindings/bleio/__init__.h
index 4aa6dd45b..6a4c804f5 100644
--- a/shared-bindings/bleio/__init__.h
+++ b/shared-bindings/bleio/__init__.h
@@ -29,8 +29,24 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO___INIT___H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO___INIT___H
+#include "py/objlist.h"
+
+#include "shared-bindings/bleio/__init__.h"
+#include "shared-bindings/bleio/Adapter.h"
+
#include "common-hal/bleio/Adapter.h"
extern const super_adapter_obj_t common_hal_bleio_adapter_obj;
+extern void common_hal_bleio_check_connected(uint16_t conn_handle);
+
+extern uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device);
+extern mp_obj_list_t *common_hal_bleio_device_get_remote_services_list(mp_obj_t device);
+extern void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t service_uuids_whitelist);
+
+extern mp_obj_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle);
+extern void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo);
+extern void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response);
+
+
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO___INIT___H
diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c
index 70c01c2d8..f34cb9c46 100644
--- a/shared-bindings/time/__init__.c
+++ b/shared-bindings/time/__init__.c
@@ -99,16 +99,17 @@ mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, const mp
//|
//| Structure used to capture a date and time. Note that it takes a tuple!
//|
-//| :param Tuple[tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst] time_tuple: Tuple of time info.
-//| * the year, 2017 for example
-//| * the month, range [1, 12]
-//| * the day of the month, range [1, 31]
-//| * the hour, range [0, 23]
-//| * the minute, range [0, 59]
-//| * the second, range [0, 61]
-//| * the day of the week, range [0, 6], Monday is 0
-//| * the day of the year, range [1, 366], -1 indicates not known
-//| * 1 when in daylight savings, 0 when not, -1 if unknown.
+//| :param tuple time_tuple: Tuple of time info: ``(tm_year, tm_mon, tm_mday, tm_hour, tm_min, tm_sec, tm_wday, tm_yday, tm_isdst)``
+//|
+//| * ``tm_year``: the year, 2017 for example
+//| * ``tm_month``: the month, range [1, 12]
+//| * ``tm_mday``: the day of the month, range [1, 31]
+//| * ``tm_hour``: the hour, range [0, 23]
+//| * ``tm_minute``: the minute, range [0, 59]
+//| * ``tm_sec``: the second, range [0, 61]
+//| * ``tm_wday``: the day of the week, range [0, 6], Monday is 0
+//| * ``tm_yday``: the day of the year, range [1, 366], -1 indicates not known
+//| * ``tm_isdst``: 1 when in daylight savings, 0 when not, -1 if unknown.
//|
const mp_obj_namedtuple_type_t struct_time_type_obj = {
.base = {
diff --git a/shared-module/bleio/Attribute.c b/shared-module/bleio/Attribute.c
new file mode 100644
index 000000000..2275003c9
--- /dev/null
+++ b/shared-module/bleio/Attribute.c
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ *
+ * 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/runtime.h"
+#include "shared-bindings/bleio/Attribute.h"
+
+void common_hal_bleio_attribute_security_mode_check_valid(bleio_attribute_security_mode_t security_mode) {
+ switch (security_mode) {
+ case SECURITY_MODE_NO_ACCESS:
+ case SECURITY_MODE_OPEN:
+ case SECURITY_MODE_ENC_NO_MITM:
+ case SECURITY_MODE_ENC_WITH_MITM:
+ case SECURITY_MODE_LESC_ENC_WITH_MITM:
+ case SECURITY_MODE_SIGNED_NO_MITM:
+ case SECURITY_MODE_SIGNED_WITH_MITM:
+ break;
+ default:
+ mp_raise_ValueError(translate("Invalid security_mode"));
+ break;
+ }
+}
diff --git a/shared-module/bleio/Attribute.h b/shared-module/bleio/Attribute.h
new file mode 100644
index 000000000..a498a14a5
--- /dev/null
+++ b/shared-module/bleio/Attribute.h
@@ -0,0 +1,41 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ *
+ * 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_MODULE_BLEIO_ATTRIBUTE_H
+#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ATTRIBUTE_H
+
+// BLE security modes: 0x<level><mode>
+typedef enum {
+ SECURITY_MODE_NO_ACCESS = 0x00,
+ SECURITY_MODE_OPEN = 0x11,
+ SECURITY_MODE_ENC_NO_MITM = 0x21,
+ SECURITY_MODE_ENC_WITH_MITM = 0x31,
+ SECURITY_MODE_LESC_ENC_WITH_MITM = 0x41,
+ SECURITY_MODE_SIGNED_NO_MITM = 0x12,
+ SECURITY_MODE_SIGNED_WITH_MITM = 0x22,
+} bleio_attribute_security_mode_t;
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ATTRIBUTE_H
diff --git a/shared-module/bleio/Characteristic.h b/shared-module/bleio/Characteristic.h
index 27b43588f..409a57c76 100644
--- a/shared-module/bleio/Characteristic.h
+++ b/shared-module/bleio/Characteristic.h
@@ -27,14 +27,17 @@
#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H
#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H
-// Flags for each characteristic property. Common across ports.
-typedef struct {
- bool broadcast : 1;
- bool read : 1;
- bool write_no_response : 1;
- bool write : 1;
- bool notify : 1;
- bool indicate : 1;
-} bleio_characteristic_properties_t;
+typedef enum {
+ CHAR_PROP_NONE = 0,
+ CHAR_PROP_BROADCAST = 1u << 0,
+ CHAR_PROP_INDICATE = 1u << 1,
+ CHAR_PROP_NOTIFY = 1u << 2,
+ CHAR_PROP_READ = 1u << 3,
+ CHAR_PROP_WRITE = 1u << 4,
+ CHAR_PROP_WRITE_NO_RESPONSE = 1u << 5,
+ CHAR_PROP_ALL = (CHAR_PROP_BROADCAST | CHAR_PROP_INDICATE | CHAR_PROP_NOTIFY |
+ CHAR_PROP_READ | CHAR_PROP_WRITE | CHAR_PROP_WRITE_NO_RESPONSE)
+} bleio_characteristic_properties_enum_t;
+typedef uint8_t bleio_characteristic_properties_t;
#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H
diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c
index 0678a3a3f..c1d70c5b0 100644
--- a/supervisor/shared/usb/usb.c
+++ b/supervisor/shared/usb/usb.c
@@ -25,6 +25,7 @@
*/
#include "tick.h"
+#include "py/objstr.h"
#include "shared-bindings/microcontroller/Processor.h"
#include "shared-module/usb_midi/__init__.h"
#include "supervisor/port.h"
@@ -43,13 +44,11 @@ void load_serial_number(void) {
uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH];
common_hal_mcu_processor_get_uid(raw_id);
- static const char nibble_to_hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F'};
for (int i = 0; i < COMMON_HAL_MCU_PROCESSOR_UID_LENGTH; i++) {
for (int j = 0; j < 2; j++) {
uint8_t nibble = (raw_id[i] >> (j * 4)) & 0xf;
// Strings are UTF-16-LE encoded.
- usb_serial_number[1 + i * 2 + j] = nibble_to_hex[nibble];
+ usb_serial_number[1 + i * 2 + j] = nibble_to_hex_upper[nibble];
}
}
}