nRF5x: Add ability to get RSSI of current connection (fix #928)

This commit is contained in:
Gordon Williams 2016-10-14 16:11:55 +01:00
parent c47f3e1eb6
commit f8b74ac9c1
8 changed files with 86 additions and 13 deletions

View File

@ -25,6 +25,7 @@
Add Third option to pinMode to allow the pin mode to be set while keeping it 'unforced'
Save and dump now keep track of whether pin mode had been forced or not
readFile (and File.read) now uses Flat Strings to allow more memory efficient reads (fix #932)
nRF5x: Add ability to get RSSI of current connection (fix #928)
1v87 : Add support for compiling with float-abi=hard (even if it doesn't give us real-world benefits)
Add shortcut for quick execution of common call types

View File

@ -616,7 +616,7 @@ void jswrap_nrf_bluetooth_updateServices(JsVar *data) {
"name" : "setScan",
"generate" : "jswrap_nrf_bluetooth_setScan",
"params" : [
["callback","JsVar","The callback to call with information about received, or undefined to stop"]
["callback","JsVar","The callback to call with received advertising packets, or undefined to stop"]
]
}
@ -643,6 +643,44 @@ void jswrap_nrf_bluetooth_setScan(JsVar *callback) {
jsExceptionHere(JSET_ERROR, "Got BLE error code %d", err_code);
}
/*JSON{
"type" : "staticmethod",
"class" : "NRF",
"name" : "setRSSIHandler",
"generate" : "jswrap_nrf_bluetooth_setRSSIHandler",
"params" : [
["callback","JsVar","The callback to call with the RSSI value, or undefined to stop"]
]
}
Start/stop listening for RSSI values on the currently active connection
RSSI is the 'Received Signal Strength Indication' in dBm
```
// Start scanning
NRF.setRSSIHandler(function(rssi) {
console.log(rssi);
});
// prints -85 (or similar)
// Stop Scanning
NRF.setRSSIHandler();
```
*/
void jswrap_nrf_bluetooth_setRSSIHandler(JsVar *callback) {
// set the callback event variable
if (!jsvIsFunction(callback)) callback=0;
jsvObjectSetChild(execInfo.root, BLE_RSSI_EVENT, callback);
// either start or stop scanning
uint32_t err_code = jsble_set_rssi_scan(callback != 0);
if (err_code)
jsExceptionHere(JSET_ERROR, "Got BLE error code %d", err_code);
}
/*JSON{
"type" : "staticmethod",
"class" : "NRF",

View File

@ -22,6 +22,7 @@ void jswrap_nrf_bluetooth_setAdvertising(JsVar *data, JsVar *options);
void jswrap_nrf_bluetooth_setServices(JsVar *data, JsVar *options);
void jswrap_nrf_bluetooth_updateServices(JsVar *data);
void jswrap_nrf_bluetooth_setScan(JsVar *callback);
void jswrap_nrf_bluetooth_setRSSIHandler(JsVar *callback);
void jswrap_nrf_bluetooth_setTxPower(JsVarInt pwr);
void jswrap_nrf_bluetooth_connect(JsVar *mac);

View File

@ -377,6 +377,11 @@ typedef enum {
volatile uint32_t *jshGetPinAddress(Pin pin, JshGetPinAddressFlags flags);
#endif
#if defined(NRF51) || defined(NRF52)
/// Called when we have had an event that means we should execute JS
extern void jshHadEvent();
#endif
/// the temperature from the internal temperature sensor, in degrees C
JsVarFloat jshReadTemperature();

View File

@ -15,6 +15,7 @@
#include "jswrap_bluetooth.h"
#include "jsinteractive.h"
#include "jsdevices.h"
#include "jshardware.h"
#include "nrf5x_utils.h"
#include "bluetooth.h"
#include "bluetooth_utils.h"
@ -101,12 +102,6 @@ volatile BLEStatus bleStatus = 0;
// -----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------
/// Called when we have had an event that means we should execute JS
extern void jshHadEvent();
// -----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------
/** Is BLE connected to any device at all? */
bool jsble_has_connection() {
#if CENTRAL_LINK_COUNT>0
@ -234,6 +229,8 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
case BLE_GAP_EVT_CONNECTED:
if (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_PERIPH) {
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
if (bleStatus & BLE_IS_RSSI_SCANNING); // attempt to restart RSSI scan
sd_ble_gap_rssi_start(m_conn_handle, 0, 0);
bleStatus &= ~BLE_IS_SENDING; // reset state - just in case
bleStatus &= ~BLE_IS_ADVERTISING; // we're not advertising now we're connected
if (!jsiIsConsoleDeviceForced() && (bleStatus & BLE_NUS_INITED))
@ -244,7 +241,6 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
if (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_CENTRAL) {
m_central_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
bleQueueEventAndUnLock(JS_EVENT_PREFIX"connect", 0);
jshHadEvent();
}
#endif
break;
@ -254,10 +250,10 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
if (m_central_conn_handle == p_ble_evt->evt.gap_evt.conn_handle) {
m_central_conn_handle = BLE_CONN_HANDLE_INVALID;
bleQueueEventAndUnLock(JS_EVENT_PREFIX"disconnect", 0);
jshHadEvent();
} else
#endif
{
bleStatus &= ~BLE_IS_RSSI_SCANNING; // scanning will have stopped now we're disconnected
m_conn_handle = BLE_CONN_HANDLE_INVALID;
if (!jsiIsConsoleDeviceForced()) jsiSetConsoleDevice(DEFAULT_CONSOLE_DEVICE, 0);
// restart advertising after disconnection
@ -282,6 +278,13 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
APP_ERROR_CHECK(err_code);
} break; // BLE_GAP_EVT_SEC_PARAMS_REQUEST
case BLE_GAP_EVT_RSSI_CHANGED: {
JsVar *evt = jsvNewFromInteger(p_ble_evt->evt.gap_evt.params.rssi_changed.rssi);
if (evt) jsiQueueObjectCallbacks(execInfo.root, BLE_RSSI_EVENT, &evt, 1);
jsvUnLock(evt);
jshHadEvent();
} break;
case BLE_GATTS_EVT_SYS_ATTR_MISSING:
// No system attributes have been stored.
err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
@ -344,6 +347,7 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
bleStatus &= ~BLE_IS_SENDING_HID;
jsiQueueObjectCallbacks(execInfo.root, BLE_HID_SENT_EVENT, 0, 0);
jsvObjectSetChild(execInfo.root, BLE_HID_SENT_EVENT, 0); // fire only once
jshHadEvent();
}
break;
@ -424,7 +428,6 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
// When done, sent the result to the handler
bleQueueEventAndUnLock(JS_EVENT_PREFIX"servicesDiscover", srvcs);
jsvObjectSetChild(execInfo.hiddenRoot, "bleSvcs", 0);
jshHadEvent();
}
} // else error
break;
@ -445,7 +448,6 @@ static void on_ble_evt(ble_evt_t * p_ble_evt)
}
}
bleQueueEventAndUnLock(JS_EVENT_PREFIX"characteristicsDiscover", chars);
jshHadEvent();
break;
}
case BLE_GATTC_EVT_DESC_DISC_RSP:
@ -902,6 +904,8 @@ void jsble_reset() {
if (bleStatus & BLE_IS_SCANNING) {
jswrap_nrf_bluetooth_setScan(0);
}
jswrap_nrf_bluetooth_setRSSIHandler(0);
#if CENTRAL_LINK_COUNT>0
// if we were connected to something, disconnect
if (jsble_has_central_connection()) {
@ -961,6 +965,22 @@ uint32_t jsble_set_scanning(bool enabled) {
return err_code;
}
uint32_t jsble_set_rssi_scan(bool enabled) {
uint32_t err_code = 0;
if (enabled) {
if (bleStatus & BLE_IS_RSSI_SCANNING) return 0;
bleStatus |= BLE_IS_RSSI_SCANNING;
if (jsble_has_simple_connection())
err_code = sd_ble_gap_rssi_start(m_conn_handle, 0, 0);
} else {
if (!(bleStatus & BLE_IS_RSSI_SCANNING)) return 0;
bleStatus &= ~BLE_IS_RSSI_SCANNING;
if (jsble_has_simple_connection())
err_code = sd_ble_gap_rssi_stop(m_conn_handle);
}
return err_code;
}
/** 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 */

View File

@ -36,6 +36,7 @@ typedef enum {
BLE_NUS_INITED = 32, // Has the Nordic UART service been initialised?
BLE_HID_INITED = 64, // Has the BLE HID service been initialised?
BLE_IS_SENDING_HID = 128, // Are we waiting to send data for USB HID?
BLE_IS_RSSI_SCANNING = 256, // Are we scanning for RSSI values
} BLEStatus;
@ -70,8 +71,12 @@ bool jsble_has_central_connection();
/** Is BLE connected to a server device at all (eg, the simple, 'slave' mode)? */
bool jsble_has_simple_connection();
/// Scanning for advertisign packets
uint32_t jsble_set_scanning(bool enabled);
/// 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 */

View File

@ -16,6 +16,7 @@
#include "jsvariterator.h"
#include "jsinteractive.h"
#include "jsparse.h"
#include "jshardware.h"
#include "app_error.h"
@ -119,12 +120,13 @@ const char *bleVarToUUIDAndUnLock(ble_uuid_t *uuid, JsVar *v) {
return r;
}
/// Queue an event on the 'NRF' object
/// Queue an event on the 'NRF' object. Also calls jshHadEvent()
void bleQueueEventAndUnLock(const char *name, JsVar *data) {
//jsiConsolePrintf("[%s] %j\n", name, data);
JsVar *nrf = jsvObjectGetChild(execInfo.root, "NRF", 0);
if (jsvHasChildren(nrf)) {
jsiQueueObjectCallbacks(nrf, name, &data, data?1:0);
jshHadEvent();
}
jsvUnLock2(nrf, data);
}

View File

@ -18,6 +18,7 @@
#define BLE_SCAN_EVENT JS_EVENT_PREFIX"blescan"
#define BLE_WRITE_EVENT JS_EVENT_PREFIX"blew"
#define BLE_HID_SENT_EVENT JS_EVENT_PREFIX"blehid"
#define BLE_RSSI_EVENT JS_EVENT_PREFIX"blerssi"
/// Names for objects that get defined in the 'hidden root'
#define BLE_NAME_SERVICE_DATA "BLE_SVC_D"
#define BLE_NAME_HID_DATA "BLE_HID_D"
@ -40,7 +41,7 @@ const char *bleVarToUUID(ble_uuid_t *uuid, JsVar *v);
/// Same as bleVarToUUID, but unlocks v
const char *bleVarToUUIDAndUnLock(ble_uuid_t *uuid, JsVar *v);
/// Queue an event on the 'NRF' object
/// Queue an event on the 'NRF' object. Also calls jshHadEvent()
void bleQueueEventAndUnLock(const char *name, JsVar *data);
/// Get the correct event name for a BLE write event to a characteristic (eventName should be max 12 chars long)