diff options
| author | Scott Shawcroft <scott@tannewt.org> | 2018-11-07 12:03:46 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-11-07 12:03:46 -0800 |
| commit | d08747d374057b24803b429bbf6474a2e4dcea5c (patch) | |
| tree | c3bfee81668dbd842039c178222fda9df77a9b76 | |
| parent | 283e07254e9eb50e52d6f07b7ac177feeef02d83 (diff) | |
| parent | 64d457dad9bb3843ee468136022996ecb91a98df (diff) | |
Merge pull request #1319 from dhalbert/origin/arturo182_bleio_pr_1289
Resubmit PR #1289, "WIP: bleio rewrite" by @arturo182
79 files changed, 6032 insertions, 4299 deletions
diff --git a/.travis.yml b/.travis.yml index 79aebdcd4..77642872e 100755 --- a/.travis.yml +++ b/.travis.yml @@ -50,7 +50,7 @@ before_script: - (! var_search "${TRAVIS_SDK-}" arm || (wget https://s3.amazonaws.com/adafruit-circuit-python/gcc-arm-embedded_7-2018q2-1~trusty1_amd64.deb && sudo dpkg -i gcc-arm-embedded*_amd64.deb)) # For nrf builds - - (! var_search "${TRAVIS_SDK-}" nrf || sudo ports/nrf/drivers/bluetooth/download_ble_stack.sh) + - (! var_search "${TRAVIS_SDK-}" nrf || sudo ports/nrf/bluetooth/download_ble_stack.sh) # For huzzah builds - (! var_search "${TRAVIS_SDK-}" esp8266 || (wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz && tar -C .. -xavf xtensa-lx106-elf-standalone.tar.gz)) @@ -115,7 +115,7 @@ exclude_patterns = ["**/build*", "ports/esp8266/modules", "ports/minimal", "ports/nrf/device", - "ports/nrf/drivers", + "ports/nrf/bluetooth", "ports/nrf/modules", "ports/nrf/nrfx", "ports/nrf/peripherals", diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index b389ec24a..b15fe38b1 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: 2018-10-25 12:53+1100\n" +"POT-Creation-Date: 2018-11-07 14:10-0500\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" @@ -696,143 +696,165 @@ msgstr "" msgid "AnalogOut functionality not supported" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:96 -msgid "All I2C peripherals are in use" +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:115 -msgid "All SPI peripherals are in use" +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:48 +#: ports/nrf/common-hal/bleio/Adapter.c:135 #, c-format -msgid "error = 0x%08lX" +msgid "Failed to get softdevice state, error: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:86 -msgid "Invalid buffer size" +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:90 -msgid "Odd parity is not supported" +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, c-format +msgid "Failed to write gatts value, status: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 -#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 -#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 -#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 -#: ports/nrf/common-hal/busio/UART.c:364 -msgid "busio.UART not available" +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/microcontroller/Processor.c:49 +#: ports/nrf/common-hal/bleio/Characteristic.c:91 #, c-format -msgid "Can not get temperature. status: 0x%02x" +msgid "Failed to read attribute value, status: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/pulseio/PWMOut.c:161 -msgid "All PWM peripherals are in use" +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, c-format +msgid "Failed to write attribute value, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +msgid "Can not fit data into the advertisment packet" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." +#: ports/nrf/common-hal/bleio/Device.c:436 +#, c-format +msgid "Failed to connect, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." +#: ports/nrf/common-hal/bleio/Device.c:513 +#, c-format +msgid "Failed to add service, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." +#: ports/nrf/common-hal/bleio/Device.c:531 +#, c-format +msgid "Failed to start advertisment, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." +#: ports/nrf/common-hal/bleio/Device.c:549 +#, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, c-format +msgid "Failed to start scanning, status: 0x%0xlX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 +#: ports/nrf/common-hal/bleio/Device.c:592 #, c-format -msgid "Can not apply advertisement data. status: 0x%02x" +msgid "Failed to create mutex, status: 0x%0xlX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 +#: ports/nrf/common-hal/bleio/Service.c:83 #, c-format -msgid "Can not start advertisement. status: 0x%02x" +msgid "Failed to add characteristic, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 +#: ports/nrf/common-hal/bleio/UUID.c:97 #, c-format -msgid "Can not stop advertisement. status: 0x%02x" +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 -#, c-format -msgid "Can not read attribute value. status: 0x%02x" +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 -#, c-format -msgid "Can not write attribute value. status: 0x%02x" +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 -#, c-format -msgid "Can not notify attribute value. status: 0x%02x" +#: ports/nrf/common-hal/busio/I2C.c:96 +msgid "All I2C peripherals are in use" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 -#, c-format -msgid "Can not start scanning. status: 0x%02x" +#: ports/nrf/common-hal/busio/SPI.c:115 +msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 +#: ports/nrf/common-hal/busio/UART.c:48 #, c-format -msgid "Can not connect. status: 0x%02x" +msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 -msgid "Invalid UUID parameter" +#: ports/nrf/common-hal/busio/UART.c:86 +msgid "Invalid buffer size" msgstr "" -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" +#: ports/nrf/common-hal/busio/UART.c:90 +msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" +#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 +#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 +#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 +#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 +#: ports/nrf/common-hal/busio/UART.c:364 +msgid "busio.UART not available" +msgstr "" + +#: ports/nrf/common-hal/microcontroller/Processor.c:49 +#, c-format +msgid "Can not get temperature. status: 0x%02x" +msgstr "" + +#: ports/nrf/common-hal/pulseio/PWMOut.c:161 +msgid "All PWM peripherals are in use" msgstr "" #: ports/unix/modffi.c:138 @@ -2088,6 +2110,30 @@ msgstr "" msgid "buffer slices must be of equal length" msgstr "" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +msgid "Wrong number of bytes provided" +msgstr "" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" diff --git a/locale/de_DE.po b/locale/de_DE.po index f633c93a4..2ff7acb87 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: 2018-10-25 12:20+1100\n" +"POT-Creation-Date: 2018-11-07 14:10-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: Sebastian Plamauer\n" "Language-Team: \n" @@ -708,6 +708,130 @@ msgstr "" msgid "AnalogOut functionality not supported" msgstr "" +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:135 +#, c-format +msgid "Failed to get softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, fuzzy, c-format +msgid "Failed to write gatts value, status: 0x%08lX" +msgstr "Kann den Attributwert nicht schreiben. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, fuzzy, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" +msgstr "Kann den Attributwert nicht mitteilen. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#, fuzzy, c-format +msgid "Failed to read attribute value, status: 0x%08lX" +msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, fuzzy, c-format +msgid "Failed to write attribute value, status: 0x%08lX" +msgstr "Kann den Attributwert nicht schreiben. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +#, fuzzy +msgid "Can not fit data into the advertisment packet" +msgstr "Daten können nicht in das advertisement packet eingefügt werden." + +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, fuzzy, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" +msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:436 +#, fuzzy, c-format +msgid "Failed to connect, status: 0x%08lX" +msgstr "Kann nicht verbinden. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:513 +#, fuzzy, c-format +msgid "Failed to add service, status: 0x%08lX" +msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:531 +#, fuzzy, c-format +msgid "Failed to start advertisment, status: 0x%08lX" +msgstr "Kann advertisement nicht starten. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:549 +#, fuzzy, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" +msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, fuzzy, c-format +msgid "Failed to start scanning, status: 0x%0xlX" +msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:592 +#, fuzzy, c-format +msgid "Failed to create mutex, status: 0x%0xlX" +msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Service.c:83 +#, c-format +msgid "Failed to add characteristic, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:97 +#, fuzzy, c-format +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgstr "Kann keine herstellerspezifische 128-Bit-UUID hinzufügen." + +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" +msgstr "Ungültige UUID-Stringlänge" + +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" +msgstr "Ungültiger UUID-Parameter" + #: ports/nrf/common-hal/busio/I2C.c:96 #, fuzzy msgid "All I2C peripherals are in use" @@ -751,107 +875,6 @@ msgstr "" msgid "All PWM peripherals are in use" msgstr "Alle timer werden benutzt" -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." -msgstr "Kann GAP Parameter nicht anwenden." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." -msgstr "Kann PPCP Parameter nicht setzen." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." -msgstr "Kann nicht nach der Geräteadresse suchen." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." -msgstr "Kann keine herstellerspezifische 128-Bit-UUID hinzufügen." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." -msgstr "Kann den Dienst nicht hinzufügen." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." -msgstr "Kann das Merkmal nicht hinzufügen." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." -msgstr "Der Gerätename kann nicht im Stack verwendet werden." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." -msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." -msgstr "Kann UUID in das advertisement packet kodieren." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." -msgstr "Daten können nicht in das advertisement packet eingefügt werden." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 -#, c-format -msgid "Can not apply advertisement data. status: 0x%02x" -msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 -#, c-format -msgid "Can not start advertisement. status: 0x%02x" -msgstr "Kann advertisement nicht starten. Status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 -#, c-format -msgid "Can not stop advertisement. status: 0x%02x" -msgstr "Kann advertisement nicht stoppen. Status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 -#, c-format -msgid "Can not read attribute value. status: 0x%02x" -msgstr "Kann den Attributwert nicht lesen. Status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 -#, c-format -msgid "Can not write attribute value. status: 0x%02x" -msgstr "Kann den Attributwert nicht schreiben. Status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 -#, c-format -msgid "Can not notify attribute value. status: 0x%02x" -msgstr "Kann den Attributwert nicht mitteilen. Status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 -#, c-format -msgid "Can not start scanning. status: 0x%02x" -msgstr "Der Scanvorgang kann nicht gestartet werden. Status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 -#, c-format -msgid "Can not connect. status: 0x%02x" -msgstr "Kann nicht verbinden. Status: 0x%02x" - -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 -msgid "Invalid UUID parameter" -msgstr "Ungültiger UUID-Parameter" - -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" -msgstr "Ungültiger Diensttyp" - -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" -msgstr "Ungültige UUID-Stringlänge" - #: ports/unix/modffi.c:138 msgid "Unknown type" msgstr "Unbekannter Typ" @@ -2109,6 +2132,30 @@ msgstr "" msgid "buffer slices must be of equal length" msgstr "" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +msgid "Wrong number of bytes provided" +msgstr "" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" @@ -2478,3 +2525,33 @@ msgstr "" #: shared-module/struct/__init__.c:83 msgid "too many arguments provided with the given format" msgstr "" + +#~ msgid "Invalid Service type" +#~ msgstr "Ungültiger Diensttyp" + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Kann advertisement data nicht anwenden. Status: 0x%02x" + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Kann UUID in das advertisement packet kodieren." + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Kann UUID nicht kodieren, um die Länge zu überprüfen." + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Der Gerätename kann nicht im Stack verwendet werden." + +#~ msgid "Can not add Characteristic." +#~ msgstr "Kann das Merkmal nicht hinzufügen." + +#~ msgid "Can not add Service." +#~ msgstr "Kann den Dienst nicht hinzufügen." + +#~ msgid "Can not query for the device address." +#~ msgstr "Kann nicht nach der Geräteadresse suchen." + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Kann PPCP Parameter nicht setzen." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Kann GAP Parameter nicht anwenden." diff --git a/locale/en_US.po b/locale/en_US.po index db06a23ff..e3a1062e0 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: 2018-10-25 12:20+1100\n" +"POT-Creation-Date: 2018-11-07 14:10-0500\n" "PO-Revision-Date: 2018-07-27 11:55-0700\n" "Last-Translator: \n" "Language-Team: \n" @@ -696,143 +696,165 @@ msgstr "" msgid "AnalogOut functionality not supported" msgstr "" -#: ports/nrf/common-hal/busio/I2C.c:96 -msgid "All I2C peripherals are in use" +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/SPI.c:115 -msgid "All SPI peripherals are in use" +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:48 +#: ports/nrf/common-hal/bleio/Adapter.c:135 #, c-format -msgid "error = 0x%08lX" +msgid "Failed to get softdevice state, error: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:86 -msgid "Invalid buffer size" +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:90 -msgid "Odd parity is not supported" +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, c-format +msgid "Failed to write gatts value, status: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 -#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 -#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 -#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 -#: ports/nrf/common-hal/busio/UART.c:364 -msgid "busio.UART not available" +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/microcontroller/Processor.c:49 +#: ports/nrf/common-hal/bleio/Characteristic.c:91 #, c-format -msgid "Can not get temperature. status: 0x%02x" +msgid "Failed to read attribute value, status: 0x%08lX" msgstr "" -#: ports/nrf/common-hal/pulseio/PWMOut.c:161 -msgid "All PWM peripherals are in use" +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, c-format +msgid "Failed to write attribute value, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +msgid "Can not fit data into the advertisment packet" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." +#: ports/nrf/common-hal/bleio/Device.c:436 +#, c-format +msgid "Failed to connect, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." +#: ports/nrf/common-hal/bleio/Device.c:513 +#, c-format +msgid "Failed to add service, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." +#: ports/nrf/common-hal/bleio/Device.c:531 +#, c-format +msgid "Failed to start advertisment, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." +#: ports/nrf/common-hal/bleio/Device.c:549 +#, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, c-format +msgid "Failed to start scanning, status: 0x%0xlX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 +#: ports/nrf/common-hal/bleio/Device.c:592 #, c-format -msgid "Can not apply advertisement data. status: 0x%02x" +msgid "Failed to create mutex, status: 0x%0xlX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 +#: ports/nrf/common-hal/bleio/Service.c:83 #, c-format -msgid "Can not start advertisement. status: 0x%02x" +msgid "Failed to add characteristic, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 +#: ports/nrf/common-hal/bleio/UUID.c:97 #, c-format -msgid "Can not stop advertisement. status: 0x%02x" +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 -#, c-format -msgid "Can not read attribute value. status: 0x%02x" +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 -#, c-format -msgid "Can not write attribute value. status: 0x%02x" +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 -#, c-format -msgid "Can not notify attribute value. status: 0x%02x" +#: ports/nrf/common-hal/busio/I2C.c:96 +msgid "All I2C peripherals are in use" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 -#, c-format -msgid "Can not start scanning. status: 0x%02x" +#: ports/nrf/common-hal/busio/SPI.c:115 +msgid "All SPI peripherals are in use" msgstr "" -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 +#: ports/nrf/common-hal/busio/UART.c:48 #, c-format -msgid "Can not connect. status: 0x%02x" +msgid "error = 0x%08lX" msgstr "" -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 -msgid "Invalid UUID parameter" +#: ports/nrf/common-hal/busio/UART.c:86 +msgid "Invalid buffer size" msgstr "" -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" +#: ports/nrf/common-hal/busio/UART.c:90 +msgid "Odd parity is not supported" msgstr "" -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" +#: ports/nrf/common-hal/busio/UART.c:322 ports/nrf/common-hal/busio/UART.c:326 +#: ports/nrf/common-hal/busio/UART.c:331 ports/nrf/common-hal/busio/UART.c:336 +#: ports/nrf/common-hal/busio/UART.c:342 ports/nrf/common-hal/busio/UART.c:347 +#: ports/nrf/common-hal/busio/UART.c:352 ports/nrf/common-hal/busio/UART.c:356 +#: ports/nrf/common-hal/busio/UART.c:364 +msgid "busio.UART not available" +msgstr "" + +#: ports/nrf/common-hal/microcontroller/Processor.c:49 +#, c-format +msgid "Can not get temperature. status: 0x%02x" +msgstr "" + +#: ports/nrf/common-hal/pulseio/PWMOut.c:161 +msgid "All PWM peripherals are in use" msgstr "" #: ports/unix/modffi.c:138 @@ -2088,6 +2110,30 @@ msgstr "" msgid "buffer slices must be of equal length" msgstr "" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +msgid "Wrong number of bytes provided" +msgstr "" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" diff --git a/locale/es.po b/locale/es.po index fd92071c0..340741e69 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: 2018-10-25 12:20+1100\n" +"POT-Creation-Date: 2018-11-07 14:10-0500\n" "PO-Revision-Date: 2018-08-24 22:56-0500\n" "Last-Translator: \n" "Language-Team: \n" @@ -709,6 +709,130 @@ msgstr "parámetro config desconocido" msgid "AnalogOut functionality not supported" msgstr "Funcionalidad AnalogOut no soportada" +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:135 +#, c-format +msgid "Failed to get softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, fuzzy, c-format +msgid "Failed to write gatts value, status: 0x%08lX" +msgstr "No se puede escribir el valor del atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, fuzzy, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" +msgstr "No se puede notificar el valor del anuncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#, fuzzy, c-format +msgid "Failed to read attribute value, status: 0x%08lX" +msgstr "No se puede leer el valor del atributo. status 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, fuzzy, c-format +msgid "Failed to write attribute value, status: 0x%08lX" +msgstr "No se puede escribir el valor del atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +#, fuzzy +msgid "Can not fit data into the advertisment packet" +msgstr "Los datos no caben en el paquete de anuncio." + +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, fuzzy, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" +msgstr "No se puede iniciar el escaneo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:436 +#, fuzzy, c-format +msgid "Failed to connect, status: 0x%08lX" +msgstr "No se puede conectar. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:513 +#, fuzzy, c-format +msgid "Failed to add service, status: 0x%08lX" +msgstr "No se puede detener el anuncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:531 +#, fuzzy, c-format +msgid "Failed to start advertisment, status: 0x%08lX" +msgstr "No se puede inicar el anuncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:549 +#, fuzzy, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" +msgstr "No se puede detener el anuncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, fuzzy, c-format +msgid "Failed to start scanning, status: 0x%0xlX" +msgstr "No se puede iniciar el escaneo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:592 +#, fuzzy, c-format +msgid "Failed to create mutex, status: 0x%0xlX" +msgstr "No se puede leer el valor del atributo. status 0x%02x" + +#: ports/nrf/common-hal/bleio/Service.c:83 +#, c-format +msgid "Failed to add characteristic, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:97 +#, fuzzy, c-format +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgstr "No se puede agregar el Vendor Specific 128-bit UUID." + +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" +msgstr "Longitud de string UUID inválida" + +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" +msgstr "Parámetro UUID inválido" + #: ports/nrf/common-hal/busio/I2C.c:96 msgid "All I2C peripherals are in use" msgstr "Todos los timers están siendo usados" @@ -747,107 +871,6 @@ msgstr "No se puede obtener la temperatura. status: 0x%02x" msgid "All PWM peripherals are in use" msgstr "Todos los periféricos PWM en uso" -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." -msgstr "No se pueden aplicar los parámetros GAP." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." -msgstr "No se pueden establecer los parámetros PPCP." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." -msgstr "No se puede consultar la dirección del dispositivo." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." -msgstr "No se puede agregar el Vendor Specific 128-bit UUID." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." -msgstr "No se puede agregar el Servicio." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." -msgstr "No se puede agregar la CaracterÃstica." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." -msgstr "No se puede aplicar el nombre del dispositivo en el stack." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." -msgstr "No se puede codificar el UUID, para revisar la longitud." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." -msgstr "Se puede codificar el UUID en el paquete de anuncio." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." -msgstr "Los datos no caben en el paquete de anuncio." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 -#, c-format -msgid "Can not apply advertisement data. status: 0x%02x" -msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 -#, c-format -msgid "Can not start advertisement. status: 0x%02x" -msgstr "No se puede inicar el anuncio. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 -#, c-format -msgid "Can not stop advertisement. status: 0x%02x" -msgstr "No se puede detener el anuncio. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 -#, c-format -msgid "Can not read attribute value. status: 0x%02x" -msgstr "No se puede leer el valor del atributo. status 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 -#, c-format -msgid "Can not write attribute value. status: 0x%02x" -msgstr "No se puede escribir el valor del atributo. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 -#, c-format -msgid "Can not notify attribute value. status: 0x%02x" -msgstr "No se puede notificar el valor del anuncio. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 -#, c-format -msgid "Can not start scanning. status: 0x%02x" -msgstr "No se puede iniciar el escaneo. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 -#, c-format -msgid "Can not connect. status: 0x%02x" -msgstr "No se puede conectar. status: 0x%02x" - -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 -msgid "Invalid UUID parameter" -msgstr "Parámetro UUID inválido" - -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" -msgstr "Tipo de Servicio inválido" - -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" -msgstr "Longitud de string UUID inválida" - #: ports/unix/modffi.c:138 msgid "Unknown type" msgstr "Tipo desconocido" @@ -2104,6 +2127,30 @@ msgstr "" msgid "buffer slices must be of equal length" msgstr "" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +msgid "Wrong number of bytes provided" +msgstr "" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" @@ -2474,3 +2521,33 @@ msgstr "" #~ msgid "Baud rate too high for this SPI peripheral" #~ msgstr "Baud rate demasiado alto para este periférico SPI" + +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de Servicio inválido" + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "No se puede aplicar los datos de anuncio. status: 0x%02x" + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Se puede codificar el UUID en el paquete de anuncio." + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "No se puede codificar el UUID, para revisar la longitud." + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "No se puede aplicar el nombre del dispositivo en el stack." + +#~ msgid "Can not add Characteristic." +#~ msgstr "No se puede agregar la CaracterÃstica." + +#~ msgid "Can not add Service." +#~ msgstr "No se puede agregar el Servicio." + +#~ msgid "Can not query for the device address." +#~ msgstr "No se puede consultar la dirección del dispositivo." + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "No se pueden establecer los parámetros PPCP." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "No se pueden aplicar los parámetros GAP." diff --git a/locale/fil.po b/locale/fil.po index d0ba55cdb..2a84b506e 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: 2018-10-25 12:20+1100\n" +"POT-Creation-Date: 2018-11-07 14:10-0500\n" "PO-Revision-Date: 2018-08-30 23:04-0700\n" "Last-Translator: Timothy <me@timothygarcia.ca>\n" "Language-Team: fil\n" @@ -711,6 +711,130 @@ msgstr "hindi alam na config param" msgid "AnalogOut functionality not supported" msgstr "Hindi supportado ang AnalogOut" +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:135 +#, c-format +msgid "Failed to get softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, fuzzy, c-format +msgid "Failed to write gatts value, status: 0x%08lX" +msgstr "Hindi maisulat ang attribute value. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, fuzzy, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" +msgstr "Hindi mabalitaan ang attribute value. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#, fuzzy, c-format +msgid "Failed to read attribute value, status: 0x%08lX" +msgstr "Hindi mabasa ang value ng attribute. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, fuzzy, c-format +msgid "Failed to write attribute value, status: 0x%08lX" +msgstr "Hindi maisulat ang attribute value. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +#, fuzzy +msgid "Can not fit data into the advertisment packet" +msgstr "Hindi makasya ang data sa loob ng advertisement packet." + +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, fuzzy, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" +msgstr "Hindi masimulaan mag i-scan. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:436 +#, fuzzy, c-format +msgid "Failed to connect, status: 0x%08lX" +msgstr "Hindi makaconnect. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:513 +#, fuzzy, c-format +msgid "Failed to add service, status: 0x%08lX" +msgstr "Hindi mahinto ang advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:531 +#, fuzzy, c-format +msgid "Failed to start advertisment, status: 0x%08lX" +msgstr "Hindi masimulaan ang advertisement. status 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:549 +#, fuzzy, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" +msgstr "Hindi mahinto ang advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, fuzzy, c-format +msgid "Failed to start scanning, status: 0x%0xlX" +msgstr "Hindi masimulaan mag i-scan. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:592 +#, fuzzy, c-format +msgid "Failed to create mutex, status: 0x%0xlX" +msgstr "Hindi mabasa ang value ng attribute. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Service.c:83 +#, c-format +msgid "Failed to add characteristic, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:97 +#, fuzzy, c-format +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgstr "Hindi maaaring magdagdag ng Vendor Specific na 128-bit UUID." + +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" +msgstr "Mali ang UUID string length" + +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" +msgstr "Mali ang UUID parameter" + #: ports/nrf/common-hal/busio/I2C.c:96 #, fuzzy msgid "All I2C peripherals are in use" @@ -754,107 +878,6 @@ msgstr "Hindi makuha ang temperatura. status 0x%02x" msgid "All PWM peripherals are in use" msgstr "Lahat ng timer ginagamit" -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." -msgstr "Hindi ma-apply ang GAP parameters." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." -msgstr "Hindi ma-set ang PPCP parameters." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." -msgstr "Hindi maaaring mag-query para sa address ng device." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." -msgstr "Hindi maaaring magdagdag ng Vendor Specific na 128-bit UUID." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." -msgstr "Hindi maidaragdag ang serbisyo." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." -msgstr "Hindi mabasa and Characteristic." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." -msgstr "Hindi maaaring ma-aplay ang device name sa stack." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." -msgstr "Hindi ma-encode UUID, para suriin ang haba." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." -msgstr "Maaring i-encode ang UUID sa advertisement packet." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." -msgstr "Hindi makasya ang data sa loob ng advertisement packet." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 -#, c-format -msgid "Can not apply advertisement data. status: 0x%02x" -msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 -#, c-format -msgid "Can not start advertisement. status: 0x%02x" -msgstr "Hindi masimulaan ang advertisement. status 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 -#, c-format -msgid "Can not stop advertisement. status: 0x%02x" -msgstr "Hindi mahinto ang advertisement. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 -#, c-format -msgid "Can not read attribute value. status: 0x%02x" -msgstr "Hindi mabasa ang value ng attribute. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 -#, c-format -msgid "Can not write attribute value. status: 0x%02x" -msgstr "Hindi maisulat ang attribute value. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 -#, c-format -msgid "Can not notify attribute value. status: 0x%02x" -msgstr "Hindi mabalitaan ang attribute value. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 -#, c-format -msgid "Can not start scanning. status: 0x%02x" -msgstr "Hindi masimulaan mag i-scan. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 -#, c-format -msgid "Can not connect. status: 0x%02x" -msgstr "Hindi makaconnect. status: 0x%02x" - -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 -msgid "Invalid UUID parameter" -msgstr "Mali ang UUID parameter" - -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" -msgstr "Mali ang tipo ng serbisyo" - -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" -msgstr "Mali ang UUID string length" - #: ports/unix/modffi.c:138 msgid "Unknown type" msgstr "Hindi alam ang type" @@ -2138,6 +2161,31 @@ msgstr "Mali ang bilang ng bits" msgid "buffer slices must be of equal length" msgstr "aarehas na haba dapat ang buffer slices" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +#, fuzzy +msgid "Wrong number of bytes provided" +msgstr "mali ang bilang ng argumento" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "Kailangan ng lock ang function." @@ -2529,3 +2577,33 @@ msgstr "masyadong maraming mga argumento na ibinigay sa ibinigay na format" #, fuzzy #~ msgid "palette must be displayio.Palette" #~ msgstr "ang palette ay dapat 32 bytes ang haba" + +#~ msgid "Invalid Service type" +#~ msgstr "Mali ang tipo ng serbisyo" + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Hindi ma i-apply ang advertisement data. status: 0x%02x" + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Maaring i-encode ang UUID sa advertisement packet." + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Hindi ma-encode UUID, para suriin ang haba." + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Hindi maaaring ma-aplay ang device name sa stack." + +#~ msgid "Can not add Characteristic." +#~ msgstr "Hindi mabasa and Characteristic." + +#~ msgid "Can not add Service." +#~ msgstr "Hindi maidaragdag ang serbisyo." + +#~ msgid "Can not query for the device address." +#~ msgstr "Hindi maaaring mag-query para sa address ng device." + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Hindi ma-set ang PPCP parameters." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Hindi ma-apply ang GAP parameters." diff --git a/locale/fr.po b/locale/fr.po index b7f3f8a6e..b6d7d4855 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-25 12:53+1100\n" +"POT-Creation-Date: 2018-11-07 14:10-0500\n" "PO-Revision-Date: 2018-08-14 11:01+0200\n" "Last-Translator: Pierrick Couturier <arofarn@arofarn.info>\n" "Language-Team: fr\n" @@ -707,6 +707,129 @@ msgstr "paramètre de config. inconnu" msgid "AnalogOut functionality not supported" msgstr "AnalogOut non supporté" +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:135 +#, c-format +msgid "Failed to get softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, fuzzy, c-format +msgid "Failed to write gatts value, status: 0x%08lX" +msgstr "Impossible d'écrire la valeur de l'attribut. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, fuzzy, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" +msgstr "Impossible de notifier la valeur de l'attribut. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#, fuzzy, c-format +msgid "Failed to read attribute value, status: 0x%08lX" +msgstr "Impossible de lire la valeur de l'attribut. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, fuzzy, c-format +msgid "Failed to write attribute value, status: 0x%08lX" +msgstr "Impossible d'écrire la valeur de l'attribut. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +msgid "Can not fit data into the advertisment packet" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, fuzzy, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" +msgstr "Impossible de commencer à scanner. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:436 +#, fuzzy, c-format +msgid "Failed to connect, status: 0x%08lX" +msgstr "Connection impossible. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:513 +#, c-format +msgid "Failed to add service, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:531 +#, fuzzy, c-format +msgid "Failed to start advertisment, status: 0x%08lX" +msgstr "Impossible de commencer à scanner. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:549 +#, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, fuzzy, c-format +msgid "Failed to start scanning, status: 0x%0xlX" +msgstr "Impossible de commencer à scanner. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:592 +#, fuzzy, c-format +msgid "Failed to create mutex, status: 0x%0xlX" +msgstr "Impossible de lire la valeur de l'attribut. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Service.c:83 +#, c-format +msgid "Failed to add characteristic, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:97 +#, fuzzy, c-format +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgstr "Impossible d'ajouter l'UUID 128bits Vendor Specific" + +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" +msgstr "Longeur de chaîne UUID invalide" + +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" +msgstr "Paramètre UUID invalide" + #: ports/nrf/common-hal/busio/I2C.c:96 #, fuzzy msgid "All I2C peripherals are in use" @@ -751,107 +874,6 @@ msgstr "Impossible de lire la température. status: 0x%02x" msgid "All PWM peripherals are in use" msgstr "Tous les timers sont utilisés" -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." -msgstr "Impossible d'appliquer les paramètres GAP" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." -msgstr "Impossible d'appliquer les paramètres PPCP" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." -msgstr "Impossible d'obtenir l'adresse du périphérique" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." -msgstr "Impossible d'ajouter l'UUID 128bits Vendor Specific" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." -msgstr "Impossible d'ajouter le Service" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." -msgstr "Impossible d'ajouter la Characteristic." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." -msgstr "Impossible d'appliquer le nom de périphérique dans la pile" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." -msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 -#, c-format -msgid "Can not apply advertisement data. status: 0x%02x" -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 -#, c-format -msgid "Can not start advertisement. status: 0x%02x" -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 -#, c-format -msgid "Can not stop advertisement. status: 0x%02x" -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 -#, c-format -msgid "Can not read attribute value. status: 0x%02x" -msgstr "Impossible de lire la valeur de l'attribut. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 -#, c-format -msgid "Can not write attribute value. status: 0x%02x" -msgstr "Impossible d'écrire la valeur de l'attribut. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 -#, c-format -msgid "Can not notify attribute value. status: 0x%02x" -msgstr "Impossible de notifier la valeur de l'attribut. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 -#, c-format -msgid "Can not start scanning. status: 0x%02x" -msgstr "Impossible de commencer à scanner. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 -#, c-format -msgid "Can not connect. status: 0x%02x" -msgstr "Connection impossible. status: 0x%02x" - -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 -msgid "Invalid UUID parameter" -msgstr "Paramètre UUID invalide" - -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" -msgstr "Type de service invalide" - -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" -msgstr "Longeur de chaîne UUID invalide" - #: ports/unix/modffi.c:138 msgid "Unknown type" msgstr "Type inconnu" @@ -2129,6 +2151,31 @@ msgstr "Nombre de bits invalide" msgid "buffer slices must be of equal length" msgstr "les slices de tampon doivent être de longueurs égales" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +#, fuzzy +msgid "Wrong number of bytes provided" +msgstr "mauvais nombres d'arguments" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "La fonction nécessite un verrou." @@ -2204,7 +2251,9 @@ msgstr "" #: shared-bindings/displayio/Palette.c:102 msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" -msgstr "Le tampon couleur doit avoir 3 octets (RVB) ou 4 octets (RVB + octet de padding)" +msgstr "" +"Le tampon couleur doit avoir 3 octets (RVB) ou 4 octets (RVB + octet de " +"padding)" #: shared-bindings/displayio/Palette.c:106 #, fuzzy @@ -2524,9 +2573,33 @@ msgid "too many arguments provided with the given format" msgstr "trop d'arguments fournis avec ce format" #, fuzzy +#~ msgid "palette must be displayio.Palette" +#~ msgstr "palettre doit être displayio.Palette" + +#, fuzzy #~ msgid "value_size must be power of two" #~ msgstr "value_size est une puissance de deux" -#, fuzzy -#~ msgid "palette must be displayio.Palette" -#~ msgstr "palettre doit être displayio.Palette" +#~ msgid "Invalid Service type" +#~ msgstr "Type de service invalide" + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Impossible d'encoder l'UUID pour vérifier la longueur." + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Impossible d'appliquer le nom de périphérique dans la pile" + +#~ msgid "Can not add Characteristic." +#~ msgstr "Impossible d'ajouter la Characteristic." + +#~ msgid "Can not add Service." +#~ msgstr "Impossible d'ajouter le Service" + +#~ msgid "Can not query for the device address." +#~ msgstr "Impossible d'obtenir l'adresse du périphérique" + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossible d'appliquer les paramètres PPCP" + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossible d'appliquer les paramètres GAP" diff --git a/locale/it_IT.po b/locale/it_IT.po index 637dbe0f3..a90a3aa1f 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: 2018-10-25 12:20+1100\n" +"POT-Creation-Date: 2018-11-07 14:10-0500\n" "PO-Revision-Date: 2018-10-02 16:27+0200\n" "Last-Translator: Enrico Paganin <enrico.paganin@mail.com>\n" "Language-Team: \n" @@ -713,6 +713,130 @@ msgstr "parametro di configurazione sconosciuto" msgid "AnalogOut functionality not supported" msgstr "funzionalità AnalogOut non supportata" +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:135 +#, c-format +msgid "Failed to get softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, fuzzy, c-format +msgid "Failed to write gatts value, status: 0x%08lX" +msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, fuzzy, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" +msgstr "Impossibile notificare valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#, fuzzy, c-format +msgid "Failed to read attribute value, status: 0x%08lX" +msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, fuzzy, c-format +msgid "Failed to write attribute value, status: 0x%08lX" +msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +#, fuzzy +msgid "Can not fit data into the advertisment packet" +msgstr "Impossibile inserire dati nel pacchetto di advertisement." + +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, fuzzy, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" +msgstr "Impossible iniziare la scansione. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:436 +#, fuzzy, c-format +msgid "Failed to connect, status: 0x%08lX" +msgstr "Impossibile connettersi. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:513 +#, fuzzy, c-format +msgid "Failed to add service, status: 0x%08lX" +msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:531 +#, fuzzy, c-format +msgid "Failed to start advertisment, status: 0x%08lX" +msgstr "Impossibile avviare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:549 +#, fuzzy, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" +msgstr "Impossibile fermare advertisement. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, fuzzy, c-format +msgid "Failed to start scanning, status: 0x%0xlX" +msgstr "Impossible iniziare la scansione. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:592 +#, fuzzy, c-format +msgid "Failed to create mutex, status: 0x%0xlX" +msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Service.c:83 +#, c-format +msgid "Failed to add characteristic, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:97 +#, fuzzy, c-format +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgstr "Non è possibile aggiungere l'UUID del vendor specifico da 128-bit" + +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" +msgstr "Lunghezza della stringa UUID non valida" + +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" +msgstr "Parametro UUID non valido" + #: ports/nrf/common-hal/busio/I2C.c:96 msgid "All I2C peripherals are in use" msgstr "Tutte le periferiche I2C sono in uso" @@ -755,107 +879,6 @@ msgstr "Impossibile leggere la temperatura. status: 0x%02x" msgid "All PWM peripherals are in use" msgstr "Tutte le periferiche SPI sono in uso" -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." -msgstr "Impossibile applicare i parametri GAP." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." -msgstr "Impossibile impostare i parametri PPCP." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." -msgstr "Non è possibile trovare l'indirizzo del dispositivo." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." -msgstr "Non è possibile aggiungere l'UUID del vendor specifico da 128-bit" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." -msgstr "Non è possibile aggiungere Service." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." -msgstr "Non è possibile aggiungere Characteristic." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." -msgstr "Non è possibile inserire il nome del dipositivo nella lista." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." -msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." -msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." -msgstr "Impossibile inserire dati nel pacchetto di advertisement." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 -#, c-format -msgid "Can not apply advertisement data. status: 0x%02x" -msgstr "Impossible inserire dati advertisement. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 -#, c-format -msgid "Can not start advertisement. status: 0x%02x" -msgstr "Impossibile avviare advertisement. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 -#, c-format -msgid "Can not stop advertisement. status: 0x%02x" -msgstr "Impossibile fermare advertisement. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 -#, c-format -msgid "Can not read attribute value. status: 0x%02x" -msgstr "Impossibile leggere valore dell'attributo. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 -#, c-format -msgid "Can not write attribute value. status: 0x%02x" -msgstr "Impossibile scrivere valore dell'attributo. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 -#, c-format -msgid "Can not notify attribute value. status: 0x%02x" -msgstr "Impossibile notificare valore dell'attributo. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 -#, c-format -msgid "Can not start scanning. status: 0x%02x" -msgstr "Impossible iniziare la scansione. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 -#, c-format -msgid "Can not connect. status: 0x%02x" -msgstr "Impossibile connettersi. status: 0x%02x" - -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 -msgid "Invalid UUID parameter" -msgstr "Parametro UUID non valido" - -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" -msgstr "Tipo di servizio non valido" - -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" -msgstr "Lunghezza della stringa UUID non valida" - #: ports/unix/modffi.c:138 msgid "Unknown type" msgstr "Tipo sconosciuto" @@ -2133,6 +2156,31 @@ msgstr "Numero di bit non valido" msgid "buffer slices must be of equal length" msgstr "slice del buffer devono essere della stessa lunghezza" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +#, fuzzy +msgid "Wrong number of bytes provided" +msgstr "numero di argomenti errato" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" @@ -2510,3 +2558,33 @@ msgstr "'S' e 'O' non sono formati supportati" #: shared-module/struct/__init__.c:83 msgid "too many arguments provided with the given format" msgstr "troppi argomenti forniti con il formato specificato" + +#~ msgid "Invalid Service type" +#~ msgstr "Tipo di servizio non valido" + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Impossible inserire dati advertisement. status: 0x%02x" + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "È possibile codificare l'UUID nel pacchetto di advertisement." + +#~ msgid "Can not encode UUID, to check length." +#~ msgstr "Non è possibile codificare l'UUID, lunghezza da controllare." + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Non è possibile inserire il nome del dipositivo nella lista." + +#~ msgid "Can not add Characteristic." +#~ msgstr "Non è possibile aggiungere Characteristic." + +#~ msgid "Can not add Service." +#~ msgstr "Non è possibile aggiungere Service." + +#~ msgid "Can not query for the device address." +#~ msgstr "Non è possibile trovare l'indirizzo del dispositivo." + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Impossibile impostare i parametri PPCP." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Impossibile applicare i parametri GAP." diff --git a/locale/pt_BR.po b/locale/pt_BR.po index a8eb2dd51..4ee9a32ff 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: 2018-10-25 12:20+1100\n" +"POT-Creation-Date: 2018-11-07 14:10-0500\n" "PO-Revision-Date: 2018-10-02 21:14-0000\n" "Last-Translator: \n" "Language-Team: \n" @@ -696,6 +696,130 @@ msgstr "parâmetro configuração desconhecido" msgid "AnalogOut functionality not supported" msgstr "Funcionalidade AnalogOut não suportada" +#: ports/nrf/common-hal/bleio/Adapter.c:41 +#, c-format +msgid "Soft device assert, id: 0x%08lX, pc: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:125 +#, c-format +msgid "Failed to change softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:135 +#, c-format +msgid "Failed to get softdevice state, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Adapter.c:155 +#, c-format +msgid "Failed to get local address, error: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:52 +#, fuzzy, c-format +msgid "Failed to write gatts value, status: 0x%08lX" +msgstr "Não é possÃvel gravar o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:76 +#, fuzzy, c-format +msgid "Failed to notify attribute value, status: 0x%08lX" +msgstr "Não é possÃvel gravar o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:91 +#, fuzzy, c-format +msgid "Failed to read attribute value, status: 0x%08lX" +msgstr "Não é possÃvel ler o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:119 +#: ports/nrf/common-hal/bleio/Device.c:272 +#: ports/nrf/common-hal/bleio/Device.c:307 +#, c-format +msgid "Failed to acquire mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Characteristic.c:126 +#, fuzzy, c-format +msgid "Failed to write attribute value, status: 0x%08lX" +msgstr "Não é possÃvel gravar o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Characteristic.c:138 +#: ports/nrf/common-hal/bleio/Device.c:284 +#: ports/nrf/common-hal/bleio/Device.c:319 +#: ports/nrf/common-hal/bleio/Device.c:354 +#: ports/nrf/common-hal/bleio/Device.c:391 +#, c-format +msgid "Failed to release mutex, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:81 +#: ports/nrf/common-hal/bleio/Device.c:114 +#, fuzzy +msgid "Can not fit data into the advertisment packet" +msgstr "Não é possÃvel ajustar dados no pacote de anúncios." + +#: ports/nrf/common-hal/bleio/Device.c:266 +#, c-format +msgid "Failed to discover serivices, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:403 +#: ports/nrf/common-hal/bleio/Scanner.c:76 +#, c-format +msgid "Failed to continue scanning, status: 0x%0xlX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:436 +#, c-format +msgid "Failed to connect, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/Device.c:513 +#, fuzzy, c-format +msgid "Failed to add service, status: 0x%08lX" +msgstr "Não pode parar propaganda. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:531 +#, fuzzy, c-format +msgid "Failed to start advertisment, status: 0x%08lX" +msgstr "Não é possÃvel iniciar o anúncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:549 +#, fuzzy, c-format +msgid "Failed to stop advertisment, status: 0x%08lX" +msgstr "Não pode parar propaganda. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:575 +#: ports/nrf/common-hal/bleio/Scanner.c:103 +#, fuzzy, c-format +msgid "Failed to start scanning, status: 0x%0xlX" +msgstr "Não é possÃvel iniciar o anúncio. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Device.c:592 +#, fuzzy, c-format +msgid "Failed to create mutex, status: 0x%0xlX" +msgstr "Não é possÃvel ler o valor do atributo. status: 0x%02x" + +#: ports/nrf/common-hal/bleio/Service.c:83 +#, c-format +msgid "Failed to add characteristic, status: 0x%08lX" +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:97 +#, fuzzy, c-format +msgid "Failed to add Vendor Specific UUID, status: 0x%08lX" +msgstr "Não é possÃvel adicionar o UUID de 128 bits especÃfico do fornecedor." + +#: ports/nrf/common-hal/bleio/UUID.c:102 +msgid "Invalid UUID string length" +msgstr "" + +#: ports/nrf/common-hal/bleio/UUID.c:109 +#: shared-bindings/bleio/Characteristic.c:125 +#: shared-bindings/bleio/Service.c:105 +msgid "Invalid UUID parameter" +msgstr "Parâmetro UUID inválido" + #: ports/nrf/common-hal/busio/I2C.c:96 msgid "All I2C peripherals are in use" msgstr "Todos os periféricos I2C estão em uso" @@ -737,107 +861,6 @@ msgstr "Não pode obter a temperatura. status: 0x%02x" msgid "All PWM peripherals are in use" msgstr "Todos os temporizadores em uso" -#: ports/nrf/drivers/bluetooth/ble_drv.c:199 -msgid "Cannot apply GAP parameters." -msgstr "Não é possÃvel aplicar parâmetros GAP." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:213 -msgid "Cannot set PPCP parameters." -msgstr "Não é possÃvel definir parâmetros PPCP." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:245 -msgid "Can not query for the device address." -msgstr "Não é possÃvel consultar o endereço do dispositivo." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:264 -msgid "Can not add Vendor Specific 128-bit UUID." -msgstr "Não é possÃvel adicionar o UUID de 128 bits especÃfico do fornecedor." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:284 -#: ports/nrf/drivers/bluetooth/ble_drv.c:298 -msgid "Can not add Service." -msgstr "Não é possÃvel adicionar o serviço." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:373 -msgid "Can not add Characteristic." -msgstr "Não é possÃvel adicionar CaracterÃstica." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:400 -msgid "Can not apply device name in the stack." -msgstr "Não é possÃvel aplicar o nome do dispositivo na pilha." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:464 -#: ports/nrf/drivers/bluetooth/ble_drv.c:514 -msgid "Can not encode UUID, to check length." -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:470 -#: ports/nrf/drivers/bluetooth/ble_drv.c:520 -msgid "Can encode UUID into the advertisement packet." -msgstr "Pode codificar o UUID no pacote de anúncios." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:545 -msgid "Can not fit data into the advertisement packet." -msgstr "Não é possÃvel ajustar dados no pacote de anúncios." - -#: ports/nrf/drivers/bluetooth/ble_drv.c:558 -#: ports/nrf/drivers/bluetooth/ble_drv.c:604 -#, c-format -msgid "Can not apply advertisement data. status: 0x%02x" -msgstr "Não é possÃvel aplicar dados de anúncio. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:614 -#, c-format -msgid "Can not start advertisement. status: 0x%02x" -msgstr "Não é possÃvel iniciar o anúncio. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:631 -#, c-format -msgid "Can not stop advertisement. status: 0x%02x" -msgstr "Não pode parar propaganda. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:650 -#: ports/nrf/drivers/bluetooth/ble_drv.c:726 -#, c-format -msgid "Can not read attribute value. status: 0x%02x" -msgstr "Não é possÃvel ler o valor do atributo. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:667 -#: ports/nrf/drivers/bluetooth/ble_drv.c:756 -#, c-format -msgid "Can not write attribute value. status: 0x%02x" -msgstr "Não é possÃvel gravar o valor do atributo. status: 0x%02x" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:691 -#, c-format -msgid "Can not notify attribute value. status: 0x%02x" -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:784 -#, c-format -msgid "Can not start scanning. status: 0x%02x" -msgstr "" - -#: ports/nrf/drivers/bluetooth/ble_drv.c:829 -#, c-format -msgid "Can not connect. status: 0x%02x" -msgstr "" - -#: ports/nrf/modules/ubluepy/ubluepy_characteristic.c:68 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:80 -#: ports/nrf/modules/ubluepy/ubluepy_service.c:132 -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:137 -msgid "Invalid UUID parameter" -msgstr "Parâmetro UUID inválido" - -#: ports/nrf/modules/ubluepy/ubluepy_service.c:73 -msgid "Invalid Service type" -msgstr "Tipo de serviço inválido" - -#: ports/nrf/modules/ubluepy/ubluepy_uuid.c:127 -msgid "Invalid UUID string length" -msgstr "" - #: ports/unix/modffi.c:138 msgid "Unknown type" msgstr "Tipo desconhecido" @@ -2095,6 +2118,30 @@ msgstr "Número inválido de bits" msgid "buffer slices must be of equal length" msgstr "" +#: shared-bindings/bleio/Address.c:101 +msgid "Wrong address length" +msgstr "" + +#: shared-bindings/bleio/Address.c:107 +msgid "Wrong number of bytes provided" +msgstr "" + +#: shared-bindings/bleio/Device.c:210 +msgid "Can't add services in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:226 +msgid "Can't connect in Peripheral mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:256 +msgid "Can't change the name in Central mode" +msgstr "" + +#: shared-bindings/bleio/Device.c:277 shared-bindings/bleio/Device.c:313 +msgid "Can't advertise in Central mode" +msgstr "" + #: shared-bindings/busio/I2C.c:120 msgid "Function requires lock." msgstr "" @@ -2466,3 +2513,30 @@ msgstr "Muitos argumentos fornecidos com o formato dado" #~ msgid "Baud rate too high for this SPI peripheral" #~ msgstr "Taxa de transmissão muito alta para esse periférico SPI" + +#~ msgid "Invalid Service type" +#~ msgstr "Tipo de serviço inválido" + +#~ msgid "Can not apply advertisement data. status: 0x%02x" +#~ msgstr "Não é possÃvel aplicar dados de anúncio. status: 0x%02x" + +#~ msgid "Can encode UUID into the advertisement packet." +#~ msgstr "Pode codificar o UUID no pacote de anúncios." + +#~ msgid "Can not apply device name in the stack." +#~ msgstr "Não é possÃvel aplicar o nome do dispositivo na pilha." + +#~ msgid "Can not add Characteristic." +#~ msgstr "Não é possÃvel adicionar CaracterÃstica." + +#~ msgid "Can not add Service." +#~ msgstr "Não é possÃvel adicionar o serviço." + +#~ msgid "Can not query for the device address." +#~ msgstr "Não é possÃvel consultar o endereço do dispositivo." + +#~ msgid "Cannot set PPCP parameters." +#~ msgstr "Não é possÃvel definir parâmetros PPCP." + +#~ msgid "Cannot apply GAP parameters." +#~ msgstr "Não é possÃvel aplicar parâmetros GAP." diff --git a/ports/nrf/.gitignore b/ports/nrf/.gitignore index ace93515a..227a82e50 100644 --- a/ports/nrf/.gitignore +++ b/ports/nrf/.gitignore @@ -1,6 +1,6 @@ # Nordic files ##################### -drivers/bluetooth/s1*/ +bluetooth/s1*/ # Build files ##################### diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index a1a6a4d35..25ddebc57 100755 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -21,7 +21,7 @@ include ../../py/mkenv.mk -include mpconfigport.mk ifneq ($(SD), ) - include drivers/bluetooth/bluetooth_common.mk + include bluetooth/bluetooth_common.mk endif FROZEN_MPY_DIR = freeze @@ -47,10 +47,9 @@ INC += -I./nrfx INC += -I./nrfx/hal INC += -I./nrfx/mdk INC += -I./nrfx/drivers/include -INC += -I../../lib/mp-readline -INC += -I./drivers/bluetooth -INC += -I./drivers +INC += -I./bluetooth INC += -I./peripherals +INC += -I../../lib/mp-readline INC += -I../../lib/tinyusb/src INC += -I./usb @@ -105,8 +104,8 @@ SRC_C += \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ device/$(MCU_VARIANT)/startup_$(MCU_SUB_VARIANT).c \ - drivers/bluetooth/ble_drv.c \ - drivers/bluetooth/ble_uart.c \ + bluetooth/ble_drv.c \ + bluetooth/ble_uart.c \ lib/libc/string0.c \ lib/mp-readline/readline.c \ lib/oofatfs/ff.c \ @@ -127,18 +126,6 @@ SRC_C += \ peripherals/nrf/timers.c \ supervisor/shared/memory.c -DRIVERS_SRC_C += $(addprefix modules/,\ - ubluepy/modubluepy.c \ - ubluepy/ubluepy_peripheral.c \ - ubluepy/ubluepy_service.c \ - ubluepy/ubluepy_characteristic.c \ - ubluepy/ubluepy_uuid.c \ - ubluepy/ubluepy_delegate.c \ - ubluepy/ubluepy_constants.c \ - ubluepy/ubluepy_descriptor.c \ - ubluepy/ubluepy_scanner.c \ - ubluepy/ubluepy_scan_entry.c \ - ) SRC_COMMON_HAL += \ analogio/AnalogIn.c \ @@ -168,7 +155,13 @@ SRC_COMMON_HAL += \ ifneq ($(SD), ) SRC_COMMON_HAL += \ bleio/__init__.c \ - bleio/Adapter.c + bleio/Adapter.c \ + bleio/Characteristic.c \ + bleio/Descriptor.c \ + bleio/Device.c \ + bleio/Scanner.c \ + bleio/Service.c \ + bleio/UUID.c endif # These don't have corresponding files in each port but are still located in @@ -183,6 +176,15 @@ SRC_BINDINGS_ENUMS = \ math/__init__.c \ util.c +ifneq ($(SD), ) +SRC_BINDINGS_ENUMS += \ + bleio/Address.c \ + bleio/AddressType.c \ + bleio/AdvertisementData.c \ + bleio/ScanEntry.c \ + bleio/UUIDType.c +endif + SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ $(addprefix common-hal/, $(SRC_COMMON_HAL)) diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c new file mode 100644 index 000000000..0b6daf711 --- /dev/null +++ b/ports/nrf/bluetooth/ble_drv.c @@ -0,0 +1,97 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <stdbool.h> +#include <stdio.h> + +#include "ble.h" +#include "ble_drv.h" +#include "nrf_nvic.h" +#include "nrf_sdm.h" +#include "py/misc.h" + +nrf_nvic_state_t nrf_nvic_state = { 0 }; + +__attribute__((aligned(4))) +static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATT_ATT_MTU_DEFAULT)]; + +typedef struct event_handler { + struct event_handler *next; + void *param; + ble_drv_evt_handler_t func; +} event_handler_t; + +static event_handler_t *m_event_handlers; + +void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param) { + event_handler_t *handler = m_new_ll(event_handler_t, 1); + handler->next = NULL; + handler->param = param; + handler->func = func; + + if (m_event_handlers == NULL) { + m_event_handlers = handler; + return; + } + + event_handler_t *it = m_event_handlers; + while (it->next != NULL) { + if ((it->func == func) && (it->param == param)) { + m_free(handler); + return; + } + + it = it->next; + } + + it->next = handler; +} + +void SD_EVT_IRQHandler(void) { + uint32_t evt_id; + while (sd_evt_get(&evt_id) != NRF_ERROR_NOT_FOUND) { +// sd_evt_handler(evt_id); + } + + while (1) { + uint16_t evt_len = sizeof(m_ble_evt_buf); + const uint32_t err_code = sd_ble_evt_get(m_ble_evt_buf, &evt_len); + if (err_code != NRF_SUCCESS) { + if (err_code == NRF_ERROR_DATA_SIZE) { + printf("NRF_ERROR_DATA_SIZE\n"); + } + + break; + } + + event_handler_t *it = m_event_handlers; + while (it != NULL) { + it->func((ble_evt_t *)m_ble_evt_buf, it->param); + it = it->next; + } + } +} diff --git a/ports/nrf/bluetooth/ble_drv.h b/ports/nrf/bluetooth/ble_drv.h new file mode 100644 index 000000000..0443b41b8 --- /dev/null +++ b/ports/nrf/bluetooth/ble_drv.h @@ -0,0 +1,53 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H +#define MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H + +#include "ble.h" + +#if (BLUETOOTH_SD == 132) && (BLE_API_VERSION == 2) +#define NRF52 +#endif + +#define MAX_TX_IN_PROGRESS 10 + +#ifndef BLE_GATT_ATT_MTU_DEFAULT + #define BLE_GATT_ATT_MTU_DEFAULT GATT_MTU_SIZE_DEFAULT +#endif + +#define BLE_CONN_CFG_TAG_CUSTOM 1 + +#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) +#define UNIT_0_625_MS (625) +#define UNIT_10_MS (10000) + +typedef void (*ble_drv_evt_handler_t)(ble_evt_t*, void*); + +void ble_drv_add_event_handler(ble_drv_evt_handler_t func, void *param); + +#endif // MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_DRV_H diff --git a/ports/nrf/bluetooth/ble_uart.c b/ports/nrf/bluetooth/ble_uart.c new file mode 100644 index 000000000..7faaafb0e --- /dev/null +++ b/ports/nrf/bluetooth/ble_uart.c @@ -0,0 +1,196 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <string.h> + +#include "ble.h" +#include "ble_uart.h" +#include "ringbuffer.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "lib/utils/interrupt_char.h" +#include "shared-bindings/bleio/Adapter.h" +#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/Device.h" +#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/bleio/UUID.h" + +#if (MICROPY_PY_BLE_NUS == 1) + +static const char default_name[] = "CP-REPL"; // max 8 chars or uuid won't fit in adv data +static const char NUS_UUID[] = "6e400001-b5a3-f393-e0a9-e50e24dcca9e"; + +#define NUS_RX_UUID 0x0002 +#define NUS_TX_UUID 0x0003 +#define BUFFER_SIZE 128 + +ringBuffer_typedef(uint8_t, ringbuffer_t); + +static bleio_device_obj_t m_device; +static bleio_service_obj_t *m_nus; +static bleio_characteristic_obj_t *m_tx_chara; +static bleio_characteristic_obj_t *m_rx_chara; + +static volatile bool m_cccd_enabled; + +static uint8_t m_rx_ring_buffer_data[BUFFER_SIZE]; +static ringbuffer_t m_rx_ring_buffer = { + .size = sizeof(m_rx_ring_buffer_data) + 1, + .elems = m_rx_ring_buffer_data, +}; + +STATIC void on_ble_evt(ble_evt_t *ble_evt, void *param) { + switch (ble_evt->header.evt_id) { + case BLE_GAP_EVT_DISCONNECTED: + { + mp_obj_t device_obj = MP_OBJ_FROM_PTR(&m_device); + mp_call_function_0(mp_load_attr(device_obj, qstr_from_str("start_advertising"))); + break; + } + + case BLE_GATTS_EVT_WRITE: + { + ble_gatts_evt_write_t *write = &ble_evt->evt.gatts_evt.params.write; + + if (write->handle == m_tx_chara->cccd_handle) { + m_cccd_enabled = true; + } else if (write->handle == m_rx_chara->handle) { + for (size_t i = 0; i < write->len; ++i) { +#if MICROPY_KBD_EXCEPTION + if (write->data[i] == mp_interrupt_char) { + mp_keyboard_interrupt(); + } else +#endif + { + bufferWrite(&m_rx_ring_buffer, write->data[i]); + } + } + } + } + } +} + +void ble_uart_init(void) { + mp_obj_t device_obj = MP_OBJ_FROM_PTR(&m_device); + m_device.base.type = &bleio_device_type; + m_device.service_list = mp_obj_new_list(0, NULL); + m_device.notif_handler = mp_const_none; + m_device.conn_handler = mp_const_none; + m_device.conn_handle = 0xFFFF; + m_device.is_peripheral = true; + m_device.name = mp_obj_new_str(default_name, strlen(default_name), false); + common_hal_bleio_adapter_get_address(&m_device.address); + + mp_obj_t nus_uuid_str = mp_obj_new_str(NUS_UUID, strlen(NUS_UUID), false); + mp_obj_t nus_uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &nus_uuid_str); + mp_obj_t nus_obj = bleio_service_type.make_new(&bleio_service_type, 1, 0, &nus_uuid_obj); + m_nus = MP_OBJ_TO_PTR(nus_obj); + mp_call_function_1(mp_load_attr(device_obj, qstr_from_str("add_service")), nus_obj); + + mp_obj_t tx_uuid_int = mp_obj_new_int(NUS_TX_UUID); + mp_obj_t tx_uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &tx_uuid_int); + mp_obj_t tx_obj = bleio_characteristic_type.make_new(&bleio_characteristic_type, 1, 0, &tx_uuid_obj); + m_tx_chara = MP_OBJ_TO_PTR(tx_obj); + m_tx_chara->uuid->type = UUID_TYPE_128BIT; + m_tx_chara->uuid->uuid_vs_idx = m_nus->uuid->uuid_vs_idx; + m_tx_chara->props.notify = true; + mp_call_function_1(mp_load_attr(nus_obj, qstr_from_str("add_characteristic")), tx_obj); + + mp_obj_t rx_uuid_int = mp_obj_new_int(NUS_RX_UUID); + mp_obj_t rx_uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &rx_uuid_int); + mp_obj_t rx_obj = bleio_characteristic_type.make_new(&bleio_characteristic_type, 1, 0, &rx_uuid_obj); + m_rx_chara = MP_OBJ_TO_PTR(rx_obj); + m_rx_chara->uuid->type = UUID_TYPE_128BIT; + m_rx_chara->uuid->uuid_vs_idx = m_nus->uuid->uuid_vs_idx; + m_rx_chara->props.write = true; + m_rx_chara->props.write_wo_resp = true; + mp_call_function_1(mp_load_attr(nus_obj, qstr_from_str("add_characteristic")), rx_obj); + + mp_call_function_0(mp_load_attr(device_obj, qstr_from_str("start_advertising"))); + + ble_drv_add_event_handler(on_ble_evt, &m_device); + + m_cccd_enabled = false; + + while (!m_cccd_enabled) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } +} + +bool ble_uart_connected(void) { + return (m_device.conn_handle != BLE_CONN_HANDLE_INVALID); +} + +char ble_uart_rx_chr(void) { + while (isBufferEmpty(&m_rx_ring_buffer)) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } + + uint8_t byte; + bufferRead(&m_rx_ring_buffer, byte); + return (int)byte; +} + +bool ble_uart_stdin_any(void) { + return !isBufferEmpty(&m_rx_ring_buffer); +} + +void ble_uart_stdout_tx_str(const char *text) { + mp_hal_stdout_tx_strn(text, strlen(text)); +} + +int mp_hal_stdin_rx_chr(void) { + return ble_uart_rx_chr(); +} + +void mp_hal_stdout_tx_strn(const char *str, size_t len) { + size_t send_len; + + while (len > 0) { + if (len >= BLE_GATT_ATT_MTU_DEFAULT - 3) { + send_len = (BLE_GATT_ATT_MTU_DEFAULT - 3); + } else { + send_len = len; + } + + mp_buffer_info_t bufinfo = { + .buf = (uint8_t*)str, + .len = send_len, + }; + + common_hal_bleio_characteristic_write_value(m_tx_chara, &bufinfo); + + len -= send_len; + str += send_len; + } +} + +#endif // MICROPY_PY_BLE_NUS diff --git a/ports/nrf/drivers/bluetooth/ble_uart.h b/ports/nrf/bluetooth/ble_uart.h index e67176a26..d86e6293a 100644 --- a/ports/nrf/drivers/bluetooth/ble_uart.h +++ b/ports/nrf/bluetooth/ble_uart.h @@ -24,19 +24,17 @@ * THE SOFTWARE. */ -#ifndef BLUETOOTH_LE_UART_H__ -#define BLUETOOTH_LE_UART_H__ +#ifndef MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_UART_H +#define MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_UART_H -#if BLUETOOTH_SD +#include <stdbool.h> -#include "modubluepy.h" #include "ble_drv.h" -void ble_uart_init0(void); -void ble_uart_advertise(void); +void ble_uart_init(void); bool ble_uart_connected(void); -bool ble_uart_enabled(void); +char ble_uart_rx_chr(void); +bool ble_uart_stdin_any(void); +void ble_uart_stdout_tx_str(const char *text); -#endif // BLUETOOTH_SD - -#endif // BLUETOOTH_LE_UART_H__ +#endif // MICROPY_INCLUDED_NRF_BLUETOOTH_BLE_UART_H diff --git a/ports/nrf/drivers/bluetooth/bluetooth_common.mk b/ports/nrf/bluetooth/bluetooth_common.mk index 81e50e333..7dad38e9e 100644 --- a/ports/nrf/drivers/bluetooth/bluetooth_common.mk +++ b/ports/nrf/bluetooth/bluetooth_common.mk @@ -15,11 +15,11 @@ endif CFLAGS += -DBLUETOOTH_SD_DEBUG=1 -INC += -Idrivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include -INC += -Idrivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include/$(MCU_VARIANT) +INC += -Ibluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include +INC += -Ibluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_API/include/$(MCU_VARIANT) SOFTDEV_HEX_NAME = $(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION)_softdevice.hex -SOFTDEV_HEX_PATH = drivers/bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION) +SOFTDEV_HEX_PATH = bluetooth/$(SD)_$(MCU_VARIANT)_$(SOFTDEV_VERSION) SOFTDEV_HEX = $(SOFTDEV_HEX_PATH)/$(SOFTDEV_HEX_NAME) define STACK_MISSING_ERROR @@ -32,7 +32,7 @@ define STACK_MISSING_ERROR # # # Please run the download script: # # # -# drivers/bluetooth/download_ble_stack.sh # +# bluetooth/download_ble_stack.sh # # # ####################################################### diff --git a/ports/nrf/drivers/bluetooth/download_ble_stack.sh b/ports/nrf/bluetooth/download_ble_stack.sh index 385dbb451..385dbb451 100755 --- a/ports/nrf/drivers/bluetooth/download_ble_stack.sh +++ b/ports/nrf/bluetooth/download_ble_stack.sh diff --git a/ports/nrf/drivers/bluetooth/ringbuffer.h b/ports/nrf/bluetooth/ringbuffer.h index 3438b5c9b..9a06e7ccc 100644 --- a/ports/nrf/drivers/bluetooth/ringbuffer.h +++ b/ports/nrf/bluetooth/ringbuffer.h @@ -79,21 +79,21 @@ BUF.elems = (T*)calloc(BUF.size, sizeof(T)) -#define bufferDestroy(BUF) free(BUF->elems) -#define nextStartIndex(BUF) ((BUF->start + 1) % BUF->size) -#define nextEndIndex(BUF) ((BUF->end + 1) % BUF->size) -#define isBufferEmpty(BUF) (BUF->end == BUF->start) -#define isBufferFull(BUF) (nextEndIndex(BUF) == BUF->start) +#define bufferDestroy(BUF) free((BUF)->elems) +#define nextStartIndex(BUF) (((BUF)->start + 1) % (BUF)->size) +#define nextEndIndex(BUF) (((BUF)->end + 1) % (BUF)->size) +#define isBufferEmpty(BUF) ((BUF)->end == (BUF)->start) +#define isBufferFull(BUF) (nextEndIndex(BUF) == (BUF)->start) #define bufferWrite(BUF, ELEM) \ - BUF->elems[BUF->end] = ELEM; \ - BUF->end = (BUF->end + 1) % BUF->size; \ + (BUF)->elems[(BUF)->end] = ELEM; \ + (BUF)->end = ((BUF)->end + 1) % (BUF)->size; \ if (isBufferEmpty(BUF)) { \ - BUF->start = nextStartIndex(BUF); \ + (BUF)->start = nextStartIndex(BUF); \ } #define bufferRead(BUF, ELEM) \ - ELEM = BUF->elems[BUF->start]; \ - BUF->start = nextStartIndex(BUF); + ELEM = (BUF)->elems[(BUF)->start]; \ + (BUF)->start = nextStartIndex(BUF); #endif diff --git a/ports/nrf/boards/feather_nrf52832/README.md b/ports/nrf/boards/feather_nrf52832/README.md index b5acd6360..ef910509a 100644 --- a/ports/nrf/boards/feather_nrf52832/README.md +++ b/ports/nrf/boards/feather_nrf52832/README.md @@ -18,7 +18,7 @@ You then need to download the SD and Nordic SDK files via: ``` $ cd ports/nrf -$ ./drivers/bluetooth/download_ble_stack.sh +$ ./bluetooth/download_ble_stack.sh ``` ## Installing `adafruit-nrfutil` diff --git a/ports/nrf/boards/feather_nrf52840_express/README.md b/ports/nrf/boards/feather_nrf52840_express/README.md index 5d2177ff3..8d515010f 100644 --- a/ports/nrf/boards/feather_nrf52840_express/README.md +++ b/ports/nrf/boards/feather_nrf52840_express/README.md @@ -33,7 +33,7 @@ You then need to download the SD and Nordic SDK files via: ``` $ cd ports/nrf -$ ./drivers/bluetooth/download_ble_stack.sh +$ ./bluetooth/download_ble_stack.sh ``` ## Installing the Serial Bootloader @@ -198,4 +198,4 @@ Converting to uf2, output size: 392192, start address: 0x26000 Wrote 392192 bytes to build-feather52840-s140/firmware.uf2. ``` -Simply drag and drop firmware.uf2 to the MSC, the nrf52840 will blink fast and reset after done.
\ No newline at end of file +Simply drag and drop firmware.uf2 to the MSC, the nrf52840 will blink fast and reset after done. diff --git a/ports/nrf/common-hal/bleio/Adapter.c b/ports/nrf/common-hal/bleio/Adapter.c index 52069e305..985e262e4 100644 --- a/ports/nrf/common-hal/bleio/Adapter.c +++ b/ports/nrf/common-hal/bleio/Adapter.c @@ -26,35 +26,135 @@ */ #include <stdio.h> +#include <string.h> +#include "ble.h" #include "ble_drv.h" -#include "nrfx.h" -#include "nrf_error.h" -#include "py/misc.h" +#include "nrfx_power.h" +#include "nrf_nvic.h" +#include "nrf_sdm.h" +#include "py/nlr.h" +#include "shared-bindings/bleio/Adapter.h" + +STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AssertionError, + translate("Soft device assert, id: 0x%08lX, pc: 0x%08lX"), id, pc)); +} + +STATIC uint32_t ble_stack_enable(void) { + nrf_clock_lf_cfg_t clock_config = { + .source = NRF_CLOCK_LF_SRC_XTAL, +#if (BLE_API_VERSION == 4) + .accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM +#else + .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM +#endif + }; + +#if (BLUETOOTH_SD == 140) + // The SD takes over the POWER IRQ and will fail if the IRQ is already in use + nrfx_power_uninit(); +#endif + + uint32_t err_code = sd_softdevice_enable(&clock_config, softdevice_assert_handler); + if (err_code != NRF_SUCCESS) + return err_code; + + err_code = sd_nvic_EnableIRQ(SD_EVT_IRQn); + if (err_code != NRF_SUCCESS) + return err_code; + + uint32_t app_ram_start; +#if (BLE_API_VERSION == 2) + ble_enable_params_t ble_enable_params = { + .gatts_enable_params.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, + .gap_enable_params.central_conn_count = 1, + .gap_enable_params.periph_conn_count = 1, + }; + + app_ram_start = 0x200039c0; + err_code = sd_ble_enable(&ble_enable_params, &app_ram_start); +#else + app_ram_start = 0x20004000; + + 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.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) + 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.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) + 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) + return err_code; + + err_code = sd_ble_enable(&app_ram_start); +#endif + + return err_code; +} void common_hal_bleio_adapter_set_enabled(bool enabled) { - if (enabled) { - const uint32_t err = ble_drv_stack_enable(); - if (err != NRF_SUCCESS) { - NRFX_ASSERT(err); - } + const bool is_enabled = common_hal_bleio_adapter_get_enabled(); + + // Don't enable or disable twice + if ((is_enabled && enabled) || (!is_enabled && !enabled)) { + return; + } - printf("SoftDevice enabled\n"); + uint32_t err_code; + if (enabled) { + err_code = ble_stack_enable(); } else { - ble_drv_stack_disable(); + err_code = sd_softdevice_disable(); + } + + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to change softdevice state, error: 0x%08lX"), err_code)); } } bool common_hal_bleio_adapter_get_enabled(void) { - return ble_drv_stack_enabled(); + uint8_t is_enabled; + + const uint32_t err_code = sd_softdevice_is_enabled(&is_enabled); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to get softdevice state, error: 0x%08lX"), err_code)); + } + + return is_enabled; } -void common_hal_bleio_adapter_get_address(vstr_t *vstr) { - ble_drv_addr_t address; - ble_drv_address_get(&address); +void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address) { + ble_gap_addr_t local_address; + uint32_t err_code; + + common_hal_bleio_adapter_set_enabled(true); + +#if (BLE_API_VERSION == 2) + err_code = sd_ble_gap_address_get(&local_address); +#else + err_code = sd_ble_gap_addr_get(&local_address); +#endif + + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to get local address, error: 0x%08lX"), err_code)); + } - vstr_printf(vstr, ""HEX2_FMT":"HEX2_FMT":"HEX2_FMT":" \ - HEX2_FMT":"HEX2_FMT":"HEX2_FMT"", - address.addr[5], address.addr[4], address.addr[3], - address.addr[2], address.addr[1], address.addr[0]); + address->type = local_address.addr_type; + memcpy(address->value, local_address.addr, BLEIO_ADDRESS_BYTES); } diff --git a/ports/nrf/common-hal/bleio/Characteristic.c b/ports/nrf/common-hal/bleio/Characteristic.c new file mode 100644 index 000000000..246c35005 --- /dev/null +++ b/ports/nrf/common-hal/bleio/Characteristic.c @@ -0,0 +1,191 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <string.h> +#include <stdio.h> + +#include "ble_drv.h" +#include "ble_gatts.h" +#include "nrf_soc.h" +#include "py/nlr.h" +#include "shared-module/bleio/Characteristic.h" + +static volatile bleio_characteristic_obj_t *m_read_characteristic; +static volatile uint8_t m_tx_in_progress; +static nrf_mutex_t *m_write_mutex; + +STATIC void gatts_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { + bleio_device_obj_t *device = characteristic->service->device; + const uint16_t conn_handle = device->conn_handle; + + 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, characteristic->handle, &gatts_value); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to write gatts value, status: 0x%08lX"), err_code)); + } +} + +STATIC void gatts_notify(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { + bleio_device_obj_t *device = characteristic->service->device; + uint16_t hvx_len = bufinfo->len; + + ble_gatts_hvx_params_t hvx_params = { + .handle = characteristic->handle, + .type = BLE_GATT_HVX_NOTIFICATION, + .p_len = &hvx_len, + .p_data = bufinfo->buf, + }; + + while (m_tx_in_progress > MAX_TX_IN_PROGRESS) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } + + const uint32_t err_code = sd_ble_gatts_hvx(device->conn_handle, &hvx_params); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to notify attribute value, status: 0x%08lX"), err_code)); + } + + m_tx_in_progress += 1; +} + +STATIC void gattc_read(bleio_characteristic_obj_t *characteristic) { + bleio_service_obj_t *service = characteristic->service; + bleio_device_obj_t *device = service->device; + + m_read_characteristic = characteristic; + + const uint32_t err_code = sd_ble_gattc_read(device->conn_handle, characteristic->handle, 0); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to read attribute value, status: 0x%08lX"), err_code)); + } + + while (m_read_characteristic != NULL) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } +} + +STATIC void gattc_write(bleio_characteristic_obj_t *characteristic, mp_buffer_info_t *bufinfo) { + bleio_device_obj_t *device = characteristic->service->device; + uint32_t err_code; + + ble_gattc_write_params_t write_params = { + .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL, + .write_op = BLE_GATT_OP_WRITE_REQ, + .handle = characteristic->handle, + .p_value = bufinfo->buf, + .len = bufinfo->len, + }; + + if (characteristic->props.write_wo_resp) { + write_params.write_op = BLE_GATT_OP_WRITE_CMD; + + err_code = sd_mutex_acquire(m_write_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to acquire mutex, status: 0x%08lX"), err_code)); + } + } + + err_code = sd_ble_gattc_write(device->conn_handle, &write_params); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to write attribute value, status: 0x%08lX"), err_code)); + } + + while (sd_mutex_acquire(m_write_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } + + err_code = sd_mutex_release(m_write_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to release mutex, status: 0x%08lX"), err_code)); + } +} + +STATIC void on_ble_evt(ble_evt_t *ble_evt, void *param) { + switch (ble_evt->header.evt_id) { +#if (BLE_API_VERSION == 4) + case BLE_GATTS_EVT_HVN_TX_COMPLETE: + m_tx_in_progress -= ble_evt->evt.gatts_evt.params.hvn_tx_complete.count; + break; +#else + case BLE_EVT_TX_COMPLETE: + m_tx_in_progress -= ble_evt->evt.common_evt.params.tx_complete.count; + break; +#endif + + case BLE_GATTC_EVT_READ_RSP: + { + ble_gattc_evt_read_rsp_t *response = &ble_evt->evt.gattc_evt.params.read_rsp; + m_read_characteristic->value_data = mp_obj_new_bytearray(response->len, response->data); + m_read_characteristic = NULL; + break; + } + + case BLE_GATTC_EVT_WRITE_RSP: + sd_mutex_release(m_write_mutex); +// m_write_done = true; + break; + } +} + +void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self) { + ble_drv_add_event_handler(on_ble_evt, NULL); +} + +void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self) { + gattc_read(self); +} + +void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { + const bleio_device_obj_t *device = self->service->device; + + if (device->is_peripheral) { + // TODO: Add indications + if (self->props.notify) { + gatts_notify(self, bufinfo); + } else { + gatts_write(self, bufinfo); + } + } else { + gattc_write(self, bufinfo); + } + +} diff --git a/ports/nrf/common-hal/bleio/Descriptor.c b/ports/nrf/common-hal/bleio/Descriptor.c new file mode 100644 index 000000000..9b61345fa --- /dev/null +++ b/ports/nrf/common-hal/bleio/Descriptor.c @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "common-hal/bleio/Descriptor.h" + +void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid) { + self->uuid = uuid; +} + +void common_hal_bleio_descriptor_print(bleio_descriptor_obj_t *self, const mp_print_t *print) { + mp_printf(print, "Descriptor(uuid: 0x" HEX2_FMT HEX2_FMT ")", + self->uuid->value[1], self->uuid->value[0]); +} + +mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self) { + return self->handle; +} + +mp_int_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) { + return self->uuid->value[0] | (self->uuid->value[1] << 8); +} diff --git a/ports/nrf/common-hal/bleio/Descriptor.h b/ports/nrf/common-hal/bleio/Descriptor.h new file mode 100644 index 000000000..ee0886c22 --- /dev/null +++ b/ports/nrf/common-hal/bleio/Descriptor.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H + +#include "py/obj.h" +#include "common-hal/bleio/UUID.h" + +typedef struct { + mp_obj_base_t base; + uint16_t handle; + bleio_uuid_obj_t *uuid; +} bleio_descriptor_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_DESCRIPTOR_H diff --git a/ports/nrf/common-hal/bleio/Device.c b/ports/nrf/common-hal/bleio/Device.c new file mode 100644 index 000000000..2c000ae2e --- /dev/null +++ b/ports/nrf/common-hal/bleio/Device.c @@ -0,0 +1,627 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <string.h> +#include <stdio.h> + +#include "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/Adapter.h" +#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/Device.h" +#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/bleio/UUID.h" + +#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) +#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(300, UNIT_0_625_MS) +#define BLE_SLAVE_LATENCY 0 +#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) + +#define BLE_ADV_LENGTH_FIELD_SIZE 1 +#define BLE_ADV_AD_TYPE_FIELD_SIZE 1 +#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1 + +#ifndef BLE_GAP_ADV_MAX_SIZE +#define BLE_GAP_ADV_MAX_SIZE 31 +#endif + +static bleio_service_obj_t *m_char_discovery_service; +static volatile bool m_discovery_successful; +static nrf_mutex_t *m_discovery_mutex; + +#if (BLUETOOTH_SD == 140) +static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; + +static uint8_t m_scan_buffer_data[BLE_GAP_SCAN_BUFFER_MIN]; + +static ble_data_t m_scan_buffer = { + .p_data = m_scan_buffer_data, + .len = BLE_GAP_SCAN_BUFFER_MIN +}; +#endif + +STATIC uint32_t set_advertisement_data(bleio_device_obj_t *device, bool connectable, mp_buffer_info_t *raw_data) { + common_hal_bleio_adapter_set_enabled(true); + + uint8_t adv_data[BLE_GAP_ADV_MAX_SIZE]; + uint8_t byte_pos = 0; + uint32_t err_code; + +#define ADD_FIELD(field, len) \ + do { \ + if (byte_pos + (len) > BLE_GAP_ADV_MAX_SIZE) { \ + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, \ + translate("Can not fit data into the advertisment packet"))); \ + } \ + adv_data[byte_pos] = (field); \ + byte_pos += (len); \ + } while (0) + + GET_STR_DATA_LEN(device->name, name_data, name_len); + if (name_len > 0) { + 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) { + return err_code; + } + + // TODO: Shorten if too long + + ADD_FIELD(BLE_ADV_AD_TYPE_FIELD_SIZE + name_len, BLE_ADV_LENGTH_FIELD_SIZE); + ADD_FIELD(BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, BLE_ADV_AD_TYPE_FIELD_SIZE); + + memcpy(&adv_data[byte_pos], name_data, name_len); + byte_pos += name_len; + } + + // set flags, default to disc mode + if (raw_data->len == 0) { + ADD_FIELD(BLE_ADV_AD_TYPE_FIELD_SIZE + BLE_AD_TYPE_FLAGS_DATA_SIZE, BLE_ADV_LENGTH_FIELD_SIZE); + ADD_FIELD(BLE_GAP_AD_TYPE_FLAGS, BLE_AD_TYPE_FLAGS_DATA_SIZE); + ADD_FIELD(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE, BLE_AD_TYPE_FLAGS_DATA_SIZE); + } else { + if (byte_pos + raw_data->len > BLE_GAP_ADV_MAX_SIZE) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Can not fit data into the advertisment packet"))); + } + + memcpy(&adv_data[byte_pos], raw_data->buf, raw_data->len); + byte_pos += raw_data->len; + } + + const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(device->service_list); + if (service_list->len > 0) { + bool has_128bit_services = false; + bool has_16bit_services = false; + + for (size_t i = 0; i < service_list->len; ++i) { + const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); + + if (service->is_secondary) { + continue; + } + + if (service->uuid->type == UUID_TYPE_16BIT) { + has_16bit_services = true; + } + + if (service->uuid->type == UUID_TYPE_128BIT) { + has_128bit_services = true; + } + } + + if (has_16bit_services) { + const uint8_t size_byte_pos = byte_pos; + uint8_t uuid_total_size = 0; + + // skip length byte for now, apply total length post calculation + byte_pos += BLE_ADV_LENGTH_FIELD_SIZE; + + ADD_FIELD(BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE, BLE_ADV_AD_TYPE_FIELD_SIZE); + + for (size_t i = 0; i < service_list->len; ++i) { + const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); + uint8_t encoded_size = 0; + + if ((service->uuid->type != UUID_TYPE_16BIT) || service->is_secondary) { + continue; + } + + ble_uuid_t uuid; + uuid.type = BLE_UUID_TYPE_BLE; + uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8); + + err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]); + if (err_code != NRF_SUCCESS) { + return err_code; + } + + uuid_total_size += encoded_size; + byte_pos += encoded_size; + } + + adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size); + } + + if (has_128bit_services) { + const uint8_t size_byte_pos = byte_pos; + uint8_t uuid_total_size = 0; + + // skip length byte for now, apply total length post calculation + byte_pos += BLE_ADV_LENGTH_FIELD_SIZE; + + ADD_FIELD(BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE, BLE_ADV_AD_TYPE_FIELD_SIZE); + + for (size_t i = 0; i < service_list->len; ++i) { + const bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_list->items[i]); + uint8_t encoded_size = 0; + + if ((service->uuid->type != UUID_TYPE_128BIT) || service->is_secondary) { + continue; + } + + ble_uuid_t uuid; + uuid.type = service->uuid->uuid_vs_idx; + uuid.uuid = service->uuid->value[0] | (service->uuid->value[1] << 8); + + err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]); + if (err_code != NRF_SUCCESS) { + return err_code; + } + + uuid_total_size += encoded_size; + byte_pos += encoded_size; + } + + adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size); + } + } + +#if (BLUETOOTH_SD == 132) + err_code = sd_ble_gap_adv_data_set(adv_data, byte_pos, NULL, 0); + if (err_code != NRF_SUCCESS) { + return err_code; + } +#endif + + static ble_gap_adv_params_t m_adv_params = { + .interval = MSEC_TO_UNITS(100, UNIT_0_625_MS), +#if (BLUETOOTH_SD == 140) + .properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED, + .duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED, + .filter_policy = BLE_GAP_ADV_FP_ANY, + .primary_phy = BLE_GAP_PHY_1MBPS, +#else + .type = BLE_GAP_ADV_TYPE_ADV_IND, + .fp = BLE_GAP_ADV_FP_ANY, +#endif + }; + + if (!connectable) { +#if (BLUETOOTH_SD == 140) + m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED; +#else + m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND; +#endif + } + + common_hal_bleio_device_stop_advertising(device); + +#if (BLUETOOTH_SD == 140) + const ble_gap_adv_data_t ble_gap_adv_data = { + .adv_data.p_data = adv_data, + .adv_data.len = byte_pos, + }; + + err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params); + if (err_code != NRF_SUCCESS) { + return err_code; + } + + err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_CONN_CFG_TAG_CUSTOM); +#elif (BLUETOOTH_SD == 132 && BLE_API_VERSION == 4) + err_code = sd_ble_gap_adv_start(&m_adv_params, BLE_CONN_CFG_TAG_CUSTOM); +#else + err_code = sd_ble_gap_adv_start(&m_adv_params); +#endif + + return err_code; +} + +STATIC bool discover_services(bleio_device_obj_t *device, uint16_t start_handle) { + m_discovery_successful = false; + + uint32_t err_code = sd_ble_gattc_primary_services_discover(device->conn_handle, start_handle, NULL); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to discover serivices, status: 0x%08lX"), err_code)); + } + + err_code = sd_mutex_acquire(m_discovery_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to acquire mutex, status: 0x%08lX"), err_code)); + } + + while (sd_mutex_acquire(m_discovery_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } + + err_code = sd_mutex_release(m_discovery_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to release mutex, status: 0x%08lX"), err_code)); + } + + return m_discovery_successful; +} + +STATIC bool discover_characteristics(bleio_device_obj_t *device, bleio_service_obj_t *service, uint16_t start_handle) { + m_char_discovery_service = service; + + ble_gattc_handle_range_t handle_range; + handle_range.start_handle = start_handle; + handle_range.end_handle = service->end_handle; + + m_discovery_successful = false; + + uint32_t err_code = sd_ble_gattc_characteristics_discover(device->conn_handle, &handle_range); + if (err_code != NRF_SUCCESS) { + return false; + } + + err_code = sd_mutex_acquire(m_discovery_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to acquire mutex, status: 0x%08lX"), err_code)); + } + + while (sd_mutex_acquire(m_discovery_mutex) == NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } + + err_code = sd_mutex_release(m_discovery_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to release mutex, status: 0x%08lX"), err_code)); + } + + return m_discovery_successful; +} + +STATIC void on_primary_srv_discovery_rsp(ble_gattc_evt_prim_srvc_disc_rsp_t *response, bleio_device_obj_t *device) { + for (size_t i = 0; i < response->count; ++i) { + const 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; + service->device = device; + service->char_list = mp_obj_new_list(0, NULL); + 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; + + bleio_uuid_obj_t *uuid = m_new_obj(bleio_uuid_obj_t); + uuid->base.type = &bleio_uuid_type; + uuid->type = (gattc_service->uuid.type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT; + uuid->value[0] = gattc_service->uuid.uuid & 0xFF; + uuid->value[1] = gattc_service->uuid.uuid >> 8; + service->uuid = uuid; + + mp_obj_list_append(device->service_list, service); + } + + if (response->count > 0) { + m_discovery_successful = true; + } + + const uint32_t err_code = sd_mutex_release(m_discovery_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to release mutex, status: 0x%08lX"), err_code)); + } +} + +STATIC void on_char_discovery_rsp(ble_gattc_evt_char_disc_rsp_t *response, bleio_device_obj_t *device) { + for (size_t i = 0; i < response->count; ++i) { + const 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 = m_new_obj(bleio_uuid_obj_t); + uuid->base.type = &bleio_uuid_type; + uuid->type = (gattc_char->uuid.type == BLE_UUID_TYPE_BLE) ? UUID_TYPE_16BIT : UUID_TYPE_128BIT; + uuid->value[0] = gattc_char->uuid.uuid & 0xFF; + uuid->value[1] = gattc_char->uuid.uuid >> 8; + characteristic->uuid = uuid; + + characteristic->props.broadcast = gattc_char->char_props.broadcast; + characteristic->props.indicate = gattc_char->char_props.indicate; + characteristic->props.notify = gattc_char->char_props.notify; + characteristic->props.read = gattc_char->char_props.read; + characteristic->props.write = gattc_char->char_props.write; + characteristic->props.write_wo_resp = gattc_char->char_props.write_wo_resp; + characteristic->handle = gattc_char->handle_value; + characteristic->service = m_char_discovery_service; + + mp_obj_list_append(m_char_discovery_service->char_list, MP_OBJ_FROM_PTR(characteristic)); + } + + if (response->count > 0) { + m_discovery_successful = true; + } + + const uint32_t err_code = sd_mutex_release(m_discovery_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to release mutex, status: 0x%08lX"), err_code)); + } +} + +STATIC void on_adv_report(ble_gap_evt_adv_report_t *report, bleio_device_obj_t *device) { + uint32_t err_code; + + if (memcmp(report->peer_addr.addr, device->address.value, BLEIO_ADDRESS_BYTES) != 0) { +#if (BLUETOOTH_SD == 140) + err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to continue scanning, status: 0x%0xlX"), err_code)); + } +#endif + return; + } + + ble_gap_scan_params_t scan_params = { + .active = 1, + .interval = MSEC_TO_UNITS(100, UNIT_0_625_MS), + .window = MSEC_TO_UNITS(100, UNIT_0_625_MS), + }; + + ble_gap_addr_t addr; + memset(&addr, 0, sizeof(addr)); + + addr.addr_type = report->peer_addr.addr_type; + memcpy(addr.addr, report->peer_addr.addr, BLEIO_ADDRESS_BYTES); + + ble_gap_conn_params_t conn_params = { + .min_conn_interval = BLE_MIN_CONN_INTERVAL, + .max_conn_interval = BLE_MAX_CONN_INTERVAL, + .conn_sup_timeout = BLE_CONN_SUP_TIMEOUT, + .slave_latency = BLE_SLAVE_LATENCY, + }; + +#if (BLE_API_VERSION == 2) + err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params); +#else + err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_CUSTOM); +#endif + + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to connect, status: 0x%08lX"), err_code)); + } +} + +STATIC void on_ble_evt(ble_evt_t *ble_evt, void *device_in) { + bleio_device_obj_t *device = (bleio_device_obj_t*)device_in; + + switch (ble_evt->header.evt_id) { + case BLE_GAP_EVT_CONNECTED: + { + ble_gap_conn_params_t conn_params; + device->conn_handle = ble_evt->evt.gap_evt.conn_handle; + + sd_ble_gap_ppcp_get(&conn_params); + sd_ble_gap_conn_param_update(ble_evt->evt.gap_evt.conn_handle, &conn_params); + break; + } + + case BLE_GAP_EVT_DISCONNECTED: + device->conn_handle = BLE_CONN_HANDLE_INVALID; + break; + + case BLE_GAP_EVT_ADV_REPORT: + on_adv_report(&ble_evt->evt.gap_evt.params.adv_report, device); + 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_GATTS_EVT_SYS_ATTR_MISSING: + sd_ble_gatts_sys_attr_set(ble_evt->evt.gatts_evt.conn_handle, NULL, 0, 0); + break; + +#if (BLE_API_VERSION == 4) + case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: + sd_ble_gatts_exchange_mtu_reply(device->conn_handle, BLE_GATT_ATT_MTU_DEFAULT); + break; +#endif + + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: + sd_ble_gap_sec_params_reply(device->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(device->conn_handle, &request->conn_params); + break; + } + } +} + +void common_hal_bleio_device_add_service(bleio_device_obj_t *device, bleio_service_obj_t *service) { + ble_uuid_t uuid = { + .type = BLE_UUID_TYPE_BLE, + .uuid = service->uuid->value[0] | (service->uuid->value[1] << 8) + }; + + if (service->uuid->type == UUID_TYPE_128BIT) { + uuid.type = service->uuid->uuid_vs_idx; + } + + uint8_t service_type = BLE_GATTS_SRVC_TYPE_PRIMARY; + if (service->is_secondary) { + service_type = BLE_GATTS_SRVC_TYPE_SECONDARY; + } + + common_hal_bleio_adapter_set_enabled(true); + + const uint32_t err_code = sd_ble_gatts_service_add(service_type, &uuid, &service->handle); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to add service, status: 0x%08lX"), err_code)); + } + + const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(service->char_list); + for (size_t i = 0; i < char_list->len; ++i) { + bleio_characteristic_obj_t *characteristic = char_list->items[i]; + common_hal_bleio_service_add_characteristic(service, characteristic); + } +} + +void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bool connectable, mp_buffer_info_t *raw_data) { + if (connectable) { + ble_drv_add_event_handler(on_ble_evt, device); + } + + const uint32_t err_code = set_advertisement_data(device, connectable, raw_data); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to start advertisment, status: 0x%08lX"), err_code)); + } +} + +void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device) { + uint32_t err_code; + +#if (BLUETOOTH_SD == 140) + if (m_adv_handle == BLE_GAP_ADV_SET_HANDLE_NOT_SET) + return; + + err_code = sd_ble_gap_adv_stop(m_adv_handle); +#else + err_code = sd_ble_gap_adv_stop(); +#endif + + if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to stop advertisment, status: 0x%08lX"), err_code)); + } +} + +void common_hal_bleio_device_connect(bleio_device_obj_t *device) { + ble_drv_add_event_handler(on_ble_evt, device); + + 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), +#if (BLUETOOTH_SD == 140) + .scan_phys = BLE_GAP_PHY_1MBPS, +#endif + }; + + common_hal_bleio_adapter_set_enabled(true); + + uint32_t err_code; +#if (BLUETOOTH_SD == 140) + err_code = sd_ble_gap_scan_start(&scan_params, &m_scan_buffer); +#else + err_code = sd_ble_gap_scan_start(&scan_params); +#endif + + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to start scanning, status: 0x%0xlX"), err_code)); + } + + while (device->conn_handle == BLE_CONN_HANDLE_INVALID) { +#ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP +#endif + } + + // TODO: read name + + if (m_discovery_mutex == NULL) { + m_discovery_mutex = m_new_ll(nrf_mutex_t, 1); + + err_code = sd_mutex_new(m_discovery_mutex); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to create mutex, status: 0x%0xlX"), err_code)); + } + } + + // find services + bool found_service = discover_services(device, BLE_GATT_HANDLE_START); + while (found_service) { + const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(device->service_list); + const bleio_service_obj_t *service = service_list->items[service_list->len - 1]; + + found_service = discover_services(device, service->end_handle + 1); + } + + // find characteristics in each service + const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(device->service_list); + for (size_t i = 0; i < service_list->len; ++i) { + bleio_service_obj_t *service = service_list->items[i]; + + bool found_char = discover_characteristics(device, service, service->start_handle); + while (found_char) { + const mp_obj_list_t *char_list = MP_OBJ_TO_PTR(service->char_list); + const bleio_characteristic_obj_t *characteristic = char_list->items[char_list->len - 1]; + + const uint16_t next_handle = characteristic->handle + 1; + if (next_handle >= service->end_handle) { + break; + } + + found_char = discover_characteristics(device, service, next_handle); + } + } +} + +void common_hal_bleio_device_disconnect(bleio_device_obj_t *device) { + sd_ble_gap_disconnect(device->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); +} diff --git a/ports/nrf/common-hal/bleio/Scanner.c b/ports/nrf/common-hal/bleio/Scanner.c new file mode 100644 index 000000000..e56c1860c --- /dev/null +++ b/ports/nrf/common-hal/bleio/Scanner.c @@ -0,0 +1,110 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <string.h> + +#include "ble_drv.h" +#include "ble_gap.h" +#include "py/mphal.h" +#include "py/nlr.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" + +#if (BLUETOOTH_SD == 140) +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 +}; +#endif + +STATIC void 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; + } + + // TODO: Don't add new entry for each item, group by address and update + bleio_scanentry_obj_t *entry = m_new_obj(bleio_scanentry_obj_t); + entry->base.type = &bleio_scanentry_type; + entry->rssi = report->rssi; + + entry->address.type = report->peer_addr.addr_type; + memcpy(entry->address.value, report->peer_addr.addr, BLEIO_ADDRESS_BYTES); + +#if (BLUETOOTH_SD == 140) + entry->data = mp_obj_new_bytearray(report->data.len, report->data.p_data); +#else + entry->data = mp_obj_new_bytearray(report->dlen, report->data); +#endif + + mp_obj_list_append(scanner->adv_reports, entry); + +#if (BLUETOOTH_SD == 140) + const uint32_t err_code = sd_ble_gap_scan_start(NULL, &m_scan_buffer); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to continue scanning, status: 0x%0xlX"), err_code)); + } +#endif +} + +void common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_int_t timeout) { + ble_drv_add_event_handler(on_ble_evt, self); + + ble_gap_scan_params_t scan_params = { + .interval = MSEC_TO_UNITS(self->interval, UNIT_0_625_MS), + .window = MSEC_TO_UNITS(self->window, UNIT_0_625_MS), +#if (BLUETOOTH_SD == 140) + .scan_phys = BLE_GAP_PHY_1MBPS, +#endif + }; + + common_hal_bleio_adapter_set_enabled(true); + + uint32_t err_code; +#if (BLUETOOTH_SD == 140) + err_code = sd_ble_gap_scan_start(&scan_params, &m_scan_buffer); +#else + err_code = sd_ble_gap_scan_start(&scan_params); +#endif + + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to start scanning, status: 0x%0xlX"), err_code)); + } + + if (timeout > 0) { + mp_hal_delay_ms(timeout); + sd_ble_gap_scan_stop(); + } +} diff --git a/ports/nrf/common-hal/bleio/Service.c b/ports/nrf/common-hal/bleio/Service.c new file mode 100644 index 000000000..c17c16904 --- /dev/null +++ b/ports/nrf/common-hal/bleio/Service.c @@ -0,0 +1,90 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "ble_drv.h" +#include "ble.h" +#include "py/nlr.h" +#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/bleio/Adapter.h" + +void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic) { + ble_gatts_char_md_t char_md = { + .char_props.broadcast = characteristic->props.broadcast, + .char_props.read = characteristic->props.read, + .char_props.write_wo_resp = characteristic->props.write_wo_resp, + .char_props.write = characteristic->props.write, + .char_props.notify = characteristic->props.notify, + .char_props.indicate = characteristic->props.indicate, + }; + + ble_gatts_attr_md_t cccd_md = { + .vloc = BLE_GATTS_VLOC_STACK, + }; + + if (char_md.char_props.notify || char_md.char_props.indicate) { + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); + + char_md.p_cccd_md = &cccd_md; + } + + ble_uuid_t uuid = { + .type = BLE_UUID_TYPE_BLE, + .uuid = characteristic->uuid->value[0] | (characteristic->uuid->value[1] << 8), + }; + + if (characteristic->uuid->type == UUID_TYPE_128BIT) + uuid.type = characteristic->uuid->uuid_vs_idx; + + ble_gatts_attr_md_t attr_md = { + .vloc = BLE_GATTS_VLOC_STACK, + .vlen = 1, + }; + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + + ble_gatts_attr_t attr_char_value = { + .p_uuid = &uuid, + .p_attr_md = &attr_md, + .init_len = sizeof(uint8_t), + .max_len = (BLE_GATT_ATT_MTU_DEFAULT - 3), + }; + + ble_gatts_char_handles_t handles; + + uint32_t err_code; + err_code = sd_ble_gatts_characteristic_add(self->handle, &char_md, &attr_char_value, &handles); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to add characteristic, status: 0x%08lX"), err_code)); + } + + characteristic->user_desc_handle = handles.user_desc_handle; + characteristic->cccd_handle = handles.cccd_handle; + characteristic->sccd_handle = handles.sccd_handle; + characteristic->handle = handles.value_handle; +} diff --git a/ports/nrf/common-hal/bleio/UUID.c b/ports/nrf/common-hal/bleio/UUID.c new file mode 100644 index 000000000..9a2e101ea --- /dev/null +++ b/ports/nrf/common-hal/bleio/UUID.c @@ -0,0 +1,124 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "ble.h" +#include "ble_drv.h" +#include "common-hal/bleio/UUID.h" +#include "nrf_error.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/Adapter.h" +#include "shared-bindings/bleio/UUID.h" + +#define UUID_STR_16BIT_LEN 6 +#define UUID_STR_128BIT_LEN 36 + +static uint8_t xdigit_8b_value(byte nibble1, byte nibble2) { + return unichar_xdigit_value(nibble1) | + (unichar_xdigit_value(nibble2) << 4); +} + +void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, const mp_obj_t *uuid) { + if (MP_OBJ_IS_INT(*uuid)) { + self->type = UUID_TYPE_16BIT; + + self->value[1] = (mp_obj_get_int(*uuid) >> 8) & 0xFF; + self->value[0] = (mp_obj_get_int(*uuid) >> 0) & 0xFF; + return; + } + + if (MP_OBJ_IS_STR(*uuid)) { + GET_STR_DATA_LEN(*uuid, str_data, str_len); + + if (str_len == UUID_STR_16BIT_LEN) { + self->type = UUID_TYPE_16BIT; + + self->value[0] = xdigit_8b_value(str_data[5], str_data[4]); + self->value[1] = xdigit_8b_value(str_data[3], str_data[2]); + } else if (str_len == UUID_STR_128BIT_LEN) { + self->type = UUID_TYPE_128BIT; + + ble_uuid128_t vs_uuid; + vs_uuid.uuid128[0] = xdigit_8b_value(str_data[35], str_data[34]); + vs_uuid.uuid128[1] = xdigit_8b_value(str_data[33], str_data[32]); + vs_uuid.uuid128[2] = xdigit_8b_value(str_data[31], str_data[30]); + vs_uuid.uuid128[3] = xdigit_8b_value(str_data[29], str_data[28]); + vs_uuid.uuid128[4] = xdigit_8b_value(str_data[27], str_data[26]); + vs_uuid.uuid128[5] = xdigit_8b_value(str_data[25], str_data[24]); + + // 23 '-' + vs_uuid.uuid128[6] = xdigit_8b_value(str_data[22], str_data[21]); + vs_uuid.uuid128[7] = xdigit_8b_value(str_data[20], str_data[19]); + + // 18 '-' + vs_uuid.uuid128[8] = xdigit_8b_value(str_data[17], str_data[16]); + vs_uuid.uuid128[9] = xdigit_8b_value(str_data[15], str_data[14]); + + // 13 '-' + vs_uuid.uuid128[10] = xdigit_8b_value(str_data[12], str_data[11]); + vs_uuid.uuid128[11] = xdigit_8b_value(str_data[10], str_data[9]); + + // 8 '-' + self->value[0] = xdigit_8b_value(str_data[7], str_data[6]); + self->value[1] = xdigit_8b_value(str_data[5], str_data[4]); + + vs_uuid.uuid128[14] = xdigit_8b_value(str_data[3], str_data[2]); + vs_uuid.uuid128[15] = xdigit_8b_value(str_data[1], str_data[0]); + + common_hal_bleio_adapter_set_enabled(true); + + const uint32_t err_code = sd_ble_uuid_vs_add(&vs_uuid, &self->uuid_vs_idx); + if (err_code != NRF_SUCCESS) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + translate("Failed to add Vendor Specific UUID, status: 0x%08lX"), err_code)); + } + + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + translate("Invalid UUID string length"))); + } + + return; + } + + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + translate("Invalid UUID parameter"))); +} + +void common_hal_bleio_uuid_print(bleio_uuid_obj_t *self, const mp_print_t *print) { + if (self->type == UUID_TYPE_16BIT) { + mp_printf(print, "UUID(uuid: 0x" HEX2_FMT HEX2_FMT ")", + self->value[1], self->value[0]); + } else { + mp_printf(print, "UUID(uuid: 0x" HEX2_FMT HEX2_FMT ", VS idx: " HEX2_FMT ")", + self->value[1], self->value[0], self->uuid_vs_idx); + } +} + +bleio_uuid_type_t common_hal_bleio_uuid_get_type(bleio_uuid_obj_t *self) { + return self->type; +} diff --git a/ports/nrf/common-hal/bleio/UUID.h b/ports/nrf/common-hal/bleio/UUID.h new file mode 100644 index 000000000..cb0fddcfd --- /dev/null +++ b/ports/nrf/common-hal/bleio/UUID.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H + +#include "shared-bindings/bleio/UUIDType.h" + +typedef struct { + mp_obj_base_t base; + bleio_uuid_type_t type; + uint8_t uuid_vs_idx; + uint8_t value[2]; +} bleio_uuid_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_UUID_H diff --git a/ports/nrf/drivers/bluetooth/ble_drv.c b/ports/nrf/drivers/bluetooth/ble_drv.c deleted file mode 100644 index 3f21f8c49..000000000 --- a/ports/nrf/drivers/bluetooth/ble_drv.c +++ /dev/null @@ -1,1117 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * 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. - */ - -#if BLUETOOTH_SD - -#include <stdio.h> -#include <string.h> -#include <stdbool.h> - -#if (BLUETOOTH_SD == 132) -#define NRF52 // Needed for SD132 v2 -#endif - -#include "py/runtime.h" -#include "supervisor/shared/translate.h" -#include "ble_drv.h" -#include "mpconfigport.h" -#include "nrf_sdm.h" -#include "nrfx_power.h" -#include "ble_gap.h" -#include "ble.h" // sd_ble_uuid_encode - - -#define BLE_DRIVER_VERBOSE 0 -#if BLE_DRIVER_VERBOSE -#define BLE_DRIVER_LOG printf -#else -#define BLE_DRIVER_LOG(...) -#endif - -#define BLE_ADV_LENGTH_FIELD_SIZE 1 -#define BLE_ADV_AD_TYPE_FIELD_SIZE 1 -#define BLE_AD_TYPE_FLAGS_DATA_SIZE 1 - -#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) -#define UNIT_0_625_MS (625) -#define UNIT_10_MS (10000) -#define APP_CFG_NON_CONN_ADV_TIMEOUT 0 // Disable timeout. -#define NON_CONNECTABLE_ADV_INTERVAL MSEC_TO_UNITS(100, UNIT_0_625_MS) - -#define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(12, UNIT_0_625_MS) -#define BLE_MAX_CONN_INTERVAL MSEC_TO_UNITS(12, UNIT_0_625_MS) -#define BLE_SLAVE_LATENCY 0 -#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) - -#ifndef BLE_GAP_ADV_MAX_SIZE -#define BLE_GAP_ADV_MAX_SIZE 31 -#endif - -#define SD_TEST_OR_ENABLE() \ -if (ble_drv_stack_enabled() == 0) { \ - (void)ble_drv_stack_enable(); \ -} - -static volatile bool m_adv_in_progress; -static volatile bool m_tx_in_progress; - -static ble_drv_gap_evt_callback_t gap_event_handler; -static ble_drv_gatts_evt_callback_t gatts_event_handler; - -static mp_obj_t mp_gap_observer; -static mp_obj_t mp_gatts_observer; - -static volatile bool m_primary_service_found; -static volatile bool m_characteristic_found; -static volatile bool m_write_done; - -static volatile ble_drv_adv_evt_callback_t adv_event_handler; -static volatile ble_drv_gattc_evt_callback_t gattc_event_handler; -static volatile ble_drv_disc_add_service_callback_t disc_add_service_handler; -static volatile ble_drv_disc_add_char_callback_t disc_add_char_handler; -static volatile ble_drv_gattc_char_data_callback_t gattc_char_data_handle; - -static mp_obj_t mp_adv_observer; -static mp_obj_t mp_gattc_observer; -static mp_obj_t mp_gattc_disc_service_observer; -static mp_obj_t mp_gattc_disc_char_observer; -static mp_obj_t mp_gattc_char_data_observer; - -#if (BLUETOOTH_SD == 140) -static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; -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 -}; -#endif - -#include "nrf_nvic.h" - -nrf_nvic_state_t nrf_nvic_state = {0}; - -void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { - BLE_DRIVER_LOG("ERROR: SoftDevice assert!!!"); -} - -uint32_t ble_drv_stack_enable(void) { - m_adv_in_progress = false; - m_tx_in_progress = false; - -#if BLUETOOTH_LFCLK_RC - nrf_clock_lf_cfg_t clock_config = { - .source = NRF_CLOCK_LF_SRC_RC, - .rc_ctiv = 16, - .rc_temp_ctiv = 2, -#if (BLE_API_VERSION == 4) - .accuracy = 0 -#else - .xtal_accuracy = 0 -#endif - }; -#else - nrf_clock_lf_cfg_t clock_config = { - .source = NRF_CLOCK_LF_SRC_XTAL, - .rc_ctiv = 0, - .rc_temp_ctiv = 0, -#if (BLE_API_VERSION == 4) - .accuracy = NRF_CLOCK_LF_ACCURACY_20_PPM -#else - .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM -#endif - }; -#endif - -#if (BLUETOOTH_SD == 140) - // The SD takes over the POWER IRQ and will fail if the IRQ is already in use - nrfx_power_uninit(); -#endif - - uint32_t err_code = sd_softdevice_enable(&clock_config, - softdevice_assert_handler); - - BLE_DRIVER_LOG("SoftDevice enable status: " UINT_FMT "\n", (uint16_t)err_code); - - err_code = sd_nvic_EnableIRQ(SWI2_EGU2_IRQn); - - BLE_DRIVER_LOG("IRQ enable status: " UINT_FMT "\n", (uint16_t)err_code); - - // Enable BLE stack. -#if (BLE_API_VERSION == 2) - ble_enable_params_t ble_enable_params; - memset(&ble_enable_params, 0x00, sizeof(ble_enable_params)); - ble_enable_params.gatts_enable_params.attr_tab_size = BLE_GATTS_ATTR_TAB_SIZE_DEFAULT; - ble_enable_params.gatts_enable_params.service_changed = 0; - ble_enable_params.gap_enable_params.periph_conn_count = 1; - ble_enable_params.gap_enable_params.central_conn_count = 1; -#endif - -#if (BLE_API_VERSION == 2) - uint32_t app_ram_start = 0x200039c0; - err_code = sd_ble_enable(&ble_enable_params, &app_ram_start); // 8K SD headroom from linker script. - BLE_DRIVER_LOG("BLE ram size: " UINT_FMT "\n", (uint16_t)app_ram_start); -#else - uint32_t app_ram_start = 0x20004000; - err_code = sd_ble_enable(&app_ram_start); - BLE_DRIVER_LOG("BLE ram size: " UINT_FMT "\n", (uint16_t)app_ram_start); -#endif - - - BLE_DRIVER_LOG("BLE enable status: " UINT_FMT "\n", (uint16_t)err_code); - - // set up security mode - ble_gap_conn_params_t gap_conn_params; - ble_gap_conn_sec_mode_t sec_mode; - - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); - - const char device_name[] = "micr"; - - if ((err_code = sd_ble_gap_device_name_set(&sec_mode, - (const uint8_t *)device_name, - strlen(device_name))) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Cannot apply GAP parameters."))); - } - - // set connection parameters - memset(&gap_conn_params, 0, sizeof(gap_conn_params)); - - gap_conn_params.min_conn_interval = BLE_MIN_CONN_INTERVAL; - gap_conn_params.max_conn_interval = BLE_MAX_CONN_INTERVAL; - gap_conn_params.slave_latency = BLE_SLAVE_LATENCY; - gap_conn_params.conn_sup_timeout = BLE_CONN_SUP_TIMEOUT; - - if (sd_ble_gap_ppcp_set(&gap_conn_params) != 0) { - - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Cannot set PPCP parameters."))); - } - - return err_code; -} - -void ble_drv_stack_disable(void) { - sd_softdevice_disable(); -} - -uint8_t ble_drv_stack_enabled(void) { - uint8_t is_enabled; - uint32_t err_code = sd_softdevice_is_enabled(&is_enabled); - (void)err_code; - - BLE_DRIVER_LOG("Is enabled status: " UINT_FMT "\n", (uint16_t)err_code); - - return is_enabled; -} - -void ble_drv_address_get(ble_drv_addr_t * p_addr) { - SD_TEST_OR_ENABLE(); - - ble_gap_addr_t local_ble_addr; -#if (BLE_API_VERSION == 2) - uint32_t err_code = sd_ble_gap_address_get(&local_ble_addr); -#else - uint32_t err_code = sd_ble_gap_addr_get(&local_ble_addr); -#endif - - if (err_code != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not query for the device address."))); - } - - BLE_DRIVER_LOG("ble address, type: " HEX2_FMT ", " \ - "address: " HEX2_FMT ":" HEX2_FMT ":" HEX2_FMT ":" \ - HEX2_FMT ":" HEX2_FMT ":" HEX2_FMT "\n", \ - local_ble_addr.addr_type, \ - local_ble_addr.addr[5], local_ble_addr.addr[4], local_ble_addr.addr[3], \ - local_ble_addr.addr[2], local_ble_addr.addr[1], local_ble_addr.addr[0]); - - p_addr->addr_type = local_ble_addr.addr_type; - memcpy(p_addr->addr, local_ble_addr.addr, 6); -} - -bool ble_drv_uuid_add_vs(uint8_t * p_uuid, uint8_t * idx) { - SD_TEST_OR_ENABLE(); - - if (sd_ble_uuid_vs_add((ble_uuid128_t const *)p_uuid, idx) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not add Vendor Specific 128-bit UUID."))); - } - - return true; -} - -bool ble_drv_service_add(ubluepy_service_obj_t * p_service_obj) { - SD_TEST_OR_ENABLE(); - - if (p_service_obj->p_uuid->type > BLE_UUID_TYPE_BLE) { - - ble_uuid_t uuid; - uuid.type = p_service_obj->p_uuid->uuid_vs_idx; - uuid.uuid = p_service_obj->p_uuid->value[0]; - uuid.uuid += p_service_obj->p_uuid->value[1] << 8; - - if (sd_ble_gatts_service_add(p_service_obj->type, - &uuid, - &p_service_obj->handle) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not add Service."))); - } - } else if (p_service_obj->p_uuid->type == BLE_UUID_TYPE_BLE) { - BLE_DRIVER_LOG("adding service\n"); - - ble_uuid_t uuid; - uuid.type = p_service_obj->p_uuid->type; - uuid.uuid = p_service_obj->p_uuid->value[0]; - uuid.uuid += p_service_obj->p_uuid->value[1] << 8; - - if (sd_ble_gatts_service_add(p_service_obj->type, - &uuid, - &p_service_obj->handle) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not add Service."))); - } - } - return true; -} - -bool ble_drv_characteristic_add(ubluepy_characteristic_obj_t * p_char_obj) { - ble_gatts_char_md_t char_md; - ble_gatts_attr_md_t cccd_md; - ble_gatts_attr_t attr_char_value; - ble_uuid_t uuid; - ble_gatts_attr_md_t attr_md; - - memset(&char_md, 0, sizeof(char_md)); - - char_md.char_props.broadcast = (p_char_obj->props & UBLUEPY_PROP_BROADCAST) ? 1 : 0; - char_md.char_props.read = (p_char_obj->props & UBLUEPY_PROP_READ) ? 1 : 0; - char_md.char_props.write_wo_resp = (p_char_obj->props & UBLUEPY_PROP_WRITE_WO_RESP) ? 1 : 0; - char_md.char_props.write = (p_char_obj->props & UBLUEPY_PROP_WRITE) ? 1 : 0; - char_md.char_props.notify = (p_char_obj->props & UBLUEPY_PROP_NOTIFY) ? 1 : 0; - char_md.char_props.indicate = (p_char_obj->props & UBLUEPY_PROP_INDICATE) ? 1 : 0; -#if 0 - char_md.char_props.auth_signed_wr = (p_char_obj->props & UBLUEPY_PROP_NOTIFY) ? 1 : 0; -#endif - - - char_md.p_char_user_desc = NULL; - char_md.p_char_pf = NULL; - char_md.p_user_desc_md = NULL; - char_md.p_sccd_md = NULL; - - // if cccd - if (p_char_obj->attrs & UBLUEPY_ATTR_CCCD) { - memset(&cccd_md, 0, sizeof(cccd_md)); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); - cccd_md.vloc = BLE_GATTS_VLOC_STACK; - char_md.p_cccd_md = &cccd_md; - } else { - char_md.p_cccd_md = NULL; - } - - uuid.type = p_char_obj->p_uuid->type; - uuid.uuid = p_char_obj->p_uuid->value[0]; - uuid.uuid += p_char_obj->p_uuid->value[1] << 8; - - memset(&attr_md, 0, sizeof(attr_md)); - - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); - - attr_md.vloc = BLE_GATTS_VLOC_STACK; - attr_md.rd_auth = 0; - attr_md.wr_auth = 0; - attr_md.vlen = 1; - - memset(&attr_char_value, 0, sizeof(attr_char_value)); - - attr_char_value.p_uuid = &uuid; - attr_char_value.p_attr_md = &attr_md; - attr_char_value.init_len = sizeof(uint8_t); - attr_char_value.init_offs = 0; -#if (BLE_API_VERSION == 2) - attr_char_value.max_len = (GATT_MTU_SIZE_DEFAULT - 3); -#else - attr_char_value.max_len = (BLE_GATT_ATT_MTU_DEFAULT - 3); -#endif - - ble_gatts_char_handles_t handles; - - if (sd_ble_gatts_characteristic_add(p_char_obj->service_handle, - &char_md, - &attr_char_value, - &handles) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not add Characteristic."))); - } - - // apply handles to object instance - p_char_obj->handle = handles.value_handle; - p_char_obj->user_desc_handle = handles.user_desc_handle; - p_char_obj->cccd_handle = handles.cccd_handle; - p_char_obj->sccd_handle = handles.sccd_handle; - - return true; -} - -bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params) { - SD_TEST_OR_ENABLE(); - - uint8_t byte_pos = 0; - uint8_t adv_data[BLE_GAP_ADV_MAX_SIZE]; - - if (p_adv_params->device_name_len > 0) { - ble_gap_conn_sec_mode_t sec_mode; - - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); - - if (sd_ble_gap_device_name_set(&sec_mode, - p_adv_params->p_device_name, - p_adv_params->device_name_len) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not apply device name in the stack."))); - } - - BLE_DRIVER_LOG("Device name applied\n"); - - adv_data[byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + p_adv_params->device_name_len); - byte_pos += BLE_ADV_LENGTH_FIELD_SIZE; - adv_data[byte_pos] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME; - byte_pos += BLE_ADV_AD_TYPE_FIELD_SIZE; - memcpy(&adv_data[byte_pos], p_adv_params->p_device_name, p_adv_params->device_name_len); - // increment position counter to see if it fits, and in case more content should - // follow in this adv packet. - byte_pos += p_adv_params->device_name_len; - } - - // Add FLAGS only if manually controlled data has not been used. - if (p_adv_params->data_len == 0) { - // set flags, default to disc mode - adv_data[byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + BLE_AD_TYPE_FLAGS_DATA_SIZE); - byte_pos += BLE_ADV_LENGTH_FIELD_SIZE; - adv_data[byte_pos] = BLE_GAP_AD_TYPE_FLAGS; - byte_pos += BLE_AD_TYPE_FLAGS_DATA_SIZE; - adv_data[byte_pos] = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; - byte_pos += 1; - } - - if (p_adv_params->num_of_services > 0) { - - bool type_16bit_present = false; - bool type_128bit_present = false; - - for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) { - ubluepy_service_obj_t * p_service = (ubluepy_service_obj_t *)p_adv_params->p_services[i]; - if (p_service->p_uuid->type == UBLUEPY_UUID_16_BIT) { - type_16bit_present = true; - } - - if (p_service->p_uuid->type == UBLUEPY_UUID_128_BIT) { - type_128bit_present = true; - } - } - - if (type_16bit_present) { - uint8_t size_byte_pos = byte_pos; - - // skip length byte for now, apply total length post calculation - byte_pos += BLE_ADV_LENGTH_FIELD_SIZE; - - adv_data[byte_pos] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE; - byte_pos += BLE_ADV_AD_TYPE_FIELD_SIZE; - - uint8_t uuid_total_size = 0; - uint8_t encoded_size = 0; - - for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) { - ubluepy_service_obj_t * p_service = (ubluepy_service_obj_t *)p_adv_params->p_services[i]; - - ble_uuid_t uuid; - uuid.type = p_service->p_uuid->type; - uuid.uuid = p_service->p_uuid->value[0]; - uuid.uuid += p_service->p_uuid->value[1] << 8; - // calculate total size of uuids - if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not encode UUID, to check length."))); - } - - // do encoding into the adv buffer - if (sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can encode UUID into the advertisement packet."))); - } - - BLE_DRIVER_LOG("encoded uuid for service %u: ", 0); - for (uint8_t j = 0; j < encoded_size; j++) { - BLE_DRIVER_LOG(HEX2_FMT " ", adv_data[byte_pos + j]); - } - BLE_DRIVER_LOG("\n"); - - uuid_total_size += encoded_size; // size of entry - byte_pos += encoded_size; // relative to adv data packet - BLE_DRIVER_LOG("ADV: uuid size: %u, type: %u, uuid: %x%x, vs_idx: %u\n", - encoded_size, p_service->p_uuid->type, - p_service->p_uuid->value[1], - p_service->p_uuid->value[0], - p_service->p_uuid->uuid_vs_idx); - } - - adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size); - } - - if (type_128bit_present) { - uint8_t size_byte_pos = byte_pos; - - // skip length byte for now, apply total length post calculation - byte_pos += BLE_ADV_LENGTH_FIELD_SIZE; - - adv_data[byte_pos] = BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE; - byte_pos += BLE_ADV_AD_TYPE_FIELD_SIZE; - - uint8_t uuid_total_size = 0; - uint8_t encoded_size = 0; - - for (uint8_t i = 0; i < p_adv_params->num_of_services; i++) { - ubluepy_service_obj_t * p_service = (ubluepy_service_obj_t *)p_adv_params->p_services[i]; - - ble_uuid_t uuid; - uuid.type = p_service->p_uuid->uuid_vs_idx; - uuid.uuid = p_service->p_uuid->value[0]; - uuid.uuid += p_service->p_uuid->value[1] << 8; - - // calculate total size of uuids - if (sd_ble_uuid_encode(&uuid, &encoded_size, NULL) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not encode UUID, to check length."))); - } - - // do encoding into the adv buffer - if (sd_ble_uuid_encode(&uuid, &encoded_size, &adv_data[byte_pos]) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can encode UUID into the advertisement packet."))); - } - - BLE_DRIVER_LOG("encoded uuid for service %u: ", 0); - for (uint8_t j = 0; j < encoded_size; j++) { - BLE_DRIVER_LOG(HEX2_FMT " ", adv_data[byte_pos + j]); - } - BLE_DRIVER_LOG("\n"); - - uuid_total_size += encoded_size; // size of entry - byte_pos += encoded_size; // relative to adv data packet - BLE_DRIVER_LOG("ADV: uuid size: %u, type: %x%x, uuid: %u, vs_idx: %u\n", - encoded_size, p_service->p_uuid->type, - p_service->p_uuid->value[1], - p_service->p_uuid->value[0], - p_service->p_uuid->uuid_vs_idx); - } - - adv_data[size_byte_pos] = (BLE_ADV_AD_TYPE_FIELD_SIZE + uuid_total_size); - } - } - - if ((p_adv_params->data_len > 0) && (p_adv_params->p_data != NULL)) { - if (p_adv_params->data_len + byte_pos > BLE_GAP_ADV_MAX_SIZE) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not fit data into the advertisement packet."))); - } - - memcpy(adv_data, p_adv_params->p_data, p_adv_params->data_len); - byte_pos += p_adv_params->data_len; - } - - // scan response data not set - uint32_t err_code; -#if (BLUETOOTH_SD == 132) - if ((err_code = sd_ble_gap_adv_data_set(adv_data, byte_pos, NULL, 0)) != 0) { - - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not apply advertisement data. status: 0x%02x"), (uint16_t)err_code)); - } - BLE_DRIVER_LOG("Set Adv data size: " UINT_FMT "\n", byte_pos); -#endif - - static ble_gap_adv_params_t m_adv_params; - - // initialize advertising params - memset(&m_adv_params, 0, sizeof(m_adv_params)); - if (p_adv_params->connectable) { -#if (BLUETOOTH_SD == 140) - m_adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED; -#else - m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; -#endif - } else { -#if (BLUETOOTH_SD == 140) - m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED; -#else - m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND; -#endif - } - - m_adv_params.p_peer_addr = NULL; // undirected advertisement - m_adv_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS); // approx 8 ms -#if (BLUETOOTH_SD == 140) - m_adv_params.duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED; - m_adv_params.filter_policy = BLE_GAP_ADV_FP_ANY; - m_adv_params.primary_phy = BLE_GAP_PHY_1MBPS; -#else - m_adv_params.fp = BLE_GAP_ADV_FP_ANY; - m_adv_params.timeout = 0; // infinite advertisement -#endif - - ble_drv_advertise_stop(); - -#if (BLUETOOTH_SD == 140) - const ble_gap_adv_data_t ble_gap_adv_data = { - .adv_data = { - .p_data = adv_data, - .len = byte_pos - } - }; - - if ((err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &ble_gap_adv_data, &m_adv_params)) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not apply advertisement data. status: 0x%02x"), (uint16_t)err_code)); - } - err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_CONN_CFG_TAG_DEFAULT); -#elif (BLUETOOTH_SD == 132 && BLE_API_VERSION == 4) - err_code = sd_ble_gap_adv_start(&m_adv_params, BLE_CONN_CFG_TAG_DEFAULT); -#else - err_code = sd_ble_gap_adv_start(&m_adv_params); -#endif - if (err_code != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not start advertisement. status: 0x%02x"), (uint16_t)err_code)); - } - - m_adv_in_progress = true; - - return true; -} - -void ble_drv_advertise_stop(void) { - if (m_adv_in_progress == true) { - uint32_t err_code; -#if (BLUETOOTH_SD == 140) - if ((err_code = sd_ble_gap_adv_stop(m_adv_handle)) != 0) { -#else - if ((err_code = sd_ble_gap_adv_stop()) != 0) { -#endif - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not stop advertisement. status: 0x%02x"), (uint16_t)err_code)); - } - } - m_adv_in_progress = false; -} - -void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data) { - ble_gatts_value_t gatts_value; - memset(&gatts_value, 0, sizeof(gatts_value)); - - gatts_value.len = len; - gatts_value.offset = 0; - gatts_value.p_value = p_data; - - uint32_t err_code = sd_ble_gatts_value_get(conn_handle, - handle, - &gatts_value); - if (err_code != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not read attribute value. status: 0x%02x"), (uint16_t)err_code)); - } - -} - -void ble_drv_attr_s_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data) { - ble_gatts_value_t gatts_value; - memset(&gatts_value, 0, sizeof(gatts_value)); - - gatts_value.len = len; - gatts_value.offset = 0; - gatts_value.p_value = p_data; - - uint32_t err_code = sd_ble_gatts_value_set(conn_handle, handle, &gatts_value); - - if (err_code != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not write attribute value. status: 0x%02x"), (uint16_t)err_code)); - } -} - -void ble_drv_attr_s_notify(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data) { - uint16_t hvx_len = len; - ble_gatts_hvx_params_t hvx_params; - - memset(&hvx_params, 0, sizeof(hvx_params)); - - hvx_params.handle = handle; - hvx_params.type = BLE_GATT_HVX_NOTIFICATION; - hvx_params.offset = 0; - hvx_params.p_len = &hvx_len; - hvx_params.p_data = p_data; - - while (m_tx_in_progress) { - ; - } - - m_tx_in_progress = true; - uint32_t err_code; - if ((err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params)) != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not notify attribute value. status: 0x%02x"), (uint16_t)err_code)); - } -} - -void ble_drv_gap_event_handler_set(mp_obj_t obj, ble_drv_gap_evt_callback_t evt_handler) { - mp_gap_observer = obj; - gap_event_handler = evt_handler; -} - -void ble_drv_gatts_event_handler_set(mp_obj_t obj, ble_drv_gatts_evt_callback_t evt_handler) { - mp_gatts_observer = obj; - gatts_event_handler = evt_handler; -} - -void ble_drv_gattc_event_handler_set(mp_obj_t obj, ble_drv_gattc_evt_callback_t evt_handler) { - mp_gattc_observer = obj; - gattc_event_handler = evt_handler; -} - -void ble_drv_adv_report_handler_set(mp_obj_t obj, ble_drv_adv_evt_callback_t evt_handler) { - mp_adv_observer = obj; - adv_event_handler = evt_handler; -} - - -void ble_drv_attr_c_read(uint16_t conn_handle, uint16_t handle, mp_obj_t obj, ble_drv_gattc_char_data_callback_t cb) { - - mp_gattc_char_data_observer = obj; - gattc_char_data_handle = cb; - - uint32_t err_code = sd_ble_gattc_read(conn_handle, - handle, - 0); - if (err_code != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not read attribute value. status: 0x%02x"), (uint16_t)err_code)); - } - - while (gattc_char_data_handle != NULL) { - ; - } -} - -void ble_drv_attr_c_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data, bool w_response) { - - ble_gattc_write_params_t write_params; - - if (w_response) { - write_params.write_op = BLE_GATT_OP_WRITE_REQ; - } else { - write_params.write_op = BLE_GATT_OP_WRITE_CMD; - } - - write_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL; - write_params.handle = handle; - write_params.offset = 0; - write_params.len = len; - write_params.p_value = p_data; - - m_write_done = !w_response; - - uint32_t err_code = sd_ble_gattc_write(conn_handle, &write_params); - - if (err_code != 0) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not write attribute value. status: 0x%02x"), (uint16_t)err_code)); - } - - while (m_write_done != true) { - ; - } -} -void ble_drv_scan_start(void) { - SD_TEST_OR_ENABLE(); - - ble_gap_scan_params_t scan_params; - memset(&scan_params, 0, sizeof(ble_gap_scan_params_t)); - - scan_params.active = 1; - scan_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS); - scan_params.window = MSEC_TO_UNITS(100, UNIT_0_625_MS); -#if (BLUETOOTH_SD == 140) - scan_params.scan_phys = BLE_GAP_PHY_1MBPS; -#endif - scan_params.timeout = 0; // Infinite - - uint32_t err_code; -#if (BLUETOOTH_SD == 140) - if ((err_code = sd_ble_gap_scan_start(&scan_params, &m_scan_buffer)) != 0) { -#else - if ((err_code = sd_ble_gap_scan_start(&scan_params)) != 0) { -#endif - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not start scanning. status: 0x%02x"), (uint16_t)err_code)); - } -} - -void ble_drv_scan_stop(void) { - sd_ble_gap_scan_stop(); -} - -void ble_drv_connect(uint8_t * p_addr, uint8_t addr_type) { - SD_TEST_OR_ENABLE(); - - ble_gap_scan_params_t scan_params; - scan_params.active = 1; - scan_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS); - scan_params.window = MSEC_TO_UNITS(100, UNIT_0_625_MS); - scan_params.timeout = 0; // Infinite - - ble_gap_addr_t addr; - memset(&addr, 0, sizeof(addr)); - - addr.addr_type = addr_type; - memcpy(addr.addr, p_addr, 6); - - BLE_DRIVER_LOG("GAP CONNECTING: "HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT", type: %d\n", - addr.addr[0], addr.addr[1], addr.addr[2], addr.addr[3], addr.addr[4], addr.addr[5], addr.addr_type); - - ble_gap_conn_params_t conn_params; - -// (void)sd_ble_gap_ppcp_get(&conn_params); - - // set connection parameters - memset(&conn_params, 0, sizeof(conn_params)); - - conn_params.min_conn_interval = BLE_MIN_CONN_INTERVAL; - conn_params.max_conn_interval = BLE_MAX_CONN_INTERVAL; - conn_params.slave_latency = BLE_SLAVE_LATENCY; - conn_params.conn_sup_timeout = BLE_CONN_SUP_TIMEOUT; - - uint32_t err_code; -#if (BLE_API_VERSION == 2) - if ((err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params)) != 0) { -#else - if ((err_code = sd_ble_gap_connect(&addr, &scan_params, &conn_params, BLE_CONN_CFG_TAG_DEFAULT)) != 0) { -#endif - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - translate("Can not connect. status: 0x%02x"), (uint16_t)err_code)); - } -} - -bool ble_drv_discover_services(mp_obj_t obj, uint16_t conn_handle, uint16_t start_handle, ble_drv_disc_add_service_callback_t cb) { - BLE_DRIVER_LOG("Discover primary services. Conn handle: 0x" HEX2_FMT "\n", - conn_handle); - - mp_gattc_disc_service_observer = obj; - disc_add_service_handler = cb; - - m_primary_service_found = false; - - uint32_t err_code; - err_code = sd_ble_gattc_primary_services_discover(conn_handle, - start_handle, - NULL); - if (err_code != 0) { - return false; - } - - // busy loop until last service has been iterated - while (disc_add_service_handler != NULL) { - ; - } - - if (m_primary_service_found) { - return true; - } else { - return false; - } -} - -bool ble_drv_discover_characteristic(mp_obj_t obj, - uint16_t conn_handle, - uint16_t start_handle, - uint16_t end_handle, - ble_drv_disc_add_char_callback_t cb) { - BLE_DRIVER_LOG("Discover characteristicts. Conn handle: 0x" HEX2_FMT "\n", - conn_handle); - - mp_gattc_disc_char_observer = obj; - disc_add_char_handler = cb; - - ble_gattc_handle_range_t handle_range; - handle_range.start_handle = start_handle; - handle_range.end_handle = end_handle; - - m_characteristic_found = false; - - uint32_t err_code; - err_code = sd_ble_gattc_characteristics_discover(conn_handle, &handle_range); - if (err_code != 0) { - return false; - } - - // busy loop until last service has been iterated - while (disc_add_char_handler != NULL) { - ; - } - - if (m_characteristic_found) { - return true; - } else { - return false; - } -} - -void ble_drv_discover_descriptors(void) { - -} - -static void ble_evt_handler(ble_evt_t * p_ble_evt) { -// S132 event ranges. -// Common 0x01 -> 0x0F -// GAP 0x10 -> 0x2F -// GATTC 0x30 -> 0x4F -// GATTS 0x50 -> 0x6F -// L2CAP 0x70 -> 0x8F - switch (p_ble_evt->header.evt_id) { - case BLE_GAP_EVT_CONNECTED: - BLE_DRIVER_LOG("GAP CONNECT\n"); - m_adv_in_progress = false; - gap_event_handler(mp_gap_observer, p_ble_evt->header.evt_id, p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->header.evt_len - (2 * sizeof(uint16_t)), NULL); - - ble_gap_conn_params_t conn_params; - (void)sd_ble_gap_ppcp_get(&conn_params); - (void)sd_ble_gap_conn_param_update(p_ble_evt->evt.gap_evt.conn_handle, &conn_params); - break; - - case BLE_GAP_EVT_DISCONNECTED: - BLE_DRIVER_LOG("GAP DISCONNECT\n"); - gap_event_handler(mp_gap_observer, p_ble_evt->header.evt_id, p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->header.evt_len - (2 * sizeof(uint16_t)), NULL); - break; - - case BLE_GATTS_EVT_HVC: - gatts_event_handler(mp_gatts_observer, p_ble_evt->header.evt_id, p_ble_evt->evt.gatts_evt.params.hvc.handle, p_ble_evt->header.evt_len - (2 * sizeof(uint16_t)), NULL); - break; - - case BLE_GATTS_EVT_WRITE: - BLE_DRIVER_LOG("GATTS write\n"); - - uint16_t handle = p_ble_evt->evt.gatts_evt.params.write.handle; - uint16_t data_len = p_ble_evt->evt.gatts_evt.params.write.len; - uint8_t * p_data = &p_ble_evt->evt.gatts_evt.params.write.data[0]; - - gatts_event_handler(mp_gatts_observer, p_ble_evt->header.evt_id, handle, data_len, p_data); - break; - - case BLE_GAP_EVT_CONN_PARAM_UPDATE: - BLE_DRIVER_LOG("GAP CONN PARAM UPDATE\n"); - break; - - case BLE_GATTS_EVT_SYS_ATTR_MISSING: - // No system attributes have been stored. - (void)sd_ble_gatts_sys_attr_set(p_ble_evt->evt.gatts_evt.conn_handle, NULL, 0, 0); - break; - -#if (BLE_API_VERSION == 4) - case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: - BLE_DRIVER_LOG("GATTS EVT EXCHANGE MTU REQUEST\n"); - (void)sd_ble_gatts_exchange_mtu_reply(p_ble_evt->evt.gatts_evt.conn_handle, 23); // MAX MTU size - break; -#endif - -#if (BLE_API_VERSION == 4) - case BLE_GATTS_EVT_HVN_TX_COMPLETE: -#else - case BLE_EVT_TX_COMPLETE: -#endif - BLE_DRIVER_LOG("BLE EVT TX COMPLETE\n"); - m_tx_in_progress = false; - break; - - case BLE_GAP_EVT_SEC_PARAMS_REQUEST: - BLE_DRIVER_LOG("BLE EVT SEC PARAMS REQUEST\n"); - // pairing not supported - (void)sd_ble_gap_sec_params_reply(p_ble_evt->evt.gatts_evt.conn_handle, - BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, - NULL, NULL); - break; - - case BLE_GAP_EVT_ADV_REPORT: - BLE_DRIVER_LOG("BLE EVT ADV REPORT\n"); - ble_drv_adv_data_t adv_data = { - .p_peer_addr = p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr, - .addr_type = p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr_type, -#if (BLUETOOTH_SD == 140) - .is_scan_resp = p_ble_evt->evt.gap_evt.params.adv_report.type.scannable, -#else - .is_scan_resp = p_ble_evt->evt.gap_evt.params.adv_report.scan_rsp, -#endif - .rssi = p_ble_evt->evt.gap_evt.params.adv_report.rssi, -#if (BLUETOOTH_SD == 140) - .data_len = p_ble_evt->evt.gap_evt.params.adv_report.data.len, - .p_data = p_ble_evt->evt.gap_evt.params.adv_report.data.p_data, -#else - .data_len = p_ble_evt->evt.gap_evt.params.adv_report.dlen, - .p_data = p_ble_evt->evt.gap_evt.params.adv_report.data, -#endif -#if (BLUETOOTH_SD == 132) - .adv_type = p_ble_evt->evt.gap_evt.params.adv_report.type -#endif - }; - - // TODO: Fix unsafe callback to possible undefined callback... - adv_event_handler(mp_adv_observer, - p_ble_evt->header.evt_id, - &adv_data); - break; - - case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: - BLE_DRIVER_LOG("BLE EVT CONN PARAM UPDATE REQUEST\n"); - - (void)sd_ble_gap_conn_param_update(p_ble_evt->evt.gap_evt.conn_handle, - &p_ble_evt->evt.gap_evt.params.conn_param_update_request.conn_params); - break; - - case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: - BLE_DRIVER_LOG("BLE EVT PRIMARY SERVICE DISCOVERY RESPONSE\n"); - BLE_DRIVER_LOG(">>> service count: %d\n", p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count); - - for (uint16_t i = 0; i < p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count; i++) { - ble_gattc_service_t * p_service = &p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i]; - - ble_drv_service_data_t service; - service.uuid_type = p_service->uuid.type; - service.uuid = p_service->uuid.uuid; - service.start_handle = p_service->handle_range.start_handle; - service.end_handle = p_service->handle_range.end_handle; - - disc_add_service_handler(mp_gattc_disc_service_observer, &service); - } - - if (p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count > 0) { - m_primary_service_found = true; - } - - // mark end of service discovery - disc_add_service_handler = NULL; - - break; - - case BLE_GATTC_EVT_CHAR_DISC_RSP: - BLE_DRIVER_LOG("BLE EVT CHAR DISCOVERY RESPONSE\n"); - BLE_DRIVER_LOG(">>> characteristic count: %d\n", p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count); - - for (uint16_t i = 0; i < p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count; i++) { - ble_gattc_char_t * p_char = &p_ble_evt->evt.gattc_evt.params.char_disc_rsp.chars[i]; - - ble_drv_char_data_t char_data; - char_data.uuid_type = p_char->uuid.type; - char_data.uuid = p_char->uuid.uuid; - char_data.decl_handle = p_char->handle_decl; - char_data.value_handle = p_char->handle_value; - - char_data.props |= (p_char->char_props.broadcast) ? UBLUEPY_PROP_BROADCAST : 0; - char_data.props |= (p_char->char_props.read) ? UBLUEPY_PROP_READ : 0; - char_data.props |= (p_char->char_props.write_wo_resp) ? UBLUEPY_PROP_WRITE_WO_RESP : 0; - char_data.props |= (p_char->char_props.write) ? UBLUEPY_PROP_WRITE : 0; - char_data.props |= (p_char->char_props.notify) ? UBLUEPY_PROP_NOTIFY : 0; - char_data.props |= (p_char->char_props.indicate) ? UBLUEPY_PROP_INDICATE : 0; - #if 0 - char_data.props |= (p_char->char_props.auth_signed_wr) ? UBLUEPY_PROP_NOTIFY : 0; - #endif - - disc_add_char_handler(mp_gattc_disc_char_observer, &char_data); - } - - if (p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count > 0) { - m_characteristic_found = true; - } - - // mark end of characteristic discovery - disc_add_char_handler = NULL; - - break; - - case BLE_GATTC_EVT_READ_RSP: - BLE_DRIVER_LOG("BLE EVT READ RESPONSE, offset: 0x"HEX2_FMT", length: 0x"HEX2_FMT"\n", - p_ble_evt->evt.gattc_evt.params.read_rsp.offset, - p_ble_evt->evt.gattc_evt.params.read_rsp.len); - - gattc_char_data_handle(mp_gattc_char_data_observer, - p_ble_evt->evt.gattc_evt.params.read_rsp.len, - p_ble_evt->evt.gattc_evt.params.read_rsp.data); - - // mark end of read - gattc_char_data_handle = NULL; - - break; - - case BLE_GATTC_EVT_WRITE_RSP: - BLE_DRIVER_LOG("BLE EVT WRITE RESPONSE\n"); - m_write_done = true; - break; - - case BLE_GATTC_EVT_HVX: - BLE_DRIVER_LOG("BLE EVT HVX RESPONSE\n"); - break; - - default: - BLE_DRIVER_LOG(">>> unhandled evt: 0x" HEX2_FMT "\n", p_ble_evt->header.evt_id); - break; - } -} - -#if (BLE_API_VERSION == 2) -static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (GATT_MTU_SIZE_DEFAULT)] __attribute__ ((aligned (4))); -#else -static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATT_ATT_MTU_DEFAULT)] __attribute__ ((aligned (4))); -#endif - -void SWI2_EGU2_IRQHandler(void) { - uint32_t evt_id; - uint32_t err_code; - do { - err_code = sd_evt_get(&evt_id); - // TODO: handle non ble events - } while (err_code != NRF_ERROR_NOT_FOUND && err_code != NRF_SUCCESS); - - uint16_t evt_len = sizeof(m_ble_evt_buf); - do { - err_code = sd_ble_evt_get(m_ble_evt_buf, &evt_len); - ble_evt_handler((ble_evt_t *)m_ble_evt_buf); - } while (err_code != NRF_ERROR_NOT_FOUND && err_code != NRF_SUCCESS); -} - -#endif // BLUETOOTH_SD diff --git a/ports/nrf/drivers/bluetooth/ble_drv.h b/ports/nrf/drivers/bluetooth/ble_drv.h deleted file mode 100644 index d8b715467..000000000 --- a/ports/nrf/drivers/bluetooth/ble_drv.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * 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. - */ - -#ifndef BLUETOOTH_LE_DRIVER_H__ -#define BLUETOOTH_LE_DRIVER_H__ - -#if BLUETOOTH_SD - -#include <stdint.h> -#include <stdbool.h> - -#include "modubluepy.h" - -typedef struct { - uint8_t addr[6]; - uint8_t addr_type; -} ble_drv_addr_t; - -typedef struct { - uint8_t * p_peer_addr; - uint8_t addr_type; - bool is_scan_resp; - int8_t rssi; - uint8_t data_len; - uint8_t * p_data; - uint8_t adv_type; -} ble_drv_adv_data_t; - -typedef struct { - uint16_t uuid; - uint8_t uuid_type; - uint16_t start_handle; - uint16_t end_handle; -} ble_drv_service_data_t; - -typedef struct { - uint16_t uuid; - uint8_t uuid_type; - uint8_t props; - uint16_t decl_handle; - uint16_t value_handle; -} ble_drv_char_data_t; - -typedef void (*ble_drv_gap_evt_callback_t)(mp_obj_t self, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data); -typedef void (*ble_drv_gatts_evt_callback_t)(mp_obj_t self, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); -typedef void (*ble_drv_gattc_evt_callback_t)(mp_obj_t self, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data); -typedef void (*ble_drv_adv_evt_callback_t)(mp_obj_t self, uint16_t event_id, ble_drv_adv_data_t * data); -typedef void (*ble_drv_disc_add_service_callback_t)(mp_obj_t self, ble_drv_service_data_t * p_service_data); -typedef void (*ble_drv_disc_add_char_callback_t)(mp_obj_t self, ble_drv_char_data_t * p_desc_data); -typedef void (*ble_drv_gattc_char_data_callback_t)(mp_obj_t self, uint16_t length, uint8_t * p_data); - -uint32_t ble_drv_stack_enable(void); - -void ble_drv_stack_disable(void); - -uint8_t ble_drv_stack_enabled(void); - -void ble_drv_address_get(ble_drv_addr_t * p_addr); - -bool ble_drv_uuid_add_vs(uint8_t * p_uuid, uint8_t * idx); - -bool ble_drv_service_add(ubluepy_service_obj_t * p_service_obj); - -bool ble_drv_characteristic_add(ubluepy_characteristic_obj_t * p_char_obj); - -bool ble_drv_advertise_data(ubluepy_advertise_data_t * p_adv_params); - -void ble_drv_advertise_stop(void); - -void ble_drv_gap_event_handler_set(mp_obj_t obs, ble_drv_gap_evt_callback_t evt_handler); - -void ble_drv_gatts_event_handler_set(mp_obj_t obj, ble_drv_gatts_evt_callback_t evt_handler); - -void ble_drv_gattc_event_handler_set(mp_obj_t obj, ble_drv_gattc_evt_callback_t evt_handler); - -void ble_drv_attr_s_read(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data); - -void ble_drv_attr_c_read(uint16_t conn_handle, uint16_t handle, mp_obj_t obj, ble_drv_gattc_char_data_callback_t cb); - -void ble_drv_attr_s_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data); - -void ble_drv_attr_s_notify(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data); - -void ble_drv_attr_c_write(uint16_t conn_handle, uint16_t handle, uint16_t len, uint8_t * p_data, bool w_response); - -void ble_drv_scan_start(void); - -void ble_drv_scan_stop(void); - -void ble_drv_adv_report_handler_set(mp_obj_t obj, ble_drv_adv_evt_callback_t evt_handler); - -void ble_drv_connect(uint8_t * p_addr, uint8_t addr_type); - -bool ble_drv_discover_services(mp_obj_t obj, uint16_t conn_handle, uint16_t start_handle, ble_drv_disc_add_service_callback_t cb); - -bool ble_drv_discover_characteristic(mp_obj_t obj, - uint16_t conn_handle, - uint16_t start_handle, - uint16_t end_handle, - ble_drv_disc_add_char_callback_t cb); - -void ble_drv_discover_descriptors(void); - -#endif // BLUETOOTH_SD - -#endif // BLUETOOTH_LE_DRIVER_H__ diff --git a/ports/nrf/drivers/bluetooth/ble_uart.c b/ports/nrf/drivers/bluetooth/ble_uart.c deleted file mode 100644 index 52c042f7b..000000000 --- a/ports/nrf/drivers/bluetooth/ble_uart.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * 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. - */ - -#if BLUETOOTH_SD - -#include <string.h> -#include "ble_uart.h" -#include "ringbuffer.h" -#include "py/mphal.h" -#include "lib/utils/interrupt_char.h" - -#if MICROPY_PY_BLE_NUS - -static ubluepy_uuid_obj_t uuid_obj_service = { - .base.type = &ubluepy_uuid_type, - .type = UBLUEPY_UUID_128_BIT, - .value = {0x01, 0x00} -}; - -static ubluepy_uuid_obj_t uuid_obj_char_tx = { - .base.type = &ubluepy_uuid_type, - .type = UBLUEPY_UUID_128_BIT, - .value = {0x03, 0x00} -}; - -static ubluepy_uuid_obj_t uuid_obj_char_rx = { - .base.type = &ubluepy_uuid_type, - .type = UBLUEPY_UUID_128_BIT, - .value = {0x02, 0x00} -}; - -static ubluepy_service_obj_t ble_uart_service = { - .base.type = &ubluepy_service_type, - .p_uuid = &uuid_obj_service, - .type = UBLUEPY_SERVICE_PRIMARY -}; - -static ubluepy_characteristic_obj_t ble_uart_char_rx = { - .base.type = &ubluepy_characteristic_type, - .p_uuid = &uuid_obj_char_rx, - .props = UBLUEPY_PROP_WRITE | UBLUEPY_PROP_WRITE_WO_RESP, - .attrs = 0, -}; - -static ubluepy_characteristic_obj_t ble_uart_char_tx = { - .base.type = &ubluepy_characteristic_type, - .p_uuid = &uuid_obj_char_tx, - .props = UBLUEPY_PROP_NOTIFY, - .attrs = UBLUEPY_ATTR_CCCD, -}; - -static ubluepy_peripheral_obj_t ble_uart_peripheral = { - .base.type = &ubluepy_peripheral_type, - .conn_handle = 0xFFFF, -}; - -static volatile bool m_cccd_enabled; -static volatile bool m_connected; - -ringBuffer_typedef(uint8_t, ringbuffer_t); - -static ringbuffer_t m_rx_ring_buffer; -static ringbuffer_t * mp_rx_ring_buffer = &m_rx_ring_buffer; -static uint8_t m_rx_ring_buffer_data[128]; - -static ubluepy_advertise_data_t m_adv_data_uart_service; - -#if BLUETOOTH_WEBBLUETOOTH_REPL -static ubluepy_advertise_data_t m_adv_data_eddystone_url; -#endif // BLUETOOTH_WEBBLUETOOTH_REPL - -int mp_hal_stdin_rx_chr(void) { - while (isBufferEmpty(mp_rx_ring_buffer)) { - ; - } - - uint8_t byte; - bufferRead(mp_rx_ring_buffer, byte); - return (int)byte; -} - -bool mp_hal_stdin_any(void) { - return !isBufferEmpty(mp_rx_ring_buffer); -} - -void mp_hal_stdout_tx_strn(const char *str, size_t len) { - uint8_t *buf = (uint8_t *)str; - size_t send_len; - - while (len > 0) { - if (len >= 20) { - send_len = 20; // (GATT_MTU_SIZE_DEFAULT - 3) - } else { - send_len = len; - } - - ubluepy_characteristic_obj_t * p_char = &ble_uart_char_tx; - - ble_drv_attr_s_notify(p_char->p_service->p_periph->conn_handle, - p_char->handle, - send_len, - buf); - - len -= send_len; - buf += send_len; - } -} - -void mp_hal_stdout_tx_strn_cooked(const char *str, mp_uint_t len) { - mp_hal_stdout_tx_strn(str, len); -} - -STATIC void gap_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data) { - ubluepy_peripheral_obj_t * self = MP_OBJ_TO_PTR(self_in); - - if (event_id == 16) { // connect event - self->conn_handle = conn_handle; - m_connected = true; - } else if (event_id == 17) { // disconnect event - self->conn_handle = 0xFFFF; // invalid connection handle - m_connected = false; - ble_uart_advertise(); - } -} - -STATIC void gatts_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) { - ubluepy_peripheral_obj_t * self = MP_OBJ_TO_PTR(self_in); - (void)self; - - if (event_id == 80) { // gatts write - if (ble_uart_char_tx.cccd_handle == attr_handle) { - m_cccd_enabled = true; - } else if (ble_uart_char_rx.handle == attr_handle) { - for (uint16_t i = 0; i < length; i++) { - #if MICROPY_KBD_EXCEPTION - if (data[i] == mp_interrupt_char) { - mp_keyboard_interrupt(); - } else - #endif - { - bufferWrite(mp_rx_ring_buffer, data[i]); - } - } - } - } -} - -void ble_uart_init0(void) { - uint8_t base_uuid[] = {0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x00, 0x00, 0x40, 0x6E}; - uint8_t uuid_vs_idx; - - (void)ble_drv_uuid_add_vs(base_uuid, &uuid_vs_idx); - - uuid_obj_service.uuid_vs_idx = uuid_vs_idx; - uuid_obj_char_tx.uuid_vs_idx = uuid_vs_idx; - uuid_obj_char_rx.uuid_vs_idx = uuid_vs_idx; - - (void)ble_drv_service_add(&ble_uart_service); - ble_uart_service.char_list = mp_obj_new_list(0, NULL); - - // add TX characteristic - ble_uart_char_tx.service_handle = ble_uart_service.handle; - bool retval = ble_drv_characteristic_add(&ble_uart_char_tx); - if (retval) { - ble_uart_char_tx.p_service = &ble_uart_service; - } - mp_obj_list_append(ble_uart_service.char_list, MP_OBJ_FROM_PTR(&ble_uart_char_tx)); - - // add RX characteristic - ble_uart_char_rx.service_handle = ble_uart_service.handle; - retval = ble_drv_characteristic_add(&ble_uart_char_rx); - if (retval) { - ble_uart_char_rx.p_service = &ble_uart_service; - } - mp_obj_list_append(ble_uart_service.char_list, MP_OBJ_FROM_PTR(&ble_uart_char_rx)); - - // setup the peripheral - ble_uart_peripheral.service_list = mp_obj_new_list(0, NULL); - mp_obj_list_append(ble_uart_peripheral.service_list, MP_OBJ_FROM_PTR(&ble_uart_service)); - ble_uart_service.p_periph = &ble_uart_peripheral; - - ble_drv_gap_event_handler_set(MP_OBJ_FROM_PTR(&ble_uart_peripheral), gap_event_handler); - ble_drv_gatts_event_handler_set(MP_OBJ_FROM_PTR(&ble_uart_peripheral), gatts_event_handler); - - ble_uart_peripheral.conn_handle = 0xFFFF; - - char device_name[] = "mpus"; - - mp_obj_t service_list = mp_obj_new_list(0, NULL); - mp_obj_list_append(service_list, MP_OBJ_FROM_PTR(&ble_uart_service)); - - mp_obj_t * services = NULL; - mp_uint_t num_services; - mp_obj_get_array(service_list, &num_services, &services); - - m_adv_data_uart_service.p_services = services; - m_adv_data_uart_service.num_of_services = num_services; - m_adv_data_uart_service.p_device_name = (uint8_t *)device_name; - m_adv_data_uart_service.device_name_len = strlen(device_name); - m_adv_data_uart_service.connectable = true; - m_adv_data_uart_service.p_data = NULL; - -#if BLUETOOTH_WEBBLUETOOTH_REPL - // for now point eddystone URL to https://goo.gl/x46FES => https://glennrub.github.io/webbluetooth/micropython/repl/ - static uint8_t eddystone_url_data[27] = {0x2, 0x1, 0x6, - 0x3, 0x3, 0xaa, 0xfe, - 19, 0x16, 0xaa, 0xfe, 0x10, 0xee, 0x3, 'g', 'o', 'o', '.', 'g', 'l', '/', 'x', '4', '6', 'F', 'E', 'S'}; - // eddystone url adv data - m_adv_data_eddystone_url.p_data = eddystone_url_data; - m_adv_data_eddystone_url.data_len = sizeof(eddystone_url_data); - m_adv_data_eddystone_url.connectable = false; -#endif - - m_cccd_enabled = false; - - // initialize ring buffer - m_rx_ring_buffer.size = sizeof(m_rx_ring_buffer_data) + 1; - m_rx_ring_buffer.start = 0; - m_rx_ring_buffer.end = 0; - m_rx_ring_buffer.elems = m_rx_ring_buffer_data; - - m_connected = false; - - ble_uart_advertise(); -} - -void ble_uart_advertise(void) { -#if BLUETOOTH_WEBBLUETOOTH_REPL - while (!m_connected) { - (void)ble_drv_advertise_data(&m_adv_data_uart_service); - mp_hal_delay_ms(500); - (void)ble_drv_advertise_data(&m_adv_data_eddystone_url); - mp_hal_delay_ms(500); - } - - ble_drv_advertise_stop(); -#else - (void)ble_drv_advertise_data(&m_adv_data_uart_service); -#endif // BLUETOOTH_WEBBLUETOOTH_REPL -} - -bool ble_uart_connected(void) { - return (m_connected); -} - -bool ble_uart_enabled(void) { - return (m_cccd_enabled); -} - -#endif // MICROPY_PY_BLE_NUS - -#endif // BLUETOOTH_SD diff --git a/ports/nrf/modules/ubluepy/modubluepy.c b/ports/nrf/modules/ubluepy/modubluepy.c deleted file mode 100644 index b306c065b..000000000 --- a/ports/nrf/modules/ubluepy/modubluepy.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * 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 "py/obj.h" - -#if MICROPY_PY_UBLUEPY - -extern const mp_obj_type_t ubluepy_peripheral_type; -extern const mp_obj_type_t ubluepy_service_type; -extern const mp_obj_type_t ubluepy_uuid_type; -extern const mp_obj_type_t ubluepy_characteristic_type; -extern const mp_obj_type_t ubluepy_delegate_type; -extern const mp_obj_type_t ubluepy_constants_type; -extern const mp_obj_type_t ubluepy_scanner_type; -extern const mp_obj_type_t ubluepy_scan_entry_type; - -STATIC const mp_rom_map_elem_t mp_module_ubluepy_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ubluepy) }, -#if MICROPY_PY_UBLUEPY_PERIPHERAL - { MP_ROM_QSTR(MP_QSTR_Peripheral), MP_ROM_PTR(&ubluepy_peripheral_type) }, -#endif -#if 0 // MICROPY_PY_UBLUEPY_CENTRAL - { MP_ROM_QSTR(MP_QSTR_Central), MP_ROM_PTR(&ubluepy_central_type) }, -#endif -#if MICROPY_PY_UBLUEPY_CENTRAL - { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&ubluepy_scanner_type) }, - { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&ubluepy_scan_entry_type) }, -#endif - { MP_ROM_QSTR(MP_QSTR_DefaultDelegate), MP_ROM_PTR(&ubluepy_delegate_type) }, - { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&ubluepy_uuid_type) }, - { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&ubluepy_service_type) }, - { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&ubluepy_characteristic_type) }, - { MP_ROM_QSTR(MP_QSTR_constants), MP_ROM_PTR(&ubluepy_constants_type) }, -#if MICROPY_PY_UBLUEPY_DESCRIPTOR - { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&ubluepy_descriptor_type) }, -#endif -}; - - -STATIC MP_DEFINE_CONST_DICT(mp_module_ubluepy_globals, mp_module_ubluepy_globals_table); - -const mp_obj_module_t mp_module_ubluepy = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&mp_module_ubluepy_globals, -}; - -#endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/modules/ubluepy/modubluepy.h b/ports/nrf/modules/ubluepy/modubluepy.h deleted file mode 100644 index 83d86c5df..000000000 --- a/ports/nrf/modules/ubluepy/modubluepy.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Glenn Ruben Bakke - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef UBLUEPY_H__ -#define UBLUEPY_H__ - -/* Examples: - -Advertisment: - -from ubluepy import Peripheral -p = Peripheral() -p.advertise(device_name="MicroPython") - -DB setup: - -from ubluepy import Service, Characteristic, UUID, Peripheral, constants -from pyb import LED - -def event_handler(id, handle, data): - print("BLE event:", id, "handle:", handle) - print(data) - - if id == constants.EVT_GAP_CONNECTED: - # connected - LED(2).on() - elif id == constants.EVT_GAP_DISCONNECTED: - # disconnect - LED(2).off() - elif id == 80: - print("id 80, data:", data) - -# u0 = UUID("0x180D") # HRM service -# u1 = UUID("0x2A37") # HRM measurement - -u0 = UUID("6e400001-b5a3-f393-e0a9-e50e24dcca9e") -u1 = UUID("6e400002-b5a3-f393-e0a9-e50e24dcca9e") -u2 = UUID("6e400003-b5a3-f393-e0a9-e50e24dcca9e") -s = Service(u0) -c0 = Characteristic(u1, props = Characteristic.PROP_WRITE | Characteristic.PROP_WRITE_WO_RESP) -c1 = Characteristic(u2, props = Characteristic.PROP_NOTIFY, attrs = Characteristic.ATTR_CCCD) -s.addCharacteristic(c0) -s.addCharacteristic(c1) -p = Peripheral() -p.addService(s) -p.setConnectionHandler(event_handler) -p.advertise(device_name="micr", services=[s]) - -*/ - -#include "py/obj.h" - -extern const mp_obj_type_t ubluepy_uuid_type; -extern const mp_obj_type_t ubluepy_service_type; -extern const mp_obj_type_t ubluepy_characteristic_type; -extern const mp_obj_type_t ubluepy_peripheral_type; -extern const mp_obj_type_t ubluepy_scanner_type; -extern const mp_obj_type_t ubluepy_scan_entry_type; -extern const mp_obj_type_t ubluepy_constants_type; -extern const mp_obj_type_t ubluepy_constants_ad_types_type; - -typedef enum { - UBLUEPY_UUID_16_BIT = 1, - UBLUEPY_UUID_128_BIT -} ubluepy_uuid_type_t; - -typedef enum { - UBLUEPY_SERVICE_PRIMARY = 1, - UBLUEPY_SERVICE_SECONDARY = 2 -} ubluepy_service_type_t; - -typedef enum { - UBLUEPY_ADDR_TYPE_PUBLIC = 0, - UBLUEPY_ADDR_TYPE_RANDOM_STATIC = 1, -#if 0 - UBLUEPY_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE = 2, - UBLUEPY_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE = 3, -#endif -} ubluepy_addr_type_t; - -typedef enum { - UBLUEPY_ROLE_PERIPHERAL, - UBLUEPY_ROLE_CENTRAL -} ubluepy_role_type_t; - -typedef struct _ubluepy_uuid_obj_t { - mp_obj_base_t base; - ubluepy_uuid_type_t type; - uint8_t value[2]; - uint8_t uuid_vs_idx; -} ubluepy_uuid_obj_t; - -typedef struct _ubluepy_peripheral_obj_t { - mp_obj_base_t base; - ubluepy_role_type_t role; - volatile uint16_t conn_handle; - mp_obj_t delegate; - mp_obj_t notif_handler; - mp_obj_t conn_handler; - mp_obj_t service_list; -} ubluepy_peripheral_obj_t; - -typedef struct _ubluepy_service_obj_t { - mp_obj_base_t base; - uint16_t handle; - uint8_t type; - ubluepy_uuid_obj_t * p_uuid; - ubluepy_peripheral_obj_t * p_periph; - mp_obj_t char_list; - uint16_t start_handle; - uint16_t end_handle; -} ubluepy_service_obj_t; - -typedef struct _ubluepy_characteristic_obj_t { - mp_obj_base_t base; - uint16_t handle; - ubluepy_uuid_obj_t * p_uuid; - uint16_t service_handle; - uint16_t user_desc_handle; - uint16_t cccd_handle; - uint16_t sccd_handle; - uint8_t props; - uint8_t attrs; - ubluepy_service_obj_t * p_service; - mp_obj_t value_data; -} ubluepy_characteristic_obj_t; - -typedef struct _ubluepy_descriptor_obj_t { - mp_obj_base_t base; - uint16_t handle; - ubluepy_uuid_obj_t * p_uuid; -} ubluepy_descriptor_obj_t; - -typedef struct _ubluepy_delegate_obj_t { - mp_obj_base_t base; -} ubluepy_delegate_obj_t; - -typedef struct _ubluepy_advertise_data_t { - uint8_t * p_device_name; - uint8_t device_name_len; - mp_obj_t * p_services; - uint8_t num_of_services; - uint8_t * p_data; - uint8_t data_len; - bool connectable; -} ubluepy_advertise_data_t; - -typedef struct _ubluepy_scanner_obj_t { - mp_obj_base_t base; - mp_obj_t adv_reports; -} ubluepy_scanner_obj_t; - -typedef struct _ubluepy_scan_entry_obj_t { - mp_obj_base_t base; - mp_obj_t addr; - uint8_t addr_type; - bool connectable; - int8_t rssi; - mp_obj_t data; -} ubluepy_scan_entry_obj_t; - -typedef enum _ubluepy_prop_t { - UBLUEPY_PROP_BROADCAST = 0x01, - UBLUEPY_PROP_READ = 0x02, - UBLUEPY_PROP_WRITE_WO_RESP = 0x04, - UBLUEPY_PROP_WRITE = 0x08, - UBLUEPY_PROP_NOTIFY = 0x10, - UBLUEPY_PROP_INDICATE = 0x20, - UBLUEPY_PROP_AUTH_SIGNED_WR = 0x40, -} ubluepy_prop_t; - -typedef enum _ubluepy_attr_t { - UBLUEPY_ATTR_CCCD = 0x01, - UBLUEPY_ATTR_SCCD = 0x02, -} ubluepy_attr_t; - -#endif // UBLUEPY_H__ diff --git a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c b/ports/nrf/modules/ubluepy/ubluepy_characteristic.c deleted file mode 100644 index 0935615a5..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_characteristic.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * 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 "py/obj.h" -#include "py/runtime.h" -#include "supervisor/shared/translate.h" - -#if MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL - -#include "modubluepy.h" -#include "ble_drv.h" - -STATIC void ubluepy_characteristic_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_characteristic_obj_t * self = (ubluepy_characteristic_obj_t *)o; - - mp_printf(print, "Characteristic(handle: 0x" HEX2_FMT ", conn_handle: " HEX2_FMT ")", - self->handle, self->p_service->p_periph->conn_handle); -} - -STATIC mp_obj_t ubluepy_characteristic_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - static const mp_arg_t allowed_args[] = { - { MP_QSTR_uuid, MP_ARG_REQUIRED| MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_props, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = UBLUEPY_PROP_READ | UBLUEPY_PROP_WRITE} }, - { MP_QSTR_attrs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - ubluepy_characteristic_obj_t *s = m_new_obj(ubluepy_characteristic_obj_t); - s->base.type = type; - - mp_obj_t uuid_obj = args[0].u_obj; - - if (uuid_obj == mp_const_none) { - return MP_OBJ_FROM_PTR(s); - } - - if (MP_OBJ_IS_TYPE(uuid_obj, &ubluepy_uuid_type)) { - s->p_uuid = MP_OBJ_TO_PTR(uuid_obj); - // (void)sd_characterstic_add(s); - } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid UUID parameter"))); - } - - if (args[1].u_int > 0) { - s->props = (uint8_t)args[1].u_int; - } - - if (args[2].u_int > 0) { - s->attrs = (uint8_t)args[2].u_int; - } - - // clear pointer to service - s->p_service = NULL; - - // clear pointer to char value data - s->value_data = NULL; - - return MP_OBJ_FROM_PTR(s); -} - -void char_data_callback(mp_obj_t self_in, uint16_t length, uint8_t * p_data) { - ubluepy_characteristic_obj_t * self = MP_OBJ_TO_PTR(self_in); - self->value_data = mp_obj_new_bytearray(length, p_data); -} - -/// \method read() -/// Read Characteristic value. -/// -STATIC mp_obj_t char_read(mp_obj_t self_in) { - ubluepy_characteristic_obj_t * self = MP_OBJ_TO_PTR(self_in); - -#if MICROPY_PY_UBLUEPY_CENTRAL - // TODO: free any previous allocation of value_data - - ble_drv_attr_c_read(self->p_service->p_periph->conn_handle, - self->handle, - self_in, - char_data_callback); - - return self->value_data; -#else - (void)self; - return mp_const_none; -#endif -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_characteristic_read_obj, char_read); - -/// \method write(data, [with_response=False]) -/// Write Characteristic value. -/// -STATIC mp_obj_t char_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - ubluepy_characteristic_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - mp_obj_t data = pos_args[1]; - - static const mp_arg_t allowed_args[] = { - { MP_QSTR_with_response, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false } }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); - - // figure out mode of the Peripheral - ubluepy_role_type_t role = self->p_service->p_periph->role; - - if (role == UBLUEPY_ROLE_PERIPHERAL) { - if (self->props & UBLUEPY_PROP_NOTIFY) { - ble_drv_attr_s_notify(self->p_service->p_periph->conn_handle, - self->handle, - bufinfo.len, - bufinfo.buf); - } else { - ble_drv_attr_s_write(self->p_service->p_periph->conn_handle, - self->handle, - bufinfo.len, - bufinfo.buf); - } - } else { -#if MICROPY_PY_UBLUEPY_CENTRAL - bool with_response = args[0].u_bool; - - ble_drv_attr_c_write(self->p_service->p_periph->conn_handle, - self->handle, - bufinfo.len, - bufinfo.buf, - with_response); -#endif - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ubluepy_characteristic_write_obj, 2, char_write); - -/// \method properties() -/// Read Characteristic value properties. -/// -STATIC mp_obj_t char_properties(mp_obj_t self_in) { - ubluepy_characteristic_obj_t * self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(self->props); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_characteristic_get_properties_obj, char_properties); - -/// \method uuid() -/// Get UUID instance of the characteristic. -/// -STATIC mp_obj_t char_uuid(mp_obj_t self_in) { - ubluepy_characteristic_obj_t * self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_FROM_PTR(self->p_uuid); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_characteristic_get_uuid_obj, char_uuid); - - -STATIC const mp_rom_map_elem_t ubluepy_characteristic_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&ubluepy_characteristic_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&ubluepy_characteristic_write_obj) }, -#if 0 - { MP_ROM_QSTR(MP_QSTR_supportsRead), MP_ROM_PTR(&ubluepy_characteristic_supports_read_obj) }, - { MP_ROM_QSTR(MP_QSTR_propertiesToString), MP_ROM_PTR(&ubluepy_characteristic_properties_to_str_obj) }, - { MP_ROM_QSTR(MP_QSTR_getHandle), MP_ROM_PTR(&ubluepy_characteristic_get_handle_obj) }, - - // Properties - { MP_ROM_QSTR(MP_QSTR_peripheral), MP_ROM_PTR(&ubluepy_characteristic_get_peripheral_obj) }, -#endif - { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&ubluepy_characteristic_get_uuid_obj) }, - { MP_ROM_QSTR(MP_QSTR_properties), MP_ROM_PTR(&ubluepy_characteristic_get_properties_obj) }, - - { MP_ROM_QSTR(MP_QSTR_PROP_BROADCAST), MP_ROM_INT(UBLUEPY_PROP_BROADCAST) }, - { MP_ROM_QSTR(MP_QSTR_PROP_READ), MP_ROM_INT(UBLUEPY_PROP_READ) }, - { MP_ROM_QSTR(MP_QSTR_PROP_WRITE_WO_RESP), MP_ROM_INT(UBLUEPY_PROP_WRITE_WO_RESP) }, - { MP_ROM_QSTR(MP_QSTR_PROP_WRITE), MP_ROM_INT(UBLUEPY_PROP_WRITE) }, - { MP_ROM_QSTR(MP_QSTR_PROP_NOTIFY), MP_ROM_INT(UBLUEPY_PROP_NOTIFY) }, - { MP_ROM_QSTR(MP_QSTR_PROP_INDICATE), MP_ROM_INT(UBLUEPY_PROP_INDICATE) }, - { MP_ROM_QSTR(MP_QSTR_PROP_AUTH_SIGNED_WR), MP_ROM_INT(UBLUEPY_PROP_AUTH_SIGNED_WR) }, - -#if MICROPY_PY_UBLUEPY_PERIPHERAL - { MP_ROM_QSTR(MP_QSTR_ATTR_CCCD), MP_ROM_INT(UBLUEPY_ATTR_CCCD) }, -#endif - -#if MICROPY_PY_UBLUEPY_CENTRAL - { MP_ROM_QSTR(MP_QSTR_PROP_AUTH_SIGNED_WR), MP_ROM_INT(UBLUEPY_ATTR_SCCD) }, -#endif -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_characteristic_locals_dict, ubluepy_characteristic_locals_dict_table); - -const mp_obj_type_t ubluepy_characteristic_type = { - { &mp_type_type }, - .name = MP_QSTR_Characteristic, - .print = ubluepy_characteristic_print, - .make_new = ubluepy_characteristic_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_characteristic_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_constants.c b/ports/nrf/modules/ubluepy/ubluepy_constants.c deleted file mode 100644 index 14e433e6e..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_constants.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * 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 "py/obj.h" -#include "py/runtime.h" - -#if MICROPY_PY_UBLUEPY - -#include "modubluepy.h" - -STATIC const mp_rom_map_elem_t ubluepy_constants_ad_types_locals_dict_table[] = { - // GAP AD Types - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_FLAGS), MP_ROM_INT(0x01) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE), MP_ROM_INT(0x02) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE), MP_ROM_INT(0x03) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE), MP_ROM_INT(0x04) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE), MP_ROM_INT(0x05) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE), MP_ROM_INT(0x06) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE), MP_ROM_INT(0x07) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SHORT_LOCAL_NAME), MP_ROM_INT(0x08) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_COMPLETE_LOCAL_NAME), MP_ROM_INT(0x09) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_TX_POWER_LEVEL), MP_ROM_INT(0x0A) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_CLASS_OF_DEVICE), MP_ROM_INT(0x0D) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SIMPLE_PAIRING_HASH_C), MP_ROM_INT(0x0E) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R), MP_ROM_INT(0x0F) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SECURITY_MANAGER_TK_VALUE), MP_ROM_INT(0x10) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS), MP_ROM_INT(0x11) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE), MP_ROM_INT(0x12) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT), MP_ROM_INT(0x14) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT), MP_ROM_INT(0x15) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SERVICE_DATA), MP_ROM_INT(0x16) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_PUBLIC_TARGET_ADDRESS), MP_ROM_INT(0x17) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_RANDOM_TARGET_ADDRESS), MP_ROM_INT(0x18) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_APPEARANCE), MP_ROM_INT(0x19) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_ADVERTISING_INTERVAL), MP_ROM_INT(0x1A) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS), MP_ROM_INT(0x1B) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_LE_ROLE), MP_ROM_INT(0x1C) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SIMPLE_PAIRING_HASH_C256), MP_ROM_INT(0x1D) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256), MP_ROM_INT(0x1E) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SERVICE_DATA_32BIT_UUID), MP_ROM_INT(0x20) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_SERVICE_DATA_128BIT_UUID), MP_ROM_INT(0x21) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_URI), MP_ROM_INT(0x24) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_3D_INFORMATION_DATA), MP_ROM_INT(0x3D) }, - { MP_ROM_QSTR(MP_QSTR_AD_TYPE_MANUFACTURER_SPECIFIC_DATA), MP_ROM_INT(0xFF) }, -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_constants_ad_types_locals_dict, ubluepy_constants_ad_types_locals_dict_table); - -const mp_obj_type_t ubluepy_constants_ad_types_type = { - { &mp_type_type }, - .name = MP_QSTR_ad_types, - .locals_dict = (mp_obj_dict_t*)&ubluepy_constants_ad_types_locals_dict -}; - -STATIC const mp_rom_map_elem_t ubluepy_constants_locals_dict_table[] = { - // GAP events - { MP_ROM_QSTR(MP_QSTR_EVT_GAP_CONNECTED), MP_ROM_INT(16) }, - { MP_ROM_QSTR(MP_QSTR_EVT_GAP_DISCONNECTED), MP_ROM_INT(17) }, - { MP_ROM_QSTR(MP_QSTR_EVT_GATTS_WRITE), MP_ROM_INT(80) }, - { MP_ROM_QSTR(MP_QSTR_UUID_CCCD), MP_ROM_INT(0x2902) }, - - { MP_ROM_QSTR(MP_QSTR_ADDR_TYPE_PUBLIC), MP_ROM_INT(UBLUEPY_ADDR_TYPE_PUBLIC) }, - { MP_ROM_QSTR(MP_QSTR_ADDR_TYPE_RANDOM_STATIC), MP_ROM_INT(UBLUEPY_ADDR_TYPE_RANDOM_STATIC) }, - - { MP_ROM_QSTR(MP_QSTR_ad_types), MP_ROM_PTR(&ubluepy_constants_ad_types_type) }, -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_constants_locals_dict, ubluepy_constants_locals_dict_table); - -const mp_obj_type_t ubluepy_constants_type = { - { &mp_type_type }, - .name = MP_QSTR_constants, - .locals_dict = (mp_obj_dict_t*)&ubluepy_constants_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/modules/ubluepy/ubluepy_delegate.c b/ports/nrf/modules/ubluepy/ubluepy_delegate.c deleted file mode 100644 index 07bb7f492..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_delegate.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * 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 "py/obj.h" -#include "py/runtime.h" - -#if MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL - -#include "modubluepy.h" - -STATIC void ubluepy_delegate_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_delegate_obj_t * self = (ubluepy_delegate_obj_t *)o; - (void)self; - mp_printf(print, "DefaultDelegate()"); -} - -STATIC mp_obj_t ubluepy_delegate_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - ubluepy_delegate_obj_t *s = m_new_obj(ubluepy_delegate_obj_t); - s->base.type = type; - - return MP_OBJ_FROM_PTR(s); -} - -/// \method handleConnection() -/// Handle connection events. -/// -STATIC mp_obj_t delegate_handle_conn(mp_obj_t self_in) { - ubluepy_delegate_obj_t *self = MP_OBJ_TO_PTR(self_in); - - (void)self; - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_delegate_handle_conn_obj, delegate_handle_conn); - -/// \method handleNotification() -/// Handle notification events. -/// -STATIC mp_obj_t delegate_handle_notif(mp_obj_t self_in) { - ubluepy_delegate_obj_t *self = MP_OBJ_TO_PTR(self_in); - - (void)self; - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_delegate_handle_notif_obj, delegate_handle_notif); - -STATIC const mp_rom_map_elem_t ubluepy_delegate_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_handleConnection), MP_ROM_PTR(&ubluepy_delegate_handle_conn_obj) }, - { MP_ROM_QSTR(MP_QSTR_handleNotification), MP_ROM_PTR(&ubluepy_delegate_handle_notif_obj) }, -#if 0 - { MP_ROM_QSTR(MP_QSTR_handleDiscovery), MP_ROM_PTR(&ubluepy_delegate_handle_disc_obj) }, -#endif -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_delegate_locals_dict, ubluepy_delegate_locals_dict_table); - -const mp_obj_type_t ubluepy_delegate_type = { - { &mp_type_type }, - .name = MP_QSTR_DefaultDelegate, - .print = ubluepy_delegate_print, - .make_new = ubluepy_delegate_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_delegate_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_descriptor.c b/ports/nrf/modules/ubluepy/ubluepy_descriptor.c deleted file mode 100644 index b15301954..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_descriptor.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * 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 "py/obj.h" -#include "py/runtime.h" -#include "py/objstr.h" -#include "py/misc.h" - -#if MICROPY_PY_UBLUEPY - -#include "modubluepy.h" -#include "ble_drv.h" - -STATIC void ubluepy_descriptor_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_descriptor_obj_t * self = (ubluepy_descriptor_obj_t *)o; - - mp_printf(print, "Descriptor(uuid: 0x" HEX2_FMT HEX2_FMT ")", - self->p_uuid->value[1], self->p_uuid->value[0]); -} - -STATIC mp_obj_t ubluepy_descriptor_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - - enum { ARG_NEW_UUID }; - - static const mp_arg_t allowed_args[] = { - { ARG_NEW_UUID, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - ubluepy_descriptor_obj_t * s = m_new_obj(ubluepy_descriptor_obj_t); - s->base.type = type; - - mp_obj_t uuid_obj = args[ARG_NEW_UUID].u_obj; - - (void)uuid_obj; - - return MP_OBJ_FROM_PTR(s); -} - -STATIC const mp_rom_map_elem_t ubluepy_descriptor_locals_dict_table[] = { -#if 0 - { MP_ROM_QSTR(MP_QSTR_binVal), MP_ROM_PTR(&ubluepy_descriptor_bin_val_obj) }, -#endif -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_descriptor_locals_dict, ubluepy_descriptor_locals_dict_table); - -const mp_obj_type_t ubluepy_descriptor_type = { - { &mp_type_type }, - .name = MP_QSTR_Descriptor, - .print = ubluepy_descriptor_print, - .make_new = ubluepy_descriptor_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_descriptor_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c b/ports/nrf/modules/ubluepy/ubluepy_peripheral.c deleted file mode 100644 index 7b6b315a9..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_peripheral.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * 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/obj.h" -#include "py/runtime.h" -#include "py/objstr.h" -#include "py/objlist.h" - -#if MICROPY_PY_UBLUEPY - -#include "ble_drv.h" - -STATIC void ubluepy_peripheral_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_peripheral_obj_t * self = (ubluepy_peripheral_obj_t *)o; - (void)self; - mp_printf(print, "Peripheral(conn_handle: " HEX2_FMT ")", - self->conn_handle); -} - -STATIC void gap_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t conn_handle, uint16_t length, uint8_t * data) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - - if (event_id == 16) { // connect event - self->conn_handle = conn_handle; - } else if (event_id == 17) { // disconnect event - self->conn_handle = 0xFFFF; // invalid connection handle - } - - if (self->conn_handler != mp_const_none) { - mp_obj_t args[3]; - mp_uint_t num_of_args = 3; - args[0] = MP_OBJ_NEW_SMALL_INT(event_id); - args[1] = MP_OBJ_NEW_SMALL_INT(conn_handle); - if (data != NULL) { - args[2] = mp_obj_new_bytearray_by_ref(length, data); - } else { - args[2] = mp_const_none; - } - - // for now hard-code all events to conn_handler - mp_call_function_n_kw(self->conn_handler, num_of_args, 0, args); - } - - (void)self; -} - -STATIC void gatts_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - - if (self->conn_handler != mp_const_none) { - mp_obj_t args[3]; - mp_uint_t num_of_args = 3; - args[0] = MP_OBJ_NEW_SMALL_INT(event_id); - args[1] = MP_OBJ_NEW_SMALL_INT(attr_handle); - if (data != NULL) { - args[2] = mp_obj_new_bytearray_by_ref(length, data); - } else { - args[2] = mp_const_none; - } - - // for now hard-code all events to conn_handler - mp_call_function_n_kw(self->conn_handler, num_of_args, 0, args); - } - -} - -#if MICROPY_PY_UBLUEPY_CENTRAL - -static volatile bool m_disc_evt_received; - -STATIC void gattc_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t attr_handle, uint16_t length, uint8_t * data) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - (void)self; - m_disc_evt_received = true; -} -#endif - -STATIC mp_obj_t ubluepy_peripheral_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - enum { - ARG_NEW_DEVICE_ADDR, - ARG_NEW_ADDR_TYPE - }; - - static const mp_arg_t allowed_args[] = { - { ARG_NEW_DEVICE_ADDR, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { ARG_NEW_ADDR_TYPE, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - ubluepy_peripheral_obj_t *s = m_new_obj(ubluepy_peripheral_obj_t); - s->base.type = type; - - s->delegate = mp_const_none; - s->conn_handler = mp_const_none; - s->notif_handler = mp_const_none; - s->conn_handle = 0xFFFF; - - s->service_list = mp_obj_new_list(0, NULL); - - return MP_OBJ_FROM_PTR(s); -} - -/// \method withDelegate(DefaultDelegate) -/// Set delegate instance for handling Bluetooth LE events. -/// -STATIC mp_obj_t peripheral_with_delegate(mp_obj_t self_in, mp_obj_t delegate) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - - self->delegate = delegate; - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_peripheral_with_delegate_obj, peripheral_with_delegate); - -/// \method setNotificationHandler(func) -/// Set handler for Bluetooth LE notification events. -/// -STATIC mp_obj_t peripheral_set_notif_handler(mp_obj_t self_in, mp_obj_t func) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - - self->notif_handler = func; - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_peripheral_set_notif_handler_obj, peripheral_set_notif_handler); - -/// \method setConnectionHandler(func) -/// Set handler for Bluetooth LE connection events. -/// -STATIC mp_obj_t peripheral_set_conn_handler(mp_obj_t self_in, mp_obj_t func) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - - self->conn_handler = func; - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_peripheral_set_conn_handler_obj, peripheral_set_conn_handler); - -#if MICROPY_PY_UBLUEPY_PERIPHERAL - -/// \method advertise(device_name, [service=[service1, service2, ...]], [data=bytearray], [connectable=True]) -/// Start advertising. Connectable advertisement type by default. -/// -STATIC mp_obj_t peripheral_advertise(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - static const mp_arg_t allowed_args[] = { - { MP_QSTR_device_name, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_services, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_data, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - }; - - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - - self->role = UBLUEPY_ROLE_PERIPHERAL; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - // ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - mp_obj_t device_name_obj = args[0].u_obj; - mp_obj_t service_obj = args[1].u_obj; - mp_obj_t data_obj = args[2].u_obj; - mp_obj_t connectable_obj = args[3].u_obj; - - ubluepy_advertise_data_t adv_data; - memset(&adv_data, 0, sizeof(ubluepy_advertise_data_t)); - - if (device_name_obj != mp_const_none && MP_OBJ_IS_STR(device_name_obj)) { - GET_STR_DATA_LEN(device_name_obj, str_data, str_len); - - adv_data.p_device_name = (uint8_t *)str_data; - adv_data.device_name_len = str_len; - } - - if (service_obj != mp_const_none) { - mp_obj_t * services = NULL; - mp_uint_t num_services; - mp_obj_get_array(service_obj, &num_services, &services); - - if (num_services > 0) { - adv_data.p_services = services; - adv_data.num_of_services = num_services; - } - } - - if (data_obj != mp_const_none) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(data_obj, &bufinfo, MP_BUFFER_READ); - - if (bufinfo.len > 0) { - adv_data.p_data = bufinfo.buf; - adv_data.data_len = bufinfo.len; - } - } - - adv_data.connectable = true; - if (connectable_obj != mp_const_none && !(mp_obj_is_true(connectable_obj))) { - adv_data.connectable = false; - } else { - ble_drv_gap_event_handler_set(MP_OBJ_FROM_PTR(self), gap_event_handler); - ble_drv_gatts_event_handler_set(MP_OBJ_FROM_PTR(self), gatts_event_handler); - } - - (void)ble_drv_advertise_data(&adv_data); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ubluepy_peripheral_advertise_obj, 0, peripheral_advertise); - -/// \method advertise_stop() -/// Stop advertisement if any onging advertisement. -/// -STATIC mp_obj_t peripheral_advertise_stop(mp_obj_t self_in) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - - (void)self; - - ble_drv_advertise_stop(); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_peripheral_advertise_stop_obj, peripheral_advertise_stop); - -#endif // MICROPY_PY_UBLUEPY_PERIPHERAL - -/// \method disconnect() -/// disconnect connection. -/// -STATIC mp_obj_t peripheral_disconnect(mp_obj_t self_in) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(self_in); - - (void)self; - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_peripheral_disconnect_obj, peripheral_disconnect); - -/// \method addService(Service) -/// Add service to the Peripheral. -/// -STATIC mp_obj_t peripheral_add_service(mp_obj_t self_in, mp_obj_t service) { - ubluepy_peripheral_obj_t * self = MP_OBJ_TO_PTR(self_in); - ubluepy_service_obj_t * p_service = MP_OBJ_TO_PTR(service); - - p_service->p_periph = self; - - mp_obj_list_append(self->service_list, service); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_peripheral_add_service_obj, peripheral_add_service); - -/// \method getServices() -/// Return list with all service registered in the Peripheral. -/// -STATIC mp_obj_t peripheral_get_services(mp_obj_t self_in) { - ubluepy_peripheral_obj_t * self = MP_OBJ_TO_PTR(self_in); - - return self->service_list; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_peripheral_get_services_obj, peripheral_get_services); - -#if MICROPY_PY_UBLUEPY_CENTRAL - -void static disc_add_service(mp_obj_t self, ble_drv_service_data_t * p_service_data) { - ubluepy_service_obj_t * p_service = m_new_obj(ubluepy_service_obj_t); - p_service->base.type = &ubluepy_service_type; - - ubluepy_uuid_obj_t * p_uuid = m_new_obj(ubluepy_uuid_obj_t); - p_uuid->base.type = &ubluepy_uuid_type; - - p_service->p_uuid = p_uuid; - - p_uuid->type = p_service_data->uuid_type; - p_uuid->value[0] = p_service_data->uuid & 0xFF; - p_uuid->value[1] = p_service_data->uuid >> 8; - - p_service->handle = p_service_data->start_handle; - p_service->start_handle = p_service_data->start_handle; - p_service->end_handle = p_service_data->end_handle; - - p_service->char_list = mp_obj_new_list(0, NULL); - - peripheral_add_service(self, MP_OBJ_FROM_PTR(p_service)); -} - -void static disc_add_char(mp_obj_t service_in, ble_drv_char_data_t * p_desc_data) { - ubluepy_service_obj_t * p_service = MP_OBJ_TO_PTR(service_in); - ubluepy_characteristic_obj_t * p_char = m_new_obj(ubluepy_characteristic_obj_t); - p_char->base.type = &ubluepy_characteristic_type; - - ubluepy_uuid_obj_t * p_uuid = m_new_obj(ubluepy_uuid_obj_t); - p_uuid->base.type = &ubluepy_uuid_type; - - p_char->p_uuid = p_uuid; - - p_uuid->type = p_desc_data->uuid_type; - p_uuid->value[0] = p_desc_data->uuid & 0xFF; - p_uuid->value[1] = p_desc_data->uuid >> 8; - - // add characteristic specific data from discovery - p_char->props = p_desc_data->props; - p_char->handle = p_desc_data->value_handle; - - // equivalent to ubluepy_service.c - service_add_characteristic() - // except the registration of the characteristic towards the bluetooth stack - p_char->service_handle = p_service->handle; - p_char->p_service = p_service; - - mp_obj_list_append(p_service->char_list, MP_OBJ_FROM_PTR(p_char)); -} - -/// \method connect(device_address [, addr_type=ADDR_TYPE_PUBLIC]) -/// Connect to device peripheral with the given device address. -/// addr_type can be either ADDR_TYPE_PUBLIC (default) or -/// ADDR_TYPE_RANDOM_STATIC. -/// -STATIC mp_obj_t peripheral_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - ubluepy_peripheral_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - mp_obj_t dev_addr = pos_args[1]; - - self->role = UBLUEPY_ROLE_CENTRAL; - - static const mp_arg_t allowed_args[] = { - { MP_QSTR_addr_type, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = UBLUEPY_ADDR_TYPE_PUBLIC } }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - uint8_t addr_type = args[0].u_int; - - ble_drv_gap_event_handler_set(MP_OBJ_FROM_PTR(self), gap_event_handler); - - if (MP_OBJ_IS_STR(dev_addr)) { - GET_STR_DATA_LEN(dev_addr, str_data, str_len); - if (str_len == 17) { // Example "11:22:33:aa:bb:cc" - - uint8_t * p_addr = m_new(uint8_t, 6); - - p_addr[0] = unichar_xdigit_value(str_data[16]); - p_addr[0] += unichar_xdigit_value(str_data[15]) << 4; - p_addr[1] = unichar_xdigit_value(str_data[13]); - p_addr[1] += unichar_xdigit_value(str_data[12]) << 4; - p_addr[2] = unichar_xdigit_value(str_data[10]); - p_addr[2] += unichar_xdigit_value(str_data[9]) << 4; - p_addr[3] = unichar_xdigit_value(str_data[7]); - p_addr[3] += unichar_xdigit_value(str_data[6]) << 4; - p_addr[4] = unichar_xdigit_value(str_data[4]); - p_addr[4] += unichar_xdigit_value(str_data[3]) << 4; - p_addr[5] = unichar_xdigit_value(str_data[1]); - p_addr[5] += unichar_xdigit_value(str_data[0]) << 4; - - ble_drv_connect(p_addr, addr_type); - - m_del(uint8_t, p_addr, 6); - } - } - - // block until connected - while (self->conn_handle == 0xFFFF) { - ; - } - - ble_drv_gattc_event_handler_set(MP_OBJ_FROM_PTR(self), gattc_event_handler); - - bool service_disc_retval = ble_drv_discover_services(self, self->conn_handle, 0x0001, disc_add_service); - - // continue discovery of primary services ... - while (service_disc_retval) { - // locate the last added service - mp_obj_t * services = NULL; - mp_uint_t num_services; - mp_obj_get_array(self->service_list, &num_services, &services); - - ubluepy_service_obj_t * p_service = (ubluepy_service_obj_t *)services[num_services - 1]; - - service_disc_retval = ble_drv_discover_services(self, - self->conn_handle, - p_service->end_handle + 1, - disc_add_service); - } - - // For each service perform a characteristic discovery - mp_obj_t * services = NULL; - mp_uint_t num_services; - mp_obj_get_array(self->service_list, &num_services, &services); - - for (uint16_t s = 0; s < num_services; s++) { - ubluepy_service_obj_t * p_service = (ubluepy_service_obj_t *)services[s]; - bool char_disc_retval = ble_drv_discover_characteristic(p_service, - self->conn_handle, - p_service->start_handle, - p_service->end_handle, - disc_add_char); - // continue discovery of characteristics ... - while (char_disc_retval) { - mp_obj_t * characteristics = NULL; - mp_uint_t num_chars; - mp_obj_get_array(p_service->char_list, &num_chars, &characteristics); - - ubluepy_characteristic_obj_t * p_char = (ubluepy_characteristic_obj_t *)characteristics[num_chars - 1]; - uint16_t next_handle = p_char->handle + 1; - if ((next_handle) < p_service->end_handle) { - char_disc_retval = ble_drv_discover_characteristic(p_service, - self->conn_handle, - next_handle, - p_service->end_handle, - disc_add_char); - } else { - break; - } - } - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(ubluepy_peripheral_connect_obj, 2, peripheral_connect); - -#endif - -STATIC const mp_rom_map_elem_t ubluepy_peripheral_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_withDelegate), MP_ROM_PTR(&ubluepy_peripheral_with_delegate_obj) }, - { MP_ROM_QSTR(MP_QSTR_setNotificationHandler), MP_ROM_PTR(&ubluepy_peripheral_set_notif_handler_obj) }, - { MP_ROM_QSTR(MP_QSTR_setConnectionHandler), MP_ROM_PTR(&ubluepy_peripheral_set_conn_handler_obj) }, - { MP_ROM_QSTR(MP_QSTR_getServices), MP_ROM_PTR(&ubluepy_peripheral_get_services_obj) }, -#if MICROPY_PY_UBLUEPY_CENTRAL - { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&ubluepy_peripheral_connect_obj) }, -#if 0 - { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&ubluepy_peripheral_disconnect_obj) }, - { MP_ROM_QSTR(MP_QSTR_getServiceByUUID), MP_ROM_PTR(&ubluepy_peripheral_get_service_by_uuid_obj) }, - { MP_ROM_QSTR(MP_QSTR_getCharacteristics), MP_ROM_PTR(&ubluepy_peripheral_get_chars_obj) }, - { MP_ROM_QSTR(MP_QSTR_getDescriptors), MP_ROM_PTR(&ubluepy_peripheral_get_descs_obj) }, - { MP_ROM_QSTR(MP_QSTR_waitForNotifications), MP_ROM_PTR(&ubluepy_peripheral_wait_for_notif_obj) }, - { MP_ROM_QSTR(MP_QSTR_writeCharacteristic), MP_ROM_PTR(&ubluepy_peripheral_write_char_obj) }, - { MP_ROM_QSTR(MP_QSTR_readCharacteristic), MP_ROM_PTR(&ubluepy_peripheral_read_char_obj) }, -#endif // 0 -#endif // MICROPY_PY_UBLUEPY_CENTRAL -#if MICROPY_PY_UBLUEPY_PERIPHERAL - { MP_ROM_QSTR(MP_QSTR_advertise), MP_ROM_PTR(&ubluepy_peripheral_advertise_obj) }, - { MP_ROM_QSTR(MP_QSTR_advertise_stop), MP_ROM_PTR(&ubluepy_peripheral_advertise_stop_obj) }, - { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&ubluepy_peripheral_disconnect_obj) }, - { MP_ROM_QSTR(MP_QSTR_addService), MP_ROM_PTR(&ubluepy_peripheral_add_service_obj) }, -#if 0 - { MP_ROM_QSTR(MP_QSTR_addCharacteristic), MP_ROM_PTR(&ubluepy_peripheral_add_char_obj) }, - { MP_ROM_QSTR(MP_QSTR_addDescriptor), MP_ROM_PTR(&ubluepy_peripheral_add_desc_obj) }, - { MP_ROM_QSTR(MP_QSTR_writeCharacteristic), MP_ROM_PTR(&ubluepy_peripheral_write_char_obj) }, - { MP_ROM_QSTR(MP_QSTR_readCharacteristic), MP_ROM_PTR(&ubluepy_peripheral_read_char_obj) }, -#endif -#endif -#if MICROPY_PY_UBLUEPY_BROADCASTER - { MP_ROM_QSTR(MP_QSTR_advertise), MP_ROM_PTR(&ubluepy_peripheral_advertise_obj) }, -#endif -#if MICROPY_PY_UBLUEPY_OBSERVER - // Nothing yet. -#endif -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_peripheral_locals_dict, ubluepy_peripheral_locals_dict_table); - -const mp_obj_type_t ubluepy_peripheral_type = { - { &mp_type_type }, - .name = MP_QSTR_Peripheral, - .print = ubluepy_peripheral_print, - .make_new = ubluepy_peripheral_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_peripheral_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c b/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c deleted file mode 100644 index 773070b08..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_scan_entry.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * 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/obj.h" -#include "py/runtime.h" -#include "py/objstr.h" -#include "py/objlist.h" -#include "py/objarray.h" -#include "py/objtuple.h" -#include "py/qstr.h" - -#if MICROPY_PY_UBLUEPY_CENTRAL - -#include "ble_drv.h" - -STATIC void ubluepy_scan_entry_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_scan_entry_obj_t * self = (ubluepy_scan_entry_obj_t *)o; - (void)self; - mp_printf(print, "ScanEntry"); -} - -/// \method addr() -/// Return address as text string. -/// -STATIC mp_obj_t scan_entry_get_addr(mp_obj_t self_in) { - ubluepy_scan_entry_obj_t *self = MP_OBJ_TO_PTR(self_in); - return self->addr; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scan_entry_get_addr_obj, scan_entry_get_addr); - -/// \method addr_type() -/// Return address type value. -/// -STATIC mp_obj_t scan_entry_get_addr_type(mp_obj_t self_in) { - ubluepy_scan_entry_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_int(self->addr_type); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scan_entry_get_addr_type_obj, scan_entry_get_addr_type); - -/// \method rssi() -/// Return RSSI value. -/// -STATIC mp_obj_t scan_entry_get_rssi(mp_obj_t self_in) { - ubluepy_scan_entry_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_int(self->rssi); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scan_entry_get_rssi_obj, scan_entry_get_rssi); - -/// \method getScanData() -/// Return list of the scan data tupples (ad_type, description, value) -/// -STATIC mp_obj_t scan_entry_get_scan_data(mp_obj_t self_in) { - ubluepy_scan_entry_obj_t * self = MP_OBJ_TO_PTR(self_in); - - mp_obj_t retval_list = mp_obj_new_list(0, NULL); - - // TODO: check if self->data is set - mp_obj_array_t * data = MP_OBJ_TO_PTR(self->data); - - uint16_t byte_index = 0; - - while (byte_index < data->len) { - mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL)); - - uint8_t adv_item_len = ((uint8_t * )data->items)[byte_index]; - uint8_t adv_item_type = ((uint8_t * )data->items)[byte_index + 1]; - - mp_obj_t description = mp_const_none; - - mp_map_t *constant_map = mp_obj_dict_get_map(ubluepy_constants_ad_types_type.locals_dict); - mp_map_elem_t *ad_types_table = MP_OBJ_TO_PTR(constant_map->table); - - uint16_t num_of_elements = constant_map->used; - - for (uint16_t i = 0; i < num_of_elements; i++) { - mp_map_elem_t element = (mp_map_elem_t)*ad_types_table; - ad_types_table++; - uint16_t element_value = mp_obj_get_int(element.value); - - if (adv_item_type == element_value) { - qstr key_qstr = MP_OBJ_QSTR_VALUE(element.key); - const char * text = qstr_str(key_qstr); - size_t len = qstr_len(key_qstr); - - vstr_t vstr; - vstr_init(&vstr, len); - vstr_printf(&vstr, "%s", text); - description = mp_obj_new_str(vstr.buf, vstr.len); - vstr_clear(&vstr); - } - } - - t->items[0] = MP_OBJ_NEW_SMALL_INT(adv_item_type); - t->items[1] = description; - t->items[2] = mp_obj_new_bytearray(adv_item_len - 1, - &((uint8_t * )data->items)[byte_index + 2]); - mp_obj_list_append(retval_list, MP_OBJ_FROM_PTR(t)); - - byte_index += adv_item_len + 1; - } - - return retval_list; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_scan_entry_get_scan_data_obj, scan_entry_get_scan_data); - -STATIC const mp_rom_map_elem_t ubluepy_scan_entry_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_addr), MP_ROM_PTR(&bluepy_scan_entry_get_addr_obj) }, - { MP_ROM_QSTR(MP_QSTR_addr_type), MP_ROM_PTR(&bluepy_scan_entry_get_addr_type_obj) }, - { MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&bluepy_scan_entry_get_rssi_obj) }, - { MP_ROM_QSTR(MP_QSTR_getScanData), MP_ROM_PTR(&ubluepy_scan_entry_get_scan_data_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_scan_entry_locals_dict, ubluepy_scan_entry_locals_dict_table); - -const mp_obj_type_t ubluepy_scan_entry_type = { - { &mp_type_type }, - .name = MP_QSTR_ScanEntry, - .print = ubluepy_scan_entry_print, - .locals_dict = (mp_obj_dict_t*)&ubluepy_scan_entry_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_scanner.c b/ports/nrf/modules/ubluepy/ubluepy_scanner.c deleted file mode 100644 index 1cde3d551..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_scanner.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * 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/obj.h" -#include "py/runtime.h" -#include "py/objstr.h" -#include "py/objlist.h" -#include "py/mphal.h" - -#if MICROPY_PY_UBLUEPY_CENTRAL - -#include "ble_drv.h" - -STATIC void adv_event_handler(mp_obj_t self_in, uint16_t event_id, ble_drv_adv_data_t * data) { - ubluepy_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in); - - ubluepy_scan_entry_obj_t * item = m_new_obj(ubluepy_scan_entry_obj_t); - item->base.type = &ubluepy_scan_entry_type; - - vstr_t vstr; - vstr_init(&vstr, 17); - - vstr_printf(&vstr, ""HEX2_FMT":"HEX2_FMT":"HEX2_FMT":" \ - HEX2_FMT":"HEX2_FMT":"HEX2_FMT"", - data->p_peer_addr[5], data->p_peer_addr[4], data->p_peer_addr[3], - data->p_peer_addr[2], data->p_peer_addr[1], data->p_peer_addr[0]); - - item->addr = mp_obj_new_str(vstr.buf, vstr.len); - - vstr_clear(&vstr); - - item->addr_type = data->addr_type; - item->rssi = data->rssi; - item->data = mp_obj_new_bytearray(data->data_len, data->p_data); - - mp_obj_list_append(self->adv_reports, item); -} - -STATIC void ubluepy_scanner_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_scanner_obj_t * self = (ubluepy_scanner_obj_t *)o; - (void)self; - mp_printf(print, "Scanner"); -} - -STATIC mp_obj_t ubluepy_scanner_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - static const mp_arg_t allowed_args[] = { - - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - ubluepy_scanner_obj_t * s = m_new_obj(ubluepy_scanner_obj_t); - s->base.type = type; - - return MP_OBJ_FROM_PTR(s); -} - -/// \method scan(timeout) -/// Scan for devices. Timeout is in milliseconds and will set the duration -/// of the scanning. -/// -STATIC mp_obj_t scanner_scan(mp_obj_t self_in, mp_obj_t timeout_in) { - ubluepy_scanner_obj_t * self = MP_OBJ_TO_PTR(self_in); - mp_int_t timeout = mp_obj_get_int(timeout_in); - - self->adv_reports = mp_obj_new_list(0, NULL); - - ble_drv_adv_report_handler_set(MP_OBJ_FROM_PTR(self), adv_event_handler); - - // start - ble_drv_scan_start(); - - // sleep - mp_hal_delay_ms(timeout); - - // stop - ble_drv_scan_stop(); - - return self->adv_reports; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_scanner_scan_obj, scanner_scan); - -STATIC const mp_rom_map_elem_t ubluepy_scanner_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&ubluepy_scanner_scan_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_scanner_locals_dict, ubluepy_scanner_locals_dict_table); - - -const mp_obj_type_t ubluepy_scanner_type = { - { &mp_type_type }, - .name = MP_QSTR_Scanner, - .print = ubluepy_scanner_print, - .make_new = ubluepy_scanner_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_scanner_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_service.c b/ports/nrf/modules/ubluepy/ubluepy_service.c deleted file mode 100644 index 59b81234f..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_service.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * 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 "py/obj.h" -#include "py/runtime.h" -#include "py/objlist.h" -#include "supervisor/shared/translate.h" - -#if MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL - -#include "modubluepy.h" -#include "ble_drv.h" - -STATIC void ubluepy_service_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_service_obj_t * self = (ubluepy_service_obj_t *)o; - - mp_printf(print, "Service(handle: 0x" HEX2_FMT ")", self->handle); -} - -STATIC mp_obj_t ubluepy_service_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - - enum { ARG_NEW_UUID, ARG_NEW_TYPE }; - - static const mp_arg_t allowed_args[] = { - { ARG_NEW_UUID, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { ARG_NEW_TYPE, MP_ARG_INT, {.u_int = UBLUEPY_SERVICE_PRIMARY} }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - ubluepy_service_obj_t *s = m_new_obj(ubluepy_service_obj_t); - s->base.type = type; - - mp_obj_t uuid_obj = args[ARG_NEW_UUID].u_obj; - - if (uuid_obj == MP_OBJ_NULL) { - return MP_OBJ_FROM_PTR(s); - } - - if (MP_OBJ_IS_TYPE(uuid_obj, &ubluepy_uuid_type)) { - s->p_uuid = MP_OBJ_TO_PTR(uuid_obj); - - uint8_t type = args[ARG_NEW_TYPE].u_int; - if (type > 0 && type <= UBLUEPY_SERVICE_PRIMARY) { - s->type = type; - } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid Service type"))); - } - - (void)ble_drv_service_add(s); - - } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid UUID parameter"))); - } - - // clear reference to peripheral - s->p_periph = NULL; - s->char_list = mp_obj_new_list(0, NULL); - - return MP_OBJ_FROM_PTR(s); -} - -/// \method addCharacteristic(Characteristic) -/// Add Characteristic to the Service. -/// -STATIC mp_obj_t service_add_characteristic(mp_obj_t self_in, mp_obj_t characteristic) { - ubluepy_service_obj_t * self = MP_OBJ_TO_PTR(self_in); - ubluepy_characteristic_obj_t * p_char = MP_OBJ_TO_PTR(characteristic); - - p_char->service_handle = self->handle; - - bool retval = ble_drv_characteristic_add(p_char); - - if (retval) { - p_char->p_service = self; - } - - mp_obj_list_append(self->char_list, characteristic); - - // return mp_obj_new_bool(retval); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_service_add_char_obj, service_add_characteristic); - -/// \method getCharacteristics() -/// Return list with all characteristics registered in the Service. -/// -STATIC mp_obj_t service_get_chars(mp_obj_t self_in) { - ubluepy_service_obj_t * self = MP_OBJ_TO_PTR(self_in); - - return self->char_list; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_service_get_chars_obj, service_get_chars); - -/// \method getCharacteristic(UUID) -/// Return Characteristic with the given UUID. -/// -STATIC mp_obj_t service_get_characteristic(mp_obj_t self_in, mp_obj_t uuid) { - ubluepy_service_obj_t * self = MP_OBJ_TO_PTR(self_in); - ubluepy_uuid_obj_t * p_uuid = MP_OBJ_TO_PTR(uuid); - - // validate that there is an UUID object passed in as parameter - if (!(MP_OBJ_IS_TYPE(uuid, &ubluepy_uuid_type))) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid UUID parameter"))); - } - - mp_obj_t * chars = NULL; - mp_uint_t num_chars = 0; - mp_obj_get_array(self->char_list, &num_chars, &chars); - - for (uint8_t i = 0; i < num_chars; i++) { - ubluepy_characteristic_obj_t * p_char = (ubluepy_characteristic_obj_t *)chars[i]; - - bool type_match = p_char->p_uuid->type == p_uuid->type; - bool uuid_match = ((uint16_t)(*(uint16_t *)&p_char->p_uuid->value[0]) == - (uint16_t)(*(uint16_t *)&p_uuid->value[0])); - - if (type_match && uuid_match) { - return MP_OBJ_FROM_PTR(p_char); - } - } - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_2(ubluepy_service_get_char_obj, service_get_characteristic); - -/// \method uuid() -/// Get UUID instance of the Service. -/// -STATIC mp_obj_t service_uuid(mp_obj_t self_in) { - ubluepy_service_obj_t * self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_FROM_PTR(self->p_uuid); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_service_get_uuid_obj, service_uuid); - -STATIC const mp_rom_map_elem_t ubluepy_service_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_getCharacteristic), MP_ROM_PTR(&ubluepy_service_get_char_obj) }, - { MP_ROM_QSTR(MP_QSTR_addCharacteristic), MP_ROM_PTR(&ubluepy_service_add_char_obj) }, - { MP_ROM_QSTR(MP_QSTR_getCharacteristics), MP_ROM_PTR(&ubluepy_service_get_chars_obj) }, -#if 0 - // Properties - { MP_ROM_QSTR(MP_QSTR_peripheral), MP_ROM_PTR(&ubluepy_service_get_peripheral_obj) }, -#endif - { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&ubluepy_service_get_uuid_obj) }, - { MP_ROM_QSTR(MP_QSTR_PRIMARY), MP_ROM_INT(UBLUEPY_SERVICE_PRIMARY) }, - { MP_ROM_QSTR(MP_QSTR_SECONDARY), MP_ROM_INT(UBLUEPY_SERVICE_SECONDARY) }, -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_service_locals_dict, ubluepy_service_locals_dict_table); - -const mp_obj_type_t ubluepy_service_type = { - { &mp_type_type }, - .name = MP_QSTR_Service, - .print = ubluepy_service_print, - .make_new = ubluepy_service_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_service_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY_PERIPHERAL || MICROPY_PY_UBLUEPY_CENTRAL diff --git a/ports/nrf/modules/ubluepy/ubluepy_uuid.c b/ports/nrf/modules/ubluepy/ubluepy_uuid.c deleted file mode 100644 index b45494e41..000000000 --- a/ports/nrf/modules/ubluepy/ubluepy_uuid.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * 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 "py/obj.h" -#include "py/runtime.h" -#include "py/objstr.h" -#include "py/misc.h" -#include "supervisor/shared/translate.h" - -#if MICROPY_PY_UBLUEPY - -#include "modubluepy.h" -#include "ble_drv.h" - -STATIC void ubluepy_uuid_print(const mp_print_t *print, mp_obj_t o, mp_print_kind_t kind) { - ubluepy_uuid_obj_t * self = (ubluepy_uuid_obj_t *)o; - if (self->type == UBLUEPY_UUID_16_BIT) { - mp_printf(print, "UUID(uuid: 0x" HEX2_FMT HEX2_FMT ")", - self->value[1], self->value[0]); - } else { - mp_printf(print, "UUID(uuid: 0x" HEX2_FMT HEX2_FMT ", VS idx: " HEX2_FMT ")", - self->value[1], self->value[0], self->uuid_vs_idx); - } -} - -STATIC mp_obj_t ubluepy_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - - enum { ARG_NEW_UUID }; - - static const mp_arg_t allowed_args[] = { - { ARG_NEW_UUID, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - }; - - // parse args - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - ubluepy_uuid_obj_t *s = m_new_obj(ubluepy_uuid_obj_t); - s->base.type = type; - - mp_obj_t uuid_obj = args[ARG_NEW_UUID].u_obj; - - if (uuid_obj == MP_OBJ_NULL) { - return MP_OBJ_FROM_PTR(s); - } - - if (MP_OBJ_IS_INT(uuid_obj)) { - s->type = UBLUEPY_UUID_16_BIT; - s->value[1] = (((uint16_t)mp_obj_get_int(uuid_obj)) >> 8) & 0xFF; - s->value[0] = ((uint8_t)mp_obj_get_int(uuid_obj)) & 0xFF; - } else if (MP_OBJ_IS_STR(uuid_obj)) { - GET_STR_DATA_LEN(uuid_obj, str_data, str_len); - if (str_len == 6) { // Assume hex digit prefixed with 0x - s->type = UBLUEPY_UUID_16_BIT; - s->value[0] = unichar_xdigit_value(str_data[5]); - s->value[0] += unichar_xdigit_value(str_data[4]) << 4; - s->value[1] = unichar_xdigit_value(str_data[3]); - s->value[1] += unichar_xdigit_value(str_data[2]) << 4; - } else if (str_len == 36) { - s->type = UBLUEPY_UUID_128_BIT; - uint8_t buffer[16]; - buffer[0] = unichar_xdigit_value(str_data[35]); - buffer[0] += unichar_xdigit_value(str_data[34]) << 4; - buffer[1] = unichar_xdigit_value(str_data[33]); - buffer[1] += unichar_xdigit_value(str_data[32]) << 4; - buffer[2] = unichar_xdigit_value(str_data[31]); - buffer[2] += unichar_xdigit_value(str_data[30]) << 4; - buffer[3] = unichar_xdigit_value(str_data[29]); - buffer[3] += unichar_xdigit_value(str_data[28]) << 4; - buffer[4] = unichar_xdigit_value(str_data[27]); - buffer[4] += unichar_xdigit_value(str_data[26]) << 4; - buffer[5] = unichar_xdigit_value(str_data[25]); - buffer[5] += unichar_xdigit_value(str_data[24]) << 4; - // 23 '-' - buffer[6] = unichar_xdigit_value(str_data[22]); - buffer[6] += unichar_xdigit_value(str_data[21]) << 4; - buffer[7] = unichar_xdigit_value(str_data[20]); - buffer[7] += unichar_xdigit_value(str_data[19]) << 4; - // 18 '-' - buffer[8] = unichar_xdigit_value(str_data[17]); - buffer[8] += unichar_xdigit_value(str_data[16]) << 4; - buffer[9] = unichar_xdigit_value(str_data[15]); - buffer[9] += unichar_xdigit_value(str_data[14]) << 4; - // 13 '-' - buffer[10] = unichar_xdigit_value(str_data[12]); - buffer[10] += unichar_xdigit_value(str_data[11]) << 4; - buffer[11] = unichar_xdigit_value(str_data[10]); - buffer[11] += unichar_xdigit_value(str_data[9]) << 4; - // 8 '-' - // 16-bit field - s->value[0] = unichar_xdigit_value(str_data[7]); - s->value[0] += unichar_xdigit_value(str_data[6]) << 4; - s->value[1] = unichar_xdigit_value(str_data[5]); - s->value[1] += unichar_xdigit_value(str_data[4]) << 4; - - buffer[14] = unichar_xdigit_value(str_data[3]); - buffer[14] += unichar_xdigit_value(str_data[2]) << 4; - buffer[15] = unichar_xdigit_value(str_data[1]); - buffer[15] += unichar_xdigit_value(str_data[0]) << 4; - - ble_drv_uuid_add_vs(buffer, &s->uuid_vs_idx); - } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid UUID string length"))); - } - } else if (MP_OBJ_IS_TYPE(uuid_obj, &ubluepy_uuid_type)) { - // deep copy instance - ubluepy_uuid_obj_t * p_old = MP_OBJ_TO_PTR(uuid_obj); - s->type = p_old->type; - s->value[0] = p_old->value[0]; - s->value[1] = p_old->value[1]; - } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - translate("Invalid UUID parameter"))); - } - - return MP_OBJ_FROM_PTR(s); -} - -/// \method binVal() -/// Get binary value of the 16 or 128 bit UUID. Returned as bytearray type. -/// -STATIC mp_obj_t uuid_bin_val(mp_obj_t self_in) { - ubluepy_uuid_obj_t * self = MP_OBJ_TO_PTR(self_in); - - // TODO: Extend the uint16 byte value to 16 byte if 128-bit, - // also encapsulate it in a bytearray. For now, return - // the uint16_t field of the UUID. - return MP_OBJ_NEW_SMALL_INT(self->value[0] | self->value[1] << 8); -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(ubluepy_uuid_bin_val_obj, uuid_bin_val); - -STATIC const mp_rom_map_elem_t ubluepy_uuid_locals_dict_table[] = { -#if 0 - { MP_ROM_QSTR(MP_QSTR_getCommonName), MP_ROM_PTR(&ubluepy_uuid_get_common_name_obj) }, -#endif - // Properties - { MP_ROM_QSTR(MP_QSTR_binVal), MP_ROM_PTR(&ubluepy_uuid_bin_val_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(ubluepy_uuid_locals_dict, ubluepy_uuid_locals_dict_table); - -const mp_obj_type_t ubluepy_uuid_type = { - { &mp_type_type }, - .name = MP_QSTR_UUID, - .print = ubluepy_uuid_print, - .make_new = ubluepy_uuid_make_new, - .locals_dict = (mp_obj_dict_t*)&ubluepy_uuid_locals_dict -}; - -#endif // MICROPY_PY_UBLUEPY diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index b710808b9..8b193fb59 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -129,21 +129,14 @@ #define CIRCUITPY_GAMEPAD_TICKS 0x1f #if BLUETOOTH_SD -#define MICROPY_PY_BLEIO (1) -#define MICROPY_PY_BLE_NUS (0) -#define MICROPY_PY_UBLUEPY (1) -#define MICROPY_PY_UBLUEPY_PERIPHERAL (1) -#define MICROPY_PY_UBLUEPY_CENTRAL (1) -#define BLUETOOTH_WEBBLUETOOTH_REPL (0) -#endif - -#ifndef MICROPY_PY_BLEIO -#define MICROPY_PY_BLEIO (0) + #define MICROPY_PY_BLEIO (1) + #define MICROPY_PY_BLE_NUS (0) +#else + #ifndef MICROPY_PY_BLEIO + #define MICROPY_PY_BLEIO (0) + #endif #endif -#ifndef MICROPY_PY_UBLUEPY -#define MICROPY_PY_UBLUEPY (0) -#endif // type definitions for the specific machine @@ -184,16 +177,8 @@ extern const struct _mp_obj_module_t neopixel_write_module; extern const struct _mp_obj_module_t usb_hid_module; extern const struct _mp_obj_module_t bleio_module; -extern const struct _mp_obj_module_t mp_module_ubluepy; - -#if MICROPY_PY_UBLUEPY -#define UBLUEPY_MODULE { MP_ROM_QSTR(MP_QSTR_ubluepy), MP_ROM_PTR(&mp_module_ubluepy) }, -#else -#define UBLUEPY_MODULE -#endif - #if MICROPY_PY_BLEIO -#define BLEIO_MODULE { MP_ROM_QSTR(MP_QSTR_bleio), MP_ROM_PTR(&bleio_module) }, +#define BLEIO_MODULE { MP_ROM_QSTR(MP_QSTR_bleio), MP_ROM_PTR(&bleio_module) }, #else #define BLEIO_MODULE #endif @@ -221,8 +206,7 @@ extern const struct _mp_obj_module_t mp_module_ubluepy; { MP_OBJ_NEW_QSTR (MP_QSTR_gamepad ), (mp_obj_t)&gamepad_module }, \ { MP_OBJ_NEW_QSTR (MP_QSTR_time ), (mp_obj_t)&time_module }, \ USBHID_MODULE \ - BLEIO_MODULE \ - UBLUEPY_MODULE \ + BLEIO_MODULE // extra built in names to add to the global namespace #define MICROPY_PORT_BUILTINS \ diff --git a/ports/nrf/mphalport.c b/ports/nrf/mphalport.c index 27ed57bf3..e9a8722c6 100644 --- a/ports/nrf/mphalport.c +++ b/ports/nrf/mphalport.c @@ -109,8 +109,7 @@ void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) { #endif // USB -#endif // NUS - +#endif // MICROPY_PY_BLE_NUS /*------------------------------------------------------------------*/ /* delay diff --git a/ports/nrf/supervisor/serial.c b/ports/nrf/supervisor/serial.c index cfbcc4b31..c7744fd79 100644 --- a/ports/nrf/supervisor/serial.c +++ b/ports/nrf/supervisor/serial.c @@ -26,25 +26,41 @@ #include "py/mphal.h" -#if MICROPY_PY_BLE_NUS +#if (MICROPY_PY_BLE_NUS == 1) #include "ble_uart.h" #else #include "nrf_gpio.h" #include "nrfx_uarte.h" #endif -#if !defined(NRF52840_XXAA) +#if (MICROPY_PY_BLE_NUS == 1) + +void serial_init(void) { + ble_uart_init(); +} + +bool serial_connected(void) { + return ble_uart_connected(); +} + +char serial_read(void) { + return (char) ble_uart_rx_chr(); +} + +bool serial_bytes_available(void) { + return ble_uart_stdin_any(); +} + +void serial_write(const char *text) { + ble_uart_stdout_tx_str(text); +} + +#elif !defined(NRF52840_XXAA) uint8_t serial_received_char; nrfx_uarte_t serial_instance = NRFX_UARTE_INSTANCE(0); void serial_init(void) { -#if MICROPY_PY_BLE_NUS - ble_uart_init0(); - while (!ble_uart_enabled()) { - ; - } -#else nrfx_uarte_config_t config = { .pseltxd = MICROPY_HW_UART_TX, .pselrxd = MICROPY_HW_UART_RX, @@ -66,7 +82,6 @@ void serial_init(void) { // enabled receiving nrf_uarte_task_trigger(serial_instance.p_reg, NRF_UARTE_TASK_STARTRX); -#endif } bool serial_connected(void) { @@ -93,7 +108,6 @@ void serial_init(void) { // usb is already initialized in board_init() } - bool serial_connected(void) { return tud_cdc_connected(); } diff --git a/shared-bindings/bleio/Adapter.c b/shared-bindings/bleio/Adapter.c index bfe87071d..d9449d3ab 100644 --- a/shared-bindings/bleio/Adapter.c +++ b/shared-bindings/bleio/Adapter.c @@ -25,6 +25,7 @@ */ #include "py/objproperty.h" +#include "shared-bindings/bleio/Address.h" #include "shared-bindings/bleio/Adapter.h" //| .. currentmodule:: bleio @@ -57,8 +58,6 @@ //| MAC address of the BLE adapter. (read-only) //| -#define BLE_ADDRESS_LEN 17 - STATIC mp_obj_t bleio_adapter_get_enabled(mp_obj_t self) { return mp_obj_new_bool(common_hal_bleio_adapter_get_enabled()); } @@ -81,16 +80,12 @@ const mp_obj_property_t bleio_adapter_enabled_obj = { }; STATIC mp_obj_t bleio_adapter_get_address(mp_obj_t self) { - vstr_t vstr; - vstr_init(&vstr, BLE_ADDRESS_LEN); - - common_hal_bleio_adapter_get_address(&vstr); - - const mp_obj_t mac_str = mp_obj_new_str(vstr.buf, vstr.len); + mp_obj_t obj = bleio_address_type.make_new(&bleio_address_type, 1, 0, mp_const_none); + bleio_address_obj_t *address = MP_OBJ_TO_PTR(obj); - vstr_clear(&vstr); + common_hal_bleio_adapter_get_address(address); - return mac_str; + return obj; } MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_get_address_obj, bleio_adapter_get_address); diff --git a/shared-bindings/bleio/Adapter.h b/shared-bindings/bleio/Adapter.h index 6c5d56948..fe3886e59 100644 --- a/shared-bindings/bleio/Adapter.h +++ b/shared-bindings/bleio/Adapter.h @@ -27,12 +27,12 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H #define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H -#include "py/obj.h" +#include "shared-module/bleio/Address.h" const mp_obj_type_t bleio_adapter_type; extern bool common_hal_bleio_adapter_get_enabled(void); extern void common_hal_bleio_adapter_set_enabled(bool enabled); -extern void common_hal_bleio_adapter_get_address(vstr_t *address); +extern void common_hal_bleio_adapter_get_address(bleio_address_obj_t *address); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADAPTER_H diff --git a/shared-bindings/bleio/Address.c b/shared-bindings/bleio/Address.c new file mode 100644 index 000000000..ec23ff207 --- /dev/null +++ b/shared-bindings/bleio/Address.c @@ -0,0 +1,167 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <string.h> +#include <stdio.h> + +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/Address.h" +#include "shared-module/bleio/Address.h" + +#define ADDRESS_LONG_LEN 17 // XX:XX:XX:XX:XX:XX +#define ADDRESS_SHORT_LEN 12 // XXXXXXXXXXXX + +//| .. currentmodule:: bleio +//| +//| :class:`Address` -- BLE address +//| ========================================================= +//| +//| Encapsulates the address of a BLE device. +//| + +//| .. class:: Address(address) +//| +//| Create a new Address object encapsulating the address value. +//| The value itself can be one of: +//| +//| - a `str` value in the format of 'XXXXXXXXXXXX' or 'XX:XX:XX:XX:XX' +//| - a `bytes` or `bytearray` containing 6 bytes +//| - another Address object +//| +//| :param address: The address to encapsulate +//| + +//| .. attribute:: type +//| +//| The address type. One of: +//| +//| - `bleio.AddressType.PUBLIC` +//| - `bleio.AddressType.RANDOM_STATIC` +//| - `bleio.AddressType.RANDOM_PRIVATE_RESOLVABLE` +//| - `bleio.AddressType.RANDOM_PRIVATE_NON_RESOLVABLE` +//| +STATIC mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 1, 1, true); + bleio_address_obj_t *self = m_new_obj(bleio_address_obj_t); + self->base.type = &bleio_address_type; + self->type = ADDRESS_PUBLIC; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + + enum { ARG_address }; + static const mp_arg_t allowed_args[] = { + { ARG_address, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mp_obj_t address = args[ARG_address].u_obj; + + if (MP_OBJ_IS_STR(address)) { + GET_STR_DATA_LEN(address, str_data, str_len); + const bool is_long = (str_len == ADDRESS_LONG_LEN); + const bool is_short = (str_len == ADDRESS_SHORT_LEN); + + if (is_long || is_short) { + size_t i = str_len - 1; + for (size_t b = 0; b < BLEIO_ADDRESS_BYTES; ++b) { + self->value[b] = unichar_xdigit_value(str_data[i]) | + unichar_xdigit_value(str_data[i - 1]) << 4; + + i -= is_long ? 3 : 2; + } + } else { + mp_raise_ValueError(translate("Wrong address length")); + } + } else if (MP_OBJ_IS_TYPE(address, &mp_type_bytearray) || MP_OBJ_IS_TYPE(address, &mp_type_bytes)) { + mp_buffer_info_t buf_info; + mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ); + if (buf_info.len != BLEIO_ADDRESS_BYTES) { + mp_raise_ValueError(translate("Wrong number of bytes provided")); + } + + for (size_t b = 0; b < BLEIO_ADDRESS_BYTES; ++b) { + self->value[BLEIO_ADDRESS_BYTES - b - 1] = ((uint8_t*)buf_info.buf)[b]; + } + } else if (MP_OBJ_IS_TYPE(address, &bleio_address_type)) { + // deep copy + bleio_address_obj_t *other = MP_OBJ_TO_PTR(address); + self->type = other->type; + memcpy(self->value, other->value, BLEIO_ADDRESS_BYTES); + } + + return MP_OBJ_FROM_PTR(self); +} + +STATIC void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_printf(print, "Address('"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT"')", + self->value[5], self->value[4], self->value[3], + self->value[2], self->value[1], self->value[0]); +} + +STATIC mp_obj_t bleio_address_get_type(mp_obj_t self_in) { + bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (self->type == ADDRESS_PUBLIC) { + return (mp_obj_t)&bleio_addresstype_public_obj; + } else if (self->type == ADDRESS_RANDOM_STATIC) { + return (mp_obj_t)&bleio_addresstype_random_static_obj; + } else if (self->type == ADDRESS_RANDOM_PRIVATE_RESOLVABLE) { + return (mp_obj_t)&bleio_addresstype_random_private_resolvable_obj; + } else if (self->type == ADDRESS_RANDOM_PRIVATE_NON_RESOLVABLE) { + return (mp_obj_t)&bleio_addresstype_random_private_non_resolvable_obj; + } + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_address_get_type_obj, bleio_address_get_type); + +const mp_obj_property_t bleio_address_type_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_address_get_type_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t bleio_address_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_address_type_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_address_locals_dict, bleio_address_locals_dict_table); + +const mp_obj_type_t bleio_address_type = { + { &mp_type_type }, + .name = MP_QSTR_Address, + .print = bleio_address_print, + .make_new = bleio_address_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_address_locals_dict +}; diff --git a/shared-bindings/bleio/Address.h b/shared-bindings/bleio/Address.h new file mode 100644 index 000000000..9c9e20968 --- /dev/null +++ b/shared-bindings/bleio/Address.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H + +#include "py/objtype.h" + +extern const mp_obj_type_t bleio_address_type; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESS_H diff --git a/shared-bindings/bleio/AddressType.c b/shared-bindings/bleio/AddressType.c new file mode 100644 index 000000000..cf2151c94 --- /dev/null +++ b/shared-bindings/bleio/AddressType.c @@ -0,0 +1,99 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/bleio/AddressType.h" + +//| .. currentmodule:: bleio +//| +//| :class:`AddressType` -- defines the type of a BLE address +//| ============================================================= +//| +//| .. class:: bleio.AddressType +//| +//| Enum-like class to define the type of a BLE address, see also `bleio.Address`. +//| +//| .. data:: PUBLIC +//| +//| The address is public +//| +//| .. data:: RANDOM_STATIC +//| +//| The address is random static +//| +//| .. data:: RANDOM_PRIVATE_RESOLVABLE +//| +//| The address is random private resolvable +//| +//| .. data:: RANDOM_PRIVATE_NON_RESOLVABLE +//| +//| The address is private non-resolvable +//| +const mp_obj_type_t bleio_addresstype_type; + +const bleio_addresstype_obj_t bleio_addresstype_public_obj = { + { &bleio_addresstype_type }, +}; + +const bleio_addresstype_obj_t bleio_addresstype_random_static_obj = { + { &bleio_addresstype_type }, +}; + +const bleio_addresstype_obj_t bleio_addresstype_random_private_resolvable_obj = { + { &bleio_addresstype_type }, +}; + +const bleio_addresstype_obj_t bleio_addresstype_random_private_non_resolvable_obj = { + { &bleio_addresstype_type }, +}; + +STATIC const mp_rom_map_elem_t bleio_addresstype_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_PUBLIC), MP_ROM_PTR(&bleio_addresstype_public_obj) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_STATIC), MP_ROM_PTR(&bleio_addresstype_random_static_obj) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_RESOLVABLE), MP_ROM_PTR(&bleio_addresstype_random_private_resolvable_obj) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE), MP_ROM_PTR(&bleio_addresstype_random_private_non_resolvable_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(bleio_addresstype_locals_dict, bleio_addresstype_locals_dict_table); + +STATIC void bleio_addresstype_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + qstr type = MP_QSTR_PUBLIC; + + if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_static_obj)) { + type = MP_QSTR_RANDOM_STATIC; + } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_private_resolvable_obj)) { + type = MP_QSTR_RANDOM_PRIVATE_RESOLVABLE; + } else if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_addresstype_random_private_non_resolvable_obj)) { + type = MP_QSTR_RANDOM_PRIVATE_NON_RESOLVABLE; + } + + mp_printf(print, "%q.%q.%q", MP_QSTR_bleio, MP_QSTR_AddressType, type); +} + +const mp_obj_type_t bleio_addresstype_type = { + { &mp_type_type }, + .name = MP_QSTR_AddressType, + .print = bleio_addresstype_print, + .locals_dict = (mp_obj_t)&bleio_addresstype_locals_dict, +}; diff --git a/shared-bindings/bleio/AddressType.h b/shared-bindings/bleio/AddressType.h new file mode 100644 index 000000000..e69caffab --- /dev/null +++ b/shared-bindings/bleio/AddressType.h @@ -0,0 +1,50 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H + +#include "py/obj.h" + +typedef enum { + ADDRESS_PUBLIC, + ADDRESS_RANDOM_STATIC, + ADDRESS_RANDOM_PRIVATE_RESOLVABLE, + ADDRESS_RANDOM_PRIVATE_NON_RESOLVABLE +} bleio_address_type_t; + +extern const mp_obj_type_t bleio_addresstype_type; + +typedef struct { + mp_obj_base_t base; +} bleio_addresstype_obj_t; + +extern const bleio_addresstype_obj_t bleio_addresstype_public_obj; +extern const bleio_addresstype_obj_t bleio_addresstype_random_static_obj; +extern const bleio_addresstype_obj_t bleio_addresstype_random_private_resolvable_obj; +extern const bleio_addresstype_obj_t bleio_addresstype_random_private_non_resolvable_obj; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADDRESSTYPE_H diff --git a/shared-bindings/bleio/AdvertisementData.c b/shared-bindings/bleio/AdvertisementData.c new file mode 100644 index 000000000..9cfdd74e9 --- /dev/null +++ b/shared-bindings/bleio/AdvertisementData.c @@ -0,0 +1,90 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/obj.h" +#include "shared-module/bleio/AdvertisementData.h" + +//| .. currentmodule:: bleio +//| +//| :class:`AdvertisementData` -- data used during BLE advertising +//| ============================================================== +//| +//| Represents the data to be broadcast during BLE advertising. +//| + +STATIC const mp_rom_map_elem_t bleio_advertisementdata_locals_dict_table[] = { + // Static variables + { MP_ROM_QSTR(MP_QSTR_FLAGS), MP_ROM_INT(AdFlags) }, + { MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_16BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf16BitServiceClassUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_16BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf16BitServiceClassUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_32BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf32BitServiceClassUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_32BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf32BitServiceClassUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_INCOMPLETE_LIST_OF_128BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdIncompleteListOf128BitServiceClassUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_COMPLETE_LIST_OF_128BIT_SERVICE_CLASS_UUIDS), MP_ROM_INT(AdCompleteListOf128BitServiceClassUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_SHORTENED_LOCAL_NAME), MP_ROM_INT(AdShortenedLocalName) }, + { MP_ROM_QSTR(MP_QSTR_COMPLETE_LOCAL_NAME), MP_ROM_INT(AdCompleteLocalName) }, + { MP_ROM_QSTR(MP_QSTR_TX_POWER_LEVEL), MP_ROM_INT(AdTxPowerLevel) }, + { MP_ROM_QSTR(MP_QSTR_CLASS_OF_DEVICE), MP_ROM_INT(AdClassOfDevice) }, + { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_HASH_C), MP_ROM_INT(AdSimplePairingHashC) }, + { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_RANDOMIZER_R), MP_ROM_INT(AdSimplePairingRandomizerR) }, + { MP_ROM_QSTR(MP_QSTR_SECURITY_MANAGER_TK_VALUE), MP_ROM_INT(AdSecurityManagerTKValue) }, + { MP_ROM_QSTR(MP_QSTR_SECURITY_MANAGER_OOB_FLAGS), MP_ROM_INT(AdSecurityManagerOOBFlags) }, + { MP_ROM_QSTR(MP_QSTR_SLAVE_CONNECTION_INTERVAL_RANGE), MP_ROM_INT(AdSlaveConnectionIntervalRange) }, + { MP_ROM_QSTR(MP_QSTR_LIST_OF_16BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf16BitServiceSolicitationUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_LIST_OF_128BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf128BitServiceSolicitationUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_DATA), MP_ROM_INT(AdServiceData) }, + { MP_ROM_QSTR(MP_QSTR_PUBLIC_TARGET_ADDRESS), MP_ROM_INT(AdPublicTargetAddress) }, + { MP_ROM_QSTR(MP_QSTR_RANDOM_TARGET_ADDRESS), MP_ROM_INT(AdRandomTargetAddress) }, + { MP_ROM_QSTR(MP_QSTR_APPEARANCE), MP_ROM_INT(AdAppearance) }, + { MP_ROM_QSTR(MP_QSTR_ADVERTISING_INTERNAL), MP_ROM_INT(AdAdvertisingInterval) }, + { MP_ROM_QSTR(MP_QSTR_LE_BLUETOOTH_DEVICE_ADDRESS), MP_ROM_INT(AdLEBluetoothDeviceAddress) }, + { MP_ROM_QSTR(MP_QSTR_LE_ROLE), MP_ROM_INT(AdLERole) }, + { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_HASH_C256), MP_ROM_INT(AdSimplePairingHashC256) }, + { MP_ROM_QSTR(MP_QSTR_SIMPLE_PAIRING_RANDOMIZER_R256), MP_ROM_INT(AdSimplePairingRandomizerR256) }, + { MP_ROM_QSTR(MP_QSTR_LIST_OF_32BIT_SERVICE_SOLICITATION_UUIDS), MP_ROM_INT(AdListOf32BitServiceSolicitationUUIDs) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_DATA_32BIT_UUID), MP_ROM_INT(AdServiceData32BitUUID) }, + { MP_ROM_QSTR(MP_QSTR_SERVICE_DATA_128BIT_UUID), MP_ROM_INT(AdServiceData128BitUUID) }, + { MP_ROM_QSTR(MP_QSTR_LE_SECURE_CONNECTIONS_CONFIRMATION_VALUE), MP_ROM_INT(AdLESecureConnectionsConfirmationValue) }, + { MP_ROM_QSTR(MP_QSTR_LE_SECURE_CONNECTIONS_RANDOM_VALUE), MP_ROM_INT(AdLESecureConnectionsRandomValue) }, + { MP_ROM_QSTR(MP_QSTR_URI), MP_ROM_INT(AdURI) }, + { MP_ROM_QSTR(MP_QSTR_INDOOR_POSITIONING), MP_ROM_INT(AdIndoorPositioning) }, + { MP_ROM_QSTR(MP_QSTR_TRANSPORT_DISCOVERY_DATA), MP_ROM_INT(AdTransportDiscoveryData) }, + { MP_ROM_QSTR(MP_QSTR_LE_SUPPORTED_FEATURES), MP_ROM_INT(AdLESupportedFeatures) }, + { MP_ROM_QSTR(MP_QSTR_CHANNEL_MAP_UPDATE_INDICATION), MP_ROM_INT(AdChannelMapUpdateIndication) }, + { MP_ROM_QSTR(MP_QSTR_PB_ADV), MP_ROM_INT(AdPBADV) }, + { MP_ROM_QSTR(MP_QSTR_MESH_MESSAGE), MP_ROM_INT(AdMeshMessage) }, + { MP_ROM_QSTR(MP_QSTR_MESH_BEACON), MP_ROM_INT(AdMeshBeacon) }, + { MP_ROM_QSTR(MP_QSTR_3D_INFORMATION_DATA), MP_ROM_INT(Ad3DInformationData) }, + { MP_ROM_QSTR(MP_QSTR_MANUFACTURER_SPECIFIC_DATA), MP_ROM_INT(AdManufacturerSpecificData) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_advertisementdata_locals_dict, bleio_advertisementdata_locals_dict_table); + +const mp_obj_type_t bleio_advertisementdata_type = { + { &mp_type_type }, + .name = MP_QSTR_AdvertisementData, + .locals_dict = (mp_obj_dict_t*)&bleio_advertisementdata_locals_dict +}; diff --git a/shared-bindings/bleio/AdvertisementData.h b/shared-bindings/bleio/AdvertisementData.h new file mode 100644 index 000000000..05b5a2c8d --- /dev/null +++ b/shared-bindings/bleio/AdvertisementData.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADVERTISEMENTDATA_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADVERTISEMENTDATA_H + +#include "py/obj.h" + +extern const mp_obj_type_t bleio_advertisementdata_type; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_ADVERTISEMENTDATA_H diff --git a/shared-bindings/bleio/Characteristic.c b/shared-bindings/bleio/Characteristic.c new file mode 100644 index 000000000..369f3f991 --- /dev/null +++ b/shared-bindings/bleio/Characteristic.c @@ -0,0 +1,332 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/UUID.h" + +//| .. currentmodule:: bleio +//| +//| :class:`Characteristic` -- BLE service characteristic +//| ========================================================= +//| +//| Stores information about a BLE service characteristic and allows to read +//| and write the characteristic's value. +//| + +//| .. class:: Characteristic(uuid) +//| +//| Create a new Characteristic object identified by the specified UUID. +//| +//| :param bleio.UUID uuid: The uuid of the characteristic +//| + +//| .. attribute:: broadcast +//| +//| A `bool` specifying if the characteristic allows broadcasting its value. +//| + +//| .. attribute:: indicate +//| +//| A `bool` specifying if the characteristic allows indicating its value. +//| + +//| .. attribute:: notify +//| +//| A `bool` specifying if the characteristic allows notifying its value. +//| + +//| .. attribute:: read +//| +//| A `bool` specifying if the characteristic allows reading its value. +//| + +//| .. attribute:: uuid +//| +//| The UUID of this characteristic. (read-only) +//| + +//| .. attribute:: value +//| +//| The value of this characteristic. The value can be written to if the `write` property allows it. +//| If the `read` property allows it, the value can be read. If the `notify` property is set, writting +//| to the value will generate a BLE notification. +//| + +//| .. attribute:: write +//| +//| A `bool` specifying if the characteristic allows writting to its value. +//| + +//| .. attribute:: write_no_resp +//| +//| A `bool` specifying if the characteristic allows writting to its value without response. +//| +STATIC void bleio_characteristic_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_printf(print, "Characteristic(uuid: 0x"HEX2_FMT""HEX2_FMT" handle: 0x" HEX2_FMT ")", + self->uuid->value[1], self->uuid->value[0], self->handle); +} + +STATIC mp_obj_t bleio_characteristic_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 1, 1, true); + bleio_characteristic_obj_t *self = m_new_obj(bleio_characteristic_obj_t); + self->base.type = &bleio_characteristic_type; + self->service = NULL; + self->value_data = NULL; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + + enum { ARG_uuid }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_uuid, MP_ARG_REQUIRED| MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mp_obj_t uuid = args[ARG_uuid].u_obj; + + if (uuid == mp_const_none) { + return MP_OBJ_FROM_PTR(self); + } + + if (MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) { + self->uuid = MP_OBJ_TO_PTR(uuid); + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + translate("Invalid UUID parameter"))); + } + + common_hal_bleio_characteristic_construct(self); + + return MP_OBJ_FROM_PTR(self); +} + +STATIC mp_obj_t bleio_characteristic_get_broadcast(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(self->props.broadcast); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_broadcast_obj, bleio_characteristic_get_broadcast); + +STATIC mp_obj_t bleio_characteristic_set_broadcast(mp_obj_t self_in, mp_obj_t broadcast_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->props.broadcast = mp_obj_is_true(broadcast_in); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_broadcast_obj, bleio_characteristic_set_broadcast); + +const mp_obj_property_t bleio_characteristic_broadcast_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_broadcast_obj, + (mp_obj_t)&bleio_characteristic_set_broadcast_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_characteristic_get_indicate(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(self->props.indicate); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_indicate_obj, bleio_characteristic_get_indicate); + +STATIC mp_obj_t bleio_characteristic_set_indicate(mp_obj_t self_in, mp_obj_t indicate_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->props.indicate = mp_obj_is_true(indicate_in); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_indicate_obj, bleio_characteristic_set_indicate); + +const mp_obj_property_t bleio_characteristic_indicate_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_indicate_obj, + (mp_obj_t)&bleio_characteristic_set_indicate_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_characteristic_get_notify(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(self->props.notify); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_notify_obj, bleio_characteristic_get_notify); + +STATIC mp_obj_t bleio_characteristic_set_notify(mp_obj_t self_in, mp_obj_t notify_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->props.notify = mp_obj_is_true(notify_in); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_notify_obj, bleio_characteristic_set_notify); + +const mp_obj_property_t bleio_characteristic_notify_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_notify_obj, + (mp_obj_t)&bleio_characteristic_set_notify_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_characteristic_get_read(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(self->props.read); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_read_obj, bleio_characteristic_get_read); + +STATIC mp_obj_t bleio_characteristic_set_read(mp_obj_t self_in, mp_obj_t read_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->props.read = mp_obj_is_true(read_in); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_read_obj, bleio_characteristic_set_read); + +const mp_obj_property_t bleio_characteristic_read_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_read_obj, + (mp_obj_t)&bleio_characteristic_set_read_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_characteristic_get_write(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(self->props.write); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_obj, bleio_characteristic_get_write); + +STATIC mp_obj_t bleio_characteristic_set_write(mp_obj_t self_in, mp_obj_t write_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->props.write = mp_obj_is_true(write_in); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_write_obj, bleio_characteristic_set_write); + +const mp_obj_property_t bleio_characteristic_write_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_write_obj, + (mp_obj_t)&bleio_characteristic_set_write_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_characteristic_get_write_wo_resp(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(self->props.write_wo_resp); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_write_wo_resp_obj, bleio_characteristic_get_write_wo_resp); + +STATIC mp_obj_t bleio_characteristic_set_write_wo_resp(mp_obj_t self_in, mp_obj_t write_wo_resp_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->props.write_wo_resp = mp_obj_is_true(write_wo_resp_in); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_write_wo_resp_obj, bleio_characteristic_set_write_wo_resp); + +const mp_obj_property_t bleio_characteristic_write_wo_resp_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_write_wo_resp_obj, + (mp_obj_t)&bleio_characteristic_set_write_wo_resp_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_characteristic_get_uuid(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_FROM_PTR(self->uuid); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_uuid_obj, bleio_characteristic_get_uuid); + +const mp_obj_property_t bleio_characteristic_uuid_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_uuid_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_characteristic_get_value(mp_obj_t self_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_bleio_characteristic_read_value(self); + + return self->value_data; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_get_value_obj, bleio_characteristic_get_value); + +STATIC mp_obj_t bleio_characteristic_set_value(mp_obj_t self_in, mp_obj_t value_in) { + bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(value_in, &bufinfo, MP_BUFFER_READ); + + common_hal_bleio_characteristic_write_value(self, &bufinfo); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_characteristic_set_value_obj, bleio_characteristic_set_value); + +const mp_obj_property_t bleio_characteristic_value_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_characteristic_get_value_obj, + (mp_obj_t)&bleio_characteristic_set_value_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC const mp_rom_map_elem_t bleio_characteristic_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_broadcast), MP_ROM_PTR(&bleio_characteristic_broadcast_obj) }, + { MP_ROM_QSTR(MP_QSTR_indicate), MP_ROM_PTR(&bleio_characteristic_indicate_obj) }, + { MP_ROM_QSTR(MP_QSTR_notify), MP_ROM_PTR(&bleio_characteristic_notify_obj) }, + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&bleio_characteristic_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_characteristic_uuid_obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&bleio_characteristic_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&bleio_characteristic_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_write_wo_resp), MP_ROM_PTR(&bleio_characteristic_write_wo_resp_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_characteristic_locals_dict, bleio_characteristic_locals_dict_table); + +const mp_obj_type_t bleio_characteristic_type = { + { &mp_type_type }, + .name = MP_QSTR_Characteristic, + .print = bleio_characteristic_print, + .make_new = bleio_characteristic_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_characteristic_locals_dict +}; diff --git a/shared-bindings/bleio/Characteristic.h b/shared-bindings/bleio/Characteristic.h new file mode 100644 index 000000000..0e99e97cc --- /dev/null +++ b/shared-bindings/bleio/Characteristic.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H + +#include "shared-module/bleio/Characteristic.h" + +extern const mp_obj_type_t bleio_characteristic_type; + +extern void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self); +extern void common_hal_bleio_characteristic_read_value(bleio_characteristic_obj_t *self); +extern void common_hal_bleio_characteristic_write_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_CHARACTERISTIC_H diff --git a/shared-bindings/bleio/Descriptor.c b/shared-bindings/bleio/Descriptor.c new file mode 100644 index 000000000..df32a00e7 --- /dev/null +++ b/shared-bindings/bleio/Descriptor.c @@ -0,0 +1,171 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/Descriptor.h" +#include "shared-bindings/bleio/UUID.h" + +enum { + DescriptorUuidCharacteristicExtendedProperties = 0x2900, + DescriptorUuidCharacteristicUserDescription = 0x2901, + DescriptorUuidClientCharacteristicConfiguration = 0x2902, + DescriptorUuidServerCharacteristicConfiguration = 0x2903, + DescriptorUuidCharacteristicPresentationFormat = 0x2904, + DescriptorUuidCharacteristicAggregateFormat = 0x2905, + DescriptorUuidValidRange = 0x2906, + DescriptorUuidExternalReportReference = 0x2907, + DescriptorUuidReportReference = 0x2908, + DescriptorUuidNumberOfDigitals = 0x2909, + DescriptorUuidValueTriggerSetting = 0x290A, + DescriptorUuidEnvironmentalSensingConfiguration = 0x290B, + DescriptorUuidEnvironmentalSensingMeasurement = 0x290C, + DescriptorUuidEnvironmentalSensingTriggerSetting = 0x290D, + DescriptorUuidTimeTriggerSetting = 0x290E, +}; + +//| .. currentmodule:: bleio +//| +//| :class:`Descriptor` -- BLE descriptor +//| ========================================================= +//| +//| Stores information about a BLE descriptor. +//| Descriptors are encapsulated by BLE characteristics and provide contextual +//| information about the characteristic. +//| + +//| .. class:: Descriptor(uuid) +//| +//| Create a new descriptor object with the UUID uuid. +//| The value can be either of type `bleio.UUID` or any value allowed by the `bleio.UUID` constructor. + +//| .. attribute:: handle +//| +//| The descriptor handle. (read-only) +//| + +//| .. attribute:: uuid +//| +//| The descriptor uuid. (read-only) +//| +STATIC mp_obj_t bleio_descriptor_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 0, 1, true); + bleio_descriptor_obj_t *self = m_new_obj(bleio_descriptor_obj_t); + self->base.type = type; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + + enum { ARG_uuid }; + static const mp_arg_t allowed_args[] = { + { ARG_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mp_obj_t uuid_arg = args[ARG_uuid].u_obj; + + bleio_uuid_obj_t *uuid; + if (MP_OBJ_IS_TYPE(uuid_arg, &bleio_uuid_type)) { + uuid = MP_OBJ_TO_PTR(uuid_arg); + } else { + uuid = MP_OBJ_TO_PTR(bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &uuid_arg)); + } + + common_hal_bleio_descriptor_construct(self, uuid); + + return MP_OBJ_FROM_PTR(self); +} + +STATIC void bleio_descriptor_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_bleio_descriptor_print(self, print); +} + +STATIC mp_obj_t bleio_descriptor_get_handle(mp_obj_t self_in) { + bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_int(common_hal_bleio_descriptor_get_handle(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_handle_obj, bleio_descriptor_get_handle); + +const mp_obj_property_t bleio_descriptor_handle_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_descriptor_get_handle_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC mp_obj_t bleio_descriptor_get_uuid(mp_obj_t self_in) { + bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); + const mp_obj_t uuid = mp_obj_new_int(common_hal_bleio_descriptor_get_uuid(self)); + + return bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &uuid); +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_descriptor_get_uuid_obj, bleio_descriptor_get_uuid); + +const mp_obj_property_t bleio_descriptor_uuid_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_descriptor_get_uuid_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t bleio_descriptor_locals_dict_table[] = { + // Properties + { MP_ROM_QSTR(MP_QSTR_handle), MP_ROM_PTR(&bleio_descriptor_handle_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_descriptor_uuid_obj) }, + + // Static variables + { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_EXTENDED_PROPERTIES), MP_ROM_INT(DescriptorUuidCharacteristicExtendedProperties) }, + { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_USER_DESCRIPTION), MP_ROM_INT(DescriptorUuidCharacteristicUserDescription) }, + { MP_ROM_QSTR(MP_QSTR_CLIENT_CHARACTERISTIC_CONFIGURATION), MP_ROM_INT(DescriptorUuidClientCharacteristicConfiguration) }, + { MP_ROM_QSTR(MP_QSTR_SERVER_CHARACTERISTIC_CONFIGURATION), MP_ROM_INT(DescriptorUuidServerCharacteristicConfiguration) }, + { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_PRESENTATION_FORMAT), MP_ROM_INT(DescriptorUuidCharacteristicPresentationFormat) }, + { MP_ROM_QSTR(MP_QSTR_CHARACTERISTIC_AGGREGATE_FORMAT), MP_ROM_INT(DescriptorUuidCharacteristicAggregateFormat) }, + { MP_ROM_QSTR(MP_QSTR_VALID_RANGE), MP_ROM_INT(DescriptorUuidValidRange) }, + { MP_ROM_QSTR(MP_QSTR_EXTERNAL_REPORT_REFERENCE), MP_ROM_INT(DescriptorUuidExternalReportReference) }, + { MP_ROM_QSTR(MP_QSTR_REPORT_REFERENCE), MP_ROM_INT(DescriptorUuidReportReference) }, + { MP_ROM_QSTR(MP_QSTR_NUMBER_OF_DIGITALS), MP_ROM_INT(DescriptorUuidNumberOfDigitals) }, + { MP_ROM_QSTR(MP_QSTR_VALUE_TRIGGER_SETTING), MP_ROM_INT(DescriptorUuidValueTriggerSetting) }, + { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_CONFIGURATION), MP_ROM_INT(DescriptorUuidEnvironmentalSensingConfiguration) }, + { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_MEASUREMENT ), MP_ROM_INT(DescriptorUuidEnvironmentalSensingMeasurement) }, + { MP_ROM_QSTR(MP_QSTR_ENVIRONMENTAL_SENSING_TRIGGER_SETTING), MP_ROM_INT(DescriptorUuidEnvironmentalSensingTriggerSetting) }, + { MP_ROM_QSTR(MP_QSTR_TIME_TRIGGER_SETTING), MP_ROM_INT(DescriptorUuidTimeTriggerSetting) } +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_descriptor_locals_dict, bleio_descriptor_locals_dict_table); + +const mp_obj_type_t bleio_descriptor_type = { + { &mp_type_type }, + .name = MP_QSTR_Descriptor, + .print = bleio_descriptor_print, + .make_new = bleio_descriptor_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_descriptor_locals_dict +}; diff --git a/shared-bindings/bleio/Descriptor.h b/shared-bindings/bleio/Descriptor.h new file mode 100644 index 000000000..85310d304 --- /dev/null +++ b/shared-bindings/bleio/Descriptor.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H + +#include "common-hal/bleio/Descriptor.h" +#include "common-hal/bleio/UUID.h" + +extern const mp_obj_type_t bleio_descriptor_type; + +extern void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, bleio_uuid_obj_t *uuid); +extern void common_hal_bleio_descriptor_print(bleio_descriptor_obj_t *self, const mp_print_t *print); +extern mp_int_t common_hal_bleio_descriptor_get_handle(bleio_descriptor_obj_t *self); +extern mp_int_t common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DESCRIPTOR_H diff --git a/shared-bindings/bleio/Device.c b/shared-bindings/bleio/Device.c new file mode 100644 index 000000000..94834ef7c --- /dev/null +++ b/shared-bindings/bleio/Device.c @@ -0,0 +1,357 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <string.h> +#include <stdio.h> + +#include "ble_drv.h" +#include "py/objarray.h" +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/Adapter.h" +#include "shared-bindings/bleio/AddressType.h" +#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/Device.h" +#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/bleio/UUID.h" +#include "shared-module/bleio/AdvertisementData.h" +#include "shared-module/bleio/Device.h" +#include "shared-module/bleio/ScanEntry.h" + +//| .. currentmodule:: bleio +//| +//| :class:`Device` -- BLE device +//| ========================================================= +//| +//| Provides access a to BLE device, either in a Peripheral or Central role. +//| When a device is created without any parameter passed to the constructor, +//| it will be set to the Peripheral role. If a address is passed, the device +//| will be a Central. For a Peripheral you can set the `name`, add services +//| via `add_service` and then start and stop advertising via `start_advertising` +//| and `stop_advertising`. For the Central, you can `bleio.Device.connect` and `bleio.Device.disconnect` +//| to the device, once a connection is established, the device's services can +//| be accessed using `services`. +//| +//| Usage:: +//| +//| import bleio +//| +//| # Peripheral +//| periph = bleio.Device() +//| +//| serv = bleio.Service(bleio.UUID(0x180f)) +//| p.add_service(serv) +//| +//| chara = bleio.Characteristic(bleio.UUID(0x2919)) +//| chara.read = True +//| chara.notify = True +//| serv.add_characteristic(chara) +//| +//| periph.start_advertising() +//| +//| # Central +//| scanner = bleio.Scanner() +//| entries = scanner.scan(2500) +//| +//| my_entry = None +//| for entry in entries: +//| if entry.name is not None and entry.name == 'MyDevice': +//| my_entry = entry +//| break +//| +//| central = bleio.Device(my_entry.address) +//| central.connect() +//| + +//| .. class:: Device(address=None, scan_entry=None) +//| +//| Create a new Device object. If the `address` or :py:data:`scan_entry` parameters are not `None`, +//| the role is set to Central, otherwise it's set to Peripheral. +//| +//| :param bleio.Address address: The address of the device to connect to +//| :param bleio.ScanEntry scan_entry: The scan entry returned from `bleio.Scanner` +//| + +//| .. attribute:: name +//| +//| For the Peripheral role, this property can be used to read and write the device's name. +//| For the Central role, this property will equal the name of the remote device, if one was +//| advertised by the device. In the Central role this property is read-only. +//| + +//| .. attribute:: services +//| +//| A `list` of `bleio.Service` that are offered by this device. (read-only) +//| For a Peripheral device, this list will contain services added using `add_service`, +//| for a Central, this list will be empty until a connection is established, at which point +//| it will be filled with the remote device's services. +//| + +//| .. method:: add_service(service) +//| +//| Appends the :py:data:`service` to the list of this devices's services. +//| This method can only be called for Peripheral devices. +//| +//| :param bleio.Service service: the service to append +//| + +//| .. method:: connect() +//| +//| Attempts a connection to the remote device. If the connection is successful, +//| the device's services are available via `services`. +//| This method can only be called for Central devices. +//| + +//| .. method:: disconnect() +//| +//| Disconnects from the remote device. +//| This method can only be called for Central devices. +//| + +//| .. method:: start_advertising(connectable=True) +//| +//| Starts advertising the device. The device's name and +//| services are put into the advertisement packets. +//| If :py:data:`connectable` is `True` then other devices are allowed to conncet to this device. +//| This method can only be called for Peripheral devices. +//| + +//| .. method:: stop_advertising() +//| +//| Disconnects from the remote device. +//| This method can only be called for Peripheral devices. +//| + +// TODO: Add unique MAC address part to name +static const char default_name[] = "CIRCUITPY"; + +STATIC void bleio_device_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_printf(print, "Device(role: %s)", self->is_peripheral ? "Peripheral" : "Central"); +} + +STATIC mp_obj_t bleio_device_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 0, 1, true); + bleio_device_obj_t *self = m_new_obj(bleio_device_obj_t); + self->base.type = &bleio_device_type; + self->service_list = mp_obj_new_list(0, NULL); + self->notif_handler = mp_const_none; + self->conn_handler = mp_const_none; + self->conn_handle = 0xFFFF; + self->is_peripheral = true; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + + enum { ARG_address, ARG_scan_entry }; + static const mp_arg_t allowed_args[] = { + { ARG_address, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_scan_entry, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mp_obj_t address_obj = args[ARG_address].u_obj; + const mp_obj_t scan_entry_obj = args[ARG_scan_entry].u_obj; + + if (address_obj != mp_const_none) { + bleio_address_obj_t *address = MP_OBJ_TO_PTR(address_obj); + + self->is_peripheral = false; + self->address.type = address->type; + memcpy(self->address.value, address->value, BLEIO_ADDRESS_BYTES); + } else if (scan_entry_obj != mp_const_none) { + bleio_scanentry_obj_t *scan_entry = MP_OBJ_TO_PTR(scan_entry_obj); + + self->is_peripheral = false; + self->address.type = scan_entry->address.type; + memcpy(self->address.value, scan_entry->address.value, BLEIO_ADDRESS_BYTES); + } else { + self->name = mp_obj_new_str(default_name, strlen(default_name)); + common_hal_bleio_adapter_get_address(&self->address); + } + + return MP_OBJ_FROM_PTR(self); +} + +STATIC mp_obj_t bleio_device_add_service(mp_obj_t self_in, mp_obj_t service_in) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + bleio_service_obj_t *service = MP_OBJ_TO_PTR(service_in); + + if (!self->is_peripheral) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + translate("Can't add services in Central mode"))); + } + + service->device = self; + + mp_obj_list_append(self->service_list, service); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_device_add_service_obj, bleio_device_add_service); + +STATIC mp_obj_t bleio_device_connect(mp_obj_t self_in) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (self->is_peripheral) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + translate("Can't connect in Peripheral mode"))); + } + + common_hal_bleio_device_connect(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_connect_obj, bleio_device_connect); + +STATIC mp_obj_t bleio_device_disconnect(mp_obj_t self_in) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_bleio_device_disconnect(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_disconnect_obj, bleio_device_disconnect); + +STATIC mp_obj_t bleio_device_get_name(mp_obj_t self_in) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return self->name; +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_get_name_obj, bleio_device_get_name); + +static mp_obj_t bleio_device_set_name(mp_obj_t self_in, mp_obj_t value) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (!self->is_peripheral) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + translate("Can't change the name in Central mode"))); + } + + self->name = value; + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_device_set_name_obj, bleio_device_set_name); + +const mp_obj_property_t bleio_device_name_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_device_get_name_obj, + (mp_obj_t)&bleio_device_set_name_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_device_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + + if (!self->is_peripheral) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + translate("Can't advertise in Central mode"))); + } + + enum { ARG_connectable, ARG_data }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_connectable, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, + { MP_QSTR_data, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t bufinfo = { 0 }; + if (args[ARG_data].u_obj != mp_const_none) { + mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ); + } + + const mp_obj_list_t *service_list = MP_OBJ_TO_PTR(self->service_list); + for (size_t i = 0; i < service_list->len; ++i) { + bleio_service_obj_t *service = service_list->items[i]; + if (service->handle == 0xFFFF) { + common_hal_bleio_device_add_service(self, service); + } + } + + common_hal_bleio_device_start_advertising(self, args[ARG_connectable].u_bool, &bufinfo); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_device_start_advertising_obj, 0, bleio_device_start_advertising); + +STATIC mp_obj_t bleio_device_stop_advertising(mp_obj_t self_in) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + if (!self->is_peripheral) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + translate("Can't advertise in Central mode"))); + } + + common_hal_bleio_device_stop_advertising(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_stop_advertising_obj, bleio_device_stop_advertising); + +STATIC mp_obj_t bleio_device_get_services(mp_obj_t self_in) { + bleio_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return self->service_list; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_device_get_services_obj, bleio_device_get_services); + +const mp_obj_property_t bleio_device_services_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_device_get_services_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC const mp_rom_map_elem_t bleio_device_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_add_service), MP_ROM_PTR(&bleio_device_add_service_obj) }, + { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&bleio_device_connect_obj) }, + { MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&bleio_device_disconnect_obj) }, + { MP_ROM_QSTR(MP_QSTR_start_advertising), MP_ROM_PTR(&bleio_device_start_advertising_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop_advertising), MP_ROM_PTR(&bleio_device_stop_advertising_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_device_name_obj) }, + { MP_ROM_QSTR(MP_QSTR_services), MP_ROM_PTR(&bleio_device_services_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_device_locals_dict, bleio_device_locals_dict_table); + +const mp_obj_type_t bleio_device_type = { + { &mp_type_type }, + .name = MP_QSTR_Device, + .print = bleio_device_print, + .make_new = bleio_device_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_device_locals_dict +}; diff --git a/shared-bindings/bleio/Device.h b/shared-bindings/bleio/Device.h new file mode 100644 index 000000000..aebf1d639 --- /dev/null +++ b/shared-bindings/bleio/Device.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H + +#include "shared-module/bleio/AdvertisementData.h" +#include "shared-module/bleio/Device.h" +#include "shared-module/bleio/Service.h" + +extern const mp_obj_type_t bleio_device_type; + +extern void common_hal_bleio_device_add_service(bleio_device_obj_t *device, bleio_service_obj_t *service); +extern void common_hal_bleio_device_start_advertising(bleio_device_obj_t *device, bool connectable, mp_buffer_info_t *raw_data); +extern void common_hal_bleio_device_stop_advertising(bleio_device_obj_t *device); +extern void common_hal_bleio_device_connect(bleio_device_obj_t *device); +extern void common_hal_bleio_device_disconnect(bleio_device_obj_t *device); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_DEVICE_H diff --git a/shared-bindings/bleio/ScanEntry.c b/shared-bindings/bleio/ScanEntry.c new file mode 100644 index 000000000..e452c7267 --- /dev/null +++ b/shared-bindings/bleio/ScanEntry.c @@ -0,0 +1,308 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <string.h> + +#include "py/objarray.h" +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/objtuple.h" +#include "shared-bindings/bleio/Address.h" +#include "shared-bindings/bleio/ScanEntry.h" +#include "shared-bindings/bleio/UUID.h" +#include "shared-module/bleio/AdvertisementData.h" +#include "shared-module/bleio/ScanEntry.h" + +//| .. currentmodule:: bleio +//| +//| :class:`ScanEntry` -- BLE scan response entry +//| ========================================================= +//| +//| Encapsulates information about a device that was received as a +//| response to a BLE scan request. +//| + +//| .. attribute:: address +//| +//| The address of the device. (read-only) +//| This attribute is of type `bleio.Address`. +//| + +//| .. attribute:: manufacturer_specific_data +//| +//| The manufacturer-specific data present in the advertisement packet. (read-only) +//| + +//| .. attribute:: name +//| +//| The name of the device. (read-only) +//| This attribute might be `None` if the data was missing from the advertisement packet. +//| + +//| .. attribute:: raw_data +//| +//| All the advertisement data present in the packet. (read-only) +//| + +//| .. attribute:: rssi +//| +//| The signal strength of the device at the time of the scan. (read-only) +//| + +//| .. attribute:: service_uuids +//| +//| The address of the device. (read-only) +//| This attribute is a list of `bleio.UUID`. +//| This attribute might be empty or incomplete, depending on the advertisement packet. +//| Currently only 16-bit UUIDS are listed. +//| + +//| .. attribute:: tx_power_level +//| +//| The transmit power level of the device. (read-only) +//| This attribute might be `None` if the data was missing from the advertisement packet. +//| +static uint8_t find_data_item(mp_obj_array_t *data_in, uint8_t type, uint8_t **data_out) { + uint16_t i = 0; + while (i < data_in->len) { + const uint8_t item_len = ((uint8_t*)data_in->items)[i]; + const uint8_t item_type = ((uint8_t*)data_in->items)[i + 1]; + if (item_type != type) { + i += (item_len + 1); + continue; + } + + *data_out = &((uint8_t*)data_in->items)[i + 2]; + + return item_len; + } + + return 0; +} + +STATIC mp_obj_t scanentry_get_name(mp_obj_t self_in); + +STATIC void bleio_scanentry_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_scanentry_obj_t *self = (bleio_scanentry_obj_t *)self_in; + mp_printf(print, "ScanEntry(address: "HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT":"HEX2_FMT"", + self->address.value[5], self->address.value[4], self->address.value[3], + self->address.value[1], self->address.value[1], self->address.value[0]); + + const mp_obj_t name_obj = scanentry_get_name(self_in); + if (name_obj != mp_const_none) { + mp_obj_str_t *str = MP_OBJ_TO_PTR(name_obj); + mp_printf(print, " name: %s", str->data); + } + + mp_print_str(print, ")"); +} + +STATIC mp_obj_t bleio_scanentry_get_address(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_obj_t obj = bleio_address_type.make_new(&bleio_address_type, 1, 0, (mp_obj_t)&mp_const_none_obj); + bleio_address_obj_t *address = MP_OBJ_TO_PTR(obj); + + address->type = self->address.type; + memcpy(address->value, self->address.value, BLEIO_ADDRESS_BYTES); + + return obj; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_address_obj, bleio_scanentry_get_address); + +const mp_obj_property_t bleio_scanentry_address_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bluepy_scanentry_get_address_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t scanentry_get_manufacturer_specific_data(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data); + uint8_t *manuf_data; + + const uint8_t manuf_data_len = find_data_item(data, AdManufacturerSpecificData, &manuf_data); + if (manuf_data_len == 0) { + return mp_const_none; + } + + return mp_obj_new_bytearray_by_ref(manuf_data_len, manuf_data); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_manufacturer_specific_data_obj, scanentry_get_manufacturer_specific_data); + +const mp_obj_property_t bleio_scanentry_manufacturer_specific_data_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&scanentry_get_manufacturer_specific_data_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t scanentry_get_name(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data); + uint8_t *name; + + // Try for Complete but settle for Shortened + uint8_t name_len = find_data_item(data, AdCompleteLocalName, &name); + if (name_len == 0) { + name_len = find_data_item(data, AdShortenedLocalName, &name); + } + + if (name_len == 0) { + return mp_const_none; + } + + return mp_obj_new_str((const char*)name, name_len - 1); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_name_obj, scanentry_get_name); + +const mp_obj_property_t bleio_scanentry_name_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bluepy_scanentry_get_name_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t scanentry_get_raw_data(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_obj_t entries = mp_obj_new_list(0, NULL); + + mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data); + + uint16_t i = 0; + while (i < data->len) { + mp_obj_tuple_t *entry = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); + + const uint8_t item_len = ((uint8_t*)data->items)[i]; + const uint8_t item_type = ((uint8_t*)data->items)[i + 1]; + + entry->items[0] = MP_OBJ_NEW_SMALL_INT(item_type); + entry->items[1] = mp_obj_new_bytearray(item_len - 1, &((uint8_t*)data->items)[i + 2]); + mp_obj_list_append(entries, MP_OBJ_FROM_PTR(entry)); + + i += (item_len + 1); + } + + return entries; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanentry_get_raw_data_obj, scanentry_get_raw_data); + +const mp_obj_property_t bleio_scanentry_raw_data_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_scanentry_get_raw_data_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t scanentry_get_rssi(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_int(self->rssi); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bluepy_scanentry_get_rssi_obj, scanentry_get_rssi); + +const mp_obj_property_t bleio_scanentry_rssi_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bluepy_scanentry_get_rssi_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t scanentry_get_service_uuids(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data); + uint8_t *uuids; + + // Try for Complete but settle for Incomplete + uint8_t uuids_len = find_data_item(data, AdCompleteListOf16BitServiceClassUUIDs, &uuids); + if (uuids_len == 0) { + uuids_len = find_data_item(data, AdIncompleteListOf16BitServiceClassUUIDs, &uuids); + } + + mp_obj_t entries = mp_obj_new_list(0, NULL); + for (size_t i = 0; i < uuids_len / sizeof(uint16_t); ++i) { + const mp_obj_t uuid_int = mp_obj_new_int(uuids[sizeof(uint16_t) * i] | (uuids[sizeof(uint16_t) * i + 1] << 8)); + const mp_obj_t uuid_obj = bleio_uuid_type.make_new(&bleio_uuid_type, 1, 0, &uuid_int); + + mp_obj_list_append(entries, uuid_obj); + } + + // TODO: 32-bit UUIDs + // TODO: 128-bit UUIDs + + return entries; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_service_uuids_obj, scanentry_get_service_uuids); + +const mp_obj_property_t bleio_scanentry_service_uuids_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&scanentry_get_service_uuids_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t scanentry_get_tx_power_level(mp_obj_t self_in) { + bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_array_t *data = MP_OBJ_TO_PTR(self->data); + uint8_t *tx_power; + + const uint8_t tx_power_len = find_data_item(data, AdTxPowerLevel, &tx_power); + if (tx_power_len == 0) { + return mp_const_none; + } + + return mp_obj_new_int((int8_t)(*tx_power)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(scanentry_get_tx_power_level_obj, scanentry_get_tx_power_level); + +const mp_obj_property_t bleio_scanentry_tx_power_level_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&scanentry_get_tx_power_level_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC const mp_rom_map_elem_t bleio_scanentry_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&bleio_scanentry_address_obj) }, + { MP_ROM_QSTR(MP_QSTR_manufacturer_specific_data), MP_ROM_PTR(&bleio_scanentry_manufacturer_specific_data_obj) }, + { MP_ROM_QSTR(MP_QSTR_name), MP_ROM_PTR(&bleio_scanentry_name_obj) }, + { MP_ROM_QSTR(MP_QSTR_raw_data), MP_ROM_PTR(&bleio_scanentry_raw_data_obj) }, + { MP_ROM_QSTR(MP_QSTR_rssi), MP_ROM_PTR(&bleio_scanentry_rssi_obj) }, + { MP_ROM_QSTR(MP_QSTR_service_uuids), MP_ROM_PTR(&bleio_scanentry_service_uuids_obj) }, + { MP_ROM_QSTR(MP_QSTR_tx_power_level), MP_ROM_PTR(&bleio_scanentry_tx_power_level_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_scanentry_locals_dict, bleio_scanentry_locals_dict_table); + +const mp_obj_type_t bleio_scanentry_type = { + { &mp_type_type }, + .name = MP_QSTR_ScanEntry, + .print = bleio_scanentry_print, + .locals_dict = (mp_obj_dict_t*)&bleio_scanentry_locals_dict +}; diff --git a/shared-bindings/bleio/ScanEntry.h b/shared-bindings/bleio/ScanEntry.h new file mode 100644 index 000000000..2b44ba3f4 --- /dev/null +++ b/shared-bindings/bleio/ScanEntry.h @@ -0,0 +1,35 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * Copyright (c) 2017 Glenn Ruben Bakke + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H + +#include "py/obj.h" + +extern const mp_obj_type_t bleio_scanentry_type; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANENTRY_H diff --git a/shared-bindings/bleio/Scanner.c b/shared-bindings/bleio/Scanner.c new file mode 100644 index 000000000..5d19778f6 --- /dev/null +++ b/shared-bindings/bleio/Scanner.c @@ -0,0 +1,162 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/objproperty.h" +#include "shared-bindings/bleio/ScanEntry.h" +#include "shared-bindings/bleio/Scanner.h" + +#define DEFAULT_INTERVAL 100 +#define DEFAULT_WINDOW 100 + +//| .. currentmodule:: bleio +//| +//| :class:`Scanner` -- scan for nearby BLE devices +//| ========================================================= +//| +//| Allows scanning for nearby BLE devices. +//| +//| Usage:: +//| +//| import bleio +//| scanner = bleio.Scanner() +//| entries = scanner.scan(2500) +//| print(entries) +//| + +//| .. class:: Scanner() +//| +//| Create a new Scanner object. +//| + +//| .. attribute:: interval +//| +//| The interval (in ms) between the start of two consecutive scan windows. +//| Allowed values are between 10ms and 10.24 sec. +//| + +//| .. attribute:: window +//| +//| The duration (in ms) in which a single BLE channel is scanned. +//| Allowed values are between 10ms and 10.24 sec. +//| + +//| .. method:: scan(timeout) +//| +//| Performs a BLE scan. +//| +//| :param int timeout: the scan timeout in ms +//| :returns: advertising packets found +//| :rtype: list of :py:class:`bleio.ScanEntry` +//| +STATIC void bleio_scanner_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_printf(print, "Scanner(interval: %d window: %d)", self->interval, self->window); +} + +STATIC mp_obj_t bleio_scanner_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + bleio_scanner_obj_t *self = m_new_obj(bleio_scanner_obj_t); + self->base.type = type; + + self->interval = DEFAULT_INTERVAL; + self->window = DEFAULT_WINDOW; + + return MP_OBJ_FROM_PTR(self); +} + +STATIC mp_obj_t bleio_scanner_get_interval(mp_obj_t self_in) { + bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_int(self->interval); +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanner_get_interval_obj, bleio_scanner_get_interval); + +static mp_obj_t bleio_scanner_set_interval(mp_obj_t self_in, mp_obj_t value) { + bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->interval = mp_obj_get_int(value); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_scanner_set_interval_obj, bleio_scanner_set_interval); + +const mp_obj_property_t bleio_scanner_interval_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_scanner_get_interval_obj, + (mp_obj_t)&bleio_scanner_set_interval_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t scanner_scan(mp_obj_t self_in, mp_obj_t timeout_in) { + bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in); + const mp_int_t timeout = mp_obj_get_int(timeout_in); + + self->adv_reports = mp_obj_new_list(0, NULL); + + common_hal_bleio_scanner_scan(self, timeout); + + return self->adv_reports; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_scanner_scan_obj, scanner_scan); + +STATIC mp_obj_t bleio_scanner_get_window(mp_obj_t self_in) { + bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_int(self->window); +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_scanner_get_window_obj, bleio_scanner_get_window); + +static mp_obj_t bleio_scanner_set_window(mp_obj_t self_in, mp_obj_t value) { + bleio_scanner_obj_t *self = MP_OBJ_TO_PTR(self_in); + + self->window = mp_obj_get_int(value); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_scanner_set_window_obj, bleio_scanner_set_window); + +const mp_obj_property_t bleio_scanner_window_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_scanner_get_window_obj, + (mp_obj_t)&bleio_scanner_set_window_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC const mp_rom_map_elem_t bleio_scanner_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_interval), MP_ROM_PTR(&bleio_scanner_interval_obj) }, + { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&bleio_scanner_scan_obj) }, + { MP_ROM_QSTR(MP_QSTR_window), MP_ROM_PTR(&bleio_scanner_window_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_scanner_locals_dict, bleio_scanner_locals_dict_table); + +const mp_obj_type_t bleio_scanner_type = { + { &mp_type_type }, + .name = MP_QSTR_Scanner, + .print = bleio_scanner_print, + .make_new = bleio_scanner_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_scanner_locals_dict +}; diff --git a/shared-bindings/bleio/Scanner.h b/shared-bindings/bleio/Scanner.h new file mode 100644 index 000000000..9bd071747 --- /dev/null +++ b/shared-bindings/bleio/Scanner.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H + +#include "py/objtype.h" +#include "shared-module/bleio/Scanner.h" + +extern const mp_obj_type_t bleio_scanner_type; + +extern void common_hal_bleio_scanner_scan(bleio_scanner_obj_t *self, mp_int_t timeout); +extern void common_hal_bleio_scanner_stop(bleio_scanner_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SCANNER_H diff --git a/shared-bindings/bleio/Service.c b/shared-bindings/bleio/Service.c new file mode 100644 index 000000000..2d09cbc3c --- /dev/null +++ b/shared-bindings/bleio/Service.c @@ -0,0 +1,170 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/bleio/UUID.h" + +//| .. currentmodule:: bleio +//| +//| :class:`Service` -- BLE service +//| ========================================================= +//| +//| Stores information about a BLE service and its characteristics. +//| + +//| .. class:: Service(uuid, secondary=False) +//| +//| Create a new Service object identified by the specified UUID. +//| To mark the service as secondary, pass `True` as :py:data:`secondary`. +//| +//| :param bleio.UUID uuid: The uuid of the service +//| :param bool secondary: If the service is a secondary one +//| + +//| .. method:: add_characteristic(characteristic) +//| +//| Appends the :py:data:`characteristic` to the list of this service's characteristics. +//| +//| :param bleio.Characteristic characteristic: the characteristic to append +//| + +//| .. attribute:: characteristics +//| +//| A `list` of `bleio.Characteristic` that are offered by this service. (read-only) +//| + +//| .. attribute:: uuid +//| +//| The UUID of this service. (read-only) +//| +STATIC void bleio_service_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_printf(print, "Service(uuid: 0x"HEX2_FMT""HEX2_FMT")", + self->uuid->value[1], self->uuid->value[0]); +} + +STATIC mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 1, 1, true); + bleio_service_obj_t *self = m_new_obj(bleio_service_obj_t); + self->base.type = &bleio_service_type; + self->device = NULL; + self->char_list = mp_obj_new_list(0, NULL); + self->handle = 0xFFFF; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + + enum { ARG_uuid, ARG_secondary }; + static const mp_arg_t allowed_args[] = { + { ARG_uuid, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_secondary, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + self->is_secondary = args[ARG_secondary].u_bool; + + const mp_obj_t uuid = args[ARG_uuid].u_obj; + + if (uuid == mp_const_none) { + return MP_OBJ_FROM_PTR(self); + } + + if (MP_OBJ_IS_TYPE(uuid, &bleio_uuid_type)) { + self->uuid = MP_OBJ_TO_PTR(uuid); + } else { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, + translate("Invalid UUID parameter"))); + } + + return MP_OBJ_FROM_PTR(self); +} + +STATIC mp_obj_t bleio_service_add_characteristic(mp_obj_t self_in, mp_obj_t characteristic_in) { + bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); + bleio_characteristic_obj_t *characteristic = MP_OBJ_TO_PTR(characteristic_in); + + if (self->uuid->type == UUID_TYPE_128BIT) { + characteristic->uuid->type = UUID_TYPE_128BIT; + characteristic->uuid->uuid_vs_idx = self->uuid->uuid_vs_idx; + } + + characteristic->service = self; + + mp_obj_list_append(self->char_list, characteristic); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_service_add_characteristic_obj, bleio_service_add_characteristic); + +STATIC mp_obj_t bleio_service_get_characteristics(mp_obj_t self_in) { + bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return self->char_list; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_characteristics_obj, bleio_service_get_characteristics); + +const mp_obj_property_t bleio_service_characteristics_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_service_get_characteristics_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC mp_obj_t bleio_service_get_uuid(mp_obj_t self_in) { + bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return MP_OBJ_FROM_PTR(self->uuid); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_service_get_uuid_obj, bleio_service_get_uuid); + +const mp_obj_property_t bleio_service_uuid_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_service_get_uuid_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC const mp_rom_map_elem_t bleio_service_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_add_characteristic), MP_ROM_PTR(&bleio_service_add_characteristic_obj) }, + { MP_ROM_QSTR(MP_QSTR_characteristics), MP_ROM_PTR(&bleio_service_characteristics_obj) }, + { MP_ROM_QSTR(MP_QSTR_uuid), MP_ROM_PTR(&bleio_service_uuid_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_service_locals_dict, bleio_service_locals_dict_table); + +const mp_obj_type_t bleio_service_type = { + { &mp_type_type }, + .name = MP_QSTR_Service, + .print = bleio_service_print, + .make_new = bleio_service_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_service_locals_dict +}; diff --git a/shared-bindings/bleio/Service.h b/shared-bindings/bleio/Service.h new file mode 100644 index 000000000..77c751829 --- /dev/null +++ b/shared-bindings/bleio/Service.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H + +#include "shared-module/bleio/Characteristic.h" +#include "shared-module/bleio/Service.h" + +const mp_obj_type_t bleio_service_type; + +extern void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, bleio_characteristic_obj_t *characteristic); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_SERVICE_H diff --git a/shared-bindings/bleio/UUID.c b/shared-bindings/bleio/UUID.c new file mode 100644 index 000000000..7cef9a26f --- /dev/null +++ b/shared-bindings/bleio/UUID.c @@ -0,0 +1,146 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/bleio/UUID.h" + +//| .. currentmodule:: bleio +//| +//| :class:`UUID` -- BLE UUID +//| ========================================================= +//| +//| Encapsulates both 16-bit and 128-bit UUIDs. Can be used for services, +//| characteristics, descriptors and more. +//| + +//| .. class:: UUID(uuid) +//| +//| Create a new UUID object encapsulating the uuid value. +//| The value itself can be one of: +//| +//| - a `int` value in range of 0 to 0xFFFF +//| - a `str` value in the format of '0xXXXX' for 16-bit or 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX' for 128-bit +//| +//| :param int/str uuid: The uuid to encapsulate +//| + +//| .. method:: __len__() +//| +//| Returns the uuid length in bits +//| +//| This allows you to: +//| +//| uuid = bleio.UUID(0x1801) +//| print(len(uuid)) +//| + +//| .. attribute:: type +//| +//| The UUID type. One of: +//| +//| - `bleio.UUIDType.TYPE_16BIT` +//| - `bleio.UUIDType.TYPE_128BIT` +//| +STATIC mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 1, 1, true); + bleio_uuid_obj_t *self = m_new_obj(bleio_uuid_obj_t); + self->base.type = &bleio_uuid_type; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + + enum { ARG_uuid }; + static const mp_arg_t allowed_args[] = { + { ARG_uuid, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mp_obj_t uuid = args[ARG_uuid].u_obj; + + common_hal_bleio_uuid_construct(self, &uuid); + + return MP_OBJ_FROM_PTR(self); +} + +STATIC mp_obj_t bleio_uuid_unary_op(mp_unary_op_t op, mp_obj_t self_in) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + + const bleio_uuid_type_t type = common_hal_bleio_uuid_get_type(self); + const uint8_t len = (type == UUID_TYPE_16BIT) ? 16 : 128; + switch (op) { + case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); + case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len); + default: return MP_OBJ_NULL; // op not supported + } +} + +STATIC void bleio_uuid_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_bleio_uuid_print(self, print); +} + +STATIC mp_obj_t bleio_uuid_get_type(mp_obj_t self_in) { + bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); + + const bleio_uuid_type_t type = common_hal_bleio_uuid_get_type(self); + if (type == UUID_TYPE_16BIT) { + return (mp_obj_t)&bleio_uuidtype_16bit_obj; + } + + if (type == UUID_TYPE_128BIT) { + return (mp_obj_t)&bleio_uuidtype_128bit_obj; + } + + return (mp_obj_t)&mp_const_none_obj; +} +MP_DEFINE_CONST_FUN_OBJ_1(bleio_uuid_get_type_obj, bleio_uuid_get_type); + +const mp_obj_property_t bleio_uuid_type_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&bleio_uuid_get_type_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t bleio_uuid_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_uuid_type_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_uuid_locals_dict, bleio_uuid_locals_dict_table); + +const mp_obj_type_t bleio_uuid_type = { + { &mp_type_type }, + .name = MP_QSTR_UUID, + .print = bleio_uuid_print, + .make_new = bleio_uuid_make_new, + .unary_op = bleio_uuid_unary_op, + .locals_dict = (mp_obj_dict_t*)&bleio_uuid_locals_dict +}; diff --git a/shared-bindings/bleio/UUID.h b/shared-bindings/bleio/UUID.h new file mode 100644 index 000000000..d6fcbac1b --- /dev/null +++ b/shared-bindings/bleio/UUID.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H + +#include "common-hal/bleio/UUID.h" +#include "shared-bindings/bleio/UUIDType.h" + +extern const mp_obj_type_t bleio_uuid_type; + +extern void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, const mp_obj_t *uuid); +extern void common_hal_bleio_uuid_print(bleio_uuid_obj_t *self, const mp_print_t *print); +extern bleio_uuid_type_t common_hal_bleio_uuid_get_type(bleio_uuid_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUID_H diff --git a/shared-bindings/bleio/UUIDType.c b/shared-bindings/bleio/UUIDType.c new file mode 100644 index 000000000..e36d1f06d --- /dev/null +++ b/shared-bindings/bleio/UUIDType.c @@ -0,0 +1,75 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/bleio/UUIDType.h" + +//| .. currentmodule:: bleio +//| +//| :class:`UUIDType` -- defines the type of a BLE UUID +//| ============================================================= +//| +//| .. class:: bleio.UUIDType +//| +//| Enum-like class to define the type of a BLE UUID. +//| +//| .. data:: TYPE_16BIT +//| +//| The UUID is 16-bit +//| +//| .. data:: TYPE_128BIT +//| +//| The UUID is 128-bit +//| +const mp_obj_type_t bleio_uuidtype_type; + +const bleio_uuidtype_obj_t bleio_uuidtype_16bit_obj = { + { &bleio_uuidtype_type }, +}; + +const bleio_uuidtype_obj_t bleio_uuidtype_128bit_obj = { + { &bleio_uuidtype_type }, +}; + +STATIC const mp_rom_map_elem_t bleio_uuidtype_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_TYPE_16BIT), MP_ROM_PTR(&bleio_uuidtype_16bit_obj) }, + { MP_ROM_QSTR(MP_QSTR_TYPE_128BIT), MP_ROM_PTR(&bleio_uuidtype_128bit_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(bleio_uuidtype_locals_dict, bleio_uuidtype_locals_dict_table); + +STATIC void bleio_uuidtype_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + qstr type = MP_QSTR_TYPE_128BIT; + if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&bleio_uuidtype_16bit_obj)) { + type = MP_QSTR_TYPE_16BIT; + } + mp_printf(print, "%q.%q.%q", MP_QSTR_bleio, MP_QSTR_UUIDType, type); +} + +const mp_obj_type_t bleio_uuidtype_type = { + { &mp_type_type }, + .name = MP_QSTR_UUIDType, + .print = bleio_uuidtype_print, + .locals_dict = (mp_obj_t)&bleio_uuidtype_locals_dict, +}; diff --git a/shared-bindings/bleio/UUIDType.h b/shared-bindings/bleio/UUIDType.h new file mode 100644 index 000000000..87bbf9b53 --- /dev/null +++ b/shared-bindings/bleio/UUIDType.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUIDTYPE_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUIDTYPE_H + +#include "py/obj.h" + +typedef enum { + UUID_TYPE_16BIT, + UUID_TYPE_128BIT +} bleio_uuid_type_t; + +extern const mp_obj_type_t bleio_uuidtype_type; + +typedef struct { + mp_obj_base_t base; +} bleio_uuidtype_obj_t; + +extern const bleio_uuidtype_obj_t bleio_uuidtype_16bit_obj; +extern const bleio_uuidtype_obj_t bleio_uuidtype_128bit_obj; + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_UUIDTYPE_H diff --git a/shared-bindings/bleio/__init__.c b/shared-bindings/bleio/__init__.c index 475fb395a..98099422c 100644 --- a/shared-bindings/bleio/__init__.c +++ b/shared-bindings/bleio/__init__.c @@ -25,8 +25,18 @@ * THE SOFTWARE. */ -#include "py/obj.h" #include "shared-bindings/bleio/__init__.h" +#include "shared-bindings/bleio/Address.h" +#include "shared-bindings/bleio/AddressType.h" +#include "shared-bindings/bleio/AdvertisementData.h" +#include "shared-bindings/bleio/Characteristic.h" +#include "shared-bindings/bleio/Descriptor.h" +#include "shared-bindings/bleio/Device.h" +#include "shared-bindings/bleio/ScanEntry.h" +#include "shared-bindings/bleio/Scanner.h" +#include "shared-bindings/bleio/Service.h" +#include "shared-bindings/bleio/UUID.h" +#include "shared-bindings/bleio/UUIDType.h" //| :mod:`bleio` --- Bluetooth Low Energy functionality //| ================================================================ @@ -42,7 +52,18 @@ //| .. toctree:: //| :maxdepth: 3 //| +//| Address +//| AddressType +//| AdvertisementData //| Adapter +//| Characteristic +//| Descriptor +//| Device +//| ScanEntry +//| Scanner +//| Service +//| UUID +//| UUIDType //| //| .. attribute:: adapter //| @@ -52,8 +73,23 @@ //| STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) }, - { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) }, + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_bleio) }, + { MP_ROM_QSTR(MP_QSTR_Address), MP_ROM_PTR(&bleio_address_type) }, + { MP_ROM_QSTR(MP_QSTR_AdvertisementData), MP_ROM_PTR(&bleio_advertisementdata_type) }, + { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) }, + { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, + { MP_ROM_QSTR(MP_QSTR_Device), MP_ROM_PTR(&bleio_device_type) }, + { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) }, + { MP_ROM_QSTR(MP_QSTR_Scanner), MP_ROM_PTR(&bleio_scanner_type) }, + { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) }, + { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_adapter), MP_ROM_PTR(&common_hal_bleio_adapter_obj) }, + + // Enum-like Classes. + { MP_ROM_QSTR(MP_QSTR_AddressType), MP_ROM_PTR(&bleio_addresstype_type) }, + { MP_ROM_QSTR(MP_QSTR_UUIDType), MP_ROM_PTR(&bleio_uuidtype_type) }, }; STATIC MP_DEFINE_CONST_DICT(bleio_module_globals, bleio_module_globals_table); diff --git a/shared-module/bleio/Address.h b/shared-module/bleio/Address.h new file mode 100644 index 000000000..f0998c163 --- /dev/null +++ b/shared-module/bleio/Address.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADDRESS_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADDRESS_H + +#include "shared-bindings/bleio/AddressType.h" + +#define BLEIO_ADDRESS_BYTES 6 + +typedef struct { + mp_obj_base_t base; + bleio_address_type_t type; + uint8_t value[BLEIO_ADDRESS_BYTES]; +} bleio_address_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADDRESS_H diff --git a/shared-module/bleio/AdvertisementData.h b/shared-module/bleio/AdvertisementData.h new file mode 100644 index 000000000..738d53b23 --- /dev/null +++ b/shared-module/bleio/AdvertisementData.h @@ -0,0 +1,85 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H + +#include "py/obj.h" + +// Taken from https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile +enum { + AdFlags = 0x01, + AdIncompleteListOf16BitServiceClassUUIDs = 0x02, + AdCompleteListOf16BitServiceClassUUIDs = 0x03, + AdIncompleteListOf32BitServiceClassUUIDs = 0x04, + AdCompleteListOf32BitServiceClassUUIDs = 0x05, + AdIncompleteListOf128BitServiceClassUUIDs = 0x06, + AdCompleteListOf128BitServiceClassUUIDs = 0x07, + AdShortenedLocalName = 0x08, + AdCompleteLocalName = 0x09, + AdTxPowerLevel = 0x0A, + AdClassOfDevice = 0x0D, + AdSimplePairingHashC = 0x0E, + AdSimplePairingRandomizerR = 0x0F, + AdSecurityManagerTKValue = 0x10, + AdSecurityManagerOOBFlags = 0x11, + AdSlaveConnectionIntervalRange = 0x12, + AdListOf16BitServiceSolicitationUUIDs = 0x14, + AdListOf128BitServiceSolicitationUUIDs = 0x15, + AdServiceData = 0x16, + AdPublicTargetAddress = 0x17, + AdRandomTargetAddress = 0x18, + AdAppearance = 0x19, + AdAdvertisingInterval = 0x1A, + AdLEBluetoothDeviceAddress = 0x1B, + AdLERole = 0x1C, + AdSimplePairingHashC256 = 0x1D, + AdSimplePairingRandomizerR256 = 0x1E, + AdListOf32BitServiceSolicitationUUIDs = 0x1F, + AdServiceData32BitUUID = 0x20, + AdServiceData128BitUUID = 0x21, + AdLESecureConnectionsConfirmationValue = 0x22, + AdLESecureConnectionsRandomValue = 0x23, + AdURI = 0x24, + AdIndoorPositioning = 0x25, + AdTransportDiscoveryData = 0x26, + AdLESupportedFeatures = 0x27, + AdChannelMapUpdateIndication = 0x28, + AdPBADV = 0x29, + AdMeshMessage = 0x2A, + AdMeshBeacon = 0x2B, + Ad3DInformationData = 0x3D, + AdManufacturerSpecificData = 0xFF, +}; + +typedef struct { + mp_obj_t device_name; + mp_obj_t services; + mp_obj_t data; + bool connectable; +} bleio_advertisement_data_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_ADVERTISEMENTDATA_H diff --git a/shared-module/bleio/Characteristic.h b/shared-module/bleio/Characteristic.h new file mode 100644 index 000000000..94c43f81e --- /dev/null +++ b/shared-module/bleio/Characteristic.h @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H + +#include "shared-module/bleio/Service.h" +#include "common-hal/bleio/UUID.h" + +typedef struct { + mp_obj_base_t base; + bleio_service_obj_t *service; + bleio_uuid_obj_t *uuid; + mp_obj_t value_data; + uint16_t handle; + struct { + bool broadcast : 1; + bool read : 1; + bool write_wo_resp : 1; + bool write : 1; + bool notify : 1; + bool indicate : 1; + } props; + uint16_t user_desc_handle; + uint16_t cccd_handle; + uint16_t sccd_handle; +} bleio_characteristic_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_CHARACTERISTIC_H diff --git a/shared-module/bleio/Device.h b/shared-module/bleio/Device.h new file mode 100644 index 000000000..8d9ece5ef --- /dev/null +++ b/shared-module/bleio/Device.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_DEVICE_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_DEVICE_H + +#include <stdbool.h> + +#include "shared-module/bleio/Address.h" + +typedef struct { + mp_obj_base_t base; + bool is_peripheral; + mp_obj_t name; + bleio_address_obj_t address; + volatile uint16_t conn_handle; + mp_obj_t service_list; + mp_obj_t notif_handler; + mp_obj_t conn_handler; +} bleio_device_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_DEVICE_H diff --git a/shared-module/bleio/ScanEntry.h b/shared-module/bleio/ScanEntry.h new file mode 100644 index 000000000..2f01669e2 --- /dev/null +++ b/shared-module/bleio/ScanEntry.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H + +#include "shared-module/bleio/Address.h" + +typedef struct { + mp_obj_base_t base; + bleio_address_obj_t address; + bool connectable; + int8_t rssi; + mp_obj_t data; +} bleio_scanentry_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANENTRY_H diff --git a/shared-module/bleio/Scanner.h b/shared-module/bleio/Scanner.h new file mode 100644 index 000000000..76f5e5866 --- /dev/null +++ b/shared-module/bleio/Scanner.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANNER_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANNER_H + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + mp_obj_t adv_reports; + uint16_t interval; + uint16_t window; +} bleio_scanner_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SCANNER_H diff --git a/shared-module/bleio/Service.h b/shared-module/bleio/Service.h new file mode 100644 index 000000000..ff506d3f3 --- /dev/null +++ b/shared-module/bleio/Service.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Artur Pacholec + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SERVICE_H +#define MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SERVICE_H + +#include "common-hal/bleio/UUID.h" +#include "shared-module/bleio/Device.h" + +typedef struct { + mp_obj_base_t base; + uint16_t handle; + bool is_secondary; + bleio_uuid_obj_t *uuid; + bleio_device_obj_t *device; + mp_obj_t char_list; + uint16_t start_handle; + uint16_t end_handle; +} bleio_service_obj_t; + +#endif // MICROPY_INCLUDED_SHARED_MODULE_BLEIO_SERVICE_H |
