summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHierophect <hierophect@gmail.com>2019-11-05 12:25:10 -0500
committerHierophect <hierophect@gmail.com>2019-11-05 12:25:10 -0500
commit1006c5600c3a4fd24265a1ee21643f5e80bc4e38 (patch)
tree72f44bf5b2ed0726a253c89b7527d48cb7c3428b
parentb9063dd2267b9eee4acb7f4b7e0ad6ab2101e253 (diff)
parent01bf9321692d00da8628b7b230be3b03665eff82 (diff)
Merge remote-tracking branch 'upstream/master'
-rw-r--r--.github/workflows/build.yml1
-rw-r--r--lib/utils/interrupt_char.c2
-rw-r--r--locale/ID.po151
-rw-r--r--locale/circuitpython.pot109
-rw-r--r--locale/de_DE.po172
-rw-r--r--locale/en_US.po109
-rw-r--r--locale/en_x_pirate.po109
-rw-r--r--locale/es.po147
-rw-r--r--locale/fil.po147
-rw-r--r--locale/fr.po151
-rw-r--r--locale/it_IT.po147
-rw-r--r--locale/pl.po147
-rw-r--r--locale/pt_BR.po147
-rw-r--r--locale/zh_Latn_pinyin.po168
-rwxr-xr-xmain.c13
-rw-r--r--ports/atmel-samd/boards/winterbloom_sol/board.c38
-rw-r--r--ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.h33
-rw-r--r--ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk27
-rw-r--r--ports/atmel-samd/boards/winterbloom_sol/pins.c15
-rw-r--r--ports/nrf/background.c7
-rw-r--r--ports/nrf/bluetooth/ble_drv.c28
-rw-r--r--ports/nrf/bluetooth/ble_drv.h7
-rw-r--r--ports/nrf/boards/adafruit_nrf52840_s140_v6.ld9
-rw-r--r--ports/nrf/common-hal/_bleio/Adapter.c526
-rw-r--r--ports/nrf/common-hal/_bleio/Adapter.h20
-rw-r--r--ports/nrf/common-hal/_bleio/Central.c145
-rw-r--r--ports/nrf/common-hal/_bleio/Characteristic.c126
-rw-r--r--ports/nrf/common-hal/_bleio/Characteristic.h5
-rw-r--r--ports/nrf/common-hal/_bleio/CharacteristicBuffer.c12
-rw-r--r--ports/nrf/common-hal/_bleio/Connection.c629
-rw-r--r--ports/nrf/common-hal/_bleio/Connection.h (renamed from ports/nrf/common-hal/_bleio/Peripheral.h)38
-rw-r--r--ports/nrf/common-hal/_bleio/Descriptor.c58
-rw-r--r--ports/nrf/common-hal/_bleio/Descriptor.h9
-rw-r--r--ports/nrf/common-hal/_bleio/Peripheral.c361
-rw-r--r--ports/nrf/common-hal/_bleio/Scanner.c105
-rw-r--r--ports/nrf/common-hal/_bleio/Service.c48
-rw-r--r--ports/nrf/common-hal/_bleio/Service.h12
-rw-r--r--ports/nrf/common-hal/_bleio/UUID.c23
-rw-r--r--ports/nrf/common-hal/_bleio/__init__.c489
-rw-r--r--ports/nrf/common-hal/_bleio/__init__.h5
-rw-r--r--ports/stm32f4/boards/feather_stm32f405_express/stm32f4xx_hal_conf.h2
-rw-r--r--ports/stm32f4/boards/pyboard_v11/stm32f4xx_hal_conf.h2
-rw-r--r--ports/stm32f4/boards/stm32f411ve_discovery/stm32f4xx_hal_conf.h2
-rw-r--r--ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h2
-rw-r--r--ports/stm32f4/common-hal/pulseio/PWMOut.c399
-rw-r--r--ports/stm32f4/common-hal/pulseio/PWMOut.h (renamed from shared-bindings/_bleio/Central.h)36
-rw-r--r--ports/stm32f4/common-hal/pulseio/PulseIn.c79
-rw-r--r--ports/stm32f4/common-hal/pulseio/PulseIn.h53
-rw-r--r--ports/stm32f4/common-hal/pulseio/PulseOut.c55
-rw-r--r--ports/stm32f4/common-hal/pulseio/PulseOut.h (renamed from ports/nrf/common-hal/_bleio/Central.h)24
-rw-r--r--ports/stm32f4/common-hal/pulseio/__init__.c1
-rw-r--r--ports/stm32f4/mpconfigport.mk1
-rw-r--r--ports/stm32f4/peripherals/stm32f4/periph.h16
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.c76
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.h5
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.c52
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.h5
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.c68
-rw-r--r--ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.h5
-rw-r--r--ports/stm32f4/supervisor/port.c2
-rw-r--r--py/circuitpy_defns.mk5
-rw-r--r--py/ringbuf.h7
-rw-r--r--py/vm.c2
-rw-r--r--shared-bindings/_bleio/Adapter.c300
-rw-r--r--shared-bindings/_bleio/Adapter.h28
-rw-r--r--shared-bindings/_bleio/Address.c30
-rw-r--r--shared-bindings/_bleio/Central.c207
-rw-r--r--shared-bindings/_bleio/Characteristic.c33
-rw-r--r--shared-bindings/_bleio/Characteristic.h6
-rw-r--r--shared-bindings/_bleio/Connection.c171
-rw-r--r--shared-bindings/_bleio/Connection.h (renamed from shared-bindings/_bleio/Scanner.h)19
-rw-r--r--shared-bindings/_bleio/Descriptor.c9
-rw-r--r--shared-bindings/_bleio/Descriptor.h2
-rw-r--r--shared-bindings/_bleio/Peripheral.c325
-rw-r--r--shared-bindings/_bleio/Peripheral.h48
-rw-r--r--shared-bindings/_bleio/ScanEntry.c74
-rw-r--r--shared-bindings/_bleio/ScanEntry.h3
-rw-r--r--shared-bindings/_bleio/ScanResults.c72
-rw-r--r--shared-bindings/_bleio/ScanResults.h (renamed from ports/nrf/common-hal/_bleio/Scanner.h)17
-rw-r--r--shared-bindings/_bleio/Scanner.c129
-rw-r--r--shared-bindings/_bleio/Service.c74
-rw-r--r--shared-bindings/_bleio/Service.h14
-rw-r--r--shared-bindings/_bleio/UUID.c51
-rw-r--r--shared-bindings/_bleio/UUID.h5
-rw-r--r--shared-bindings/_bleio/__init__.c19
-rw-r--r--shared-bindings/_bleio/__init__.h18
-rw-r--r--shared-module/_bleio/ScanEntry.c43
-rw-r--r--shared-module/_bleio/ScanEntry.h7
-rw-r--r--shared-module/_bleio/ScanResults.c139
-rw-r--r--shared-module/_bleio/ScanResults.h64
-rw-r--r--supervisor/shared/autoreload.c8
-rw-r--r--supervisor/shared/autoreload.h2
-rw-r--r--supervisor/shared/bluetooth.c340
-rw-r--r--supervisor/shared/bluetooth.h34
-rw-r--r--supervisor/shared/external_flash/devices.h17
-rw-r--r--supervisor/shared/safe_mode.h3
-rw-r--r--supervisor/supervisor.mk5
97 files changed, 4867 insertions, 2843 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index c393afe7d..10c34355d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -158,6 +158,7 @@ jobs:
- "trinket_m0_haxpress"
- "uchip"
- "ugame10"
+ - "winterbloom_sol"
steps:
- name: Set up Python 3.5
diff --git a/lib/utils/interrupt_char.c b/lib/utils/interrupt_char.c
index 91ee5c80e..da7f70254 100644
--- a/lib/utils/interrupt_char.c
+++ b/lib/utils/interrupt_char.c
@@ -49,7 +49,7 @@ void mp_keyboard_interrupt(void) {
// Check to see if we've been CTRL-C'ed by autoreload or the user.
bool mp_hal_is_interrupted(void) {
- return MP_STATE_VM(mp_pending_exception) == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception));
+ return MP_STATE_VM(mp_pending_exception) != NULL;
}
#endif
diff --git a/locale/ID.po b/locale/ID.po
index 63e3466b6..9c70789af 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-10-21 19:50-0700\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"
@@ -261,6 +261,10 @@ msgstr "Semua timer untuk pin ini sedang digunakan"
msgid "All timers in use"
msgstr "Semua timer sedang digunakan"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "fungsionalitas AnalogOut tidak didukung"
@@ -329,6 +333,11 @@ msgstr ""
msgid "Brightness not adjustable"
msgstr ""
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -465,6 +474,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr ""
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -507,7 +522,7 @@ msgstr ""
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, fuzzy
msgid "Data too large for advertisement packet"
msgstr "Tidak bisa menyesuaikan data ke dalam paket advertisment"
@@ -554,10 +569,6 @@ msgstr ""
msgid "Expected a Characteristic"
msgstr ""
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -567,7 +578,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr ""
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -576,6 +587,11 @@ msgstr ""
msgid "Expected tuple of length %d, got %d"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Failed initiate attribute read, err 0x%04x"
+msgstr ""
+
#: shared-bindings/ps2io/Ps2.c
msgid "Failed sending command."
msgstr ""
@@ -586,20 +602,14 @@ msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX"
#: ports/nrf/common-hal/_bleio/Service.c
-#, fuzzy, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Gagal untuk menambahkan karakteristik, status: 0x%08lX"
+msgid "Failed to add characteristic, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
msgid "Failed to add descriptor, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Gagal untuk mengalokasikan buffer RX"
@@ -611,25 +621,22 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Gagal untuk megalokasikan buffer RX dari %d byte"
#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to change softdevice state"
-msgstr "Gagal untuk merubah status softdevice, error: 0x%08lX"
+msgid "Failed to change softdevice state, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, fuzzy, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX"
+#: ports/nrf/common-hal/_bleio/Service.c
+msgid "Failed to create service, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
#, fuzzy
msgid "Failed to discover services"
msgstr "Gagal untuk menemukan layanan, status: 0x%08lX"
@@ -649,7 +656,7 @@ 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
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to pair"
msgstr ""
@@ -658,8 +665,7 @@ msgstr ""
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
+#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr ""
@@ -679,35 +685,27 @@ msgstr "Gagal untuk menambahkan Vendor Spesific UUID, status: 0x%08lX"
msgid "Failed to release mutex, err 0x%04x"
msgstr "Gagal untuk melepaskan mutex, status: 0x%08lX"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to start advertising, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "Gagal untuk memulai advertisement, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
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"
+#: ports/nrf/common-hal/_bleio/Connection.c
+msgid "Failed to start pairing, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, fuzzy, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Gagal untuk melakukan scanning, status: 0x%08lX"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to stop advertising, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
@@ -1004,9 +1002,8 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
#, fuzzy
msgid "Not connected"
msgstr "Tidak dapat menyambungkan ke AP"
@@ -1081,6 +1078,10 @@ msgstr "Tambahkan module apapun pada filesystem\n"
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1151,6 +1152,10 @@ msgstr ""
msgid "Sample rate too high. It must be less than %d"
msgstr "Nilai sampel terlalu tinggi. Nilai harus kurang dari %d"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1165,11 +1170,6 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr "Dukungan soft device, id: 0x%08lX, pc: 0x%08l"
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Memisahkan dengan menggunakan sub-captures"
@@ -1984,7 +1984,7 @@ msgstr ""
msgid "integer required"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2161,11 +2161,6 @@ msgstr ""
msgid "name '%q' is not defined"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c
-#, fuzzy
-msgid "name must be a string"
-msgstr "keyword harus berupa string"
-
#: py/runtime.c
msgid "name not defined"
msgstr ""
@@ -2216,7 +2211,7 @@ msgstr ""
msgid "no such attribute"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2700,7 +2695,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2770,10 +2765,22 @@ msgstr ""
#~ msgid "Failed to acquire mutex"
#~ msgstr "Gagal untuk mendapatkan mutex, status: 0x%08lX"
+#, fuzzy, c-format
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Gagal untuk menambahkan karakteristik, status: 0x%08lX"
+
#, fuzzy
#~ msgid "Failed to add service"
#~ msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX"
+#, fuzzy, c-format
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Gagal untuk menambahkan layanan, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Gagal untuk merubah status softdevice, error: 0x%08lX"
+
#, fuzzy
#~ msgid "Failed to connect:"
#~ msgstr "Gagal untuk menyambungkan, status: 0x%08lX"
@@ -2782,6 +2789,10 @@ msgstr ""
#~ msgid "Failed to continue scanning"
#~ msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX"
+#, fuzzy, c-format
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ msgstr "Gagal untuk melanjutkan scanning, status: 0x%08lX"
+
#, fuzzy
#~ msgid "Failed to create mutex"
#~ msgstr "Gagal untuk membuat mutex, status: 0x%08lX"
@@ -2802,6 +2813,10 @@ msgstr ""
#~ msgid "Failed to start advertising"
#~ msgstr "Gagal untuk memulai advertisement, status: 0x%08lX"
+#, fuzzy, c-format
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ msgstr "Gagal untuk memulai advertisement, status: 0x%08lX"
+
#, fuzzy
#~ msgid "Failed to start scanning"
#~ msgstr "Gagal untuk melakukan scanning, status: 0x%08lX"
@@ -2810,6 +2825,10 @@ msgstr ""
#~ msgid "Failed to stop advertising"
#~ msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX"
+#, fuzzy, c-format
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Gagal untuk memberhentikan advertisement, status: 0x%08lX"
+
#~ msgid "GPIO16 does not support pull up."
#~ msgstr "GPIO16 tidak mendukung pull up"
@@ -2859,6 +2878,10 @@ msgstr ""
#~ msgid "STA required"
#~ msgstr "STA dibutuhkan"
+#, fuzzy, c-format
+#~ msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
+#~ msgstr "Dukungan soft device, id: 0x%08lX, pc: 0x%08l"
+
#~ msgid "UART(%d) does not exist"
#~ msgstr "UART(%d) tidak ada"
@@ -2936,6 +2959,10 @@ msgstr ""
#~ msgid "memory allocation failed, allocating %u bytes for native code"
#~ msgstr "alokasi memori gagal, mengalokasikan %u byte untuk kode native"
+#, fuzzy
+#~ msgid "name must be a string"
+#~ msgstr "keyword harus berupa string"
+
#~ msgid "not a valid ADC Channel: %d"
#~ msgstr "tidak valid channel ADC: %d"
diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot
index d709a69cc..34aa3ff0a 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-10-21 19:50-0700\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"
@@ -259,6 +259,10 @@ msgstr ""
msgid "All timers in use"
msgstr ""
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr ""
@@ -325,6 +329,11 @@ msgstr ""
msgid "Brightness not adjustable"
msgstr ""
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -455,6 +464,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr ""
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -497,7 +512,7 @@ msgstr ""
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr ""
@@ -543,10 +558,6 @@ msgstr ""
msgid "Expected a Characteristic"
msgstr ""
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -556,7 +567,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr ""
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -565,6 +576,11 @@ msgstr ""
msgid "Expected tuple of length %d, got %d"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Failed initiate attribute read, err 0x%04x"
+msgstr ""
+
#: shared-bindings/ps2io/Ps2.c
msgid "Failed sending command."
msgstr ""
@@ -575,8 +591,7 @@ msgid "Failed to acquire mutex, err 0x%04x"
msgstr ""
#: ports/nrf/common-hal/_bleio/Service.c
-#, c-format
-msgid "Failed to add characteristic, err 0x%04x"
+msgid "Failed to add characteristic, NRF_ERROR_%q"
msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
@@ -584,11 +599,6 @@ msgstr ""
msgid "Failed to add descriptor, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr ""
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr ""
@@ -600,24 +610,22 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr ""
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to change softdevice state"
+msgid "Failed to change softdevice state, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to continue scanning, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Service.c
+msgid "Failed to create service, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to discover services"
msgstr ""
@@ -634,7 +642,7 @@ msgstr ""
msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to pair"
msgstr ""
@@ -643,8 +651,7 @@ msgstr ""
msgid "Failed to read CCCD value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#: ports/nrf/common-hal/_bleio/Descriptor.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr ""
@@ -664,34 +671,26 @@ msgstr ""
msgid "Failed to release mutex, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to start advertising, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
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"
+#: ports/nrf/common-hal/_bleio/Connection.c
+msgid "Failed to start pairing, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to stop advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to stop advertising, NRF_ERROR_%q"
msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
@@ -989,9 +988,8 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
msgid "Not connected"
msgstr ""
@@ -1065,6 +1063,10 @@ msgstr ""
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1131,6 +1133,10 @@ msgstr ""
msgid "Sample rate too high. It must be less than %d"
msgstr ""
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1145,11 +1151,6 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr ""
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr ""
@@ -1950,7 +1951,7 @@ msgstr ""
msgid "integer required"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2127,10 +2128,6 @@ msgstr ""
msgid "name '%q' is not defined"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c
-msgid "name must be a string"
-msgstr ""
-
#: py/runtime.c
msgid "name not defined"
msgstr ""
@@ -2181,7 +2178,7 @@ msgstr ""
msgid "no such attribute"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2663,7 +2660,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
diff --git a/locale/de_DE.po b/locale/de_DE.po
index 971687d19..afe97ff9f 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-10-21 19:50-0700\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: Pascal Deneaux\n"
"Language-Team: Sebastian Plamauer, Pascal Deneaux\n"
@@ -261,6 +261,10 @@ msgstr "Alle timer für diesen Pin werden bereits benutzt"
msgid "All timers in use"
msgstr "Alle timer werden benutzt"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "AnalogOut-Funktion wird nicht unterstützt"
@@ -329,6 +333,11 @@ msgstr "Die Helligkeit muss zwischen 0 und 255 liegen"
msgid "Brightness not adjustable"
msgstr "Die Helligkeit ist nicht einstellbar"
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -459,6 +468,12 @@ msgstr "Der Befehl muss zwischen 0 und 255 liegen"
msgid "Command must be an int between 0 and 255"
msgstr "Der Befehl muss ein int zwischen 0 und 255 sein"
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr "Beschädigte .mpy Datei"
@@ -501,7 +516,7 @@ msgstr "Data 0 pin muss am Byte ausgerichtet sein"
msgid "Data chunk must follow fmt chunk"
msgstr "Dem fmt Block muss ein Datenblock folgen"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr "Zu vielen Daten für das advertisement packet"
@@ -547,10 +562,6 @@ msgstr "Erwartet ein(e) %q"
msgid "Expected a Characteristic"
msgstr "Characteristic wird erwartet"
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr "Ein Peripheriegerät wird erwartet"
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr "Ein Service wird erwartet"
@@ -560,7 +571,7 @@ msgstr "Ein Service wird erwartet"
msgid "Expected a UUID"
msgstr "Eine UUID wird erwartet"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr "Erwartet eine Adresse"
@@ -569,6 +580,11 @@ msgstr "Erwartet eine Adresse"
msgid "Expected tuple of length %d, got %d"
msgstr "Habe ein Tupel der Länge %d erwartet aber %d erhalten"
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Failed initiate attribute read, err 0x%04x"
+msgstr ""
+
#: shared-bindings/ps2io/Ps2.c
msgid "Failed sending command."
msgstr "Kommando nicht gesendet."
@@ -579,20 +595,14 @@ msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Mutex konnte nicht akquiriert werden. Status: 0x%04x"
#: ports/nrf/common-hal/_bleio/Service.c
-#, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Hinzufügen des Characteristic ist gescheitert. Status: 0x%04x"
+msgid "Failed to add characteristic, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
msgid "Failed to add descriptor, err 0x%04x"
msgstr "Deskriptor konnte nicht hinzugefügt werden. Status: 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Dienst konnte nicht hinzugefügt werden. Status: 0x%04x"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Konnte keinen RX Buffer allozieren"
@@ -604,24 +614,22 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Konnte keine RX Buffer mit %d allozieren"
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to change softdevice state"
-msgstr "Fehler beim Ändern des Softdevice-Status"
+msgid "Failed to change softdevice state, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Failed to connect: timeout"
msgstr "Verbindung nicht erfolgreich: timeout"
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "Der Scanvorgang kann nicht fortgesetzt werden. Status: 0x%04x"
+#: ports/nrf/common-hal/_bleio/Service.c
+msgid "Failed to create service, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to discover services"
msgstr "Es konnten keine Dienste gefunden werden"
@@ -638,7 +646,7 @@ 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
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to pair"
msgstr "Koppeln fehlgeschlagen"
@@ -647,8 +655,7 @@ msgstr "Koppeln fehlgeschlagen"
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
+#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr "Kann Attributwert nicht lesen, Status: 0x%04x"
@@ -668,35 +675,27 @@ msgstr "Kann keine herstellerspezifische UUID hinzufügen. Status: 0x%04x"
msgid "Failed to release mutex, err 0x%04x"
msgstr "Mutex konnte nicht freigegeben werden. Status: 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr "Gerätename konnte nicht gesetzt werden, Status: 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "Kann advertisement nicht starten. Status: 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to start advertising, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
msgid "Failed to start connecting, error 0x%04x"
msgstr "Verbindung konnte nicht hergestellt werden. Status: 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start pairing, error 0x%04x"
-msgstr "Starten des Koppelns fehlgeschlagen, Status: 0x%04x"
+#: ports/nrf/common-hal/_bleio/Connection.c
+msgid "Failed to start pairing, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Kann advertisement nicht stoppen. Status: 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to stop advertising, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
@@ -1002,9 +1001,8 @@ msgstr "Kein Speicherplatz mehr verfügbar auf dem Gerät"
msgid "No such file/directory"
msgstr "Keine solche Datei/Verzeichnis"
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
msgid "Not connected"
msgstr "Nicht verbunden"
@@ -1033,7 +1031,8 @@ msgstr "Nur 8 oder 16 bit mono mit "
msgid ""
"Only Windows format, uncompressed BMP supported: given header size is %d"
msgstr ""
-"Nur Windows-Format, unkomprimiertes BMP unterstützt: die gegebene Header-Größe ist %d"
+"Nur Windows-Format, unkomprimiertes BMP unterstützt: die gegebene Header-"
+"Größe ist %d"
#: shared-module/displayio/OnDiskBitmap.c
#, c-format
@@ -1041,8 +1040,8 @@ msgid ""
"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: "
"%d bpp given"
msgstr ""
-"Nur monochrome, indizierte 4bpp oder 8bpp, und 16bpp oder größere BMPs unterstützt: "
-"%d bpp wurden gegeben"
+"Nur monochrome, indizierte 4bpp oder 8bpp, und 16bpp oder größere BMPs "
+"unterstützt: %d bpp wurden gegeben"
#: shared-bindings/_pixelbuf/PixelBuf.c
msgid "Only slices with step=1 (aka None) are supported"
@@ -1083,6 +1082,10 @@ msgstr "und alle Module im Dateisystem \n"
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1151,6 +1154,10 @@ msgstr "Abtastrate muss positiv sein"
msgid "Sample rate too high. It must be less than %d"
msgstr "Abtastrate zu hoch. Wert muss unter %d liegen"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1165,11 +1172,6 @@ msgstr "Slice und Wert (value) haben unterschiedliche Längen."
msgid "Slices not supported"
msgstr "Slices werden nicht unterstützt"
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr ""
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Splitting mit sub-captures"
@@ -1202,8 +1204,8 @@ msgid ""
"The `microcontroller` module was used to boot into safe mode. Press reset to "
"exit safe mode.\n"
msgstr ""
-"Das `Mikrocontroller` Modul wurde benutzt, um in den Sicherheitsmodus zu starten. "
-"Drücke Reset um den Sicherheitsmodus zu verlassen.\n"
+"Das `Mikrocontroller` Modul wurde benutzt, um in den Sicherheitsmodus zu "
+"starten. Drücke Reset um den Sicherheitsmodus zu verlassen.\n"
#: supervisor/shared/safe_mode.c
msgid ""
@@ -1740,7 +1742,8 @@ msgstr "Farbpuffer muss ein Puffer oder ein int sein"
#: shared-bindings/displayio/Palette.c
msgid "color buffer must be a bytearray or array of type 'b' or 'B'"
-msgstr "Farbpuffer muss ein Byte-Array oder ein Array vom Typ 'b' oder 'B' sein"
+msgstr ""
+"Farbpuffer muss ein Byte-Array oder ein Array vom Typ 'b' oder 'B' sein"
#: shared-bindings/displayio/Palette.c
msgid "color must be between 0x000000 and 0xffffff"
@@ -1996,7 +1999,7 @@ msgstr "int() arg 2 muss >= 2 und <= 36 sein"
msgid "integer required"
msgstr "integer erforderlich"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr "Das Intervall muss im Bereich %s-%s sein"
@@ -2179,10 +2182,6 @@ msgstr "muss Schlüsselwortargument für key function verwenden"
msgid "name '%q' is not defined"
msgstr "Name '%q' ist nirgends definiert worden (Schreibweise kontrollieren)"
-#: shared-bindings/_bleio/Peripheral.c
-msgid "name must be a string"
-msgstr "name muss ein String sein"
-
#: py/runtime.c
msgid "name not defined"
msgstr "Dieser Name ist nirgends definiert worden (Schreibweise kontrollieren)"
@@ -2233,7 +2232,7 @@ msgstr "kein Reset Pin verfügbar"
msgid "no such attribute"
msgstr "kein solches Attribut"
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2724,7 +2723,7 @@ msgstr "Wert muss in %d Byte(s) passen"
msgid "value_count must be > 0"
msgstr "value_count muss größer als 0 sein"
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2811,18 +2810,36 @@ msgstr ""
#~ msgid "Error in ffi_prep_cif"
#~ msgstr "Fehler in ffi_prep_cif"
+#~ msgid "Expected a Peripheral"
+#~ msgstr "Ein Peripheriegerät wird erwartet"
+
#~ msgid "Failed to acquire mutex"
#~ msgstr "Akquirieren des Mutex gescheitert"
+#, c-format
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Hinzufügen des Characteristic ist gescheitert. Status: 0x%04x"
+
#~ msgid "Failed to add service"
#~ msgstr "Dienst konnte nicht hinzugefügt werden"
+#, c-format
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Dienst konnte nicht hinzugefügt werden. Status: 0x%04x"
+
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Fehler beim Ändern des Softdevice-Status"
+
#~ msgid "Failed to connect:"
#~ msgstr "Verbindung fehlgeschlagen:"
#~ msgid "Failed to continue scanning"
#~ msgstr "Der Scanvorgang kann nicht fortgesetzt werden"
+#, c-format
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ msgstr "Der Scanvorgang kann nicht fortgesetzt werden. Status: 0x%04x"
+
#~ msgid "Failed to create mutex"
#~ msgstr "Erstellen des Mutex ist fehlgeschlagen"
@@ -2835,15 +2852,31 @@ msgstr ""
#~ msgid "Failed to release mutex"
#~ msgstr "Loslassen des Mutex gescheitert"
+#, c-format
+#~ msgid "Failed to set device name, err 0x%04x"
+#~ msgstr "Gerätename konnte nicht gesetzt werden, Status: 0x%04x"
+
#~ msgid "Failed to start advertising"
#~ msgstr "Kann advertisement nicht starten"
+#, c-format
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ msgstr "Kann advertisement nicht starten. Status: 0x%04x"
+
+#, c-format
+#~ msgid "Failed to start pairing, error 0x%04x"
+#~ msgstr "Starten des Koppelns fehlgeschlagen, Status: 0x%04x"
+
#~ msgid "Failed to start scanning"
#~ msgstr "Der Scanvorgang kann nicht gestartet werden"
#~ msgid "Failed to stop advertising"
#~ msgstr "Kann advertisement nicht stoppen"
+#, c-format
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Kann advertisement nicht stoppen. Status: 0x%04x"
+
#~ msgid "Function requires lock."
#~ msgstr ""
#~ "Die Funktion erwartet, dass der 'lock'-Befehl zuvor ausgeführt wurde"
@@ -2977,6 +3010,9 @@ msgstr ""
#~ msgstr ""
#~ "Speicherallozierung fehlgeschlagen, alloziere %u Bytes für nativen Code"
+#~ msgid "name must be a string"
+#~ msgstr "name muss ein String sein"
+
#~ msgid "not a valid ADC Channel: %d"
#~ msgstr "Kein gültiger ADC Kanal: %d"
diff --git a/locale/en_US.po b/locale/en_US.po
index 652053ee9..b30e17cec 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-10-21 19:50-0700\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -259,6 +259,10 @@ msgstr ""
msgid "All timers in use"
msgstr ""
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr ""
@@ -325,6 +329,11 @@ msgstr ""
msgid "Brightness not adjustable"
msgstr ""
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -455,6 +464,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr ""
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -497,7 +512,7 @@ msgstr ""
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr ""
@@ -543,10 +558,6 @@ msgstr ""
msgid "Expected a Characteristic"
msgstr ""
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -556,7 +567,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr ""
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -565,6 +576,11 @@ msgstr ""
msgid "Expected tuple of length %d, got %d"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Failed initiate attribute read, err 0x%04x"
+msgstr ""
+
#: shared-bindings/ps2io/Ps2.c
msgid "Failed sending command."
msgstr ""
@@ -575,8 +591,7 @@ msgid "Failed to acquire mutex, err 0x%04x"
msgstr ""
#: ports/nrf/common-hal/_bleio/Service.c
-#, c-format
-msgid "Failed to add characteristic, err 0x%04x"
+msgid "Failed to add characteristic, NRF_ERROR_%q"
msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
@@ -584,11 +599,6 @@ msgstr ""
msgid "Failed to add descriptor, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr ""
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr ""
@@ -600,24 +610,22 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr ""
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to change softdevice state"
+msgid "Failed to change softdevice state, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to continue scanning, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Service.c
+msgid "Failed to create service, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to discover services"
msgstr ""
@@ -634,7 +642,7 @@ msgstr ""
msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to pair"
msgstr ""
@@ -643,8 +651,7 @@ msgstr ""
msgid "Failed to read CCCD value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#: ports/nrf/common-hal/_bleio/Descriptor.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr ""
@@ -664,34 +671,26 @@ msgstr ""
msgid "Failed to release mutex, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to start advertising, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
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"
+#: ports/nrf/common-hal/_bleio/Connection.c
+msgid "Failed to start pairing, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to stop advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to stop advertising, NRF_ERROR_%q"
msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
@@ -989,9 +988,8 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
msgid "Not connected"
msgstr ""
@@ -1065,6 +1063,10 @@ msgstr ""
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1131,6 +1133,10 @@ msgstr ""
msgid "Sample rate too high. It must be less than %d"
msgstr ""
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1145,11 +1151,6 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr ""
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr ""
@@ -1950,7 +1951,7 @@ msgstr ""
msgid "integer required"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2127,10 +2128,6 @@ msgstr ""
msgid "name '%q' is not defined"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c
-msgid "name must be a string"
-msgstr ""
-
#: py/runtime.c
msgid "name not defined"
msgstr ""
@@ -2181,7 +2178,7 @@ msgstr ""
msgid "no such attribute"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2663,7 +2660,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po
index 1d2fcb659..f9bb0a400 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-10-21 19:50-0700\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: @sommersoft, @MrCertainly\n"
@@ -261,6 +261,10 @@ msgstr ""
msgid "All timers in use"
msgstr ""
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr ""
@@ -329,6 +333,11 @@ msgstr ""
msgid "Brightness not adjustable"
msgstr ""
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -459,6 +468,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr ""
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -501,7 +516,7 @@ msgstr ""
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr ""
@@ -547,10 +562,6 @@ msgstr ""
msgid "Expected a Characteristic"
msgstr ""
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -560,7 +571,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr ""
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -569,6 +580,11 @@ msgstr ""
msgid "Expected tuple of length %d, got %d"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Failed initiate attribute read, err 0x%04x"
+msgstr ""
+
#: shared-bindings/ps2io/Ps2.c
msgid "Failed sending command."
msgstr ""
@@ -579,8 +595,7 @@ msgid "Failed to acquire mutex, err 0x%04x"
msgstr ""
#: ports/nrf/common-hal/_bleio/Service.c
-#, c-format
-msgid "Failed to add characteristic, err 0x%04x"
+msgid "Failed to add characteristic, NRF_ERROR_%q"
msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
@@ -588,11 +603,6 @@ msgstr ""
msgid "Failed to add descriptor, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr ""
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr ""
@@ -604,24 +614,22 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr ""
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to change softdevice state"
+msgid "Failed to change softdevice state, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to continue scanning, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Service.c
+msgid "Failed to create service, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to discover services"
msgstr ""
@@ -638,7 +646,7 @@ msgstr ""
msgid "Failed to notify or indicate attribute value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to pair"
msgstr ""
@@ -647,8 +655,7 @@ msgstr ""
msgid "Failed to read CCCD value, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Characteristic.c
-#: ports/nrf/common-hal/_bleio/Descriptor.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr ""
@@ -668,34 +675,26 @@ msgstr ""
msgid "Failed to release mutex, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr ""
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to start advertising, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
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"
+#: ports/nrf/common-hal/_bleio/Connection.c
+msgid "Failed to start pairing, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to stop advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to stop advertising, NRF_ERROR_%q"
msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
@@ -993,9 +992,8 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
msgid "Not connected"
msgstr ""
@@ -1069,6 +1067,10 @@ msgstr ""
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1135,6 +1137,10 @@ msgstr ""
msgid "Sample rate too high. It must be less than %d"
msgstr ""
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1149,11 +1155,6 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr ""
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr ""
@@ -1954,7 +1955,7 @@ msgstr ""
msgid "integer required"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2131,10 +2132,6 @@ msgstr ""
msgid "name '%q' is not defined"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c
-msgid "name must be a string"
-msgstr ""
-
#: py/runtime.c
msgid "name not defined"
msgstr ""
@@ -2185,7 +2182,7 @@ msgstr ""
msgid "no such attribute"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2667,7 +2664,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
diff --git a/locale/es.po b/locale/es.po
index ca8593dcd..8bcfcedbe 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-10-21 19:50-0700\n"
"PO-Revision-Date: 2018-08-24 22:56-0500\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -263,6 +263,10 @@ msgstr "Todos los timers para este pin están siendo utilizados"
msgid "All timers in use"
msgstr "Todos los timers en uso"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "Funcionalidad AnalogOut no soportada"
@@ -333,6 +337,11 @@ msgstr "El brillo debe estar entro 0 y 255"
msgid "Brightness not adjustable"
msgstr "El brillo no se puede ajustar"
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -463,6 +472,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr "Command debe estar entre 0 y 255."
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -505,7 +520,7 @@ msgstr "El pin Data 0 debe estar alineado a bytes"
msgid "Data chunk must follow fmt chunk"
msgstr "Trozo de datos debe seguir fmt chunk"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr "Data es muy grande para el paquete de advertisement."
@@ -551,10 +566,6 @@ msgstr "Se espera un %q"
msgid "Expected a Characteristic"
msgstr "Se esperaba una Característica."
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -564,7 +575,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr "Se esperaba un UUID"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -573,6 +584,11 @@ msgstr ""
msgid "Expected tuple of length %d, got %d"
msgstr "Se esperaba un tuple de %d, se obtuvo %d"
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Failed initiate attribute read, err 0x%04x"
+msgstr ""
+
#: shared-bindings/ps2io/Ps2.c
msgid "Failed sending command."
msgstr "Fallo enviando comando"
@@ -583,20 +599,14 @@ msgid "Failed to acquire mutex, err 0x%04x"
msgstr "No se puede adquirir el mutex, status: 0x%08lX"
#: ports/nrf/common-hal/_bleio/Service.c
-#, fuzzy, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Fallo al añadir caracteristica, err: 0x%08lX"
+msgid "Failed to add characteristic, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
msgid "Failed to add descriptor, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Fallo al agregar servicio. err: 0x%02x"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Ha fallado la asignación del buffer RX"
@@ -608,24 +618,22 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Falló la asignación del buffer RX de %d bytes"
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to change softdevice state"
-msgstr "No se puede cambiar el estado del softdevice"
+msgid "Failed to change softdevice state, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "No se puede iniciar el escaneo. err: 0x%02x"
+#: ports/nrf/common-hal/_bleio/Service.c
+msgid "Failed to create service, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
#, fuzzy
msgid "Failed to discover services"
msgstr "No se puede descubrir servicios"
@@ -643,7 +651,7 @@ 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
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to pair"
msgstr ""
@@ -652,8 +660,7 @@ msgstr ""
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
+#: ports/nrf/common-hal/_bleio/__init__.c
#, fuzzy, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr "Error al leer valor del atributo, err 0x%04"
@@ -673,35 +680,27 @@ msgstr "Fallo al registrar el Vendor-Specific UUID, err 0x%04x"
msgid "Failed to release mutex, err 0x%04x"
msgstr "No se puede liberar el mutex, err 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to start advertising, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "No se puede inicar el anuncio. err: 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
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"
+#: ports/nrf/common-hal/_bleio/Connection.c
+msgid "Failed to start pairing, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "No se puede iniciar el escaneo. err 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "No se puede detener el anuncio. err: 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to stop advertising, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
@@ -1004,9 +1003,8 @@ msgstr "No queda espacio en el dispositivo"
msgid "No such file/directory"
msgstr "No existe el archivo/directorio"
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
msgid "Not connected"
msgstr "No conectado"
@@ -1088,6 +1086,10 @@ msgstr "Incapaz de montar de nuevo el sistema de archivos"
msgid "Pop from an empty Ps2 buffer"
msgstr "Pop de un buffer Ps2 vacio"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1157,6 +1159,10 @@ msgstr "Sample rate debe ser positivo"
msgid "Sample rate too high. It must be less than %d"
msgstr "Frecuencia de muestreo demasiado alta. Debe ser menor a %d"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1171,11 +1177,6 @@ msgstr "Slice y value tienen diferentes longitudes"
msgid "Slices not supported"
msgstr "Rebanadas no soportadas"
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Dividiendo con sub-capturas"
@@ -2004,7 +2005,7 @@ msgstr "int() arg 2 debe ser >= 2 y <= 36"
msgid "integer required"
msgstr "Entero requerido"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2184,10 +2185,6 @@ msgstr "debe utilizar argumento de palabra clave para la función clave"
msgid "name '%q' is not defined"
msgstr "name '%q' no esta definido"
-#: shared-bindings/_bleio/Peripheral.c
-msgid "name must be a string"
-msgstr "name debe de ser un string"
-
#: py/runtime.c
msgid "name not defined"
msgstr "name no definido"
@@ -2238,7 +2235,7 @@ msgstr ""
msgid "no such attribute"
msgstr "no hay tal atributo"
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2728,7 +2725,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2818,10 +2815,21 @@ msgstr "paso cero"
#~ msgid "Failed to acquire mutex"
#~ msgstr "No se puede adquirir el mutex, status: 0x%08lX"
+#, fuzzy, c-format
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Fallo al añadir caracteristica, err: 0x%08lX"
+
#, fuzzy
#~ msgid "Failed to add service"
#~ msgstr "No se puede detener el anuncio. status: 0x%02x"
+#, c-format
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Fallo al agregar servicio. err: 0x%02x"
+
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "No se puede cambiar el estado del softdevice"
+
#, fuzzy
#~ msgid "Failed to connect:"
#~ msgstr "No se puede conectar. status: 0x%02x"
@@ -2830,6 +2838,10 @@ msgstr "paso cero"
#~ msgid "Failed to continue scanning"
#~ msgstr "No se puede iniciar el escaneo. status: 0x%02x"
+#, c-format
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ msgstr "No se puede iniciar el escaneo. err: 0x%02x"
+
#, fuzzy
#~ msgid "Failed to create mutex"
#~ msgstr "No se puede leer el valor del atributo. status 0x%02x"
@@ -2850,6 +2862,10 @@ msgstr "paso cero"
#~ msgid "Failed to start advertising"
#~ msgstr "No se puede inicar el anuncio. status: 0x%02x"
+#, c-format
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ msgstr "No se puede inicar el anuncio. err: 0x%04x"
+
#, fuzzy
#~ msgid "Failed to start scanning"
#~ msgstr "No se puede iniciar el escaneo. status: 0x%02x"
@@ -2858,6 +2874,10 @@ msgstr "paso cero"
#~ msgid "Failed to stop advertising"
#~ msgstr "No se puede detener el anuncio. status: 0x%02x"
+#, c-format
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "No se puede detener el anuncio. err: 0x%04x"
+
#~ msgid "Function requires lock."
#~ msgstr "La función requiere lock"
@@ -2932,6 +2952,10 @@ msgstr "paso cero"
#~ msgid "STA required"
#~ msgstr "STA requerido"
+#, c-format
+#~ msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
+#~ msgstr "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
+
#~ msgid "Tile indices must be 0 - 255"
#~ msgstr "Los índices de Tile deben ser 0 - 255"
@@ -3027,6 +3051,9 @@ msgstr "paso cero"
#~ msgstr ""
#~ "falló la asignación de memoria, asignando %u bytes para código nativo"
+#~ msgid "name must be a string"
+#~ msgstr "name debe de ser un string"
+
#~ msgid "not a valid ADC Channel: %d"
#~ msgstr "no es un canal ADC válido: %d"
diff --git a/locale/fil.po b/locale/fil.po
index 6f460c94c..2223ee779 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-10-21 19:50-0700\n"
"PO-Revision-Date: 2018-12-20 22:15-0800\n"
"Last-Translator: Timothy <me@timothygarcia.ca>\n"
"Language-Team: fil\n"
@@ -263,6 +263,10 @@ msgstr "Lahat ng timers para sa pin na ito ay ginagamit"
msgid "All timers in use"
msgstr "Lahat ng timer ginagamit"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "Hindi supportado ang AnalogOut"
@@ -331,6 +335,11 @@ msgstr "Ang liwanag ay dapat sa gitna ng 0 o 255"
msgid "Brightness not adjustable"
msgstr ""
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -464,6 +473,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr "Sa gitna ng 0 o 255 dapat ang bytes."
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -507,7 +522,7 @@ msgstr "graphic ay dapat 2048 bytes ang haba"
msgid "Data chunk must follow fmt chunk"
msgstr "Dapat sunurin ng Data chunk ang fmt chunk"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, fuzzy
msgid "Data too large for advertisement packet"
msgstr "Hindi makasya ang data sa loob ng advertisement packet"
@@ -556,10 +571,6 @@ msgstr "Umasa ng %q"
msgid "Expected a Characteristic"
msgstr "Hindi mabasa and Characteristic."
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -570,7 +581,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr "Umasa ng %q"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -579,6 +590,11 @@ msgstr ""
msgid "Expected tuple of length %d, got %d"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Failed initiate attribute read, err 0x%04x"
+msgstr ""
+
#: shared-bindings/ps2io/Ps2.c
msgid "Failed sending command."
msgstr ""
@@ -589,20 +605,14 @@ msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX"
#: ports/nrf/common-hal/_bleio/Service.c
-#, fuzzy, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Nabigo sa paglagay ng characteristic, status: 0x%08lX"
+msgid "Failed to add characteristic, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
msgid "Failed to add descriptor, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Hindi matagumpay ang paglagay ng service, status: 0x%08lX"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Nabigong ilaan ang RX buffer"
@@ -614,25 +624,22 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Nabigong ilaan ang RX buffer ng %d bytes"
#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to change softdevice state"
-msgstr "Nabigo sa pagbago ng softdevice state, error: 0x%08lX"
+msgid "Failed to change softdevice state, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, fuzzy, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX"
+#: ports/nrf/common-hal/_bleio/Service.c
+msgid "Failed to create service, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
#, fuzzy
msgid "Failed to discover services"
msgstr "Nabigo sa pagdiscover ng services, status: 0x%08lX"
@@ -652,7 +659,7 @@ 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
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to pair"
msgstr ""
@@ -661,8 +668,7 @@ msgstr ""
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
+#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr ""
@@ -682,35 +688,27 @@ msgstr "Hindi matagumpay ang paglagay ng Vender Specific UUID, status: 0x%08lX"
msgid "Failed to release mutex, err 0x%04x"
msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to start advertising, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX"
-
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
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"
+#: ports/nrf/common-hal/_bleio/Connection.c
+msgid "Failed to start pairing, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, fuzzy, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Hindi masimulaan mag i-scan, status: 0x%0xlX"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Hindi mahinto ang advertisement, status: 0x%08lX"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to stop advertising, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
@@ -1013,9 +1011,8 @@ msgstr ""
msgid "No such file/directory"
msgstr "Walang file/directory"
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
#, fuzzy
msgid "Not connected"
msgstr "Hindi maka connect sa AP"
@@ -1094,6 +1091,10 @@ msgstr "Kasama ang kung ano pang modules na sa filesystem\n"
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1164,6 +1165,10 @@ msgstr "Sample rate ay dapat positibo"
msgid "Sample rate too high. It must be less than %d"
msgstr "Sample rate ay masyadong mataas. Ito ay dapat hindi hiigit sa %d"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1178,11 +1183,6 @@ msgstr "Slice at value iba't ibang haba."
msgid "Slices not supported"
msgstr "Hindi suportado ang Slices"
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr ""
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Binibiyak gamit ang sub-captures"
@@ -2016,7 +2016,7 @@ msgstr "int() arg 2 ay dapat >=2 at <= 36"
msgid "integer required"
msgstr "kailangan ng int"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2197,11 +2197,6 @@ msgstr "dapat gumamit ng keyword argument para sa key function"
msgid "name '%q' is not defined"
msgstr "name '%q' ay hindi defined"
-#: shared-bindings/_bleio/Peripheral.c
-#, fuzzy
-msgid "name must be a string"
-msgstr "ang keywords dapat strings"
-
#: py/runtime.c
msgid "name not defined"
msgstr "name hindi na define"
@@ -2252,7 +2247,7 @@ msgstr ""
msgid "no such attribute"
msgstr "walang ganoon na attribute"
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2741,7 +2736,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2825,10 +2820,22 @@ msgstr "zero step"
#~ msgid "Failed to acquire mutex"
#~ msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX"
+#, fuzzy, c-format
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Nabigo sa paglagay ng characteristic, status: 0x%08lX"
+
#, fuzzy
#~ msgid "Failed to add service"
#~ msgstr "Hindi matagumpay ang paglagay ng service, status: 0x%08lX"
+#, fuzzy, c-format
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Hindi matagumpay ang paglagay ng service, status: 0x%08lX"
+
+#, fuzzy
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Nabigo sa pagbago ng softdevice state, error: 0x%08lX"
+
#, fuzzy
#~ msgid "Failed to connect:"
#~ msgstr "Hindi makaconnect, status: 0x%08lX"
@@ -2837,6 +2844,10 @@ msgstr "zero step"
#~ msgid "Failed to continue scanning"
#~ msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX"
+#, fuzzy, c-format
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ msgstr "Hindi maituloy ang pag scan, status: 0x%0xlX"
+
#, fuzzy
#~ msgid "Failed to create mutex"
#~ msgstr "Hindi matagumpay ang pagbuo ng mutex, status: 0x%0xlX"
@@ -2857,6 +2868,10 @@ msgstr "zero step"
#~ msgid "Failed to start advertising"
#~ msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX"
+#, fuzzy, c-format
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ msgstr "Hindi masimulaan ang advertisement, status: 0x%08lX"
+
#, fuzzy
#~ msgid "Failed to start scanning"
#~ msgstr "Hindi masimulaan mag i-scan, status: 0x%0xlX"
@@ -2865,6 +2880,10 @@ msgstr "zero step"
#~ msgid "Failed to stop advertising"
#~ msgstr "Hindi mahinto ang advertisement, status: 0x%08lX"
+#, fuzzy, c-format
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Hindi mahinto ang advertisement, status: 0x%08lX"
+
#~ msgid "Function requires lock."
#~ msgstr "Kailangan ng lock ang function."
@@ -3010,6 +3029,10 @@ msgstr "zero step"
#~ msgstr ""
#~ "nabigo ang paglalaan ng memorya, naglalaan ng %u bytes para sa native code"
+#, fuzzy
+#~ msgid "name must be a string"
+#~ msgstr "ang keywords dapat strings"
+
#~ msgid "not a valid ADC Channel: %d"
#~ msgstr "hindi tamang ADC Channel: %d"
diff --git a/locale/fr.po b/locale/fr.po
index c176fd8bc..913637675 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-10-21 19:50-0700\n"
"PO-Revision-Date: 2019-04-14 20:05+0100\n"
"Last-Translator: Pierrick Couturier <arofarn@arofarn.info>\n"
"Language-Team: fr\n"
@@ -266,6 +266,10 @@ msgstr "Tous les timers pour cette broche sont utilisés"
msgid "All timers in use"
msgstr "Tous les timers sont utilisés"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "Fonctionnalité AnalogOut non supportée"
@@ -336,6 +340,11 @@ msgstr "La luminosité doit être entre 0 et 255"
msgid "Brightness not adjustable"
msgstr "Luminosité non-ajustable"
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -470,6 +479,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr "La commande doit être un entier entre 0 et 255"
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -513,7 +528,7 @@ msgstr "La broche 'Data 0' doit être aligné sur l'octet"
msgid "Data chunk must follow fmt chunk"
msgstr "Un bloc de données doit suivre un bloc de format"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr "Données trop volumineuses pour un paquet de diffusion"
@@ -560,10 +575,6 @@ msgstr "Attendu un %q"
msgid "Expected a Characteristic"
msgstr "Une 'Characteristic' est attendue"
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -574,7 +585,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr "Un UUID est attendu"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -583,6 +594,11 @@ msgstr ""
msgid "Expected tuple of length %d, got %d"
msgstr "Tuple de longueur %d attendu, obtenu %d"
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Failed initiate attribute read, err 0x%04x"
+msgstr ""
+
#: shared-bindings/ps2io/Ps2.c
msgid "Failed sending command."
msgstr ""
@@ -593,20 +609,14 @@ msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Echec de l'obtention de mutex, err 0x%04x"
#: ports/nrf/common-hal/_bleio/Service.c
-#, fuzzy, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Echec de l'ajout de caractéristique, err 0x%04x"
+msgid "Failed to add characteristic, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
msgid "Failed to add descriptor, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Echec de l'ajout de service, err 0x%04x"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Echec de l'allocation du tampon RX"
@@ -618,25 +628,22 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Echec de l'allocation de %d octets du tampon RX"
#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to change softdevice state"
-msgstr "Echec de la modification de l'état du périphérique"
+msgid "Failed to change softdevice state, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, fuzzy, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "Impossible de poursuivre le scan, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Service.c
+msgid "Failed to create service, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
#, fuzzy
msgid "Failed to discover services"
msgstr "Echec de la découverte de services"
@@ -657,7 +664,7 @@ 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
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to pair"
msgstr ""
@@ -666,8 +673,7 @@ msgstr ""
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
+#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr "Impossible de lire la valeur de l'attribut, err 0x%04x"
@@ -687,35 +693,27 @@ msgstr "Echec de l'ajout de l'UUID du fournisseur, err 0x%04x"
msgid "Failed to release mutex, err 0x%04x"
msgstr "Impossible de libérer mutex, err 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to start advertising, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "Impossible de commencer à diffuser, err 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
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"
+#: ports/nrf/common-hal/_bleio/Connection.c
+msgid "Failed to start pairing, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, fuzzy, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Impossible de commencer à scanner, err 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Echec de l'arrêt de diffusion, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to stop advertising, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
@@ -1022,9 +1020,8 @@ 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/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
#, fuzzy
msgid "Not connected"
msgstr "Non connecté"
@@ -1111,6 +1108,10 @@ msgstr "Ainsi que tout autre module présent sur le système de fichiers\n"
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr "Appuyez sur une touche pour entrer sur REPL ou CTRL-D pour recharger."
@@ -1180,6 +1181,10 @@ msgstr "Le taux d'échantillonage doit être positif"
msgid "Sample rate too high. It must be less than %d"
msgstr "Taux d'échantillonage trop élevé. Doit être inf. à %d"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1194,11 +1199,6 @@ msgstr "Tranche et valeur de tailles différentes"
msgid "Slices not supported"
msgstr "Tranches non supportées"
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr "Assertion en mode 'soft-device', id: 0x%08lX, pc: 0x%08lX"
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Fractionnement avec des sous-captures"
@@ -2048,7 +2048,7 @@ msgstr "l'argument 2 de int() doit être >=2 et <=36"
msgid "integer required"
msgstr "entier requis"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2229,11 +2229,6 @@ msgstr "doit utiliser un argument nommé pour une fonction key"
msgid "name '%q' is not defined"
msgstr "nom '%q' non défini"
-#: shared-bindings/_bleio/Peripheral.c
-#, fuzzy
-msgid "name must be a string"
-msgstr "les noms doivent être des chaînes de caractère"
-
#: py/runtime.c
msgid "name not defined"
msgstr "nom non défini"
@@ -2285,7 +2280,7 @@ msgstr ""
msgid "no such attribute"
msgstr "pas de tel attribut"
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2783,7 +2778,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr "'value_count' doit être > 0"
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2873,10 +2868,22 @@ msgstr "'step' nul"
#~ msgid "Failed to acquire mutex"
#~ msgstr "Echec de l'obtention de mutex"
+#, fuzzy, c-format
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Echec de l'ajout de caractéristique, err 0x%04x"
+
#, fuzzy
#~ msgid "Failed to add service"
#~ msgstr "Echec de l'ajout de service"
+#, fuzzy, c-format
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Echec de l'ajout de service, err 0x%04x"
+
+#, fuzzy
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Echec de la modification de l'état du périphérique"
+
#, fuzzy
#~ msgid "Failed to connect:"
#~ msgstr "Echec de connection:"
@@ -2885,6 +2892,10 @@ msgstr "'step' nul"
#~ msgid "Failed to continue scanning"
#~ msgstr "Impossible de poursuivre le scan"
+#, fuzzy, c-format
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ msgstr "Impossible de poursuivre le scan, err 0x%04x"
+
#, fuzzy
#~ msgid "Failed to create mutex"
#~ msgstr "Echec de la création de mutex"
@@ -2905,6 +2916,10 @@ msgstr "'step' nul"
#~ msgid "Failed to start advertising"
#~ msgstr "Echec du démarrage de la diffusion"
+#, fuzzy, c-format
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ msgstr "Impossible de commencer à diffuser, err 0x%04x"
+
#, fuzzy
#~ msgid "Failed to start scanning"
#~ msgstr "Impossible de commencer à scanner"
@@ -2913,6 +2928,10 @@ msgstr "'step' nul"
#~ msgid "Failed to stop advertising"
#~ msgstr "Echec de l'arrêt de diffusion"
+#, fuzzy, c-format
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Echec de l'arrêt de diffusion, err 0x%04x"
+
#~ msgid "Function requires lock."
#~ msgstr "La fonction nécessite un verrou."
@@ -2984,6 +3003,10 @@ msgstr "'step' nul"
#~ msgid "STA required"
#~ msgstr "'STA' requis"
+#, c-format
+#~ msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
+#~ msgstr "Assertion en mode 'soft-device', id: 0x%08lX, pc: 0x%08lX"
+
#~ msgid "Tile indices must be 0 - 255"
#~ msgstr "Les indices des tuiles doivent être compris entre 0 et 255 "
@@ -3077,6 +3100,10 @@ msgstr "'step' nul"
#~ msgstr ""
#~ "l'allocation de mémoire a échoué en allouant %u octets pour un code natif"
+#, fuzzy
+#~ msgid "name must be a string"
+#~ msgstr "les noms doivent être des chaînes de caractère"
+
#~ msgid "not a valid ADC Channel: %d"
#~ msgstr "canal ADC non valide : %d"
diff --git a/locale/it_IT.po b/locale/it_IT.po
index 883c65d41..d4035fdf0 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-10-21 19:50-0700\n"
"PO-Revision-Date: 2018-10-02 16:27+0200\n"
"Last-Translator: Enrico Paganin <enrico.paganin@mail.com>\n"
"Language-Team: \n"
@@ -262,6 +262,10 @@ msgstr "Tutti i timer per questo pin sono in uso"
msgid "All timers in use"
msgstr "Tutti i timer utilizzati"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "funzionalità AnalogOut non supportata"
@@ -331,6 +335,11 @@ msgstr "La luminosità deve essere compreso tra 0 e 255"
msgid "Brightness not adjustable"
msgstr "Illiminazione non è regolabile"
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -465,6 +474,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr "I byte devono essere compresi tra 0 e 255"
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -508,7 +523,7 @@ msgstr "graphic deve essere lunga 2048 byte"
msgid "Data chunk must follow fmt chunk"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, fuzzy
msgid "Data too large for advertisement packet"
msgstr "Impossibile inserire dati nel pacchetto di advertisement."
@@ -556,10 +571,6 @@ msgstr "Atteso un %q"
msgid "Expected a Characteristic"
msgstr "Non è possibile aggiungere Characteristic."
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -570,7 +581,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr "Atteso un %q"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -579,6 +590,11 @@ msgstr ""
msgid "Expected tuple of length %d, got %d"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Failed initiate attribute read, err 0x%04x"
+msgstr ""
+
#: shared-bindings/ps2io/Ps2.c
msgid "Failed sending command."
msgstr ""
@@ -589,20 +605,14 @@ msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
#: ports/nrf/common-hal/_bleio/Service.c
-#, fuzzy, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Impossibile fermare advertisement. status: 0x%02x"
+msgid "Failed to add characteristic, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
msgid "Failed to add descriptor, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Impossibile fermare advertisement. status: 0x%02x"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Impossibile allocare buffer RX"
@@ -614,25 +624,22 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Fallita allocazione del buffer RX di %d byte"
#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to change softdevice state"
-msgstr "Impossibile fermare advertisement. status: 0x%02x"
+msgid "Failed to change softdevice state, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, fuzzy, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "Impossible iniziare la scansione. status: 0x%02x"
+#: ports/nrf/common-hal/_bleio/Service.c
+msgid "Failed to create service, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
#, fuzzy
msgid "Failed to discover services"
msgstr "Impossibile fermare advertisement. status: 0x%02x"
@@ -651,7 +658,7 @@ 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
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to pair"
msgstr ""
@@ -660,8 +667,7 @@ msgstr ""
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
+#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr "Tentative leggere attribute value fallito, err 0x%04x"
@@ -681,35 +687,27 @@ msgstr "Non è possibile aggiungere l'UUID del vendor specifico da 128-bit"
msgid "Failed to release mutex, err 0x%04x"
msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to start advertising, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "Impossibile avviare advertisement. status: 0x%02x"
-
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
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"
+#: ports/nrf/common-hal/_bleio/Connection.c
+msgid "Failed to start pairing, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, fuzzy, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Impossible iniziare la scansione. status: 0x%02x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Impossibile fermare advertisement. status: 0x%02x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to stop advertising, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
@@ -1012,9 +1010,8 @@ msgstr "Non che spazio sul dispositivo"
msgid "No such file/directory"
msgstr "Nessun file/directory esistente"
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
#, fuzzy
msgid "Not connected"
msgstr "Impossible connettersi all'AP"
@@ -1099,6 +1096,10 @@ msgstr "Imposssibile rimontare il filesystem"
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1170,6 +1171,10 @@ msgid "Sample rate too high. It must be less than %d"
msgstr ""
"Frequenza di campionamento troppo alta. Il valore deve essere inferiore a %d"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1184,11 +1189,6 @@ msgstr ""
msgid "Slices not supported"
msgstr "Slice non supportate"
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr ""
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Suddivisione con sotto-catture"
@@ -2008,7 +2008,7 @@ msgstr "il secondo argomanto di int() deve essere >= 2 e <= 36"
msgid "integer required"
msgstr "intero richiesto"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2190,11 +2190,6 @@ msgstr ""
msgid "name '%q' is not defined"
msgstr "nome '%q'non definito"
-#: shared-bindings/_bleio/Peripheral.c
-#, fuzzy
-msgid "name must be a string"
-msgstr "argomenti nominati devono essere stringhe"
-
#: py/runtime.c
msgid "name not defined"
msgstr "nome non definito"
@@ -2246,7 +2241,7 @@ msgstr ""
msgid "no such attribute"
msgstr "attributo inesistente"
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2739,7 +2734,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2829,10 +2824,22 @@ msgstr "zero step"
#~ msgid "Failed to acquire mutex"
#~ msgstr "Impossibile allocare buffer RX"
+#, fuzzy, c-format
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
+
#, fuzzy
#~ msgid "Failed to add service"
#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
+#, fuzzy, c-format
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
+
#, fuzzy
#~ msgid "Failed to connect:"
#~ msgstr "Impossibile connettersi. status: 0x%02x"
@@ -2841,6 +2848,10 @@ msgstr "zero step"
#~ msgid "Failed to continue scanning"
#~ msgstr "Impossible iniziare la scansione. status: 0x%02x"
+#, fuzzy, c-format
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ msgstr "Impossible iniziare la scansione. status: 0x%02x"
+
#, fuzzy
#~ msgid "Failed to create mutex"
#~ msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x"
@@ -2861,6 +2872,10 @@ msgstr "zero step"
#~ msgid "Failed to start advertising"
#~ msgstr "Impossibile avviare advertisement. status: 0x%02x"
+#, fuzzy, c-format
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ msgstr "Impossibile avviare advertisement. status: 0x%02x"
+
#, fuzzy
#~ msgid "Failed to start scanning"
#~ msgstr "Impossible iniziare la scansione. status: 0x%02x"
@@ -2869,6 +2884,10 @@ msgstr "zero step"
#~ msgid "Failed to stop advertising"
#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
+#, fuzzy, c-format
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Impossibile fermare advertisement. status: 0x%02x"
+
#~ msgid "GPIO16 does not support pull up."
#~ msgstr "GPIO16 non supporta pull-up"
@@ -3008,6 +3027,10 @@ msgstr "zero step"
#~ msgstr ""
#~ "allocazione di memoria fallita, allocazione di %d byte per codice nativo"
+#, fuzzy
+#~ msgid "name must be a string"
+#~ msgstr "argomenti nominati devono essere stringhe"
+
#~ msgid "not a valid ADC Channel: %d"
#~ msgstr "canale ADC non valido: %d"
diff --git a/locale/pl.po b/locale/pl.po
index 9ed76924b..0edc5906e 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-10-21 19:50-0700\n"
"PO-Revision-Date: 2019-03-19 18:37-0700\n"
"Last-Translator: Radomir Dopieralski <circuitpython@sheep.art.pl>\n"
"Language-Team: pl\n"
@@ -260,6 +260,10 @@ msgstr "Wszystkie timery tej nóżki w użyciu"
msgid "All timers in use"
msgstr "Wszystkie timery w użyciu"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "AnalogOut jest niewspierane"
@@ -328,6 +332,11 @@ msgstr "Jasność musi być pomiędzy 0 a 255"
msgid "Brightness not adjustable"
msgstr "Jasność nie jest regulowana"
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -458,6 +467,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr "Komenda musi być int pomiędzy 0 a 255"
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -500,7 +515,7 @@ msgstr "Nóżka data 0 musi być wyrównana do bajtu"
msgid "Data chunk must follow fmt chunk"
msgstr "Fragment danych musi następować po fragmencie fmt"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr "Zbyt dużo danych pakietu rozgłoszeniowego"
@@ -546,10 +561,6 @@ msgstr "Oczekiwano %q"
msgid "Expected a Characteristic"
msgstr "Oczekiwano charakterystyki"
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -559,7 +570,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr "Oczekiwano UUID"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -568,6 +579,11 @@ msgstr ""
msgid "Expected tuple of length %d, got %d"
msgstr "Oczekiwano krotkę długości %d, otrzymano %d"
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Failed initiate attribute read, err 0x%04x"
+msgstr ""
+
#: shared-bindings/ps2io/Ps2.c
msgid "Failed sending command."
msgstr ""
@@ -578,20 +594,14 @@ msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Nie udało się uzyskać blokady, błąd 0x$04x"
#: ports/nrf/common-hal/_bleio/Service.c
-#, fuzzy, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Nie udało się dodać charakterystyki, błąd 0x$04x"
+msgid "Failed to add characteristic, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
msgid "Failed to add descriptor, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Nie udało się dodać serwisu, błąd 0x%04x"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Nie udała się alokacja bufora RX"
@@ -603,24 +613,22 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Nie udała się alokacja %d bajtów na bufor RX"
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to change softdevice state"
-msgstr "Nie udało się zmienić stanu softdevice"
+msgid "Failed to change softdevice state, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-msgid "Failed to continue scanning, err 0x%04x"
-msgstr "Nie udała się kontynuacja skanowania, błąd 0x%04x"
+#: ports/nrf/common-hal/_bleio/Service.c
+msgid "Failed to create service, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to discover services"
msgstr "Nie udało się odkryć serwisów"
@@ -637,7 +645,7 @@ 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
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to pair"
msgstr ""
@@ -646,8 +654,7 @@ msgstr ""
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
+#: ports/nrf/common-hal/_bleio/__init__.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"
@@ -667,35 +674,27 @@ msgstr "Nie udało się zarejestrować UUID dostawcy, błąd 0x%04x"
msgid "Failed to release mutex, err 0x%04x"
msgstr "Nie udało się zwolnić blokady, błąd 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to start advertising, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "Nie udało się rozpocząć rozgłaszania, błąd 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
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"
+#: ports/nrf/common-hal/_bleio/Connection.c
+msgid "Failed to start pairing, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Nie udało się rozpocząć skanowania, błąd 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Nie udało się zatrzymać rozgłaszania, błąd 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to stop advertising, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
@@ -999,9 +998,8 @@ msgstr "Brak miejsca"
msgid "No such file/directory"
msgstr "Brak pliku/katalogu"
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
msgid "Not connected"
msgstr "Nie podłączono"
@@ -1075,6 +1073,10 @@ msgstr "Oraz moduły w systemie plików\n"
msgid "Pop from an empty Ps2 buffer"
msgstr ""
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr "Dowolny klawisz aby uruchomić konsolę. CTRL-D aby przeładować."
@@ -1141,6 +1143,10 @@ msgstr "Częstotliwość próbkowania musi być dodatnia"
msgid "Sample rate too high. It must be less than %d"
msgstr "Zbyt wysoka częstotliwość próbkowania. Musi być mniejsza niż %d"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1155,11 +1161,6 @@ msgstr "Fragment i wartość są różnych długości."
msgid "Slices not supported"
msgstr "Fragmenty nieobsługiwane"
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Podział z podgrupami"
@@ -1975,7 +1976,7 @@ msgstr "argument 2 do int() busi być pomiędzy 2 a 36"
msgid "integer required"
msgstr "wymagana liczba całkowita"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2152,10 +2153,6 @@ msgstr "funkcja key musi być podana jako argument nazwany"
msgid "name '%q' is not defined"
msgstr "nazwa '%q' niezdefiniowana"
-#: shared-bindings/_bleio/Peripheral.c
-msgid "name must be a string"
-msgstr "nazwa musi być łańcuchem"
-
#: py/runtime.c
msgid "name not defined"
msgstr "nazwa niezdefiniowana"
@@ -2206,7 +2203,7 @@ msgstr ""
msgid "no such attribute"
msgstr "nie ma takiego atrybutu"
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2690,7 +2687,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr "value_count musi być > 0"
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2749,15 +2746,30 @@ msgstr "zerowy krok"
#~ msgid "Failed to acquire mutex"
#~ msgstr "Nie udało się uzyskać blokady"
+#, fuzzy, c-format
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Nie udało się dodać charakterystyki, błąd 0x$04x"
+
#~ msgid "Failed to add service"
#~ msgstr "Nie udało się dodać serwisu"
+#, c-format
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Nie udało się dodać serwisu, błąd 0x%04x"
+
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Nie udało się zmienić stanu softdevice"
+
#~ msgid "Failed to connect:"
#~ msgstr "Nie udało się połączenie:"
#~ msgid "Failed to continue scanning"
#~ msgstr "Nie udała się kontynuacja skanowania"
+#, c-format
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ msgstr "Nie udała się kontynuacja skanowania, błąd 0x%04x"
+
#~ msgid "Failed to create mutex"
#~ msgstr "Nie udało się stworzyć blokady"
@@ -2767,12 +2779,20 @@ msgstr "zerowy krok"
#~ msgid "Failed to start advertising"
#~ msgstr "Nie udało się rozpocząć rozgłaszania"
+#, c-format
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ msgstr "Nie udało się rozpocząć rozgłaszania, błąd 0x%04x"
+
#~ msgid "Failed to start scanning"
#~ msgstr "Nie udało się rozpocząć skanowania"
#~ msgid "Failed to stop advertising"
#~ msgstr "Nie udało się zatrzymać rozgłaszania"
+#, c-format
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Nie udało się zatrzymać rozgłaszania, błąd 0x%04x"
+
#~ msgid "Invalid bit clock pin"
#~ msgstr "Zła nóżka zegara"
@@ -2790,6 +2810,10 @@ msgstr "zerowy krok"
#~ "bpp given"
#~ msgstr "Wspierane są tylko pliki BMP czarno-białe, 8bpp i 16bpp: %d bpp "
+#, c-format
+#~ msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
+#~ msgstr "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
+
#~ msgid "Tile indices must be 0 - 255"
#~ msgstr "Indeks kafelka musi być pomiędzy 0 a 255 włącznie"
@@ -2809,6 +2833,9 @@ msgstr "zerowy krok"
#~ msgid "interval not in range 0.0020 to 10.24"
#~ msgstr "przedział poza zakresem 0.0020 do 10.24"
+#~ msgid "name must be a string"
+#~ msgstr "nazwa musi być łańcuchem"
+
#~ msgid "services includes an object that is not a Service"
#~ msgstr "obiekt typu innego niż Service w services"
diff --git a/locale/pt_BR.po b/locale/pt_BR.po
index a17a27539..b5cd24405 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-10-21 19:50-0700\n"
"PO-Revision-Date: 2018-10-02 21:14-0000\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -262,6 +262,10 @@ msgstr "Todos os temporizadores para este pino estão em uso"
msgid "All timers in use"
msgstr "Todos os temporizadores em uso"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "Funcionalidade AnalogOut não suportada"
@@ -328,6 +332,11 @@ msgstr "O brilho deve estar entre 0 e 255"
msgid "Brightness not adjustable"
msgstr ""
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -461,6 +470,12 @@ msgstr ""
msgid "Command must be an int between 0 and 255"
msgstr "Os bytes devem estar entre 0 e 255."
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr ""
@@ -503,7 +518,7 @@ msgstr ""
msgid "Data chunk must follow fmt chunk"
msgstr "Pedaço de dados deve seguir o pedaço de cortes"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, fuzzy
msgid "Data too large for advertisement packet"
msgstr "Não é possível ajustar dados no pacote de anúncios."
@@ -551,10 +566,6 @@ msgstr "Esperado um"
msgid "Expected a Characteristic"
msgstr "Não é possível adicionar Característica."
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr ""
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr ""
@@ -565,7 +576,7 @@ msgstr ""
msgid "Expected a UUID"
msgstr "Esperado um"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr ""
@@ -574,6 +585,11 @@ msgstr ""
msgid "Expected tuple of length %d, got %d"
msgstr ""
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Failed initiate attribute read, err 0x%04x"
+msgstr ""
+
#: shared-bindings/ps2io/Ps2.c
msgid "Failed sending command."
msgstr "Falha ao enviar comando."
@@ -584,20 +600,14 @@ msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
#: ports/nrf/common-hal/_bleio/Service.c
-#, fuzzy, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Não pode parar propaganda. status: 0x%02x"
+msgid "Failed to add characteristic, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
msgid "Failed to add descriptor, err 0x%04x"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Não pode parar propaganda. status: 0x%02x"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Falha ao alocar buffer RX"
@@ -609,25 +619,22 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Falha ao alocar buffer RX de %d bytes"
#: ports/nrf/common-hal/_bleio/Adapter.c
-#, fuzzy
-msgid "Failed to change softdevice state"
-msgstr "Não pode parar propaganda. status: 0x%02x"
+msgid "Failed to change softdevice state, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to connect: internal error"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Failed to connect: timeout"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, fuzzy, c-format
-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/Service.c
+msgid "Failed to create service, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
#, fuzzy
msgid "Failed to discover services"
msgstr "Não pode parar propaganda. status: 0x%02x"
@@ -646,7 +653,7 @@ 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
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to pair"
msgstr ""
@@ -655,8 +662,7 @@ msgstr ""
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
+#: ports/nrf/common-hal/_bleio/__init__.c
#, c-format
msgid "Failed to read attribute value, err 0x%04x"
msgstr ""
@@ -676,35 +682,27 @@ msgstr "Não é possível adicionar o UUID de 128 bits específico do fornecedor
msgid "Failed to release mutex, err 0x%04x"
msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to start advertising, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to start advertising, 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/Adapter.c
#, c-format
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"
+#: ports/nrf/common-hal/_bleio/Connection.c
+msgid "Failed to start pairing, NRF_ERROR_%q"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, fuzzy, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, fuzzy, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Não pode parar propaganda. status: 0x%02x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to stop advertising, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
@@ -1004,9 +1002,8 @@ msgstr ""
msgid "No such file/directory"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
#, fuzzy
msgid "Not connected"
msgstr "Não é possível conectar-se ao AP"
@@ -1084,6 +1081,10 @@ msgstr "Não é possível remontar o sistema de arquivos"
msgid "Pop from an empty Ps2 buffer"
msgstr "Buffer Ps2 vazio"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr ""
@@ -1151,6 +1152,10 @@ msgstr ""
msgid "Sample rate too high. It must be less than %d"
msgstr "Taxa de amostragem muito alta. Deve ser menor que %d"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1165,11 +1170,6 @@ msgstr ""
msgid "Slices not supported"
msgstr ""
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr ""
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr ""
@@ -1975,7 +1975,7 @@ msgstr ""
msgid "integer required"
msgstr "inteiro requerido"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr ""
@@ -2152,11 +2152,6 @@ msgstr ""
msgid "name '%q' is not defined"
msgstr ""
-#: shared-bindings/_bleio/Peripheral.c
-#, fuzzy
-msgid "name must be a string"
-msgstr "heap deve ser uma lista"
-
#: py/runtime.c
msgid "name not defined"
msgstr "nome não definido"
@@ -2207,7 +2202,7 @@ msgstr ""
msgid "no such attribute"
msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr ""
@@ -2692,7 +2687,7 @@ msgstr ""
msgid "value_count must be > 0"
msgstr ""
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr ""
@@ -2759,10 +2754,26 @@ msgstr "passo zero"
#~ msgid "Failed to acquire mutex"
#~ msgstr "Falha ao alocar buffer RX"
+#, fuzzy, c-format
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Não pode parar propaganda. status: 0x%02x"
+
#, fuzzy
#~ msgid "Failed to add service"
#~ msgstr "Não pode parar propaganda. status: 0x%02x"
+#, fuzzy, c-format
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Não pode parar propaganda. status: 0x%02x"
+
+#, fuzzy
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Não pode parar propaganda. status: 0x%02x"
+
+#, fuzzy, c-format
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
+
#, fuzzy
#~ msgid "Failed to create mutex"
#~ msgstr "Não é possível ler o valor do atributo. status: 0x%02x"
@@ -2783,6 +2794,10 @@ msgstr "passo zero"
#~ msgid "Failed to start advertising"
#~ msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
+#, fuzzy, c-format
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
+
#, fuzzy
#~ msgid "Failed to start scanning"
#~ msgstr "Não é possível iniciar o anúncio. status: 0x%02x"
@@ -2791,6 +2806,10 @@ msgstr "passo zero"
#~ msgid "Failed to stop advertising"
#~ msgstr "Não pode parar propaganda. status: 0x%02x"
+#, fuzzy, c-format
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Não pode parar propaganda. status: 0x%02x"
+
#~ msgid "GPIO16 does not support pull up."
#~ msgstr "GPIO16 não suporta pull up."
@@ -2921,6 +2940,10 @@ msgstr "passo zero"
#~ msgid "memory allocation failed, allocating %u bytes for native code"
#~ msgstr "alocação de memória falhou, alocando %u bytes para código nativo"
+#, fuzzy
+#~ msgid "name must be a string"
+#~ msgstr "heap deve ser uma lista"
+
#~ msgid "not a valid ADC Channel: %d"
#~ msgstr "não é um canal ADC válido: %d"
diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po
index d5df0b7b0..dfd7e8b0d 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-09-08 17:30-0500\n"
+"POT-Creation-Date: 2019-10-21 19:50-0700\n"
"PO-Revision-Date: 2019-04-13 10:10-0700\n"
"Last-Translator: hexthat\n"
"Language-Team: Chinese Hanyu Pinyin\n"
@@ -261,6 +261,10 @@ msgstr "Cǐ yǐn jiǎo de suǒyǒu jìshí qì zhèngzài shǐyòng"
msgid "All timers in use"
msgstr "Suǒyǒu jìshí qì shǐyòng"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Already advertising."
+msgstr ""
+
#: ports/nrf/common-hal/analogio/AnalogOut.c
msgid "AnalogOut functionality not supported"
msgstr "Bù zhīchí AnalogOut gōngnéng"
@@ -329,6 +333,11 @@ msgstr "Liàngdù bìxū jiè yú 0 dào 255 zhī jiān"
msgid "Brightness not adjustable"
msgstr "Liàngdù wúfǎ tiáozhěng"
+#: shared-bindings/_bleio/UUID.c
+#, c-format
+msgid "Buffer + offset too small %d %d %d"
+msgstr ""
+
#: shared-module/usb_hid/Device.c
#, c-format
msgid "Buffer incorrect size. Should be %d bytes."
@@ -459,6 +468,12 @@ msgstr "Mìnglìng bìxū wèi 0-255"
msgid "Command must be an int between 0 and 255"
msgstr "Mìnglìng bìxū shì 0 dào 255 zhī jiān de int"
+#: shared-bindings/_bleio/Connection.c
+msgid ""
+"Connection has been disconnected and can no longer be used. Create a new "
+"connection."
+msgstr ""
+
#: py/persistentcode.c
msgid "Corrupt .mpy file"
msgstr "Fǔbài de .mpy wénjiàn"
@@ -501,7 +516,7 @@ msgstr "Shùjù 0 de yǐn jiǎo bìxū shì zì jié duìqí"
msgid "Data chunk must follow fmt chunk"
msgstr "Shùjù kuài bìxū zūnxún fmt qū kuài"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Data too large for advertisement packet"
msgstr "Guǎnggào bāo de shùjù tài dà"
@@ -547,10 +562,6 @@ msgstr "Yùqí %q"
msgid "Expected a Characteristic"
msgstr "Yùqí de tèdiǎn"
-#: shared-bindings/_bleio/Service.c
-msgid "Expected a Peripheral"
-msgstr "Qídài yīgè wàiwéi shèbèi"
-
#: shared-bindings/_bleio/Characteristic.c
msgid "Expected a Service"
msgstr "Yùqí fúwù"
@@ -560,7 +571,7 @@ msgstr "Yùqí fúwù"
msgid "Expected a UUID"
msgstr "Yùqí UUID"
-#: shared-bindings/_bleio/Central.c
+#: shared-bindings/_bleio/Adapter.c
msgid "Expected an Address"
msgstr "Qídài yīgè dìzhǐ"
@@ -569,6 +580,11 @@ msgstr "Qídài yīgè dìzhǐ"
msgid "Expected tuple of length %d, got %d"
msgstr "Qīwàng de chángdù wèi %d de yuán zǔ, dédào %d"
+#: ports/nrf/common-hal/_bleio/__init__.c
+#, c-format
+msgid "Failed initiate attribute read, err 0x%04x"
+msgstr ""
+
#: shared-bindings/ps2io/Ps2.c
msgid "Failed sending command."
msgstr "Fāsòng mìnglìng shībài."
@@ -579,20 +595,14 @@ msgid "Failed to acquire mutex, err 0x%04x"
msgstr "Wúfǎ huòdé mutex, err 0x%04x"
#: ports/nrf/common-hal/_bleio/Service.c
-#, c-format
-msgid "Failed to add characteristic, err 0x%04x"
-msgstr "Tiānjiā tèxìng shībài, err 0x%04x"
+msgid "Failed to add characteristic, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
msgid "Failed to add descriptor, err 0x%04x"
msgstr "Wúfǎ tiānjiā miáoshù fú, err 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to add service, err 0x%04x"
-msgstr "Tiānjiā fúwù shībài, err 0x%04x"
-
#: ports/atmel-samd/common-hal/busio/UART.c ports/nrf/common-hal/busio/UART.c
msgid "Failed to allocate RX buffer"
msgstr "Fēnpèi RX huǎnchōng shībài"
@@ -604,24 +614,22 @@ msgid "Failed to allocate RX buffer of %d bytes"
msgstr "Fēnpèi RX huǎnchōng qū%d zì jié shībài"
#: ports/nrf/common-hal/_bleio/Adapter.c
-msgid "Failed to change softdevice state"
-msgstr "Gēnggǎi ruǎn shèbèi zhuàngtài shībài"
+msgid "Failed to change softdevice state, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to configure advertising, err 0x%04x"
-msgstr "Wúfǎ pèizhì guǎnggào, cuòwù 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to connect: internal error"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
msgid "Failed to connect: timeout"
msgstr "Liánjiē shībài: Chāoshí"
-#: ports/nrf/common-hal/_bleio/Scanner.c
-#, c-format
-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/Service.c
+msgid "Failed to create service, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to discover services"
msgstr "Fāxiàn fúwù shībài"
@@ -638,7 +646,7 @@ 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
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "Failed to pair"
msgstr "Pèiduì shībài"
@@ -647,8 +655,7 @@ msgstr "Pèiduì shībài"
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
+#: ports/nrf/common-hal/_bleio/__init__.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"
@@ -668,35 +675,27 @@ msgstr "Wúfǎ zhùcè màizhǔ tèdìng de UUID, err 0x%04x"
msgid "Failed to release mutex, err 0x%04x"
msgstr "Wúfǎ shìfàng mutex, err 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to set device name, err 0x%04x"
-msgstr "Wúfǎ shèzhì shèbèi míngchēng, cuòwù 0x%04x"
-
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to start advertising, err 0x%04x"
-msgstr "Qǐdòng guǎnggào shībài, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to start advertising, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
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 "Wúfǎ kāishǐ pèiduì, cuòwù 0x%04x"
+#: ports/nrf/common-hal/_bleio/Connection.c
+msgid "Failed to start pairing, NRF_ERROR_%q"
+msgstr ""
-#: ports/nrf/common-hal/_bleio/Scanner.c
+#: ports/nrf/common-hal/_bleio/Adapter.c
#, c-format
msgid "Failed to start scanning, err 0x%04x"
msgstr "Qǐdòng sǎomiáo shībài, err 0x%04x"
-#: ports/nrf/common-hal/_bleio/Peripheral.c
-#, c-format
-msgid "Failed to stop advertising, err 0x%04x"
-msgstr "Wúfǎ tíngzhǐ guǎnggào, err 0x%04x"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Failed to stop advertising, NRF_ERROR_%q"
+msgstr ""
#: ports/nrf/common-hal/_bleio/Characteristic.c
#, c-format
@@ -999,9 +998,8 @@ 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/__init__.c shared-bindings/_bleio/Central.c
+#: ports/nrf/common-hal/_bleio/__init__.c
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Peripheral.c
msgid "Not connected"
msgstr "Wèi liánjiē"
@@ -1079,6 +1077,10 @@ msgstr "Zài wénjiàn xìtǒng shàng tiānjiā rènhé mókuài\n"
msgid "Pop from an empty Ps2 buffer"
msgstr "Cóng kōng de Ps2 huǎnchōng qū dànchū"
+#: shared-bindings/_bleio/Adapter.c
+msgid "Prefix buffer must be on the heap"
+msgstr ""
+
#: main.c
msgid "Press any key to enter the REPL. Use CTRL-D to reload."
msgstr "Àn xià rènhé jiàn jìnrù REPL. Shǐyòng CTRL-D chóngxīn jiāzài."
@@ -1145,6 +1147,10 @@ msgstr "Cǎiyàng lǜ bìxū wèi zhèng shù"
msgid "Sample rate too high. It must be less than %d"
msgstr "Cǎiyàng lǜ tài gāo. Tā bìxū xiǎoyú %d"
+#: ports/nrf/common-hal/_bleio/Adapter.c
+msgid "Scan already in progess. Stop with stop_scan."
+msgstr ""
+
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c
msgid "Serializer in use"
@@ -1159,11 +1165,6 @@ msgstr "Qiēpiàn hé zhí bùtóng chángdù."
msgid "Slices not supported"
msgstr "Qiēpiàn bù shòu zhīchí"
-#: ports/nrf/common-hal/_bleio/Adapter.c
-#, c-format
-msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
-msgstr "Ruǎn shèbèi wéihù, id: 0X%08lX, pc: 0X%08lX"
-
#: extmod/modure.c
msgid "Splitting with sub-captures"
msgstr "Yǔ zi bǔhuò fēnliè"
@@ -1986,7 +1987,7 @@ msgstr "zhěngshù() cānshù 2 bìxū > = 2 qiě <= 36"
msgid "integer required"
msgstr "xūyào zhěngshù"
-#: shared-bindings/_bleio/Peripheral.c shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
#, c-format
msgid "interval must be in range %s-%s"
msgstr "Jiàngé bìxū zài %s-%s fànwéi nèi"
@@ -2164,10 +2165,6 @@ msgstr "bìxū shǐyòng guānjiàn cí cānshù"
msgid "name '%q' is not defined"
msgstr "míngchēng '%q' wèi dìngyì"
-#: shared-bindings/_bleio/Peripheral.c
-msgid "name must be a string"
-msgstr "míngchēng bìxū shì yīgè zìfú chuàn"
-
#: py/runtime.c
msgid "name not defined"
msgstr "míngchēng wèi dìngyì"
@@ -2219,7 +2216,7 @@ msgstr "Méiyǒu kěyòng de fùwèi yǐn jiǎo"
msgid "no such attribute"
msgstr "méiyǒu cǐ shǔxìng"
-#: ports/nrf/common-hal/_bleio/__init__.c
+#: ports/nrf/common-hal/_bleio/Connection.c
msgid "non-UUID found in service_uuids_whitelist"
msgstr "Zài service_uuids bái míngdān zhōng zhǎodào fēi UUID"
@@ -2703,7 +2700,7 @@ msgstr "Zhí bìxū fúhé %d zì jié"
msgid "value_count must be > 0"
msgstr "zhí jìshù bìxū wèi > 0"
-#: shared-bindings/_bleio/Scanner.c
+#: shared-bindings/_bleio/Adapter.c
msgid "window must be <= interval"
msgstr "Chuāngkǒu bìxū shì <= jiàngé"
@@ -2762,33 +2759,71 @@ msgstr "líng bù"
#~ msgid "Data too large for the advertisement packet"
#~ msgstr "Guǎnggào bāo de shùjù tài dà"
+#~ msgid "Expected a Peripheral"
+#~ msgstr "Qídài yīgè wàiwéi shèbèi"
+
#~ msgid "Failed to acquire mutex"
#~ msgstr "Wúfǎ huòdé mutex"
+#, c-format
+#~ msgid "Failed to add characteristic, err 0x%04x"
+#~ msgstr "Tiānjiā tèxìng shībài, err 0x%04x"
+
#~ msgid "Failed to add service"
#~ msgstr "Tiānjiā fúwù shībài"
+#, c-format
+#~ msgid "Failed to add service, err 0x%04x"
+#~ msgstr "Tiānjiā fúwù shībài, err 0x%04x"
+
+#~ msgid "Failed to change softdevice state"
+#~ msgstr "Gēnggǎi ruǎn shèbèi zhuàngtài shībài"
+
+#, c-format
+#~ msgid "Failed to configure advertising, err 0x%04x"
+#~ msgstr "Wúfǎ pèizhì guǎnggào, cuòwù 0x%04x"
+
#~ msgid "Failed to connect:"
#~ msgstr "Liánjiē shībài:"
#~ msgid "Failed to continue scanning"
#~ msgstr "Jìxù sǎomiáo shībài"
+#, c-format
+#~ msgid "Failed to continue scanning, err 0x%04x"
+#~ msgstr "Jìxù sǎomiáo shībài, err 0x%04x"
+
#~ msgid "Failed to create mutex"
#~ msgstr "Wúfǎ chuàngjiàn hù chì suǒ"
#~ msgid "Failed to release mutex"
#~ msgstr "Wúfǎ shìfàng mutex"
+#, c-format
+#~ msgid "Failed to set device name, err 0x%04x"
+#~ msgstr "Wúfǎ shèzhì shèbèi míngchēng, cuòwù 0x%04x"
+
#~ msgid "Failed to start advertising"
#~ msgstr "Qǐdòng guǎnggào shībài"
+#, c-format
+#~ msgid "Failed to start advertising, err 0x%04x"
+#~ msgstr "Qǐdòng guǎnggào shībài, err 0x%04x"
+
+#, c-format
+#~ msgid "Failed to start pairing, error 0x%04x"
+#~ msgstr "Wúfǎ kāishǐ pèiduì, cuòwù 0x%04x"
+
#~ msgid "Failed to start scanning"
#~ msgstr "Qǐdòng sǎomiáo shībài"
#~ msgid "Failed to stop advertising"
#~ msgstr "Wúfǎ tíngzhǐ guǎnggào"
+#, c-format
+#~ msgid "Failed to stop advertising, err 0x%04x"
+#~ msgstr "Wúfǎ tíngzhǐ guǎnggào, err 0x%04x"
+
#~ msgid "Invalid bit clock pin"
#~ msgstr "Wúxiào de wèi shízhōng yǐn jiǎo"
@@ -2819,6 +2854,10 @@ msgstr "líng bù"
#~ msgstr ""
#~ "Jǐn zhīchí dān sè, suǒyǐn 8bpp hé 16bpp huò gèng dà de BMP: %d bpp tígōng"
+#, c-format
+#~ msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX"
+#~ msgstr "Ruǎn shèbèi wéihù, id: 0X%08lX, pc: 0X%08lX"
+
#~ msgid "Tile indices must be 0 - 255"
#~ msgstr "Píng pū zhǐshù bìxū wèi 0 - 255"
@@ -2840,6 +2879,9 @@ msgstr "líng bù"
#~ msgid "interval not in range 0.0020 to 10.24"
#~ msgstr "jùlí 0.0020 Zhì 10.24 Zhī jiān de jiàngé shíjiān"
+#~ msgid "name must be a string"
+#~ msgstr "míngchēng bìxū shì yīgè zìfú chuàn"
+
#~ msgid "row must be packed and word aligned"
#~ msgstr "xíng bìxū dǎbāo bìngqiě zì duìqí"
diff --git a/main.c b/main.c
index 8715672ea..a6c7c0581 100755
--- a/main.c
+++ b/main.c
@@ -69,6 +69,11 @@
#include "shared-module/board/__init__.h"
#endif
+#if CIRCUITPY_BLEIO
+#include "shared-bindings/_bleio/__init__.h"
+#include "supervisor/shared/bluetooth.h"
+#endif
+
void do_str(const char *src, mp_parse_input_kind_t input_kind) {
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0);
if (lex == NULL) {
@@ -439,6 +444,10 @@ int __attribute__((used)) main(void) {
// Start serial and HID after giving boot.py a chance to tweak behavior.
serial_init();
+ #if CIRCUITPY_BLEIO
+ supervisor_start_bluetooth();
+ #endif
+
// Boot script is finished, so now go into REPL/main mode.
int exit_code = PYEXEC_FORCED_EXIT;
bool skip_repl = true;
@@ -475,6 +484,10 @@ void gc_collect(void) {
displayio_gc_collect();
#endif
+ #if CIRCUITPY_BLEIO
+ common_hal_bleio_gc_collect();
+ #endif
+
// This naively collects all object references from an approximate stack
// range.
gc_collect_root((void**)sp, ((uint32_t)port_stack_get_top() - sp) / sizeof(uint32_t));
diff --git a/ports/atmel-samd/boards/winterbloom_sol/board.c b/ports/atmel-samd/boards/winterbloom_sol/board.c
new file mode 100644
index 000000000..8096b9b8e
--- /dev/null
+++ b/ports/atmel-samd/boards/winterbloom_sol/board.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft 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 "boards/board.h"
+#include "mpconfigboard.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.h b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.h
new file mode 100644
index 000000000..7e01e228a
--- /dev/null
+++ b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.h
@@ -0,0 +1,33 @@
+#define MICROPY_HW_BOARD_NAME "Winterbloom Sol"
+#define MICROPY_HW_MCU_NAME "samd51j20"
+
+#define CIRCUITPY_MCU_FAMILY samd51
+
+#define MICROPY_HW_LED_STATUS (&pin_PA23)
+#define MICROPY_HW_NEOPIXEL (&pin_PB03)
+
+// These are pins not to reset.
+// QSPI Data pins
+#define MICROPY_PORT_A (PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11)
+// QSPI CS, QSPI SCK and NeoPixel pin
+#define MICROPY_PORT_B (PORT_PB03 | PORT_PB10 | PORT_PB11)
+#define MICROPY_PORT_C (0)
+#define MICROPY_PORT_D (0)
+
+#define AUTORESET_DELAY_MS 500
+
+// If you change this, then make sure to update the linker scripts as well to
+// make sure you don't overwrite code
+#define CIRCUITPY_INTERNAL_NVM_SIZE 8192
+
+#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
+
+#define BOARD_HAS_CRYSTAL 1
+
+#define DEFAULT_SPI_BUS_SCK (&pin_PA17)
+#define DEFAULT_SPI_BUS_MOSI (&pin_PB23)
+#define DEFAULT_SPI_BUS_MISO (&pin_PB22)
+
+// USB is always used internally so skip the pin objects for it.
+#define IGNORE_PIN_PA24 1
+#define IGNORE_PIN_PA25 1
diff --git a/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk
new file mode 100644
index 000000000..19917898b
--- /dev/null
+++ b/ports/atmel-samd/boards/winterbloom_sol/mpconfigboard.mk
@@ -0,0 +1,27 @@
+LD_FILE = boards/samd51x20-bootloader-external-flash.ld
+# Adafruit
+USB_VID = 0x239A
+# Allocated for Winterbloom Sol
+# https://github.com/adafruit/circuitpython/issues/2217
+USB_PID = 0x8062
+USB_PRODUCT = "Sol"
+USB_MANUFACTURER = "Winterbloom"
+
+CHIP_VARIANT = SAMD51J20A
+CHIP_FAMILY = samd51
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = W25Q32JV_IQ
+LONGINT_IMPL = MPZ
+
+# Disable modules that are unusable on this special-purpose board.
+CIRCUITPY_AUDIOBUSIO = 0
+CIRCUITPY_AUDIOIO = 0
+CIRCUITPY_BLEIO = 0
+CIRCUITPY_DISPLAYIO = 0
+CIRCUITPY_GAMEPAD = 0
+CIRCUITPY_I2CSLAVE = 0
+CIRCUITPY_NETWORK = 0
+CIRCUITPY_TOUCHIO = 0
+CIRCUITPY_PS2IO = 0
diff --git a/ports/atmel-samd/boards/winterbloom_sol/pins.c b/ports/atmel-samd/boards/winterbloom_sol/pins.c
new file mode 100644
index 000000000..013542d3c
--- /dev/null
+++ b/ports/atmel-samd/boards/winterbloom_sol/pins.c
@@ -0,0 +1,15 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA17) },
+ { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB23) },
+ { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB22) },
+ { MP_ROM_QSTR(MP_QSTR_DAC_CS), MP_ROM_PTR(&pin_PA18) },
+ { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_PA20) },
+ { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_PA21) },
+ { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_PA22) },
+ { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_PA23) },
+ { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB03) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/nrf/background.c b/ports/nrf/background.c
index 305f607c5..629967b3d 100644
--- a/ports/nrf/background.c
+++ b/ports/nrf/background.c
@@ -41,6 +41,10 @@
#include "common-hal/audiopwmio/PWMAudioOut.h"
#endif
+#if CIRCUITPY_BLEIO
+#include "supervisor/shared/bluetooth.h"
+#endif
+
static bool running_background_tasks = false;
void background_tasks_reset(void) {
@@ -62,6 +66,9 @@ void run_background_tasks(void) {
i2s_background();
#endif
+#if CIRCUITPY_BLEIO
+ supervisor_bluetooth_background();
+#endif
#if CIRCUITPY_DISPLAYIO
displayio_background();
diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c
index 6b17e7af2..16475e4b3 100644
--- a/ports/nrf/bluetooth/ble_drv.c
+++ b/ports/nrf/bluetooth/ble_drv.c
@@ -38,6 +38,8 @@
#include "py/misc.h"
#include "py/mpstate.h"
+#include "supervisor/shared/bluetooth.h"
+
nrf_nvic_state_t nrf_nvic_state = { 0 };
// Flag indicating progress of internal flash operation.
@@ -52,6 +54,14 @@ void ble_drv_reset() {
sd_flash_operation_status = SD_FLASH_OPERATION_DONE;
}
+void ble_drv_add_event_handler_entry(ble_drv_evt_handler_entry_t* entry, ble_drv_evt_handler_t func, void *param) {
+ entry->next = MP_STATE_VM(ble_drv_evt_handler_entries);
+ entry->param = param;
+ entry->func = func;
+
+ MP_STATE_VM(ble_drv_evt_handler_entries) = entry;
+}
+
void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) {
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
while (it != NULL) {
@@ -64,11 +74,7 @@ void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) {
// Add a new handler to the front of the list
ble_drv_evt_handler_entry_t *handler = m_new_ll(ble_drv_evt_handler_entry_t, 1);
- handler->next = MP_STATE_VM(ble_drv_evt_handler_entries);
- handler->param = param;
- handler->func = func;
-
- MP_STATE_VM(ble_drv_evt_handler_entries) = handler;
+ ble_drv_add_event_handler_entry(handler, func, param);
}
void ble_drv_remove_event_handler(ble_drv_evt_handler_t func, void *param) {
@@ -127,10 +133,20 @@ void SD_EVT_IRQHandler(void) {
break;
}
+ ble_evt_t* event = (ble_evt_t *)m_ble_evt_buf;
+
+ if (supervisor_bluetooth_hook(event)) {
+ continue;
+ }
+
ble_drv_evt_handler_entry_t *it = MP_STATE_VM(ble_drv_evt_handler_entries);
+ bool done = false;
while (it != NULL) {
- it->func((ble_evt_t *)m_ble_evt_buf, it->param);
+ done = it->func(event, it->param) || done;
it = it->next;
}
+ if (!done) {
+ //mp_printf(&mp_plat_print, "Unhandled ble event: 0x%04x\n", event->header.evt_id);
+ }
}
}
diff --git a/ports/nrf/bluetooth/ble_drv.h b/ports/nrf/bluetooth/ble_drv.h
index a066f588f..7716cab8b 100644
--- a/ports/nrf/bluetooth/ble_drv.h
+++ b/ports/nrf/bluetooth/ble_drv.h
@@ -29,6 +29,8 @@
#ifndef MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H
#define MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H
+#include <stdbool.h>
+
#include "ble.h"
#define MAX_TX_IN_PROGRESS 10
@@ -48,7 +50,7 @@
#define UNIT_1_25_MS (1250)
#define UNIT_10_MS (10000)
-typedef void (*ble_drv_evt_handler_t)(ble_evt_t*, void*);
+typedef bool (*ble_drv_evt_handler_t)(ble_evt_t*, void*);
typedef enum {
SD_FLASH_OPERATION_DONE,
@@ -69,4 +71,7 @@ void ble_drv_reset(void);
void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param);
void ble_drv_remove_event_handler(ble_drv_evt_handler_t func, void *param);
+// Allow for user provided entries to prevent allocations outside the VM.
+void ble_drv_add_event_handler_entry(ble_drv_evt_handler_entry_t* entry, ble_drv_evt_handler_t func, void *param);
+
#endif // MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H
diff --git a/ports/nrf/boards/adafruit_nrf52840_s140_v6.ld b/ports/nrf/boards/adafruit_nrf52840_s140_v6.ld
index 2587a19e3..756060f96 100644
--- a/ports/nrf/boards/adafruit_nrf52840_s140_v6.ld
+++ b/ports/nrf/boards/adafruit_nrf52840_s140_v6.ld
@@ -16,6 +16,7 @@
0x00000000..0x00000FFF (4KB) Master Boot Record
*/
+
/* Specify the memory areas (S140 6.x.x) */
MEMORY
{
@@ -26,7 +27,10 @@ MEMORY
FLASH_FATFS (r) : ORIGIN = 0x000AD000, LENGTH = 0x040000
/* 0x2000000 - RAM:ORIGIN is reserved for Softdevice */
- RAM (xrw) : ORIGIN = 0x20004000, LENGTH = 0x20040000 - 0x20004000
+ /* SoftDevice 6.1.0 takes 0x1628 bytes (5.54 kb) minimum. */
+ /* To measure the minimum required amount of memory for given configuration, set this number
+ high enough to work and then check the mutation of the value done by sd_ble_enable. */
+ RAM (xrw) : ORIGIN = 0x20000000 + 16K, LENGTH = 256K - 16K
}
/* produce a link error if there is not this amount of RAM for these sections */
@@ -38,7 +42,8 @@ _minimum_heap_size = 0;
/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/
_estack = ORIGIN(RAM) + LENGTH(RAM);
-/* RAM extents for the garbage collector */
+/* RAM extents for the garbage collector and soft device init */
+_ram_start = ORIGIN(RAM);
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
_heap_end = 0x20020000; /* tunable */
diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c
index a8e1f1905..295a42d63 100644
--- a/ports/nrf/common-hal/_bleio/Adapter.c
+++ b/ports/nrf/common-hal/_bleio/Adapter.c
@@ -26,6 +26,7 @@
* THE SOFTWARE.
*/
+#include <stdint.h>
#include <stdio.h>
#include <string.h>
@@ -34,11 +35,18 @@
#include "nrfx_power.h"
#include "nrf_nvic.h"
#include "nrf_sdm.h"
+#include "tick.h"
+#include "py/gc.h"
#include "py/objstr.h"
#include "py/runtime.h"
+#include "supervisor/shared/safe_mode.h"
#include "supervisor/usb.h"
+#include "shared-bindings/_bleio/__init__.h"
#include "shared-bindings/_bleio/Adapter.h"
#include "shared-bindings/_bleio/Address.h"
+#include "shared-bindings/_bleio/Connection.h"
+#include "shared-bindings/_bleio/ScanEntry.h"
+#include "shared-bindings/time/__init__.h"
#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS)
#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS)
@@ -46,10 +54,13 @@
#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS)
STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) {
- mp_raise_msg_varg(&mp_type_AssertionError,
- translate("Soft device assert, id: 0x%08lX, pc: 0x%08lX"), id, pc);
+ reset_into_safe_mode(NORDIC_SOFT_DEVICE_ASSERT);
}
+bleio_connection_internal_t connections[BLEIO_TOTAL_CONNECTION_COUNT];
+
+// Linker script provided ram start.
+extern uint32_t _ram_start;
STATIC uint32_t ble_stack_enable(void) {
nrf_clock_lf_cfg_t clock_config = {
#if BOARD_HAS_32KHZ_XTAL
@@ -78,34 +89,56 @@ STATIC uint32_t ble_stack_enable(void) {
// Start with no event handlers, etc.
ble_drv_reset();
- uint32_t app_ram_start;
- app_ram_start = 0x20004000;
+ // Set everything up to have one persistent code editing connection and one user managed
+ // connection. In the future we could move .data and .bss to the other side of the stack and
+ // dynamically adjust for different memory requirements of the SD based on boot.py
+ // configuration.
+ uint32_t app_ram_start = (uint32_t) &_ram_start;
ble_cfg_t ble_conf;
ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM;
- ble_conf.conn_cfg.params.gap_conn_cfg.conn_count = BLE_GAP_CONN_COUNT_DEFAULT;
+ ble_conf.conn_cfg.params.gap_conn_cfg.conn_count = BLEIO_TOTAL_CONNECTION_COUNT;
+ // Event length here can influence throughput so perhaps make multiple connection profiles
+ // available.
ble_conf.conn_cfg.params.gap_conn_cfg.event_length = BLE_GAP_EVENT_LENGTH_DEFAULT;
err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_conf, app_ram_start);
- if (err_code != NRF_SUCCESS)
+ if (err_code != NRF_SUCCESS) {
return err_code;
+ }
memset(&ble_conf, 0, sizeof(ble_conf));
- ble_conf.gap_cfg.role_count_cfg.periph_role_count = 1;
+ ble_conf.gap_cfg.role_count_cfg.adv_set_count = 1;
+ ble_conf.gap_cfg.role_count_cfg.periph_role_count = 2;
ble_conf.gap_cfg.role_count_cfg.central_role_count = 1;
err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_conf, app_ram_start);
- if (err_code != NRF_SUCCESS)
+ if (err_code != NRF_SUCCESS) {
return err_code;
+ }
memset(&ble_conf, 0, sizeof(ble_conf));
ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM;
ble_conf.conn_cfg.params.gatts_conn_cfg.hvn_tx_queue_size = MAX_TX_IN_PROGRESS;
err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTS, &ble_conf, app_ram_start);
- if (err_code != NRF_SUCCESS)
+ if (err_code != NRF_SUCCESS) {
return err_code;
+ }
+ // Triple the GATT Server attribute size to accomodate both the CircuitPython built-in service
+ // and anything the user does.
+ memset(&ble_conf, 0, sizeof(ble_conf));
+ ble_conf.gatts_cfg.attr_tab_size.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT * 3;
+ err_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_conf, app_ram_start);
+ if (err_code != NRF_SUCCESS) {
+ return err_code;
+ }
+
+ // TODO set ATT_MTU so that the maximum MTU we can negotiate is higher than the default.
+
+ // This sets app_ram_start to the minimum value needed for the settings set above.
err_code = sd_ble_enable(&app_ram_start);
- if (err_code != NRF_SUCCESS)
+ if (err_code != NRF_SUCCESS) {
return err_code;
+ }
ble_gap_conn_params_t gap_conn_params = {
.min_conn_interval = BLE_MIN_CONN_INTERVAL,
@@ -122,11 +155,109 @@ STATIC uint32_t ble_stack_enable(void) {
return err_code;
}
-void common_hal_bleio_adapter_set_enabled(bool enabled) {
- const bool is_enabled = common_hal_bleio_adapter_get_enabled();
+STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
+ bleio_adapter_obj_t *self = (bleio_adapter_obj_t*)self_in;
+
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Adapter event: 0x%04x\n", ble_evt->header.evt_id);
+
+ switch (ble_evt->header.evt_id) {
+ case BLE_GAP_EVT_CONNECTED: {
+ // Find an empty connection. One must always be available because the SD has the same
+ // total connection limit.
+ bleio_connection_internal_t *connection;
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ connection = &connections[i];
+ if (connection->conn_handle == BLE_CONN_HANDLE_INVALID) {
+ break;
+ }
+ }
+
+ // Central has connected.
+ ble_gap_evt_connected_t* connected = &ble_evt->evt.gap_evt.params.connected;
+
+ connection->conn_handle = ble_evt->evt.gap_evt.conn_handle;
+ connection->connection_obj = mp_const_none;
+ ble_drv_add_event_handler_entry(&connection->handler_entry, connection_on_ble_evt, connection);
+ self->connection_objs = NULL;
+
+ // See if connection interval set by Central is out of range.
+ // If so, negotiate our preferred range.
+ ble_gap_conn_params_t conn_params;
+ sd_ble_gap_ppcp_get(&conn_params);
+ if (conn_params.min_conn_interval < connected->conn_params.min_conn_interval ||
+ conn_params.min_conn_interval > connected->conn_params.max_conn_interval) {
+ sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params);
+ }
+ self->current_advertising_data = NULL;
+ break;
+ }
+ case BLE_GAP_EVT_DISCONNECTED: {
+ // Find the connection that was disconnected.
+ bleio_connection_internal_t *connection;
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ connection = &connections[i];
+ if (connection->conn_handle == ble_evt->evt.gap_evt.conn_handle) {
+ break;
+ }
+ }
+ ble_drv_remove_event_handler(connection_on_ble_evt, connection);
+ connection->conn_handle = BLE_CONN_HANDLE_INVALID;
+ if (connection->connection_obj != mp_const_none) {
+ bleio_connection_obj_t* obj = connection->connection_obj;
+ obj->connection = NULL;
+ obj->disconnect_reason = ble_evt->evt.gap_evt.params.disconnected.reason;
+ }
+ self->connection_objs = NULL;
+
+ break;
+ }
+
+ case BLE_GAP_EVT_ADV_SET_TERMINATED:
+ self->current_advertising_data = NULL;
+ break;
+
+ default:
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Unhandled adapter event: 0x%04x\n", ble_evt->header.evt_id);
+ return false;
+ break;
+ }
+ return true;
+}
+
+STATIC void get_address(bleio_adapter_obj_t *self, ble_gap_addr_t *address) {
+ uint32_t err_code;
+
+ err_code = sd_ble_gap_addr_get(address);
+
+ if (err_code != NRF_SUCCESS) {
+ mp_raise_OSError_msg(translate("Failed to get local address"));
+ }
+}
+
+char default_ble_name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0, 0 , 0};
+
+STATIC void bleio_adapter_reset_name(bleio_adapter_obj_t *self) {
+ uint8_t len = sizeof(default_ble_name) - 1;
+
+ ble_gap_addr_t local_address;
+ get_address(self, &local_address);
+
+ default_ble_name[len - 4] = nibble_to_hex_lower[local_address.addr[1] >> 4 & 0xf];
+ default_ble_name[len - 3] = nibble_to_hex_lower[local_address.addr[1] & 0xf];
+ default_ble_name[len - 2] = nibble_to_hex_lower[local_address.addr[0] >> 4 & 0xf];
+ default_ble_name[len - 1] = nibble_to_hex_lower[local_address.addr[0] & 0xf];
+ default_ble_name[len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings
+
+ common_hal_bleio_adapter_set_name(self, (char*) default_ble_name);
+}
+
+void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enabled) {
+ const bool is_enabled = common_hal_bleio_adapter_get_enabled(self);
// Don't enable or disable twice
- if ((is_enabled && enabled) || (!is_enabled && !enabled)) {
+ if (is_enabled == enabled) {
return;
}
@@ -137,22 +268,34 @@ void common_hal_bleio_adapter_set_enabled(bool enabled) {
nrfx_power_uninit();
err_code = ble_stack_enable();
-
- // Re-init USB hardware
- init_usb_hardware();
} else {
err_code = sd_softdevice_disable();
-
- // Re-init USB hardware
- init_usb_hardware();
}
+ // Re-init USB hardware
+ init_usb_hardware();
if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to change softdevice state"));
+ mp_raise_OSError_msg_varg(translate("Failed to change softdevice state, NRF_ERROR_%q"), MP_OBJ_QSTR_VALUE(base_error_messages[err_code - NRF_ERROR_BASE_NUM]));
+ }
+
+ // Add a handler for incoming peripheral connections.
+ if (enabled) {
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &connections[i];
+ connection->conn_handle = BLE_CONN_HANDLE_INVALID;
+ }
+ bleio_adapter_reset_name(self);
+ ble_drv_add_event_handler_entry(&self->handler_entry, adapter_on_ble_evt, self);
+ } else {
+ ble_drv_reset();
+ self->scan_results = NULL;
+ self->current_advertising_data = NULL;
+ self->advertising_data = NULL;
+ self->scan_response_data = NULL;
}
}
-bool common_hal_bleio_adapter_get_enabled(void) {
+bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self) {
uint8_t is_enabled;
const uint32_t err_code = sd_softdevice_is_enabled(&is_enabled);
@@ -163,42 +306,339 @@ bool common_hal_bleio_adapter_get_enabled(void) {
return is_enabled;
}
-void get_address(ble_gap_addr_t *address) {
+bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *self) {
+ common_hal_bleio_adapter_set_enabled(self, true);
+
+ ble_gap_addr_t local_address;
+ get_address(self, &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_str_t* common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self) {
+ uint16_t len = 0;
+ sd_ble_gap_device_name_get(NULL, &len);
+ uint8_t buf[len];
+ uint32_t err_code = sd_ble_gap_device_name_get(buf, &len);
+ if (err_code != NRF_SUCCESS) {
+ return NULL;
+ }
+ return mp_obj_new_str((char*) buf, len);
+}
+
+void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char* name) {
+ ble_gap_conn_sec_mode_t sec;
+ sec.lv = 0;
+ sec.sm = 0;
+ sd_ble_gap_device_name_set(&sec, (const uint8_t*) name, strlen(name));
+}
+
+STATIC bool scan_on_ble_evt(ble_evt_t *ble_evt, void *scan_results_in) {
+ bleio_scanresults_obj_t *scan_results = (bleio_scanresults_obj_t*)scan_results_in;
+
+ if (ble_evt->header.evt_id == BLE_GAP_EVT_TIMEOUT &&
+ ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN) {
+ shared_module_bleio_scanresults_set_done(scan_results, true);
+ ble_drv_remove_event_handler(scan_on_ble_evt, scan_results);
+ return true;
+ }
+
+ if (ble_evt->header.evt_id != BLE_GAP_EVT_ADV_REPORT) {
+ return false;
+ }
+ ble_gap_evt_adv_report_t *report = &ble_evt->evt.gap_evt.params.adv_report;
+
+ shared_module_bleio_scanresults_append(scan_results,
+ ticks_ms,
+ report->type.connectable,
+ report->type.scan_response,
+ report->rssi,
+ report->peer_addr.addr,
+ report->peer_addr.addr_type,
+ report->data.p_data,
+ report->data.len);
+
+ const uint32_t err_code = sd_ble_gap_scan_start(NULL, scan_results->common_hal_data);
+ if (err_code != NRF_SUCCESS) {
+ // TODO: Pass the error into the scan results so it can throw an exception.
+ scan_results->done = true;
+ }
+ return true;
+}
+
+mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t* prefixes, size_t prefix_length, bool extended, mp_int_t buffer_size, mp_float_t timeout, mp_float_t interval, mp_float_t window, mp_int_t minimum_rssi, bool active) {
+ if (self->scan_results != NULL) {
+ if (!shared_module_bleio_scanresults_get_done(self->scan_results)) {
+ mp_raise_RuntimeError(translate("Scan already in progess. Stop with stop_scan."));
+ }
+ self->scan_results = NULL;
+ }
+ self->scan_results = shared_module_bleio_new_scanresults(buffer_size, prefixes, prefix_length, minimum_rssi);
+ size_t max_packet_size = extended ? BLE_GAP_SCAN_BUFFER_EXTENDED_MAX_SUPPORTED : BLE_GAP_SCAN_BUFFER_MAX;
+ uint8_t *raw_data = m_malloc(sizeof(ble_data_t) + max_packet_size, false);
+ ble_data_t * sd_data = (ble_data_t *) raw_data;
+ self->scan_results->common_hal_data = sd_data;
+ sd_data->len = max_packet_size;
+ sd_data->p_data = raw_data + sizeof(ble_data_t);
+
+ ble_drv_add_event_handler(scan_on_ble_evt, self->scan_results);
+
+ uint32_t nrf_timeout = SEC_TO_UNITS(timeout, UNIT_10_MS);
+ if (timeout <= 0.0001) {
+ nrf_timeout = BLE_GAP_SCAN_TIMEOUT_UNLIMITED;
+ }
+
+ ble_gap_scan_params_t scan_params = {
+ .extended = extended,
+ .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS),
+ .timeout = nrf_timeout,
+ .window = SEC_TO_UNITS(window, UNIT_0_625_MS),
+ .scan_phys = BLE_GAP_PHY_1MBPS,
+ .active = active
+ };
uint32_t err_code;
+ err_code = sd_ble_gap_scan_start(&scan_params, sd_data);
- common_hal_bleio_adapter_set_enabled(true);
- err_code = sd_ble_gap_addr_get(address);
+ if (err_code != NRF_SUCCESS) {
+ self->scan_results = NULL;
+ ble_drv_remove_event_handler(scan_on_ble_evt, self->scan_results);
+ mp_raise_OSError_msg_varg(translate("Failed to start scanning, err 0x%04x"), err_code);
+ }
+
+ return MP_OBJ_FROM_PTR(self->scan_results);
+}
+
+void common_hal_bleio_adapter_stop_scan(bleio_adapter_obj_t *self) {
+ sd_ble_gap_scan_stop();
+ shared_module_bleio_scanresults_set_done(self->scan_results, true);
+ ble_drv_remove_event_handler(scan_on_ble_evt, self->scan_results);
+ self->scan_results = NULL;
+}
+
+typedef struct {
+ uint16_t conn_handle;
+ volatile bool done;
+} connect_info_t;
+
+STATIC bool connect_on_ble_evt(ble_evt_t *ble_evt, void *info_in) {
+ connect_info_t *info = (connect_info_t*)info_in;
+
+ switch (ble_evt->header.evt_id) {
+ case BLE_GAP_EVT_CONNECTED:
+ info->conn_handle = ble_evt->evt.gap_evt.conn_handle;
+ info->done = true;
+
+ break;
+
+ case BLE_GAP_EVT_TIMEOUT:
+ // Handle will be invalid.
+ info->done = true;
+ break;
+ default:
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Unhandled central event: 0x%04x\n", ble_evt->header.evt_id);
+ return false;
+ break;
+ }
+ return true;
+}
+
+mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout, bool pair) {
+
+ ble_gap_addr_t addr;
+
+ addr.addr_type = address->type;
+ mp_buffer_info_t address_buf_info;
+ mp_get_buffer_raise(address->bytes, &address_buf_info, MP_BUFFER_READ);
+ memcpy(addr.addr, (uint8_t *) address_buf_info.buf, NUM_BLEIO_ADDRESS_BYTES);
+
+ ble_gap_scan_params_t scan_params = {
+ .interval = MSEC_TO_UNITS(100, UNIT_0_625_MS),
+ .window = MSEC_TO_UNITS(100, UNIT_0_625_MS),
+ .scan_phys = BLE_GAP_PHY_1MBPS,
+ // timeout of 0 means no timeout
+ .timeout = SEC_TO_UNITS(timeout, UNIT_10_MS),
+ };
+
+ ble_gap_conn_params_t conn_params = {
+ .conn_sup_timeout = MSEC_TO_UNITS(4000, UNIT_10_MS),
+ .min_conn_interval = MSEC_TO_UNITS(15, UNIT_1_25_MS),
+ .max_conn_interval = MSEC_TO_UNITS(300, UNIT_1_25_MS),
+ .slave_latency = 0, // number of conn events
+ };
+
+ connect_info_t event_info;
+ ble_drv_add_event_handler(connect_on_ble_evt, &event_info);
+ event_info.done = false;
+
+ uint32_t err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_CUSTOM);
if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg(translate("Failed to get local address"));
+ ble_drv_remove_event_handler(connect_on_ble_evt, &event_info);
+ mp_raise_OSError_msg_varg(translate("Failed to start connecting, error 0x%04x"), err_code);
+ }
+
+ while (!event_info.done) {
+ RUN_BACKGROUND_TASKS;
+ }
+
+ ble_drv_remove_event_handler(connect_on_ble_evt, &event_info);
+
+ if (event_info.conn_handle == BLE_CONN_HANDLE_INVALID) {
+ mp_raise_OSError_msg(translate("Failed to connect: timeout"));
}
+
+ // Make the connection object and return it.
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &connections[i];
+ if (connection->conn_handle == event_info.conn_handle) {
+ return bleio_connection_new_from_internal(connection);
+ }
+ }
+
+ mp_raise_OSError_msg(translate("Failed to connect: internal error"));
+
+ return mp_const_none;
}
-bleio_address_obj_t *common_hal_bleio_adapter_get_address(void) {
- common_hal_bleio_adapter_set_enabled(true);
+// The nRF SD 6.1.0 can only do one concurrent advertisement so share the advertising handle.
+uint8_t adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
- ble_gap_addr_t local_address;
- get_address(&local_address);
+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"));
+ }
+}
- bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t);
- address->base.type = &bleio_address_type;
+uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, float interval, uint8_t *advertising_data, uint16_t advertising_data_len, uint8_t *scan_response_data, uint16_t scan_response_data_len) {
+ if (self->current_advertising_data != NULL && self->current_advertising_data == self->advertising_data) {
+ return NRF_ERROR_BUSY;
+ }
- common_hal_bleio_address_construct(address, local_address.addr, local_address.addr_type);
- return address;
+ // If the current advertising data isn't owned by the adapter then it must be an internal
+ // advertisement that we should stop.
+ if (self->current_advertising_data != NULL) {
+ common_hal_bleio_adapter_stop_advertising(self);
+ }
+
+ uint32_t err_code;
+ ble_gap_adv_params_t adv_params = {
+ .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS),
+ .properties.type = connectable ? BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED
+ : BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED,
+ .duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED,
+ .filter_policy = BLE_GAP_ADV_FP_ANY,
+ .primary_phy = BLE_GAP_PHY_1MBPS,
+ };
+
+ const ble_gap_adv_data_t ble_gap_adv_data = {
+ .adv_data.p_data = advertising_data,
+ .adv_data.len = advertising_data_len,
+ .scan_rsp_data.p_data = scan_response_data_len > 0 ? scan_response_data : NULL,
+ .scan_rsp_data.len = scan_response_data_len,
+ };
+
+ err_code = sd_ble_gap_adv_set_configure(&adv_handle, &ble_gap_adv_data, &adv_params);
+ if (err_code != NRF_SUCCESS) {
+ return err_code;
+ }
+
+ err_code = sd_ble_gap_adv_start(adv_handle, BLE_CONN_CFG_TAG_CUSTOM);
+ if (err_code != NRF_SUCCESS) {
+ return err_code;
+ }
+ self->current_advertising_data = advertising_data;
+ return NRF_SUCCESS;
}
-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);
+void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, mp_float_t interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo) {
+ if (self->current_advertising_data != NULL && self->current_advertising_data == self->advertising_data) {
+ mp_raise_OSError_msg(translate("Already advertising."));
+ }
+ // interval value has already been validated.
+
+ uint32_t err_code;
+
+ check_data_fit(advertising_data_bufinfo->len);
+ check_data_fit(scan_response_data_bufinfo->len);
+ // The advertising data buffers must not move, because the SoftDevice depends on them.
+ // So make them long-lived and reuse them onwards.
+ if (self->advertising_data == NULL) {
+ self->advertising_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_MAX * sizeof(uint8_t), false, true);
+ }
+ if (self->scan_response_data == NULL) {
+ self->scan_response_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_MAX * sizeof(uint8_t), false, true);
+ }
+
+ memcpy(self->advertising_data, advertising_data_bufinfo->buf, advertising_data_bufinfo->len);
+ memcpy(self->scan_response_data, scan_response_data_bufinfo->buf, scan_response_data_bufinfo->len);
+
+ err_code = _common_hal_bleio_adapter_start_advertising(self, connectable, interval, self->advertising_data, advertising_data_bufinfo->len, self->scan_response_data, scan_response_data_bufinfo->len);
- char name[] = { 'C', 'I', 'R', 'C', 'U', 'I', 'T', 'P', 'Y', 0, 0, 0, 0 };
+ if (err_code != NRF_SUCCESS) {
+ mp_raise_OSError_msg_varg(translate("Failed to start advertising, NRF_ERROR_%q"), MP_OBJ_QSTR_VALUE(base_error_messages[err_code - NRF_ERROR_BASE_NUM]));
+ }
+}
+
+void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) {
+ if (adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET)
+ return;
+
+ // TODO: Don't actually stop. Switch to advertising CircuitPython if we don't already have a connection.
+ const uint32_t err_code = sd_ble_gap_adv_stop(adv_handle);
+ self->current_advertising_data = NULL;
+
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) {
+ mp_raise_OSError_msg_varg(translate("Failed to stop advertising, NRF_ERROR_%q"), MP_OBJ_QSTR_VALUE(base_error_messages[err_code - NRF_ERROR_BASE_NUM]));
+ }
+}
- 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];
+bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self) {
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &connections[i];
+ if (connection->conn_handle != BLE_CONN_HANDLE_INVALID) {
+ return true;
+ }
+ }
+ return false;
+}
- return mp_obj_new_str(name, sizeof(name));
+mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
+ if (self->connection_objs != NULL) {
+ return self->connection_objs;
+ }
+ size_t total_connected = 0;
+ mp_obj_t items[BLEIO_TOTAL_CONNECTION_COUNT];
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &connections[i];
+ if (connection->conn_handle != BLE_CONN_HANDLE_INVALID) {
+ if (connection->connection_obj == mp_const_none) {
+ connection->connection_obj = bleio_connection_new_from_internal(connection);
+ }
+ items[total_connected] = connection->connection_obj;
+ total_connected++;
+ }
+ }
+ self->connection_objs = mp_obj_new_tuple(total_connected, items);
+ return self->connection_objs;
+}
+
+void bleio_adapter_gc_collect(bleio_adapter_obj_t* adapter) {
+ gc_collect_root((void**)adapter, sizeof(bleio_adapter_obj_t) / sizeof(size_t));
+ gc_collect_root((void**)connections, sizeof(connections) / sizeof(size_t));
+}
+
+void bleio_adapter_reset(bleio_adapter_obj_t* adapter) {
+ common_hal_bleio_adapter_stop_scan(adapter);
+ common_hal_bleio_adapter_stop_advertising(adapter);
+ adapter->connection_objs = NULL;
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &connections[i];
+ connection->connection_obj = mp_const_none;
+ }
}
diff --git a/ports/nrf/common-hal/_bleio/Adapter.h b/ports/nrf/common-hal/_bleio/Adapter.h
index 5dcc62540..dca443990 100644
--- a/ports/nrf/common-hal/_bleio/Adapter.h
+++ b/ports/nrf/common-hal/_bleio/Adapter.h
@@ -30,9 +30,27 @@
#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ADAPTER_H
#include "py/obj.h"
+#include "py/objtuple.h"
+
+#include "shared-bindings/_bleio/Connection.h"
+#include "shared-bindings/_bleio/ScanResults.h"
+
+#define BLEIO_TOTAL_CONNECTION_COUNT 2
+
+extern bleio_connection_internal_t connections[BLEIO_TOTAL_CONNECTION_COUNT];
typedef struct {
mp_obj_base_t base;
-} super_adapter_obj_t;
+ uint8_t* advertising_data;
+ uint8_t* scan_response_data;
+ uint8_t* current_advertising_data;
+ bleio_scanresults_obj_t* scan_results;
+ mp_obj_t name;
+ mp_obj_tuple_t *connection_objs;
+ ble_drv_evt_handler_entry_t handler_entry;
+} bleio_adapter_obj_t;
+
+void bleio_adapter_gc_collect(bleio_adapter_obj_t* adapter);
+void bleio_adapter_reset(bleio_adapter_obj_t* adapter);
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_ADAPTER_H
diff --git a/ports/nrf/common-hal/_bleio/Central.c b/ports/nrf/common-hal/_bleio/Central.c
deleted file mode 100644
index db67b763c..000000000
--- a/ports/nrf/common-hal/_bleio/Central.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include "ble.h"
-#include "ble_drv.h"
-#include "ble_hci.h"
-#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/Central.h"
-
-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;
-
- switch (ble_evt->header.evt_id) {
- case BLE_GAP_EVT_CONNECTED:
- central->conn_handle = ble_evt->evt.gap_evt.conn_handle;
- central->waiting_to_connect = false;
- break;
-
- case BLE_GAP_EVT_TIMEOUT:
- // Handle will be invalid.
- central->waiting_to_connect = false;
- break;
-
- case BLE_GAP_EVT_DISCONNECTED:
- central->conn_handle = BLE_CONN_HANDLE_INVALID;
- break;
-
- case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
- sd_ble_gap_sec_params_reply(central->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;
- 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);
- break;
- }
-}
-
-void common_hal_bleio_central_construct(bleio_central_obj_t *self) {
- common_hal_bleio_adapter_set_enabled(true);
-
- self->remote_service_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) {
- common_hal_bleio_adapter_set_enabled(true);
- ble_drv_add_event_handler(central_on_ble_evt, self);
-
- ble_gap_addr_t addr;
-
- addr.addr_type = address->type;
- mp_buffer_info_t address_buf_info;
- mp_get_buffer_raise(address->bytes, &address_buf_info, MP_BUFFER_READ);
- memcpy(addr.addr, (uint8_t *) address_buf_info.buf, NUM_BLEIO_ADDRESS_BYTES);
-
- ble_gap_scan_params_t scan_params = {
- .interval = MSEC_TO_UNITS(100, UNIT_0_625_MS),
- .window = MSEC_TO_UNITS(100, UNIT_0_625_MS),
- .scan_phys = BLE_GAP_PHY_1MBPS,
- // timeout of 0 means no timeout
- .timeout = SEC_TO_UNITS(timeout, UNIT_10_MS),
- };
-
- ble_gap_conn_params_t conn_params = {
- .conn_sup_timeout = MSEC_TO_UNITS(4000, UNIT_10_MS),
- .min_conn_interval = MSEC_TO_UNITS(15, UNIT_1_25_MS),
- .max_conn_interval = MSEC_TO_UNITS(300, UNIT_1_25_MS),
- .slave_latency = 0, // number of conn events
- };
-
- self->waiting_to_connect = true;
-
- uint32_t err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_CUSTOM);
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to start connecting, error 0x%04x"), err_code);
- }
-
- while (self->waiting_to_connect) {
- RUN_BACKGROUND_TASKS;
- }
-
- if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
- mp_raise_OSError_msg(translate("Failed to connect: timeout"));
- }
-}
-
-void common_hal_bleio_central_disconnect(bleio_central_obj_t *self) {
- sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
-}
-
-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_service_list->len,
- self->remote_service_list->items);
- mp_obj_list_clear(self->remote_service_list);
- return services_tuple;
-}
-
-mp_obj_list_t *common_hal_bleio_central_get_remote_services(bleio_central_obj_t *self) {
- return self->remote_service_list;
-}
diff --git a/ports/nrf/common-hal/_bleio/Characteristic.c b/ports/nrf/common-hal/_bleio/Characteristic.c
index e8454d528..ab765d1ed 100644
--- a/ports/nrf/common-hal/_bleio/Characteristic.c
+++ b/ports/nrf/common-hal/_bleio/Characteristic.c
@@ -32,7 +32,7 @@
#include "shared-bindings/_bleio/Descriptor.h"
#include "shared-bindings/_bleio/Service.h"
-static volatile bleio_characteristic_obj_t *m_read_characteristic;
+#include "common-hal/_bleio/Adapter.h"
STATIC uint16_t characteristic_get_cccd(uint16_t cccd_handle, uint16_t conn_handle) {
uint16_t cccd;
@@ -53,27 +53,6 @@ STATIC uint16_t characteristic_get_cccd(uint16_t cccd_handle, uint16_t conn_hand
return cccd;
}
-STATIC void characteristic_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_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;
- }
-
- default:
- // For debugging.
- // mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id);
- break;
- }
-}
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;
@@ -103,35 +82,14 @@ STATIC void characteristic_gatts_notify_indicate(uint16_t handle, uint16_t conn_
}
}
-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);
- 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);
- }
-
- while (m_read_characteristic != NULL) {
- RUN_BACKGROUND_TASKS;
- }
-
- ble_drv_remove_event_handler(characteristic_on_gattc_read_rsp_evt, characteristic);
-}
-
-void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, 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_buffer_info_t *initial_value_bufinfo) {
+void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, uint16_t handle, 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_buffer_info_t *initial_value_bufinfo) {
self->service = service;
self->uuid = uuid;
self->handle = BLE_GATT_HANDLE_INVALID;
self->props = props;
self->read_perm = read_perm;
self->write_perm = write_perm;
- self->descriptor_list = mp_obj_new_list(0, NULL);
+ self->descriptor_list = NULL;
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) {
@@ -141,10 +99,18 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self,
self->max_length = max_length;
self->fixed_length = fixed_length;
- common_hal_bleio_characteristic_set_value(self, initial_value_bufinfo);
+ if (service->is_remote) {
+ self->handle = handle;
+ } else {
+ common_hal_bleio_service_add_characteristic(self->service, self, initial_value_bufinfo);
+ }
+
+ if (initial_value_bufinfo != NULL) {
+ common_hal_bleio_characteristic_set_value(self, initial_value_bufinfo);
+ }
}
-mp_obj_list_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self) {
+bleio_descriptor_obj_t *common_hal_bleio_characteristic_get_descriptor_list(bleio_characteristic_obj_t *self) {
return self->descriptor_list;
}
@@ -152,19 +118,19 @@ bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_character
return self->service;
}
-mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self) {
+size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t* buf, size_t len) {
// 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);
+ uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
if (common_hal_bleio_service_get_is_remote(self->service)) {
// self->value is set by evt handler.
- characteristic_gattc_read(self);
+ return common_hal_bleio_gattc_read(self->handle, conn_handle, buf, len);
} else {
- self->value = common_hal_bleio_gatts_read(self->handle, conn_handle);
+ return common_hal_bleio_gatts_read(self->handle, conn_handle, buf, len);
}
}
- return self->value;
+ return 0;
}
void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) {
@@ -175,39 +141,40 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self,
mp_raise_ValueError(translate("Value length > max_length"));
}
- self->value = mp_obj_new_bytes(bufinfo->buf, bufinfo->len);
-
// 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)) {
+ uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
// 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 {
-
- bool sent = false;
- uint16_t cccd = 0;
-
- 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 (notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) {
- characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_NOTIFICATION);
- sent = true;
- }
- if (indicate && (cccd & BLE_GATT_HVX_INDICATION)) {
- characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_INDICATION);
- sent = true;
- }
-
- if (!sent) {
- common_hal_bleio_gatts_write(self->handle, conn_handle, bufinfo);
+ // Always write the value locally even if no connections are active.
+ common_hal_bleio_gatts_write(self->handle, BLE_CONN_HANDLE_INVALID, bufinfo);
+ // Check to see if we need to notify or indicate any active connections.
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ bleio_connection_internal_t *connection = &connections[i];
+ uint16_t conn_handle = connection->conn_handle;
+ if (connection->conn_handle == BLE_CONN_HANDLE_INVALID) {
+ continue;
+ }
+
+ uint16_t cccd = 0;
+
+ 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 (notify && (cccd & BLE_GATT_HVX_NOTIFICATION)) {
+ characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_NOTIFICATION);
+ }
+ if (indicate && (cccd & BLE_GATT_HVX_INDICATION)) {
+ characteristic_gatts_notify_indicate(self->handle, conn_handle, bufinfo, BLE_GATT_HVX_INDICATION);
+ }
}
}
}
@@ -252,7 +219,8 @@ void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *
mp_raise_OSError_msg_varg(translate("Failed to add descriptor, err 0x%04x"), err_code);
}
- mp_obj_list_append(self->descriptor_list, MP_OBJ_FROM_PTR(descriptor));
+ descriptor->next = self->descriptor_list;
+ self->descriptor_list = descriptor;
}
void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate) {
@@ -264,7 +232,7 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self,
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);
+ const uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection);
common_hal_bleio_check_connected(conn_handle);
uint16_t cccd_value =
diff --git a/ports/nrf/common-hal/_bleio/Characteristic.h b/ports/nrf/common-hal/_bleio/Characteristic.h
index 3a7691d07..bb8f28495 100644
--- a/ports/nrf/common-hal/_bleio/Characteristic.h
+++ b/ports/nrf/common-hal/_bleio/Characteristic.h
@@ -29,11 +29,12 @@
#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CHARACTERISTIC_H
#include "shared-bindings/_bleio/Attribute.h"
+#include "common-hal/_bleio/Descriptor.h"
#include "shared-module/_bleio/Characteristic.h"
#include "common-hal/_bleio/Service.h"
#include "common-hal/_bleio/UUID.h"
-typedef struct {
+typedef struct _bleio_characteristic_obj {
mp_obj_base_t base;
// Will be MP_OBJ_NULL before being assigned to a Service.
bleio_service_obj_t *service;
@@ -45,7 +46,7 @@ typedef struct {
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;
+ bleio_descriptor_obj_t *descriptor_list;
uint16_t user_desc_handle;
uint16_t cccd_handle;
uint16_t sccd_handle;
diff --git a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c
index 95794feec..5f280e121 100644
--- a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c
+++ b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c
@@ -38,6 +38,7 @@
#include "tick.h"
#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Connection.h"
#include "common-hal/_bleio/CharacteristicBuffer.h"
STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) {
@@ -50,7 +51,7 @@ STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *d
sd_nvic_critical_region_exit(is_nested_critical_region);
}
-STATIC void characteristic_buffer_on_ble_evt(ble_evt_t *ble_evt, void *param) {
+STATIC bool characteristic_buffer_on_ble_evt(ble_evt_t *ble_evt, void *param) {
bleio_characteristic_buffer_obj_t *self = (bleio_characteristic_buffer_obj_t *) param;
switch (ble_evt->header.evt_id) {
case BLE_GATTS_EVT_WRITE: {
@@ -75,7 +76,11 @@ STATIC void characteristic_buffer_on_ble_evt(ble_evt_t *ble_evt, void *param) {
}
break;
}
+ default:
+ return false;
+ break;
}
+ return true;
}
// Assumes that timeout and buffer_size have been validated before call.
@@ -150,6 +155,7 @@ void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_o
bool common_hal_bleio_characteristic_buffer_connected(bleio_characteristic_buffer_obj_t *self) {
return self->characteristic != NULL &&
self->characteristic->service != NULL &&
- self->characteristic->service->device != NULL &&
- common_hal_bleio_device_get_conn_handle(self->characteristic->service->device) != BLE_CONN_HANDLE_INVALID;
+ (!self->characteristic->service->is_remote ||
+ (self->characteristic->service->connection != MP_OBJ_NULL &&
+ common_hal_bleio_connection_get_connected(self->characteristic->service->connection)));
}
diff --git a/ports/nrf/common-hal/_bleio/Connection.c b/ports/nrf/common-hal/_bleio/Connection.c
new file mode 100644
index 000000000..5d3e3ace1
--- /dev/null
+++ b/ports/nrf/common-hal/_bleio/Connection.c
@@ -0,0 +1,629 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-bindings/_bleio/Connection.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#include "ble.h"
+#include "ble_drv.h"
+#include "ble_hci.h"
+#include "nrf_soc.h"
+#include "py/gc.h"
+#include "py/objlist.h"
+#include "py/objstr.h"
+#include "py/qstr.h"
+#include "py/runtime.h"
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Adapter.h"
+#include "shared-bindings/_bleio/Attribute.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+#include "shared-bindings/_bleio/Service.h"
+#include "shared-bindings/_bleio/UUID.h"
+
+#define BLE_ADV_LENGTH_FIELD_SIZE 1
+#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 = 1,
+ .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 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;
+
+bool dump_events = false;
+
+bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
+ bleio_connection_internal_t *self = (bleio_connection_internal_t*)self_in;
+
+ if (BLE_GAP_EVT_BASE <= ble_evt->header.evt_id && ble_evt->header.evt_id <= BLE_GAP_EVT_LAST &&
+ ble_evt->evt.gap_evt.conn_handle != self->conn_handle) {
+ return false;
+ }
+ if (BLE_GATTS_EVT_BASE <= ble_evt->header.evt_id && ble_evt->header.evt_id <= BLE_GATTS_EVT_LAST &&
+ ble_evt->evt.gatts_evt.conn_handle != self->conn_handle) {
+ return false;
+ }
+
+ // For debugging.
+ if (dump_events) {
+ mp_printf(&mp_plat_print, "Connection event: 0x%04x\n", ble_evt->header.evt_id);
+ }
+
+ switch (ble_evt->header.evt_id) {
+ case BLE_GAP_EVT_DISCONNECTED:
+ break;
+ case BLE_GAP_EVT_CONN_PARAM_UPDATE: // 0x12
+ break;
+ case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
+ ble_gap_phys_t const phys = {
+ .rx_phys = BLE_GAP_PHY_AUTO,
+ .tx_phys = BLE_GAP_PHY_AUTO,
+ };
+ sd_ble_gap_phy_update(ble_evt->evt.gap_evt.conn_handle, &phys);
+ break;
+ }
+
+ case BLE_GAP_EVT_PHY_UPDATE: // 0x22
+ break;
+
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
+ // SoftDevice will respond to a length update request.
+ sd_ble_gap_data_length_update(self->conn_handle, NULL, NULL);
+ break;
+
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE: // 0x24
+ break;
+
+ case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: {
+ // We only handle MTU of size BLE_GATT_ATT_MTU_DEFAULT.
+ sd_ble_gatts_exchange_mtu_reply(self->conn_handle, BLE_GATT_ATT_MTU_DEFAULT);
+ break;
+ }
+
+ case BLE_GATTS_EVT_SYS_ATTR_MISSING:
+ sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
+ break;
+
+ case BLE_GATTS_EVT_HVN_TX_COMPLETE: // Capture this for now. 0x55
+ 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;
+ sd_ble_gap_conn_param_update(self->conn_handle, &request->conn_params);
+ break;
+ }
+ case BLE_GAP_EVT_SEC_PARAMS_REQUEST: {
+ ble_gap_sec_keyset_t keyset = {
+ .keys_own = {
+ .p_enc_key = &self->bonding_keys.own_enc,
+ .p_id_key = NULL,
+ .p_sign_key = NULL,
+ .p_pk = NULL
+ },
+
+ .keys_peer = {
+ .p_enc_key = &self->bonding_keys.peer_enc,
+ .p_id_key = &self->bonding_keys.peer_id,
+ .p_sign_key = NULL,
+ .p_pk = NULL
+ }
+ };
+
+ sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_SUCCESS,
+ &pairing_sec_params, &keyset);
+ 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: { // 0x19
+ // 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) {
+ // TODO _ediv = bonding_keys->own_enc.master_id.ediv;
+ self->pair_status = PAIR_PAIRED;
+ } else {
+ self->pair_status = PAIR_NOT_PAIRED;
+ }
+ break;
+ }
+
+ case BLE_GAP_EVT_SEC_INFO_REQUEST: { // 0x14
+ // Peer asks for the stored keys.
+ // - load key and return if bonded previously.
+ // - Else return NULL --> Initiate key exchange
+ ble_gap_evt_sec_info_request_t* sec_info_request = &ble_evt->evt.gap_evt.params.sec_info_request;
+ (void) sec_info_request;
+ //if ( bond_load_keys(_role, sec_req->master_id.ediv, &bkeys) ) {
+ //sd_ble_gap_sec_info_reply(_conn_hdl, &bkeys.own_enc.enc_info, &bkeys.peer_id.id_info, NULL);
+ //
+ //_ediv = bkeys.own_enc.master_id.ediv;
+ // } else {
+ sd_ble_gap_sec_info_reply(self->conn_handle, NULL, NULL, NULL);
+ // }
+ break;
+ }
+
+ case BLE_GAP_EVT_CONN_SEC_UPDATE: { // 0x1a
+ 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 {
+ //if ( !bond_load_cccd(_role, _conn_hdl, _ediv) ) {
+ if (true) { // TODO: no bonding yet
+ // Initialize system attributes fresh.
+ sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
+ }
+ // Not quite paired yet: wait for BLE_GAP_EVT_AUTH_STATUS SUCCESS.
+ self->ediv = self->bonding_keys.own_enc.master_id.ediv;
+ }
+ break;
+ }
+
+
+ default:
+ // For debugging.
+ if (dump_events) {
+ mp_printf(&mp_plat_print, "Unhandled connection event: 0x%04x\n", ble_evt->header.evt_id);
+ }
+
+ return false;
+ }
+ return true;
+}
+
+void bleio_connection_clear(bleio_connection_internal_t *self) {
+ self->remote_service_list = NULL;
+
+ self->conn_handle = BLE_CONN_HANDLE_INVALID;
+ self->pair_status = PAIR_NOT_PAIRED;
+
+ memset(&self->bonding_keys, 0, sizeof(self->bonding_keys));
+}
+
+bool common_hal_bleio_connection_get_connected(bleio_connection_obj_t *self) {
+ if (self->connection == NULL) {
+ return false;
+ }
+ return self->connection->conn_handle != BLE_CONN_HANDLE_INVALID;
+}
+
+void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self) {
+ sd_ble_gap_disconnect(self->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+}
+
+void common_hal_bleio_connection_pair(bleio_connection_internal_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, NRF_ERROR_%q"), MP_OBJ_QSTR_VALUE(base_error_messages[err_code - NRF_ERROR_BASE_NUM]));
+ }
+
+ while (self->pair_status == PAIR_WAITING) {
+ RUN_BACKGROUND_TASKS;
+ }
+
+ if (self->pair_status == PAIR_NOT_PAIRED) {
+ mp_raise_OSError_msg(translate("Failed to pair"));
+ }
+}
+
+
+// service_uuid may be NULL, to discover all services.
+STATIC bool discover_next_services(bleio_connection_internal_t* connection, 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(connection->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_connection_internal_t* connection, 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(connection->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_connection_internal_t* connection, 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(connection->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_connection_internal_t* connection) {
+ bleio_service_obj_t* tail = connection->remote_service_list;
+
+ 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.
+ bleio_service_from_connection(service, bleio_connection_new_from_internal(connection));
+
+ 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;
+ }
+
+ service->next = tail;
+ tail = service;
+ }
+
+ connection->remote_service_list = tail;
+
+ 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_connection_internal_t* connection) {
+ 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, m_char_discovery_service, gattc_char->handle_value, uuid,
+ props, SECURITY_MODE_OPEN, SECURITY_MODE_OPEN,
+ GATT_MAX_DATA_LENGTH, false, // max_length, fixed_length: values may not matter for gattc
+ NULL);
+
+ 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_connection_internal_t* connection) {
+ 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, m_desc_discovery_characteristic, uuid,
+ SECURITY_MODE_OPEN, SECURITY_MODE_OPEN,
+ GATT_MAX_DATA_LENGTH, false, mp_const_empty_bytes);
+ descriptor->handle = gattc_desc->handle;
+
+ 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 bool discovery_on_ble_evt(ble_evt_t *ble_evt, mp_obj_t payload) {
+ bleio_connection_internal_t* connection = MP_OBJ_TO_PTR(payload);
+ 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, connection);
+ break;
+
+ case BLE_GATTC_EVT_CHAR_DISC_RSP:
+ on_char_discovery_rsp(&ble_evt->evt.gattc_evt.params.char_disc_rsp, connection);
+ break;
+
+ case BLE_GATTC_EVT_DESC_DISC_RSP:
+ on_desc_discovery_rsp(&ble_evt->evt.gattc_evt.params.desc_disc_rsp, connection);
+ break;
+
+ default:
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Unhandled discovery event: 0x%04x\n", ble_evt->header.evt_id);
+ return false;
+ break;
+ }
+ return true;
+}
+
+STATIC void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t service_uuids_whitelist) {
+ ble_drv_add_event_handler(discovery_on_ble_evt, self);
+
+ // Start over with an empty list.
+ self->remote_service_list = NULL;
+
+ 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(self, 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 = self->remote_service_list;
+ 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(self, BLE_GATT_HANDLE_START, &nrf_uuid);
+ }
+ }
+
+
+ bleio_service_obj_t *service = self->remote_service_list;
+ while (service != NULL) {
+ // Skip the service if it had an unknown (unregistered) UUID.
+ if (service->uuid == NULL) {
+ service = service->next;
+ 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 = characteristic->descriptor_list;
+ next_desc_start_handle = descriptor->handle + 1;
+ }
+ }
+ service = service->next;
+ }
+
+ // This event handler is no longer needed.
+ ble_drv_remove_event_handler(discovery_on_ble_evt, self);
+
+}
+mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist) {
+ discover_remote_services(self->connection, service_uuids_whitelist);
+ // Convert to a tuple and then clear the list so the callee will take ownership.
+ mp_obj_tuple_t *services_tuple = service_linked_list_to_tuple(self->connection->remote_service_list);
+ self->connection->remote_service_list = NULL;
+
+ return services_tuple;
+}
+
+
+uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self) {
+ if (self == NULL || self->connection == NULL) {
+ return BLE_CONN_HANDLE_INVALID;
+ }
+ return self->connection->conn_handle;
+}
+
+mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t* internal) {
+ if (internal->connection_obj != mp_const_none) {
+ return internal->connection_obj;
+ }
+ bleio_connection_obj_t *connection = m_new_obj(bleio_connection_obj_t);
+ connection->base.type = &bleio_connection_type;
+ connection->connection = internal;
+ internal->connection_obj = connection;
+
+ return MP_OBJ_FROM_PTR(connection);
+}
diff --git a/ports/nrf/common-hal/_bleio/Peripheral.h b/ports/nrf/common-hal/_bleio/Connection.h
index a4f62d288..2d4aad0c8 100644
--- a/ports/nrf/common-hal/_bleio/Peripheral.h
+++ b/ports/nrf/common-hal/_bleio/Connection.h
@@ -25,8 +25,8 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PERIPHERAL_H
-#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PERIPHERAL_H
+#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CONNECTION_H
+#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CONNECTION_H
#include <stdbool.h>
@@ -37,6 +37,7 @@
#include "common-hal/_bleio/__init__.h"
#include "shared-module/_bleio/Address.h"
+#include "common-hal/_bleio/Service.h"
typedef enum {
PAIR_NOT_PAIRED,
@@ -44,24 +45,35 @@ typedef enum {
PAIR_PAIRED,
} pair_status_t;
+// We split the Connection object into two so that the internal mechanics can live outside of the
+// VM. If it were one object, then we'd risk user code seeing a connection object of theirs be
+// reused.
typedef struct {
- mp_obj_base_t base;
- mp_obj_t name;
- volatile uint16_t conn_handle;
- // Services provided by this peripheral.
- mp_obj_list_t *service_list;
+ uint16_t conn_handle;
+ bool is_central;
// Remote services discovered when this peripheral is acting as a client.
- mp_obj_list_t *remote_service_list;
+ bleio_service_obj_t *remote_service_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).
// EDIV: Encrypted Diversifier: Identifies LTK during legacy pairing.
bonding_keys_t bonding_keys;
uint16_t ediv;
- uint8_t* advertising_data;
- uint8_t* scan_response_data;
- uint8_t adv_handle;
pair_status_t pair_status;
-} bleio_peripheral_obj_t;
+ mp_obj_t connection_obj;
+ ble_drv_evt_handler_entry_t handler_entry;
+} bleio_connection_internal_t;
+
+typedef struct {
+ mp_obj_base_t base;
+ bleio_connection_internal_t* connection;
+ // The HCI disconnect reason.
+ uint8_t disconnect_reason;
+} bleio_connection_obj_t;
+
+bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in);
+
+uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self);
+mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t* connection);
-#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PERIPHERAL_H
+#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CONNECTION_H
diff --git a/ports/nrf/common-hal/_bleio/Descriptor.c b/ports/nrf/common-hal/_bleio/Descriptor.c
index 137f004ba..faf50c658 100644
--- a/ports/nrf/common-hal/_bleio/Descriptor.c
+++ b/ports/nrf/common-hal/_bleio/Descriptor.c
@@ -33,8 +33,6 @@
#include "shared-bindings/_bleio/Service.h"
#include "shared-bindings/_bleio/UUID.h"
-static volatile bleio_descriptor_obj_t *m_read_descriptor;
-
void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_characteristic_obj_t *characteristic, 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, mp_buffer_info_t *initial_value_bufinfo) {
self->characteristic = characteristic;
self->uuid = uuid;
@@ -61,62 +59,18 @@ bleio_characteristic_obj_t *common_hal_bleio_descriptor_get_characteristic(bleio
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) {
+size_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self, uint8_t* buf, size_t len) {
// Do GATT operations only if this descriptor has been registered
if (self->handle != BLE_GATT_HANDLE_INVALID) {
+ uint16_t conn_handle = bleio_connection_get_conn_handle(self->characteristic->service->connection);
if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) {
- descriptor_gattc_read(self);
+ return common_hal_bleio_gattc_read(self->handle, conn_handle, buf, len);
} else {
- self->value = common_hal_bleio_gatts_read(
- self->handle, common_hal_bleio_device_get_conn_handle(self->characteristic->service->device));
+ return common_hal_bleio_gatts_read(self->handle, conn_handle, buf, len);
}
}
- return self->value;
+ return 0;
}
void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buffer_info_t *bufinfo) {
@@ -131,7 +85,7 @@ void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buff
// 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);
+ uint16_t conn_handle = bleio_connection_get_conn_handle(self->characteristic->service->connection);
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);
diff --git a/ports/nrf/common-hal/_bleio/Descriptor.h b/ports/nrf/common-hal/_bleio/Descriptor.h
index 3adb0df18..c70547c08 100644
--- a/ports/nrf/common-hal/_bleio/Descriptor.h
+++ b/ports/nrf/common-hal/_bleio/Descriptor.h
@@ -31,13 +31,15 @@
#include "py/obj.h"
-#include "common-hal/_bleio/Characteristic.h"
#include "common-hal/_bleio/UUID.h"
-typedef struct {
+// Forward declare characteristic because it includes a Descriptor.
+struct _bleio_characteristic_obj;
+
+typedef struct _bleio_descriptor_obj {
mp_obj_base_t base;
// Will be MP_OBJ_NULL before being assigned to a Characteristic.
- bleio_characteristic_obj_t *characteristic;
+ struct _bleio_characteristic_obj *characteristic;
bleio_uuid_obj_t *uuid;
mp_obj_t value;
uint16_t max_length;
@@ -45,6 +47,7 @@ typedef struct {
uint16_t handle;
bleio_attribute_security_mode_t read_perm;
bleio_attribute_security_mode_t write_perm;
+ struct _bleio_descriptor_obj* next;
} 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
deleted file mode 100644
index 9b0f96d48..000000000
--- a/ports/nrf/common-hal/_bleio/Peripheral.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include "ble.h"
-#include "ble_drv.h"
-#include "ble_hci.h"
-#include "nrf_soc.h"
-#include "py/gc.h"
-#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/Attribute.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"
-
-#define BLE_ADV_LENGTH_FIELD_SIZE 1
-#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 = 1,
- .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"));
- }
-}
-
-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.
- ble_gap_evt_connected_t* connected = &ble_evt->evt.gap_evt.params.connected;
-
- self->conn_handle = ble_evt->evt.gap_evt.conn_handle;
-
- // See if connection interval set by Central is out of range.
- // If so, negotiate our preferred range.
- ble_gap_conn_params_t conn_params;
- sd_ble_gap_ppcp_get(&conn_params);
- if (conn_params.min_conn_interval < connected->conn_params.min_conn_interval ||
- conn_params.min_conn_interval > connected->conn_params.max_conn_interval) {
- sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params);
- }
- break;
- }
-
- case BLE_GAP_EVT_DISCONNECTED:
- // Central has disconnected.
- self->conn_handle = BLE_CONN_HANDLE_INVALID;
- break;
-
- case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
- ble_gap_phys_t const phys = {
- .rx_phys = BLE_GAP_PHY_AUTO,
- .tx_phys = BLE_GAP_PHY_AUTO,
- };
- sd_ble_gap_phy_update(ble_evt->evt.gap_evt.conn_handle, &phys);
- break;
- }
-
- case BLE_GAP_EVT_ADV_SET_TERMINATED:
- // TODO: Someday may handle timeouts or limit reached.
- break;
-
- case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
- // SoftDevice will respond to a length update request.
- sd_ble_gap_data_length_update(self->conn_handle, NULL, NULL);
- break;
-
- case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: {
- // We only handle MTU of size BLE_GATT_ATT_MTU_DEFAULT.
- sd_ble_gatts_exchange_mtu_reply(self->conn_handle, BLE_GATT_ATT_MTU_DEFAULT);
- break;
- }
-
- case BLE_GATTS_EVT_SYS_ATTR_MISSING:
- sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
- break;
-
- case BLE_GAP_EVT_SEC_PARAMS_REQUEST: {
- ble_gap_sec_keyset_t keyset = {
- .keys_own = {
- .p_enc_key = &self->bonding_keys.own_enc,
- .p_id_key = NULL,
- .p_sign_key = NULL,
- .p_pk = NULL
- },
-
- .keys_peer = {
- .p_enc_key = &self->bonding_keys.peer_enc,
- .p_id_key = &self->bonding_keys.peer_id,
- .p_sign_key = NULL,
- .p_pk = NULL
- }
- };
-
- sd_ble_gap_sec_params_reply(self->conn_handle, BLE_GAP_SEC_STATUS_SUCCESS,
- &pairing_sec_params, &keyset);
- 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) {
- // TODO _ediv = bonding_keys->own_enc.master_id.ediv;
- self->pair_status = PAIR_PAIRED;
- } else {
- self->pair_status = PAIR_NOT_PAIRED;
- }
- break;
- }
-
- case BLE_GAP_EVT_SEC_INFO_REQUEST: {
- // Peer asks for the stored keys.
- // - load key and return if bonded previously.
- // - Else return NULL --> Initiate key exchange
- ble_gap_evt_sec_info_request_t* sec_info_request = &ble_evt->evt.gap_evt.params.sec_info_request;
- (void) sec_info_request;
- //if ( bond_load_keys(_role, sec_req->master_id.ediv, &bkeys) ) {
- //sd_ble_gap_sec_info_reply(_conn_hdl, &bkeys.own_enc.enc_info, &bkeys.peer_id.id_info, NULL);
- //
- //_ediv = bkeys.own_enc.master_id.ediv;
- // } else {
- sd_ble_gap_sec_info_reply(self->conn_handle, NULL, NULL, NULL);
- // }
- 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 {
- //if ( !bond_load_cccd(_role, _conn_hdl, _ediv) ) {
- if (true) { // TODO: no bonding yet
- // Initialize system attributes fresh.
- sd_ble_gatts_sys_attr_set(self->conn_handle, NULL, 0, 0);
- }
- // Not quite paired yet: wait for BLE_GAP_EVT_AUTH_STATUS SUCCESS.
- self->ediv = self->bonding_keys.own_enc.master_id.ediv;
- }
- break;
- }
-
-
- default:
- // For debugging.
- // mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id);
- break;
- }
-}
-
-void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_t name) {
- common_hal_bleio_adapter_set_enabled(true);
-
- self->service_list = mp_obj_new_list(0, NULL);
- // Used only for discovery when acting as a client.
- self->remote_service_list = mp_obj_new_list(0, NULL);
- self->name = name;
-
- self->conn_handle = BLE_CONN_HANDLE_INVALID;
- self->adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
- self->pair_status = PAIR_NOT_PAIRED;
-
- memset(&self->bonding_keys, 0, sizeof(self->bonding_keys));
-}
-
-void common_hal_bleio_peripheral_add_service(bleio_peripheral_obj_t *self, bleio_service_obj_t *service) {
- ble_uuid_t uuid;
- bleio_uuid_convert_to_nrf_ble_uuid(service->uuid, &uuid);
-
- uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY;
- if (common_hal_bleio_service_get_is_secondary(service)) {
- service_type = BLE_GATTS_SRVC_TYPE_SECONDARY;
- }
-
- const uint32_t err_code = sd_ble_gatts_service_add(service_type, &uuid, &service->handle);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to add service, err 0x%04x"), err_code);
- }
-
- mp_obj_list_append(self->service_list, MP_OBJ_FROM_PTR(service));
-}
-
-mp_obj_list_t *common_hal_bleio_peripheral_get_services(bleio_peripheral_obj_t *self) {
- return self->service_list;
-}
-
-bool common_hal_bleio_peripheral_get_connected(bleio_peripheral_obj_t *self) {
- return self->conn_handle != BLE_CONN_HANDLE_INVALID;
-}
-
-mp_obj_t common_hal_bleio_peripheral_get_name(bleio_peripheral_obj_t *self) {
- return self->name;
-}
-
-void common_hal_bleio_peripheral_start_advertising(bleio_peripheral_obj_t *self, bool connectable, mp_float_t interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo) {
-
- // interval value has already been validated.
-
- if (connectable) {
- ble_drv_add_event_handler(peripheral_on_ble_evt, self);
- }
-
- common_hal_bleio_adapter_set_enabled(true);
-
- uint32_t err_code;
-
- GET_STR_DATA_LEN(self->name, name_data, name_len);
- if (name_len > 0) {
- // Set device name, and make it available to anyone.
- ble_gap_conn_sec_mode_t sec_mode;
- BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
- err_code = sd_ble_gap_device_name_set(&sec_mode, name_data, name_len);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to set device name, err 0x%04x"), err_code);
-
- }
- }
-
- check_data_fit(advertising_data_bufinfo->len);
- // The advertising data buffers must not move, because the SoftDevice depends on them.
- // So make them long-lived.
- self->advertising_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_MAX * sizeof(uint8_t), false, true);
- memcpy(self->advertising_data, advertising_data_bufinfo->buf, advertising_data_bufinfo->len);
-
- check_data_fit(scan_response_data_bufinfo->len);
- self->scan_response_data = (uint8_t *) gc_alloc(BLE_GAP_ADV_SET_DATA_SIZE_MAX * sizeof(uint8_t), false, true);
- memcpy(self->scan_response_data, scan_response_data_bufinfo->buf, scan_response_data_bufinfo->len);
-
-
- ble_gap_adv_params_t adv_params = {
- .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS),
- .properties.type = connectable ? BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED
- : BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED,
- .duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED,
- .filter_policy = BLE_GAP_ADV_FP_ANY,
- .primary_phy = BLE_GAP_PHY_1MBPS,
- };
-
- common_hal_bleio_peripheral_stop_advertising(self);
-
- const ble_gap_adv_data_t ble_gap_adv_data = {
- .adv_data.p_data = self->advertising_data,
- .adv_data.len = advertising_data_bufinfo->len,
- .scan_rsp_data.p_data = scan_response_data_bufinfo-> len > 0 ? self->scan_response_data : NULL,
- .scan_rsp_data.len = scan_response_data_bufinfo->len,
- };
-
- err_code = sd_ble_gap_adv_set_configure(&self->adv_handle, &ble_gap_adv_data, &adv_params);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to configure advertising, err 0x%04x"), err_code);
- }
-
- err_code = sd_ble_gap_adv_start(self->adv_handle, BLE_CONN_CFG_TAG_CUSTOM);
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to start advertising, err 0x%04x"), err_code);
- }
-}
-
-void common_hal_bleio_peripheral_stop_advertising(bleio_peripheral_obj_t *self) {
- if (self->adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET)
- return;
-
- const uint32_t err_code = sd_ble_gap_adv_stop(self->adv_handle);
-
- if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) {
- mp_raise_OSError_msg_varg(translate("Failed to stop advertising, err 0x%04x"), err_code);
- }
-}
-
-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_service_list->len,
- self->remote_service_list->items);
- mp_obj_list_clear(self->remote_service_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) {
- RUN_BACKGROUND_TASKS;
- }
-
- if (self->pair_status == PAIR_NOT_PAIRED) {
- mp_raise_OSError_msg(translate("Failed to pair"));
- }
-
-
-}
diff --git a/ports/nrf/common-hal/_bleio/Scanner.c b/ports/nrf/common-hal/_bleio/Scanner.c
deleted file mode 100644
index ec73f7eb8..000000000
--- a/ports/nrf/common-hal/_bleio/Scanner.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
- * Copyright (c) 2016 Glenn Ruben Bakke
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <string.h>
-
-#include "ble_drv.h"
-#include "ble_gap.h"
-#include "py/mphal.h"
-#include "py/objlist.h"
-#include "py/runtime.h"
-#include "shared-bindings/_bleio/Adapter.h"
-#include "shared-bindings/_bleio/ScanEntry.h"
-#include "shared-bindings/_bleio/Scanner.h"
-#include "shared-module/_bleio/ScanEntry.h"
-
-static uint8_t m_scan_buffer_data[BLE_GAP_SCAN_BUFFER_MIN];
-
-static ble_data_t m_scan_buffer = {
- m_scan_buffer_data,
- BLE_GAP_SCAN_BUFFER_MIN
-};
-
-STATIC void scanner_on_ble_evt(ble_evt_t *ble_evt, void *scanner_in) {
- bleio_scanner_obj_t *scanner = (bleio_scanner_obj_t*)scanner_in;
- ble_gap_evt_adv_report_t *report = &ble_evt->evt.gap_evt.params.adv_report;
-
- if (ble_evt->header.evt_id != BLE_GAP_EVT_ADV_REPORT) {
- return;
- }
-
- bleio_scanentry_obj_t *entry = m_new_obj(bleio_scanentry_obj_t);
- entry->base.type = &bleio_scanentry_type;
- entry->rssi = report->rssi;
-
- bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t);
- address->base.type = &bleio_address_type;
- common_hal_bleio_address_construct(MP_OBJ_TO_PTR(address),
- report->peer_addr.addr, report->peer_addr.addr_type);
- entry->address = address;
-
- entry->data = mp_obj_new_bytes(report->data.p_data, report->data.len);
-
- mp_obj_list_append(scanner->scan_entries, MP_OBJ_FROM_PTR(entry));
-
- const uint32_t err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer);
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to continue scanning, err 0x%04x"), err_code);
- }
-}
-
-void common_hal_bleio_scanner_construct(bleio_scanner_obj_t *self) {
-}
-
-mp_obj_t common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_float_t timeout, mp_float_t interval, mp_float_t window) {
- common_hal_bleio_adapter_set_enabled(true);
- ble_drv_add_event_handler(scanner_on_ble_evt, self);
-
- ble_gap_scan_params_t scan_params = {
- .interval = SEC_TO_UNITS(interval, UNIT_0_625_MS),
- .window = SEC_TO_UNITS(window, UNIT_0_625_MS),
- .scan_phys = BLE_GAP_PHY_1MBPS,
- };
-
- self->scan_entries = mp_obj_new_list(0, NULL);
-
- uint32_t err_code;
- err_code = sd_ble_gap_scan_start(&scan_params, &m_scan_buffer);
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to start scanning, err 0x%04x"), err_code);
- }
-
- mp_hal_delay_ms(timeout * 1000);
- sd_ble_gap_scan_stop();
-
- // Return list, and don't hang on to it, so it can be GC'd.
- mp_obj_t entries = self->scan_entries;
- self->scan_entries = MP_OBJ_NULL;
- return entries;
-}
diff --git a/ports/nrf/common-hal/_bleio/Service.c b/ports/nrf/common-hal/_bleio/Service.c
index 650cdc4ec..3362ed137 100644
--- a/ports/nrf/common-hal/_bleio/Service.c
+++ b/ports/nrf/common-hal/_bleio/Service.c
@@ -31,17 +31,44 @@
#include "common-hal/_bleio/__init__.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/Adapter.h"
-void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_peripheral_obj_t *peripheral, bleio_uuid_obj_t *uuid, bool is_secondary) {
- self->device = MP_OBJ_FROM_PTR(peripheral);
+uint32_t _common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary, mp_obj_list_t * characteristic_list) {
self->handle = 0xFFFF;
self->uuid = uuid;
- self->characteristic_list = mp_obj_new_list(0, NULL);
+ self->characteristic_list = characteristic_list;
self->is_remote = false;
+ self->connection = NULL;
self->is_secondary = is_secondary;
+
+ ble_uuid_t nordic_uuid;
+ bleio_uuid_convert_to_nrf_ble_uuid(uuid, &nordic_uuid);
+
+ uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY;
+ if (is_secondary) {
+ service_type = BLE_GATTS_SRVC_TYPE_SECONDARY;
+ }
+
+ vm_used_ble = true;
+
+ return sd_ble_gatts_service_add(service_type, &nordic_uuid, &self->handle);
+}
+
+void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary) {
+ const uint32_t err_code = _common_hal_bleio_service_construct(self, uuid, is_secondary, mp_obj_new_list(0, NULL));
+ if (err_code != NRF_SUCCESS) {
+ mp_raise_OSError_msg_varg(translate("Failed to create service, NRF_ERROR_%q"), MP_OBJ_QSTR_VALUE(base_error_messages[err_code - NRF_ERROR_BASE_NUM]));
+ }
+}
+
+void bleio_service_from_connection(bleio_service_obj_t *self, mp_obj_t connection) {
+ self->handle = 0xFFFF;
+ self->uuid = NULL;
+ self->characteristic_list = mp_obj_new_list(0, NULL);
+ self->is_remote = true;
+ self->is_secondary = false;
+ self->connection = connection;
}
bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self) {
@@ -60,7 +87,9 @@ bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self) {
return self->is_secondary;
}
-void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic) {
+void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self,
+ bleio_characteristic_obj_t *characteristic,
+ mp_buffer_info_t *initial_value_bufinfo) {
ble_gatts_char_md_t char_md = {
.char_props.broadcast = (characteristic->props & CHAR_PROP_BROADCAST) ? 1 : 0,
.char_props.read = (characteristic->props & CHAR_PROP_READ) ? 1 : 0,
@@ -93,14 +122,11 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, blei
bleio_attribute_gatts_set_security_mode(&char_attr_md.read_perm, characteristic->read_perm);
bleio_attribute_gatts_set_security_mode(&char_attr_md.write_perm, characteristic->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 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_len = 0,
+ .p_value = NULL,
.init_offs = 0,
.max_len = characteristic->max_length,
};
@@ -110,7 +136,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, blei
uint32_t err_code;
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);
+ mp_raise_OSError_msg_varg(translate("Failed to add characteristic, NRF_ERROR_%q"), MP_OBJ_QSTR_VALUE(base_error_messages[err_code - NRF_ERROR_BASE_NUM]));
}
characteristic->user_desc_handle = char_handles.user_desc_handle;
diff --git a/ports/nrf/common-hal/_bleio/Service.h b/ports/nrf/common-hal/_bleio/Service.h
index a4614b9f5..f101bc825 100644
--- a/ports/nrf/common-hal/_bleio/Service.h
+++ b/ports/nrf/common-hal/_bleio/Service.h
@@ -31,20 +31,22 @@
#include "py/objlist.h"
#include "common-hal/_bleio/UUID.h"
-typedef struct {
+typedef struct bleio_service_obj {
mp_obj_base_t base;
- // Handle for this service.
+ // Handle for the local 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.
- mp_obj_t device;
+ mp_obj_t connection;
mp_obj_list_t *characteristic_list;
- // Range of attribute handles of this service.
+ // Range of attribute handles of this remote service.
uint16_t start_handle;
uint16_t end_handle;
+ struct bleio_service_obj* next;
} bleio_service_obj_t;
+void bleio_service_from_connection(bleio_service_obj_t *self, mp_obj_t connection);
+
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SERVICE_H
diff --git a/ports/nrf/common-hal/_bleio/UUID.c b/ports/nrf/common-hal/_bleio/UUID.c
index 0e65b7d58..5bf35e6a5 100644
--- a/ports/nrf/common-hal/_bleio/UUID.c
+++ b/ports/nrf/common-hal/_bleio/UUID.c
@@ -30,6 +30,7 @@
#include "py/runtime.h"
#include "common-hal/_bleio/UUID.h"
+#include "shared-bindings/_bleio/__init__.h"
#include "shared-bindings/_bleio/Adapter.h"
#include "ble.h"
@@ -39,9 +40,7 @@
// If uuid128 is NULL, this is a Bluetooth SIG 16-bit UUID.
// If uuid128 is not NULL, it's a 128-bit (16-byte) UUID, with bytes 12 and 13 zero'd out, where
// the 16-bit part goes. Those 16 bits are passed in uuid16.
-void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, uint8_t uuid128[]) {
- common_hal_bleio_adapter_set_enabled(true);
-
+void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, const uint8_t uuid128[]) {
self->nrf_ble_uuid.uuid = uuid16;
if (uuid128 == NULL) {
self->nrf_ble_uuid.type = BLE_UUID_TYPE_BLE;
@@ -54,6 +53,7 @@ void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, uint32_t uuid16, ui
if (err_code != NRF_SUCCESS) {
mp_raise_OSError_msg_varg(translate("Failed to register Vendor-Specific UUID, err 0x%04x"), err_code);
}
+ vm_used_ble = true;
}
}
@@ -65,25 +65,24 @@ uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self) {
return self->nrf_ble_uuid.uuid;
}
-// True if uuid128 has been successfully filled in.
-bool common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]) {
+void common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]) {
uint8_t length;
const uint32_t err_code = sd_ble_uuid_encode(&self->nrf_ble_uuid, &length, uuid128);
if (err_code != NRF_SUCCESS) {
mp_raise_OSError_msg_varg(translate("Could not decode ble_uuid, err 0x%04x"), err_code);
}
- // If not 16 bytes, this is not a 128-bit UUID, so return.
- return length == 16;
}
-// Returns 0 if this is a 16-bit UUID, otherwise returns a non-zero index
-// into the 128-bit uuid registration table.
-uint32_t common_hal_bleio_uuid_get_uuid128_reference(bleio_uuid_obj_t *self) {
- return self->nrf_ble_uuid.type == BLE_UUID_TYPE_BLE ? 0 : self->nrf_ble_uuid.type;
+void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t* buf) {
+ if (self->nrf_ble_uuid.type == BLE_UUID_TYPE_BLE) {
+ buf[0] = self->nrf_ble_uuid.uuid & 0xff;
+ buf[1] = self->nrf_ble_uuid.uuid >> 8;
+ } else {
+ common_hal_bleio_uuid_get_uuid128(self, buf);
+ }
}
-
void bleio_uuid_construct_from_nrf_ble_uuid(bleio_uuid_obj_t *self, ble_uuid_t *nrf_ble_uuid) {
if (nrf_ble_uuid->type == BLE_UUID_TYPE_UNKNOWN) {
mp_raise_RuntimeError(translate("Unexpected nrfx uuid type"));
diff --git a/ports/nrf/common-hal/_bleio/__init__.c b/ports/nrf/common-hal/_bleio/__init__.c
index 553044190..1e07ea969 100644
--- a/ports/nrf/common-hal/_bleio/__init__.c
+++ b/ports/nrf/common-hal/_bleio/__init__.c
@@ -26,34 +26,58 @@
* THE SOFTWARE.
*/
+#include <string.h>
+
#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/Connection.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 "supervisor/shared/bluetooth.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;
+const mp_obj_t base_error_messages[20] = {
+ MP_ROM_QSTR(MP_QSTR_SUCCESS),
+ MP_ROM_QSTR(MP_QSTR_SVC_HANDLER_MISSING),
+ MP_ROM_QSTR(MP_QSTR_SOFTDEVICE_NOT_ENABLED),
+ MP_ROM_QSTR(MP_QSTR_INTERNAL),
+ MP_ROM_QSTR(MP_QSTR_NO_MEM),
+ MP_ROM_QSTR(MP_QSTR_NOT_FOUND),
+ MP_ROM_QSTR(MP_QSTR_NOT_SUPPORTED),
+ MP_ROM_QSTR(MP_QSTR_INVALID_PARAM),
+ MP_ROM_QSTR(MP_QSTR_INVALID_STATE),
+ MP_ROM_QSTR(MP_QSTR_INVALID_LENGTH),
+ MP_ROM_QSTR(MP_QSTR_INVALID_FLAGS),
+ MP_ROM_QSTR(MP_QSTR_INVALID_DATA),
+ MP_ROM_QSTR(MP_QSTR_DATA_SIZE),
+ MP_ROM_QSTR(MP_QSTR_TIMEOUT),
+ MP_ROM_QSTR(MP_QSTR_NULL),
+ MP_ROM_QSTR(MP_QSTR_FORBIDDEN),
+ MP_ROM_QSTR(MP_QSTR_INVALID_ADDR),
+ MP_ROM_QSTR(MP_QSTR_BUSY),
+ MP_ROM_QSTR(MP_QSTR_CONN_COUNT),
+ MP_ROM_QSTR(MP_QSTR_RESOURCES),
+};
// Turn off BLE on a reset or reload.
void bleio_reset() {
- if (common_hal_bleio_adapter_get_enabled()) {
- common_hal_bleio_adapter_set_enabled(false);
+ bleio_adapter_reset(&common_hal_bleio_adapter_obj);
+ if (!vm_used_ble) {
+ return;
}
+ if (common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) {
+ common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, false);
+ }
+ supervisor_start_bluetooth();
}
// The singleton _bleio.Adapter object, bound to _bleio.adapter
// It currently only has properties and no state
-const super_adapter_obj_t common_hal_bleio_adapter_obj = {
+bleio_adapter_obj_t common_hal_bleio_adapter_obj = {
.base = {
.type = &bleio_adapter_type,
},
@@ -65,410 +89,103 @@ void common_hal_bleio_check_connected(uint16_t conn_handle) {
}
}
-uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device) {
- if (MP_OBJ_IS_TYPE(device, &bleio_peripheral_type)) {
- return ((bleio_peripheral_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle;
- } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) {
- return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->conn_handle;
- } else {
- return BLE_CONN_HANDLE_INVALID;
- }
-}
-
-mp_obj_list_t *common_hal_bleio_device_get_remote_service_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_service_list;
- } else if (MP_OBJ_IS_TYPE(device, &bleio_central_type)) {
- return ((bleio_central_obj_t*) MP_OBJ_TO_PTR(device))->remote_service_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;
+// GATTS read of a Characteristic or Descriptor.
+size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_t* buf, size_t len) {
+ // 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.
- m_discovery_successful = false;
- m_discovery_in_process = true;
+ ble_gatts_value_t gatts_value = {
+ .p_value = buf,
+ .len = len,
+ };
- 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);
+ uint32_t err_code = sd_ble_gatts_value_get(conn_handle, handle, &gatts_value);
if (err_code != NRF_SUCCESS) {
- return false;
+ mp_raise_OSError_msg_varg(translate("Failed to read gatts value, err 0x%04x"), err_code);
}
- // Wait for a discovery event.
- while (m_discovery_in_process) {
- MICROPY_VM_HOOK_LOOP;
- }
- return m_discovery_successful;
+ return gatts_value.len;
}
-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;
+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.
- m_discovery_successful = false;
- m_discovery_in_process = true;
+ ble_gatts_value_t gatts_value = {
+ .p_value = bufinfo->buf,
+ .len = bufinfo->len,
+ };
- 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);
+ const uint32_t err_code = sd_ble_gatts_value_set(conn_handle, handle, &gatts_value);
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, device, NULL, false);
-
- 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_service_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, m_char_discovery_service, 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;
-
- 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, m_desc_discovery_characteristic, uuid,
- SECURITY_MODE_OPEN, SECURITY_MODE_OPEN,
- GATT_MAX_DATA_LENGTH, false, mp_const_empty_bytes);
- descriptor->handle = gattc_desc->handle;
-
- mp_obj_list_append(m_desc_discovery_characteristic->descriptor_list, MP_OBJ_FROM_PTR(descriptor));
- }
-
- if (response->count > 0) {
- m_discovery_successful = true;
+ mp_raise_OSError_msg_varg(translate("Failed to write gatts value, err 0x%04x"), err_code);
}
- m_discovery_in_process = false;
}
-STATIC void discovery_on_ble_evt(ble_evt_t *ble_evt, mp_obj_t device) {
+typedef struct {
+ uint8_t* buf;
+ size_t len;
+ size_t final_len;
+ uint16_t conn_handle;
+ volatile uint16_t status;
+ volatile bool done;
+} read_info_t;
+
+STATIC bool _on_gattc_read_rsp_evt(ble_evt_t *ble_evt, void *param) {
+ read_info_t* read = param;
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);
+ // More events may be handled later, so keep this as a switch.
+
+ case BLE_GATTC_EVT_READ_RSP: {
+ ble_gattc_evt_t* evt = &ble_evt->evt.gattc_evt;
+ ble_gattc_evt_read_rsp_t *response = &evt->params.read_rsp;
+ if (read && evt->conn_handle == read->conn_handle) {
+ read->status = evt->gatt_status;
+ size_t len = MIN(read->len, response->len);
+ memcpy(read->buf, response->data, len);
+ read->final_len = len;
+ // Indicate to busy-wait loop that we've read the attribute value.
+ read->done = true;
+ }
break;
+ }
default:
// For debugging.
- // mp_printf(&mp_plat_print, "Unhandled discovery event: 0x%04x\n", ble_evt->header.evt_id);
+ // mp_printf(&mp_plat_print, "Unhandled characteristic event: 0x%04x\n", ble_evt->header.evt_id);
+ return false;
break;
}
+ return true;
}
+size_t common_hal_bleio_gattc_read(uint16_t handle, uint16_t conn_handle, uint8_t* buf, size_t len) {
+ common_hal_bleio_check_connected(conn_handle);
-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_service_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_service_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)) {
+ read_info_t read_info;
+ read_info.buf = buf;
+ read_info.len = len;
+ read_info.final_len = 0;
+ read_info.conn_handle = conn_handle;
+ // Set to true by the event handler.
+ read_info.done = false;
+ ble_drv_add_event_handler(_on_gattc_read_rsp_evt, &read_info);
- // 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;
- }
- }
+ const uint32_t err_code = sd_ble_gattc_read(conn_handle, handle, 0);
+ if (err_code != NRF_SUCCESS) {
+ mp_raise_OSError_msg_varg(translate("Failed initiate attribute read, err 0x%04x"), err_code);
}
- // 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);
+ while (!read_info.done) {
+ RUN_BACKGROUND_TASKS;
}
-
- if (err_code != NRF_SUCCESS) {
- mp_raise_OSError_msg_varg(translate("Failed to read gatts value, err 0x%04x"), err_code);
+ if (read_info.status != BLE_GATT_STATUS_SUCCESS) {
+ mp_raise_OSError_msg_varg(translate("Failed to read attribute value, err 0x%04x"), read_info.status);
}
- 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);
- }
+ ble_drv_remove_event_handler(_on_gattc_read_rsp_evt, &read_info);
+ return read_info.final_len;
}
void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response) {
@@ -500,3 +217,7 @@ void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buff
}
}
+
+void common_hal_bleio_gc_collect(void) {
+ bleio_adapter_gc_collect(&common_hal_bleio_adapter_obj);
+}
diff --git a/ports/nrf/common-hal/_bleio/__init__.h b/ports/nrf/common-hal/_bleio/__init__.h
index cf1a06945..5fd2769f2 100644
--- a/ports/nrf/common-hal/_bleio/__init__.h
+++ b/ports/nrf/common-hal/_bleio/__init__.h
@@ -39,4 +39,9 @@ typedef struct {
// 20 bytes max (23 - 3).
#define GATT_MAX_DATA_LENGTH (BLE_GATT_ATT_MTU_DEFAULT - 3)
+const mp_obj_t base_error_messages[20];
+
+// Track if the user code modified the BLE state to know if we need to undo it on reload.
+bool vm_used_ble;
+
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_INIT_H
diff --git a/ports/stm32f4/boards/feather_stm32f405_express/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/feather_stm32f405_express/stm32f4xx_hal_conf.h
index a13e5ecfa..7a1a9428f 100644
--- a/ports/stm32f4/boards/feather_stm32f405_express/stm32f4xx_hal_conf.h
+++ b/ports/stm32f4/boards/feather_stm32f405_express/stm32f4xx_hal_conf.h
@@ -61,7 +61,7 @@
/* #define HAL_SD_MODULE_ENABLED */
/* #define HAL_MMC_MODULE_ENABLED */
#define HAL_SPI_MODULE_ENABLED
-/* #define HAL_TIM_MODULE_ENABLED */
+#define HAL_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */
diff --git a/ports/stm32f4/boards/pyboard_v11/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/pyboard_v11/stm32f4xx_hal_conf.h
index a13e5ecfa..7a1a9428f 100644
--- a/ports/stm32f4/boards/pyboard_v11/stm32f4xx_hal_conf.h
+++ b/ports/stm32f4/boards/pyboard_v11/stm32f4xx_hal_conf.h
@@ -61,7 +61,7 @@
/* #define HAL_SD_MODULE_ENABLED */
/* #define HAL_MMC_MODULE_ENABLED */
#define HAL_SPI_MODULE_ENABLED
-/* #define HAL_TIM_MODULE_ENABLED */
+#define HAL_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */
diff --git a/ports/stm32f4/boards/stm32f411ve_discovery/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/stm32f411ve_discovery/stm32f4xx_hal_conf.h
index b244a69b5..18d9d60eb 100644
--- a/ports/stm32f4/boards/stm32f411ve_discovery/stm32f4xx_hal_conf.h
+++ b/ports/stm32f4/boards/stm32f411ve_discovery/stm32f4xx_hal_conf.h
@@ -61,7 +61,7 @@
/* #define HAL_SD_MODULE_ENABLED */
/* #define HAL_MMC_MODULE_ENABLED */
#define HAL_SPI_MODULE_ENABLED
-/* #define HAL_TIM_MODULE_ENABLED */
+#define HAL_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */
diff --git a/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h b/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h
index 2ad0fee20..b89240f98 100644
--- a/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h
+++ b/ports/stm32f4/boards/stm32f412zg_discovery/stm32f4xx_hal_conf.h
@@ -61,7 +61,7 @@
#define HAL_SD_MODULE_ENABLED
/* #define HAL_MMC_MODULE_ENABLED */
#define HAL_SPI_MODULE_ENABLED
-/* #define HAL_TIM_MODULE_ENABLED */
+#define HAL_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */
diff --git a/ports/stm32f4/common-hal/pulseio/PWMOut.c b/ports/stm32f4/common-hal/pulseio/PWMOut.c
new file mode 100644
index 000000000..16b1b5b89
--- /dev/null
+++ b/ports/stm32f4/common-hal/pulseio/PWMOut.c
@@ -0,0 +1,399 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland for Adafruit Industries
+ * Uses code from Micropython, Copyright (c) 2013-2016 Damien P. George
+ *
+ * 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 <stdint.h>
+#include "py/runtime.h"
+#include "common-hal/pulseio/PWMOut.h"
+#include "shared-bindings/pulseio/PWMOut.h"
+#include "supervisor/shared/translate.h"
+
+#include "shared-bindings/microcontroller/__init__.h"
+#include "stm32f4xx_hal.h"
+#include "common-hal/microcontroller/Pin.h"
+
+#define ALL_CLOCKS 0xFFFF
+
+STATIC uint8_t reserved_tim[TIM_BANK_ARRAY_LEN];
+STATIC uint32_t tim_frequencies[TIM_BANK_ARRAY_LEN];
+STATIC bool never_reset_tim[TIM_BANK_ARRAY_LEN];
+
+STATIC void tim_clock_enable(uint16_t mask);
+STATIC void tim_clock_disable(uint16_t mask);
+
+// Get the frequency (in Hz) of the source clock for the given timer.
+// On STM32F405/407/415/417 there are 2 cases for how the clock freq is set.
+// If the APB prescaler is 1, then the timer clock is equal to its respective
+// APB clock. Otherwise (APB prescaler > 1) the timer clock is twice its
+// respective APB clock. See DM00031020 Rev 4, page 115.
+STATIC uint32_t timer_get_source_freq(uint32_t tim_id) {
+ uint32_t source, clk_div;
+ if (tim_id == 1 || (8 <= tim_id && tim_id <= 11)) {
+ // TIM{1,8,9,10,11} are on APB2
+ source = HAL_RCC_GetPCLK2Freq();
+ clk_div = RCC->CFGR & RCC_CFGR_PPRE2;
+ } else {
+ // TIM{2,3,4,5,6,7,12,13,14} are on APB1
+ source = HAL_RCC_GetPCLK1Freq();
+ clk_div = RCC->CFGR & RCC_CFGR_PPRE1;
+ }
+ if (clk_div != 0) {
+ // APB prescaler for this timer is > 1
+ source *= 2;
+ }
+ return source;
+}
+
+STATIC uint32_t timer_get_internal_duty(uint16_t duty, uint32_t period) {
+ //duty cycle is duty/0xFFFF fraction x (number of pulses per period)
+ return (duty*period)/((1<<16)-1);
+}
+
+STATIC void timer_get_optimal_divisors(uint32_t*period, uint32_t*prescaler,
+ uint32_t frequency, uint32_t source_freq) {
+ //Find the largest possible period supported by this frequency
+ for (int i=0; i<(1 << 16);i++) {
+ *period = source_freq/(i*frequency);
+ if (*period < (1 << 16) && *period>=2) {
+ *prescaler = i;
+ break;
+ }
+ }
+ if (*prescaler == 0) {
+ mp_raise_ValueError(translate("Invalid frequency supplied"));
+ }
+}
+
+void pwmout_reset(void) {
+ uint16_t never_reset_mask = 0x00;
+ for(int i=0;i<TIM_BANK_ARRAY_LEN;i++) {
+ if (!never_reset_tim[i]) {
+ reserved_tim[i] = 0x00;
+ tim_frequencies[i] = 0x00;
+ } else {
+ never_reset_mask |= 1<<i;
+ }
+ }
+ tim_clock_disable(ALL_CLOCKS & ~(never_reset_mask));
+}
+
+void common_hal_pulseio_pwmout_never_reset(pulseio_pwmout_obj_t *self) {
+ for(size_t i = 0 ; i < TIM_BANK_ARRAY_LEN; i++) {
+ if (mcu_tim_banks[i] == self->handle.Instance) {
+ never_reset_tim[i] = true;
+ never_reset_pin_number(self->tim->pin->port, self->tim->pin->number);
+ break;
+ }
+ }
+}
+
+void common_hal_pulseio_pwmout_reset_ok(pulseio_pwmout_obj_t *self) {
+ for(size_t i = 0 ; i < TIM_BANK_ARRAY_LEN; i++) {
+ if (mcu_tim_banks[i] == self->handle.Instance) {
+ never_reset_tim[i] = false;
+ break;
+ }
+ }
+}
+
+pwmout_result_t common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self,
+ const mcu_pin_obj_t* pin,
+ uint16_t duty,
+ uint32_t frequency,
+ bool variable_frequency) {
+ TIM_TypeDef * TIMx;
+ uint8_t tim_num = sizeof(mcu_tim_pin_list)/sizeof(*mcu_tim_pin_list);
+ bool tim_chan_taken = false;
+ bool tim_taken_f_mismatch = false;
+ bool var_freq_mismatch = false;
+ bool first_time_setup = true;
+
+ for(uint i = 0; i < tim_num; i++) {
+ mcu_tim_pin_obj_t l_tim = mcu_tim_pin_list[i];
+ uint8_t l_tim_index = l_tim.tim_index-1;
+ uint8_t l_tim_channel = l_tim.channel_index-1;
+
+ //if pin is same
+ if (l_tim.pin == pin) {
+ //check if the timer has a channel active
+ if (reserved_tim[l_tim_index] != 0) {
+ //is it the same channel? (or all channels reserved by a var-freq)
+ if (reserved_tim[l_tim_index] & 1<<(l_tim_channel)) {
+ tim_chan_taken = true;
+ continue; //keep looking, might be another viable option
+ }
+ //If the frequencies are the same it's ok
+ if (tim_frequencies[l_tim_index] != frequency) {
+ tim_taken_f_mismatch = true;
+ continue; //keep looking
+ }
+ //you can't put a variable frequency on a partially reserved timer
+ if (variable_frequency) {
+ var_freq_mismatch = true;
+ continue; //keep looking
+ }
+ first_time_setup = false; //skip setting up the timer
+ }
+ //No problems taken, so set it up
+ self->tim = &l_tim;
+ break;
+ }
+ }
+
+ //handle valid/invalid timer instance
+ if (self->tim!=NULL) {
+ //create instance
+ TIMx = mcu_tim_banks[self->tim->tim_index-1];
+ //reserve timer/channel
+ if (variable_frequency) {
+ reserved_tim[self->tim->tim_index-1] = 0x0F;
+ } else {
+ reserved_tim[self->tim->tim_index-1] |= 1<<(self->tim->channel_index-1);
+ }
+ tim_frequencies[self->tim->tim_index-1] = frequency;
+ } else { //no match found
+ if (tim_chan_taken) {
+ mp_raise_ValueError(translate("No more timers available on this pin."));
+ } else if (tim_taken_f_mismatch) {
+ mp_raise_ValueError(translate("Frequency must be the same as as the existing PWMOut using this timer"));
+ } else if (var_freq_mismatch) {
+ mp_raise_ValueError(translate("Cannot vary frequency on a timer that is already in use"));
+ } else {
+ mp_raise_ValueError(translate("Invalid pins"));
+ }
+ }
+
+ GPIO_InitTypeDef GPIO_InitStruct = {0};
+ GPIO_InitStruct.Pin = pin_mask(pin->number);
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.Alternate = self->tim->altfn_index;
+ HAL_GPIO_Init(pin_port(pin->port), &GPIO_InitStruct);
+
+ tim_clock_enable(1<<(self->tim->tim_index - 1));
+
+ //translate channel into handle value
+ self->channel = 4 * (self->tim->channel_index - 1);
+
+ uint32_t prescaler = 0; //prescaler is 15 bit
+ uint32_t period = 0; //period is 16 bit
+ timer_get_optimal_divisors(&period, &prescaler,frequency,timer_get_source_freq(self->tim->tim_index));
+
+ //Timer init
+ self->handle.Instance = TIMx;
+ self->handle.Init.Period = period - 1;
+ self->handle.Init.Prescaler = prescaler - 1;
+ self->handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+ self->handle.Init.CounterMode = TIM_COUNTERMODE_UP;
+ self->handle.Init.RepetitionCounter = 0;
+
+ //only run init if this is the first instance of this timer
+ if (first_time_setup) {
+ if (HAL_TIM_PWM_Init(&self->handle) != HAL_OK) {
+ mp_raise_ValueError(translate("Could not initialize timer"));
+ }
+ }
+
+ //Channel/PWM init
+ self->chan_handle.OCMode = TIM_OCMODE_PWM1;
+ self->chan_handle.Pulse = timer_get_internal_duty(duty, period);
+ self->chan_handle.OCPolarity = TIM_OCPOLARITY_LOW;
+ self->chan_handle.OCFastMode = TIM_OCFAST_DISABLE;
+ self->chan_handle.OCNPolarity = TIM_OCNPOLARITY_LOW; // needed for TIM1 and TIM8
+ self->chan_handle.OCIdleState = TIM_OCIDLESTATE_SET; // needed for TIM1 and TIM8
+ self->chan_handle.OCNIdleState = TIM_OCNIDLESTATE_SET; // needed for TIM1 and TIM8
+ if (HAL_TIM_PWM_ConfigChannel(&self->handle, &self->chan_handle, self->channel) != HAL_OK) {
+ mp_raise_ValueError(translate("Could not initialize channel"));
+ }
+ if (HAL_TIM_PWM_Start(&self->handle, self->channel) != HAL_OK) {
+ mp_raise_ValueError(translate("Could not start PWM"));
+ }
+
+ self->variable_frequency = variable_frequency;
+ self->frequency = frequency;
+ self->duty_cycle = duty;
+ self->period = period;
+
+ return PWMOUT_OK;
+}
+
+bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) {
+ return self->tim == mp_const_none;
+}
+
+void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
+ if (common_hal_pulseio_pwmout_deinited(self)) {
+ return;
+ }
+ //var freq shuts down entire timer, others just their channel
+ if (self->variable_frequency) {
+ reserved_tim[self->tim->tim_index-1] = 0x00;
+ } else {
+ reserved_tim[self->tim->tim_index-1] &= ~(1<<self->tim->channel_index);
+ HAL_TIM_PWM_Stop(&self->handle, self->channel);
+ }
+ reset_pin_number(self->tim->pin->port,self->tim->pin->number);
+ self->tim = mp_const_none;
+
+ //if reserved timer has no active channels, we can disable it
+ if (!reserved_tim[self->tim->tim_index-1]) {
+ tim_frequencies[self->tim->tim_index-1] = 0x00;
+ tim_clock_disable(1<<(self->tim->tim_index-1));
+ }
+}
+
+void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty) {
+ uint32_t internal_duty_cycle = timer_get_internal_duty(duty, self->period);
+ __HAL_TIM_SET_COMPARE(&self->handle, self->channel, internal_duty_cycle);
+ self->duty_cycle = duty;
+}
+
+uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) {
+ return self->duty_cycle;
+}
+
+void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency) {
+ //don't halt setup for the same frequency
+ if (frequency == self->frequency) return;
+
+ uint32_t prescaler = 0;
+ uint32_t period = 0;
+ timer_get_optimal_divisors(&period, &prescaler,frequency,timer_get_source_freq(self->tim->tim_index));
+
+ //shut down
+ HAL_TIM_PWM_Stop(&self->handle, self->channel);
+
+ //Only change altered values
+ self->handle.Init.Period = period - 1;
+ self->handle.Init.Prescaler = prescaler - 1;
+
+ //restart everything, adjusting for new speed
+ if (HAL_TIM_PWM_Init(&self->handle) != HAL_OK) {
+ mp_raise_ValueError(translate("Could not re-init timer"));
+ }
+
+ self->chan_handle.Pulse = timer_get_internal_duty(self->duty_cycle, period);
+
+ if (HAL_TIM_PWM_ConfigChannel(&self->handle, &self->chan_handle, self->channel) != HAL_OK) {
+ mp_raise_ValueError(translate("Could not re-init channel"));
+ }
+ if (HAL_TIM_PWM_Start(&self->handle, self->channel) != HAL_OK) {
+ mp_raise_ValueError(translate("Could not restart PWM"));
+ }
+
+ tim_frequencies[self->tim->tim_index-1] = frequency;
+ self->frequency = frequency;
+ self->period = period;
+}
+
+uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self) {
+ return self->frequency;
+}
+
+bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self) {
+ return self->variable_frequency;
+}
+
+STATIC void tim_clock_enable(uint16_t mask) {
+ #ifdef TIM1
+ if (mask & 1<<0) __HAL_RCC_TIM1_CLK_ENABLE();
+ #endif
+ #ifdef TIM2
+ if (mask & 1<<1) __HAL_RCC_TIM2_CLK_ENABLE();
+ #endif
+ #ifdef TIM3
+ if (mask & 1<<2) __HAL_RCC_TIM3_CLK_ENABLE();
+ #endif
+ #ifdef TIM4
+ if (mask & 1<<3) __HAL_RCC_TIM4_CLK_ENABLE();
+ #endif
+ #ifdef TIM5
+ if (mask & 1<<4) __HAL_RCC_TIM5_CLK_ENABLE();
+ #endif
+ //6 and 7 are reserved ADC timers
+ #ifdef TIM8
+ if (mask & 1<<7) __HAL_RCC_TIM8_CLK_ENABLE();
+ #endif
+ #ifdef TIM9
+ if (mask & 1<<8) __HAL_RCC_TIM9_CLK_ENABLE();
+ #endif
+ #ifdef TIM10
+ if (mask & 1<<9) __HAL_RCC_TIM10_CLK_ENABLE();
+ #endif
+ #ifdef TIM11
+ if (mask & 1<<10) __HAL_RCC_TIM11_CLK_ENABLE();
+ #endif
+ #ifdef TIM12
+ if (mask & 1<<11) __HAL_RCC_TIM12_CLK_ENABLE();
+ #endif
+ #ifdef TIM13
+ if (mask & 1<<12) __HAL_RCC_TIM13_CLK_ENABLE();
+ #endif
+ #ifdef TIM14
+ if (mask & 1<<13) __HAL_RCC_TIM14_CLK_ENABLE();
+ #endif
+}
+
+STATIC void tim_clock_disable(uint16_t mask) {
+ #ifdef TIM1
+ if (mask & 1<<0) __HAL_RCC_TIM1_CLK_DISABLE();
+ #endif
+ #ifdef TIM2
+ if (mask & 1<<1) __HAL_RCC_TIM2_CLK_DISABLE();
+ #endif
+ #ifdef TIM3
+ if (mask & 1<<2) __HAL_RCC_TIM3_CLK_DISABLE();
+ #endif
+ #ifdef TIM4
+ if (mask & 1<<3) __HAL_RCC_TIM4_CLK_DISABLE();
+ #endif
+ #ifdef TIM5
+ if (mask & 1<<4) __HAL_RCC_TIM5_CLK_DISABLE();
+ #endif
+ //6 and 7 are reserved ADC timers
+ #ifdef TIM8
+ if (mask & 1<<7) __HAL_RCC_TIM8_CLK_DISABLE();
+ #endif
+ #ifdef TIM9
+ if (mask & 1<<8) __HAL_RCC_TIM9_CLK_DISABLE();
+ #endif
+ #ifdef TIM10
+ if (mask & 1<<9) __HAL_RCC_TIM10_CLK_DISABLE();
+ #endif
+ #ifdef TIM11
+ if (mask & 1<<10) __HAL_RCC_TIM11_CLK_DISABLE();
+ #endif
+ #ifdef TIM12
+ if (mask & 1<<11) __HAL_RCC_TIM12_CLK_DISABLE();
+ #endif
+ #ifdef TIM13
+ if (mask & 1<<12) __HAL_RCC_TIM13_CLK_DISABLE();
+ #endif
+ #ifdef TIM14
+ if (mask & 1<<13) __HAL_RCC_TIM14_CLK_DISABLE();
+ #endif
+}
diff --git a/shared-bindings/_bleio/Central.h b/ports/stm32f4/common-hal/pulseio/PWMOut.h
index 85d788654..59fc04e5f 100644
--- a/shared-bindings/_bleio/Central.h
+++ b/ports/stm32f4/common-hal/pulseio/PWMOut.h
@@ -3,8 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2019 Lucian Copeland 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
@@ -25,19 +24,28 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
+#ifndef MICROPY_INCLUDED_STM32F4_COMMON_HAL_PULSEIO_PWMOUT_H
+#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_PULSEIO_PWMOUT_H
-#include "py/objtuple.h"
-#include "common-hal/_bleio/Central.h"
-#include "common-hal/_bleio/Service.h"
+#include "common-hal/microcontroller/Pin.h"
-extern const mp_obj_type_t bleio_central_type;
+#include "stm32f4xx_hal.h"
+#include "stm32f4/periph.h"
-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);
-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_tuple_t *common_hal_bleio_central_discover_remote_services(bleio_central_obj_t *self, mp_obj_t service_uuids_whitelist);
+#include "py/obj.h"
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CENTRAL_H
+typedef struct {
+ mp_obj_base_t base;
+ TIM_HandleTypeDef handle;
+ TIM_OC_InitTypeDef chan_handle;
+ const mcu_tim_pin_obj_t *tim;
+ uint8_t channel: 7;
+ bool variable_frequency: 1;
+ uint16_t duty_cycle;
+ uint32_t frequency;
+ uint32_t period;
+} pulseio_pwmout_obj_t;
+
+void pwmout_reset(void);
+
+#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_PULSEIO_PWMOUT_H
diff --git a/ports/stm32f4/common-hal/pulseio/PulseIn.c b/ports/stm32f4/common-hal/pulseio/PulseIn.c
new file mode 100644
index 000000000..068936bdd
--- /dev/null
+++ b/ports/stm32f4/common-hal/pulseio/PulseIn.c
@@ -0,0 +1,79 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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 "common-hal/pulseio/PulseIn.h"
+#include <stdint.h>
+#include <string.h>
+#include "py/mpconfig.h"
+#include "py/gc.h"
+#include "py/runtime.h"
+#include "shared-bindings/microcontroller/__init__.h"
+#include "shared-bindings/pulseio/PulseIn.h"
+#include "tick.h"
+
+void pulsein_reset(void) {
+}
+
+void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, const mcu_pin_obj_t* pin,
+ uint16_t maxlen, bool idle_state) {
+ mp_raise_NotImplementedError(translate("PulseIn not yet supported"));
+}
+
+bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) {
+ return true;
+}
+
+void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) {
+}
+
+void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) {
+}
+
+void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint16_t trigger_duration) {
+}
+
+void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) {
+}
+
+uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index) {
+ return 0;
+}
+
+uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) {
+ return 0;
+}
+
+uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) {
+ return 0;
+}
+
+bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self) {
+ return 0;
+}
+
+uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) {
+ return 0;
+}
diff --git a/ports/stm32f4/common-hal/pulseio/PulseIn.h b/ports/stm32f4/common-hal/pulseio/PulseIn.h
new file mode 100644
index 000000000..2538b07ab
--- /dev/null
+++ b/ports/stm32f4/common-hal/pulseio/PulseIn.h
@@ -0,0 +1,53 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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_STM32F4_COMMON_HAL_PULSEIO_PULSEIN_H
+#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_PULSEIO_PULSEIN_H
+
+#include "common-hal/microcontroller/Pin.h"
+
+#include "py/obj.h"
+
+typedef struct {
+ mp_obj_base_t base;
+
+ uint8_t pin;
+ bool idle_state;
+ bool paused;
+ volatile bool first_edge;
+
+ uint16_t* buffer;
+ uint16_t maxlen;
+
+ volatile uint16_t start;
+ volatile uint16_t len;
+ volatile uint16_t last_us;
+ volatile uint64_t last_ms;
+} pulseio_pulsein_obj_t;
+
+void pulsein_reset(void);
+
+#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_PULSEIO_PULSEIN_H
diff --git a/ports/stm32f4/common-hal/pulseio/PulseOut.c b/ports/stm32f4/common-hal/pulseio/PulseOut.c
new file mode 100644
index 000000000..d393afc5c
--- /dev/null
+++ b/ports/stm32f4/common-hal/pulseio/PulseOut.c
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Lucian Copeland 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 "common-hal/pulseio/PulseOut.h"
+
+#include <stdint.h>
+
+#include "py/mpconfig.h"
+#include "py/gc.h"
+#include "py/runtime.h"
+#include "shared-bindings/pulseio/PulseOut.h"
+#include "shared-bindings/pulseio/PWMOut.h"
+#include "supervisor/shared/translate.h"
+
+
+void pulseout_reset() {
+}
+
+void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
+ const pulseio_pwmout_obj_t* carrier) {
+ mp_raise_NotImplementedError(translate("PulseOut not yet supported"));
+}
+
+bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) {
+ return true;
+}
+
+void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) {
+}
+
+void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) {
+}
diff --git a/ports/nrf/common-hal/_bleio/Central.h b/ports/stm32f4/common-hal/pulseio/PulseOut.h
index 01f7faca7..45823d28a 100644
--- a/ports/nrf/common-hal/_bleio/Central.h
+++ b/ports/stm32f4/common-hal/pulseio/PulseOut.h
@@ -3,8 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2019 Lucian Copeland 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
@@ -25,20 +24,19 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CENTRAL_H
-#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CENTRAL_H
+#ifndef MICROPY_INCLUDED_STM32F4_COMMON_HAL_PULSEIO_PULSEOUT_H
+#define MICROPY_INCLUDED_STM32F4_COMMON_HAL_PULSEIO_PULSEOUT_H
-#include <stdbool.h>
+#include "common-hal/microcontroller/Pin.h"
+#include "common-hal/pulseio/PWMOut.h"
-#include "py/objlist.h"
-#include "shared-module/_bleio/Address.h"
+#include "py/obj.h"
typedef struct {
mp_obj_base_t base;
- volatile bool waiting_to_connect;
- volatile uint16_t conn_handle;
- // Services discovered after connecting to a remote peripheral.
- mp_obj_list_t *remote_service_list;
-} bleio_central_obj_t;
+ const pulseio_pwmout_obj_t *pwmout;
+} pulseio_pulseout_obj_t;
-#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CENTRAL_H
+void pulseout_reset(void);
+
+#endif // MICROPY_INCLUDED_STM32F4_COMMON_HAL_PULSEIO_PULSEOUT_H
diff --git a/ports/stm32f4/common-hal/pulseio/__init__.c b/ports/stm32f4/common-hal/pulseio/__init__.c
new file mode 100644
index 000000000..2bee925bc
--- /dev/null
+++ b/ports/stm32f4/common-hal/pulseio/__init__.c
@@ -0,0 +1 @@
+// No pulseio module functions.
diff --git a/ports/stm32f4/mpconfigport.mk b/ports/stm32f4/mpconfigport.mk
index ffe586898..bce68f99f 100644
--- a/ports/stm32f4/mpconfigport.mk
+++ b/ports/stm32f4/mpconfigport.mk
@@ -20,6 +20,7 @@ CIRCUITPY_DIGITALIO = 1
CIRCUITPY_ANALOGIO = 1
CIRCUITPY_MICROCONTROLLER = 1
CIRCUITPY_BUSIO = 1
+CIRCUITPY_PULSEIO = 1
CIRCUITPY_OS = 1
CIRCUITPY_STORAGE = 1
CIRCUITPY_RANDOM = 1
diff --git a/ports/stm32f4/peripherals/stm32f4/periph.h b/ports/stm32f4/peripherals/stm32f4/periph.h
index 82f179147..d066b2be7 100644
--- a/ports/stm32f4/peripherals/stm32f4/periph.h
+++ b/ports/stm32f4/peripherals/stm32f4/periph.h
@@ -99,6 +99,22 @@ typedef struct {
.pin = spi_pin, \
}
+//Timers
+typedef struct {
+ uint8_t tim_index:4;
+ uint8_t altfn_index:4;
+ uint8_t channel_index:4;
+ const mcu_pin_obj_t * pin;
+} mcu_tim_pin_obj_t;
+
+#define TIM(index, alt, channel, tim_pin) \
+{ \
+ .tim_index = index, \
+ .altfn_index = alt, \
+ .channel_index = channel, \
+ .pin = tim_pin, \
+}
+
//Starter Lines
#ifdef STM32F411xE
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.c b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.c
index 7b0a54e55..67faacdf6 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.c
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.c
@@ -85,4 +85,78 @@ const mcu_spi_nss_obj_t mcu_spi_nss_list[6] = {
SPI(3, 6, &pin_PA04),
SPI(3, 6, &pin_PA15),
};
-//UART, Etc
+
+//Timers
+//TIM6 and TIM7 are basic timers that are only used by DAC, and don't have pins
+TIM_TypeDef * mcu_tim_banks[14] = {TIM1, TIM2, TIM3, TIM4, TIM5, NULL, NULL, TIM8, TIM9, TIM10,
+ TIM11, TIM12, TIM13, TIM14};
+
+const mcu_tim_pin_obj_t mcu_tim_pin_list[56] = {
+ TIM(2,1,1,&pin_PA00),
+ TIM(5,2,1,&pin_PA00),
+ TIM(2,1,2,&pin_PA01),
+ TIM(5,2,2,&pin_PA01),
+ TIM(2,1,3,&pin_PA02),
+ TIM(5,2,3,&pin_PA02),
+ TIM(2,1,4,&pin_PA03),
+ TIM(5,2,4,&pin_PA03),
+ TIM(9,3,1,&pin_PA02),
+ TIM(9,3,2,&pin_PA03),
+ TIM(3,2,1,&pin_PA06),
+ TIM(13,9,1,&pin_PA06),
+ TIM(3,2,2,&pin_PA07),
+ TIM(14,9,1,&pin_PA07),
+ TIM(1,1,1,&pin_PA08),
+ TIM(1,1,2,&pin_PA09),
+ TIM(1,1,3,&pin_PA10),
+ TIM(1,1,4,&pin_PA11),
+ TIM(2,1,1,&pin_PA15),
+ TIM(3,2,3,&pin_PB00),
+ TIM(3,2,4,&pin_PB01),
+ TIM(2,1,2,&pin_PB03),
+ TIM(3,2,1,&pin_PB04),
+ TIM(3,2,2,&pin_PB05),
+ TIM(4,2,1,&pin_PB06),
+ TIM(4,2,2,&pin_PB07),
+ TIM(4,2,3,&pin_PB08),
+ TIM(10,2,1,&pin_PB08),
+ TIM(4,2,4,&pin_PB09),
+ TIM(11,2,1,&pin_PB09),
+ TIM(2,1,3,&pin_PB10),
+ TIM(2,1,4,&pin_PB11),
+ TIM(12,9,1,&pin_PB14),
+ TIM(12,9,2,&pin_PB15),
+ TIM(3,2,1,&pin_PC06),
+ TIM(3,2,2,&pin_PC07),
+ TIM(3,2,3,&pin_PC08),
+ TIM(3,2,4,&pin_PC09),
+ TIM(8,3,1,&pin_PC06),
+ TIM(8,3,2,&pin_PC07),
+ TIM(8,3,3,&pin_PC08),
+ TIM(8,3,4,&pin_PC09),
+ TIM(4,2,1,&pin_PD12),
+ TIM(4,2,2,&pin_PD13),
+ TIM(4,2,3,&pin_PD14),
+ TIM(4,2,4,&pin_PD15),
+ TIM(9,3,1,&pin_PE05),
+ TIM(9,3,2,&pin_PE06),
+ TIM(1,1,1,&pin_PE09),
+ TIM(1,1,2,&pin_PE11),
+ TIM(1,1,3,&pin_PE13),
+ TIM(1,1,4,&pin_PE14),
+ TIM(10,3,1,&pin_PF06),
+ TIM(11,3,1,&pin_PF07),
+ TIM(13,9,1,&pin_PF08),
+ TIM(14,9,1,&pin_PF09),
+ // TIM(12,9,1,&pin_PH06), //TODO: include these when pin map is expanded
+ // TIM(12,9,2,&pin_PH09),
+ // TIM(5,2,1,&pin_PH10),
+ // TIM(5,2,2,&pin_PH11),
+ // TIM(5,2,3,&pin_PH12),
+ // TIM(5,2,4,&pin_PI00),
+ // TIM(8,3,4,&pin_PI02),
+ // TIM(8,3,1,&pin_PI05),
+ // TIM(8,3,2,&pin_PI06),
+ // TIM(8,3,3,&pin_PI07),
+};
+
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.h b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.h
index cb9b33f6e..89298cdab 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.h
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f405xx/periph.h
@@ -41,5 +41,10 @@ extern const mcu_spi_mosi_obj_t mcu_spi_mosi_list[6];
extern const mcu_spi_miso_obj_t mcu_spi_miso_list[6];
extern const mcu_spi_nss_obj_t mcu_spi_nss_list[6];
+#define TIM_BANK_ARRAY_LEN 14
+#define TIM_PIN_ARRAY_LEN 56
+TIM_TypeDef * mcu_tim_banks[TIM_BANK_ARRAY_LEN];
+const mcu_tim_pin_obj_t mcu_tim_pin_list[TIM_PIN_ARRAY_LEN];
+
#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F405XX_PERIPH_H \ No newline at end of file
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.c b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.c
index f0966f785..1d4034bbf 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.c
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.c
@@ -120,3 +120,55 @@ const mcu_spi_nss_obj_t mcu_spi_nss_list[12] = {
};
//UART, Etc
+
+//Timers
+//TIM6 and TIM7 are basic timers that are only used by DAC, and don't have pins
+TIM_TypeDef * mcu_tim_banks[14] = {TIM1, TIM2, TIM3, TIM4, TIM5, NULL, NULL, NULL, TIM9, TIM10,
+ TIM11, NULL, NULL, NULL};
+
+const mcu_tim_pin_obj_t mcu_tim_pin_list[44] = {
+ TIM(2,1,1,&pin_PA00),
+ TIM(5,2,1,&pin_PA00),
+ TIM(2,1,2,&pin_PA01),
+ TIM(5,2,2,&pin_PA01),
+ TIM(2,1,3,&pin_PA02),
+ TIM(5,2,3,&pin_PA02),
+ TIM(2,1,4,&pin_PA03),
+ TIM(5,2,4,&pin_PA03),
+ TIM(9,3,1,&pin_PA02),
+ TIM(9,3,2,&pin_PA03),
+ TIM(3,2,1,&pin_PA06),
+ TIM(3,2,2,&pin_PA07),
+ TIM(1,1,1,&pin_PA08),
+ TIM(1,1,2,&pin_PA09),
+ TIM(1,1,3,&pin_PA10),
+ TIM(1,1,4,&pin_PA11),
+ TIM(2,1,1,&pin_PA15),
+ TIM(3,2,3,&pin_PB00),
+ TIM(3,2,4,&pin_PB01),
+ TIM(2,1,2,&pin_PB03),
+ TIM(3,2,1,&pin_PB04),
+ TIM(3,2,2,&pin_PB05),
+ TIM(4,2,1,&pin_PB06),
+ TIM(4,2,2,&pin_PB07),
+ TIM(4,2,3,&pin_PB08),
+ TIM(10,2,1,&pin_PB08),
+ TIM(4,2,4,&pin_PB09),
+ TIM(11,2,1,&pin_PB09),
+ TIM(2,1,3,&pin_PB10),
+ TIM(3,2,1,&pin_PC06),
+ TIM(3,2,2,&pin_PC07),
+ TIM(3,2,3,&pin_PC08),
+ TIM(3,2,4,&pin_PC09),
+ TIM(4,2,1,&pin_PD12),
+ TIM(4,2,2,&pin_PD13),
+ TIM(4,2,3,&pin_PD14),
+ TIM(4,2,4,&pin_PD15),
+ TIM(9,3,1,&pin_PE05),
+ TIM(9,3,2,&pin_PE06),
+ TIM(1,1,1,&pin_PE09),
+ TIM(1,1,2,&pin_PE11),
+ TIM(1,1,3,&pin_PE13),
+ TIM(1,1,4,&pin_PE14),
+};
+
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.h b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.h
index 08efa14ca..3045397a3 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.h
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f411xe/periph.h
@@ -41,4 +41,9 @@ extern const mcu_spi_mosi_obj_t mcu_spi_mosi_list[14];
extern const mcu_spi_miso_obj_t mcu_spi_miso_list[12];
extern const mcu_spi_nss_obj_t mcu_spi_nss_list[12];
+#define TIM_BANK_ARRAY_LEN 14
+TIM_TypeDef * mcu_tim_banks[14];
+#define TIM_PIN_ARRAY_LEN 44
+const mcu_tim_pin_obj_t mcu_tim_pin_list[44];
+
#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411VE_PERIPH_H \ No newline at end of file
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.c b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.c
index ea94719ec..edce2845b 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.c
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.c
@@ -121,3 +121,71 @@ const mcu_spi_nss_obj_t mcu_spi_nss_list[12] = {
};
//UART, Etc
+
+//Timers
+//TIM6 and TIM7 are basic timers that are only used by DAC, and don't have pins
+TIM_TypeDef * mcu_tim_banks[14] = {TIM1, TIM2, TIM3, TIM4, TIM5, NULL, NULL, TIM8, TIM9, TIM10,
+ TIM11, TIM12, TIM13, TIM14};
+
+const mcu_tim_pin_obj_t mcu_tim_pin_list[60] = {
+ TIM(2,1,1,&pin_PA00),
+ TIM(5,2,1,&pin_PA00),
+ TIM(2,1,2,&pin_PA01),
+ TIM(5,2,2,&pin_PA01),
+ TIM(2,1,3,&pin_PA02),
+ TIM(5,2,3,&pin_PA02),
+ TIM(2,1,4,&pin_PA03),
+ TIM(5,2,4,&pin_PA03),
+ TIM(9,3,1,&pin_PA02),
+ TIM(9,3,2,&pin_PA03),
+ TIM(3,2,1,&pin_PA06),
+ TIM(13,9,1,&pin_PA06),
+ TIM(3,2,2,&pin_PA07),
+ TIM(14,9,1,&pin_PA07),
+ TIM(1,1,1,&pin_PA08),
+ TIM(1,1,2,&pin_PA09),
+ TIM(1,1,3,&pin_PA10),
+ TIM(1,1,4,&pin_PA11),
+ TIM(2,1,1,&pin_PA15),
+ TIM(3,2,3,&pin_PB00),
+ TIM(3,2,4,&pin_PB01),
+ TIM(2,1,2,&pin_PB03),
+ TIM(3,2,1,&pin_PB04),
+ TIM(3,2,2,&pin_PB05),
+ TIM(4,2,1,&pin_PB06),
+ TIM(4,2,2,&pin_PB07),
+ TIM(4,2,3,&pin_PB08),
+ TIM(10,2,1,&pin_PB08),
+ TIM(4,2,4,&pin_PB09),
+ TIM(11,2,1,&pin_PB09),
+ TIM(2,1,3,&pin_PB10),
+ TIM(2,1,4,&pin_PB11),
+ TIM(12,9,1,&pin_PB14),
+ TIM(12,9,2,&pin_PB15),
+ TIM(3,2,1,&pin_PC06),
+ TIM(3,2,2,&pin_PC07),
+ TIM(3,2,3,&pin_PC08),
+ TIM(3,2,4,&pin_PC09),
+ TIM(8,3,1,&pin_PC06),
+ TIM(8,3,2,&pin_PC07),
+ TIM(8,3,3,&pin_PC08),
+ TIM(8,3,4,&pin_PC09),
+ TIM(4,2,1,&pin_PD12),
+ TIM(4,2,2,&pin_PD13),
+ TIM(4,2,3,&pin_PD14),
+ TIM(4,2,4,&pin_PD15),
+ TIM(9,3,1,&pin_PE05),
+ TIM(9,3,2,&pin_PE06),
+ TIM(1,1,1,&pin_PE09),
+ TIM(1,1,2,&pin_PE11),
+ TIM(1,1,3,&pin_PE13),
+ TIM(1,1,4,&pin_PE14),
+ TIM(10,3,1,&pin_PF06),
+ TIM(11,3,1,&pin_PF07),
+ TIM(13,9,1,&pin_PF08),
+ TIM(14,9,1,&pin_PF09),
+ TIM(5,2,1,&pin_PF03),
+ TIM(5,2,2,&pin_PF04),
+ TIM(5,2,3,&pin_PF05),
+ TIM(5,2,4,&pin_PF10),
+};
diff --git a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.h b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.h
index d12bbba93..49ba10827 100644
--- a/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.h
+++ b/ports/stm32f4/peripherals/stm32f4/stm32f412zx/periph.h
@@ -42,4 +42,9 @@ extern const mcu_spi_mosi_obj_t mcu_spi_mosi_list[14];
extern const mcu_spi_miso_obj_t mcu_spi_miso_list[12];
extern const mcu_spi_nss_obj_t mcu_spi_nss_list[12];
+#define TIM_BANK_ARRAY_LEN 14
+TIM_TypeDef * mcu_tim_banks[14];
+#define TIM_PIN_ARRAY_LEN 60
+const mcu_tim_pin_obj_t mcu_tim_pin_list[60];
+
#endif // MICROPY_INCLUDED_STM32F4_PERIPHERALS_STM32F411VE_PERIPH_H \ No newline at end of file
diff --git a/ports/stm32f4/supervisor/port.c b/ports/stm32f4/supervisor/port.c
index 502202f52..602bec4be 100644
--- a/ports/stm32f4/supervisor/port.c
+++ b/ports/stm32f4/supervisor/port.c
@@ -33,6 +33,7 @@
#include "common-hal/microcontroller/Pin.h"
#include "common-hal/busio/I2C.h"
#include "common-hal/busio/SPI.h"
+#include "common-hal/pulseio/PWMOut.h"
#include "stm32f4/clocks.h"
#include "stm32f4/gpio.h"
@@ -57,6 +58,7 @@ void reset_port(void) {
reset_all_pins();
i2c_reset();
spi_reset();
+ pwmout_reset();
}
void reset_to_bootloader(void) {
diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk
index b72d75390..211e85368 100644
--- a/py/circuitpy_defns.mk
+++ b/py/circuitpy_defns.mk
@@ -229,12 +229,10 @@ SRC_COMMON_HAL_ALL = \
_bleio/__init__.c \
_bleio/Adapter.c \
_bleio/Attribute.c \
- _bleio/Central.c \
_bleio/Characteristic.c \
_bleio/CharacteristicBuffer.c \
+ _bleio/Connection.c \
_bleio/Descriptor.c \
- _bleio/Peripheral.c \
- _bleio/Scanner.c \
_bleio/Service.c \
_bleio/UUID.c \
analogio/AnalogIn.c \
@@ -307,6 +305,7 @@ SRC_SHARED_MODULE_ALL = \
_bleio/Address.c \
_bleio/Attribute.c \
_bleio/ScanEntry.c \
+ _bleio/ScanResults.c \
_pixelbuf/PixelBuf.c \
_pixelbuf/__init__.c \
_stage/Layer.c \
diff --git a/py/ringbuf.h b/py/ringbuf.h
index 5f82cc096..7fc35d266 100644
--- a/py/ringbuf.h
+++ b/py/ringbuf.h
@@ -99,4 +99,11 @@ static inline void ringbuf_put_n(ringbuf_t* r, uint8_t* buf, uint8_t bufsize)
}
}
}
+
+static inline void ringbuf_get_n(ringbuf_t* r, uint8_t* buf, uint8_t bufsize)
+{
+ for(uint8_t i=0; i < bufsize; i++) {
+ buf[i] = ringbuf_get(r);
+ }
+}
#endif // MICROPY_INCLUDED_PY_RINGBUF_H
diff --git a/py/vm.c b/py/vm.c
index b5f53ee9a..353fc8810 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -758,7 +758,7 @@ unwind_jump:;
} else {
PUSH(value); // push the next iteration value
}
- DISPATCH();
+ DISPATCH_WITH_PEND_EXC_CHECK();
}
// matched against: SETUP_EXCEPT, SETUP_FINALLY, SETUP_WITH
diff --git a/shared-bindings/_bleio/Adapter.c b/shared-bindings/_bleio/Adapter.c
index 0caca96b8..a64167e5a 100644
--- a/shared-bindings/_bleio/Adapter.c
+++ b/shared-bindings/_bleio/Adapter.c
@@ -25,22 +25,45 @@
* THE SOFTWARE.
*/
+#include <string.h>
+
#include "py/objproperty.h"
+#include "py/runtime.h"
#include "shared-bindings/_bleio/Address.h"
#include "shared-bindings/_bleio/Adapter.h"
+#define ADV_INTERVAL_MIN (0.0020f)
+#define ADV_INTERVAL_MIN_STRING "0.0020"
+#define ADV_INTERVAL_MAX (10.24f)
+#define ADV_INTERVAL_MAX_STRING "10.24"
+// 20ms is recommended by Apple
+#define ADV_INTERVAL_DEFAULT (0.1f)
+
+#define INTERVAL_DEFAULT (0.1f)
+#define INTERVAL_MIN (0.0025f)
+#define INTERVAL_MIN_STRING "0.0025"
+#define INTERVAL_MAX (40.959375f)
+#define INTERVAL_MAX_STRING "40.959375"
+#define WINDOW_DEFAULT (0.1f)
+
//| .. currentmodule:: _bleio
//|
-//| :class:`Adapter` --- BLE adapter information
+//| :class:`Adapter` --- BLE adapter
//| ----------------------------------------------------
//|
-//| Get current status of the BLE adapter
+//| The Adapter manages the discovery and connection to other nearby Bluetooth Low Energy devices.
+//| This part of the Bluetooth Low Energy Specification is known as Generic Access Profile (GAP).
//|
-//| Usage::
+//| Discovery of other devices happens during a scanning process that listens for small packets of
+//| information, known as advertisements, that are broadcast unencrypted. The advertising packets
+//| have two different uses. The first is to broadcast a small piece of data to anyone who cares and
+//| and nothing more. These are known as Beacons. The second class of advertisement is to promote
+//| additional functionality available after the devices establish a connection. For example, a
+//| BLE keyboard may advertise that it can provide key information, but not what the key info is.
//|
-//| import _bleio
-//| _bleio.adapter.enabled = True
-//| print(_bleio.adapter.address)
+//| The built-in BLE adapter can do both parts of this process: it can scan for other device
+//| advertisements and it can advertise its own data. Furthermore, Adapters can accept incoming
+//| connections and also initiate connections.
//|
//| .. class:: Adapter()
@@ -49,19 +72,19 @@
//| Use `_bleio.adapter` to access the sole instance available.
//|
-//| .. attribute:: adapter.enabled
+//| .. attribute:: enabled
//|
-//| State of the BLE adapter.
+//| State of the BLE adapter.
//|
STATIC mp_obj_t bleio_adapter_get_enabled(mp_obj_t self) {
- return mp_obj_new_bool(common_hal_bleio_adapter_get_enabled());
+ return mp_obj_new_bool(common_hal_bleio_adapter_get_enabled(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_enabled_obj, bleio_adapter_get_enabled);
static mp_obj_t bleio_adapter_set_enabled(mp_obj_t self, mp_obj_t value) {
const bool enabled = mp_obj_is_true(value);
- common_hal_bleio_adapter_set_enabled(enabled);
+ common_hal_bleio_adapter_set_enabled(self, enabled);
return mp_const_none;
}
@@ -74,12 +97,12 @@ const mp_obj_property_t bleio_adapter_enabled_obj = {
(mp_obj_t)&mp_const_none_obj },
};
-//| .. attribute:: adapter.address
+//| .. attribute:: address
//|
-//| MAC address of the BLE adapter. (read-only)
+//| MAC address of the BLE adapter. (read-only)
//|
STATIC mp_obj_t bleio_adapter_get_address(mp_obj_t self) {
- return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_address());
+ return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_address(self));
}
MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_address_obj, bleio_adapter_get_address);
@@ -91,29 +114,260 @@ const mp_obj_property_t bleio_adapter_address_obj = {
(mp_obj_t)&mp_const_none_obj },
};
-//| .. attribute:: adapter.default_name
+//| .. attribute:: name
+//|
+//| name of the BLE adapter used once connected. Not used in advertisements.
+//| 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_name(mp_obj_t self) {
+ return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_name(self));
+}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_name_obj, bleio_adapter_get_name);
+
+
+STATIC mp_obj_t bleio_adapter_set_name(mp_obj_t self, mp_obj_t new_name) {
+ common_hal_bleio_adapter_set_name(self, mp_obj_str_get_str(new_name));
+ return mp_const_none;
+}
+MP_DEFINE_CONST_FUN_OBJ_2(bleio_adapter_set_name_obj, bleio_adapter_set_name);
+
+const mp_obj_property_t bleio_adapter_name_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_adapter_get_name_obj,
+ (mp_obj_t)&bleio_adapter_set_name_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+//| .. method:: start_advertising(data, *, scan_response=None, connectable=True, interval=0.1)
+//|
+//| Starts advertising until `stop_advertising` is called or if connectable, another device
+//| connects to us.
+//|
+//| :param buf data: advertising data packet bytes
+//| :param buf scan_response: scan response data packet bytes. ``None`` if no scan response is needed.
+//| :param bool connectable: If `True` then other devices are allowed to connect to this peripheral.
+//| :param float interval: advertising interval, in seconds
+//|
+STATIC mp_obj_t bleio_adapter_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_data, ARG_scan_response, ARG_connectable, ARG_interval };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_scan_response, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
+ { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
+ { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ mp_buffer_info_t data_bufinfo;
+ mp_get_buffer_raise(args[ARG_data].u_obj, &data_bufinfo, MP_BUFFER_READ);
+
+ // Pass an empty buffer if scan_response not provided.
+ mp_buffer_info_t scan_response_bufinfo = { 0 };
+ if (args[ARG_scan_response].u_obj != mp_const_none) {
+ mp_get_buffer_raise(args[ARG_scan_response].u_obj, &scan_response_bufinfo, MP_BUFFER_READ);
+ }
+
+ if (args[ARG_interval].u_obj == MP_OBJ_NULL) {
+ args[ARG_interval].u_obj = mp_obj_new_float(ADV_INTERVAL_DEFAULT);
+ }
+
+ const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj);
+ if (interval < ADV_INTERVAL_MIN || interval > ADV_INTERVAL_MAX) {
+ mp_raise_ValueError_varg(translate("interval must be in range %s-%s"),
+ ADV_INTERVAL_MIN_STRING, ADV_INTERVAL_MAX_STRING);
+ }
+
+ common_hal_bleio_adapter_start_advertising(self, args[ARG_connectable].u_bool, interval,
+ &data_bufinfo, &scan_response_bufinfo);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_adapter_start_advertising_obj, 2, bleio_adapter_start_advertising);
+
+//| .. method:: stop_advertising()
+//|
+//| Stop sending advertising packets.
+STATIC mp_obj_t bleio_adapter_stop_advertising(mp_obj_t self_in) {
+ bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ common_hal_bleio_adapter_stop_advertising(self);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_stop_advertising_obj, bleio_adapter_stop_advertising);
+
+//| .. method:: start_scan(prefixes=b"", \*, buffer_size=512, extended=False, timeout=None, interval=0.1, window=0.1, minimum_rssi=-80)
+//|
+//| Starts a BLE scan and returns an iterator of results. Advertisements and scan responses are
+//| filtered and returned separately.
+//|
+//| :param sequence prefixes: Sequence of byte string prefixes to filter advertising packets
+//| with. A packet without an advertising structure that matches one of the prefixes is
+//| ignored. Format is one byte for length (n) and n bytes of prefix and can be repeated.
+//| :param int buffer_size: the maximum number of advertising bytes to buffer.
+//| :param bool extended: When True, support extended advertising packets. Increasing buffer_size is recommended when this is set.
+//| :param float timeout: the scan timeout in seconds. If None, will scan until `stop_scan` is called.
+//| :param float interval: the interval (in seconds) between the start of two consecutive scan windows
+//| Must be in the range 0.0025 - 40.959375 seconds.
+//| :param float window: the duration (in seconds) to scan a single BLE channel.
+//| window must be <= interval.
+//| :param int minimum_rssi: the minimum rssi of entries to return.
+//| :param bool active: retrieve scan responses for scannable advertisements.
+//| :returns: an iterable of `_bleio.ScanEntry` objects
+//| :rtype: iterable
+//|
+STATIC mp_obj_t bleio_adapter_start_scan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_prefixes, ARG_buffer_size, ARG_extended, ARG_timeout, ARG_interval, ARG_window, ARG_minimum_rssi, ARG_active };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_prefixes, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 512} },
+ { MP_QSTR_extended, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
+ { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_window, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_minimum_rssi, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -80} },
+ { MP_QSTR_active, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
+ };
+
+ bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ mp_float_t timeout = 0;
+ if (args[ARG_timeout].u_obj != MP_OBJ_NULL) {
+ timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
+ }
+
+ if (args[ARG_interval].u_obj == MP_OBJ_NULL) {
+ args[ARG_interval].u_obj = mp_obj_new_float(INTERVAL_DEFAULT);
+ }
+
+ if (args[ARG_window].u_obj == MP_OBJ_NULL) {
+ args[ARG_window].u_obj = mp_obj_new_float(WINDOW_DEFAULT);
+ }
+
+ const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj);
+ if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
+ mp_raise_ValueError_varg(translate("interval must be in range %s-%s"), INTERVAL_MIN_STRING, INTERVAL_MAX_STRING);
+ }
+
+ const mp_float_t window = mp_obj_float_get(args[ARG_window].u_obj);
+ if (window > interval) {
+ mp_raise_ValueError(translate("window must be <= interval"));
+ }
+
+ mp_buffer_info_t prefix_bufinfo;
+ prefix_bufinfo.len = 0;
+ if (args[ARG_prefixes].u_obj != MP_OBJ_NULL) {
+ mp_get_buffer_raise(args[ARG_prefixes].u_obj, &prefix_bufinfo, MP_BUFFER_READ);
+ if (gc_nbytes(prefix_bufinfo.buf) == 0) {
+ mp_raise_ValueError(translate("Prefix buffer must be on the heap"));
+ }
+ }
+
+ return common_hal_bleio_adapter_start_scan(self, prefix_bufinfo.buf, prefix_bufinfo.len, args[ARG_extended].u_bool, args[ARG_buffer_size].u_int, timeout, interval, window, args[ARG_minimum_rssi].u_int, args[ARG_active].u_bool);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_adapter_start_scan_obj, 1, bleio_adapter_start_scan);
+
+//| .. method:: stop_scan()
+//|
+//| Stop the current scan.
+STATIC mp_obj_t bleio_adapter_stop_scan(mp_obj_t self_in) {
+ bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ common_hal_bleio_adapter_stop_scan(self);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_stop_scan_obj, bleio_adapter_stop_scan);
+
+//| .. attribute:: connected
//|
-//| 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.
+//| True when the adapter is connected to another device regardless of who initiated the
+//| connection. (read-only)
//|
-STATIC mp_obj_t bleio_adapter_get_default_name(mp_obj_t self) {
- return common_hal_bleio_adapter_get_default_name();
+STATIC mp_obj_t bleio_adapter_get_connected(mp_obj_t self) {
+ return mp_obj_new_bool(common_hal_bleio_adapter_get_connected(self));
}
-MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_default_name_obj, bleio_adapter_get_default_name);
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_connected_obj, bleio_adapter_get_connected);
-const mp_obj_property_t bleio_adapter_default_name_obj = {
+const mp_obj_property_t bleio_adapter_connected_obj = {
.base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_adapter_get_default_name_obj,
+ .proxy = { (mp_obj_t)&bleio_adapter_get_connected_obj,
(mp_obj_t)&mp_const_none_obj,
(mp_obj_t)&mp_const_none_obj },
};
+//| .. attribute:: connections
+//|
+//| Tuple of active connections including those initiated through
+//| :py:meth:`_bleio.Adapter.connect`. (read-only)
+//|
+STATIC mp_obj_t bleio_adapter_get_connections(mp_obj_t self) {
+ return common_hal_bleio_adapter_get_connections(self);
+}
+MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_connections_obj, bleio_adapter_get_connections);
+
+const mp_obj_property_t bleio_adapter_connections_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_adapter_get_connections_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+//| .. method:: connect(address, *, timeout, pair=False)
+//|
+//| Attempts a connection to the device with the given address.
+//|
+//| :param Address address: The address of the peripheral to connect to
+//| :param float/int timeout: Try to connect for timeout seconds.
+//|
+STATIC mp_obj_t bleio_adapter_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_address, ARG_timeout, ARG_pair };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_pair, MP_ARG_KW_ONLY | MP_ARG_BOOL, { .u_bool = false } },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ if (!MP_OBJ_IS_TYPE(args[ARG_address].u_obj, &bleio_address_type)) {
+ mp_raise_ValueError(translate("Expected an Address"));
+ }
+
+ bleio_address_obj_t *address = MP_OBJ_TO_PTR(args[ARG_address].u_obj);
+ mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
+
+ return common_hal_bleio_adapter_connect(self, address, timeout, args[ARG_pair].u_bool);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_adapter_connect_obj, 2, bleio_adapter_connect);
+
+
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) },
+ { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_adapter_name_obj) },
+
+ { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_adapter_start_advertising_obj) },
+ { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_adapter_stop_advertising_obj) },
+
+ { MP_ROM_QSTR(MP_QSTR_start_scan), MP_ROM_PTR(&bleio_adapter_start_scan_obj) },
+ { MP_ROM_QSTR(MP_QSTR_stop_scan), MP_ROM_PTR(&bleio_adapter_stop_scan_obj) },
+
+ { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_adapter_connect_obj) },
+
+ { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_adapter_connected_obj) },
+ { MP_ROM_QSTR(MP_QSTR_connections), MP_ROM_PTR(&bleio_adapter_connections_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 932fc9c95..2ff77f755 100644
--- a/shared-bindings/_bleio/Adapter.h
+++ b/shared-bindings/_bleio/Adapter.h
@@ -28,13 +28,33 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H
+#include <stdint.h>
+
+#include "common-hal/_bleio/Adapter.h"
+
+#include "py/objstr.h"
#include "shared-module/_bleio/Address.h"
const mp_obj_type_t bleio_adapter_type;
-extern bool common_hal_bleio_adapter_get_enabled(void);
-extern void common_hal_bleio_adapter_set_enabled(bool enabled);
-extern bleio_address_obj_t *common_hal_bleio_adapter_get_address(void);
-extern mp_obj_t common_hal_bleio_adapter_get_default_name(void);
+extern bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self);
+extern void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enabled);
+extern bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self);
+extern bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *self);
+
+extern mp_obj_str_t* common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self);
+extern void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char* name);
+
+extern uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, float interval, uint8_t *advertising_data, uint16_t advertising_data_len, uint8_t *scan_response_data, uint16_t scan_response_data_len);
+
+extern void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool connectable, mp_float_t interval, mp_buffer_info_t *advertising_data_bufinfo, mp_buffer_info_t *scan_response_data_bufinfo);
+void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self);
+
+mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t* prefixes, size_t prefix_length, bool extended, mp_int_t buffer_size, mp_float_t timeout, mp_float_t interval, mp_float_t window, mp_int_t minimum_rssi, bool active);
+void common_hal_bleio_adapter_stop_scan(bleio_adapter_obj_t *self);
+
+bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self);
+mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self);
+mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout, bool pair);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H
diff --git a/shared-bindings/_bleio/Address.c b/shared-bindings/_bleio/Address.c
index cdee02b5d..c31eb604b 100644
--- a/shared-bindings/_bleio/Address.c
+++ b/shared-bindings/_bleio/Address.c
@@ -114,10 +114,11 @@ const mp_obj_property_t bleio_address_address_bytes_obj = {
};
//| .. attribute:: type
-//|
+//|
//| The address type (read-only).
-//| One of the integer values: `PUBLIC`, `RANDOM_STATIC`,
-//| `RANDOM_PRIVATE_RESOLVABLE`, or `RANDOM_PRIVATE_NON_RESOLVABLE`.
+//|
+//| One of the integer values: `PUBLIC`, `RANDOM_STATIC`, `RANDOM_PRIVATE_RESOLVABLE`,
+//| or `RANDOM_PRIVATE_NON_RESOLVABLE`.
//|
STATIC mp_obj_t bleio_address_get_type(mp_obj_t self_in) {
bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -159,6 +160,28 @@ STATIC mp_obj_t bleio_address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_o
}
}
+//| .. method:: __hash__()
+//|
+//| Returns a hash for the Address data.
+//|
+STATIC mp_obj_t bleio_address_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
+ switch (op) {
+ // Two Addresses are equal if their address bytes and address_type are equal
+ case MP_UNARY_OP_HASH: {
+ mp_obj_t bytes = common_hal_bleio_address_get_address_bytes(MP_OBJ_TO_PTR(self_in));
+ GET_STR_HASH(bytes, h);
+ if (h == 0) {
+ GET_STR_DATA_LEN(bytes, data, len);
+ h = qstr_compute_hash(data, len);
+ }
+ h ^= common_hal_bleio_address_get_type(MP_OBJ_TO_PTR(self_in));
+ return MP_OBJ_NEW_SMALL_INT(h);
+ }
+ default:
+ return MP_OBJ_NULL; // op not supported
+ }
+}
+
STATIC void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_buffer_info_t buf_info;
@@ -205,6 +228,7 @@ const mp_obj_type_t bleio_address_type = {
.name = MP_QSTR_Address,
.make_new = bleio_address_make_new,
.print = bleio_address_print,
+ .unary_op = bleio_address_unary_op,
.binary_op = bleio_address_binary_op,
.locals_dict = (mp_obj_dict_t*)&bleio_address_locals_dict
};
diff --git a/shared-bindings/_bleio/Central.c b/shared-bindings/_bleio/Central.c
deleted file mode 100644
index 084f40cd6..000000000
--- a/shared-bindings/_bleio/Central.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
- * Copyright (c) 2016 Glenn Ruben Bakke
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include "ble_drv.h"
-#include "py/objarray.h"
-#include "py/objproperty.h"
-#include "py/objstr.h"
-#include "py/runtime.h"
-#include "shared-bindings/_bleio/Adapter.h"
-#include "shared-bindings/_bleio/Address.h"
-#include "shared-bindings/_bleio/Characteristic.h"
-#include "shared-bindings/_bleio/Central.h"
-#include "shared-bindings/_bleio/Service.h"
-
-//| .. currentmodule:: _bleio
-//|
-//| :class:`Central` -- A BLE central device
-//| =========================================================
-//|
-//| Implement a BLE central, which runs locally. Can connect to a given address.
-//|
-//| Usage::
-//|
-//| import _bleio
-//|
-//| scanner = _bleio.Scanner()
-//| entries = scanner.scan(2.5)
-//|
-//| my_entry = None
-//| for entry in entries:
-//| if entry.name is not None and entry.name == 'InterestingPeripheral':
-//| my_entry = entry
-//| break
-//|
-//| 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()
-//|
-//| Create a new Central object.
-//|
-STATIC mp_obj_t bleio_central_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- mp_arg_check_num(n_args, kw_args, 0, 0, false);
-
- bleio_central_obj_t *self = m_new_obj(bleio_central_obj_t);
- self->base.type = &bleio_central_type;
-
- common_hal_bleio_central_construct(self);
-
- return MP_OBJ_FROM_PTR(self);
-}
-
-//| .. method:: connect(address, timeout, *, service_uuids_whitelist=None)
-//| Attempts a connection to the remote peripheral.
-//|
-//| :param Address address: The address of the peripheral to connect to
-//| :param float/int timeout: Try to connect for timeout seconds.
-//|
-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]);
-
- enum { ARG_address, ARG_timeout, ARG_service_uuids_whitelist };
- 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_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 (!MP_OBJ_IS_TYPE(args[ARG_address].u_obj, &bleio_address_type)) {
- mp_raise_ValueError(translate("Expected an Address"));
- }
-
- bleio_address_obj_t *address = MP_OBJ_TO_PTR(args[ARG_address].u_obj);
- 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);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_central_connect_obj, 3, bleio_central_connect);
-
-
-//| .. method:: disconnect()
-//|
-//| Disconnects from the remote peripheral.
-//|
-STATIC mp_obj_t bleio_central_disconnect(mp_obj_t self_in) {
- bleio_central_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- common_hal_bleio_central_disconnect(self);
-
- return mp_const_none;
-}
-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.
-//|
-STATIC mp_obj_t bleio_central_get_connected(mp_obj_t self_in) {
- bleio_central_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return mp_obj_new_bool(common_hal_bleio_central_get_connected(self));
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_central_get_connected_obj, bleio_central_get_connected);
-
-const mp_obj_property_t bleio_central_connected_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_central_get_connected_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_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) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(bleio_central_locals_dict, bleio_central_locals_dict_table);
-
-const mp_obj_type_t bleio_central_type = {
- { &mp_type_type },
- .name = MP_QSTR_Central,
- .make_new = bleio_central_make_new,
- .locals_dict = (mp_obj_dict_t*)&bleio_central_locals_dict
-};
diff --git a/shared-bindings/_bleio/Characteristic.c b/shared-bindings/_bleio/Characteristic.c
index 198155589..d89da2a2f 100644
--- a/shared-bindings/_bleio/Characteristic.c
+++ b/shared-bindings/_bleio/Characteristic.c
@@ -45,8 +45,8 @@
//|
//| There is no regular constructor for a Characteristic. A new local Characteristic can be created
//| and attached to a Service by calling `add_to_service()`.
-//| Remote Characteristic objects are created by `Central.discover_remote_services()`
-//| or `Peripheral.discover_remote_services()` as part of remote Services.
+//| Remote Characteristic objects are created by `Connection.discover_remote_services()`
+//| as part of remote Services.
//|
//| .. method:: add_to_service(service, uuid, *, properties=0, read_perm=`Attribute.OPEN`, write_perm=`Attribute.OPEN`, max_length=20, fixed_length=False, initial_value=None)
@@ -134,12 +134,10 @@ STATIC mp_obj_t bleio_characteristic_add_to_service(size_t n_args, const mp_obj_
// 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(
- characteristic, MP_OBJ_TO_PTR(service_obj), MP_OBJ_TO_PTR(uuid_obj),
+ characteristic, MP_OBJ_TO_PTR(service_obj), 0, MP_OBJ_TO_PTR(uuid_obj),
properties, read_perm, write_perm,
max_length, fixed_length, &initial_value_bufinfo);
- common_hal_bleio_service_add_characteristic(service_obj, characteristic);
-
return MP_OBJ_FROM_PTR(characteristic);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_characteristic_add_to_service_fun_obj, 3, bleio_characteristic_add_to_service);
@@ -170,7 +168,8 @@ const mp_obj_property_t bleio_characteristic_properties_obj = {
//| .. attribute:: uuid
//|
//| The UUID of this characteristic. (read-only)
-//| Will be ``None`` if the 128-bit UUID for this characteristic is not known.
+//|
+//| Will be ``None`` if the 128-bit UUID for this characteristic is not known.
//|
STATIC mp_obj_t bleio_characteristic_get_uuid(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -194,7 +193,9 @@ const mp_obj_property_t bleio_characteristic_uuid_obj = {
STATIC mp_obj_t bleio_characteristic_get_value(mp_obj_t self_in) {
bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return common_hal_bleio_characteristic_get_value(self);
+ uint8_t temp[512];
+ size_t actual_len = common_hal_bleio_characteristic_get_value(self, temp, sizeof(temp));
+ return mp_obj_new_bytearray(actual_len, temp);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_value_obj, bleio_characteristic_get_value);
@@ -224,8 +225,20 @@ const mp_obj_property_t bleio_characteristic_value_obj = {
STATIC mp_obj_t bleio_characteristic_get_descriptors(mp_obj_t self_in) {
bleio_characteristic_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 *char_list = common_hal_bleio_characteristic_get_descriptor_list(self);
- return mp_obj_new_tuple(char_list->len, char_list->items);
+ bleio_descriptor_obj_t *descriptors = common_hal_bleio_characteristic_get_descriptor_list(self);
+ bleio_descriptor_obj_t *head = descriptors;
+ size_t len = 0;
+ while (head != NULL) {
+ len++;
+ head = head->next;
+ }
+ mp_obj_tuple_t * t = MP_OBJ_TO_PTR(mp_obj_new_tuple(len, NULL));
+ head = descriptors;
+ for (size_t i = len - 1; i >= 0; i--) {
+ t->items[i] = MP_OBJ_FROM_PTR(head);
+ head = head->next;
+ }
+ return MP_OBJ_FROM_PTR(t);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_descriptors_obj, bleio_characteristic_get_descriptors);
@@ -282,7 +295,7 @@ 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_add_to_service), MP_ROM_PTR(&bleio_characteristic_add_to_service_obj) },
- { MP_ROM_QSTR(MP_QSTR_properties), MP_ROM_PTR(&bleio_characteristic_get_properties_obj) },
+ { MP_ROM_QSTR(MP_QSTR_properties), MP_ROM_PTR(&bleio_characteristic_properties_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_set_cccd), MP_ROM_PTR(&bleio_characteristic_set_cccd_obj) },
diff --git a/shared-bindings/_bleio/Characteristic.h b/shared-bindings/_bleio/Characteristic.h
index a816c6050..c4356fd4b 100644
--- a/shared-bindings/_bleio/Characteristic.h
+++ b/shared-bindings/_bleio/Characteristic.h
@@ -36,12 +36,12 @@
extern const mp_obj_type_t bleio_characteristic_type;
-extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, 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_buffer_info_t *initial_value_bufinfo);
-extern mp_obj_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self);
+extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, bleio_service_obj_t *service, uint16_t handle, 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_buffer_info_t *initial_value_bufinfo);
+extern size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t* buf, size_t len);
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_descriptor_obj_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_add_descriptor(bleio_characteristic_obj_t *self, bleio_descriptor_obj_t *descriptor);
extern void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate);
diff --git a/shared-bindings/_bleio/Connection.c b/shared-bindings/_bleio/Connection.c
new file mode 100644
index 000000000..1c6931b29
--- /dev/null
+++ b/shared-bindings/_bleio/Connection.c
@@ -0,0 +1,171 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "shared-bindings/_bleio/Connection.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#include "ble_drv.h"
+#include "py/objarray.h"
+#include "py/objproperty.h"
+#include "py/objstr.h"
+#include "py/runtime.h"
+#include "shared-bindings/_bleio/Adapter.h"
+#include "shared-bindings/_bleio/Address.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+#include "shared-bindings/_bleio/Service.h"
+
+//| .. currentmodule:: _bleio
+//|
+//| :class:`Connection` -- A BLE connection
+//| =========================================================
+//|
+//| A BLE connection to another device. Used to discover and interact with services on the other
+//| device.
+//|
+//| Usage::
+//|
+//| import _bleio
+//|
+//| my_entry = None
+//| for entry in _bleio.adapter.scan(2.5):
+//| if entry.name is not None and entry.name == 'InterestingPeripheral':
+//| my_entry = entry
+//| break
+//|
+//| if not my_entry:
+//| raise Exception("'InterestingPeripheral' not found")
+//|
+//| connection = _bleio.adapter.connect(my_entry.address, timeout=10)
+//|
+
+STATIC void ensure_connected(bleio_connection_obj_t *self) {
+ if (!common_hal_bleio_connection_get_connected(self)) {
+ mp_raise_ValueError(translate("Connection has been disconnected and can no longer be used. Create a new connection."));
+ }
+}
+
+//| .. class:: Connection()
+//|
+//| Connections cannot be made directly. Instead, to initiate a connection use `Adapter.connect`.
+//| Connections may also be made when another device initiates a connection. To use a Connection
+//| created by a peer, read the `Adapter.connections` property.
+//|
+//| .. method:: disconnect()
+//|
+//| Disconnects from the remote peripheral.
+//|
+STATIC mp_obj_t bleio_connection_disconnect(mp_obj_t self_in) {
+ bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ ensure_connected(self);
+
+ common_hal_bleio_connection_disconnect(self->connection);
+
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_disconnect_obj, bleio_connection_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.
+//| `Connection.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 `_bleio.Service` objects provided by the remote peripheral.
+//|
+STATIC mp_obj_t bleio_connection_discover_remote_services(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_connection_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);
+
+ ensure_connected(self);
+
+ return MP_OBJ_FROM_PTR(common_hal_bleio_connection_discover_remote_services(
+ self,
+ args[ARG_service_uuids_whitelist].u_obj));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_connection_discover_remote_services_obj, 1, bleio_connection_discover_remote_services);
+
+//| .. attribute:: connected
+//|
+//| True if connected to a remote peer.
+//|
+STATIC mp_obj_t bleio_connection_get_connected(mp_obj_t self_in) {
+ bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(common_hal_bleio_connection_get_connected(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_get_connected_obj, bleio_connection_get_connected);
+
+const mp_obj_property_t bleio_connection_connected_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_connection_get_connected_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC const mp_rom_map_elem_t bleio_connection_locals_dict_table[] = {
+ // Methods
+ { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_connection_disconnect_obj) },
+ { MP_ROM_QSTR(MP_QSTR_discover_remote_services), MP_ROM_PTR(&bleio_connection_discover_remote_services_obj) },
+
+ // Properties
+ { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&bleio_connection_connected_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(bleio_connection_locals_dict, bleio_connection_locals_dict_table);
+
+const mp_obj_type_t bleio_connection_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_Connection,
+ .locals_dict = (mp_obj_dict_t*)&bleio_connection_locals_dict,
+ .unary_op = mp_generic_unary_op,
+};
diff --git a/shared-bindings/_bleio/Scanner.h b/shared-bindings/_bleio/Connection.h
index cbaa77866..5de6730c9 100644
--- a/shared-bindings/_bleio/Scanner.h
+++ b/shared-bindings/_bleio/Connection.h
@@ -25,16 +25,17 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CONNECTION_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CONNECTION_H
-#include "py/objtype.h"
-#include "common-hal/_bleio/Scanner.h"
+#include "py/objtuple.h"
+#include "common-hal/_bleio/Connection.h"
+#include "common-hal/_bleio/Service.h"
-extern const mp_obj_type_t bleio_scanner_type;
+extern const mp_obj_type_t bleio_connection_type;
-extern void common_hal_bleio_scanner_construct(bleio_scanner_obj_t *self);
-extern mp_obj_t common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_float_t timeout, mp_float_t interval, mp_float_t window);
-extern void common_hal_bleio_scanner_stop(bleio_scanner_obj_t *self);
+extern void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self);
+extern bool common_hal_bleio_connection_get_connected(bleio_connection_obj_t *self);
+extern mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist);
-#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CONNECTION_H
diff --git a/shared-bindings/_bleio/Descriptor.c b/shared-bindings/_bleio/Descriptor.c
index 0ab9fe8e9..45a95903e 100644
--- a/shared-bindings/_bleio/Descriptor.c
+++ b/shared-bindings/_bleio/Descriptor.c
@@ -46,9 +46,8 @@
//|
//| There is no regular constructor for a Descriptor. A new local Descriptor can be created
//| and attached to a Characteristic by calling `add_to_characteristic()`.
-//| Remote Descriptor objects are created by `Central.discover_remote_services()`
-//| or `Peripheral.discover_remote_services()` as part of remote Characteristics
-//| in the remote Services that are discovered.
+//| Remote Descriptor objects are created by `Connection.discover_remote_services()`
+//| as part of remote Characteristics in the remote Services that are discovered.
//|
//| .. classmethod:: add_to_characteristic(characteristic, uuid, *, read_perm=`Attribute.OPEN`, write_perm=`Attribute.OPEN`, max_length=20, fixed_length=False, initial_value=b'')
//|
@@ -180,7 +179,9 @@ const mp_obj_property_t bleio_descriptor_characteristic_obj = {
STATIC mp_obj_t bleio_descriptor_get_value(mp_obj_t self_in) {
bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in);
- return common_hal_bleio_descriptor_get_value(self);
+ uint8_t temp[512];
+ size_t actual_len = common_hal_bleio_descriptor_get_value(self, temp, sizeof(temp));
+ return mp_obj_new_bytearray(actual_len, temp);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_value_obj, bleio_descriptor_get_value);
diff --git a/shared-bindings/_bleio/Descriptor.h b/shared-bindings/_bleio/Descriptor.h
index 7544bdb17..273cb1c1e 100644
--- a/shared-bindings/_bleio/Descriptor.h
+++ b/shared-bindings/_bleio/Descriptor.h
@@ -38,7 +38,7 @@ extern const mp_obj_type_t bleio_descriptor_type;
extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_characteristic_obj_t *characteristic, 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, mp_buffer_info_t *initial_value_bufinfo);
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 size_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self, uint8_t* buf, size_t len);
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
deleted file mode 100644
index 0bf292744..000000000
--- a/shared-bindings/_bleio/Peripheral.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
- * Copyright (c) 2016 Glenn Ruben Bakke
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include "ble_drv.h"
-#include "py/objarray.h"
-#include "py/objproperty.h"
-#include "py/objstr.h"
-#include "py/runtime.h"
-
-#include "shared-bindings/_bleio/Adapter.h"
-#include "shared-bindings/_bleio/Characteristic.h"
-#include "shared-bindings/_bleio/Peripheral.h"
-#include "shared-bindings/_bleio/Service.h"
-#include "shared-bindings/_bleio/UUID.h"
-#include "shared-module/_bleio/ScanEntry.h"
-
-#include "common-hal/_bleio/Peripheral.h"
-
-#define ADV_INTERVAL_MIN (0.0020f)
-#define ADV_INTERVAL_MIN_STRING "0.0020"
-#define ADV_INTERVAL_MAX (10.24f)
-#define ADV_INTERVAL_MAX_STRING "10.24"
-// 20ms is recommended by Apple
-#define ADV_INTERVAL_DEFAULT (0.1f)
-
-//| .. currentmodule:: _bleio
-//|
-//| :class:`Peripheral` -- A BLE peripheral device
-//| =========================================================
-//|
-//| Implement a BLE peripheral which runs locally.
-//| Set up using the supplied services, and then allow advertising to be started and stopped.
-//|
-//| Usage::
-//|
-//| from _bleio import Characteristic, Peripheral, Service
-//| from adafruit_ble.advertising import ServerAdvertisement
-//|
-//| # Create a peripheral and start it up.
-//| peripheral = _bleio.Peripheral()
-//|
-//| # Create a Service and add it to this Peripheral.
-//| service = Service.add_to_peripheral(peripheral, _bleio.UUID(0x180f))
-//|
-//| # Create a Characteristic and add it to the Service.
-//| characteristic = Characteristic.add_to_service(service,
-//| _bleio.UUID(0x2919), properties=Characteristic.READ | Characteristic.NOTIFY)
-//|
-//| adv = ServerAdvertisement(peripheral)
-//| peripheral.start_advertising(adv.advertising_data_bytes, scan_response=adv.scan_response_bytes)
-//|
-//| while not peripheral.connected:
-//| # Wait for connection.
-//| pass
-//|
-//| .. class:: Peripheral(name=None)
-//|
-//| Create a new Peripheral object.
-//|
-//| :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_name };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_name, MP_ARG_OBJ, {.u_obj = mp_const_none} },
- };
-
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- bleio_peripheral_obj_t *self = m_new_obj(bleio_peripheral_obj_t);
- self->base.type = &bleio_peripheral_type;
-
- mp_obj_t name = args[ARG_name].u_obj;
- if (name == mp_const_none) {
- 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, name);
-
- return MP_OBJ_FROM_PTR(self);
-}
-
-//| .. attribute:: connected (read-only)
-//|
-//| True if connected to a BLE Central device.
-//|
-STATIC mp_obj_t bleio_peripheral_get_connected(mp_obj_t self_in) {
- bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return mp_obj_new_bool(common_hal_bleio_peripheral_get_connected(self));
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_connected_obj, bleio_peripheral_get_connected);
-
-const mp_obj_property_t bleio_peripheral_connected_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_peripheral_get_connected_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-//| .. attribute:: services
-//|
-//| A tuple of :py:class:`Service` objects offered by this peripheral. (read-only)
-//|
-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 *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);
-
-const mp_obj_property_t bleio_peripheral_services_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_peripheral_get_services_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-//| .. attribute:: name
-//|
-//| The peripheral's name, included when advertising. (read-only)
-//|
-STATIC mp_obj_t bleio_peripheral_get_name(mp_obj_t self_in) {
- bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- return common_hal_bleio_peripheral_get_name(self);
-}
-MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_get_name_obj, bleio_peripheral_get_name);
-
-const mp_obj_property_t bleio_peripheral_name_obj = {
- .base.type = &mp_type_property,
- .proxy = { (mp_obj_t)&bleio_peripheral_get_name_obj,
- (mp_obj_t)&mp_const_none_obj,
- (mp_obj_t)&mp_const_none_obj },
-};
-
-//| .. method:: start_advertising(data, *, scan_response=None, connectable=True, interval=0.1)
-//|
-//| Starts advertising the peripheral. The peripheral's name and
-//| services are included in the advertisement packets.
-//|
-//| :param buf data: advertising data packet bytes
-//| :param buf scan_response: scan response data packet bytes. ``None`` if no scan response is needed.
-//| :param bool connectable: If `True` then other devices are allowed to connect to this peripheral.
-//| :param float interval: advertising interval, in seconds
-//|
-STATIC mp_obj_t bleio_peripheral_start_advertising(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_data, ARG_scan_response, ARG_connectable, ARG_interval };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ },
- { MP_QSTR_scan_response, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
- { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} },
- { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
- };
-
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- mp_buffer_info_t data_bufinfo;
- mp_get_buffer_raise(args[ARG_data].u_obj, &data_bufinfo, MP_BUFFER_READ);
-
- // Pass an empty buffer if scan_response not provided.
- mp_buffer_info_t scan_response_bufinfo = { 0 };
- if (args[ARG_scan_response].u_obj != mp_const_none) {
- mp_get_buffer_raise(args[ARG_scan_response].u_obj, &scan_response_bufinfo, MP_BUFFER_READ);
- }
-
- if (args[ARG_interval].u_obj == MP_OBJ_NULL) {
- args[ARG_interval].u_obj = mp_obj_new_float(ADV_INTERVAL_DEFAULT);
- }
-
- const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj);
- if (interval < ADV_INTERVAL_MIN || interval > ADV_INTERVAL_MAX) {
- mp_raise_ValueError_varg(translate("interval must be in range %s-%s"),
- ADV_INTERVAL_MIN_STRING, ADV_INTERVAL_MAX_STRING);
- }
-
- common_hal_bleio_peripheral_start_advertising(self, args[ARG_connectable].u_bool, interval,
- &data_bufinfo, &scan_response_bufinfo);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_peripheral_start_advertising_obj, 2, bleio_peripheral_start_advertising);
-
-//| .. method:: stop_advertising()
-//|
-//| Stop sending advertising packets.
-STATIC mp_obj_t bleio_peripheral_stop_advertising(mp_obj_t self_in) {
- bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- common_hal_bleio_peripheral_stop_advertising(self);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_peripheral_stop_advertising_obj, bleio_peripheral_stop_advertising);
-
-//| .. method:: disconnect()
-//|
-//| Disconnects from the remote central.
-//| Normally the central initiates a disconnection. Use this only
-//| if necessary for your application.
-//|
-STATIC mp_obj_t bleio_peripheral_disconnect(mp_obj_t self_in) {
- bleio_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in);
-
- common_hal_bleio_peripheral_disconnect(self);
-
- return mp_const_none;
-}
-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_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) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(bleio_peripheral_locals_dict, bleio_peripheral_locals_dict_table);
-
-const mp_obj_type_t bleio_peripheral_type = {
- { &mp_type_type },
- .name = MP_QSTR_Peripheral,
- .make_new = bleio_peripheral_make_new,
- .locals_dict = (mp_obj_dict_t*)&bleio_peripheral_locals_dict
-};
diff --git a/shared-bindings/_bleio/Peripheral.h b/shared-bindings/_bleio/Peripheral.h
deleted file mode 100644
index bc56a9338..000000000
--- a/shared-bindings/_bleio/Peripheral.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H
-#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PERIPHERAL_H
-
-#include "py/objtuple.h"
-#include "common-hal/_bleio/Peripheral.h"
-#include "common-hal/_bleio/Service.h"
-
-extern const mp_obj_type_t bleio_peripheral_type;
-
-extern void common_hal_bleio_peripheral_construct(bleio_peripheral_obj_t *self, mp_obj_t name);
-extern void common_hal_bleio_peripheral_add_service(bleio_peripheral_obj_t *self, bleio_service_obj_t *service);
-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/ScanEntry.c b/shared-bindings/_bleio/ScanEntry.c
index bec380d03..d03cd6fb5 100644
--- a/shared-bindings/_bleio/ScanEntry.c
+++ b/shared-bindings/_bleio/ScanEntry.c
@@ -29,6 +29,7 @@
#include <string.h>
#include "py/objproperty.h"
+#include "py/runtime.h"
#include "shared-bindings/_bleio/Address.h"
#include "shared-bindings/_bleio/ScanEntry.h"
#include "shared-bindings/_bleio/UUID.h"
@@ -36,14 +37,43 @@
//| .. currentmodule:: _bleio
//|
-//| :class:`ScanEntry` -- BLE scan response entry
+//| :class:`ScanEntry` -- BLE scan data
//| =========================================================
//|
-//| Encapsulates information about a device that was received as a
-//| response to a BLE scan request. This object may only be created
-//| by a `_bleio.Scanner`: it has no user-visible constructor.
+//| Encapsulates information about a device that was received during scanning. It can be
+//| advertisement or scan response data. This object may only be created by a `_bleio.ScanResults`:
+//| it has no user-visible constructor.
//|
+//| .. class:: ScanEntry()
+//|
+//| Cannot be instantiated directly. Use `_bleio.Adapter.start_scan`.
+//|
+//| .. method:: matches(prefixes, *, all=True)
+//|
+//| Returns True if the ScanEntry matches all prefixes when ``all`` is True. This is stricter
+//| than the scan filtering which accepts any advertisements that match any of the prefixes
+//| where all is False.
+//|
+STATIC mp_obj_t bleio_scanentry_matches(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_prefixes, ARG_all };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_prefixes, MP_ARG_OBJ | MP_ARG_REQUIRED },
+ { MP_QSTR_all, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[ARG_prefixes].u_obj, &bufinfo, MP_BUFFER_READ);
+ return mp_obj_new_bool(common_hal_bleio_scanentry_matches(self, bufinfo.buf, bufinfo.len, args[ARG_all].u_bool));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_scanentry_matches_obj, 2, bleio_scanentry_matches);
+
//| .. attribute:: address
//|
//| The address of the device (read-only), of type `_bleio.Address`.
@@ -95,11 +125,47 @@ const mp_obj_property_t bleio_scanentry_rssi_obj = {
(mp_obj_t)&mp_const_none_obj },
};
+//| .. attribute:: connectable
+//|
+//| True if the device can be connected to. (read-only)
+//|
+STATIC mp_obj_t scanentry_get_connectable(mp_obj_t self_in) {
+ bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ return mp_obj_new_bool(common_hal_bleio_scanentry_get_connectable(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_connectable_obj, scanentry_get_connectable);
+
+const mp_obj_property_t bleio_scanentry_connectable_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_scanentry_get_connectable_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+//| .. attribute:: scan_response
+//|
+//| True if the entry was a scan response. (read-only)
+//|
+STATIC mp_obj_t scanentry_get_scan_response(mp_obj_t self_in) {
+ bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ return mp_obj_new_bool(common_hal_bleio_scanentry_get_scan_response(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_scan_response_obj, scanentry_get_scan_response);
+
+const mp_obj_property_t bleio_scanentry_scan_response_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_scanentry_get_scan_response_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
STATIC const mp_rom_map_elem_t bleio_scanentry_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_scanentry_address_obj) },
{ MP_ROM_QSTR(MP_QSTR_advertisement_bytes), MP_ROM_PTR(&bleio_scanentry_advertisement_bytes_obj) },
{ MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&bleio_scanentry_rssi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_connectable), MP_ROM_PTR(&bleio_scanentry_connectable_obj) },
+ { MP_ROM_QSTR(MP_QSTR_scan_response), MP_ROM_PTR(&bleio_scanentry_scan_response_obj) },
+ { MP_ROM_QSTR(MP_QSTR_matches), MP_ROM_PTR(&bleio_scanentry_matches_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_scanentry_locals_dict, bleio_scanentry_locals_dict_table);
diff --git a/shared-bindings/_bleio/ScanEntry.h b/shared-bindings/_bleio/ScanEntry.h
index 8af1f050a..9aeaf20d3 100644
--- a/shared-bindings/_bleio/ScanEntry.h
+++ b/shared-bindings/_bleio/ScanEntry.h
@@ -37,5 +37,8 @@ extern const mp_obj_type_t bleio_scanentry_type;
mp_obj_t common_hal_bleio_scanentry_get_address(bleio_scanentry_obj_t *self);
mp_obj_t common_hal_bleio_scanentry_get_advertisement_bytes(bleio_scanentry_obj_t *self);
mp_int_t common_hal_bleio_scanentry_get_rssi(bleio_scanentry_obj_t *self);
+bool common_hal_bleio_scanentry_get_connectable(bleio_scanentry_obj_t *self);
+bool common_hal_bleio_scanentry_get_scan_response(bleio_scanentry_obj_t *self);
+bool common_hal_bleio_scanentry_matches(bleio_scanentry_obj_t *self, uint8_t* prefixes, size_t prefixes_len, bool all);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H
diff --git a/shared-bindings/_bleio/ScanResults.c b/shared-bindings/_bleio/ScanResults.c
new file mode 100644
index 000000000..dcece3d5d
--- /dev/null
+++ b/shared-bindings/_bleio/ScanResults.c
@@ -0,0 +1,72 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "shared-bindings/_bleio/ScanResults.h"
+
+//| .. currentmodule:: _bleio
+//|
+//| :class:`ScanResults` -- An Iterator over BLE scanning results
+//| ===============================================================
+//|
+//| Iterates over advertising data received while scanning. This object is always created
+//| by a `_bleio.Adapter`: it has no user-visible constructor.
+//|
+STATIC mp_obj_t scanresults_iternext(mp_obj_t self_in) {
+ mp_check_self(MP_OBJ_IS_TYPE(self_in, &bleio_scanresults_type));
+ bleio_scanresults_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_obj_t scan_entry = common_hal_bleio_scanresults_next(self);
+ if (scan_entry != mp_const_none) {
+ return scan_entry;
+ }
+ return MP_OBJ_STOP_ITERATION;
+}
+
+//| .. class:: ScanResults()
+//|
+//| Cannot be instantiated directly. Use `_bleio.Adapter.start_scan`.
+//|
+//| .. method:: __iter__()
+//|
+//| Returns itself since it is the iterator.
+//|
+//| .. method:: __next__()
+//|
+//| Returns the next `_bleio.ScanEntry`. Blocks if none have been received and scanning is still
+//| active. Raises `StopIteration` if scanning is finished and no other results are available.
+//|
+
+const mp_obj_type_t bleio_scanresults_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_ScanResults,
+ .getiter = mp_identity_getiter,
+ .iternext = scanresults_iternext,
+};
diff --git a/ports/nrf/common-hal/_bleio/Scanner.h b/shared-bindings/_bleio/ScanResults.h
index 3768a52cb..a8c88c215 100644
--- a/ports/nrf/common-hal/_bleio/Scanner.h
+++ b/shared-bindings/_bleio/ScanResults.h
@@ -5,6 +5,7 @@
*
* Copyright (c) 2019 Dan Halbert for Adafruit Industries
* Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Glenn Ruben Bakke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -25,16 +26,14 @@
* THE SOFTWARE.
*/
-#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SCANNER_H
-#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SCANNER_H
+#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANRESULTS_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANRESULTS_H
#include "py/obj.h"
+#include "shared-module/_bleio/ScanResults.h"
-typedef struct {
- mp_obj_base_t base;
- mp_obj_t scan_entries;
- uint16_t interval;
- uint16_t window;
-} bleio_scanner_obj_t;
+extern const mp_obj_type_t bleio_scanresults_type;
-#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_SCANNER_H
+mp_obj_t common_hal_bleio_scanresults_next(bleio_scanresults_obj_t *self);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANRESULTS_H
diff --git a/shared-bindings/_bleio/Scanner.c b/shared-bindings/_bleio/Scanner.c
deleted file mode 100644
index 94cec9752..000000000
--- a/shared-bindings/_bleio/Scanner.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Dan Halbert for Adafruit Industries
- * Copyright (c) 2018 Artur Pacholec
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include "py/objproperty.h"
-#include "py/runtime.h"
-#include "shared-bindings/_bleio/ScanEntry.h"
-#include "shared-bindings/_bleio/Scanner.h"
-
-#define INTERVAL_DEFAULT (0.1f)
-#define INTERVAL_MIN (0.0025f)
-#define INTERVAL_MIN_STRING "0.0025"
-#define INTERVAL_MAX (40.959375f)
-#define INTERVAL_MAX_STRING "40.959375"
-#define WINDOW_DEFAULT (0.1f)
-
-//| .. currentmodule:: _bleio
-//|
-//| :class:`Scanner` -- scan for nearby BLE devices
-//| =========================================================
-//|
-//| Scan for nearby BLE devices.
-//|
-//| Usage::
-//|
-//| import _bleio
-//| scanner = _bleio.Scanner()
-//| entries = scanner.scan(2.5) # Scan for 2.5 seconds
-//|
-
-//| .. class:: Scanner()
-//|
-//| Create a new Scanner object.
-//|
-STATIC mp_obj_t bleio_scanner_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args) {
- mp_arg_check_num(n_args, kw_args, 0, 0, false);
-
- bleio_scanner_obj_t *self = m_new_obj(bleio_scanner_obj_t);
- self->base.type = type;
-
- common_hal_bleio_scanner_construct(self);
-
- return MP_OBJ_FROM_PTR(self);
-}
-
-//| .. method:: scan(timeout, \*, interval=0.1, window=0.1)
-//|
-//| Performs a BLE scan.
-//|
-//| :param float timeout: the scan timeout in seconds
-//| :param float interval: the interval (in seconds) between the start of two consecutive scan windows
-//| Must be in the range 0.0025 - 40.959375 seconds.
-//| :param float window: the duration (in seconds) to scan a single BLE channel.
-//| window must be <= interval.
-//| :returns: an iterable of `ScanEntry` objects
-//| :rtype: iterable
-//|
-STATIC mp_obj_t bleio_scanner_scan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- enum { ARG_timeout, ARG_interval, ARG_window };
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_timeout, MP_ARG_REQUIRED | MP_ARG_OBJ },
- { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
- { MP_QSTR_window, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
- };
-
- bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- 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);
-
- const mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj);
-
- if (args[ARG_interval].u_obj == MP_OBJ_NULL) {
- args[ARG_interval].u_obj = mp_obj_new_float(INTERVAL_DEFAULT);
- }
-
- if (args[ARG_window].u_obj == MP_OBJ_NULL) {
- args[ARG_window].u_obj = mp_obj_new_float(WINDOW_DEFAULT);
- }
-
- const mp_float_t interval = mp_obj_float_get(args[ARG_interval].u_obj);
- if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) {
- mp_raise_ValueError_varg(translate("interval must be in range %s-%s"), INTERVAL_MIN_STRING, INTERVAL_MAX_STRING);
- }
-
- const mp_float_t window = mp_obj_float_get(args[ARG_window].u_obj);
- if (window > interval) {
- mp_raise_ValueError(translate("window must be <= interval"));
- }
-
- return common_hal_bleio_scanner_scan(self, timeout, interval, window);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_scanner_scan_obj, 2, bleio_scanner_scan);
-
-
-STATIC const mp_rom_map_elem_t bleio_scanner_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&bleio_scanner_scan_obj) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(bleio_scanner_locals_dict, bleio_scanner_locals_dict_table);
-
-const mp_obj_type_t bleio_scanner_type = {
- { &mp_type_type },
- .name = MP_QSTR_Scanner,
- .make_new = bleio_scanner_make_new,
- .locals_dict = (mp_obj_dict_t*)&bleio_scanner_locals_dict
-};
diff --git a/shared-bindings/_bleio/Service.c b/shared-bindings/_bleio/Service.c
index c9b828807..3e1ad7088 100644
--- a/shared-bindings/_bleio/Service.c
+++ b/shared-bindings/_bleio/Service.c
@@ -29,54 +29,38 @@
#include "py/objproperty.h"
#include "py/runtime.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"
//| .. currentmodule:: _bleio
//|
-//| :class:`Service` -- BLE service
+//| :class:`Service` -- BLE GATT Service
//| =========================================================
//|
//| Stores information about a BLE service and its characteristics.
//|
-//| .. class:: Service
+//| .. class:: Service(uuid, *, secondary=False)
//|
-//| There is no regular constructor for a Service. A new local Service can be created
-//| and attached to a Peripheral by calling `add_to_peripheral()`.
-//| Remote Service objects are created by `Central.discover_remote_services()`
-//| or `Peripheral.discover_remote_services()`.
+//| Create a new Service identified by the specified UUID. It can be accessed by all
+//| connections. This is known as a Service server. Client Service objects are created via
+//| `Connection.discover_remote_services`.
//|
-//| .. classmethod:: add_to_peripheral(peripheral, uuid, *, secondary=False)
+//| To mark the Service as secondary, pass `True` as :py:data:`secondary`.
//|
-//| Create a new Service object, identified by the specified UUID, and add it
-//| to the given Peripheral.
-//|
-//| To mark the service as secondary, pass `True` as :py:data:`secondary`.
-//|
-//| :param Peripheral peripheral: The peripheral that will provide this service
-//| :param UUID uuid: The uuid of the service
-//| :param bool secondary: If the service is a secondary one
+//| :param UUID uuid: The uuid of the service
+//| :param bool secondary: If the service is a secondary one
//
-//| :return: the new Service
+//| :return: the new Service
//|
-STATIC mp_obj_t bleio_service_add_to_peripheral(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- // class is arg[0], which we can ignore.
-
- enum { ARG_peripheral, ARG_uuid, ARG_secondary };
+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_secondary };
static const mp_arg_t allowed_args[] = {
- { MP_QSTR_peripheral, MP_ARG_REQUIRED | MP_ARG_OBJ,},
{ MP_QSTR_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_secondary, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- const mp_obj_t peripheral_obj = args[ARG_peripheral].u_obj;
- if (!MP_OBJ_IS_TYPE(peripheral_obj, &bleio_peripheral_type)) {
- mp_raise_ValueError(translate("Expected a Peripheral"));
- }
+ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
const mp_obj_t uuid_obj = args[ARG_uuid].u_obj;
if (!MP_OBJ_IS_TYPE(uuid_obj, &bleio_uuid_type)) {
@@ -88,19 +72,15 @@ STATIC mp_obj_t bleio_service_add_to_peripheral(size_t n_args, const mp_obj_t *p
bleio_service_obj_t *service = m_new_obj(bleio_service_obj_t);
service->base.type = &bleio_service_type;
- common_hal_bleio_service_construct(
- service, MP_OBJ_TO_PTR(peripheral_obj), MP_OBJ_TO_PTR(uuid_obj), is_secondary);
-
- common_hal_bleio_peripheral_add_service(peripheral_obj, service);
+ common_hal_bleio_service_construct(service, MP_OBJ_TO_PTR(uuid_obj), is_secondary);
return MP_OBJ_FROM_PTR(service);
}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_service_add_to_peripheral_fun_obj, 3, bleio_service_add_to_peripheral);
-STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(bleio_service_add_to_peripheral_obj, MP_ROM_PTR(&bleio_service_add_to_peripheral_fun_obj));
//| .. attribute:: characteristics
//|
-//| A tuple of :py:class:`Characteristic` designating the characteristics that are offered by this service. (read-only)
+//| A tuple of :py:class:`Characteristic` designating the characteristics that are offered by
+//| this service. (read-only)
//|
STATIC mp_obj_t bleio_service_get_characteristics(mp_obj_t self_in) {
bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -156,7 +136,8 @@ const mp_obj_property_t bleio_service_secondary_obj = {
//| .. attribute:: uuid
//|
//| The UUID of this service. (read-only)
-//| Will be ``None`` if the 128-bit UUID for this service is not known.
+//|
+//| Will be ``None`` if the 128-bit UUID for this service is not known.
//|
STATIC mp_obj_t bleio_service_get_uuid(mp_obj_t self_in) {
bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in);
@@ -175,10 +156,10 @@ const mp_obj_property_t bleio_service_uuid_obj = {
STATIC const mp_rom_map_elem_t bleio_service_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_add_to_peripheral), MP_ROM_PTR(&bleio_service_add_to_peripheral_obj) },
{ MP_ROM_QSTR(MP_QSTR_characteristics), MP_ROM_PTR(&bleio_service_characteristics_obj) },
{ MP_ROM_QSTR(MP_QSTR_secondary), MP_ROM_PTR(&bleio_service_secondary_obj) },
{ MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_service_uuid_obj) },
+ { MP_ROM_QSTR(MP_QSTR_remote), MP_ROM_PTR(&bleio_service_remote_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_service_locals_dict, bleio_service_locals_dict_table);
@@ -196,6 +177,25 @@ STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_pr
const mp_obj_type_t bleio_service_type = {
{ &mp_type_type },
.name = MP_QSTR_Service,
+ .make_new = bleio_service_make_new,
.print = bleio_service_print,
.locals_dict = (mp_obj_dict_t*)&bleio_service_locals_dict
};
+
+// Helper for classes that store lists of services.
+mp_obj_tuple_t* service_linked_list_to_tuple(bleio_service_obj_t * services) {
+ // Return list as a tuple so user won't be able to change it.
+ bleio_service_obj_t *head = services;
+ size_t len = 0;
+ while (head != NULL) {
+ len++;
+ head = head->next;
+ }
+ mp_obj_tuple_t * t = MP_OBJ_TO_PTR(mp_obj_new_tuple(len, NULL));
+ head = services;
+ for (int32_t i = len - 1; i >= 0; i--) {
+ t->items[i] = MP_OBJ_FROM_PTR(head);
+ head = head->next;
+ }
+ return t;
+}
diff --git a/shared-bindings/_bleio/Service.h b/shared-bindings/_bleio/Service.h
index e061bcffc..273c6bd98 100644
--- a/shared-bindings/_bleio/Service.h
+++ b/shared-bindings/_bleio/Service.h
@@ -28,16 +28,24 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
-#include "common-hal/_bleio/Peripheral.h"
+#include "common-hal/_bleio/Characteristic.h"
+#include "common-hal/_bleio/Connection.h"
#include "common-hal/_bleio/Service.h"
+#include "py/objtuple.h"
+
const mp_obj_type_t bleio_service_type;
-extern void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_peripheral_obj_t *peripheral, bleio_uuid_obj_t *uuid, bool is_secondary);
+// Private version that doesn't allocate on the heap
+extern uint32_t _common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary, mp_obj_list_t * characteristic_list);
+extern void common_hal_bleio_service_construct(bleio_service_obj_t *self, bleio_uuid_obj_t *uuid, bool is_secondary);
+extern void common_hal_bleio_service_from_remote_service(bleio_service_obj_t *self, bleio_connection_obj_t* connection, bleio_uuid_obj_t *uuid, 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_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic);
+extern void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *initial_value_bufinfo);
+
+mp_obj_tuple_t* service_linked_list_to_tuple(bleio_service_obj_t * services);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H
diff --git a/shared-bindings/_bleio/UUID.c b/shared-bindings/_bleio/UUID.c
index 3c0889aad..dd3415902 100644
--- a/shared-bindings/_bleio/UUID.c
+++ b/shared-bindings/_bleio/UUID.c
@@ -156,9 +156,10 @@ STATIC mp_obj_t bleio_uuid_get_uuid128(mp_obj_t self_in) {
bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in);
uint8_t uuid128[16];
- if (!common_hal_bleio_uuid_get_uuid128(self, uuid128)) {
+ if (common_hal_bleio_uuid_get_size(self) != 128) {
mp_raise_AttributeError(translate("not a 128-bit UUID"));
}
+ common_hal_bleio_uuid_get_uuid128(self, uuid128);
return mp_obj_new_bytes(uuid128, 16);
}
@@ -192,10 +193,42 @@ const mp_obj_property_t bleio_uuid_size_obj = {
(mp_obj_t)&mp_const_none_obj},
};
+
+//| .. method:: pack_into(buffer, offset=0)
+//|
+//| Packs the UUID into the given buffer at the given offset.
+//|
+STATIC mp_obj_t bleio_uuid_pack_into(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+
+ enum { ARG_buffer, ARG_offset };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_buffer, MP_ARG_OBJ | MP_ARG_REQUIRED },
+ { MP_QSTR_offset, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE);
+
+ size_t offset = args[ARG_offset].u_int;
+ if (offset + common_hal_bleio_uuid_get_size(self) / 8 > bufinfo.len) {
+ mp_raise_ValueError(translate("Buffer + offset too small %d %d %d"));
+ }
+
+ common_hal_bleio_uuid_pack_into(self, bufinfo.buf + offset);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_uuid_pack_into_obj, 2, bleio_uuid_pack_into);
+
STATIC const mp_rom_map_elem_t bleio_uuid_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_uuid16), MP_ROM_PTR(&bleio_uuid_uuid16_obj) },
{ MP_ROM_QSTR(MP_QSTR_uuid128), MP_ROM_PTR(&bleio_uuid_uuid128_obj) },
{ MP_ROM_QSTR(MP_QSTR_size), MP_ROM_PTR(&bleio_uuid_size_obj) },
+ { MP_ROM_QSTR(MP_QSTR_pack_into), MP_ROM_PTR(&bleio_uuid_pack_into_obj) },
};
STATIC MP_DEFINE_CONST_DICT(bleio_uuid_locals_dict, bleio_uuid_locals_dict_table);
@@ -231,13 +264,19 @@ STATIC mp_obj_t bleio_uuid_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
//|
STATIC mp_obj_t bleio_uuid_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
switch (op) {
- // Two UUID's are equal if their uuid16 values and uuid128 references match.
+ // Two UUID's are equal if their uuid16 values match or their uuid128 values match.
case MP_BINARY_OP_EQUAL:
if (MP_OBJ_IS_TYPE(rhs_in, &bleio_uuid_type)) {
- return mp_obj_new_bool(
- common_hal_bleio_uuid_get_uuid16(lhs_in) == common_hal_bleio_uuid_get_uuid16(rhs_in) &&
- common_hal_bleio_uuid_get_uuid128_reference(lhs_in) ==
- common_hal_bleio_uuid_get_uuid128_reference(rhs_in));
+ if (common_hal_bleio_uuid_get_size(lhs_in) == 16 &&
+ common_hal_bleio_uuid_get_size(rhs_in) == 16) {
+ return mp_obj_new_bool(common_hal_bleio_uuid_get_uuid16(lhs_in) ==
+ common_hal_bleio_uuid_get_uuid16(rhs_in));
+ }
+ uint8_t lhs[16];
+ uint8_t rhs[16];
+ common_hal_bleio_uuid_get_uuid128(lhs_in, lhs);
+ common_hal_bleio_uuid_get_uuid128(rhs_in, rhs);
+ return mp_obj_new_bool(memcmp(lhs, rhs, sizeof(lhs)) == 0);
} else {
return mp_const_false;
}
diff --git a/shared-bindings/_bleio/UUID.h b/shared-bindings/_bleio/UUID.h
index 46ac54ff3..1490737a7 100644
--- a/shared-bindings/_bleio/UUID.h
+++ b/shared-bindings/_bleio/UUID.h
@@ -34,10 +34,11 @@ void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t
extern const mp_obj_type_t bleio_uuid_type;
-extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, uint8_t uuid128[]);
+extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, const uint8_t uuid128[]);
extern uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self);
extern bool common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]);
-extern uint32_t common_hal_bleio_uuid_get_uuid128_reference(bleio_uuid_obj_t *self);
extern uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self);
+void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t* buf);
+
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H
diff --git a/shared-bindings/_bleio/__init__.c b/shared-bindings/_bleio/__init__.c
index f207be8cf..0c6ebb973 100644
--- a/shared-bindings/_bleio/__init__.c
+++ b/shared-bindings/_bleio/__init__.c
@@ -29,13 +29,12 @@
#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/Connection.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/ScanResults.h"
#include "shared-bindings/_bleio/Service.h"
#include "shared-bindings/_bleio/UUID.h"
@@ -64,34 +63,32 @@
//| Address
//| Adapter
//| Attribute
-//| Central
//| Characteristic
//| CharacteristicBuffer
+//| Connection
//| Descriptor
-//| Peripheral
//| ScanEntry
-//| Scanner
+//| ScanResults
//| Service
//| UUID
//|
//| .. attribute:: adapter
//|
-//| BLE Adapter information, such as enabled state as well as MAC
-//| address.
+//| BLE Adapter used to manage device discovery and connections.
//| This object is the sole instance of `_bleio.Adapter`.
//|
STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__bleio) },
+ { MP_ROM_QSTR(MP_QSTR_Adapter), MP_ROM_PTR(&bleio_adapter_type) },
{ 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_Connection), MP_ROM_PTR(&bleio_connection_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_ScanResults), MP_ROM_PTR(&bleio_scanresults_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) },
diff --git a/shared-bindings/_bleio/__init__.h b/shared-bindings/_bleio/__init__.h
index 67379ae2e..92c695fa6 100644
--- a/shared-bindings/_bleio/__init__.h
+++ b/shared-bindings/_bleio/__init__.h
@@ -36,17 +36,19 @@
#include "common-hal/_bleio/__init__.h"
#include "common-hal/_bleio/Adapter.h"
-extern const super_adapter_obj_t common_hal_bleio_adapter_obj;
+extern bleio_adapter_obj_t common_hal_bleio_adapter_obj;
-extern void common_hal_bleio_check_connected(uint16_t conn_handle);
+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_service_list(mp_obj_t device);
-extern void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t service_uuids_whitelist);
+uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device);
+mp_obj_list_t *common_hal_bleio_device_get_remote_service_list(mp_obj_t device);
+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);
+size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_t* buf, size_t len);
+void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo);
+size_t common_hal_bleio_gattc_read(uint16_t handle, uint16_t conn_handle, uint8_t* buf, size_t len);
+void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response);
+void common_hal_bleio_gc_collect(void);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO___INIT___H
diff --git a/shared-module/_bleio/ScanEntry.c b/shared-module/_bleio/ScanEntry.c
index 8dfa17f31..785209c4a 100644
--- a/shared-module/_bleio/ScanEntry.c
+++ b/shared-module/_bleio/ScanEntry.c
@@ -37,9 +37,50 @@ mp_obj_t common_hal_bleio_scanentry_get_address(bleio_scanentry_obj_t *self) {
}
mp_obj_t common_hal_bleio_scanentry_get_advertisement_bytes(bleio_scanentry_obj_t *self) {
- return self->data;
+ return MP_OBJ_FROM_PTR(self->data);
}
mp_int_t common_hal_bleio_scanentry_get_rssi(bleio_scanentry_obj_t *self) {
return self->rssi;
}
+
+bool common_hal_bleio_scanentry_get_connectable(bleio_scanentry_obj_t *self) {
+ return self->connectable;
+}
+
+bool common_hal_bleio_scanentry_get_scan_response(bleio_scanentry_obj_t *self) {
+ return self->scan_response;
+}
+
+bool bleio_scanentry_data_matches(const uint8_t* data, size_t len, const uint8_t* prefixes, size_t prefixes_length, bool any) {
+ if (prefixes_length == 0) {
+ return true;
+ }
+ size_t i = 0;
+ while(i < prefixes_length) {
+ uint8_t prefix_length = prefixes[i];
+ i += 1;
+ size_t j = 0;
+ while (j < len) {
+ uint8_t structure_length = data[j];
+ j += 1;
+ if (structure_length == 0) {
+ break;
+ }
+ if (structure_length >= prefix_length && memcmp(data + j, prefixes + i, prefix_length) == 0) {
+ if (any) {
+ return true;
+ }
+ } else if (!any) {
+ return false;
+ }
+ j += structure_length;
+ }
+ i += prefix_length;
+ }
+ return !any;
+}
+
+bool common_hal_bleio_scanentry_matches(bleio_scanentry_obj_t *self, const uint8_t* prefixes, size_t prefixes_len, bool all) {
+ return bleio_scanentry_data_matches(self->data->data, self->data->len, prefixes, prefixes_len, !all);
+}
diff --git a/shared-module/_bleio/ScanEntry.h b/shared-module/_bleio/ScanEntry.h
index 1e798d78f..94361a397 100644
--- a/shared-module/_bleio/ScanEntry.h
+++ b/shared-module/_bleio/ScanEntry.h
@@ -29,14 +29,19 @@
#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H
#include "py/obj.h"
+#include "py/objstr.h"
#include "shared-bindings/_bleio/Address.h"
typedef struct {
mp_obj_base_t base;
bool connectable;
+ bool scan_response;
int8_t rssi;
bleio_address_obj_t *address;
- mp_obj_t data;
+ mp_obj_str_t *data;
+ uint64_t time_received;
} bleio_scanentry_obj_t;
+bool bleio_scanentry_data_matches(const uint8_t* data, size_t len, const uint8_t* prefixes, size_t prefix_length, bool any);
+
#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H
diff --git a/shared-module/_bleio/ScanResults.c b/shared-module/_bleio/ScanResults.c
new file mode 100644
index 000000000..7ea0c165f
--- /dev/null
+++ b/shared-module/_bleio/ScanResults.c
@@ -0,0 +1,139 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ * Copyright (c) 2017 Glenn Ruben Bakke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+
+#include "lib/utils/interrupt_char.h"
+#include "py/objstr.h"
+#include "py/runtime.h"
+#include "shared-bindings/_bleio/ScanEntry.h"
+#include "shared-bindings/_bleio/ScanResults.h"
+
+bleio_scanresults_obj_t* shared_module_bleio_new_scanresults(size_t buffer_size, uint8_t* prefixes, size_t prefixes_len, mp_int_t minimum_rssi) {
+ bleio_scanresults_obj_t* self = m_new_obj(bleio_scanresults_obj_t);
+ self->base.type = &bleio_scanresults_type;
+ ringbuf_alloc(&self->buf, buffer_size, false);
+ self->prefixes = prefixes;
+ self->prefix_length = prefixes_len;
+ self->minimum_rssi = minimum_rssi;
+ return self;
+}
+
+mp_obj_t common_hal_bleio_scanresults_next(bleio_scanresults_obj_t *self) {
+ while (ringbuf_count(&self->buf) == 0 && !self->done && !mp_hal_is_interrupted()) {
+ RUN_BACKGROUND_TASKS;
+ }
+ if (ringbuf_count(&self->buf) == 0 || mp_hal_is_interrupted()) {
+ return mp_const_none;
+ }
+
+ // Create a ScanEntry out of the data on the buffer.
+ uint8_t type = ringbuf_get(&self->buf);
+ bool connectable = (type & (1 << 0)) != 0;
+ bool scan_response = (type & (1 << 1)) != 0;
+ uint64_t ticks_ms;
+ ringbuf_get_n(&self->buf, (uint8_t*) &ticks_ms, sizeof(ticks_ms));
+ uint8_t rssi = ringbuf_get(&self->buf);
+ uint8_t peer_addr[NUM_BLEIO_ADDRESS_BYTES];
+ ringbuf_get_n(&self->buf, peer_addr, sizeof(peer_addr));
+ uint8_t addr_type = ringbuf_get(&self->buf);
+ uint16_t len;
+ ringbuf_get_n(&self->buf, (uint8_t*) &len, sizeof(len));
+
+ mp_obj_str_t *o = MP_OBJ_TO_PTR(mp_obj_new_bytes_of_zeros(len));
+ ringbuf_get_n(&self->buf, (uint8_t*) o->data, len);
+
+ bleio_scanentry_obj_t *entry = m_new_obj(bleio_scanentry_obj_t);
+ entry->base.type = &bleio_scanentry_type;
+ entry->rssi = rssi;
+
+ bleio_address_obj_t *address = m_new_obj(bleio_address_obj_t);
+ address->base.type = &bleio_address_type;
+ common_hal_bleio_address_construct(MP_OBJ_TO_PTR(address), peer_addr, addr_type);
+ entry->address = address;
+
+ entry->data = o;
+ entry->time_received = ticks_ms;
+ entry->connectable = connectable;
+ entry->scan_response = scan_response;
+
+ return MP_OBJ_FROM_PTR(entry);
+}
+
+
+void shared_module_bleio_scanresults_append(bleio_scanresults_obj_t* self,
+ uint64_t ticks_ms,
+ bool connectable,
+ bool scan_response,
+ int8_t rssi,
+ uint8_t *peer_addr,
+ uint8_t addr_type,
+ uint8_t *data,
+ uint16_t len) {
+ int32_t packet_size = sizeof(uint8_t) + sizeof(ticks_ms) + sizeof(rssi) + NUM_BLEIO_ADDRESS_BYTES +
+ sizeof(addr_type) + sizeof(len) + len;
+ int32_t empty_space = self->buf.size - ringbuf_count(&self->buf);
+ if (packet_size >= empty_space) {
+ // We can't fit the packet so skip it.
+ return;
+ }
+ // Filter the packet.
+ if (rssi < self->minimum_rssi) {
+ return;
+ }
+
+ // If any prefixes are provided, then only include packets that include at least one of them.
+ if (!bleio_scanentry_data_matches(data, len, self->prefixes, self->prefix_length, true)) {
+ return;
+ }
+ uint8_t type = 0;
+ if (connectable) {
+ type |= 1 << 0;
+ }
+ if (scan_response) {
+ type |= 1 << 1;
+ }
+
+ // Add the packet to the buffer.
+ ringbuf_put(&self->buf, type);
+ ringbuf_put_n(&self->buf, (uint8_t*) &ticks_ms, sizeof(ticks_ms));
+ ringbuf_put(&self->buf, rssi);
+ ringbuf_put_n(&self->buf, peer_addr, NUM_BLEIO_ADDRESS_BYTES);
+ ringbuf_put(&self->buf, addr_type);
+ ringbuf_put_n(&self->buf, (uint8_t*) &len, sizeof(len));
+ ringbuf_put_n(&self->buf, data, len);
+}
+
+bool shared_module_bleio_scanresults_get_done(bleio_scanresults_obj_t* self) {
+ return self->done;
+}
+
+void shared_module_bleio_scanresults_set_done(bleio_scanresults_obj_t* self, bool done) {
+ self->done = done;
+ self->common_hal_data = NULL;
+}
diff --git a/shared-module/_bleio/ScanResults.h b/shared-module/_bleio/ScanResults.h
new file mode 100644
index 000000000..8912357a9
--- /dev/null
+++ b/shared-module/_bleio/ScanResults.h
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2018 Artur Pacholec
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANRESULTS_H
+#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANRESULTS_H
+
+#include <stdint.h>
+
+#include "py/obj.h"
+#include "py/ringbuf.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ // Pointers that needs to live until the scan is done.
+ void* common_hal_data;
+ ringbuf_t buf;
+ // Prefixes is a length encoded array of prefixes.
+ uint8_t* prefixes;
+ size_t prefix_length;
+ mp_int_t minimum_rssi;
+ bool active;
+ bool done;
+} bleio_scanresults_obj_t;
+
+bleio_scanresults_obj_t* shared_module_bleio_new_scanresults(size_t buffer_size, uint8_t* prefixes, size_t prefixes_len, mp_int_t minimum_rssi);
+
+bool shared_module_bleio_scanresults_get_done(bleio_scanresults_obj_t* self);
+void shared_module_bleio_scanresults_set_done(bleio_scanresults_obj_t* self, bool done);
+
+void shared_module_bleio_scanresults_append(bleio_scanresults_obj_t* self,
+ uint64_t ticks_ms,
+ bool connectable,
+ bool scan_result,
+ int8_t rssi,
+ uint8_t *peer_addr,
+ uint8_t addr_type,
+ uint8_t* data,
+ uint16_t len);
+
+#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANRESULTS_H
diff --git a/supervisor/shared/autoreload.c b/supervisor/shared/autoreload.c
index 14b21902c..a6212c1a9 100644
--- a/supervisor/shared/autoreload.c
+++ b/supervisor/shared/autoreload.c
@@ -76,3 +76,11 @@ void autoreload_stop() {
autoreload_delay_ms = 0;
reload_requested = false;
}
+
+void autoreload_now() {
+ if (!autoreload_enabled || autoreload_suspended || reload_requested) {
+ return;
+ }
+ mp_raise_reload_exception();
+ reload_requested = true;
+}
diff --git a/supervisor/shared/autoreload.h b/supervisor/shared/autoreload.h
index bcb100151..fbd482c19 100644
--- a/supervisor/shared/autoreload.h
+++ b/supervisor/shared/autoreload.h
@@ -43,4 +43,6 @@ bool autoreload_is_enabled(void);
void autoreload_suspend(void);
void autoreload_resume(void);
+void autoreload_now(void);
+
#endif // MICROPY_INCLUDED_SUPERVISOR_AUTORELOAD_H
diff --git a/supervisor/shared/bluetooth.c b/supervisor/shared/bluetooth.c
new file mode 100644
index 000000000..02258de74
--- /dev/null
+++ b/supervisor/shared/bluetooth.c
@@ -0,0 +1,340 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft 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 "extmod/vfs.h"
+#include "extmod/vfs_fat.h"
+
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Adapter.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+#include "shared-bindings/_bleio/Service.h"
+#include "shared-bindings/_bleio/UUID.h"
+
+#include "common-hal/_bleio/__init__.h"
+
+#include "supervisor/shared/autoreload.h"
+
+#include "py/mpstate.h"
+
+bleio_service_obj_t supervisor_ble_service;
+bleio_uuid_obj_t supervisor_ble_service_uuid;
+bleio_characteristic_obj_t supervisor_ble_version_characteristic;
+bleio_uuid_obj_t supervisor_ble_version_uuid;
+bleio_characteristic_obj_t supervisor_ble_filename_characteristic;
+bleio_uuid_obj_t supervisor_ble_filename_uuid;
+bleio_characteristic_obj_t supervisor_ble_length_characteristic;
+bleio_uuid_obj_t supervisor_ble_length_uuid;
+bleio_characteristic_obj_t supervisor_ble_contents_characteristic;
+bleio_uuid_obj_t supervisor_ble_contents_uuid;
+const uint8_t circuitpython_base_uuid[16] = {0x6e, 0x68, 0x74, 0x79, 0x50, 0x74, 0x69, 0x75, 0x63, 0x72, 0x69, 0x43, 0x00, 0x00, 0xaf, 0xad };
+uint8_t circuitpython_advertising_data[] = { 0x02, 0x01, 0x06, 0x02, 0x0a, 0x00, 0x11, 0x07, 0x6e, 0x68, 0x74, 0x79, 0x50, 0x74, 0x69, 0x75, 0x63, 0x72, 0x69, 0x43, 0x00, 0x01, 0xaf, 0xad, 0x06, 0x08, 0x43, 0x49, 0x52, 0x43, 0x55 };
+uint8_t circuitpython_scan_response_data[15] = {0x0e, 0x09, 0x43, 0x49, 0x52, 0x43, 0x55, 0x49, 0x54, 0x50, 0x59, 0x00, 0x00, 0x00, 0x00};
+mp_obj_list_t service_list;
+mp_obj_t service_list_items[1];
+mp_obj_list_t characteristic_list;
+mp_obj_t characteristic_list_items[4];
+
+void supervisor_bluetooth_start_advertising(void) {
+ bool is_connected = common_hal_bleio_adapter_get_connected(&common_hal_bleio_adapter_obj);
+ if (is_connected) {
+ return;
+ }
+ // TODO: switch to Adafruit short UUID for the advertisement and add manufacturing data to distinguish ourselves from arduino.
+ _common_hal_bleio_adapter_start_advertising(&common_hal_bleio_adapter_obj,
+ true,
+ 1.0,
+ circuitpython_advertising_data,
+ sizeof(circuitpython_advertising_data),
+ circuitpython_scan_response_data,
+ sizeof(circuitpython_scan_response_data));
+}
+
+void supervisor_start_bluetooth(void) {
+ common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, true);
+
+ supervisor_ble_service_uuid.base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(&supervisor_ble_service_uuid, 0x0100, circuitpython_base_uuid);
+
+ // We know we'll only be 1 characteristic so we can statically allocate it.
+ characteristic_list.base.type = &mp_type_list;
+ characteristic_list.alloc = sizeof(characteristic_list_items) / sizeof(characteristic_list_items[0]);
+ characteristic_list.len = 0;
+ characteristic_list.items = characteristic_list_items;
+ mp_seq_clear(characteristic_list.items, 0, characteristic_list.alloc, sizeof(*characteristic_list.items));
+
+ _common_hal_bleio_service_construct(&supervisor_ble_service, &supervisor_ble_service_uuid, false /* is secondary */, &characteristic_list);
+
+ // File length
+ supervisor_ble_version_uuid.base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(&supervisor_ble_version_uuid, 0x0203, circuitpython_base_uuid);
+ common_hal_bleio_characteristic_construct(&supervisor_ble_version_characteristic,
+ &supervisor_ble_service,
+ 0, // handle (for remote only)
+ &supervisor_ble_version_uuid,
+ CHAR_PROP_READ,
+ SECURITY_MODE_OPEN,
+ SECURITY_MODE_NO_ACCESS,
+ 4, // max length
+ true, // fixed length
+ NULL); // no initial value
+
+ uint32_t version = 1;
+ mp_buffer_info_t bufinfo;
+ bufinfo.buf = &version;
+ bufinfo.len = sizeof(version);
+ common_hal_bleio_characteristic_set_value(&supervisor_ble_version_characteristic, &bufinfo);
+
+ // Active filename.
+ supervisor_ble_filename_uuid.base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(&supervisor_ble_filename_uuid, 0x0200, circuitpython_base_uuid);
+ common_hal_bleio_characteristic_construct(&supervisor_ble_filename_characteristic,
+ &supervisor_ble_service,
+ 0, // handle (for remote only)
+ &supervisor_ble_filename_uuid,
+ CHAR_PROP_READ | CHAR_PROP_WRITE,
+ SECURITY_MODE_OPEN,
+ SECURITY_MODE_OPEN,
+ 500, // max length
+ false, // fixed length
+ NULL); // no initial value
+
+ char code_py[] = "/code.py";
+ bufinfo.buf = code_py;
+ bufinfo.len = sizeof(code_py);
+ common_hal_bleio_characteristic_set_value(&supervisor_ble_filename_characteristic, &bufinfo);
+
+ // File length
+ supervisor_ble_length_uuid.base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(&supervisor_ble_length_uuid, 0x0202, circuitpython_base_uuid);
+ common_hal_bleio_characteristic_construct(&supervisor_ble_length_characteristic,
+ &supervisor_ble_service,
+ 0, // handle (for remote only)
+ &supervisor_ble_length_uuid,
+ CHAR_PROP_NOTIFY | CHAR_PROP_READ,
+ SECURITY_MODE_OPEN,
+ SECURITY_MODE_NO_ACCESS,
+ 4, // max length
+ true, // fixed length
+ NULL); // no initial value
+
+ // File actions
+ supervisor_ble_contents_uuid.base.type = &bleio_uuid_type;
+ common_hal_bleio_uuid_construct(&supervisor_ble_contents_uuid, 0x0201, circuitpython_base_uuid);
+ common_hal_bleio_characteristic_construct(&supervisor_ble_contents_characteristic,
+ &supervisor_ble_service,
+ 0, // handle (for remote only)
+ &supervisor_ble_contents_uuid,
+ CHAR_PROP_NOTIFY | CHAR_PROP_WRITE_NO_RESPONSE | CHAR_PROP_WRITE,
+ SECURITY_MODE_OPEN,
+ SECURITY_MODE_OPEN,
+ 500, // max length
+ false, // fixed length
+ NULL); // no initial value
+
+ supervisor_bluetooth_start_advertising();
+ vm_used_ble = false;
+}
+
+FIL active_file;
+volatile bool new_filename;
+volatile bool run_ble_background;
+bool was_connected;
+
+void update_file_length(void) {
+ int32_t file_length = -1;
+ mp_buffer_info_t bufinfo;
+ bufinfo.buf = &file_length;
+ bufinfo.len = sizeof(file_length);
+ if (active_file.obj.fs != 0) {
+ file_length = (int32_t) f_size(&active_file);
+ }
+ common_hal_bleio_characteristic_set_value(&supervisor_ble_length_characteristic, &bufinfo);
+}
+
+void open_current_file(void) {
+ if (active_file.obj.fs != 0) {
+ return;
+ }
+ uint16_t max_len = supervisor_ble_filename_characteristic.max_length;
+ uint8_t path[max_len];
+ size_t length = common_hal_bleio_characteristic_get_value(&supervisor_ble_filename_characteristic, path, max_len - 1);
+ path[length] = '\0';
+
+ FATFS *fs = &((fs_user_mount_t *) MP_STATE_VM(vfs_mount_table)->obj)->fatfs;
+ f_open(fs, &active_file, (char*) path, FA_READ | FA_WRITE);
+
+ update_file_length();
+}
+
+void close_current_file(void) {
+ f_close(&active_file);
+}
+
+uint32_t current_command[1024 / sizeof(uint32_t)];
+volatile size_t current_offset;
+
+void supervisor_bluetooth_background(void) {
+ if (!run_ble_background) {
+ return;
+ }
+ bool is_connected = common_hal_bleio_adapter_get_connected(&common_hal_bleio_adapter_obj);
+ if (!was_connected && is_connected) {
+ open_current_file();
+ } else if (was_connected && !is_connected) {
+ close_current_file();
+ new_filename = false;
+ }
+ was_connected = is_connected;
+ run_ble_background = false;
+ if (!is_connected) {
+ supervisor_bluetooth_start_advertising();
+ return;
+ }
+ if (new_filename) {
+ close_current_file();
+ open_current_file();
+
+ new_filename = false;
+ // get length and set the characteristic for it
+ }
+ uint16_t current_length = ((uint16_t*) current_command)[0];
+ if (current_length > 0 && current_length == current_offset) {
+ uint16_t command = ((uint16_t *) current_command)[1];
+
+ if (command == 1) {
+ uint16_t max_len = 20; //supervisor_ble_contents_characteristic.max_length;
+ uint8_t buf[max_len];
+ mp_buffer_info_t bufinfo;
+ bufinfo.buf = buf;
+ f_lseek(&active_file, 0);
+ while (f_read(&active_file, buf, max_len, &bufinfo.len) == FR_OK) {
+ if (bufinfo.len == 0) {
+ break;
+ }
+ common_hal_bleio_characteristic_set_value(&supervisor_ble_contents_characteristic, &bufinfo);
+ }
+ } else if (command == 2) { // patch
+ uint32_t offset = current_command[1];
+ uint32_t remove_length = current_command[2];
+ uint32_t insert_length = current_command[3];
+ uint32_t file_length = (int32_t) f_size(&active_file);
+ //uint32_t data_shift_length = fileLength - offset - remove_length;
+ int32_t data_shift = insert_length - remove_length;
+ uint32_t new_length = file_length + data_shift;
+
+ // TODO: Make these loops smarter to read and write on sector boundaries.
+ if (data_shift < 0) {
+ for (uint32_t shift_offset = offset + insert_length; shift_offset < new_length; shift_offset++) {
+ uint8_t data;
+ UINT actual;
+ f_lseek(&active_file, shift_offset - data_shift);
+ f_read(&active_file, &data, 1, &actual);
+ f_lseek(&active_file, shift_offset);
+ f_write(&active_file, &data, 1, &actual);
+ }
+ f_truncate(&active_file);
+ } else if (data_shift > 0) {
+ f_lseek(&active_file, file_length);
+ // Fill end with 0xff so we don't need to erase.
+ uint8_t data = 0xff;
+ for (size_t i = 0; i < (size_t) data_shift; i++) {
+ UINT actual;
+ f_write(&active_file, &data, 1, &actual);
+ }
+ for (uint32_t shift_offset = new_length - 1; shift_offset >= offset + insert_length ; shift_offset--) {
+ UINT actual;
+ f_lseek(&active_file, shift_offset - data_shift);
+ f_read(&active_file, &data, 1, &actual);
+ f_lseek(&active_file, shift_offset);
+ f_write(&active_file, &data, 1, &actual);
+ }
+ }
+
+ f_lseek(&active_file, offset);
+ uint8_t* data = (uint8_t *) (current_command + 4);
+ UINT written;
+ f_write(&active_file, data, insert_length, &written);
+ f_sync(&active_file);
+ // Notify the new file length.
+ update_file_length();
+
+ // Trigger an autoreload
+ autoreload_now();
+ }
+ current_offset = 0;
+ }
+}
+
+// This happens in an interrupt so we need to be quick.
+bool supervisor_bluetooth_hook(ble_evt_t *ble_evt) {
+ // Catch writes to filename or contents. Length is read-only.
+
+ bool done = false;
+ switch (ble_evt->header.evt_id) {
+ case BLE_GAP_EVT_CONNECTED:
+ // We run our background task even if it wasn't us connected to because we may want to
+ // advertise if the user code stopped advertising.
+ run_ble_background = true;
+ break;
+ case BLE_GAP_EVT_DISCONNECTED:
+ run_ble_background = true;
+ break;
+ case BLE_GATTS_EVT_WRITE: {
+ // A client wrote to a characteristic.
+
+ ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write;
+ // Event handle must match the handle for my characteristic.
+ if (evt_write->handle == supervisor_ble_contents_characteristic.handle) {
+ // Handle events
+ //write_to_ringbuf(self, evt_write->data, evt_write->len);
+ // First packet includes a uint16_t le for length at the start.
+ uint16_t current_length = ((uint16_t*) current_command)[0];
+ memcpy(((uint8_t*) current_command) + current_offset, evt_write->data, evt_write->len);
+ current_offset += evt_write->len;
+ current_length = ((uint16_t*) current_command)[0];
+ if (current_offset == current_length) {
+ run_ble_background = true;
+ done = true;
+ }
+ } else if (evt_write->handle == supervisor_ble_filename_characteristic.handle) {
+ new_filename = true;
+ run_ble_background = true;
+ done = true;
+ } else {
+ return done;
+ }
+ break;
+ }
+
+ default:
+ // For debugging.
+ // mp_printf(&mp_plat_print, "Unhandled peripheral event: 0x%04x\n", ble_evt->header.evt_id);
+ break;
+ }
+ return done;
+}
diff --git a/supervisor/shared/bluetooth.h b/supervisor/shared/bluetooth.h
new file mode 100644
index 000000000..7ebcb953f
--- /dev/null
+++ b/supervisor/shared/bluetooth.h
@@ -0,0 +1,34 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft 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_SUPERVISOR_SHARED_BLUETOOTH_H
+#define MICROPY_INCLUDED_SUPERVISOR_SHARED_BLUETOOTH_H
+
+void supervisor_start_bluetooth(void);
+bool supervisor_bluetooth_hook(ble_evt_t *ble_evt);
+void supervisor_bluetooth_background(void);
+
+#endif \ No newline at end of file
diff --git a/supervisor/shared/external_flash/devices.h b/supervisor/shared/external_flash/devices.h
index 05091ad8c..08d0a78fd 100644
--- a/supervisor/shared/external_flash/devices.h
+++ b/supervisor/shared/external_flash/devices.h
@@ -300,6 +300,23 @@ typedef struct {
.write_status_register_split = false, \
}
+// Settings for the Winbond W25Q32JV-IQ 4MiB SPI flash.
+// Datasheet: https://www.mouser.com/datasheet/2/949/w25q32jv_revg_03272018_plus-1489806.pdf
+#define W25Q32JV_IQ {\
+ .total_size = (1 << 22), /* 4 MiB */ \
+ .start_up_time_us = 5000, \
+ .manufacturer_id = 0xef, \
+ .memory_type = 0x40, \
+ .capacity = 0x16, \
+ .max_clock_speed_mhz = 133, \
+ .quad_enable_bit_mask = 0x02, \
+ .has_sector_protection = false, \
+ .supports_fast_read = true, \
+ .supports_qspi = true, \
+ .supports_qspi_writes = true, \
+ .write_status_register_split = false, \
+}
+
// Settings for the Winbond W25Q64JV-IM 8MiB SPI flash. Note that JV-IQ has a different .memory_type (0x40)
// Datasheet: http://www.winbond.com/resource-files/w25q64jv%20revj%2003272018%20plus.pdf
#define W25Q64JV_IM {\
diff --git a/supervisor/shared/safe_mode.h b/supervisor/shared/safe_mode.h
index ee0723cff..8c5dcd9c5 100644
--- a/supervisor/shared/safe_mode.h
+++ b/supervisor/shared/safe_mode.h
@@ -37,7 +37,8 @@ typedef enum {
MICROPY_NLR_JUMP_FAIL,
MICROPY_FATAL_ERROR,
GC_ALLOC_OUTSIDE_VM,
- PROGRAMMATIC_SAFE_MODE
+ PROGRAMMATIC_SAFE_MODE,
+ NORDIC_SOFT_DEVICE_ASSERT
} safe_mode_t;
safe_mode_t wait_for_safe_mode_reset(void);
diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk
index 48697a94a..ad0f716fb 100644
--- a/supervisor/supervisor.mk
+++ b/supervisor/supervisor.mk
@@ -28,6 +28,11 @@ ifneq ($(SPI_FLASH_FILESYSTEM),)
CFLAGS += -DSPI_FLASH_FILESYSTEM=$(SPI_FLASH_FILESYSTEM) -DEXPRESS_BOARD
endif
+
+ifeq ($(CIRCUITPY_BLEIO),1)
+ SRC_SUPERVISOR += supervisor/shared/bluetooth.c
+endif
+
# Choose which flash filesystem impl to use.
# (Right now INTERNAL_FLASH_FILESYSTEM and SPI_FLASH_FILESYSTEM are mutually exclusive.
# But that might not be true in the future.)