summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Halbert <halbert@adafruit.com>2020-01-08 14:37:28 -0500
committerGitHub <noreply@github.com>2020-01-08 14:37:28 -0500
commit28c1e4f48e5edf16b3aedc0d25e8d01d014def5f (patch)
treec644bb87198113b849d272f84c90056e6fdab4fb
parent22644d33c93d8aa1e346fc23454a14c6d6c8b1f1 (diff)
parent7a94940c89398ac8a68b988bad498955001783cd (diff)
Merge pull request #2448 from tannewt/packet_buffer
Add PacketBuffer and MTU negotiation support.
-rw-r--r--locale/ID.po15
-rw-r--r--locale/circuitpython.pot15
-rw-r--r--locale/de_DE.po15
-rw-r--r--locale/en_US.po15
-rw-r--r--locale/en_x_pirate.po15
-rw-r--r--locale/es.po15
-rw-r--r--locale/fil.po15
-rw-r--r--locale/fr.po15
-rw-r--r--locale/it_IT.po15
-rw-r--r--locale/ko.po15
-rw-r--r--locale/pl.po15
-rw-r--r--locale/pt_BR.po15
-rw-r--r--locale/zh_Latn_pinyin.po15
-rw-r--r--ports/nrf/bluetooth/ble_drv.c2
-rw-r--r--ports/nrf/boards/common.template.ld8
-rw-r--r--ports/nrf/common-hal/_bleio/Adapter.c60
-rw-r--r--ports/nrf/common-hal/_bleio/Adapter.h2
-rw-r--r--ports/nrf/common-hal/_bleio/Characteristic.c2
-rw-r--r--ports/nrf/common-hal/_bleio/Connection.c41
-rw-r--r--ports/nrf/common-hal/_bleio/Connection.h1
-rw-r--r--ports/nrf/common-hal/_bleio/PacketBuffer.c335
-rw-r--r--ports/nrf/common-hal/_bleio/PacketBuffer.h51
-rw-r--r--ports/nrf/common-hal/_bleio/__init__.c3
-rw-r--r--py/circuitpy_defns.mk1
-rw-r--r--shared-bindings/_bleio/PacketBuffer.c201
-rw-r--r--shared-bindings/_bleio/PacketBuffer.h43
-rw-r--r--shared-bindings/_bleio/__init__.c5
27 files changed, 888 insertions, 62 deletions
diff --git a/locale/ID.po b/locale/ID.po
index 20662ae9d..e6d19cc2c 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: 2020-01-01 17:29-0500\n"
+"POT-Creation-Date: 2020-01-07 14:31-0800\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"
@@ -66,7 +66,8 @@ msgid "%q indices must be integers, not %s"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
+#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
+#: shared-bindings/displayio/Shape.c
#, fuzzy
msgid "%q must be >= 1"
msgstr "buffers harus mempunyai panjang yang sama"
@@ -377,6 +378,10 @@ msgstr ""
msgid "Buffer must be at least length 1"
msgstr ""
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Buffer too large and unable to allocate"
+msgstr ""
+
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
#, fuzzy, c-format
@@ -596,7 +601,7 @@ msgid "Expected a %q"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Descriptor.c
+#: shared-bindings/_bleio/Descriptor.c shared-bindings/_bleio/PacketBuffer.c
msgid "Expected a Characteristic"
msgstr ""
@@ -1325,6 +1330,10 @@ msgstr ""
"\n"
"Untuk menampilkan modul built-in silahkan ketik `help(\"modules\")`.\n"
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Writes not supported on Characteristic"
+msgstr ""
+
#: supervisor/shared/safe_mode.c
msgid "You are in safe mode: something unanticipated happened.\n"
msgstr ""
diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot
index 5cf44cc35..085101ff1 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: 2020-01-01 17:29-0500\n"
+"POT-Creation-Date: 2020-01-07 14:31-0800\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"
@@ -66,7 +66,8 @@ msgid "%q indices must be integers, not %s"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
+#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
+#: shared-bindings/displayio/Shape.c
msgid "%q must be >= 1"
msgstr ""
@@ -373,6 +374,10 @@ msgstr ""
msgid "Buffer must be at least length 1"
msgstr ""
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Buffer too large and unable to allocate"
+msgstr ""
+
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
#, c-format
@@ -585,7 +590,7 @@ msgid "Expected a %q"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Descriptor.c
+#: shared-bindings/_bleio/Descriptor.c shared-bindings/_bleio/PacketBuffer.c
msgid "Expected a Characteristic"
msgstr ""
@@ -1302,6 +1307,10 @@ msgid ""
"To list built-in modules please do `help(\"modules\")`.\n"
msgstr ""
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Writes not supported on Characteristic"
+msgstr ""
+
#: supervisor/shared/safe_mode.c
msgid "You are in safe mode: something unanticipated happened.\n"
msgstr ""
diff --git a/locale/de_DE.po b/locale/de_DE.po
index 17f2e3828..f38a03689 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: 2020-01-01 17:29-0500\n"
+"POT-Creation-Date: 2020-01-07 14:31-0800\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: Pascal Deneaux\n"
"Language-Team: Sebastian Plamauer, Pascal Deneaux\n"
@@ -68,7 +68,8 @@ msgid "%q indices must be integers, not %s"
msgstr "%q Indizes müssen ganze Zahlen sein, nicht %s"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
+#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
+#: shared-bindings/displayio/Shape.c
msgid "%q must be >= 1"
msgstr "%q muss >= 1 sein"
@@ -377,6 +378,10 @@ msgstr "Die Pufferlänge %d ist zu groß. Sie muss kleiner als %d sein."
msgid "Buffer must be at least length 1"
msgstr "Der Puffer muss eine Mindestenslänge von 1 haben"
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Buffer too large and unable to allocate"
+msgstr ""
+
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
#, c-format
@@ -589,7 +594,7 @@ msgid "Expected a %q"
msgstr "Erwartet ein(e) %q"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Descriptor.c
+#: shared-bindings/_bleio/Descriptor.c shared-bindings/_bleio/PacketBuffer.c
msgid "Expected a Characteristic"
msgstr "Characteristic wird erwartet"
@@ -1330,6 +1335,10 @@ msgstr ""
"Um die integrierten Module aufzulisten, führe bitte `help(\"modules\")` "
"aus.\n"
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Writes not supported on Characteristic"
+msgstr ""
+
#: supervisor/shared/safe_mode.c
msgid "You are in safe mode: something unanticipated happened.\n"
msgstr ""
diff --git a/locale/en_US.po b/locale/en_US.po
index e6fbfc471..136d0699d 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: 2020-01-01 17:29-0500\n"
+"POT-Creation-Date: 2020-01-07 14:31-0800\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -66,7 +66,8 @@ msgid "%q indices must be integers, not %s"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
+#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
+#: shared-bindings/displayio/Shape.c
msgid "%q must be >= 1"
msgstr ""
@@ -373,6 +374,10 @@ msgstr ""
msgid "Buffer must be at least length 1"
msgstr ""
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Buffer too large and unable to allocate"
+msgstr ""
+
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
#, c-format
@@ -585,7 +590,7 @@ msgid "Expected a %q"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Descriptor.c
+#: shared-bindings/_bleio/Descriptor.c shared-bindings/_bleio/PacketBuffer.c
msgid "Expected a Characteristic"
msgstr ""
@@ -1302,6 +1307,10 @@ msgid ""
"To list built-in modules please do `help(\"modules\")`.\n"
msgstr ""
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Writes not supported on Characteristic"
+msgstr ""
+
#: supervisor/shared/safe_mode.c
msgid "You are in safe mode: something unanticipated happened.\n"
msgstr ""
diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po
index 563510230..81e05f7dc 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: 2020-01-01 17:29-0500\n"
+"POT-Creation-Date: 2020-01-07 14:31-0800\n"
"PO-Revision-Date: 2018-07-27 11:55-0700\n"
"Last-Translator: \n"
"Language-Team: @sommersoft, @MrCertainly\n"
@@ -68,7 +68,8 @@ msgid "%q indices must be integers, not %s"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
+#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
+#: shared-bindings/displayio/Shape.c
msgid "%q must be >= 1"
msgstr ""
@@ -377,6 +378,10 @@ msgstr ""
msgid "Buffer must be at least length 1"
msgstr ""
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Buffer too large and unable to allocate"
+msgstr ""
+
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
#, c-format
@@ -589,7 +594,7 @@ msgid "Expected a %q"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Descriptor.c
+#: shared-bindings/_bleio/Descriptor.c shared-bindings/_bleio/PacketBuffer.c
msgid "Expected a Characteristic"
msgstr ""
@@ -1306,6 +1311,10 @@ msgid ""
"To list built-in modules please do `help(\"modules\")`.\n"
msgstr ""
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Writes not supported on Characteristic"
+msgstr ""
+
#: supervisor/shared/safe_mode.c
msgid "You are in safe mode: something unanticipated happened.\n"
msgstr ""
diff --git a/locale/es.po b/locale/es.po
index c9688a41b..a8f6afb2a 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: 2020-01-01 17:29-0500\n"
+"POT-Creation-Date: 2020-01-07 14:31-0800\n"
"PO-Revision-Date: 2018-08-24 22:56-0500\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -68,7 +68,8 @@ msgid "%q indices must be integers, not %s"
msgstr "%q indices deben ser enteros, no %s"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
+#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
+#: shared-bindings/displayio/Shape.c
msgid "%q must be >= 1"
msgstr "%q debe ser >= 1"
@@ -379,6 +380,10 @@ msgstr ""
msgid "Buffer must be at least length 1"
msgstr "Buffer debe ser de longitud 1 como minimo"
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Buffer too large and unable to allocate"
+msgstr ""
+
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
#, c-format
@@ -591,7 +596,7 @@ msgid "Expected a %q"
msgstr "Se espera un %q"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Descriptor.c
+#: shared-bindings/_bleio/Descriptor.c shared-bindings/_bleio/PacketBuffer.c
msgid "Expected a Characteristic"
msgstr "Se esperaba una Característica."
@@ -1327,6 +1332,10 @@ msgstr ""
"\n"
"Para listar los módulos incorporados por favor haga `help(\"modules\")`.\n"
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Writes not supported on Characteristic"
+msgstr ""
+
#: supervisor/shared/safe_mode.c
msgid "You are in safe mode: something unanticipated happened.\n"
msgstr ""
diff --git a/locale/fil.po b/locale/fil.po
index 94f39f406..3c1d13fa8 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: 2020-01-01 17:29-0500\n"
+"POT-Creation-Date: 2020-01-07 14:31-0800\n"
"PO-Revision-Date: 2018-12-20 22:15-0800\n"
"Last-Translator: Timothy <me@timothygarcia.ca>\n"
"Language-Team: fil\n"
@@ -66,7 +66,8 @@ msgid "%q indices must be integers, not %s"
msgstr "%q indeks ay dapat integers, hindi %s"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
+#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
+#: shared-bindings/displayio/Shape.c
#, fuzzy
msgid "%q must be >= 1"
msgstr "aarehas na haba dapat ang buffer slices"
@@ -379,6 +380,10 @@ msgstr ""
msgid "Buffer must be at least length 1"
msgstr "Buffer dapat ay hindi baba sa 1 na haba"
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Buffer too large and unable to allocate"
+msgstr ""
+
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
#, fuzzy, c-format
@@ -597,7 +602,7 @@ msgid "Expected a %q"
msgstr "Umasa ng %q"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Descriptor.c
+#: shared-bindings/_bleio/Descriptor.c shared-bindings/_bleio/PacketBuffer.c
#, fuzzy
msgid "Expected a Characteristic"
msgstr "Hindi mabasa and Characteristic."
@@ -1336,6 +1341,10 @@ msgstr ""
"\n"
"Para makita ang listahan ng modules, `help(“modules”)`.\n"
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Writes not supported on Characteristic"
+msgstr ""
+
#: supervisor/shared/safe_mode.c
msgid "You are in safe mode: something unanticipated happened.\n"
msgstr ""
diff --git a/locale/fr.po b/locale/fr.po
index 42209a045..df189306c 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: 2020-01-01 17:29-0500\n"
+"POT-Creation-Date: 2020-01-07 14:31-0800\n"
"PO-Revision-Date: 2019-04-14 20:05+0100\n"
"Last-Translator: Pierrick Couturier <arofarn@arofarn.info>\n"
"Language-Team: fr\n"
@@ -68,7 +68,8 @@ msgid "%q indices must be integers, not %s"
msgstr "les indices %q doivent être des entiers, pas %s"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
+#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
+#: shared-bindings/displayio/Shape.c
#, fuzzy
msgid "%q must be >= 1"
msgstr "%d doit être >=1"
@@ -383,6 +384,10 @@ msgstr ""
msgid "Buffer must be at least length 1"
msgstr "Le tampon doit être de longueur au moins 1"
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Buffer too large and unable to allocate"
+msgstr ""
+
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
#, fuzzy, c-format
@@ -600,7 +605,7 @@ msgid "Expected a %q"
msgstr "Attendu un %q"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Descriptor.c
+#: shared-bindings/_bleio/Descriptor.c shared-bindings/_bleio/PacketBuffer.c
#, fuzzy
msgid "Expected a Characteristic"
msgstr "Une 'Characteristic' est attendue"
@@ -1353,6 +1358,10 @@ msgstr ""
"\n"
"Pour lister les modules inclus, tapez `help(\"modules\")`.\n"
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Writes not supported on Characteristic"
+msgstr ""
+
#: supervisor/shared/safe_mode.c
msgid "You are in safe mode: something unanticipated happened.\n"
msgstr ""
diff --git a/locale/it_IT.po b/locale/it_IT.po
index 684e2a90b..3a6a71006 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: 2020-01-01 17:29-0500\n"
+"POT-Creation-Date: 2020-01-07 14:31-0800\n"
"PO-Revision-Date: 2018-10-02 16:27+0200\n"
"Last-Translator: Enrico Paganin <enrico.paganin@mail.com>\n"
"Language-Team: \n"
@@ -66,7 +66,8 @@ msgid "%q indices must be integers, not %s"
msgstr "gli indici %q devono essere interi, non %s"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
+#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
+#: shared-bindings/displayio/Shape.c
#, fuzzy
msgid "%q must be >= 1"
msgstr "slice del buffer devono essere della stessa lunghezza"
@@ -379,6 +380,10 @@ msgstr ""
msgid "Buffer must be at least length 1"
msgstr "Il buffer deve essere lungo almeno 1"
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Buffer too large and unable to allocate"
+msgstr ""
+
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
#, fuzzy, c-format
@@ -597,7 +602,7 @@ msgid "Expected a %q"
msgstr "Atteso un %q"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Descriptor.c
+#: shared-bindings/_bleio/Descriptor.c shared-bindings/_bleio/PacketBuffer.c
#, fuzzy
msgid "Expected a Characteristic"
msgstr "Non è possibile aggiungere Characteristic."
@@ -1339,6 +1344,10 @@ msgid ""
"To list built-in modules please do `help(\"modules\")`.\n"
msgstr ""
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Writes not supported on Characteristic"
+msgstr ""
+
#: supervisor/shared/safe_mode.c
msgid "You are in safe mode: something unanticipated happened.\n"
msgstr ""
diff --git a/locale/ko.po b/locale/ko.po
index 7b4240800..d8c9cbfba 100644
--- a/locale/ko.po
+++ b/locale/ko.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2020-01-01 17:29-0500\n"
+"POT-Creation-Date: 2020-01-07 14:31-0800\n"
"PO-Revision-Date: 2019-05-06 14:22-0700\n"
"Last-Translator: \n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -68,7 +68,8 @@ msgid "%q indices must be integers, not %s"
msgstr "%q 인덱스는 %s 가 아닌 정수 여야합니다"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
+#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
+#: shared-bindings/displayio/Shape.c
msgid "%q must be >= 1"
msgstr "%q 는 >=1이어야합니다"
@@ -377,6 +378,10 @@ msgstr ""
msgid "Buffer must be at least length 1"
msgstr "잘못된 크기의 버퍼. >1 여야합니다"
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Buffer too large and unable to allocate"
+msgstr ""
+
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
#, c-format
@@ -589,7 +594,7 @@ msgid "Expected a %q"
msgstr "%q 이 예상되었습니다."
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Descriptor.c
+#: shared-bindings/_bleio/Descriptor.c shared-bindings/_bleio/PacketBuffer.c
msgid "Expected a Characteristic"
msgstr "특성(Characteristic)이 예상되었습니다."
@@ -1307,6 +1312,10 @@ msgid ""
"To list built-in modules please do `help(\"modules\")`.\n"
msgstr ""
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Writes not supported on Characteristic"
+msgstr ""
+
#: supervisor/shared/safe_mode.c
msgid "You are in safe mode: something unanticipated happened.\n"
msgstr ""
diff --git a/locale/pl.po b/locale/pl.po
index 1ef686e45..6a16b2437 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: 2020-01-01 17:29-0500\n"
+"POT-Creation-Date: 2020-01-07 14:31-0800\n"
"PO-Revision-Date: 2019-03-19 18:37-0700\n"
"Last-Translator: Radomir Dopieralski <circuitpython@sheep.art.pl>\n"
"Language-Team: pl\n"
@@ -67,7 +67,8 @@ msgid "%q indices must be integers, not %s"
msgstr "%q indeks musi być liczbą całkowitą, a nie %s"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
+#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
+#: shared-bindings/displayio/Shape.c
msgid "%q must be >= 1"
msgstr "%q musi być >= 1"
@@ -376,6 +377,10 @@ msgstr ""
msgid "Buffer must be at least length 1"
msgstr "Bufor musi mieć długość 1 lub więcej"
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Buffer too large and unable to allocate"
+msgstr ""
+
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
#, c-format
@@ -588,7 +593,7 @@ msgid "Expected a %q"
msgstr "Oczekiwano %q"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Descriptor.c
+#: shared-bindings/_bleio/Descriptor.c shared-bindings/_bleio/PacketBuffer.c
msgid "Expected a Characteristic"
msgstr "Oczekiwano charakterystyki"
@@ -1310,6 +1315,10 @@ msgstr ""
"Podręczniki dostępne na learn.adafruit.com/category/circuitpyhon.\n"
"Aby zobaczyć wbudowane moduły, wpisz `help(\"modules\")`.\n"
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Writes not supported on Characteristic"
+msgstr ""
+
#: supervisor/shared/safe_mode.c
msgid "You are in safe mode: something unanticipated happened.\n"
msgstr ""
diff --git a/locale/pt_BR.po b/locale/pt_BR.po
index 9d36696ce..7fb8fe9d7 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: 2020-01-01 17:29-0500\n"
+"POT-Creation-Date: 2020-01-07 14:31-0800\n"
"PO-Revision-Date: 2018-10-02 21:14-0000\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -66,7 +66,8 @@ msgid "%q indices must be integers, not %s"
msgstr ""
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
+#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
+#: shared-bindings/displayio/Shape.c
#, fuzzy
msgid "%q must be >= 1"
msgstr "buffers devem ser o mesmo tamanho"
@@ -376,6 +377,10 @@ msgstr ""
msgid "Buffer must be at least length 1"
msgstr ""
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Buffer too large and unable to allocate"
+msgstr ""
+
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
#, fuzzy, c-format
@@ -592,7 +597,7 @@ msgid "Expected a %q"
msgstr "Esperado um"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Descriptor.c
+#: shared-bindings/_bleio/Descriptor.c shared-bindings/_bleio/PacketBuffer.c
#, fuzzy
msgid "Expected a Characteristic"
msgstr "Não é possível adicionar Característica."
@@ -1320,6 +1325,10 @@ msgid ""
"To list built-in modules please do `help(\"modules\")`.\n"
msgstr ""
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Writes not supported on Characteristic"
+msgstr ""
+
#: supervisor/shared/safe_mode.c
msgid "You are in safe mode: something unanticipated happened.\n"
msgstr ""
diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po
index cb907e0a1..9f1c0ea5b 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: 2020-01-01 17:29-0500\n"
+"POT-Creation-Date: 2020-01-07 14:31-0800\n"
"PO-Revision-Date: 2019-04-13 10:10-0700\n"
"Last-Translator: hexthat\n"
"Language-Team: Chinese Hanyu Pinyin\n"
@@ -68,7 +68,8 @@ msgid "%q indices must be integers, not %s"
msgstr "%q suǒyǐn bìxū shì zhěngshù, ér bùshì %s"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/displayio/Group.c shared-bindings/displayio/Shape.c
+#: shared-bindings/_bleio/PacketBuffer.c shared-bindings/displayio/Group.c
+#: shared-bindings/displayio/Shape.c
msgid "%q must be >= 1"
msgstr "%q bìxū dàyú huò děngyú 1"
@@ -377,6 +378,10 @@ msgstr "Huǎnchōng qū chángdù%d tài dà. Tā bìxū xiǎoyú%d"
msgid "Buffer must be at least length 1"
msgstr "Huǎnchōng qū bìxū zhìshǎo chángdù 1"
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Buffer too large and unable to allocate"
+msgstr ""
+
#: ports/atmel-samd/common-hal/displayio/ParallelBus.c
#: ports/nrf/common-hal/displayio/ParallelBus.c
#, c-format
@@ -589,7 +594,7 @@ msgid "Expected a %q"
msgstr "Yùqí %q"
#: shared-bindings/_bleio/CharacteristicBuffer.c
-#: shared-bindings/_bleio/Descriptor.c
+#: shared-bindings/_bleio/Descriptor.c shared-bindings/_bleio/PacketBuffer.c
msgid "Expected a Characteristic"
msgstr "Yùqí de tèdiǎn"
@@ -1319,6 +1324,10 @@ msgstr ""
"\n"
"Ruò yào liè chū nèizài de mókuài, qǐng qǐng zuò yǐxià `help(\"modules\")`.\n"
+#: ports/nrf/common-hal/_bleio/PacketBuffer.c
+msgid "Writes not supported on Characteristic"
+msgstr ""
+
#: supervisor/shared/safe_mode.c
msgid "You are in safe mode: something unanticipated happened.\n"
msgstr ""
diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c
index 7dbb31582..28a265b7f 100644
--- a/ports/nrf/bluetooth/ble_drv.c
+++ b/ports/nrf/bluetooth/ble_drv.c
@@ -46,7 +46,7 @@ nrf_nvic_state_t nrf_nvic_state = { 0 };
volatile sd_flash_operation_status_t sd_flash_operation_status;
__attribute__((aligned(4)))
-static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATT_ATT_MTU_DEFAULT)];
+static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATTS_VAR_ATTR_LEN_MAX)];
void ble_drv_reset() {
// Linked list items will be gc'd.
diff --git a/ports/nrf/boards/common.template.ld b/ports/nrf/boards/common.template.ld
index 931f95ee9..b110e6052 100644
--- a/ports/nrf/boards/common.template.ld
+++ b/ports/nrf/boards/common.template.ld
@@ -16,7 +16,13 @@ MEMORY
FLASH_FATFS (r) : ORIGIN = ${CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR}, LENGTH = ${CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE}
FLASH_BOOTLOADER (rx) : ORIGIN = ${BOOTLOADER_START_ADDR}, LENGTH = ${BOOTLOADER_SIZE}
FLASH_BOOTLOADER_SETTINGS (r) : ORIGIN = ${BOOTLOADER_SETTINGS_START_ADDR}, LENGTH = ${BOOTLOADER_SETTINGS_SIZE}
- RAM (xrw) : ORIGIN = 0x20004000, LENGTH = 0x03C000 /* 240 KiB */
+
+
+ /* 0x2000000 - RAM:ORIGIN is reserved for Softdevice */
+ /* SoftDevice 6.1.0 takes 0x7b78 bytes (30.86 kb) minimum with high ATT MTU. */
+ /* 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 + 32K, LENGTH = 256K - 32K
}
/* produce a link error if there is not this amount of RAM for these sections */
diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c
index cee40a5a0..b9b6d2e88 100644
--- a/ports/nrf/common-hal/_bleio/Adapter.c
+++ b/ports/nrf/common-hal/_bleio/Adapter.c
@@ -67,7 +67,7 @@ STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) {
reset_into_safe_mode(NORDIC_SOFT_DEVICE_ASSERT);
}
-bleio_connection_internal_t connections[BLEIO_TOTAL_CONNECTION_COUNT];
+bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT];
// Linker script provided ram start.
extern uint32_t _ram_start;
@@ -133,6 +133,15 @@ STATIC uint32_t ble_stack_enable(void) {
return err_code;
}
+ // Set ATT_MTU so that the maximum MTU we can negotiate is up to the full characteristic size.
+ memset(&ble_conf, 0, sizeof(ble_conf));
+ ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM;
+ ble_conf.conn_cfg.params.gatt_conn_cfg.att_mtu = BLE_GATTS_VAR_ATTR_LEN_MAX;
+ err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATT, &ble_conf, app_ram_start);
+ 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));
@@ -142,7 +151,14 @@ STATIC uint32_t ble_stack_enable(void) {
return err_code;
}
- // TODO set ATT_MTU so that the maximum MTU we can negotiate is higher than the default.
+ // Increase the number of vendor UUIDs supported. Apple uses a complete random number per
+ // service and characteristic.
+ memset(&ble_conf, 0, sizeof(ble_conf));
+ ble_conf.common_cfg.vs_uuid_cfg.vs_uuid_count = 32; // Defaults to 10.
+ err_code = sd_ble_cfg_set(BLE_COMMON_CFG_VS_UUID, &ble_conf, app_ram_start);
+ if (err_code != NRF_SUCCESS) {
+ return err_code;
+ }
// This sets app_ram_start to the minimum value needed for the settings set above.
err_code = sd_ble_enable(&app_ram_start);
@@ -150,6 +166,14 @@ STATIC uint32_t ble_stack_enable(void) {
return err_code;
}
+ // Turn on connection event extension so we can transmit for a longer period of time as needed.
+ ble_opt_t opt;
+ opt.common_opt.conn_evt_ext.enable = true;
+ err_code = sd_ble_opt_set(BLE_COMMON_OPT_CONN_EVT_EXT, &opt);
+ if (err_code != NRF_SUCCESS) {
+ return err_code;
+ }
+
ble_gap_conn_params_t gap_conn_params = {
.min_conn_interval = BLE_MIN_CONN_INTERVAL,
.max_conn_interval = BLE_MAX_CONN_INTERVAL,
@@ -177,7 +201,7 @@ STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
// total connection limit.
bleio_connection_internal_t *connection;
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
- connection = &connections[i];
+ connection = &bleio_connections[i];
if (connection->conn_handle == BLE_CONN_HANDLE_INVALID) {
break;
}
@@ -189,6 +213,7 @@ STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
connection->conn_handle = ble_evt->evt.gap_evt.conn_handle;
connection->connection_obj = mp_const_none;
connection->pair_status = PAIR_NOT_PAIRED;
+ connection->mtu = 0;
ble_drv_add_event_handler_entry(&connection->handler_entry, connection_on_ble_evt, connection);
self->connection_objs = NULL;
@@ -216,7 +241,7 @@ STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
// 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];
+ connection = &bleio_connections[i];
if (connection->conn_handle == ble_evt->evt.gap_evt.conn_handle) {
break;
}
@@ -293,7 +318,7 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
// 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];
+ bleio_connection_internal_t *connection = &bleio_connections[i];
connection->conn_handle = BLE_CONN_HANDLE_INVALID;
}
bleio_adapter_reset_name(self);
@@ -497,14 +522,25 @@ mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_addre
ble_drv_remove_event_handler(connect_on_ble_evt, &event_info);
- if (event_info.conn_handle == BLE_CONN_HANDLE_INVALID) {
+ uint16_t conn_handle = event_info.conn_handle;
+ if (conn_handle == BLE_CONN_HANDLE_INVALID) {
mp_raise_bleio_BluetoothError(translate("Failed to connect: timeout"));
}
+ // Negotiate for better PHY, larger MTU and data lengths since we are the central. These are
+ // nice-to-haves so ignore any errors.
+ ble_gap_phys_t const phys = {
+ .rx_phys = BLE_GAP_PHY_AUTO,
+ .tx_phys = BLE_GAP_PHY_AUTO,
+ };
+ sd_ble_gap_phy_update(conn_handle, &phys);
+ sd_ble_gattc_exchange_mtu_request(conn_handle, BLE_GATTS_VAR_ATTR_LEN_MAX);
+ sd_ble_gap_data_length_update(conn_handle, NULL, NULL);
+
// 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) {
+ bleio_connection_internal_t *connection = &bleio_connections[i];
+ if (connection->conn_handle == conn_handle) {
return bleio_connection_new_from_internal(connection);
}
}
@@ -628,7 +664,7 @@ void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) {
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];
+ bleio_connection_internal_t *connection = &bleio_connections[i];
if (connection->conn_handle != BLE_CONN_HANDLE_INVALID) {
return true;
}
@@ -643,7 +679,7 @@ mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
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];
+ bleio_connection_internal_t *connection = &bleio_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);
@@ -658,7 +694,7 @@ mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) {
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));
+ gc_collect_root((void**)bleio_connections, sizeof(bleio_connections) / sizeof(size_t));
}
void bleio_adapter_reset(bleio_adapter_obj_t* adapter) {
@@ -666,7 +702,7 @@ void bleio_adapter_reset(bleio_adapter_obj_t* 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];
+ bleio_connection_internal_t *connection = &bleio_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 dca443990..2ac568d66 100644
--- a/ports/nrf/common-hal/_bleio/Adapter.h
+++ b/ports/nrf/common-hal/_bleio/Adapter.h
@@ -37,7 +37,7 @@
#define BLEIO_TOTAL_CONNECTION_COUNT 2
-extern bleio_connection_internal_t connections[BLEIO_TOTAL_CONNECTION_COUNT];
+extern bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT];
typedef struct {
mp_obj_base_t base;
diff --git a/ports/nrf/common-hal/_bleio/Characteristic.c b/ports/nrf/common-hal/_bleio/Characteristic.c
index 9f1255e32..c7eec94c0 100644
--- a/ports/nrf/common-hal/_bleio/Characteristic.c
+++ b/ports/nrf/common-hal/_bleio/Characteristic.c
@@ -154,7 +154,7 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self,
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];
+ bleio_connection_internal_t *connection = &bleio_connections[i];
uint16_t conn_handle = connection->conn_handle;
if (connection->conn_handle == BLE_CONN_HANDLE_INVALID) {
continue;
diff --git a/ports/nrf/common-hal/_bleio/Connection.c b/ports/nrf/common-hal/_bleio/Connection.c
index e0b50901a..daf5b937b 100644
--- a/ports/nrf/common-hal/_bleio/Connection.c
+++ b/ports/nrf/common-hal/_bleio/Connection.c
@@ -85,6 +85,7 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
switch (ble_evt->header.evt_id) {
case BLE_GAP_EVT_DISCONNECTED:
break;
+
case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
ble_gap_phys_t const phys = {
.rx_phys = BLE_GAP_PHY_AUTO,
@@ -94,20 +95,45 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
break;
}
- case BLE_GAP_EVT_PHY_UPDATE: // 0x22
+ 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
+ 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);
+ ble_gatts_evt_exchange_mtu_request_t *request =
+ &ble_evt->evt.gatts_evt.params.exchange_mtu_request;
+
+ uint16_t new_mtu = BLE_GATTS_VAR_ATTR_LEN_MAX;
+ if (request->client_rx_mtu < new_mtu) {
+ new_mtu = request->client_rx_mtu;
+ }
+ if (new_mtu < BLE_GATT_ATT_MTU_DEFAULT) {
+ new_mtu = BLE_GATT_ATT_MTU_DEFAULT;
+ }
+ if (self->mtu > 0) {
+ new_mtu = self->mtu;
+ }
+
+ self->mtu = new_mtu;
+ sd_ble_gatts_exchange_mtu_reply(self->conn_handle, new_mtu);
+ break;
+ }
+
+
+ case BLE_GATTC_EVT_EXCHANGE_MTU_RSP: {
+ ble_gattc_evt_exchange_mtu_rsp_t *response =
+ &ble_evt->evt.gattc_evt.params.exchange_mtu_rsp;
+
+ self->mtu = response->server_rx_mtu;
break;
}
@@ -319,8 +345,11 @@ STATIC bool discover_next_services(bleio_connection_internal_t* connection, uint
m_discovery_successful = false;
m_discovery_in_process = true;
- check_nrf_error(sd_ble_gattc_primary_services_discover(connection->conn_handle,
- start_handle, service_uuid));
+ uint32_t nrf_err = NRF_ERROR_BUSY;
+ while (nrf_err == NRF_ERROR_BUSY) {
+ nrf_err = sd_ble_gattc_primary_services_discover(connection->conn_handle, start_handle, service_uuid);
+ }
+ check_nrf_error(nrf_err);
// Wait for a discovery event.
while (m_discovery_in_process) {
diff --git a/ports/nrf/common-hal/_bleio/Connection.h b/ports/nrf/common-hal/_bleio/Connection.h
index 1474a0a6c..61bbea4a1 100644
--- a/ports/nrf/common-hal/_bleio/Connection.h
+++ b/ports/nrf/common-hal/_bleio/Connection.h
@@ -65,6 +65,7 @@ typedef struct {
ble_drv_evt_handler_entry_t handler_entry;
ble_gap_conn_params_t conn_params;
volatile bool conn_params_updating;
+ uint16_t mtu;
} bleio_connection_internal_t;
typedef struct {
diff --git a/ports/nrf/common-hal/_bleio/PacketBuffer.c b/ports/nrf/common-hal/_bleio/PacketBuffer.c
new file mode 100644
index 000000000..27dacb493
--- /dev/null
+++ b/ports/nrf/common-hal/_bleio/PacketBuffer.c
@@ -0,0 +1,335 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019-2020 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 <stdio.h>
+
+#include "ble_drv.h"
+#include "ble_gatts.h"
+#include "nrf_nvic.h"
+
+#include "lib/utils/interrupt_char.h"
+#include "py/runtime.h"
+#include "py/stream.h"
+
+#include "tick.h"
+
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/Connection.h"
+#include "shared-bindings/_bleio/PacketBuffer.h"
+#include "supervisor/shared/tick.h"
+
+STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) {
+ if (len + sizeof(uint16_t) > self->ringbuf.size) {
+ // This shouldn't happen.
+ return;
+ }
+ // Push all the data onto the ring buffer.
+ uint8_t is_nested_critical_region;
+ sd_nvic_critical_region_enter(&is_nested_critical_region);
+ // Make room for the new value by dropping the oldest packets first.
+ while (self->ringbuf.size - ringbuf_count(&self->ringbuf) < (int) (len + sizeof(uint16_t))) {
+ uint16_t packet_length;
+ ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
+ for (uint16_t i = 0; i < packet_length; i++) {
+ ringbuf_get(&self->ringbuf);
+ }
+ // set an overflow flag?
+ }
+ ringbuf_put_n(&self->ringbuf, (uint8_t*) &len, sizeof(uint16_t));
+ ringbuf_put_n(&self->ringbuf, data, len);
+ sd_nvic_critical_region_exit(is_nested_critical_region);
+}
+
+STATIC uint32_t queue_next_write(bleio_packet_buffer_obj_t *self) {
+ // Queue up the next outgoing buffer. We use two, one that has been passed to the SD for
+ // transmission (when packet_queued is true) and the other is `pending` and can still be
+ // modified. By primarily appending to the `pending` buffer we can reduce the protocol overhead
+ // of the lower level link and ATT layers.
+ self->packet_queued = false;
+ if (self->pending_size > 0) {
+ uint16_t conn_handle = self->conn_handle;
+ uint32_t err_code;
+ if (self->client) {
+ ble_gattc_write_params_t write_params = {
+ .write_op = self->write_type,
+ .handle = self->characteristic->handle,
+ .p_value = self->outgoing[self->pending_index],
+ .len = self->pending_size,
+ };
+
+ err_code = sd_ble_gattc_write(conn_handle, &write_params);
+ } else {
+ uint16_t hvx_len = self->pending_size;
+
+ ble_gatts_hvx_params_t hvx_params = {
+ .handle = self->characteristic->handle,
+ .type = self->write_type,
+ .offset = 0,
+ .p_len = &hvx_len,
+ .p_data = self->outgoing[self->pending_index],
+ };
+ err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params);
+ }
+ if (err_code != NRF_SUCCESS) {
+ // On error, simply skip updating the pending buffers so that the next HVC or WRITE
+ // complete event triggers another attempt.
+ return err_code;
+ }
+ self->pending_size = 0;
+ self->pending_index = (self->pending_index + 1) % 2;
+ self->packet_queued = true;
+ }
+ return NRF_SUCCESS;
+}
+
+STATIC bool packet_buffer_on_ble_client_evt(ble_evt_t *ble_evt, void *param) {
+ bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param;
+ uint16_t conn_handle = ble_evt->evt.gattc_evt.conn_handle;
+ if (conn_handle != self->conn_handle) {
+ return false;
+ }
+ switch (ble_evt->header.evt_id) {
+ case BLE_GATTC_EVT_HVX: {
+ // A remote service wrote to this characteristic.
+ ble_gattc_evt_hvx_t* evt_hvx = &ble_evt->evt.gattc_evt.params.hvx;
+ // Must be a notification, and event handle must match the handle for my characteristic.
+ if (evt_hvx->handle == self->characteristic->handle) {
+ write_to_ringbuf(self, evt_hvx->data, evt_hvx->len);
+ if (evt_hvx->type == BLE_GATT_HVX_INDICATION) {
+ sd_ble_gattc_hv_confirm(conn_handle, evt_hvx->handle);
+ }
+ }
+ break;
+ }
+ case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE: {
+ queue_next_write(self);
+ break;
+ }
+ case BLE_GATTC_EVT_WRITE_RSP: {
+ queue_next_write(self);
+ break;
+ }
+ default:
+ return false;
+ break;
+ }
+ return true;
+}
+
+STATIC bool packet_buffer_on_ble_server_evt(ble_evt_t *ble_evt, void *param) {
+ bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param;
+ uint16_t conn_handle = ble_evt->evt.gatts_evt.conn_handle;
+ switch (ble_evt->header.evt_id) {
+ case BLE_GATTS_EVT_WRITE: {
+ // A client wrote to this server 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 == self->characteristic->handle) {
+ if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
+ self->conn_handle = conn_handle;
+ } else if (self->conn_handle != conn_handle) {
+ return false;
+ }
+ write_to_ringbuf(self, evt_write->data, evt_write->len);
+ } else if (evt_write->handle == self->characteristic->cccd_handle &&
+ self->conn_handle == BLE_CONN_HANDLE_INVALID) {
+ uint16_t cccd = *((uint16_t*) evt_write->data);
+ if (cccd & BLE_GATT_HVX_NOTIFICATION) {
+ self->conn_handle = conn_handle;
+ } else {
+ self->conn_handle = BLE_CONN_HANDLE_INVALID;
+ }
+ }
+ break;
+ }
+ case BLE_GATTS_EVT_HVN_TX_COMPLETE: {
+ queue_next_write(self);
+ }
+ default:
+ return false;
+ break;
+ }
+ return true;
+}
+
+void common_hal_bleio_packet_buffer_construct(
+ bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic,
+ size_t buffer_size) {
+
+ self->characteristic = characteristic;
+ self->client = self->characteristic->service->is_remote;
+ bleio_characteristic_properties_t incoming = self->characteristic->props & (CHAR_PROP_WRITE_NO_RESPONSE | CHAR_PROP_WRITE);
+ bleio_characteristic_properties_t outgoing = self->characteristic->props & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE);
+
+ if (self->client) {
+ // Swap if we're the client.
+ bleio_characteristic_properties_t temp = incoming;
+ incoming = outgoing;
+ outgoing = temp;
+ self->conn_handle = bleio_connection_get_conn_handle(MP_OBJ_TO_PTR(self->characteristic->service->connection));
+ }
+
+ if (incoming) {
+ // This is a macro.
+ ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false);
+
+ if (self->ringbuf.buf == NULL) {
+ mp_raise_ValueError(translate("Buffer too large and unable to allocate"));
+ }
+ }
+
+ if (outgoing) {
+ self->packet_queued = false;
+ self->pending_index = 0;
+ self->pending_size = 0;
+ self->outgoing[0] = m_malloc(characteristic->max_length, false);
+ self->outgoing[1] = m_malloc(characteristic->max_length, false);
+ } else {
+ self->outgoing[0] = NULL;
+ self->outgoing[1] = NULL;
+ }
+
+ if (self->client) {
+ ble_drv_add_event_handler(packet_buffer_on_ble_client_evt, self);
+ if (incoming) {
+ // Prefer notify if both are available.
+ if (incoming & CHAR_PROP_NOTIFY) {
+ self->write_type = BLE_GATT_HVX_NOTIFICATION;
+ common_hal_bleio_characteristic_set_cccd(self->characteristic, true, false);
+ } else {
+ common_hal_bleio_characteristic_set_cccd(self->characteristic, false, true);
+ }
+ }
+ if (outgoing) {
+ self->write_type = BLE_GATT_OP_WRITE_REQ;
+ if (outgoing & CHAR_PROP_WRITE_NO_RESPONSE) {
+ self->write_type = BLE_GATT_OP_WRITE_CMD;
+ }
+ }
+ } else {
+ ble_drv_add_event_handler(packet_buffer_on_ble_server_evt, self);
+ if (outgoing) {
+ self->write_type = BLE_GATT_HVX_INDICATION;
+ if (outgoing & CHAR_PROP_NOTIFY) {
+ self->write_type = BLE_GATT_HVX_NOTIFICATION;
+ }
+ }
+ }
+}
+
+int common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len) {
+ if (ringbuf_count(&self->ringbuf) < 2) {
+ return 0;
+ }
+
+ uint16_t packet_length;
+ ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
+
+ // Copy received data. Lock out write interrupt handler while copying.
+ uint8_t is_nested_critical_region;
+ sd_nvic_critical_region_enter(&is_nested_critical_region);
+
+ if (packet_length > len) {
+ // TODO: raise an exception.
+ packet_length = len;
+ }
+
+ ringbuf_get_n(&self->ringbuf, data, packet_length);
+
+ // Writes now OK.
+ sd_nvic_critical_region_exit(is_nested_critical_region);
+
+ return packet_length;
+}
+
+void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len) {
+ if (self->outgoing[0] == NULL) {
+ mp_raise_bleio_BluetoothError(translate("Writes not supported on Characteristic"));
+ }
+ if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
+ return;
+ }
+ uint16_t packet_size = common_hal_bleio_packet_buffer_get_packet_size(self);
+ uint16_t max_size = packet_size - len;
+ while (max_size < self->pending_size && self->conn_handle != BLE_CONN_HANDLE_INVALID) {
+ RUN_BACKGROUND_TASKS;
+ }
+ if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
+ return;
+ }
+ uint8_t is_nested_critical_region;
+ sd_nvic_critical_region_enter(&is_nested_critical_region);
+
+ uint8_t* pending = self->outgoing[self->pending_index];
+
+ if (self->pending_size == 0) {
+ memcpy(pending, header, header_len);
+ self->pending_size += header_len;
+ }
+ memcpy(pending + self->pending_size, data, len);
+ self->pending_size += len;
+
+ sd_nvic_critical_region_exit(is_nested_critical_region);
+
+ // If no writes are queued then sneak in this data.
+ if (!self->packet_queued) {
+ queue_next_write(self);
+ }
+}
+
+uint16_t common_hal_bleio_packet_buffer_get_packet_size(bleio_packet_buffer_obj_t *self) {
+ uint16_t mtu;
+ if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
+ return 0;
+ }
+ bleio_connection_internal_t *connection;
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ connection = &bleio_connections[i];
+ if (connection->conn_handle == self->conn_handle) {
+ break;
+ }
+ }
+ if (connection->mtu == 0) {
+ mtu = BLE_GATT_ATT_MTU_DEFAULT;
+ }
+ if (self->characteristic->max_length > mtu) {
+ mtu = self->characteristic->max_length;
+ }
+ uint16_t att_overhead = 3;
+ return mtu - att_overhead;
+}
+
+bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {
+ return self->characteristic == NULL;
+}
+
+void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) {
+ if (!common_hal_bleio_packet_buffer_deinited(self)) {
+ ble_drv_remove_event_handler(packet_buffer_on_ble_client_evt, self);
+ }
+}
diff --git a/ports/nrf/common-hal/_bleio/PacketBuffer.h b/ports/nrf/common-hal/_bleio/PacketBuffer.h
new file mode 100644
index 000000000..cfccc852e
--- /dev/null
+++ b/ports/nrf/common-hal/_bleio/PacketBuffer.h
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019-2020 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_NRF_COMMON_HAL_BLEIO_PACKETBUFFER_H
+#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PACKETBUFFER_H
+
+#include "nrf_soc.h"
+
+#include "py/ringbuf.h"
+#include "shared-bindings/_bleio/Characteristic.h"
+
+typedef struct {
+ mp_obj_base_t base;
+ bleio_characteristic_obj_t *characteristic;
+ // Ring buffer storing consecutive incoming values.
+ ringbuf_t ringbuf;
+ // Two outgoing buffers to alternate between. One will be queued for transmission by the SD and
+ // the other is waiting to be queued and can be extended.
+ uint8_t* outgoing[2];
+ uint16_t pending_size;
+ uint16_t conn_handle;
+ uint8_t pending_index;
+ uint8_t write_type;
+ bool client;
+ bool packet_queued;
+} bleio_packet_buffer_obj_t;
+
+#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PACKETBUFFER_H
diff --git a/ports/nrf/common-hal/_bleio/__init__.c b/ports/nrf/common-hal/_bleio/__init__.c
index 4b2780ded..8606c89ec 100644
--- a/ports/nrf/common-hal/_bleio/__init__.c
+++ b/ports/nrf/common-hal/_bleio/__init__.c
@@ -48,6 +48,9 @@ void check_nrf_error(uint32_t err_code) {
case NRF_ERROR_TIMEOUT:
mp_raise_msg(&mp_type_TimeoutError, NULL);
return;
+ case BLE_ERROR_INVALID_CONN_HANDLE:
+ mp_raise_bleio_ConnectionError(translate("Not connected"));
+ return;
default:
mp_raise_bleio_BluetoothError(translate("Unknown soft device error: %04x"), err_code);
break;
diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk
index 8dd4fc6b1..35a977946 100644
--- a/py/circuitpy_defns.mk
+++ b/py/circuitpy_defns.mk
@@ -236,6 +236,7 @@ SRC_COMMON_HAL_ALL = \
_bleio/CharacteristicBuffer.c \
_bleio/Connection.c \
_bleio/Descriptor.c \
+ _bleio/PacketBuffer.c \
_bleio/Service.c \
_bleio/UUID.c \
analogio/AnalogIn.c \
diff --git a/shared-bindings/_bleio/PacketBuffer.c b/shared-bindings/_bleio/PacketBuffer.c
new file mode 100644
index 000000000..f9f171870
--- /dev/null
+++ b/shared-bindings/_bleio/PacketBuffer.c
@@ -0,0 +1,201 @@
+/*
+ * 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 "py/mperrno.h"
+#include "py/ioctl.h"
+#include "py/objproperty.h"
+#include "py/runtime.h"
+#include "py/stream.h"
+
+#include "shared-bindings/_bleio/__init__.h"
+#include "shared-bindings/_bleio/PacketBuffer.h"
+#include "shared-bindings/_bleio/UUID.h"
+#include "shared-bindings/util.h"
+
+//| .. currentmodule:: _bleio
+//|
+//| :class:`PacketBuffer` -- Packet-oriented characteristic usage.
+//| =====================================================================
+//|
+//| Accumulates a Characteristic's incoming packets in a FIFO buffer and facilitates packet aware
+//| outgoing writes. A packet's size is either the characteristic length or the maximum transmission
+//| unit (MTU), whichever is smaller. The MTU can change so check `packet_size` before creating a
+//| buffer to store data.
+//|
+//| When we're the server, we ignore all connections besides the first to subscribe to
+//| notifications.
+//|
+//| .. class:: PacketBuffer(characteristic, *, buffer_size)
+//|
+//| Monitor the given Characteristic. Each time a new value is written to the Characteristic
+//| add the newly-written bytes to a FIFO buffer.
+//|
+//| :param Characteristic characteristic: The Characteristic to monitor.
+//| It may be a local Characteristic provided by a Peripheral Service, or a remote Characteristic
+//| in a remote Service that a Central has connected to.
+//| :param int buffer_size: Size of ring buffer (in packets of the Characteristic's maximum
+//| length) that stores incoming packets coming from the peer.
+//|
+STATIC mp_obj_t bleio_packet_buffer_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_characteristic, ARG_buffer_size };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_characteristic, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_buffer_size, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ const mp_obj_t characteristic = args[ARG_characteristic].u_obj;
+
+ const int buffer_size = args[ARG_buffer_size].u_int;
+ if (buffer_size < 1) {
+ mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_buffer_size);
+ }
+
+ if (!MP_OBJ_IS_TYPE(characteristic, &bleio_characteristic_type)) {
+ mp_raise_TypeError(translate("Expected a Characteristic"));
+ }
+
+ bleio_packet_buffer_obj_t *self = m_new_obj(bleio_packet_buffer_obj_t);
+ self->base.type = &bleio_packet_buffer_type;
+
+ common_hal_bleio_packet_buffer_construct(self, MP_OBJ_TO_PTR(characteristic), buffer_size);
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+STATIC void check_for_deinit(bleio_packet_buffer_obj_t *self) {
+ if (common_hal_bleio_packet_buffer_deinited(self)) {
+ raise_deinited_error();
+ }
+}
+
+//| .. method:: readinto(buf)
+//|
+//| Reads a single BLE packet into the ``buf``. Raises an exception if the next packet is longer
+//| than the given buffer. Use `packet_size` to read the maximum length of a single packet.
+//|
+//| :return: number of bytes read and stored into ``buf``
+//| :rtype: int
+//|
+STATIC mp_obj_t bleio_packet_buffer_readinto(mp_obj_t self_in, mp_obj_t buffer_obj) {
+ bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ check_for_deinit(self);
+
+ mp_buffer_info_t bufinfo;
+ mp_get_buffer_raise(buffer_obj, &bufinfo, MP_BUFFER_WRITE);
+
+ return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_packet_buffer_readinto(self, bufinfo.buf, bufinfo.len));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_packet_buffer_readinto_obj, bleio_packet_buffer_readinto);
+
+//| .. method:: write(data, *, header=None)
+//|
+//| Writes all bytes from data into the same outgoing packet. The bytes from header are included
+//| before data when the pending packet is currently empty.
+//|
+//| This does not block until the data is sent. It only blocks until the data is pending.
+//|
+// TODO: Add a kwarg `merge=False` to dictate whether subsequent writes are merged into a pending
+// one.
+STATIC mp_obj_t bleio_packet_buffer_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum { ARG_data, ARG_header };
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ },
+ { MP_QSTR_header, 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);
+
+ bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+ check_for_deinit(self);
+
+ mp_buffer_info_t data_bufinfo;
+ mp_get_buffer_raise(args[ARG_data].u_obj, &data_bufinfo, MP_BUFFER_READ);
+
+ mp_buffer_info_t header_bufinfo;
+ header_bufinfo.len = 0;
+ if (args[ARG_header].u_obj != MP_OBJ_NULL) {
+ mp_get_buffer_raise(args[ARG_header].u_obj, &header_bufinfo, MP_BUFFER_READ);
+ }
+
+ common_hal_bleio_packet_buffer_write(self, data_bufinfo.buf, data_bufinfo.len,
+ header_bufinfo.buf, header_bufinfo.len);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_packet_buffer_write_obj, 1, bleio_packet_buffer_write);
+
+//| .. method:: deinit()
+//|
+//| Disable permanently.
+//|
+STATIC mp_obj_t bleio_packet_buffer_deinit(mp_obj_t self_in) {
+ bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ common_hal_bleio_packet_buffer_deinit(self);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_packet_buffer_deinit_obj, bleio_packet_buffer_deinit);
+
+//| .. attribute:: packet_size
+//|
+//| Maximum size of each packet in bytes. This is the minimum of the Characterstic length and
+//| the negotiated Maximum Transfer Unit (MTU).
+//|
+STATIC mp_obj_t bleio_packet_buffer_get_packet_size(mp_obj_t self_in) {
+ bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ return mp_obj_new_bool(common_hal_bleio_packet_buffer_get_packet_size(self));
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_packet_buffer_get_packet_size_obj, bleio_packet_buffer_get_packet_size);
+
+const mp_obj_property_t bleio_packet_buffer_packet_size_obj = {
+ .base.type = &mp_type_property,
+ .proxy = { (mp_obj_t)&bleio_packet_buffer_get_packet_size_obj,
+ (mp_obj_t)&mp_const_none_obj,
+ (mp_obj_t)&mp_const_none_obj },
+};
+
+STATIC const mp_rom_map_elem_t bleio_packet_buffer_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bleio_packet_buffer_deinit_obj) },
+
+ // Standard stream methods.
+ { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&bleio_packet_buffer_readinto_obj) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&bleio_packet_buffer_write_obj) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_packet_size), MP_ROM_PTR(&bleio_packet_buffer_packet_size_obj) },
+};
+
+STATIC MP_DEFINE_CONST_DICT(bleio_packet_buffer_locals_dict, bleio_packet_buffer_locals_dict_table);
+
+
+const mp_obj_type_t bleio_packet_buffer_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_PacketBuffer,
+ .make_new = bleio_packet_buffer_make_new,
+ .locals_dict = (mp_obj_dict_t*)&bleio_packet_buffer_locals_dict
+};
diff --git a/shared-bindings/_bleio/PacketBuffer.h b/shared-bindings/_bleio/PacketBuffer.h
new file mode 100644
index 000000000..990a2f8bb
--- /dev/null
+++ b/shared-bindings/_bleio/PacketBuffer.h
@@ -0,0 +1,43 @@
+/*
+ * 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_SHARED_BINDINGS_BLEIO_PACKETBUFFER_H
+#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PACKETBUFFER_H
+
+#include "common-hal/_bleio/PacketBuffer.h"
+
+extern const mp_obj_type_t bleio_packet_buffer_type;
+
+extern void common_hal_bleio_packet_buffer_construct(
+ bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic,
+ size_t buffer_size);
+void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len);
+int common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len);
+uint16_t common_hal_bleio_packet_buffer_get_packet_size(bleio_packet_buffer_obj_t *self);
+bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self);
+void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self);
+
+#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PACKETBUFFER_H
diff --git a/shared-bindings/_bleio/__init__.c b/shared-bindings/_bleio/__init__.c
index ba2454da4..5d26862a6 100644
--- a/shared-bindings/_bleio/__init__.c
+++ b/shared-bindings/_bleio/__init__.c
@@ -35,6 +35,7 @@
#include "shared-bindings/_bleio/CharacteristicBuffer.h"
#include "shared-bindings/_bleio/Connection.h"
#include "shared-bindings/_bleio/Descriptor.h"
+#include "shared-bindings/_bleio/PacketBuffer.h"
#include "shared-bindings/_bleio/ScanEntry.h"
#include "shared-bindings/_bleio/ScanResults.h"
#include "shared-bindings/_bleio/Service.h"
@@ -69,6 +70,7 @@
//| CharacteristicBuffer
//| Connection
//| Descriptor
+//| PacketBuffer
//| ScanEntry
//| ScanResults
//| Service
@@ -140,8 +142,9 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = {
{ 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_PacketBuffer), MP_ROM_PTR(&bleio_packet_buffer_type) },
{ MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) },
- { MP_ROM_QSTR(MP_QSTR_ScanResults), MP_ROM_PTR(&bleio_scanresults_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) },