/** * This file is part of Espruino, a JavaScript interpreter for Microcontrollers * * Copyright (C) 2013 Gordon Williams * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * ---------------------------------------------------------------------------- * Platform Specific Bluetooth Functionality * ---------------------------------------------------------------------------- */ #ifndef BLUETOOTH_H #define BLUETOOTH_H #include "jsdevices.h" #ifdef NRF5X #if NRF_SD_BLE_API_VERSION>5 #include "nrf_sdh_ble.h" #define BLE_GAP_ADV_MAX_SIZE BLE_GAP_ADV_SET_DATA_SIZE_MAX #else #include "ble.h" #endif #include "ble_advdata.h" #else typedef struct { uint16_t uuid; uint8_t type; //see BLE_UUID_TYPE_... definitions uint8_t uuid128[16]; //BLE knows 16/32/128 bit uuids. Espruino supports 16/128. } PACKED_FLAGS ble_uuid_t; typedef struct { //uint8_t addr_id_peer; uint8_t addr_type; uint8_t addr[6]; } ble_gap_addr_t; #define BLE_GATT_HANDLE_INVALID (0) #define BLE_GAP_ADDR_TYPE_PUBLIC (0) #define BLE_GAP_ADDR_TYPE_RANDOM_STATIC (1) #define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE (2) #define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE (3) #define BLE_GAP_ADV_MAX_SIZE (31) #define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02 #define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03 #define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 #define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07 #define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16 #define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08 #define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09 #define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF #define BLE_UUID_TYPE_UNKNOWN (0) #define BLE_UUID_TYPE_BLE (1) #define BLE_UUID_TYPE_128 2 #define MSEC_TO_UNITS(MS,MEH) MS #define GATT_MTU_SIZE_DEFAULT 23 #define BLE_NUS_MAX_DATA_LEN 20 //GATT_MTU_SIZE_DEFAULT - 3 #endif #if defined(NRF52) || defined(ESP32) // nRF52 gets the ability to connect to other #define CENTRAL_LINK_COUNT 1 /**0 extern volatile uint16_t m_central_conn_handle; /**< Handle for central mode connection */ #endif /** Initialise the BLE stack */ void jsble_init(); /** Completely deinitialise the BLE stack */ void jsble_kill(); /** Add a task to the queue to be executed (to be called mainly from IRQ-land) - with a buffer of data */ void jsble_queue_pending_buf(BLEPending blep, uint16_t data, char *ptr, size_t len); /** Add a task to the queue to be executed (to be called mainly from IRQ-land) - with simple data */ void jsble_queue_pending(BLEPending blep, uint16_t data); /** Execute a task that was added by jsble_queue_pending - this is done outside of IRQ land. Returns number of events handled */ int jsble_exec_pending(IOEvent *event); /** Stop and restart the softdevice so that we can update the services in it - * both user-defined as well as UART/HID */ void jsble_restart_softdevice(); uint32_t jsble_advertising_start(); uint32_t jsble_advertising_update_advdata(char *dPtr, unsigned int dLen); void jsble_advertising_stop(); /** Is BLE connected to any device at all? */ bool jsble_has_connection(); /** Is BLE connected to a central device at all? */ bool jsble_has_central_connection(); /** Is BLE connected to a server device at all (eg, the simple, 'slave' mode)? */ bool jsble_has_peripheral_connection(); /** Call this when something happens on BLE with this as * a peripheral - used with Dynamic Interval Adjustment */ void jsble_peripheral_activity(); /// Checks for error and reports an exception if there was one. Return true on error bool jsble_check_error(uint32_t err_code); /** Set the connection interval of the peripheral connection. Returns an error code */ uint32_t jsble_set_periph_connection_interval(JsVarFloat min, JsVarFloat max); /// Scanning for advertising packets uint32_t jsble_set_scanning(bool enabled, bool activeScan); /// returning RSSI values for current connection uint32_t jsble_set_rssi_scan(bool enabled); /** Actually set the services defined in the 'data' object. Note: we can * only do this *once* - so to change it we must reset the softdevice and * then call this again */ void jsble_set_services(JsVar *data); /// Disconnect from the given connection uint32_t jsble_disconnect(uint16_t conn_handle); /// For BLE HID, send an input report to the receiver. Must be <= HID_KEYS_MAX_LEN void jsble_send_hid_input_report(uint8_t *data, int length); /// Update the current security settings from the info in hiddenRoot.BLE_NAME_SECURITY void jsble_update_security(); /// Return an object showing the security status of the given connection JsVar *jsble_get_security_status(uint16_t conn_handle); // ------------------------------------------------- lower-level utility fns #ifdef NRF5X /// Build advertising data struct to pass into @ref ble_advertising_init. void jsble_setup_advdata(ble_advdata_t *advdata); #endif #ifdef USE_NFC #define TAG_HEADER_LEN 0x0A #define NDEF_HEADER "\x00\x00\x00\x00" /* | UID/BCC | TT = Tag Type */ \ "\x00\x00\x00\x00" /* | UID/BCC | ML = NDEF Message Length */ \ "\x00\x00\xFF\xFF" /* | UID/BCC | LOCK | TF = TNF and Flags */ \ "\xE1\x11\x7C\x0F" /* | Cap. Container | TL = Type Legnth */ \ "\x03\x00\xC1\x01" /* | TT | ML | TF | TL | RT = Record Type */ \ "\x00\x00\x00\x00" /* | Payload Length | IC = URI Identifier Code */ \ "\x55\x00" /* | RT | IC | Payload | 0x00: No prepending */ #define NDEF_FULL_RAW_HEADER_LEN 0x12 /* full header until ML */ #define NDEF_FULL_URL_HEADER_LEN 0x1A /* full header until IC */ #define NDEF_RECORD_HEADER_LEN 0x08 /* record header (TF, TL, PL, RT, IC ) */ #define NDEF_IC_OFFSET 0x19 #define NDEF_IC_LEN 0x01 #define NDEF_MSG_LEN_OFFSET 0x11 #define NDEF_PL_LEN_LSB_OFFSET 0x17 /* we support pl < 256 */ #define NDEF_TERM_TLV 0xfe /* last TLV block / byte */ #define NDEF_TERM_TLV_LEN 0x01 void jsble_nfc_stop(); void jsble_nfc_start(const uint8_t *data, size_t len); void jsble_nfc_get_internal(uint8_t *data, size_t *max_len); void jsble_nfc_send(const uint8_t *data, size_t len); void jsble_nfc_send_rsp(const uint8_t data, size_t len); #endif #if CENTRAL_LINK_COUNT>0 /** Connect to the given peer address. When done call bleCompleteTask. options is an optional object containing optional fields: { minInterval // min connection interval in milliseconds, 7.5 ms to 4 s maxInterval // max connection interval in milliseconds, 7.5 ms to 4 s } See BluetoothRemoteGATTServer.connect docs for more docs */ void jsble_central_connect(ble_gap_addr_t peer_addr, JsVar *options); /// Get primary services. Filter by UUID unless UUID is invalid, in which case return all. When done call bleCompleteTask void jsble_central_getPrimaryServices(ble_uuid_t uuid); /// Get characteristics. Filter by UUID unless UUID is invalid, in which case return all. When done call bleCompleteTask void jsble_central_getCharacteristics(JsVar *service, ble_uuid_t uuid); // Write data to the given characteristic. When done call bleCompleteTask void jsble_central_characteristicWrite(JsVar *characteristic, char *dataPtr, size_t dataLen); // Read data from the given characteristic. When done call bleCompleteTask void jsble_central_characteristicRead(JsVar *characteristic); // Discover descriptors of characteristic void jsble_central_characteristicDescDiscover(JsVar *characteristic); // Set whether to notify on the given characteristic. When done call bleCompleteTask void jsble_central_characteristicNotify(JsVar *characteristic, bool enable); /// Start bonding on the current central connection void jsble_central_startBonding(bool forceRePair); /// Get the security status of the current link JsVar *jsble_central_getSecurityStatus(); /// RSSI monitoring in central mode uint32_t jsble_set_central_rssi_scan(bool enabled); /// Set whether or not the whitelist is enabled void jsble_central_setWhitelist(bool whitelist); /// Send a passkey if one was requested (passkey = 6 bytes long) uint32_t jsble_central_send_passkey(char *passkey); #endif #endif // BLUETOOTH_H