Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of X_NUCLEO_IDB0XA1 by
Revision 219:9981f62cdb1a, committed 2016-05-16
- Comitter:
- Andrea Palmieri
- Date:
- Mon May 16 17:22:03 2016 +0200
- Parent:
- 218:25368f053411
- Child:
- 220:6eb53072d82b
- Commit message:
- Fix issues and add features
- Fix handles management
- Fix UUIDs management
- Implement API to read random address
- Fix clearing/setting of ADV payload
- Fix scanning behaviour
- Fix scanning while a connection is ongoing
- Implement Char Descriptor discovery
- Implement scanning/advertising filter policy (White List partial management)
- Update underlying BlueNRG stack
- Cosmetics
Signed-off-by: Andrea Palmieri <andrea.palmieri@st.com>
Changed in this revision
--- a/source/BlueNRGDevice.cpp Tue Apr 26 14:44:54 2016 +0200
+++ b/source/BlueNRGDevice.cpp Mon May 16 17:22:03 2016 +0200
@@ -159,9 +159,9 @@
@brief Resets the BLE HW, removing any existing services and
characteristics
@param[in] void
- @returns ble_error_t
+ @returns void
*/
-ble_error_t BlueNRGDevice::reset(void)
+void BlueNRGDevice::reset(void)
{
wait_us(500);
@@ -173,10 +173,7 @@
/* Wait for the radio to come back up */
wait_us(500);
-
- isInitialized = false;
- return BLE_ERROR_NONE;
}
/*!
@@ -260,7 +257,34 @@
return BLE_ERROR_INITIALIZATION_INCOMPLETE;
}
- return reset();
+ /* Reset the BlueNRG device first */
+ reset();
+
+ /* Shutdown the BLE API and BlueNRG glue code */
+ ble_error_t error;
+
+ /* GattServer instance */
+ error = BlueNRGGattServer::getInstance().reset();
+ if (error != BLE_ERROR_NONE) {
+ return error;
+ }
+
+ /* GattClient instance */
+ error = BlueNRGGattClient::getInstance().reset();
+ if (error != BLE_ERROR_NONE) {
+ return error;
+ }
+
+ /* Gap instance */
+ error = BlueNRGGap::getInstance().reset();
+ if (error != BLE_ERROR_NONE) {
+ return error;
+ }
+
+ isInitialized = false;
+
+ return BLE_ERROR_NONE;
+
}
/**
--- a/source/BlueNRGDiscoveredCharacteristic.cpp Tue Apr 26 14:44:54 2016 +0200
+++ b/source/BlueNRGDiscoveredCharacteristic.cpp Mon May 16 17:22:03 2016 +0200
@@ -1,60 +1,64 @@
-/* mbed Microcontroller Library
- * Copyright (c) 2006-2013 ARM Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "BlueNRGDiscoveredCharacteristic.h"
-#include "BlueNRGGattClient.h"
-
-void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn,
- Gap::Handle_t connectionHandleIn,
- DiscoveredCharacteristic::Properties_t propsIn,
- GattAttribute::Handle_t declHandleIn,
- GattAttribute::Handle_t valueHandleIn)
-{
- gattc = gattcIn;
- connHandle = connectionHandleIn;
- declHandle = declHandleIn;
- valueHandle = valueHandleIn;
-
- props._broadcast = propsIn.broadcast();
- props._read = propsIn.read();
- props._writeWoResp = propsIn.writeWoResp();
- props._write = propsIn.write();
- props._notify = propsIn.notify();
- props._indicate = propsIn.indicate();
- props._authSignedWrite = propsIn.authSignedWrite();
-}
-
-void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn,
- Gap::Handle_t connectionHandleIn,
- UUID uuidIn,
- DiscoveredCharacteristic::Properties_t propsIn,
- GattAttribute::Handle_t declHandleIn,
- GattAttribute::Handle_t valueHandleIn)
-{
- gattc = gattcIn;
- connHandle = connectionHandleIn;
- uuid = uuidIn;
- declHandle = declHandleIn;
- valueHandle = valueHandleIn;
-
- props._broadcast = propsIn.broadcast();
- props._read = propsIn.read();
- props._writeWoResp = propsIn.writeWoResp();
- props._write = propsIn.write();
- props._notify = propsIn.notify();
- props._indicate = propsIn.indicate();
- props._authSignedWrite = propsIn.authSignedWrite();
-}
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BlueNRGDiscoveredCharacteristic.h"
+#include "BlueNRGGattClient.h"
+
+void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn,
+ Gap::Handle_t connectionHandleIn,
+ DiscoveredCharacteristic::Properties_t propsIn,
+ GattAttribute::Handle_t declHandleIn,
+ GattAttribute::Handle_t valueHandleIn,
+ GattAttribute::Handle_t lastHandleIn)
+{
+ gattc = gattcIn;
+ connHandle = connectionHandleIn;
+ declHandle = declHandleIn;
+ valueHandle = valueHandleIn;
+ lastHandle = lastHandleIn;
+
+ props._broadcast = propsIn.broadcast();
+ props._read = propsIn.read();
+ props._writeWoResp = propsIn.writeWoResp();
+ props._write = propsIn.write();
+ props._notify = propsIn.notify();
+ props._indicate = propsIn.indicate();
+ props._authSignedWrite = propsIn.authSignedWrite();
+}
+
+void BlueNRGDiscoveredCharacteristic::setup(BlueNRGGattClient *gattcIn,
+ Gap::Handle_t connectionHandleIn,
+ UUID uuidIn,
+ DiscoveredCharacteristic::Properties_t propsIn,
+ GattAttribute::Handle_t declHandleIn,
+ GattAttribute::Handle_t valueHandleIn,
+ GattAttribute::Handle_t lastHandleIn)
+{
+ gattc = gattcIn;
+ connHandle = connectionHandleIn;
+ uuid = uuidIn;
+ declHandle = declHandleIn;
+ valueHandle = valueHandleIn;
+ lastHandle = lastHandleIn;
+
+ props._broadcast = propsIn.broadcast();
+ props._read = propsIn.read();
+ props._writeWoResp = propsIn.writeWoResp();
+ props._write = propsIn.write();
+ props._notify = propsIn.notify();
+ props._indicate = propsIn.indicate();
+ props._authSignedWrite = propsIn.authSignedWrite();
+}
--- a/source/BlueNRGGap.cpp Tue Apr 26 14:44:54 2016 +0200
+++ b/source/BlueNRGGap.cpp Mon May 16 17:22:03 2016 +0200
@@ -31,9 +31,7 @@
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
- */
-
-// ANDREA: Changed some types (e.g., tHalUint8 --> uint8_t)
+ */
/** @defgroup BlueNRGGap
* @brief BlueNRG BLE_API GAP Adaptation
@@ -109,8 +107,12 @@
}
/* Make sure we have a payload! */
- if (advData.getPayloadLen() <= 0) {
- return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ if (advData.getPayloadLen() == 0) {
+ PRINTF("advData.getPayloadLen() == 0\n\r");
+ //return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ local_name_length = 0;
+ servUuidlength = 0;
+ AdvLen = 0;
} else {
PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen());
for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) {
@@ -181,8 +183,8 @@
PRINTF("Advertising type: COMPLETE_LOCAL_NAME\n\r");
loadPtr.getUnitAtIndex(index).printDataAsString();
local_name_length = *loadPtr.getUnitAtIndex(index).getLenPtr()-1;
- // The total lenght should include the Data Type Value
- if(local_name_length>LOCAL_NAME_MAX_SIZE-1) {
+ // The total length should include the Data Type Value
+ if(local_name_length>ADV_DATA_MAX_SIZE-1) {
return BLE_ERROR_INVALID_PARAM;
}
local_name[0] = (uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr()); //Data Type Value
@@ -222,9 +224,11 @@
if(buffSize>ADV_DATA_MAX_SIZE-2) {
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
+#ifdef DEBUG
for(int i=0; i<buffSize+1; i++) {
PRINTF("Advertising type: SERVICE_DATA loadPtr.getUnitAtIndex(index).getDataPtr()[%d] = 0x%x\n\r", i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]);
}
+#endif
AdvLen = buffSize+2; // the total ADV DATA LEN should include two more bytes: the buffer size byte; and the Service Data Type Value byte
AdvData[0] = buffSize+1; // the fisrt byte is the data buffer size (type+data)
AdvData[1] = AD_TYPE_SERVICE_DATA;
@@ -266,10 +270,12 @@
if(buffSize>ADV_DATA_MAX_SIZE-2) {
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
+#ifdef DBEUG
for(int i=0; i<buffSize+1; i++) {
PRINTF("Advertising type: MANUFACTURER_SPECIFIC_DATA loadPtr.getUnitAtIndex(index).getDataPtr()[%d] = 0x%x\n\r",
i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]);
}
+#endif
AdvLen = buffSize+2; // the total ADV DATA LEN should include two more bytes: the buffer size byte; and the Manufacturer Specific Data Type Value byte
AdvData[0] = buffSize+1; // the fisrt byte is the data buffer size (type+data)
AdvData[1] = AD_TYPE_MANUFACTURER_SPECIFIC_DATA;
@@ -310,8 +316,7 @@
/*
* ADV timeout callback
- */
-// ANDREA: mbedOS
+ */
#ifdef AST_FOR_MBED_OS
static void advTimeoutCB(void)
{
@@ -402,6 +407,35 @@
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
+ /*
+ * Advertising filter policy setting
+ * FIXME: the Security Manager should be implemented
+ */
+ AdvertisingPolicyMode_t mode = getAdvertisingPolicyMode();
+ if(mode != ADV_POLICY_IGNORE_WHITELIST) {
+ ret = aci_gap_configure_whitelist();
+ if(ret != BLE_STATUS_SUCCESS) {
+ PRINTF("aci_gap_configure_whitelist ret=0x%x\n\r", ret);
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ }
+ }
+
+ uint8_t advFilterPolicy = NO_WHITE_LIST_USE;
+ switch(mode) {
+ case ADV_POLICY_FILTER_SCAN_REQS:
+ advFilterPolicy = WHITE_LIST_FOR_ONLY_SCAN;
+ break;
+ case ADV_POLICY_FILTER_CONN_REQS:
+ advFilterPolicy = WHITE_LIST_FOR_ONLY_CONN;
+ break;
+ case ADV_POLICY_FILTER_ALL_REQS:
+ advFilterPolicy = WHITE_LIST_FOR_ALL;
+ break;
+ default:
+ advFilterPolicy = NO_WHITE_LIST_USE;
+ break;
+ }
+
/* Check the ADV type before setting scan response data */
if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED ||
params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED) {
@@ -424,13 +458,14 @@
}
advtInterval = params.getIntervalInADVUnits();
- printf("advtInterval=%ld advType=%d\n\r", advtInterval, params.getAdvertisingType());
+ PRINTF("advtInterval=%ld advType=%d\n\r", advtInterval, params.getAdvertisingType());
+ /* Setting discoverable mode */
ret = aci_gap_set_discoverable(params.getAdvertisingType(), // AdvType
advtInterval, // AdvIntervMin
advtInterval, // AdvIntervMax
addr_type, // OwnAddrType
- NO_WHITE_LIST_USE, // AdvFilterPolicy
+ advFilterPolicy, // AdvFilterPolicy
local_name_length, // LocalNameLen
(const char*)local_name, // LocalName
servUuidlength, // ServiceUUIDLen
@@ -439,9 +474,9 @@
0); // SlaveConnIntervMax
- printf("!!!setting discoverable (servUuidlength=0x%x)\n\r", servUuidlength);
+ PRINTF("!!!setting discoverable (servUuidlength=0x%x)\n\r", servUuidlength);
if(BLE_STATUS_SUCCESS!=ret) {
- printf("error occurred while setting discoverable (ret=0x%x)\n\r", ret);
+ PRINTF("error occurred while setting discoverable (ret=0x%x)\n\r", ret);
switch (ret) {
case BLE_STATUS_INVALID_PARAMS:
return BLE_ERROR_INVALID_PARAM;
@@ -512,11 +547,10 @@
AdvToFlag = false;
if(params.getTimeout() != 0) {
PRINTF("!!! attaching to!!!\n");
- // ANDREA: mbedOS
#ifdef AST_FOR_MBED_OS
- minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout()));
+ minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000));
#else
- advTimeout.attach(advTimeoutCB, params.getTimeout());
+ advTimeout.attach(advTimeoutCB, params.getTimeout() * 1000);
#endif
}
@@ -542,7 +576,7 @@
ble_error_t BlueNRGGap::stopAdvertising(void)
{
tBleStatus ret;
-
+
if(state.advertising == 1) {
//Set non-discoverable to stop advertising
ret = aci_gap_set_non_discoverable();
@@ -714,7 +748,6 @@
@endcode
*/
/**************************************************************************/
-/*
ble_error_t BlueNRGGap::setAddress(AddressType_t type, const Address_t address)
{
tBleStatus ret;
@@ -730,12 +763,14 @@
ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,
CONFIG_DATA_PUBADDR_LEN,
address);
- printf("setAddress (ret=0x%02X)\n\r", ret);
+ if(ret != BLE_STATUS_SUCCESS) {
+ return BLE_ERROR_UNSPECIFIED;
+ }
}
return BLE_ERROR_NONE;
}
-*/
+
/**************************************************************************/
/*!
@brief Returns boolean if the address of the device has been set
@@ -770,11 +805,18 @@
/**************************************************************************/
ble_error_t BlueNRGGap::getAddress(AddressType_t *typeP, Address_t address)
{
+ uint8_t bdaddr[BDADDR_SIZE];
+ uint8_t data_len_out;
+
if(typeP != NULL) {
*typeP = addr_type;
}
- hci_read_bd_addr(bdaddr);
+ tBleStatus ret = aci_hal_read_config_data(CONFIG_DATA_RANDOM_ADDRESS_IDB05A1, BDADDR_SIZE, &data_len_out, bdaddr);
+ if(ret != BLE_STATUS_SUCCESS) {
+ return BLE_ERROR_UNSPECIFIED;
+ }
+
if(address != NULL) {
memcpy(address, bdaddr, BDADDR_SIZE);
}
@@ -924,7 +966,7 @@
{
tBleStatus ret;
- ret = aci_gatt_read_handle_value(g_device_name_char_handle+CHAR_VALUE_OFFSET,
+ ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE,
*lengthP,
(uint16_t *)lengthP,
deviceName);
@@ -1008,7 +1050,7 @@
tBleStatus ret;
uint16_t lengthP = 2;
- ret = aci_gatt_read_handle_value(g_appearance_char_handle+CHAR_VALUE_OFFSET,
+ ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE,
lengthP,
&lengthP,
(uint8_t*)appearanceP);
@@ -1026,35 +1068,40 @@
return &_scanningParams;
}
-static void radioScanning(void)
-{
- GapScanningParams* scanningParams = BlueNRGGap::getInstance().getScanningParams();
-
- BlueNRGGap::getInstance().startRadioScan(*scanningParams);
-}
-
static void makeConnection(void)
{
BlueNRGGap::getInstance().createConnection();
}
-// ANDREA
void BlueNRGGap::Discovery_CB(Reason_t reason,
uint8_t adv_type,
- uint8_t *addr_type,
+ uint8_t addr_type,
uint8_t *addr,
uint8_t *data_length,
uint8_t *data,
uint8_t *RSSI)
{
- /* avoid compiler warnings about unused variables */
- (void)addr_type;
-
switch (reason) {
case DEVICE_FOUND:
{
GapAdvertisingParams::AdvertisingType_t type;
bool isScanResponse = false;
+
+ /*
+ * Whitelisting (scan policy):
+ * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) &&
+ * Private Random Address
+ * => scan_results = FALSE
+ * FIXME: the Security Manager should be implemented
+ */
+ ScanningPolicyMode_t mode = getScanningPolicyMode();
+ PRINTF("mode=%u addr_type=%u\n\r", mode, addr_type);
+ if(mode == Gap::SCAN_POLICY_FILTER_ALL_ADV ||
+ (addr_type == RESOLVABLE_PRIVATE_ADDR ||
+ addr_type == NON_RESOLVABLE_PRIVATE_ADDR)) {
+ return;
+ }
+
switch(adv_type) {
case ADV_IND:
type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED;
@@ -1084,26 +1131,22 @@
case DISCOVERY_COMPLETE:
// The discovery is complete. If this is due to a stop scanning (i.e., the device
// we are interested in has been found) and a connection has been requested
- // then we start the device connection. Otherwise, we restart the scanning.
+ // then we start the device connection.
PRINTF("DISCOVERY_COMPLETE\n\r");
_scanning = false;
// Since the DISCOVERY_COMPLETE event can be received during the scanning interval,
- // we need to delay the starting of connection or re-scanning procedures
+ // we need to delay the starting of connection
uint16_t delay = 2*(_scanningParams.getInterval());
#ifdef AST_FOR_MBED_OS
if(_connecting) {
minar::Scheduler::postCallback(makeConnection).delay(minar::milliseconds(delay));
- } else {
- minar::Scheduler::postCallback(radioScanning).delay(minar::milliseconds(delay));
}
#else
Clock_Wait(delay);
if(_connecting) {
makeConnection();
- } else {
- radioScanning();
}
#endif /* AST_FOR_MBED_OS */
@@ -1123,13 +1166,30 @@
}
*/
- PRINTF("Scanning...\n\r");
+ /*
+ * Whitelisting (scan policy):
+ * SCAN_POLICY_FILTER_ALL_ADV (ADV packets only from devs in the White List) &&
+ * White List is empty
+ * => scan operation = FAILURE
+ * FIXME: the Security Manager should be implemented
+ */
+ ScanningPolicyMode_t mode = getScanningPolicyMode();
+ uint8_t whiteListSize = whitelistAddresses.size;
+ if(whiteListSize == 0 && mode == Gap::SCAN_POLICY_FILTER_ALL_ADV) {
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ }
+
ret = btleStartRadioScan(scanningParams.getActiveScanning(),
scanningParams.getInterval(),
scanningParams.getWindow(),
addr_type);
-
+ PRINTF("Scanning...\n\r");
+ PRINTF("scanningParams.getInterval()=%u[msec]\r\n",(scanningParams.getInterval()*625)/1000);
+ PRINTF("scanningParams.getWindow()=%u[msec]\r\n",(scanningParams.getWindow()*625)/1000);
+ //PRINTF("_advParams.getInterval()=%u\r\n",_advParams.getInterval());
+ //PRINTF("CONN_P1=%u\r\n",(unsigned)CONN_P1);
+ //PRINTF("CONN_P2=%u\r\n",(unsigned)CONN_P2);
if (BLE_STATUS_SUCCESS == ret){
PRINTF("Observation Procedure Started\n");
_scanning = true;
@@ -1139,10 +1199,10 @@
// Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED
switch (ret) {
case BLE_STATUS_INVALID_CID:
- printf("Observation Procedure not implemented!!!\n\r");
+ PRINTF("Observation Procedure not implemented!!!\n\r");
return BLE_ERROR_NOT_IMPLEMENTED;
default:
- printf("Observation Procedure failed (0x%02X)\n\r", ret);
+ PRINTF("Observation Procedure failed (0x%02X)\n\r", ret);
return BLE_ERROR_UNSPECIFIED;
}
@@ -1150,11 +1210,12 @@
ble_error_t BlueNRGGap::stopScan() {
tBleStatus ret = BLE_STATUS_SUCCESS;
-
+
+ PRINTF("stopScan\n\r");
ret = aci_gap_terminate_gap_procedure(GAP_OBSERVATION_PROC);
if (ret != BLE_STATUS_SUCCESS) {
- printf("GAP Terminate Gap Procedure failed\n");
+ PRINTF("GAP Terminate Gap Procedure failed\n");
return BLE_ERROR_UNSPECIFIED;
} else {
PRINTF("Discovery Procedure Terminated\n");
@@ -1199,34 +1260,75 @@
/**************************************************************************/
void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
static const int8_t permittedTxValues[] = {
- -18, -15, -14, -12, -11, -9, -8, -6, -5 -2, 0, 2, 4, 5, 8
+ -18, -15, -14, -12, -11, -9, -8, -6, -5, -2, 0, 2, 4, 5, 8
};
*valueArrayPP = permittedTxValues;
*countP = sizeof(permittedTxValues) / sizeof(int8_t);
}
+/**************************************************************************/
+/*!
+ @brief Set connection parameters according to the current state (ADV and/or SCAN)
+ Parameters value is set taking into account guidelines of the BlueNRG
+ time slots allocation
+*/
+/**************************************************************************/
+void BlueNRGGap::setConnectionParameters(void)
+{
+ if (state.advertising == 1) {
+
+ if (_scanningParams.getInterval() < _advParams.getInterval()) {
+ scanInterval = _advParams.getIntervalInADVUnits();
+ scanWindow = _advParams.getIntervalInADVUnits();
+ } else {
+ scanInterval = _scanningParams.getInterval();
+ scanWindow = _scanningParams.getWindow();
+ }
+ conn_min_interval = (_advParams.getInterval()+GUARD_INT)/1.25;
+ conn_max_interval = (_advParams.getInterval()+GUARD_INT)/1.25;
+
+ } else {
+
+ scanInterval = _scanningParams.getInterval();
+ scanWindow = _scanningParams.getWindow();
+ conn_min_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25;
+ conn_max_interval = SCAN_DURATION_UNITS_TO_MSEC(scanInterval)/1.25;
+
+ }
+ PRINTF("scanInterval=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanInterval));
+ PRINTF("scanWindow()=%u[msec]\r\n",SCAN_DURATION_UNITS_TO_MSEC(scanWindow));
+ PRINTF("conn_min_interval[msec]=%u\r\n",(unsigned)(conn_min_interval*1.25));
+ PRINTF("conn_max_interval[msec]=%u\r\n",(unsigned)(conn_max_interval*1.25));
+
+}
+
ble_error_t BlueNRGGap::createConnection ()
{
tBleStatus ret;
- GapScanningParams* scanningParams = getScanningParams();
-
+
+ /*
+ Before creating connection, set parameters according
+ to previous or current procedure (ADV and/or SCAN)
+ */
+ setConnectionParameters();
+
/*
Scan_Interval, Scan_Window, Peer_Address_Type, Peer_Address, Own_Address_Type, Conn_Interval_Min,
Conn_Interval_Max, Conn_Latency, Supervision_Timeout, Conn_Len_Min, Conn_Len_Max
*/
- ret = aci_gap_create_connection(scanningParams->getInterval(),
- scanningParams->getWindow(),
- PUBLIC_ADDR,
+ ret = aci_gap_create_connection(scanInterval,
+ scanWindow,
+ _peerAddrType,
(unsigned char*)_peerAddr,
- PUBLIC_ADDR,
- CONN_P1, CONN_P2, 0,
+ addr_type,
+ conn_min_interval, conn_max_interval, 0,
SUPERV_TIMEOUT, CONN_L1 , CONN_L1);
_connecting = false;
if (ret != BLE_STATUS_SUCCESS) {
- printf("Error while starting connection (ret=0x%02X).\n\r", ret);
+ PRINTF("Error while starting connection (ret=0x%02X).\n\r", ret);
return BLE_ERROR_UNSPECIFIED;
} else {
PRINTF("Connection started.\n");
@@ -1240,7 +1342,6 @@
const GapScanningParams *scanParams)
{
/* avoid compiler warnings about unused variables */
- (void)peerAddrType;
(void)connectionParams;
(void)scanParams;
@@ -1248,6 +1349,7 @@
for(int i=0; i<BDADDR_SIZE; i++) {
_peerAddr[i] = peerAddr[i];
}
+ _peerAddrType = peerAddrType;
_connecting = true;
@@ -1260,3 +1362,103 @@
return BLE_ERROR_NONE;
}
+
+/**************************************************************************/
+/*!
+ @brief Set the advertising policy filter mode that will be used in
+ the next call to startAdvertising().
+
+ @returns \ref ble_errror_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly.
+
+ BLE_ERROR_NOT_IMPLEMENTED
+ This feature is currently note implemented.
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setAdvertisingPolicyMode(Gap::AdvertisingPolicyMode_t mode)
+{
+ advertisingPolicyMode = mode;
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Set the scanning policy filter mode that will be used in
+ the next call to startAdvertising().
+
+ @returns \ref ble_errror_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly.
+
+ BLE_ERROR_NOT_IMPLEMENTED
+ This feature is currently note implemented.
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::setScanningPolicyMode(Gap::ScanningPolicyMode_t mode)
+{
+ scanningPolicyMode = mode;
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Get the current advertising policy filter mode.
+
+ @returns The advertising policy filter mode.
+*/
+/**************************************************************************/
+Gap::AdvertisingPolicyMode_t BlueNRGGap::getAdvertisingPolicyMode(void) const
+{
+ return advertisingPolicyMode;
+}
+
+/**************************************************************************/
+/*!
+ @brief Get the current scanning policy filter mode.
+
+ @returns The scanning policy filter mode.
+
+*/
+/**************************************************************************/
+Gap::ScanningPolicyMode_t BlueNRGGap::getScanningPolicyMode(void) const
+{
+ return scanningPolicyMode;
+}
+
+/**************************************************************************/
+/*!
+ @brief Clear BlueNRGGap's state.
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGap::reset(void)
+{
+ /* Clear all state that is from the parent, including private members */
+ if (Gap::reset() != BLE_ERROR_NONE) {
+ return BLE_ERROR_INVALID_STATE;
+ }
+
+ /* Clear derived class members */
+ m_connectionHandle = BLE_CONN_HANDLE_INVALID;
+
+ memset(deviceAppearance, 0, sizeof(deviceAppearance));
+ memset(local_name, 0, LOCAL_NAME_MAX_SIZE);
+ memset(local_name, 0, UUID_BUFFER_SIZE);
+ memset(AdvData, 0, ADV_DATA_MAX_SIZE);
+
+ /* Set the whitelist policy filter modes to IGNORE_WHITELIST */
+ advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST;
+ scanningPolicyMode = Gap::SCAN_POLICY_IGNORE_WHITELIST;
+
+ return BLE_ERROR_NONE;
+}
+
--- a/source/BlueNRGGattClient.cpp Tue Apr 26 14:44:54 2016 +0200
+++ b/source/BlueNRGGattClient.cpp Mon May 16 17:22:03 2016 +0200
@@ -1,630 +1,815 @@
-/* mbed Microcontroller Library
-* Copyright (c) 2006-2013 ARM Limited
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/**
- ******************************************************************************
- * @file BlueNRGGattServer.cpp
- * @author STMicroelectronics
- * @brief Implementation of BlueNRG BLE_API GattServer Class
- ******************************************************************************
- * @copy
- *
- * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
- * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
- * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
- * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
- * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
- * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
- *
- * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
- */
-
-/** @defgroup BlueNRGGATTClient
- * @brief BlueNRG BLE_API GattClient Adaptation
- * @{
- */
-
-#include "BlueNRGGattClient.h"
-#include "mbed-drivers/mbed.h"
-#include "BlueNRGGap.h"
-#include "Utils.h"
-#include "debug.h"
-
-static uint8_t props_mask[] = {
- 0x01,
- 0x02,
- 0x04,
- 0x08,
- 0x10,
- 0x20,
- 0x40,
- 0x80
- };
-
-void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code)
-{
- if(error_code != BLE_STATUS_SUCCESS) {
- return;
- }
-
- // Service Discovery complete
- if(_currentState != GATT_IDLE &&
- _currentState != GATT_DISCOVERY_TERMINATED &&
- _currentState != GATT_WRITE_CHAR &&
- _currentState != GATT_READ_CHAR) {
-
- findServiceChars(connectionHandle);
- }
-
- if(_currentState == GATT_WRITE_CHAR) {
- BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
- _currentState = GATT_IDLE;
- }
-}
-
-void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle,
- uint8_t event_data_length,
- uint8_t attribute_data_length,
- uint8_t *attribute_data_list)
-{
- GattAttribute::Handle_t startHandle, endHandle;
- UUID uuid;
- uint8_t i, offset, numAttr;
- /* avoid compiler warnings about unused variables */
- (void)connectionHandle;
-
- numAttr = (event_data_length - 1) / attribute_data_length;
-
- offset = 0;
- for (i=0; i<numAttr; i++) {
- startHandle = attribute_data_list[offset];
- endHandle = attribute_data_list[offset+2];
-
- // UUID Type
- if (attribute_data_length == 6) {
-
- PRINTF("UUID_TYPE_16\n\r");
- uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4];
- PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle);
-
- } else {
-
- PRINTF("UUID_TYPE_128\n\r");
- uuid.setupLong(attribute_data_list+offset+4);
-
- PRINTF("S UUID-");
-#ifdef DEBUG
- const uint8_t *longUUIDBytes = uuid.getBaseUUID();
- for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) {
- PRINTF("%02x", longUUIDBytes[j]);
- }
-#endif
- PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle);
-
- }
-
- PRINTF("Setup serviceIndex = %d\n\r", _numServices);
- discoveredService[_numServices].setup(uuid, startHandle, endHandle);
-
- if(serviceDiscoveryCallback) {
- if(_matchingServiceUUID == BLE_UUID_UNKNOWN || _matchingServiceUUID == discoveredService[_numServices].getUUID()) {
- serviceDiscoveryCallback(&discoveredService[_numServices]);
- }
- }
- _numServices++;
-
- offset += attribute_data_length;
- }
-
- PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr);
-
-}
-
-void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle,
- uint8_t event_data_length,
- uint8_t *handles_info_list)
-{
- GattAttribute::Handle_t startHandle, endHandle;
- UUID uuid;
- uint8_t i, offset, numHandlePairs;
- /* avoid compiler warnings about unused variables */
- (void)connectionHandle;
-
- numHandlePairs = (event_data_length - 1) / 2;
-
- offset = 0;
- for (i=0; i<numHandlePairs; i++) {
- startHandle = handles_info_list[offset];
- endHandle = handles_info_list[offset+2];
-
- PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle);
-
- discoveredService[i].setup(_matchingServiceUUID, startHandle, endHandle);
-
- if(serviceDiscoveryCallback) {
- serviceDiscoveryCallback(&discoveredService[_numServices]);
- }
- _numServices++;
-
- offset += 4;
- }
-}
-
-void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle,
- uint8_t event_data_length,
- uint8_t handle_value_pair_length,
- uint8_t *handle_value_pair)
-{
- // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16)
-
- GattAttribute::Handle_t declHandle, valueHandle;
- UUID uuid;
- uint8_t i, numChar, offset;
-
- numChar = (event_data_length - 1) / handle_value_pair_length;
-
- offset = 0;
- for (i=0; i<numChar; i++) {
- // UUID Type
- if (handle_value_pair_length == 7) {
- PRINTF("Char UUID_TYPE_16\n\r");
- uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5];
- PRINTF("C UUID-%X\r\n", uuid.getShortUUID());
- } else {
- PRINTF("Char UUID_TYPE_128\n\r");
- uuid.setupLong(handle_value_pair+offset+5);
- PRINTF("C UUID-");
-#ifdef DEBUG
- const uint8_t *longUUIDBytes = uuid.getBaseUUID();
- for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
- PRINTF("%02X", longUUIDBytes[i]);
- }
- PRINTF("\r\n");
-#endif
- }
-
- // Properties
- DiscoveredCharacteristic::Properties_t p;
-
- p._broadcast = (props_mask[0] & handle_value_pair[offset+2]);
- p._read = (props_mask[1] & handle_value_pair[offset+2])>>1;
- p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2;
- p._write = (props_mask[3] & handle_value_pair[offset+2])>>3;
- p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4;
- p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5;
- p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6;
- PRINTF("p._broadcast=%d\n\r", p._broadcast);
- PRINTF("p._read=%d\n\r", p._read);
- PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp);
- PRINTF("p._write=%d\n\r", p._write);
- PRINTF("p._notify=%d\n\r", p._notify);
- PRINTF("p._indicate=%d\n\r", p._indicate);
- PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite);
-
- /*
- uint8_t props = handle_value_pair[offset+2];
- PRINTF("CHAR PROPS: %d\n\r", props);
- */
-
- // Handles
- declHandle = handle_value_pair[offset];
- valueHandle = handle_value_pair[offset+3];
-
- discoveredChar[_numChars].setup(this,
- connectionHandle,
- uuid,
- p,
- declHandle,
- valueHandle);
-
- if(characteristicDiscoveryCallback) {
- characteristicDiscoveryCallback(&discoveredChar[_numChars]);
- }
- _numChars++;
-
- offset += handle_value_pair_length;
- }
-}
-
-void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle,
- uint8_t event_data_length,
- uint16_t attr_handle,
- uint8_t *attr_value)
-{
- // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16)
- GattAttribute::Handle_t declHandle, valueHandle;
- UUID uuid;
-
- PRINTF("serviceCharByUUIDCB\n\r");
-
- // UUID Type
- if (event_data_length == 7) {
- PRINTF("Char UUID_TYPE_16\n\r");
- uuid = attr_value[4]<<8|attr_value[3];
- PRINTF("C UUID-%X\r\n", uuid.getShortUUID());
- } else {
- PRINTF("Char UUID_TYPE_128\n\r");
- uuid.setupLong(attr_value+3);
- PRINTF("C UUID-");
-#ifdef DEBUG
- const uint8_t *longUUIDBytes = uuid.getBaseUUID();
- for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
- PRINTF("%02X", longUUIDBytes[i]);
- }
- PRINTF("\r\n");
-#endif
- }
-
- // Properties
- DiscoveredCharacteristic::Properties_t p;
-
- p._broadcast = (props_mask[0] & attr_value[0]);
- p._read = (props_mask[1] & attr_value[0])>>1;
- p._writeWoResp = (props_mask[2] & attr_value[0])>>2;
- p._write = (props_mask[3] & attr_value[0])>>3;
- p._notify = (props_mask[4] & attr_value[0])>>4;
- p._indicate = (props_mask[5] & attr_value[0])>>5;
- p._authSignedWrite = (props_mask[6] & attr_value[0])>>6;
- PRINTF("p._broadcast=%d\n\r", p._broadcast);
- PRINTF("p._read=%d\n\r", p._read);
- PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp);
- PRINTF("p._write=%d\n\r", p._write);
- PRINTF("p._notify=%d\n\r", p._notify);
- PRINTF("p._indicate=%d\n\r", p._indicate);
- PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite);
-
- /*
- uint8_t props = attr_value[0];
- PRINTF("CHAR PROPS: %d\n\r", props);
- */
-
- // Handles
- declHandle = attr_handle;
- valueHandle = attr_value[1];
-
- discoveredChar[_numChars].setup(this,
- connectionHandle,
- uuid,
- p,
- declHandle,
- valueHandle);
-
- if(characteristicDiscoveryCallback) {
- characteristicDiscoveryCallback(&discoveredChar[_numChars]);
- }
- _numChars++;
-}
-
-ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle)
-{
- PRINTF("findServiceChars\n\r");
-
- tBleStatus ret;
- uint8_t uuid_type = UUID_TYPE_16;
- uint8_t short_uuid[2];
- uint8_t *uuid = NULL;
-
- DiscoveredService *service;
-
- // We finished chars discovery for all services
- if(_servIndex >= _numServices) {
- PRINTF("!!!We finished chars discovery for all services!!!\n\r");
- _currentState = GATT_CHARS_DISCOVERY_COMPLETE;
-
- terminateServiceDiscovery();
-
- return BLE_ERROR_NONE;
- }
-
- service = &discoveredService[_servIndex];
- /*
- if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
- PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID());
- } else {
- PRINTF("S UUID-");
- const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
- for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
- PRINTF("%02X", longUUIDBytes[i]);
- }
- PRINTF("\r\n");
- }
- */
-
- PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex);
- //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle());
-
- if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) {
- PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r");
- ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle());
- } else {
-
- uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong();
-
- if(type == UUID::UUID_TYPE_SHORT) {
- STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID());
-
- uuid_type = UUID_TYPE_16;
- uuid = short_uuid;
-
- PRINTF("findServiceChars C UUID-");
- for(unsigned i = 0; i < 2; i++) {
- PRINTF("%02X", short_uuid[i]);
- }
- PRINTF("\n\r");
-
- } else if(type==UUID::UUID_TYPE_LONG) {
-
- uuid_type = UUID_TYPE_128;
- uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID();
-
- PRINTF("(findServiceChars) C UUID-");
- for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
- PRINTF("%02X", uuid[i]);
- }
- PRINTF("\r\n");
- }
-
- ret = aci_gatt_disc_charac_by_uuid(connectionHandle,
- service->getStartHandle(),
- service->getEndHandle(),
- uuid_type,
- uuid);
- }
-
- if(ret == BLE_STATUS_SUCCESS) {
- _servIndex++;
- }
-
- PRINTF("findServiceChars ret=%d\n\r", ret);
-
- return BLE_ERROR_NONE;
-}
-
-ble_error_t BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle,
- ServiceDiscovery::ServiceCallback_t sc,
- ServiceDiscovery::CharacteristicCallback_t cc,
- const UUID &matchingServiceUUID,
- const UUID &matchingCharacteristicUUIDIn)
-{
- PRINTF("launchServiceDiscovery\n\r");
-
- tBleStatus ret;
- uint8_t uuid_type = UUID_TYPE_16;
- uint8_t short_uuid[2];
- uint8_t *uuid = NULL;
- unsigned j;
-
- _connectionHandle = connectionHandle;
- serviceDiscoveryCallback = sc;
- characteristicDiscoveryCallback = cc;
- _matchingServiceUUID = matchingServiceUUID;
- _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn;
-
- //reset services
- _numServices = 0;
- _numChars = 0;
- _servIndex = 0;
- for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) {
- discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE);
- }
-
- if(matchingServiceUUID == BLE_UUID_UNKNOWN) {
-
- // Wildcard: search for all services
- ret = aci_gatt_disc_all_prim_services((uint16_t)connectionHandle);
-
- } else {
-
- uint8_t type = matchingServiceUUID.shortOrLong();
- //PRINTF("AddService(): Type:%d\n\r", type);
-
- if(type == UUID::UUID_TYPE_SHORT) {
- STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID());
-
- PRINTF("launchServiceDiscovery short_uuid=0x");
- for(j = 0; j < 2; j++) {
- PRINTF("%02X", short_uuid[j]);
- }
- PRINTF("\n\r");
-
-
- uuid_type = UUID_TYPE_16;
- uuid = short_uuid;
-
- } else if(type==UUID::UUID_TYPE_LONG) {
-
- uuid_type = UUID_TYPE_128;
- uuid = (unsigned char*)matchingServiceUUID.getBaseUUID();
-
- /*
- PRINTF("launchServiceDiscovery base_uuid=0x");
- for(j = 0; j < 16; j++) {
- PRINTF("%02X", uuid[j]);
- }
- PRINTF("\n\r");
- */
- }
-
- // search for specific service by UUID
- ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)connectionHandle, uuid_type, uuid);
- //ret = aci_gatt_disc_all_prim_services((uint16_t)connectionHandle);
- }
-
- if(ret == BLE_STATUS_SUCCESS) {
- _currentState = GATT_SERVICE_DISCOVERY;
- }
-
- PRINTF("launchServiceDiscovery ret=%d\n\r", ret);
-
- return BLE_ERROR_NONE;
-}
-
-ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle,
- ServiceDiscovery::ServiceCallback_t callback,
- const UUID &matchingServiceUUID)
-{
- /* avoid compiler warnings about unused variables */
- (void)connectionHandle;
- (void)callback;
- (void)matchingServiceUUID;
-
- return BLE_ERROR_NOT_IMPLEMENTED;
-}
-
-ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle,
- ServiceDiscovery::ServiceCallback_t callback,
- GattAttribute::Handle_t startHandle,
- GattAttribute::Handle_t endHandle)
-{
- /* avoid compiler warnings about unused variables */
- (void)connectionHandle;
- (void)callback;
- (void)startHandle;
- (void)endHandle;
-
- return BLE_ERROR_NOT_IMPLEMENTED;
-}
-
-bool BlueNRGGattClient::isServiceDiscoveryActive(void) const
-{
- if(_currentState == GATT_IDLE ||
- _currentState == GATT_DISCOVERY_TERMINATED ||
- _currentState == GATT_READ_CHAR ||
- _currentState == GATT_WRITE_CHAR ) {
- return false;
- }
-
- return true;
-}
-
-void BlueNRGGattClient::terminateServiceDiscovery(void)
-{
- _currentState = GATT_DISCOVERY_TERMINATED;
-
- if (terminationCallback) {
- terminationCallback(_connectionHandle);
- }
-}
-
-void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle,
- uint8_t event_data_length,
- uint8_t* attribute_value)
-{
- readCBParams.connHandle = connHandle;
- readCBParams.offset = 0;
- readCBParams.len = event_data_length;
- readCBParams.data = attribute_value;
-
- BlueNRGGattClient::getInstance().processReadResponse(&readCBParams);
-}
-
-ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const
-{
- /* avoid compiler warnings about unused variables */
- (void)offset;
-
- tBleStatus ret;
-
- BlueNRGGattClient *gattc = const_cast<BlueNRGGattClient*>(this);
-
- gattc->_currentState = GATT_READ_CHAR;
-
- // Save the attribute_handle not provided by evt_att_read_resp
- gattc->readCBParams.handle = attributeHandle;
-
- // FIXME: We need to wait for a while before starting a read
- // due to BlueNRG process queue handling
- Clock_Wait(100);
-
- ret = aci_gatt_read_charac_val(connHandle, attributeHandle);
-
- if(ret == BLE_STATUS_SUCCESS) {
- return BLE_ERROR_NONE;
- }
- switch (ret) {
- case BLE_STATUS_BUSY:
- return BLE_STACK_BUSY;
- default:
- return BLE_ERROR_INVALID_STATE;
- }
-}
-
-void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle,
- uint8_t event_data_length,
- uint16_t attribute_handle,
- uint16_t offset,
- uint8_t *part_attr_value)
-{
- /* avoid compiler warnings about unused variables */
- (void)connHandle;
-
- // Update the write response params
- writeCBParams.handle = attribute_handle;
- writeCBParams.offset = offset;
- writeCBParams.len = event_data_length-4; //(?)
- writeCBParams.data = part_attr_value;
-
- BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
-}
-
-void BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle,
- uint8_t event_data_length)
-{
- /* avoid compiler warnings about unused variables */
- (void)event_data_length;
-
- writeCBParams.connHandle = connHandle;
-
- BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
-}
-
-ble_error_t BlueNRGGattClient::write(GattClient::WriteOp_t cmd,
- Gap::Handle_t connHandle,
- GattAttribute::Handle_t attributeHandle,
- size_t length,
- const uint8_t *value) const
-{
- /* avoid compiler warnings about unused variables */
- (void)cmd;
-
- tBleStatus ret;
-
- BlueNRGGattClient *gattc = const_cast<BlueNRGGattClient*>(this);
-
- gattc->_currentState = GATT_WRITE_CHAR;
-
- // We save the write response params (used by the callback) because
- // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE
- gattc->writeCBParams.connHandle = connHandle;
- gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD;
- gattc->writeCBParams.handle = attributeHandle;
- gattc->writeCBParams.offset = 0;
- gattc->writeCBParams.len = length;
- gattc->writeCBParams.data = value;
-
- ret = aci_gatt_write_charac_value(connHandle, attributeHandle, length, const_cast<uint8_t *>(value));
- //ret = aci_gatt_write_charac_reliable(connHandle, attributeHandle, 0, length, const_cast<uint8_t *>(value));
-
- if (ret == BLE_STATUS_SUCCESS) {
- return BLE_ERROR_NONE;
- }
- switch (ret) {
- case BLE_STATUS_BUSY:
- return BLE_STACK_BUSY;
- default:
- return BLE_ERROR_INVALID_STATE;
- }
-
-}
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/**
+ ******************************************************************************
+ * @file BlueNRGGattServer.cpp
+ * @author STMicroelectronics
+ * @brief Implementation of BlueNRG BLE_API GattServer Class
+ ******************************************************************************
+ * @copy
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
+ */
+
+/** @defgroup BlueNRGGATTClient
+ * @brief BlueNRG BLE_API GattClient Adaptation
+ * @{
+ */
+
+#include "BlueNRGGattClient.h"
+#include "mbed-drivers/mbed.h"
+#include "BlueNRGGap.h"
+#include "Utils.h"
+#include "debug.h"
+
+static uint8_t props_mask[] = {
+ 0x01,
+ 0x02,
+ 0x04,
+ 0x08,
+ 0x10,
+ 0x20,
+ 0x40,
+ 0x80
+ };
+
+void BlueNRGGattClient::gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code)
+{
+ if(error_code != BLE_STATUS_SUCCESS) {
+ _currentState = GATT_IDLE;
+ return;
+ }
+
+ // Service Discovery complete
+/*
+ if(_currentState != GATT_IDLE &&
+ _currentState != GATT_DISCOVERY_TERMINATED &&
+ _currentState != GATT_WRITE_CHAR &&
+ _currentState != GATT_READ_CHAR) {
+*/
+ if(_currentState == GATT_SERVICE_DISCOVERY) {
+ findServiceChars(connectionHandle);
+ }
+
+ if(_currentState == GATT_CHAR_DESC_DISCOVERY) {
+ _currentState = GATT_IDLE;
+ }
+
+ // Read complete
+ if(_currentState == GATT_READ_CHAR) {
+ _currentState = GATT_IDLE;
+ }
+
+ // Write complete
+ if(_currentState == GATT_WRITE_CHAR) {
+ BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
+ _currentState = GATT_IDLE;
+ }
+}
+
+void BlueNRGGattClient::primaryServicesCB(Gap::Handle_t connectionHandle,
+ uint8_t event_data_length,
+ uint8_t attribute_data_length,
+ uint8_t *attribute_data_list)
+{
+ GattAttribute::Handle_t startHandle, endHandle;
+ UUID uuid;
+ uint8_t i, offset, numAttr;
+ /* avoid compiler warnings about unused variables */
+ (void)connectionHandle;
+
+ numAttr = (event_data_length - 1) / attribute_data_length;
+
+ offset = 0;
+ for (i=0; i<numAttr; i++) {
+ startHandle = attribute_data_list[offset];
+ endHandle = attribute_data_list[offset+2];
+
+ // UUID Type
+ if (attribute_data_length == 6) {
+
+ PRINTF("UUID_TYPE_16\n\r");
+ uuid = attribute_data_list[offset+5]<<8|attribute_data_list[offset+4];
+ PRINTF("S UUID-%X attrs[%u %u]\r\n", uuid.getShortUUID(), startHandle, endHandle);
+
+ } else {
+
+ PRINTF("UUID_TYPE_128\n\r");
+ uuid.setupLong(attribute_data_list+offset+4, UUID::LSB);
+
+#ifdef DEBUG
+ PRINTF("S UUID-");
+ const uint8_t *longUUIDBytes = uuid.getBaseUUID();
+ for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) {
+ PRINTF("%02x", longUUIDBytes[j]);
+ }
+#endif
+ PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle);
+
+ }
+
+ PRINTF("Setup serviceIndex = %d\n\r", _numServices);
+ discoveredService[_numServices].setup(uuid, startHandle, endHandle);
+
+ if(serviceDiscoveryCallback) {
+ if(_matchingServiceUUID == BLE_UUID_UNKNOWN || _matchingServiceUUID == discoveredService[_numServices].getUUID()) {
+ serviceDiscoveryCallback(&discoveredService[_numServices]);
+ }
+ }
+ _numServices++;
+
+ offset += attribute_data_length;
+ }
+
+ PRINTF("!!!Service Discovery complete (numAttr=%u)!!!\n\r", numAttr);
+
+}
+
+void BlueNRGGattClient::primaryServiceCB(Gap::Handle_t connectionHandle,
+ uint8_t event_data_length,
+ uint8_t *handles_info_list)
+{
+ GattAttribute::Handle_t startHandle, endHandle;
+ UUID uuid;
+ uint8_t i, offset, numHandlePairs;
+ /* avoid compiler warnings about unused variables */
+ (void)connectionHandle;
+
+ numHandlePairs = (event_data_length - 1) / 2;
+
+ offset = 0;
+ for (i=0; i<numHandlePairs; i++) {
+ startHandle = handles_info_list[offset];
+ endHandle = handles_info_list[offset+2];
+
+ PRINTF("primaryServiceCB attrs[%u %u]\r\n", startHandle, endHandle);
+
+
+ if (_matchingServiceUUID.shortOrLong() == UUID::UUID_TYPE_SHORT) {
+ PRINTF("S UUID-%x attrs[%u %u]\r\n", _matchingServiceUUID.getShortUUID(), startHandle, endHandle);
+ uuid = _matchingServiceUUID.getShortUUID();
+ } else {
+#ifdef DEBUG
+ PRINTF("S UUID-");
+ const uint8_t *longUUIDBytes = _matchingServiceUUID.getBaseUUID();
+ for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+ PRINTF("%02x", longUUIDBytes[i]);
+ }
+#endif
+ PRINTF(" attrs[%u %u]\r\n", startHandle, endHandle);
+ uuid.setupLong(_matchingServiceUUID.getBaseUUID(), UUID::MSB);
+ }
+
+ discoveredService[i].setup(uuid, startHandle, endHandle);
+
+ if(serviceDiscoveryCallback) {
+ serviceDiscoveryCallback(&discoveredService[_numServices]);
+ }
+ _numServices++;
+
+ offset += 4;
+ }
+}
+
+void BlueNRGGattClient::serviceCharsCB(Gap::Handle_t connectionHandle,
+ uint8_t event_data_length,
+ uint8_t handle_value_pair_length,
+ uint8_t *handle_value_pair)
+{
+ // Charac Handle (2), Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16)
+
+ GattAttribute::Handle_t declHandle, valueHandle, lastHandle;
+ UUID uuid;
+ uint8_t i, numChar, offset;
+
+ numChar = (event_data_length - 1) / handle_value_pair_length;
+
+ PRINTF("event_data_length=%d handle_value_pair_length=%d numChar=%d\n\r", event_data_length, handle_value_pair_length, numChar);
+
+ offset = 0;
+ for (i=0; i<numChar; i++) {
+ // UUID Type
+ if (handle_value_pair_length == 7) {
+ PRINTF("Char UUID_TYPE_16\n\r");
+ uuid = handle_value_pair[offset+6]<<8|handle_value_pair[offset+5];
+ PRINTF("C UUID-%X\r\n", uuid.getShortUUID());
+ } else {
+ PRINTF("Char UUID_TYPE_128\n\r");
+ uuid.setupLong(handle_value_pair+offset+5, UUID::LSB);
+#ifdef DEBUG
+ PRINTF("C UUID-");
+ const uint8_t *longUUIDBytes = uuid.getBaseUUID();
+ for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+ PRINTF("%02X", longUUIDBytes[i]);
+ }
+ PRINTF("\r\n");
+#endif
+ }
+
+ // Properties
+ DiscoveredCharacteristic::Properties_t p;
+
+ p._broadcast = (props_mask[0] & handle_value_pair[offset+2]);
+ p._read = (props_mask[1] & handle_value_pair[offset+2])>>1;
+ p._writeWoResp = (props_mask[2] & handle_value_pair[offset+2])>>2;
+ p._write = (props_mask[3] & handle_value_pair[offset+2])>>3;
+ p._notify = (props_mask[4] & handle_value_pair[offset+2])>>4;
+ p._indicate = (props_mask[5] & handle_value_pair[offset+2])>>5;
+ p._authSignedWrite = (props_mask[6] & handle_value_pair[offset+2])>>6;
+ PRINTF("p._broadcast=%d\n\r", p._broadcast);
+ PRINTF("p._read=%d\n\r", p._read);
+ PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp);
+ PRINTF("p._write=%d\n\r", p._write);
+ PRINTF("p._notify=%d\n\r", p._notify);
+ PRINTF("p._indicate=%d\n\r", p._indicate);
+ PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite);
+
+ /*
+ uint8_t props = handle_value_pair[offset+2];
+ PRINTF("CHAR PROPS: %d\n\r", props);
+ */
+
+ // Handles
+ declHandle = handle_value_pair[offset];
+ valueHandle = handle_value_pair[offset+3];
+ lastHandle = valueHandle+1;
+ PRINTF("declHandle: %u valueHandle=%u lastHandle=%u\n\r", declHandle, valueHandle, lastHandle);
+
+ discoveredChar[_numChars].setup(this,
+ connectionHandle,
+ uuid,
+ p,
+ declHandle,
+ valueHandle,
+ lastHandle);
+
+ if(characteristicDiscoveryCallback) {
+ characteristicDiscoveryCallback(&discoveredChar[_numChars]);
+ }
+ _numChars++;
+
+ offset += handle_value_pair_length;
+ }
+}
+
+void BlueNRGGattClient::serviceCharByUUIDCB(Gap::Handle_t connectionHandle,
+ uint8_t event_data_length,
+ uint16_t attr_handle,
+ uint8_t *attr_value)
+{
+ // Charac Properties(1), Charac Value Handle(2), Charac UUID(2/16)
+ GattAttribute::Handle_t declHandle, valueHandle, lastHandle;
+ UUID uuid;
+
+ PRINTF("serviceCharByUUIDCB\n\r");
+
+ // UUID Type
+ if (event_data_length == 7) {
+ PRINTF("Char UUID_TYPE_16\n\r");
+ uuid = attr_value[4]<<8|attr_value[3];
+ PRINTF("C UUID-%X\r\n", uuid.getShortUUID());
+ } else {
+ PRINTF("Char UUID_TYPE_128\n\r");
+ uuid.setupLong(attr_value+3, UUID::LSB);
+#ifdef DEBUG
+ PRINTF("C UUID-");
+ const uint8_t *longUUIDBytes = uuid.getBaseUUID();
+ for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+ PRINTF("%02X", longUUIDBytes[i]);
+ }
+ PRINTF("\r\n");
+#endif
+ }
+
+ // Properties
+ DiscoveredCharacteristic::Properties_t p;
+
+ p._broadcast = (props_mask[0] & attr_value[0]);
+ p._read = (props_mask[1] & attr_value[0])>>1;
+ p._writeWoResp = (props_mask[2] & attr_value[0])>>2;
+ p._write = (props_mask[3] & attr_value[0])>>3;
+ p._notify = (props_mask[4] & attr_value[0])>>4;
+ p._indicate = (props_mask[5] & attr_value[0])>>5;
+ p._authSignedWrite = (props_mask[6] & attr_value[0])>>6;
+ PRINTF("p._broadcast=%d\n\r", p._broadcast);
+ PRINTF("p._read=%d\n\r", p._read);
+ PRINTF("p._writeWoResp=%d\n\r", p._writeWoResp);
+ PRINTF("p._write=%d\n\r", p._write);
+ PRINTF("p._notify=%d\n\r", p._notify);
+ PRINTF("p._indicate=%d\n\r", p._indicate);
+ PRINTF("p._authSignedWrite=%d\n\r", p._authSignedWrite);
+
+ /*
+ uint8_t props = attr_value[0];
+ PRINTF("CHAR PROPS: %d\n\r", props);
+ */
+
+ // Handles
+ declHandle = attr_handle;
+ valueHandle = attr_value[1];
+ lastHandle = valueHandle+1;
+
+ discoveredChar[_numChars].setup(this,
+ connectionHandle,
+ uuid,
+ p,
+ declHandle,
+ valueHandle,
+ lastHandle);
+
+ if(characteristicDiscoveryCallback) {
+ characteristicDiscoveryCallback(&discoveredChar[_numChars]);
+ }
+ _numChars++;
+}
+
+ble_error_t BlueNRGGattClient::findServiceChars(Gap::Handle_t connectionHandle)
+{
+ PRINTF("findServiceChars\n\r");
+
+ tBleStatus ret;
+ uint8_t uuid_type = UUID_TYPE_16;
+ uint8_t short_uuid[2];
+ uint8_t *uuid = NULL;
+
+ DiscoveredService *service;
+
+ // We finished chars discovery for all services
+ if(_servIndex >= _numServices) {
+ PRINTF("!!!We finished chars discovery for all services!!!\n\r");
+ //_currentState = GATT_CHARS_DISCOVERY_COMPLETE;
+
+ terminateServiceDiscovery();
+
+ return BLE_ERROR_NONE;
+ }
+
+ service = &discoveredService[_servIndex];
+ /*
+ if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
+ PRINTF("S UUID-%X\r\n", service->getUUID().getShortUUID());
+ } else {
+ PRINTF("S UUID-");
+ const uint8_t *longUUIDBytes = service->getUUID().getBaseUUID();
+ for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+ PRINTF("%02X", longUUIDBytes[i]);
+ }
+ PRINTF("\r\n");
+ }
+ */
+
+ PRINTF("findServiceChars (_servIndex=%d)\n\r", _servIndex);
+ //ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle());
+
+ if(_matchingCharacteristicUUIDIn == BLE_UUID_UNKNOWN) {
+ PRINTF("findServiceChars (BLE_UUID_UNKNOWN)\n\r");
+ ret = aci_gatt_disc_all_charac_of_serv(connectionHandle, service->getStartHandle(), service->getEndHandle());
+ } else {
+
+ uint8_t type = _matchingCharacteristicUUIDIn.shortOrLong();
+
+ if(type == UUID::UUID_TYPE_SHORT) {
+ STORE_LE_16(short_uuid, _matchingCharacteristicUUIDIn.getShortUUID());
+
+ uuid_type = UUID_TYPE_16;
+ uuid = short_uuid;
+#ifdef DEBUG
+ PRINTF("findServiceChars C UUID-");
+ for(unsigned i = 0; i < 2; i++) {
+ PRINTF("%02X", short_uuid[i]);
+ }
+ PRINTF("\n\r");
+#endif
+ } else if(type==UUID::UUID_TYPE_LONG) {
+
+ uuid_type = UUID_TYPE_128;
+ uuid = (unsigned char*)_matchingCharacteristicUUIDIn.getBaseUUID();
+#ifdef DEBUG
+ PRINTF("(findServiceChars) C UUID-");
+ for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+ PRINTF("%02X", uuid[i]);
+ }
+ PRINTF("\r\n");
+#endif
+ }
+
+ ret = aci_gatt_disc_charac_by_uuid(connectionHandle,
+ service->getStartHandle(),
+ service->getEndHandle(),
+ uuid_type,
+ uuid);
+ }
+
+ if(ret == BLE_STATUS_SUCCESS) {
+ _servIndex++;
+ }
+
+ PRINTF("findServiceChars ret=%d\n\r", ret);
+
+ return BLE_ERROR_NONE;
+}
+
+ble_error_t BlueNRGGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle,
+ ServiceDiscovery::ServiceCallback_t sc,
+ ServiceDiscovery::CharacteristicCallback_t cc,
+ const UUID &matchingServiceUUID,
+ const UUID &matchingCharacteristicUUIDIn)
+{
+ PRINTF("launchServiceDiscovery\n\r");
+
+ tBleStatus ret;
+ uint8_t uuid_type = UUID_TYPE_16;
+ uint8_t short_uuid[2];
+ uint8_t *uuid = NULL;
+ unsigned j;
+
+ if(isServiceDiscoveryActive()) {
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ }
+
+ if(!sc && !cc) {
+ // nothing to do
+ PRINTF("launchServiceDiscovery: nothing to do\n\r");
+ return BLE_ERROR_NONE;
+ }
+
+ _connectionHandle = connectionHandle;
+ serviceDiscoveryCallback = sc;
+ characteristicDiscoveryCallback = cc;
+ _matchingServiceUUID = matchingServiceUUID;
+ _matchingCharacteristicUUIDIn = matchingCharacteristicUUIDIn;
+
+ //reset services
+ _numServices = 0;
+ _numChars = 0;
+ _servIndex = 0;
+ for(j = 0; j < BLE_TOTAL_DISCOVERED_SERVICES; j++) {
+ discoveredService[j].setup(BLE_UUID_UNKNOWN, GattAttribute::INVALID_HANDLE, GattAttribute::INVALID_HANDLE);
+ }
+
+ if(matchingServiceUUID == BLE_UUID_UNKNOWN) {
+
+ // Wildcard: search for all services
+ ret = aci_gatt_disc_all_prim_services((uint16_t)connectionHandle);
+
+ } else {
+
+ uint8_t type = matchingServiceUUID.shortOrLong();
+ //PRINTF("AddService(): Type:%d\n\r", type);
+
+ if(type == UUID::UUID_TYPE_SHORT) {
+ STORE_LE_16(short_uuid, matchingServiceUUID.getShortUUID());
+#ifdef DEBUG
+ PRINTF("launchServiceDiscovery short_uuid=0x");
+ for(j = 0; j < 2; j++) {
+ PRINTF("%02X", short_uuid[j]);
+ }
+ PRINTF("\n\r");
+#endif
+
+ uuid_type = UUID_TYPE_16;
+ uuid = short_uuid;
+
+ } else if(type==UUID::UUID_TYPE_LONG) {
+
+ uuid_type = UUID_TYPE_128;
+ uuid = (unsigned char*)matchingServiceUUID.getBaseUUID();
+
+#ifdef DEBUG
+ PRINTF("launchServiceDiscovery base_uuid=0x");
+ for(j = 0; j < 16; j++) {
+ PRINTF("%02X", uuid[j]);
+ }
+ PRINTF("\n\r");
+#endif
+ }
+
+ // search for specific service by UUID
+ ret = aci_gatt_disc_prim_service_by_uuid((uint16_t)connectionHandle, uuid_type, uuid);
+ //ret = aci_gatt_disc_all_prim_services((uint16_t)connectionHandle);
+ }
+
+ if(ret == BLE_STATUS_SUCCESS) {
+ _currentState = GATT_SERVICE_DISCOVERY;
+ }
+
+ PRINTF("launchServiceDiscovery ret=%d\n\r", ret);
+
+ return BLE_ERROR_NONE;
+}
+
+ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle,
+ ServiceDiscovery::ServiceCallback_t callback,
+ const UUID &matchingServiceUUID)
+{
+ /* avoid compiler warnings about unused variables */
+ (void)connectionHandle;
+ (void)callback;
+ (void)matchingServiceUUID;
+
+ return BLE_ERROR_NOT_IMPLEMENTED;
+}
+
+ble_error_t BlueNRGGattClient::discoverServices(Gap::Handle_t connectionHandle,
+ ServiceDiscovery::ServiceCallback_t callback,
+ GattAttribute::Handle_t startHandle,
+ GattAttribute::Handle_t endHandle)
+{
+ /* avoid compiler warnings about unused variables */
+ (void)connectionHandle;
+ (void)callback;
+ (void)startHandle;
+ (void)endHandle;
+
+ return BLE_ERROR_NOT_IMPLEMENTED;
+}
+
+bool BlueNRGGattClient::isServiceDiscoveryActive(void) const
+{
+ if(_currentState == GATT_SERVICE_DISCOVERY) {
+ return true;
+ }
+
+ return false;
+/*
+ if(_currentState == GATT_IDLE ||
+ _currentState == GATT_DISCOVERY_TERMINATED ||
+ _currentState == GATT_READ_CHAR ||
+ _currentState == GATT_WRITE_CHAR ) {
+ return false;
+ }
+
+ return true;
+*/
+}
+
+void BlueNRGGattClient::terminateServiceDiscovery(void)
+{
+ _currentState = GATT_IDLE;//GATT_DISCOVERY_TERMINATED;
+
+ if (terminationCallback) {
+ terminationCallback(_connectionHandle);
+ }
+}
+
+void BlueNRGGattClient::charReadCB(Gap::Handle_t connHandle,
+ uint8_t event_data_length,
+ uint8_t* attribute_value)
+{
+ readCBParams.connHandle = connHandle;
+ readCBParams.offset = 0;
+ readCBParams.len = event_data_length;
+ readCBParams.data = attribute_value;
+
+ BlueNRGGattClient::getInstance().processReadResponse(&readCBParams);
+}
+
+ble_error_t BlueNRGGattClient::read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const
+{
+ /* avoid compiler warnings about unused variables */
+ (void)offset;
+
+ tBleStatus ret;
+
+ BlueNRGGattClient *gattc = const_cast<BlueNRGGattClient*>(this);
+
+ // Save the attribute_handle not provided by evt_att_read_resp
+ gattc->readCBParams.handle = attributeHandle;
+
+ // FIXME: We need to wait for a while before starting a read
+ // due to BlueNRG process queue handling
+ Clock_Wait(100);
+
+ ret = aci_gatt_read_charac_val(connHandle, attributeHandle);
+
+ if(ret == BLE_STATUS_SUCCESS) {
+ gattc->_currentState = GATT_READ_CHAR;
+ return BLE_ERROR_NONE;
+ }
+ switch (ret) {
+ case BLE_STATUS_BUSY:
+ return BLE_STACK_BUSY;
+ default:
+ return BLE_ERROR_INVALID_STATE;
+ }
+}
+
+void BlueNRGGattClient::charWritePrepareCB(Gap::Handle_t connHandle,
+ uint8_t event_data_length,
+ uint16_t attribute_handle,
+ uint16_t offset,
+ uint8_t *part_attr_value)
+{
+ /* avoid compiler warnings about unused variables */
+ (void)connHandle;
+
+ // Update the write response params
+ writeCBParams.handle = attribute_handle;
+ writeCBParams.offset = offset;
+ writeCBParams.len = event_data_length-4; //(?)
+ writeCBParams.data = part_attr_value;
+
+ BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
+}
+
+void BlueNRGGattClient::charWriteExecCB(Gap::Handle_t connHandle,
+ uint8_t event_data_length)
+{
+ /* avoid compiler warnings about unused variables */
+ (void)event_data_length;
+
+ writeCBParams.connHandle = connHandle;
+
+ BlueNRGGattClient::getInstance().processWriteResponse(&writeCBParams);
+}
+
+ble_error_t BlueNRGGattClient::write(GattClient::WriteOp_t cmd,
+ Gap::Handle_t connHandle,
+ GattAttribute::Handle_t attributeHandle,
+ size_t length,
+ const uint8_t *value) const
+{
+ /* avoid compiler warnings about unused variables */
+ (void)cmd;
+
+ tBleStatus ret;
+
+ BlueNRGGattClient *gattc = const_cast<BlueNRGGattClient*>(this);
+
+ // We save the write response params (used by the callback) because
+ // when the aci_gatt_write_charac_value() is used the only event received is the EVT_BLUE_GATT_PROCEDURE_COMPLETE
+ gattc->writeCBParams.connHandle = connHandle;
+ gattc->writeCBParams.writeOp = GattWriteCallbackParams::OP_WRITE_CMD;
+ gattc->writeCBParams.handle = attributeHandle;
+ gattc->writeCBParams.offset = 0;
+ gattc->writeCBParams.len = length;
+ gattc->writeCBParams.data = value;
+
+ ret = aci_gatt_write_charac_value(connHandle, attributeHandle, length, const_cast<uint8_t *>(value));
+ //ret = aci_gatt_write_charac_reliable(connHandle, attributeHandle, 0, length, const_cast<uint8_t *>(value));
+
+ if (ret == BLE_STATUS_SUCCESS) {
+ gattc->_currentState = GATT_WRITE_CHAR;
+ return BLE_ERROR_NONE;
+ }
+ switch (ret) {
+ case BLE_STATUS_BUSY:
+ return BLE_STACK_BUSY;
+ default:
+ return BLE_ERROR_INVALID_STATE;
+ }
+
+}
+
+void BlueNRGGattClient::discAllCharacDescCB(Gap::Handle_t connHandle,
+ uint8_t event_data_length,
+ uint8_t format,
+ uint8_t *handle_uuid_pair) {
+ GattAttribute::Handle_t attHandle;
+ UUID uuid;
+ uint8_t i, numCharacDesc, offset, handle_uuid_length;
+
+ handle_uuid_length = 4; //Handle + UUID_16
+ if (format == 2)
+ handle_uuid_length = 18; //Handle + UUID_128
+
+ numCharacDesc = (event_data_length - 1) / handle_uuid_length;
+
+ offset = 0;
+
+ for (i=0; i<numCharacDesc; i++) {
+ attHandle = handle_uuid_pair[offset];
+
+ // UUID Type
+ if (handle_uuid_length == 4) {
+
+ PRINTF("UUID_TYPE_16\n\r");
+ uuid = handle_uuid_pair[offset+3]<<8|handle_uuid_pair[offset+2];
+ PRINTF("D UUID-%X attHandle=%u\r\n", uuid.getShortUUID(), attHandle);
+
+ } else {
+
+ PRINTF("UUID_TYPE_128\n\r");
+ uuid.setupLong(handle_uuid_pair+offset+2, UUID::LSB);
+#ifdef DEBUG
+ PRINTF("D UUID-");
+ const uint8_t *longUUIDBytes = uuid.getBaseUUID();
+ for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) {
+ PRINTF("%02x", longUUIDBytes[j]);
+ }
+#endif
+ }
+
+ if(charDescDiscoveryCallback != NULL) {
+ CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = {
+ _characteristic,
+ DiscoveredCharacteristicDescriptor(
+ _characteristic.getGattClient(),
+ connHandle,
+ attHandle,
+ uuid
+ )
+ };
+ charDescDiscoveryCallback(¶ms);
+ }
+
+ _numCharDesc++;
+
+ offset += handle_uuid_length;
+ }
+
+ if(charDescTerminationCallback != NULL) {
+ CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = {
+ _characteristic,
+ BLE_ERROR_NONE
+ };
+ charDescTerminationCallback(¶ms);
+ }
+
+}
+
+ble_error_t BlueNRGGattClient::discoverCharacteristicDescriptors(
+ const DiscoveredCharacteristic& characteristic,
+ const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
+ const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) {
+
+ tBleStatus ret;
+
+ if(_currentState != GATT_IDLE) {
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ }
+
+ charDescDiscoveryCallback = discoveryCallback;
+ charDescTerminationCallback = terminationCallback;
+
+ Gap::Handle_t connHandle = characteristic.getConnectionHandle();
+ GattAttribute::Handle_t valueHandle = characteristic.getValueHandle();
+ GattAttribute::Handle_t lastHandle = characteristic.getLastHandle();
+
+ ret = aci_gatt_disc_all_charac_descriptors(connHandle, valueHandle, lastHandle);
+
+ if (ret == BLE_STATUS_SUCCESS) {
+ _currentState = GATT_CHAR_DESC_DISCOVERY;
+ _characteristic = characteristic;
+ return BLE_ERROR_NONE;
+ }
+ switch (ret) {
+ case BLE_STATUS_INVALID_PARAMS:
+ return BLE_ERROR_INVALID_PARAM;
+ default:
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ }
+}
+
+/**************************************************************************/
+/*!
+ @brief Clear BlueNRGGattServer's state.
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGattClient::reset(void) {
+ /* Clear all state that is from the parent, including private members */
+ if (GattClient::reset() != BLE_ERROR_NONE) {
+ return BLE_ERROR_INVALID_STATE;
+ }
+
+ _currentState = GATT_IDLE;
+ _matchingServiceUUID = BLE_UUID_UNKNOWN;
+ _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN;
+
+ _numServices = 0;
+ _servIndex = 0;
+ _numChars = 0;
+ _numCharDesc = 0;
+
+ /* Clear class members */
+ memset(discoveredService, 0, sizeof(discoveredService));
+ memset(discoveredChar, 0, sizeof(discoveredChar));
+
+ return BLE_ERROR_NONE;
+}
+
--- a/source/BlueNRGGattServer.cpp Tue Apr 26 14:44:54 2016 +0200
+++ b/source/BlueNRGGattServer.cpp Mon May 16 17:22:03 2016 +0200
@@ -29,10 +29,7 @@
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
- */
-
-
-// ANDREA: Changed some types (e.g., tHalUint8 --> uint8_t)
+ */
/** @defgroup BlueNRGGATTSERVER
* @brief BlueNRG BLE_API GattServer Adaptation
@@ -124,14 +121,21 @@
//iterate to include all characteristics
for (uint8_t i = 0; i < charsCount; i++) {
GattCharacteristic *p_char = service.getCharacteristic(i);
- uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID();
-
+ uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID();
+
uint8_t int_8_uuid[2];
STORE_LE_16(int_8_uuid, char_uuid);
-
+
+ type = (p_char->getValueAttribute().getUUID()).shortOrLong();
+
if(type==UUID::UUID_TYPE_LONG) {
base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID();
-
+#ifdef DEBUG
+ for(uint8_t j=0; j<16; j++) {
+ PRINTF("base_char_uuid[%d] 0x%02x ", j, base_char_uuid[j]);
+ }
+ PRINTF("\n\r");
+#endif
COPY_UUID_128(char_base_uuid,base_char_uuid[15],base_char_uuid[14],int_8_uuid[1],int_8_uuid[0],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9],base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],base_char_uuid[3],base_char_uuid[2],base_char_uuid[1],base_char_uuid[0]);
}
@@ -168,7 +172,8 @@
1 /*isVariable*/,
&bleCharacteristic);
- PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r", p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret);
+ PRINTF("aci_gatt_add_char UUID_TYPE_16 props=%d MaxLength=%d ret=%d\n\r",
+ p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret);
} else if(type==UUID::UUID_TYPE_LONG) {
ret = aci_gatt_add_char(service.getHandle(),
@@ -182,20 +187,21 @@
1 /*isVariable*/,
&bleCharacteristic);
- PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r", p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret);
+ PRINTF("aci_gatt_add_char UUID_TYPE_128 props=%d MaxLength=%d ret=%d\n\r",
+ p_char->getProperties(), p_char->getValueAttribute().getMaxLength(), ret);
}
-
- /* Update the characteristic handle */
- //uint16_t charHandle = characteristicCount;
- bleCharHanldeMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle));
+ bleCharHandleMap.insert(std::pair<uint16_t, uint16_t>(bleCharacteristic, servHandle));
p_characteristics[characteristicCount++] = p_char;
- p_char->getValueAttribute().setHandle(bleCharacteristic); //Set the characteristic count as the corresponding char handle
- PRINTF("added bleCharacteristic handle =%u\n\r", bleCharacteristic);
+ /* Set the characteristic value handle */
+ p_char->getValueAttribute().setHandle(bleCharacteristic+BlueNRGGattServer::CHAR_VALUE_HANDLE);
+ PRINTF("added bleCharacteristic (value handle =%u)\n\r", p_char->getValueAttribute().getHandle());
if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) {
- write(p_char->getValueAttribute().getHandle(), p_char->getValueAttribute().getValuePtr(), p_char->getValueAttribute().getLength(), false /* localOnly */);
+ write(p_char->getValueAttribute().getHandle(),
+ p_char->getValueAttribute().getValuePtr(),
+ p_char->getValueAttribute().getLength(), false /* localOnly */);
}
// add descriptors now
@@ -206,10 +212,19 @@
GattAttribute *descriptor = p_char->getDescriptor(descIndex);
uint16_t shortUUID = descriptor->getUUID().getShortUUID();
const uint8_t uuidArray[] = {(uint8_t)((shortUUID>>8)&0xFF), (uint8_t)((shortUUID&0xFF))};
- ret = aci_gatt_add_char_desc(service.getHandle(), p_char->getValueAttribute().getHandle(),
- CHAR_DESC_TYPE_16_BIT, uuidArray, descriptor->getMaxLength(), descriptor->getLength(),
- descriptor->getValuePtr(), CHAR_DESC_SECURITY_PERMISSION, CHAR_DESC_ACCESS_PERMISSION, GATT_NOTIFY_ATTRIBUTE_WRITE,
- MIN_ENCRY_KEY_SIZE, CHAR_ATTRIBUTE_LEN_IS_FIXED, &descHandle);
+ ret = aci_gatt_add_char_desc(service.getHandle(),
+ bleCharacteristic,
+ CHAR_DESC_TYPE_16_BIT,
+ uuidArray,
+ descriptor->getMaxLength(),
+ descriptor->getLength(),
+ descriptor->getValuePtr(),
+ CHAR_DESC_SECURITY_PERMISSION,
+ CHAR_DESC_ACCESS_PERMISSION,
+ GATT_NOTIFY_ATTRIBUTE_WRITE,
+ MIN_ENCRY_KEY_SIZE,
+ CHAR_ATTRIBUTE_LEN_IS_FIXED,
+ &descHandle);
PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret);
if(ret==(tBleStatus)0) {
PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle);
@@ -252,11 +267,12 @@
@endcode
*/
/**************************************************************************/
-ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t charHandle, uint8_t buffer[], uint16_t *lengthP)
+ble_error_t BlueNRGGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP)
{
tBleStatus ret;
+ uint16_t charHandle = attributeHandle-BlueNRGGattServer::CHAR_VALUE_HANDLE;
- ret = aci_gatt_read_handle_value(charHandle+CHAR_VALUE_OFFSET, *lengthP, lengthP, buffer);
+ ret = aci_gatt_read_handle_value(charHandle, *lengthP, lengthP, buffer);
if(ret == BLE_STATUS_SUCCESS) {
return BLE_ERROR_NONE;
@@ -294,8 +310,10 @@
@endcode
*/
/**************************************************************************/
-// <<<ANDREA>>>
-ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) {
+ble_error_t BlueNRGGattServer::read(Gap::Handle_t connectionHandle,
+ GattAttribute::Handle_t attributeHandle,
+ uint8_t buffer[],
+ uint16_t *lengthP) {
/* avoid compiler warnings about unused variables */
(void)connectionHandle;
@@ -306,7 +324,10 @@
return BLE_ERROR_NONE;
}
-ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly) {
+ble_error_t BlueNRGGattServer::write(Gap::Handle_t connectionHandle,
+ GattAttribute::Handle_t,
+ const uint8_t[],
+ uint16_t, bool localOnly) {
/* avoid compiler warnings about unused variables */
(void)connectionHandle;
(void)localOnly;
@@ -314,21 +335,20 @@
return BLE_ERROR_NONE;
}
-ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t charHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
+ble_error_t BlueNRGGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
{
/* avoid compiler warnings about unused variables */
(void)localOnly;
tBleStatus ret;
- //uint8_t buff[2];
+
+ uint16_t charHandle = attributeHandle-BlueNRGGattServer::CHAR_VALUE_HANDLE;
- PRINTF("updating bleCharacteristic charHandle =%u, corresponding serviceHanle= %u len=%d\n\r", charHandle, bleCharHanldeMap.find(charHandle)->second, len);
- /*
- for(int i=0; i<len; i++) {
- PRINTF("buffer[%d]=%d\n\r", i, buffer[i]);
- }
- */
- ret = aci_gatt_update_char_value(bleCharHanldeMap.find(charHandle)->second, charHandle, 0, len, buffer);
+ PRINTF("updating bleCharacteristic valueHandle=%u,\
+ corresponding serviceHandle=%u len=%d\n\r",
+ attributeHandle, bleCharHandleMap.find(charHandle)->second, len);
+
+ ret = aci_gatt_update_char_value(bleCharHandleMap.find(charHandle)->second, charHandle, 0, len, buffer);
if (ret != BLE_STATUS_SUCCESS){
PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret);
@@ -357,8 +377,8 @@
/*!
@brief Reads a value according to the handle provided
- @param[in] charHandle
- The handle of the GattCharacteristic to read from
+ @param[in] attributeHandle
+ The handle of the attribute to read from
@returns ble_error_t
@@ -372,15 +392,14 @@
@endcode
*/
/**************************************************************************/
-ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t handle)
+ble_error_t BlueNRGGattServer::Read_Request_CB(uint16_t attributeHandle)
{
- //signed short refvalue;
uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle();
GattReadCallbackParams readParams;
- readParams.handle = handle;
+ readParams.handle = attributeHandle;
- //PRINTF("readParams.charHandle = %d\n\r", readParams.charHandle);
+ //PRINTF("readParams.handle = %d\n\r", readParams.handle);
HCIDataReadEvent(&readParams);
//EXIT:
@@ -396,8 +415,8 @@
/*!
@brief Returns the GattCharacteristic according to the handle provided
- @param[in] charHandle
- The handle of the GattCharacteristic
+ @param[in] attrHandle
+ The handle of the attribute
@returns ble_error_t
@@ -417,10 +436,10 @@
int i;
uint16_t handle, handle_1;
- PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attribute Handle received %d\n\r",attrHandle);
+ PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attr Handle received %d\n\r",attrHandle);
for(i=0; i<characteristicCount; i++)
{
- handle = p_characteristics[i]->getValueAttribute().getHandle();
+ handle = p_characteristics[i]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE;
PRINTF("handle(%d)=%d\n\r", i, handle);
if(i==characteristicCount-1)//Last Characteristic check
{
@@ -432,7 +451,7 @@
}
}
else {
- handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle();
+ handle_1 = p_characteristics[i+1]->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE;
//Testing if attribute handle is between two Characteristic Handles
if(attrHandle>=handle && attrHandle<handle_1)
{
@@ -468,3 +487,29 @@
// <TODO>
return (ble_error_t)0;
}
+
+/**************************************************************************/
+/*!
+ @brief Clear BlueNRGGattServer's state.
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+*/
+/**************************************************************************/
+ble_error_t BlueNRGGattServer::reset(void)
+{
+ /* Clear all state that is from the parent, including private members */
+ if (GattServer::reset() != BLE_ERROR_NONE) {
+ return BLE_ERROR_INVALID_STATE;
+ }
+
+ /* Clear class members */
+ memset(p_characteristics, 0, sizeof(p_characteristics));
+ memset(bleCharacteristicHandles, 0, sizeof(bleCharacteristicHandles));
+ serviceCount = 0;
+ characteristicCount = 0;
+
+ return BLE_ERROR_NONE;
+}
--- a/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Tue Apr 26 14:44:54 2016 +0200
+++ b/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Mon May 16 17:22:03 2016 +0200
@@ -119,7 +119,7 @@
uint8_t buffer[40];
uint8_t indx = 0;
- if((unsigned int)(LocalNameLen + ServiceUUIDLen + 14) > sizeof(buffer))
+ if((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer))
return BLE_STATUS_INVALID_PARAMS;
buffer[indx] = AdvType;
@@ -1300,7 +1300,8 @@
}
*num_devices = rp.num_addr;
- Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7));
+ if(device_list != NULL)
+ Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7));
return 0;
}
--- a/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Tue Apr 26 14:44:54 2016 +0200
+++ b/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Mon May 16 17:22:03 2016 +0200
@@ -317,7 +317,7 @@
uint16_t charHandle,
uint8_t charValOffset,
uint8_t charValueLen,
- const uint8_t *charValue)
+ const void *charValue)
{
struct hci_request rq;
uint8_t status;
@@ -1361,7 +1361,7 @@
uint16_t charDescHandle,
uint16_t charDescValOffset,
uint8_t charDescValueLen,
- const uint8_t *charDescValue)
+ const void *charDescValue)
{
struct hci_request rq;
uint8_t status;
--- a/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Tue Apr 26 14:44:54 2016 +0200
+++ b/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Mon May 16 17:22:03 2016 +0200
@@ -67,6 +67,35 @@
return 0;
}
+tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data)
+{
+ struct hci_request rq;
+ hal_read_config_data_cp cp;
+ hal_read_config_data_rp rp;
+
+ cp.offset = offset;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_VENDOR_CMD;
+ rq.ocf = OCF_HAL_READ_CONFIG_DATA;
+ rq.cparam = &cp;
+ rq.clen = sizeof(cp);
+ rq.rparam = &rp;
+ rq.rlen = sizeof(rp);
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ if(rp.status)
+ return rp.status;
+
+ *data_len_out_p = rq.rlen-1;
+
+ Osal_MemCpy(data, rp.data, MIN(data_len, *data_len_out_p));
+
+ return 0;
+}
+
tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level)
{
struct hci_request rq;
--- a/source/bluenrg-hci/hci/hci.c Tue Apr 26 14:44:54 2016 +0200
+++ b/source/bluenrg-hci/hci/hci.c Mon May 16 17:22:03 2016 +0200
@@ -535,7 +535,8 @@
adv_cp.advtype = advtype;
adv_cp.own_bdaddr_type = own_bdaddr_type;
adv_cp.direct_bdaddr_type = direct_bdaddr_type;
- Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr));
+ if(direct_bdaddr != NULL)
+ Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr));
adv_cp.chan_map = chan_map;
adv_cp.filter = filter;
@@ -817,6 +818,23 @@
return status;
}
+int hci_le_create_connection_cancel(void)
+{
+ struct hci_request rq;
+ uint8_t status;
+
+ Osal_MemSet(&rq, 0, sizeof(rq));
+ rq.ogf = OGF_LE_CTL;
+ rq.ocf = OCF_LE_CREATE_CONN_CANCEL;
+ rq.rparam = &status;
+ rq.rlen = 1;
+
+ if (hci_send_req(&rq, FALSE) < 0)
+ return BLE_STATUS_TIMEOUT;
+
+ return status;
+}
+
int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16])
{
struct hci_request rq;
--- a/source/bluenrg-hci/hci/hci_dma_lp.c Tue Apr 26 14:44:54 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1194 +0,0 @@
-/**
- ******************************************************************************
- * @file hci_dma_lp.c
- * @author AMS/HESA Application Team
- * @brief Function for managing HCI interface.
- ******************************************************************************
- *
- *
- * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
- * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
- * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
- * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
- * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
- * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
- *
- * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
- */
-
-// ANDREA -- FIXME: to exclude from building when DMA is disabled
-#ifdef __DMA_LP__
-
-#include "hal_types.h"
-#include "osal.h"
-#include "ble_status.h"
-#include "hal.h"
-#include "hci_const.h"
-#include "gp_timer.h"
-
-#include "bluenrg_interface.h"
-#include "stm32xx_timerserver.h"
-
-extern SPI_HandleTypeDef SpiHandle;
-
-#if BLE_CONFIG_DBG_ENABLE
-#define PRINTF(...) printf(__VA_ARGS__)
-#else
-#define PRINTF(...)
-#endif
-
-#define HCI_LOG_ON 0
-
-#define HCI_READ_PACKET_NUM_MAX (5)
-
-#define MIN(a,b) ((a) < (b) )? (a) : (b)
-#define MAX(a,b) ((a) > (b) )? (a) : (b)
-
-static void enqueue_packet(tHciDataPacket * hciReadPacket);
-static void hci_timeout_callback(void);
-
-tListNode hciReadPktPool;
-tListNode hciReadPktRxQueue;
-/* pool of hci read packets */
-static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX];
-
-static volatile uint8_t readPacketListFull=FALSE;
-
-static uint8_t *hci_buffer = NULL;
-static volatile uint16_t hci_pckt_len;
-static volatile uint8_t hci_timer_id;
-static volatile uint8_t hci_timeout;
-
-uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE];
-
-void hci_timeout_callback(void)
-{
- hci_timeout = 1;
-
- return;
-}
-
-void HCI_Init(void)
-{
- uint8_t index;
-
- /* Initialize list heads of ready and free hci data packet queues */
- list_init_head (&hciReadPktPool);
- list_init_head (&hciReadPktRxQueue);
-
- /* Initialize the queue of free hci data packets */
- for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++)
- {
- list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]);
- }
-}
-
-#define HCI_PCK_TYPE_OFFSET 0
-#define EVENT_PARAMETER_TOT_LEN_OFFSET 2
-
-void Hal_Init_Event_Request(void)
-{
- tHciDataPacket * hciReadPacket = NULL;
-
- list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket);
-
- Hal_Event_Request ((uint8_t*)hciReadPacket, HCI_READ_PACKET_SIZE);
-}
-
-static volatile hci_packet_complete_callback packet_complete_callback = NULL;
-
-static void hci_set_packet_complete_callback(hci_packet_complete_callback cb)
-{
- packet_complete_callback = cb;
-}
-
-void HCI_Input(tHciDataPacket * hciReadPacket)
-{
- uint8_t byte;
- hci_acl_hdr *acl_hdr;
-
- static hci_state state = WAITING_TYPE;
-
- uint16_t collected_payload_len = 0;
- uint16_t payload_len;
-
- hci_buffer = hciReadPacket->dataBuff;
-
- if(state == WAITING_TYPE)
- hci_pckt_len = 0;
-
- while(hci_pckt_len < HCI_READ_PACKET_SIZE){
-
- byte = hci_buffer[hci_pckt_len++];
-
- if(state == WAITING_TYPE){
- /* Only ACL Data and Events packets are accepted. */
- if(byte == HCI_EVENT_PKT){
- state = WAITING_EVENT_CODE;
- }
-// else if(byte == HCI_ACLDATA_PKT){
-// state = WAITING_HANDLE;
-// }
- else{
- /* Incorrect type. Reset state machine. */
- state = WAITING_TYPE;
- break;
- }
- }
- else if(state == WAITING_EVENT_CODE)
- state = WAITING_PARAM_LEN;
- else if(state == WAITING_HANDLE)
- state = WAITING_HANDLE_FLAG;
- else if(state == WAITING_HANDLE_FLAG)
- state = WAITING_DATA_LEN1;
- else if(state == WAITING_DATA_LEN1)
- state = WAITING_DATA_LEN2;
-
- else if(state == WAITING_DATA_LEN2){
- acl_hdr = (void *)&hci_buffer[HCI_HDR_SIZE];
- payload_len = acl_hdr->dlen;
- collected_payload_len = 0;
- state = WAITING_PAYLOAD;
- }
- else if(state == WAITING_PARAM_LEN){
- payload_len = byte;
- collected_payload_len = 0;
- state = WAITING_PAYLOAD;
- }
- else if(state == WAITING_PAYLOAD){
- collected_payload_len += 1;
- if(collected_payload_len >= payload_len){
- /* Reset state machine. */
- state = WAITING_TYPE;
- enqueue_packet(hciReadPacket);
-
- if(packet_complete_callback){
- uint16_t len = hci_pckt_len;
- packet_complete_callback(hci_buffer, len);
- }
- break;
- }
- }
- }
-}
-
-void enqueue_packet(tHciDataPacket * hciReadPacket)
-{
- hci_uart_pckt *hci_pckt = (void*)hciReadPacket->dataBuff;
- hci_event_pckt *event_pckt = (void*)hci_pckt->data;
-
- // Do not enqueue Command Complete or Command Status events
-
- if((hci_pckt->type != HCI_EVENT_PKT) ||
- event_pckt->evt == EVT_CMD_COMPLETE ||
- event_pckt->evt == EVT_CMD_STATUS){
- // Insert the packet back into the pool.
- list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket);
- }
- else {
- // Insert the packet into the queue of events to be processed.
- list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket);
- HCI_Process_Notification_Request();
- }
-}
-
-void HCI_Process(void)
-{
- //uint8_t data_len;
- //uint8_t buffer[HCI_PACKET_SIZE];
- tHciDataPacket * hciReadPacket = NULL;
-
- uint8_t list_empty = list_is_empty(&hciReadPktRxQueue);
- /* process any pending events read */
- while(list_empty == FALSE)
- {
- list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket);
- HCI_Event_CB(hciReadPacket->dataBuff);
- list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket);
- list_empty = list_is_empty(&hciReadPktRxQueue);
- }
-}
-
-BOOL HCI_Queue_Empty(void)
-{
- return list_is_empty(&hciReadPktRxQueue);
-}
-
-void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len)
-{
- tHciDataPacket * hciReadPacket = NULL;
-
- if (list_is_empty (&hciReadPktPool) == FALSE){
-
- list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket);
-
- Hal_Event_Request ((uint8_t*)hciReadPacket, HCI_READ_PACKET_SIZE);
- }
-
- if(event_payload_len > 0){
-
- HCI_Input((tHciDataPacket*)buffer);
- // Packet will be inserted to te correct queue by
- }
- else {
- // Insert the packet back into the pool.
- list_insert_head(&hciReadPktPool, (tListNode*)buffer);
- }
-}
-
-void hci_write(const void* data1, const void* data2, uint16_t n_bytes1, uint16_t n_bytes2){
-#if HCI_LOG_ON
- PRINTF("HCI <- ");
- for(int i=0; i < n_bytes1; i++)
- PRINTF("%02X ", *((uint8_t*)data1 + i));
- for(int i=0; i < n_bytes2; i++)
- PRINTF("%02X ", *((uint8_t*)data2 + i));
- PRINTF("\n");
-#endif
-
- Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2);
-}
-
-void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param)
-{
- hci_command_hdr hc;
-
- hc.opcode = htobs(cmd_opcode_pack(ogf, ocf));
- hc.plen= plen;
-
- //uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE];
- header[0] = HCI_COMMAND_PKT;
- Osal_MemCpy(header+1, &hc, sizeof(hc));
-
- hci_write(header, param, sizeof(header), plen);
-}
-
-static uint8_t new_packet;
-
-void new_hci_event(void *pckt, uint16_t len)
-{
-
- new_packet = TRUE;
-}
-
-/**
- * FIXME: Param async is unused, it has been introduced to align the interface
- * to DK 1.6.0 HCI stack
- */
-/* 'to' is timeout in system clock ticks. */
-int hci_send_req(struct hci_request *r, BOOL async)
-{
- uint8_t *ptr;
- uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf));
- hci_event_pckt *event_pckt;
- hci_uart_pckt *hci_hdr;
- int try;
- uint32_t to = DEFAULT_TIMEOUT;
-
- new_packet = FALSE;
- HCI_Cmd_Status(BUSY);
- hci_set_packet_complete_callback(new_hci_event);
- hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam);
-
- try = 10;
- while (try--) {
- evt_cmd_complete *cc;
- evt_cmd_status *cs;
- evt_le_meta_event *me;
- int len;
-
- /* Minimum timeout is 1. */
- if(to == 0)
- to = 1;
-
- hci_timeout = 0;
- Blue_NRG_HCI_Timer_Start(to, hci_timeout_callback, (uint8_t*)&hci_timer_id);
-
- while(1){
- if(hci_timeout){
- Blue_NRG_HCI_Timer_Stop(hci_timer_id);
- goto failed;
- }
- if(new_packet){
- Blue_NRG_HCI_Timer_Stop(hci_timer_id);
- break;
- }
- HCI_Wait_For_Response();
- }
-
- hci_hdr = (void *)hci_buffer;
- if(hci_hdr->type != HCI_EVENT_PKT){
- new_packet = FALSE;
- continue;
- }
-
- event_pckt = (void *) (hci_hdr->data);
-
- ptr = hci_buffer + (1 + HCI_EVENT_HDR_SIZE);
- len = hci_pckt_len - (1 + HCI_EVENT_HDR_SIZE);
-
- switch (event_pckt->evt) {
-
- case EVT_CMD_STATUS:
- cs = (void *) ptr;
-
- if (cs->opcode != opcode)
- break;
-
- if (r->event != EVT_CMD_STATUS) {
- if (cs->status) {
- goto failed;
- }
- break;
- }
-
- r->rlen = MIN(len, r->rlen);
- Osal_MemCpy(r->rparam, ptr, r->rlen);
- goto done;
-
- case EVT_CMD_COMPLETE:
- cc = (void *) ptr;
-
- if (cc->opcode != opcode)
- break;
-
- ptr += EVT_CMD_COMPLETE_SIZE;
- len -= EVT_CMD_COMPLETE_SIZE;
-
- r->rlen = MIN(len, r->rlen);
- Osal_MemCpy(r->rparam, ptr, r->rlen);
- goto done;
-
- case EVT_LE_META_EVENT:
- me = (void *) ptr;
-
- if (me->subevent != r->event)
- break;
-
- len -= 1;
- r->rlen = MIN(len, r->rlen);
- Osal_MemCpy(r->rparam, me->data, r->rlen);
- goto done;
-
- case EVT_HARDWARE_ERROR:
- goto failed;
-
- default:
- break; // In the meantime there could be other events from the controller.
- }
-
- new_packet = FALSE;
-
- }
-
-failed:
- hci_set_packet_complete_callback(NULL);
- return -1;
-
-done:
- hci_set_packet_complete_callback(NULL);
- HCI_Cmd_Status(AVAILABLE);
- return 0;
-}
-
-int hci_reset()
-{
- struct hci_request rq;
- uint8_t status;
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_HOST_CTL;
- rq.ocf = OCF_RESET;
- rq.rparam = &status;
- rq.rlen = 1;
-
- if (hci_send_req(&rq, FALSE) < 0)
- return -1;
-
- if (status) {
- return -1;
- }
-
- return 0;
-}
-
-int hci_disconnect(uint16_t handle, uint8_t reason)
-{
- struct hci_request rq;
- disconnect_cp cp;
- uint8_t status;
-
- cp.handle = handle;
- cp.reason = reason;
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LINK_CTL;
- rq.ocf = OCF_DISCONNECT;
- rq.cparam = &cp;
- rq.clen = DISCONNECT_CP_SIZE;
- rq.event = EVT_CMD_STATUS;
- rq.rparam = &status;
- rq.rlen = 1;
-
- if (hci_send_req(&rq, FALSE) < 0)
- return -1;
-
- if (status) {
- return -1;
- }
-
- return 0;
-}
-
-int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version,
- uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion)
-{
- struct hci_request rq;
- read_local_version_rp resp;
-
- Osal_MemSet(&resp, 0, sizeof(resp));
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_INFO_PARAM;
- rq.ocf = OCF_READ_LOCAL_VERSION;
- rq.cparam = NULL;
- rq.clen = 0;
- rq.rparam = &resp;
- rq.rlen = READ_LOCAL_VERSION_RP_SIZE;
-
- if (hci_send_req(&rq, FALSE) < 0)
- return -1;
-
- if (resp.status) {
- return -1;
- }
-
-
- *hci_version = resp.hci_version;
- *hci_revision = btohs(resp.hci_revision);
- *lmp_pal_version = resp.lmp_pal_version;
- *manufacturer_name = btohs(resp.manufacturer_name);
- *lmp_pal_subversion = btohs(resp.lmp_pal_subversion);
-
- return 0;
-}
-
-int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt)
-{
- struct hci_request rq;
- le_read_buffer_size_rp resp;
-
- Osal_MemSet(&resp, 0, sizeof(resp));
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_READ_BUFFER_SIZE;
- rq.cparam = NULL;
- rq.clen = 0;
- rq.rparam = &resp;
- rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE;
-
- if (hci_send_req(&rq, FALSE) < 0)
- return -1;
-
- if (resp.status) {
- return -1;
- }
-
- *pkt_len = resp.pkt_len;
- *max_pkt = resp.max_pkt;
-
- return 0;
-}
-
-int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype,
- uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map,
- uint8_t filter)
-{
- struct hci_request rq;
- le_set_adv_parameters_cp adv_cp;
- uint8_t status;
-
- Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
- adv_cp.min_interval = min_interval;
- adv_cp.max_interval = max_interval;
- adv_cp.advtype = advtype;
- adv_cp.own_bdaddr_type = own_bdaddr_type;
- adv_cp.direct_bdaddr_type = direct_bdaddr_type;
- Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr));
- adv_cp.chan_map = chan_map;
- adv_cp.filter = filter;
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_SET_ADV_PARAMETERS;
- rq.cparam = &adv_cp;
- rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE;
- rq.rparam = &status;
- rq.rlen = 1;
-
- if (hci_send_req(&rq, FALSE) < 0)
- return -1;
-
- if (status) {
- return -1;
- }
-
- return 0;
-}
-
-int hci_le_set_advertising_data(uint8_t length, const uint8_t data[])
-{
- struct hci_request rq;
- le_set_adv_data_cp adv_cp;
- uint8_t status;
-
- Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
- adv_cp.length = length;
- Osal_MemCpy(adv_cp.data, data, MIN(31,length));
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_SET_ADV_DATA;
- rq.cparam = &adv_cp;
- rq.clen = LE_SET_ADV_DATA_CP_SIZE;
- rq.rparam = &status;
- rq.rlen = 1;
-
- if (hci_send_req(&rq, FALSE) < 0)
- return -1;
-
- if (status) {
- return -1;
- }
-
- return 0;
-}
-
-int hci_le_set_advertise_enable(uint8_t enable)
-{
- struct hci_request rq;
- le_set_advertise_enable_cp adv_cp;
- uint8_t status;
-
- Osal_MemSet(&adv_cp, 0, sizeof(adv_cp));
- adv_cp.enable = enable?1:0;
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE;
- rq.cparam = &adv_cp;
- rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE;
- rq.rparam = &status;
- rq.rlen = 1;
-
- if (hci_send_req(&rq, FALSE) < 0)
- return -1;
-
- if (status) {
- return -1;
- }
-
- return 0;
-}
-
-int hci_le_rand(uint8_t random_number[8])
-{
- struct hci_request rq;
- le_rand_rp resp;
-
- Osal_MemSet(&resp, 0, sizeof(resp));
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_RAND;
- rq.cparam = NULL;
- rq.clen = 0;
- rq.rparam = &resp;
- rq.rlen = LE_RAND_RP_SIZE;
-
- if (hci_send_req(&rq, FALSE) < 0)
- return -1;
-
- if (resp.status) {
- return -1;
- }
-
- Osal_MemCpy(random_number, resp.random, 8);
-
- return 0;
-}
-
-int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[])
-{
- struct hci_request rq;
- le_set_scan_response_data_cp scan_resp_cp;
- uint8_t status;
-
- Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp));
- scan_resp_cp.length = length;
- Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length));
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA;
- rq.cparam = &scan_resp_cp;
- rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE;
- rq.rparam = &status;
- rq.rlen = 1;
-
- if (hci_send_req(&rq, FALSE) < 0)
- return -1;
-
- if (status) {
- return -1;
- }
-
- return 0;
-}
-
-int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level)
-{
- struct hci_request rq;
- le_read_adv_channel_tx_power_rp resp;
-
- Osal_MemSet(&resp, 0, sizeof(resp));
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER;
- rq.cparam = NULL;
- rq.clen = 0;
- rq.rparam = &resp;
- rq.rlen = LE_RAND_RP_SIZE;
-
- if (hci_send_req(&rq, FALSE) < 0)
- return -1;
-
- if (resp.status) {
- return -1;
- }
-
- *tx_power_level = resp.level;
-
- return 0;
-}
-
-int hci_le_set_random_address(tBDAddr bdaddr)
-{
- struct hci_request rq;
- le_set_random_address_cp set_rand_addr_cp;
- uint8_t status;
-
- Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp));
- Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr));
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_SET_RANDOM_ADDRESS;
- rq.cparam = &set_rand_addr_cp;
- rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE;
- rq.rparam = &status;
- rq.rlen = 1;
-
- if (hci_send_req(&rq, FALSE) < 0)
- return -1;
-
- if (status) {
- return -1;
- }
-
- return 0;
-}
-
-int hci_read_bd_addr(tBDAddr bdaddr)
-{
- struct hci_request rq;
- read_bd_addr_rp resp;
-
- Osal_MemSet(&resp, 0, sizeof(resp));
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_INFO_PARAM;
- rq.ocf = OCF_READ_BD_ADDR;
- rq.cparam = NULL;
- rq.clen = 0;
- rq.rparam = &resp;
- rq.rlen = READ_BD_ADDR_RP_SIZE;
-
- if (hci_send_req(&rq, FALSE) < 0)
- return -1;
-
- if (resp.status) {
- return -1;
- }
- Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr));
-
- return 0;
-}
-
-int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type,
- const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval,
- uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length)
-{
- struct hci_request rq;
- le_create_connection_cp create_cp;
- uint8_t status;
-
- Osal_MemSet(&create_cp, 0, sizeof(create_cp));
- create_cp.interval = interval;
- create_cp.window = window;
- create_cp.initiator_filter = initiator_filter;
- create_cp.peer_bdaddr_type = peer_bdaddr_type;
- Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr));
- create_cp.own_bdaddr_type = own_bdaddr_type;
- create_cp.min_interval=min_interval;
- create_cp.max_interval=max_interval;
- create_cp.latency = latency;
- create_cp.supervision_timeout=supervision_timeout;
- create_cp.min_ce_length=min_ce_length;
- create_cp.max_ce_length=max_ce_length;
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_CREATE_CONN;
- rq.cparam = &create_cp;
- rq.clen = LE_CREATE_CONN_CP_SIZE;
- rq.event = EVT_CMD_STATUS;
- rq.rparam = &status;
- rq.rlen = 1;
-
- if (hci_send_req(&rq, FALSE) < 0)
- return -1;
-
- if (status) {
- return -1;
- }
-
- return 0;
-}
-
-int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16])
-{
- struct hci_request rq;
- le_encrypt_cp params;
- le_encrypt_rp resp;
-
- Osal_MemSet(&resp, 0, sizeof(resp));
-
- Osal_MemCpy(params.key, key, 16);
- Osal_MemCpy(params.plaintext, plaintextData, 16);
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_ENCRYPT;
- rq.cparam = ¶ms;
- rq.clen = LE_ENCRYPT_CP_SIZE;
- rq.rparam = &resp;
- rq.rlen = LE_ENCRYPT_RP_SIZE;
-
- if (hci_send_req(&rq, FALSE) < 0){
- return -1;
- }
-
- if (resp.status) {
- return -1;
- }
-
- Osal_MemCpy(encryptedData, resp.encdata, 16);
-
- return 0;
-}
-
-int hci_le_ltk_request_reply(uint8_t key[16])
-{
- struct hci_request rq;
- le_ltk_reply_cp params;
- le_ltk_reply_rp resp;
-
- Osal_MemSet(&resp, 0, sizeof(resp));
-
- params.handle = 1;
- Osal_MemCpy(params.key, key, 16);
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_LTK_REPLY;
- rq.cparam = ¶ms;
- rq.clen = LE_LTK_REPLY_CP_SIZE;
- rq.rparam = &resp;
- rq.rlen = LE_LTK_REPLY_RP_SIZE;
-
- if (hci_send_req(&rq, FALSE) < 0)
- return -1;
-
- if (resp.status) {
- return -1;
- }
-
- return 0;
-}
-
-int hci_le_ltk_request_neg_reply()
-{
- struct hci_request rq;
- le_ltk_neg_reply_cp params;
- le_ltk_neg_reply_rp resp;
-
- Osal_MemSet(&resp, 0, sizeof(resp));
-
- params.handle = 1;
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_LTK_NEG_REPLY;
- rq.cparam = ¶ms;
- rq.clen = LE_LTK_NEG_REPLY_CP_SIZE;
- rq.rparam = &resp;
- rq.rlen = LE_LTK_NEG_REPLY_RP_SIZE;
-
- if (hci_send_req(&rq, FALSE) < 0)
- return -1;
-
- if (resp.status) {
- return -1;
- }
-
- return 0;
-}
-
-int hci_le_read_white_list_size(uint8_t *size)
-{
- struct hci_request rq;
- le_read_white_list_size_rp resp;
-
- Osal_MemSet(&resp, 0, sizeof(resp));
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_READ_WHITE_LIST_SIZE;
- rq.rparam = &resp;
- rq.rlen = LE_READ_WHITE_LIST_SIZE_RP_SIZE;
-
- if (hci_send_req(&rq, FALSE) < 0){
- return -1;
- }
-
- if (resp.status) {
- return -1;
- }
-
- *size = resp.size;
-
- return 0;
-}
-
-int hci_le_clear_white_list()
-{
- struct hci_request rq;
- uint8_t status;
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_CLEAR_WHITE_LIST;
- rq.rparam = &status;
- rq.rlen = 1;
-
- if (hci_send_req(&rq, FALSE) < 0){
- return -1;
- }
-
- if (status) {
- return -1;
- }
-
- return 0;
-}
-
-int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr)
-{
- struct hci_request rq;
- le_add_device_to_white_list_cp params;
- uint8_t status;
-
- params.bdaddr_type = bdaddr_type;
- Osal_MemCpy(params.bdaddr, bdaddr, 6);
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST;
- rq.cparam = ¶ms;
- rq.clen = LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE;
- rq.rparam = &status;
- rq.rlen = 1;
-
- if (hci_send_req(&rq, FALSE) < 0){
- return -1;
- }
-
- if (status) {
- return -1;
- }
-
- return 0;
-}
-
-int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr)
-{
- struct hci_request rq;
- le_remove_device_from_white_list_cp params;
- uint8_t status;
-
- params.bdaddr_type = bdaddr_type;
- Osal_MemCpy(params.bdaddr, bdaddr, 6);
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST;
- rq.cparam = ¶ms;
- rq.clen = LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE;
- rq.rparam = &status;
- rq.rlen = 1;
-
- if (hci_send_req(&rq, FALSE) < 0){
- return -1;
- }
-
- if (status) {
- return -1;
- }
-
- return 0;
-}
-
-int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level)
-{
- struct hci_request rq;
- read_transmit_power_level_cp params;
- read_transmit_power_level_rp resp;
-
- Osal_MemSet(&resp, 0, sizeof(resp));
-
- params.handle = *conn_handle;
- params.type = type;
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_HOST_CTL;
- rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL;
- rq.cparam = ¶ms;
- rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE;
- rq.rparam = &resp;
- rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE;
-
- if (hci_send_req(&rq, FALSE) < 0){
- return -1;
- }
-
- if (resp.status) {
- return -1;
- }
-
- *conn_handle = resp.handle;
- *tx_level = resp.level;
-
- return 0;
-}
-
-int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi)
-{
- struct hci_request rq;
- read_rssi_cp params;
- read_rssi_rp resp;
-
- Osal_MemSet(&resp, 0, sizeof(resp));
-
- params.handle = *conn_handle;
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_STATUS_PARAM;
- rq.ocf = OCF_READ_RSSI;
- rq.cparam = ¶ms;
- rq.clen = READ_RSSI_CP_SIZE;
- rq.rparam = &resp;
- rq.rlen = READ_RSSI_RP_SIZE;
-
- if (hci_send_req(&rq, FALSE) < 0){
- return -1;
- }
-
- if (resp.status) {
- return -1;
- }
-
- *conn_handle = resp.handle;
- *rssi = resp.rssi;
-
- return 0;
-}
-
-int hci_le_read_local_supported_features(uint8_t *features)
-{
- struct hci_request rq;
- le_read_local_supported_features_rp resp;
-
- Osal_MemSet(&resp, 0, sizeof(resp));
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_READ_LOCAL_SUPPORTED_FEATURES;
- rq.rparam = &resp;
- rq.rlen = LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE;
-
- if (hci_send_req(&rq, FALSE) < 0){
- return -1;
- }
-
- if (resp.status) {
- return -1;
- }
-
- Osal_MemCpy(features, resp.features, sizeof(resp.features));
-
- return 0;
-}
-
-int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5])
-{
- struct hci_request rq;
- le_read_channel_map_cp params;
- le_read_channel_map_rp resp;
-
- Osal_MemSet(&resp, 0, sizeof(resp));
-
- params.handle = conn_handle;
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_READ_CHANNEL_MAP;
- rq.cparam = ¶ms;
- rq.clen = LE_READ_CHANNEL_MAP_CP_SIZE;
- rq.rparam = &resp;
- rq.rlen = LE_READ_CHANNEL_MAP_RP_SIZE;
-
- if (hci_send_req(&rq, FALSE) < 0){
- return -1;
- }
-
- if (resp.status) {
- return -1;
- }
-
- Osal_MemCpy(ch_map, resp.map, 5);
-
- return 0;
-}
-
-int hci_le_read_supported_states(uint8_t states[8])
-{
- struct hci_request rq;
- le_read_supported_states_rp resp;
-
- Osal_MemSet(&resp, 0, sizeof(resp));
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_READ_SUPPORTED_STATES;
- rq.rparam = &resp;
- rq.rlen = LE_READ_SUPPORTED_STATES_RP_SIZE;
-
- if (hci_send_req(&rq, FALSE) < 0){
- return -1;
- }
-
- if (resp.status) {
- return -1;
- }
-
- Osal_MemCpy(states, resp.states, 8);
-
- return 0;
-}
-
-int hci_le_receiver_test(uint8_t frequency)
-{
- struct hci_request rq;
- le_receiver_test_cp params;
- uint8_t status;
-
- params.frequency = frequency;
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_RECEIVER_TEST;
- rq.cparam = ¶ms;
- rq.clen = LE_RECEIVER_TEST_CP_SIZE;
- rq.rparam = &status;
- rq.rlen = 1;
-
- if (hci_send_req(&rq, FALSE) < 0){
- return -1;
- }
-
- if (status) {
- return -1;
- }
-
- return 0;
-}
-
-int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload)
-{
- struct hci_request rq;
- le_transmitter_test_cp params;
- uint8_t status;
-
- params.frequency = frequency;
- params.length = length;
- params.payload = payload;
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_TRANSMITTER_TEST;
- rq.cparam = ¶ms;
- rq.clen = LE_TRANSMITTER_TEST_CP_SIZE;
- rq.rparam = &status;
- rq.rlen = 1;
-
- if (hci_send_req(&rq, FALSE) < 0){
- return -1;
- }
-
- if (status) {
- return -1;
- }
-
- return 0;
-}
-
-int hci_le_test_end(uint16_t *num_pkts)
-{
- struct hci_request rq;
- le_test_end_rp resp;
-
- Osal_MemSet(&resp, 0, sizeof(resp));
-
- Osal_MemSet(&rq, 0, sizeof(rq));
- rq.ogf = OGF_LE_CTL;
- rq.ocf = OCF_LE_TEST_END;
- rq.rparam = &resp;
- rq.rlen = LE_TEST_END_RP_SIZE;
-
- if (hci_send_req(&rq, FALSE) < 0){
- return -1;
- }
-
- if (resp.status) {
- return -1;
- }
-
- *num_pkts = resp.num_pkts;
-
- return 0;
-}
-
-#endif /* __DMA_LP__ */
\ No newline at end of file
--- a/source/platform/btle.cpp Tue Apr 26 14:44:54 2016 +0200
+++ b/source/platform/btle.cpp Mon May 16 17:22:03 2016 +0200
@@ -48,7 +48,6 @@
/* C File Includes ------------------------------------------------------------------*/
-// ANDREA: Updated includes and changed some types (e.g., tHalUint8 --> uint8_t)
#include <stdio.h>
#include <string.h>
#include "hci.h"
@@ -100,6 +99,8 @@
void btleInit(bool isSetAddress, uint8_t role)
{
PRINTF("btleInit>>\n\r");
+ /* Avoid compiler warnings about unused variables. */
+ (void)isSetAddress;
int ret;
uint8_t hwVersion;
@@ -143,7 +144,6 @@
/* The Nucleo board must be configured as SERVER */
//check if isSetAddress is set then set address.
- // ANDREA
#if 0
if(isSetAddress)
{
@@ -165,13 +165,21 @@
BLE_address_BE);
}
#endif
+
+ const Gap::Address_t BLE_address_BE = {0xFD,0x66,0x05,0x13,0xBE,0xBA};
+ BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::RANDOM_STATIC, BLE_address_BE);
ret = aci_gatt_init();
if(ret){
PRINTF("GATT_Init failed.\n");
}
if (bnrg_expansion_board == IDB05A1) {
- ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1|GAP_CENTRAL_ROLE_IDB05A1|GAP_OBSERVER_ROLE_IDB05A1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle);
+ ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1|GAP_CENTRAL_ROLE_IDB05A1|GAP_OBSERVER_ROLE_IDB05A1,
+ 0,
+ 0x18,
+ &service_handle,
+ &dev_name_char_handle,
+ &appearance_char_handle);
} else {
ret = aci_gap_init_IDB04A1(role, &service_handle, &dev_name_char_handle, &appearance_char_handle);
}
@@ -180,7 +188,7 @@
PRINTF("GAP_Init failed.\n");
}
- //ANDREA -- FIXME: Security and passkey set by default
+ //FIXME: Security and passkey set by default
ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED,
OOB_AUTH_DATA_ABSENT,
NULL,
@@ -202,7 +210,6 @@
/*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0,
strlen(name), (tHalUint8 *)name);*/
- // Andrea: mbedOS
#ifdef AST_FOR_MBED_OS
minar::Scheduler::postCallback(btle_handler);
#endif
@@ -211,7 +218,7 @@
/**************************************************************************/
/*!
- @brief Andrea: mbedOS
+ @brief mbedOS
@param[in] void
@@ -282,20 +289,43 @@
return;
}
-void Attribute_Modified_CB(uint16_t attr_handle, uint8_t data_length, uint8_t *att_data, uint8_t offset)
-{
+void Attribute_Modified_CB(evt_blue_aci *blue_evt)
+{
+ uint16_t conn_handle;
+ uint16_t attr_handle;
+ uint8_t data_length;
+ uint8_t *att_data;
+ uint8_t offset;
+
+ if (bnrg_expansion_board == IDB05A1) {
+ evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data;
+ conn_handle = evt->conn_handle;
+ attr_handle = evt->attr_handle;
+ data_length = evt->data_length;
+ att_data = evt->att_data;
+ offset = evt->offset;
+ } else {
+ evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data;
+ conn_handle = evt->conn_handle;
+ attr_handle = evt->attr_handle;
+ data_length = evt->data_length;
+ att_data = evt->att_data;
+ offset = 0;
+ }
+
//Extract the GattCharacteristic from p_characteristics[] and find the properties mask
GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(attr_handle);
if(p_char!=NULL) {
- GattAttribute::Handle_t charHandle = p_char->getValueAttribute().getHandle();
+ GattAttribute::Handle_t charHandle = p_char->getValueAttribute().getHandle()-BlueNRGGattServer::CHAR_VALUE_HANDLE;
BlueNRGGattServer::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE;
PRINTF("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]);
PRINTF("getProperties 0x%x\n\r",p_char->getProperties());
- if(attr_handle == charHandle+CHAR_VALUE_OFFSET) {
+
+ if(attr_handle == charHandle+BlueNRGGattServer::CHAR_VALUE_HANDLE) {
currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE;
}
- if(attr_handle == charHandle+CHAR_DESC_OFFSET) {
+ if(attr_handle == charHandle+BlueNRGGattServer::CHAR_DESC_HANDLE) {
currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE;
}
PRINTF("currentHandle %d\n\r", currentHandle);
@@ -303,18 +333,20 @@
(GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) &&
currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) {
+ GattAttribute::Handle_t charDescHandle = p_char->getValueAttribute().getHandle()+1;
+
PRINTF("*****NOTIFICATION CASE\n\r");
//Now Check if data written in Enable or Disable
if((uint16_t)att_data[0]==1) {
//PRINTF("Notify ENABLED\n\r");
- BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, p_char->getValueAttribute().getHandle());
+ BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, charDescHandle);
} else {
//PRINTF("Notify DISABLED\n\r");
- BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, p_char->getValueAttribute().getHandle());
+ BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, charDescHandle);
}
}
- //Check is attr handle property is WRITEABLE, if yes, generate GATT_EVENT_DATA_WRITTEN Event
+ //Check if attr handle property is WRITEABLE, in the case generate GATT_EVENT_DATA_WRITTEN Event
if((p_char->getProperties() &
(GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE)) &&
currentHandle == BlueNRGGattServer::CHAR_VALUE_HANDLE) {
@@ -322,21 +354,22 @@
PRINTF("*****WRITE CASE\n\r");
GattWriteCallbackParams writeParams;
+ writeParams.connHandle = conn_handle;
writeParams.handle = p_char->getValueAttribute().getHandle();
writeParams.writeOp = GattWriteCallbackParams::OP_WRITE_REQ;//Where to find this property in BLUENRG?
writeParams.len = data_length;
- writeParams.data = att_data;
- if (bnrg_expansion_board == IDB05A1) {
- writeParams.offset = offset;
- } else {
- writeParams.offset = 0;
- }
+ writeParams.data = att_data;
+ writeParams.offset = offset;
+
BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams);
- //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, evt->attr_handle);
+ //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, attr_handle);
//Write the actual Data to the Attr Handle? (uint8_1[])att_data contains the data
if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getLength() > 0)) {
- BlueNRGGattServer::getInstance().write(p_char->getValueAttribute().getHandle(), (uint8_t*)att_data, data_length, false);
+ BlueNRGGattServer::getInstance().write(p_char->getValueAttribute().getHandle(),
+ (uint8_t*)att_data,
+ data_length,
+ false);
}
}
}
@@ -383,7 +416,7 @@
evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data;
switch(evt->subevent){
- // ANDREA
+
case EVT_LE_CONN_COMPLETE:
{
PRINTF("EVT_LE_CONN_COMPLETE\n");
@@ -448,7 +481,7 @@
BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND,
pr->evt_type,
- &pr->bdaddr_type,
+ pr->bdaddr_type,
pr->bdaddr,
&pr->data_length,
&pr->data_RSSI[0],
@@ -469,7 +502,8 @@
{
PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK\n\r");
evt_gatt_read_permit_req *pr = (evt_gatt_read_permit_req*)blue_evt->data;
- BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle-CHAR_VALUE_OFFSET);
+ PRINTF("EVT_BLUE_GATT_READ_PERMIT_REQ_OK pr->attr_handle=%u\n\r", pr->attr_handle);
+ BlueNRGGattServer::getInstance().Read_Request_CB(pr->attr_handle);
}
break;
@@ -478,13 +512,7 @@
PRINTF("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r");
/* this callback is invoked when a GATT attribute is modified
extract callback data and pass to suitable handler function */
- if (bnrg_expansion_board == IDB05A1) {
- evt_gatt_attr_modified_IDB05A1 *evt = (evt_gatt_attr_modified_IDB05A1*)blue_evt->data;
- Attribute_Modified_CB(evt->attr_handle, evt->data_length, evt->att_data, evt->offset);
- } else {
- evt_gatt_attr_modified_IDB04A1 *evt = (evt_gatt_attr_modified_IDB04A1*)blue_evt->data;
- Attribute_Modified_CB(evt->attr_handle, evt->data_length, evt->att_data, 0);
- }
+ Attribute_Modified_CB(blue_evt);
}
break;
@@ -565,7 +593,17 @@
pr->handles_info_list);
}
break;
- case EVT_BLUE_GATT_PROCEDURE_COMPLETE:
+ case EVT_BLUE_ATT_FIND_INFORMATION_RESP:
+ {
+ PRINTF("EVT_BLUE_ATT_FIND_INFORMATION_RESP\n\r");
+ evt_att_find_information_resp *pr = (evt_att_find_information_resp*)blue_evt->data;
+ BlueNRGGattClient::getInstance().discAllCharacDescCB(pr->conn_handle,
+ pr->event_data_length,
+ pr->format,
+ pr->handle_uuid_pair);
+ }
+ break;
+ case EVT_BLUE_GATT_PROCEDURE_COMPLETE:
{
//PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE\n\r");
evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data;
@@ -582,7 +620,7 @@
BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND,
pr->evt_type,
- &pr->bdaddr_type,
+ pr->bdaddr_type,
pr->bdaddr,
&pr->data_length,
&pr->data_RSSI[0],
@@ -593,12 +631,12 @@
case EVT_BLUE_GAP_PROCEDURE_COMPLETE:
{
evt_gap_procedure_complete *pr = (evt_gap_procedure_complete*)blue_evt->data;
- //printf("EVT_BLUE_GAP_PROCEDURE_COMPLETE (code=0x%02X)\n\r", pr->procedure_code);
+ //PRINTF("EVT_BLUE_GAP_PROCEDURE_COMPLETE (code=0x%02X)\n\r", pr->procedure_code);
switch(pr->procedure_code) {
case GAP_OBSERVATION_PROC_IDB05A1:
- BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, NULL, NULL, NULL, NULL, NULL);
+ BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, 0, NULL, NULL, NULL, NULL);
break;
}
}
--- a/source/platform/stm32_bluenrg_ble_dma_lp.c Tue Apr 26 14:44:54 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,989 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32_bluenrg_ble_dma_lp.c
- * @author CL
- * @version V1.0.0
- * @date 04-July-2014
- * @brief
- ******************************************************************************
- * @attention
- *
- * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
-
-// ANDREA -- FIXME: to exclude from building when DMA is disabled
-#ifdef __DMA_LP__
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32_bluenrg_ble_dma_lp.h"
-#include "hci_const.h"
-
-/** @addtogroup BSP
- * @{
- */
-
-/** @addtogroup X-NUCLEO-IDB04A1
- * @{
- */
-
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP
- * @{
- */
-
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Defines
- * @{
- */
-
-#define TEST_TX_BUFFER_LIMITATION 0
-#define MAX_TX_BUFFER_SIZE 0x7F
-#define BLUENRG_READY_STATE 0x02
-
-#define HEADER_SIZE 5
-#define MAX_BUFFER_SIZE 255
-
-/**
- * @}
- */
-
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Types
-* @{
-*/
-
-typedef enum
-{
- SPI_HEADER_TRANSMIT,
- SPI_PAYLOAD_TRANSMIT
-} SPI_TRANSMIT_REQUEST_t;
-
-typedef enum
-{
- SPI_HEADER_TRANSMITTED,
- SPI_PAYLOAD_TRANSMITTED
-} SPI_TRANSMIT_EVENT_t;
-
-typedef enum
-{
- SPI_REQUEST_VALID_HEADER_FOR_RX,
- SPI_REQUEST_VALID_HEADER_FOR_TX,
- SPI_REQUEST_PAYLOAD
-} SPI_RECEIVE_REQUEST_t;
-
-typedef enum
-{
- SPI_CHECK_RECEIVED_HEADER_FOR_RX,
- SPI_CHECK_RECEIVED_HEADER_FOR_TX,
- SPI_RECEIVE_END
-} SPI_RECEIVE_EVENT_t;
-
-typedef enum
-{
- SPI_AVAILABLE,
- SPI_BUSY
-} SPI_PERIPHERAL_STATUS_t;
-
-typedef struct
-{
- SPI_TRANSMIT_EVENT_t Spi_Transmit_Event;
- uint8_t* header_data;
- uint8_t* payload_data;
- uint8_t header_size;
- uint8_t payload_size;
- uint8_t payload_size_to_transmit;
- uint8_t packet_cont;
- uint8_t RequestPending;
-} SPI_Transmit_Context_t;
-
-typedef struct
-{
- SPI_RECEIVE_EVENT_t Spi_Receive_Event;
- uint16_t payload_len;
- uint8_t* buffer;
- uint8_t buffer_size;
-} SPI_Receive_Context_t;
-
-typedef struct
-{
- SPI_HandleTypeDef *hspi;
- SPI_PERIPHERAL_STATUS_t Spi_Peripheral_State;
- SPI_Receive_Context_t SPI_Receive_Context;
- SPI_Transmit_Context_t SPI_Transmit_Context;
-} SPI_Context_t;
-
-/**
- * @}
- */
-
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Variables
- * @{
- */
-
-SPI_HandleTypeDef SpiHandle;
-SPI_Context_t SPI_Context;
-
-const uint8_t Write_Header_CMD[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00};
-const uint8_t Read_Header_CMD[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00};
-const uint8_t dummy_bytes = 0xFF;
-
-uint8_t Received_Header[HEADER_SIZE];
-
-#ifdef ENABLE_SPI_FIX
-static uint8_t StartupTimerId;
-#endif
-static uint8_t TxRxTimerId;
-volatile uint8_t ubnRFresetTimerLock;
-pf_TIMER_TimerCallBack_t pTimerTxRxCallback;
-
-/**
- * @}
- */
-
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Extern_Variables
- * @{
- */
-extern uint8_t* HCI_read_packet;
-
-/**
- * @}
- */
-
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Function_Prototypes
- * @{
- */
-
-/* Private function prototypes -----------------------------------------------*/
-static void SPI_Transmit_Manager(SPI_TRANSMIT_REQUEST_t TransmitRequest);
-static void SPI_Receive_Manager(SPI_RECEIVE_REQUEST_t ReceiveRequest);
-static void set_irq_as_output(void);
-static void set_irq_as_input(void);
-static void Disable_SPI_Receiving_Path(void);
-static void Enable_SPI_Receiving_Path(void);
-static void Enable_SPI_CS(void);
-static void Disable_SPI_CS(void);
-static void DisableEnable_SPI_CS(void);
-static void TransmitClosure(void);
-static void ReceiveClosure(void);
-static void ReceiveHeader(SPI_RECEIVE_EVENT_t ReceiveEvent, uint8_t * DataHeader);
-static void WakeupBlueNRG(void);
-static void TimerStartupCallback(void);
-static void TimerTransmitCallback(void);
-static void pf_nRFResetTimerCallBack(void);
-static void TimerTxRxCallback(void);
-static void ProcessEndOfReceive(void);
-
-/**
- * @}
- */
-
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Exported_Functions
- * @{
- */
-
-/**
- * @brief This function notify when then BlueNRG nRESET may be released
- * @param None
- * @retval None
- */
-static void pf_nRFResetTimerCallBack(void)
-{
- ubnRFresetTimerLock = 0;
-
- return;
-}
-
-/**
- * @brief Timer callback to handle RxTx Timers
- * @param None
- * @retval None
- */
-static void TimerTxRxCallback(void)
-{
- pTimerTxRxCallback();
-
- return;
-}
-
-/**
- * @brief Close the receiver path
- * @param None
- * @retval None
- */
-static void ReceiveClosure(void)
-{
- /*
- * Disable both DMA
- */
- __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx);
- __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx);
-
- /*
- * Check if a command is pending
- */
- __disable_irq();
- if(SPI_Context.SPI_Transmit_Context.RequestPending == TRUE)
- {
- SPI_Context.SPI_Transmit_Context.RequestPending = FALSE;
- SPI_Context.Spi_Peripheral_State = SPI_BUSY;
- Disable_SPI_Receiving_Path();
- __enable_irq();
- WakeupBlueNRG();
- }
- else
- {
- SPI_Context.Spi_Peripheral_State = SPI_AVAILABLE;
- __enable_irq();
- }
-
- return;
-}
-
-/**
- * @brief Delay Notification to the App to prevent dummy event read
- * @param None
- * @retval None
- */
-static void ProcessEndOfReceive(void)
-{
- ReceiveClosure();
-
- HCI_Isr(HCI_read_packet, SPI_Context.SPI_Receive_Context.payload_len);
-
- return;
-}
-
-/**
- * @brief Timer callback to apply timeout SPI FIX
- * @param None
- * @retval None
- */
-static void TimerTransmitCallback(void)
-{
- SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_TX); /**< BlueNRG not ready for writing */
- LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_Sleep);
-
- return;
-}
-
-/**
- * @brief Closes the SPI when BLE is disabled by the application
- * Releases allocated resources
- * @param None
- * @retval None
- */
-void BNRG_SPI_Close(void)
-{
-#ifdef ENABLE_SPI_FIX
- TIMER_Delete(StartupTimerId);
-#endif
- TIMER_Delete(TxRxTimerId);
-
- return;
-}
-
-/**
- * @brief Initializes the SPI communication with the BlueNRG Shield.
- * @param None
- * @retval None
- */
-void BNRG_SPI_Init(void)
-{
- BNRG_MSP_SPI_Init(&SpiHandle);
-
- SPI_Context.hspi = &SpiHandle;
-
- SPI_Context.Spi_Peripheral_State = SPI_AVAILABLE;
- SPI_Context.SPI_Transmit_Context.RequestPending = FALSE;
-
- __HAL_BLUENRG_SPI_ENABLE_DMAREQ(&SpiHandle, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN);
-
- __HAL_SPI_ENABLE(&SpiHandle);
-
-#ifdef ENABLE_SPI_FIX
- TIMER_Create(eTimerModuleID_Interrupt, &StartupTimerId, eTimerMode_SingleShot, TimerStartupCallback);
-#endif
- TIMER_Create(eTimerModuleID_Interrupt, &TxRxTimerId, eTimerMode_SingleShot, TimerTxRxCallback);
- return;
-}
-
-/**
- * @brief Initializes the SPI communication with the BlueNRG Shield
- * @param None
- * @retval None
- */
-void BNRG_MSP_SPI_Init(SPI_HandleTypeDef * hspi)
-{
- hspi->Instance = BNRG_SPI_INSTANCE;
- hspi->Init.Mode = BNRG_SPI_MODE;
- hspi->Init.Direction = BNRG_SPI_DIRECTION;
- hspi->Init.DataSize = BNRG_SPI_DATASIZE;
- hspi->Init.CLKPolarity = BNRG_SPI_CLKPOLARITY;
- hspi->Init.CLKPhase = BNRG_SPI_CLKPHASE;
- hspi->Init.NSS = BNRG_SPI_NSS;
- hspi->Init.FirstBit = BNRG_SPI_FIRSTBIT;
- hspi->Init.TIMode = BNRG_SPI_TIMODE;
- hspi->Init.CRCPolynomial = BNRG_SPI_CRCPOLYNOMIAL;
- hspi->Init.BaudRatePrescaler = BNRG_SPI_BAUDRATEPRESCALER;
- hspi->Init.CRCCalculation = BNRG_SPI_CRCCALCULATION;
-
- HAL_SPI_Init(hspi);
-
- return;
-}
-
-/**
- * @brief Resets the BlueNRG.
- * @param None
- * @retval None
- */
-void BlueNRG_RST(void)
-{
- uint8_t ubnRFResetTimerID;
-
- GPIO_InitTypeDef GPIO_InitStruct;
-
- GPIO_InitStruct.Pin = BNRG_SPI_RESET_PIN;
- GPIO_InitStruct.Speed = BNRG_SPI_RESET_SPEED;
- TIMER_Create(eTimerModuleID_Interrupt, &ubnRFResetTimerID, eTimerMode_SingleShot, pf_nRFResetTimerCallBack);
-
- BNRG_SPI_RESET_CLK_ENABLE();
-
- HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_RESET);
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct);
-
- TIMER_Start(ubnRFResetTimerID, BLUENRG_HOLD_TIME_IN_RESET);
- ubnRFresetTimerLock = 1;
- while(ubnRFresetTimerLock == 1);
-
- HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_SET);
-
-#if 1
- /*
- * Limitation in HAL V1.1.0
- * The HAL_GPIO_Init() is first configuring the Mode of the IO before the Pull UP configuration
- * To avoid glitch on the IO, the configuration shall go through an extra step OUTPUT/PULLUP
- * to set upfront the PULL UP configuration.
- */
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct);
-#endif
-
- GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct);
-
- TIMER_Start(ubnRFResetTimerID, BLUENRG_HOLD_TIME_AFTER_RESET);
- ubnRFresetTimerLock = 1;
- while(ubnRFresetTimerLock == 1);
- TIMER_Delete(ubnRFResetTimerID);
-
- return;
-}
-
-/**
- * @brief Writes data from local buffer to SPI.
- * @param hspi: SPI handle
- * @param header_data: First data buffer to be written
- * @param payload_data: Second data buffer to be written
- * @param header_size: Size of first data buffer to be written
- * @param payload_size: Size of second data buffer to be written
- * @retval Number of read bytes
- */
-void BlueNRG_SPI_Write(uint8_t* header_data, uint8_t* payload_data, uint8_t header_size, uint8_t payload_size)
-{
- SPI_Context.SPI_Transmit_Context.header_data = header_data;
- SPI_Context.SPI_Transmit_Context.payload_data = payload_data;
- SPI_Context.SPI_Transmit_Context.header_size = header_size;
- SPI_Context.SPI_Transmit_Context.payload_size = payload_size;
-
- SPI_Context.SPI_Transmit_Context.packet_cont = FALSE;
-
- __disable_irq();
- if(SPI_Context.Spi_Peripheral_State == SPI_AVAILABLE)
- {
- SPI_Context.Spi_Peripheral_State = SPI_BUSY;
- Disable_SPI_Receiving_Path();
- __enable_irq();
- WakeupBlueNRG();
- }
- else
- {
- SPI_Context.SPI_Transmit_Context.RequestPending = TRUE;
- __enable_irq();
- }
-
- return;
-}
-
-/**
- * @brief Set in Output mode the IRQ.
- * @param None
- * @retval None
- */
-static void set_irq_as_output(void)
-{
- HAL_GPIO_WritePin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN, GPIO_PIN_SET);
- HAL_LPPUART_GPIO_Set_Mode(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN_POSITION, GPIO_MODE_OUTPUT_PP);
- __HAL_GPIO_EXTI_CLEAR_IT(BNRG_SPI_IRQ_PIN);
-}
-
-/**
- * @brief Set the IRQ in input mode.
- * @param None
- * @retval None
- */
-static void set_irq_as_input(void)
-{
- HAL_GPIO_WritePin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN, GPIO_PIN_RESET); // WARNING: it may conflict with BlueNRG driving High
- HAL_LPPUART_GPIO_Set_Mode(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN_POSITION, GPIO_MODE_INPUT);
-}
-
-/**
- * @brief Enable SPI IRQ.
- * @param None
- * @retval None
- */
-static void Enable_SPI_Receiving_Path(void)
-{
- __HAL_GPIO_EXTI_CLEAR_IT(BNRG_SPI_EXTI_PIN);
- HAL_NVIC_ClearPendingIRQ(BNRG_SPI_EXTI_IRQn);
- HAL_NVIC_EnableIRQ(BNRG_SPI_EXTI_IRQn);
-
- if (HAL_GPIO_ReadPin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN) == GPIO_PIN_SET)
- {
- __HAL_GPIO_EXTI_GENERATE_SWIT(BNRG_SPI_IRQ_PIN);
- }
-}
-
-/**
- * @brief Disable SPI IRQ.
- * @param None
- * @retval None
- */
-static void Disable_SPI_Receiving_Path(void)
-{
- HAL_NVIC_DisableIRQ(BNRG_SPI_EXTI_IRQn);
-}
-
-/**
- * @brief Enable SPI CS.
- * @param None
- * @retval None
- */
-static void Enable_SPI_CS(void)
-{
- /* CS reset */
- HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET);
-}
-
-/**
- * @brief Disable SPI CS.
- * @param None
- * @retval None
- */
-static void Disable_SPI_CS(void)
-{
- while (__HAL_SPI_GET_FLAG(SPI_Context.hspi,SPI_FLAG_BSY) == SET);
-
- /* CS set */
- HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
-}
-
-/**
- * @brief Disable and Enable SPI CS.
- * @param None
- * @retval None
- */
-static void DisableEnable_SPI_CS(void)
-{
- while (__HAL_SPI_GET_FLAG(SPI_Context.hspi,SPI_FLAG_BSY) == SET);
-
- /* CS set */
- HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET);
-
- /* CS reset */
- HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET);
-}
-
-/**
- * @brief Tx and Rx Transfer completed callbacks
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-void BlueNRG_DMA_RxCallback(void)
-{
- uint16_t byte_count;
- uint8_t ready_state;
-
- __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmarx, BNRG_SPI_RX_DMA_TC_FLAG);
-
- /**
- * The TCIF shall be cleared to be able to start a new DMA transmission later on when required.
- * When receiving data, the TCIE is not set as there is no need to handle the interrupt
- * handler of the DMA_Tx.
- * The TCIF clearing is mandatory on STM32F4 but not on STM32L0.
- * In order to keep code identical across platform, the TCIF clearing may be kept as well on
- * the STM32L0 and all other MCUs.
- */
- __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmatx, BNRG_SPI_TX_DMA_TC_FLAG);
- switch (SPI_Context.SPI_Receive_Context.Spi_Receive_Event)
- {
- case SPI_CHECK_RECEIVED_HEADER_FOR_RX:
- byte_count = (Received_Header[4]<<8)|Received_Header[3];
- ready_state = Received_Header[0];
-
- if ((byte_count == 0) || (ready_state != BLUENRG_READY_STATE))
- {
- if (HAL_GPIO_ReadPin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN) == GPIO_PIN_RESET)
- {
- /**
- * This USE CASE shall never happen as this may break the IRQ/CS specification
- * The IRQ line shall never be low when CS is low to avoid BlueNRG race condition when
- * entering low power mode
- * the SPI_END_RECEIVE_FIX has been implemented to make sure this USE CASE never occurs
- * However, even when the behavior is not compliant to the specification, the BlueNRG
- * may not fail so it is increasing robustness by adding this checking just in case the
- * timeout define in the workaround is too short which will end up to marginally brake
- * the specification.
- * This checking will poping BluenRG for a dummy even
- */
-
- /* Release CS line */
- Disable_SPI_CS();
-
- LPM_Mode_Request(eLPM_SPI_RX, eLPM_Mode_LP_Stop);
-
- ReceiveClosure();
- }
- else
- {
- DisableEnable_SPI_CS();
- SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_RX); /**< BlueNRG not ready for reading */
- }
- }
- else
- {
- SPI_Receive_Manager(SPI_REQUEST_PAYLOAD); /**< BlueNRG is ready for reading */
- }
- break;
-
- case SPI_RECEIVE_END:
- /* Release CS line */
- Disable_SPI_CS();
-
- LPM_Mode_Request(eLPM_SPI_RX, eLPM_Mode_LP_Stop);
-
-#if (SPI_END_RECEIVE_FIX == 1)
- pTimerTxRxCallback = ProcessEndOfReceive;
- TIMER_Start(TxRxTimerId, SPI_END_RECEIVE_FIX_TIMEOUT);
-#else
- ProcessEndOfReceive();
-#endif
- break;
-
- case SPI_CHECK_RECEIVED_HEADER_FOR_TX:
- byte_count = (Received_Header[2]<<8)|Received_Header[1];
- ready_state = Received_Header[0];
-
- if ((byte_count == 0) || (ready_state != BLUENRG_READY_STATE))
- {
- DisableEnable_SPI_CS();
- SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_TX); /**< BlueNRG not ready for writing */
- }
- else
- {
-#if (TEST_TX_BUFFER_LIMITATION == 1)
- if(byte_count > MAX_TX_BUFFER_SIZE)
- {
- byte_count = MAX_TX_BUFFER_SIZE;
- }
-#endif
-
- if(SPI_Context.SPI_Transmit_Context.packet_cont != TRUE)
- {
- if( byte_count < (SPI_Context.SPI_Transmit_Context.header_size + SPI_Context.SPI_Transmit_Context.payload_size))
- {
- SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = byte_count - SPI_Context.SPI_Transmit_Context.header_size;
- SPI_Context.SPI_Transmit_Context.payload_size -= SPI_Context.SPI_Transmit_Context.payload_size_to_transmit;
- SPI_Context.SPI_Transmit_Context.packet_cont = TRUE;
- }
- else
- {
- SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = SPI_Context.SPI_Transmit_Context.payload_size;
- }
-
- SPI_Transmit_Manager(SPI_HEADER_TRANSMIT);
- }
- else
- {
- if( byte_count < SPI_Context.SPI_Transmit_Context.payload_size)
- {
- SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = byte_count;
- SPI_Context.SPI_Transmit_Context.payload_size -= SPI_Context.SPI_Transmit_Context.payload_size_to_transmit;
- }
- else
- {
- SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = SPI_Context.SPI_Transmit_Context.payload_size;
- SPI_Context.SPI_Transmit_Context.payload_size = 0;
- }
-
- SPI_Transmit_Manager(SPI_PAYLOAD_TRANSMIT);
- }
- }
-
- break;
-
- default:
- break;
- }
-}
-
-#ifdef ENABLE_SPI_FIX
-/**
- * @brief Wakeup BlueNRG
- * @param None
- * @retval None
- */
-static void WakeupBlueNRG(void)
-{
- Disable_SPI_Receiving_Path();
- pTimerTxRxCallback = TimerTransmitCallback;
- set_irq_as_output();
- TIMER_Start(StartupTimerId, SPI_FIX_TIMEOUT);
- TIMER_Start(TxRxTimerId, SPI_FIX_TIMEOUT+SPI_TX_TIMEOUT);
- LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_LP_Stop);
-
- return;
-}
-
-/**
- * @brief Timer callback to apply timeout SPI FIX
- * @param None
- * @retval None
- */
-static void TimerStartupCallback(void)
-{
- Enable_SPI_CS();
-
- return;
-}
-
-#else
-/**
- * @brief Wakeup BlueNRG
- * @param None
- * @retval None
- */
-static void WakeupBlueNRG(void)
-{
- Disable_SPI_Receiving_Path();
- pTimerTxRxCallback = TimerTransmitCallback;
- Enable_SPI_CS();
- TIMER_Start(TxRxTimerId, SPI_TX_TIMEOUT);
- LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_LP_Stop);
-
- return;
-}
-#endif /* ENABLE_SPI_FIX */
-
-/**
- * @brief Tx and Rx Transfer completed callbacks
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-void BlueNRG_DMA_TxCallback(void)
-{
- __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmatx, BNRG_SPI_TX_DMA_TC_FLAG);
-
- switch (SPI_Context.SPI_Transmit_Context.Spi_Transmit_Event)
- {
- case SPI_HEADER_TRANSMITTED:
- if(SPI_Context.SPI_Transmit_Context.payload_size_to_transmit != 0)
- {
- SPI_Transmit_Manager(SPI_PAYLOAD_TRANSMIT);
- }
- else
- {
- TransmitClosure();
- }
- break;
-
- case SPI_PAYLOAD_TRANSMITTED:
- if( (SPI_Context.SPI_Transmit_Context.packet_cont == TRUE) && (SPI_Context.SPI_Transmit_Context.payload_size != 0))
- {
- SPI_Context.SPI_Transmit_Context.payload_data += SPI_Context.SPI_Transmit_Context.payload_size_to_transmit;
- DisableEnable_SPI_CS();
- SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_TX);
- }
- else
- {
- TransmitClosure();
- }
- break;
-
- default:
- break;
- }
-
- return;
-}
-
-/**
- * @brief Close the transmit mechanism after packet has been sent
- * Wait for the event to come back
- * @param None
- * @retval None
- */
-static void TransmitClosure(void)
-{
- LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_LP_Stop);
- SPI_Context.Spi_Peripheral_State = SPI_AVAILABLE;
- Disable_SPI_CS();
- /*
- * Disable both DMA
- */
- __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx);
- __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx);
- Enable_SPI_Receiving_Path();
-
- return;
-}
-
-/**
- * @brief Manage the SPI transmit
- * @param TransmitRequest: the transmit request
- * @retval None
- */
-static void SPI_Transmit_Manager(SPI_TRANSMIT_REQUEST_t TransmitRequest)
-{
- /*
- * Disable both DMA
- */
- __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx);
- __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx);
-
- __HAL_DMA_DISABLE_IT(SPI_Context.hspi->hdmarx, DMA_IT_TC); /**< Disable Receive packet notification */
-
- __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmatx, BNRG_SPI_TX_DMA_TC_FLAG); /**< Clear flag in DMA */
- HAL_NVIC_ClearPendingIRQ(BNRG_SPI_DMA_TX_IRQn); /**< Clear DMA pending bit in NVIC */
- __HAL_DMA_ENABLE_IT(SPI_Context.hspi->hdmatx, DMA_IT_TC); /**< Enable Transmit packet notification */
-
- __HAL_BLUENRG_DMA_SET_MINC(SPI_Context.hspi->hdmatx); /**< Configure DMA to send Tx packet */
-
- switch (TransmitRequest)
- {
- case SPI_HEADER_TRANSMIT:
- SPI_Context.SPI_Transmit_Context.Spi_Transmit_Event = SPI_HEADER_TRANSMITTED;
-
-#ifdef ENABLE_SPI_FIX
- set_irq_as_input();
-#endif
-
- __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, SPI_Context.SPI_Transmit_Context.header_size); /**< Set counter in DMA TX */
- __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)SPI_Context.SPI_Transmit_Context.header_data); /**< Set memory address in DMA TX */
- break;
-
- case SPI_PAYLOAD_TRANSMIT:
- SPI_Context.SPI_Transmit_Context.Spi_Transmit_Event = SPI_PAYLOAD_TRANSMITTED;
-
- __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, SPI_Context.SPI_Transmit_Context.payload_size_to_transmit); /**< Set counter in DMA TX */
- __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)SPI_Context.SPI_Transmit_Context.payload_data); /**< Set memory address in DMA TX */
- break;
-
- default:
- break;
- }
-
- __HAL_DMA_ENABLE(SPI_Context.hspi->hdmatx); /**< Enable DMA TX */
-
-}
-
-/**
- * @brief Manage the SPI receive
- * @param ReceiveRequest: the receive request
- * @retval None
- */
-static void SPI_Receive_Manager(SPI_RECEIVE_REQUEST_t ReceiveRequest)
-{
- uint16_t byte_count;
- uint8_t localloop;
-
- /*
- * Disable both DMA
- */
- __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx);
- __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx);
-
- /**
- * Flush the Rx register or FIFO
- */
- for (localloop = 0 ; localloop < SPI_FIFO_RX_DEPTH ; localloop++)
- {
- *(volatile uint8_t*)__HAL_BLUENRG_SPI_GET_RX_DATA_REGISTER_ADDRESS(SPI_Context.hspi);
- }
-
- __HAL_DMA_ENABLE_IT(SPI_Context.hspi->hdmarx, DMA_IT_TC); /**< Enable Receive packet notification */
- __HAL_DMA_DISABLE_IT(SPI_Context.hspi->hdmatx, DMA_IT_TC); /**< Disable Transmit packet notification */
-
- switch (ReceiveRequest)
- {
- case SPI_REQUEST_VALID_HEADER_FOR_RX:
- ReceiveHeader(SPI_CHECK_RECEIVED_HEADER_FOR_RX, (uint8_t *)Read_Header_CMD);
- break;
-
- case SPI_REQUEST_VALID_HEADER_FOR_TX:
- ReceiveHeader(SPI_CHECK_RECEIVED_HEADER_FOR_TX, (uint8_t *)Write_Header_CMD);
- break;
-
- case SPI_REQUEST_PAYLOAD:
- SPI_Context.SPI_Receive_Context.Spi_Receive_Event = SPI_RECEIVE_END;
-
- /*
- * Check data to received is not available buffer size
- */
- byte_count = (Received_Header[4]<<8)|Received_Header[3];
- if (byte_count > SPI_Context.SPI_Receive_Context.buffer_size)
- {
- byte_count = SPI_Context.SPI_Receive_Context.buffer_size;
- }
- SPI_Context.SPI_Receive_Context.payload_len = byte_count;
-
- __HAL_BLUENRG_DMA_CLEAR_MINC(SPI_Context.hspi->hdmatx); /**< Configure DMA to send same Byte */
-
- /*
- * Set counter in both DMA
- */
- __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmarx, byte_count);
- __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, byte_count);
-
- /*
- * Set memory address in both DMA
- */
- __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmarx, (uint32_t)SPI_Context.SPI_Receive_Context.buffer);
- __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)&dummy_bytes);
- break;
-
- default:
- break;
- }
-
- /*
- * Enable both DMA - Rx First
- */
- __HAL_DMA_ENABLE(SPI_Context.hspi->hdmarx);
- __HAL_DMA_ENABLE(SPI_Context.hspi->hdmatx);
-
- return;
-}
-
-/**
- * @brief Receive header
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @retval None
- */
-static void ReceiveHeader(SPI_RECEIVE_EVENT_t ReceiveEvent, uint8_t * DataHeader)
-{
- SPI_Context.SPI_Receive_Context.Spi_Receive_Event = ReceiveEvent;
-
- __HAL_BLUENRG_DMA_SET_MINC(SPI_Context.hspi->hdmatx); /**< Configure DMA to send Tx packet */
-
- /*
- * Set counter in both DMA
- */
- __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, HEADER_SIZE);
- __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmarx, HEADER_SIZE);
-
- /*
- * Set memory address in both DMA
- */
- __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmarx, (uint32_t)Received_Header);
- __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)DataHeader);
-
- return;
-}
-
-/**
- * @brief BlueNRG SPI request event
- * @param buffer: the event
- * @param buff_size: the event size
- * @retval None
- */
-void BlueNRG_SPI_Request_Events(uint8_t *buffer, uint8_t buff_size)
-{
- SPI_Context.SPI_Receive_Context.buffer = buffer;
- SPI_Context.SPI_Receive_Context.buffer_size = buff_size;
-
- Enable_SPI_Receiving_Path();
-
- return;
-}
-
-/**
- * @brief BlueNRG SPI IRQ Callback
- * @param None
- * @retval None
- */
-void BlueNRG_SPI_IRQ_Callback(void)
-{
- __disable_irq();
- if(SPI_Context.Spi_Peripheral_State == SPI_AVAILABLE)
- {
- SPI_Context.Spi_Peripheral_State = SPI_BUSY;
- __enable_irq();
- Enable_SPI_CS();
- SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_RX);
- LPM_Mode_Request(eLPM_SPI_RX, eLPM_Mode_Sleep);
- }
- else
- {
- __enable_irq();
- }
-}
-
-#endif /* __DMA_LP__ */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- a/x-nucleo-idb0xa1/BlueNRGDevice.h Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/BlueNRGDevice.h Mon May 16 17:22:03 2016 +0200
@@ -76,7 +76,7 @@
virtual const SecurityManager& getSecurityManager() const {
return *sm;
}
- ble_error_t reset(void);
+ void reset(void);
virtual bool hasInitialized(void) const {
return isInitialized;
}
--- a/x-nucleo-idb0xa1/BlueNRGDiscoveredCharacteristic.h Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/BlueNRGDiscoveredCharacteristic.h Mon May 16 17:22:03 2016 +0200
@@ -1,41 +1,43 @@
-/* mbed Microcontroller Library
- * Copyright (c) 2006-2013 ARM Limited
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __BLUENRG_DISCOVERED_CHARACTERISTIC_H__
-#define __BLUENRG_DISCOVERED_CHARACTERISTIC_H__
-
-#include "ble/DiscoveredCharacteristic.h"
-
-class BlueNRGGattClient; /* forward declaration */
-
-class BlueNRGDiscoveredCharacteristic : public DiscoveredCharacteristic {
-public:
-
- void setup(BlueNRGGattClient *gattcIn,
- Gap::Handle_t connectionHandleIn,
- DiscoveredCharacteristic::Properties_t propsIn,
- GattAttribute::Handle_t declHandleIn,
- GattAttribute::Handle_t valueHandleIn);
-
- void setup(BlueNRGGattClient *gattcIn,
- Gap::Handle_t connectionHandleIn,
- UUID uuidIn,
- DiscoveredCharacteristic::Properties_t propsIn,
- GattAttribute::Handle_t declHandleIn,
- GattAttribute::Handle_t valueHandleIn);
-};
-
-#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BLUENRG_DISCOVERED_CHARACTERISTIC_H__
+#define __BLUENRG_DISCOVERED_CHARACTERISTIC_H__
+
+#include "ble/DiscoveredCharacteristic.h"
+
+class BlueNRGGattClient; /* forward declaration */
+
+class BlueNRGDiscoveredCharacteristic : public DiscoveredCharacteristic {
+public:
+
+ void setup(BlueNRGGattClient *gattcIn,
+ Gap::Handle_t connectionHandleIn,
+ DiscoveredCharacteristic::Properties_t propsIn,
+ GattAttribute::Handle_t declHandleIn,
+ GattAttribute::Handle_t valueHandleIn,
+ GattAttribute::Handle_t lastHandleIn);
+
+ void setup(BlueNRGGattClient *gattcIn,
+ Gap::Handle_t connectionHandleIn,
+ UUID uuidIn,
+ DiscoveredCharacteristic::Properties_t propsIn,
+ GattAttribute::Handle_t declHandleIn,
+ GattAttribute::Handle_t valueHandleIn,
+ GattAttribute::Handle_t lastHandleIn);
+};
+
+#endif /* __BLUENRG_DISCOVERED_CHARACTERISTIC_H__ */
--- a/x-nucleo-idb0xa1/BlueNRGGap.h Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/BlueNRGGap.h Mon May 16 17:22:03 2016 +0200
@@ -46,8 +46,8 @@
#define BDADDR_SIZE 6
#define BLUENRG_GAP_ADV_INTERVAL_MIN (0x0020)
-#define BLUENRG_GAP_ADV_INTERVAL_MAX (0x00A0)
-#define BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN (0x4000)
+#define BLUENRG_GAP_ADV_INTERVAL_MAX (0x4000)
+#define BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN (0x00A0)
// Scanning and Connection Params used by Central for creating connection
#define GAP_OBSERVATION_PROC (0x80)
@@ -59,8 +59,9 @@
#define CONN_L(x) ((int)((x)/0.625f))
#define CONN_P1 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C)
#define CONN_P2 ((int)(_advParams.getInterval()+5)/1.25f)//(0x4C)//(0x6C)
-#define CONN_L1 (0x000C)
-#define CONN_L2 (0x000C)
+#define CONN_L1 (0x0008)
+#define CONN_L2 (0x0008)
+#define GUARD_INT 5 //msec
#define LOCAL_NAME_MAX_SIZE 9 //8 + 1(AD_DATA_TYPE)
#define UUID_BUFFER_SIZE 17 //Either 8*2(16-bit UUIDs) or 4*4(32-bit UUIDs) or 1*16(128-bit UUIDs) +1(AD_DATA_TYPE)
@@ -80,22 +81,13 @@
return m_instance;
}
- // <<<ANDREA>>>
- /*
- enum AdvType_t {
- ADV_IND = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED,//Gap::ADV_IND,
- ADV_DIRECT_IND = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED,//Gap::ADV_DIRECT_IND,
- ADV_SCAN_IND = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED,//Gap::ADV_SCAN_IND,
- ADV_NONCONN_IND = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED//Gap::ADV_NONCONN_IND
- };
- */
enum Reason_t {
DEVICE_FOUND,
DISCOVERY_COMPLETE
};
/* Functions that must be implemented from Gap */
- /*virtual ble_error_t setAddress(addr_type_t type, const Address_t address);*/
+ virtual ble_error_t setAddress(addr_type_t type, const Address_t address);
virtual ble_error_t getAddress(addr_type_t *typeP, Address_t address);
virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &);
virtual ble_error_t startAdvertising(const GapAdvertisingParams &);
@@ -114,19 +106,25 @@
virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP);
virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance);
virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP);
-
+
+ virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode);
+ virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode);
+ virtual AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const;
+ virtual ScanningPolicyMode_t getScanningPolicyMode(void) const;
+
virtual ble_error_t setTxPower(int8_t txPower);
virtual void getPermittedTxPowerValues(const int8_t **, size_t *);
- // <<<ANDREA>>>
+
virtual ble_error_t connect(const Address_t peerAddr,
Gap::AddressType_t peerAddrType,
const ConnectionParams_t *connectionParams,
const GapScanningParams *scanParams);
-
+
+ virtual ble_error_t reset(void);
void Discovery_CB(Reason_t reason,
uint8_t adv_type,
- uint8_t *addr_type,
+ uint8_t addr_type,
uint8_t *addr,
uint8_t *data_length,
uint8_t *data,
@@ -156,6 +154,7 @@
uint16_t m_connectionHandle;
AddressType_t addr_type;
Address_t _peerAddr;
+ AddressType_t _peerAddrType;
uint8_t bdaddr[BDADDR_SIZE];
bool _scanning;
bool _connecting;
@@ -174,9 +173,29 @@
Timeout advTimeout;
bool AdvToFlag;
+ static uint16_t SCAN_DURATION_UNITS_TO_MSEC(uint16_t duration) {
+ return (duration * 625) / 1000;
+ }
+
+ uint16_t scanInterval;
+ uint16_t scanWindow;
+ uint16_t conn_min_interval;
+ uint16_t conn_max_interval;
+ void setConnectionParameters(void);
+
+ Gap::AdvertisingPolicyMode_t advertisingPolicyMode;
+ Gap::ScanningPolicyMode_t scanningPolicyMode;
+
+ Whitelist_t whitelistAddresses;
+
BlueNRGGap() {
m_connectionHandle = BLE_CONN_HANDLE_INVALID;
addr_type = BLEProtocol::AddressType::RANDOM_STATIC;
+
+ /* Set the whitelist policy filter modes to IGNORE_WHITELIST */
+ advertisingPolicyMode = Gap::ADV_POLICY_IGNORE_WHITELIST;
+ scanningPolicyMode = Gap::SCAN_POLICY_FILTER_ALL_ADV;//Gap::SCAN_POLICY_IGNORE_WHITELIST;
+
isSetAddress = false;
memset(deviceAppearance, 0, sizeof(deviceAppearance));
}
--- a/x-nucleo-idb0xa1/BlueNRGGattClient.h Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/BlueNRGGattClient.h Mon May 16 17:22:03 2016 +0200
@@ -1,162 +1,181 @@
-/* mbed Microcontroller Library
-* Copyright (c) 2006-2013 ARM Limited
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-/**
- ******************************************************************************
- * @file BlueNRGGattClient.cpp
- * @author STMicroelectronics
- * @brief Header file for BLE_API GattClient Class
- ******************************************************************************
- * @copy
- *
- * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
- * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
- * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
- * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
- * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
- * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
- *
- * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
- */
-
-#ifndef __BLUENRG_GATT_CLIENT_H__
-#define __BLUENRG_GATT_CLIENT_H__
-
-#include "mbed-drivers/mbed.h"
-#include "ble/blecommon.h"
-#include "btle.h"
-#include "ble/GattClient.h"
-#include "ble/DiscoveredService.h"
-#include "BlueNRGDiscoveredCharacteristic.h"
-
-using namespace std;
-
-#define BLE_TOTAL_DISCOVERED_SERVICES 10
-#define BLE_TOTAL_DISCOVERED_CHARS 10
-
-class BlueNRGGattClient : public GattClient
-{
-public:
- static BlueNRGGattClient &getInstance() {
- static BlueNRGGattClient m_instance;
- return m_instance;
- }
-
- enum {
- GATT_IDLE,
- GATT_SERVICE_DISCOVERY,
- GATT_CHARS_DISCOVERY_COMPLETE,
- GATT_DISCOVERY_TERMINATED,
- GATT_READ_CHAR,
- GATT_WRITE_CHAR
- };
-
- /* Functions that must be implemented from GattClient */
- virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle,
- ServiceDiscovery::ServiceCallback_t sc = NULL,
- ServiceDiscovery::CharacteristicCallback_t cc = NULL,
- const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN),
- const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN));
-
- virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle,
- ServiceDiscovery::ServiceCallback_t callback,
- const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN));
-
- virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle,
- ServiceDiscovery::ServiceCallback_t callback,
- GattAttribute::Handle_t startHandle,
- GattAttribute::Handle_t endHandle);
-
- virtual bool isServiceDiscoveryActive(void) const;
- virtual void terminateServiceDiscovery(void);
- virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) {
- terminationCallback = callback;
- }
- virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const;
- virtual ble_error_t write(GattClient::WriteOp_t cmd,
- Gap::Handle_t connHandle,
- GattAttribute::Handle_t attributeHandle,
- size_t length,
- const uint8_t *value) const;
-
- void gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code);
-
- void primaryServicesCB(Gap::Handle_t connectionHandle,
- uint8_t event_data_length,
- uint8_t attribute_data_length,
- uint8_t *attribute_data_list);
-
- void primaryServiceCB(Gap::Handle_t connectionHandle,
- uint8_t event_data_length,
- uint8_t *handles_info_list);
-
- ble_error_t findServiceChars(Gap::Handle_t connectionHandle);
-
- void serviceCharsCB(Gap::Handle_t connectionHandle,
- uint8_t event_data_length,
- uint8_t handle_value_pair_length,
- uint8_t *handle_value_pair);
-
- void serviceCharByUUIDCB(Gap::Handle_t connectionHandle,
- uint8_t event_data_length,
- uint16_t attr_handle,
- uint8_t *attr_value);
-
- void charReadCB(Gap::Handle_t connHandle,
- uint8_t event_data_length,
- uint8_t* attribute_value);
-
- void charWritePrepareCB(Gap::Handle_t connHandle,
- uint8_t event_data_length,
- uint16_t attribute_handle,
- uint16_t offset,
- uint8_t *part_attr_value);
-
- void charWriteExecCB(Gap::Handle_t connHandle,
- uint8_t event_data_length);
-
-protected:
-
- BlueNRGGattClient() {
- _currentState = GATT_IDLE;
- _matchingServiceUUID = BLE_UUID_UNKNOWN;
- _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN;
- }
-
- ServiceDiscovery::ServiceCallback_t serviceDiscoveryCallback;
- ServiceDiscovery::CharacteristicCallback_t characteristicDiscoveryCallback;
- ServiceDiscovery::TerminationCallback_t terminationCallback;
-
-private:
-
- BlueNRGGattClient(BlueNRGGattClient const &);
- void operator=(BlueNRGGattClient const &);
-
- Gap::Handle_t _connectionHandle;
- DiscoveredService discoveredService[BLE_TOTAL_DISCOVERED_SERVICES];
- BlueNRGDiscoveredCharacteristic discoveredChar[BLE_TOTAL_DISCOVERED_CHARS];
-
- GattReadCallbackParams readCBParams;
- GattWriteCallbackParams writeCBParams;
-
- UUID _matchingServiceUUID;
- UUID _matchingCharacteristicUUIDIn;
- uint8_t _currentState;
- uint8_t _numServices, _servIndex;
- uint8_t _numChars;
-
-};
-
-#endif /* __BLUENRG_GATT_CLIENT_H__ */
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/**
+ ******************************************************************************
+ * @file BlueNRGGattClient.cpp
+ * @author STMicroelectronics
+ * @brief Header file for BLE_API GattClient Class
+ ******************************************************************************
+ * @copy
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * <h2><center>© COPYRIGHT 2015 STMicroelectronics</center></h2>
+ */
+
+#ifndef __BLUENRG_GATT_CLIENT_H__
+#define __BLUENRG_GATT_CLIENT_H__
+
+#include "mbed-drivers/mbed.h"
+#include "ble/blecommon.h"
+#include "btle.h"
+#include "ble/GattClient.h"
+#include "ble/DiscoveredService.h"
+#include "ble/CharacteristicDescriptorDiscovery.h"
+#include "BlueNRGDiscoveredCharacteristic.h"
+
+using namespace std;
+
+#define BLE_TOTAL_DISCOVERED_SERVICES 10
+#define BLE_TOTAL_DISCOVERED_CHARS 10
+
+class BlueNRGGattClient : public GattClient
+{
+public:
+ static BlueNRGGattClient &getInstance() {
+ static BlueNRGGattClient m_instance;
+ return m_instance;
+ }
+
+ enum {
+ GATT_IDLE,
+ GATT_SERVICE_DISCOVERY,
+ GATT_CHAR_DESC_DISCOVERY,
+ //GATT_CHARS_DISCOVERY_COMPLETE,
+ //GATT_DISCOVERY_TERMINATED,
+ GATT_READ_CHAR,
+ GATT_WRITE_CHAR
+ };
+
+ /* Functions that must be implemented from GattClient */
+ virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle,
+ ServiceDiscovery::ServiceCallback_t sc = NULL,
+ ServiceDiscovery::CharacteristicCallback_t cc = NULL,
+ const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN),
+ const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN));
+
+ virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle,
+ ServiceDiscovery::ServiceCallback_t callback,
+ const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN));
+
+ virtual ble_error_t discoverServices(Gap::Handle_t connectionHandle,
+ ServiceDiscovery::ServiceCallback_t callback,
+ GattAttribute::Handle_t startHandle,
+ GattAttribute::Handle_t endHandle);
+
+ virtual bool isServiceDiscoveryActive(void) const;
+ virtual void terminateServiceDiscovery(void);
+ virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) {
+ terminationCallback = callback;
+ }
+ virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const;
+ virtual ble_error_t write(GattClient::WriteOp_t cmd,
+ Gap::Handle_t connHandle,
+ GattAttribute::Handle_t attributeHandle,
+ size_t length,
+ const uint8_t *value) const;
+ virtual ble_error_t discoverCharacteristicDescriptors(
+ const DiscoveredCharacteristic& characteristic,
+ const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
+ const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback);
+
+ virtual ble_error_t reset(void);
+
+ void gattProcedureCompleteCB(Gap::Handle_t connectionHandle, uint8_t error_code);
+
+ void primaryServicesCB(Gap::Handle_t connectionHandle,
+ uint8_t event_data_length,
+ uint8_t attribute_data_length,
+ uint8_t *attribute_data_list);
+
+ void primaryServiceCB(Gap::Handle_t connectionHandle,
+ uint8_t event_data_length,
+ uint8_t *handles_info_list);
+
+ ble_error_t findServiceChars(Gap::Handle_t connectionHandle);
+
+ void serviceCharsCB(Gap::Handle_t connectionHandle,
+ uint8_t event_data_length,
+ uint8_t handle_value_pair_length,
+ uint8_t *handle_value_pair);
+
+ void serviceCharByUUIDCB(Gap::Handle_t connectionHandle,
+ uint8_t event_data_length,
+ uint16_t attr_handle,
+ uint8_t *attr_value);
+
+ void discAllCharacDescCB(Gap::Handle_t connHandle,
+ uint8_t event_data_length,
+ uint8_t format,
+ uint8_t *handle_uuid_pair);
+
+ void charReadCB(Gap::Handle_t connHandle,
+ uint8_t event_data_length,
+ uint8_t* attribute_value);
+
+ void charWritePrepareCB(Gap::Handle_t connHandle,
+ uint8_t event_data_length,
+ uint16_t attribute_handle,
+ uint16_t offset,
+ uint8_t *part_attr_value);
+
+ void charWriteExecCB(Gap::Handle_t connHandle,
+ uint8_t event_data_length);
+
+protected:
+
+ BlueNRGGattClient() {
+ _currentState = GATT_IDLE;
+ _matchingServiceUUID = BLE_UUID_UNKNOWN;
+ _matchingCharacteristicUUIDIn = BLE_UUID_UNKNOWN;
+ }
+
+ ServiceDiscovery::ServiceCallback_t serviceDiscoveryCallback;
+ ServiceDiscovery::CharacteristicCallback_t characteristicDiscoveryCallback;
+ ServiceDiscovery::TerminationCallback_t terminationCallback;
+ CharacteristicDescriptorDiscovery::DiscoveryCallback_t charDescDiscoveryCallback;
+ CharacteristicDescriptorDiscovery::TerminationCallback_t charDescTerminationCallback;
+
+private:
+
+ BlueNRGGattClient(BlueNRGGattClient const &);
+ void operator=(BlueNRGGattClient const &);
+
+ Gap::Handle_t _connectionHandle;
+ DiscoveredService discoveredService[BLE_TOTAL_DISCOVERED_SERVICES];
+ BlueNRGDiscoveredCharacteristic discoveredChar[BLE_TOTAL_DISCOVERED_CHARS];
+
+ GattReadCallbackParams readCBParams;
+ GattWriteCallbackParams writeCBParams;
+
+ // The char for which the descriptor discovery has been launched
+ DiscoveredCharacteristic _characteristic;
+
+ UUID _matchingServiceUUID;
+ UUID _matchingCharacteristicUUIDIn;
+ uint8_t _currentState;
+ uint8_t _numServices, _servIndex;
+ uint8_t _numChars;
+ uint8_t _numCharDesc;
+
+};
+
+#endif /* __BLUENRG_GATT_CLIENT_H__ */
--- a/x-nucleo-idb0xa1/BlueNRGGattServer.h Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/BlueNRGGattServer.h Mon May 16 17:22:03 2016 +0200
@@ -29,9 +29,7 @@
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
- */
-
-// ANDREA: Changed some types (e.g., tHalUint8 --> uint8_t)
+ */
#ifndef __BLUENRG_GATT_SERVER_H__
#define __BLUENRG_GATT_SERVER_H__
@@ -46,11 +44,6 @@
#define BLE_TOTAL_CHARACTERISTICS 10
-// If the char has handle 'x', then the value declaration will have the handle 'x+1'
-// If the char has handle 'x', then the char descriptor declaration will have the handle 'x+2'
-#define CHAR_VALUE_OFFSET 1
-#define CHAR_DESC_OFFSET 2
-
using namespace std;
class BlueNRGGattServer : public GattServer
@@ -68,7 +61,6 @@
};
/* Functions that must be implemented from GattServer */
- // <<<ANDREA>>>
virtual ble_error_t addService(GattService &);
virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP);
virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP);
@@ -79,12 +71,13 @@
virtual bool isOnDataReadAvailable() const {
return true;
}
- // <<<ANDREA>>>
+
+ virtual ble_error_t reset(void);
/* BlueNRG Functions */
void eventCallback(void);
//void hwCallback(void *pckt);
- ble_error_t Read_Request_CB(uint16_t handle);
+ ble_error_t Read_Request_CB(uint16_t attributeHandle);
GattCharacteristic* getCharacteristicFromHandle(uint16_t charHandle);
void HCIDataWrittenEvent(const GattWriteCallbackParams *params);
void HCIDataReadEvent(const GattReadCallbackParams *params);
@@ -97,7 +90,7 @@
uint8_t characteristicCount;
uint16_t servHandle, charHandle;
- std::map<uint16_t, uint16_t> bleCharHanldeMap; // 1st argument is characteristic, 2nd argument is service
+ std::map<uint16_t, uint16_t> bleCharHandleMap; // 1st argument is characteristic, 2nd argument is service
GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS];
uint16_t bleCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS];
--- a/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_aci_const.h Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_aci_const.h Mon May 16 17:22:03 2016 +0200
@@ -25,6 +25,16 @@
#define OCF_HAL_WRITE_CONFIG_DATA 0x000C
+#define OCF_HAL_READ_CONFIG_DATA 0x000D
+typedef __packed struct _hal_read_config_data_cp{
+ uint8_t offset;
+} PACKED hal_read_config_data_cp;
+#define HAL_READ_CONFIG_DATA_RP_SIZE 1
+typedef __packed struct _hal_read_config_data_rp{
+ uint8_t status;
+ uint8_t data[HCI_MAX_PAYLOAD_SIZE-HAL_READ_CONFIG_DATA_RP_SIZE];
+} PACKED hal_read_config_data_rp;
+
#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F
typedef __packed struct _hal_set_tx_power_level_cp{
uint8_t en_high_power;
@@ -34,6 +44,12 @@
#define OCF_HAL_DEVICE_STANDBY 0x0013
+#define OCF_HAL_LE_TX_TEST_PACKET_NUMBER 0x0014
+typedef __packed struct _hal_le_tx_test_packet_number_rp{
+ uint8_t status;
+ uint32_t number_of_packets;
+} PACKED hal_le_tx_test_packet_number_rp;
+
#define OCF_HAL_TONE_START 0x0015
typedef __packed struct _hal_tone_start_cp{
uint8_t rf_channel;
--- a/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gap_aci.h Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gap_aci.h Mon May 16 17:22:03 2016 +0200
@@ -206,7 +206,14 @@
* @brief Put the Device in general discoverable mode (as defined in GAP specification volume 3, section 9.2.4).
* @note The device will be discoverable until the Host issue Bluehci_Gap_Set_Non_Discoverable command.
* The Adv_Interval_Min and Adv_Interval_Max parameters are optional. If both are set to 0, the GAP uses
- * the default values for advertising intervals (1.28 s and 2.56 s respectively).
+ * the default values for advertising intervals for IDB04A1 (1.28 s and 2.56 s respectively).
+ * For IDB05A1:
+ * When using connectable undirected advertising events:\n
+ * @li Adv_Interval_Min = 30 ms
+ * @li Adv_Interval_Max = 60 ms
+ * \nWhen using non-connectable advertising events or scannable undirected advertising events:\n
+ * @li Adv_Interval_Min = 100 ms
+ * @li Adv_Interval_Max = 150 ms
* Host can set the Local Name, a Service UUID list and the Slave Connection Interval Range. If provided,
* these data will be inserted into the advertising packet payload as AD data. These parameters are optional
* in this command. These values can be also set using aci_gap_update_adv_data() separately.
@@ -229,8 +236,8 @@
* const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'};
* const uint8_t serviceUUIDList[] = {AD_TYPE_16_BIT_SERV_UUID,0x34,0x12};
*
- * ret = aci_gap_set_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625,
- * (ADV_INTERVAL_MAX_MS*1000)/0.625,
+ * ret = aci_gap_set_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/625,
+ * (ADV_INTERVAL_MAX_MS*1000)/625,
* STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE,
* sizeof(local_name), local_name,
* 0, NULL,
@@ -591,7 +598,7 @@
* due to any of the above reasons, @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with
* the procedure code set to @ref GAP_LIMITED_DISCOVERY_PROC.
* The device found when the procedure is ongoing is returned to the upper layers through the
- * event @ref EVT_BLUE_GAP_DEVICE_FOUND.
+ * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) and @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1).
* @param scanInterval Time interval from when the Controller started its last LE scan until it begins
* the subsequent LE scan. The scan interval should be a number in the range
* 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
@@ -618,7 +625,7 @@
* or a timeout happens. When the procedure is terminated due to any of the above reasons,
* @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with the procedure code set to
* @ref GAP_GENERAL_DISCOVERY_PROC. The device found when the procedure is ongoing is returned to
- * the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND.
+ * the upper layers through the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) and @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1).
* @param scanInterval Time interval from when the Controller started its last LE scan until it begins
* the subsequent LE scan. The scan interval should be a number in the range
* 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec.
@@ -766,7 +773,7 @@
* @brief Start a general connection establishment procedure.
* @note The host enables scanning in the controller with the scanner filter policy set
* to accept all advertising packets and from the scanning results all the devices
- * are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND.
+ * are sent to the upper layer using the event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) and @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1).
* The upper layer then has to select one of the devices to which it wants to connect
* by issuing the command aci_gap_create_connection(). The procedure is terminated
* when a connection is established or the upper layer terminates the procedure by
@@ -805,7 +812,7 @@
* @note The GAP adds the specified device addresses into white list and enables scanning in
* the controller with the scanner filter policy set to accept packets only from
* devices in whitelist. All the devices found are sent to the upper layer by the
- * event @ref EVT_BLUE_GAP_DEVICE_FOUND. The upper layer then has to select one of the
+ * event @ref EVT_BLUE_GAP_DEVICE_FOUND (for IDB04A1) and @ref EVT_LE_ADVERTISING_REPORT (for IDB05A1). The upper layer then has to select one of the
* devices to which it wants to connect by issuing the command aci_gap_create_connection().
* On completion of the procedure a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated
* with the procedure code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC.
@@ -894,7 +901,7 @@
uint16_t max_conn_length);
/**
- * @brief Terminate the specified GATT procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is
+ * @brief Terminate the specified GAP procedure. @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is
* returned with the procedure code set to the corresponding procedure.
* @param procedure_code One of the procedure codes (@ref gap_procedure_codes "GAP procedure codes").
* @return Value indicating success or error code.
--- a/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gatt_aci.h Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gatt_aci.h Mon May 16 17:22:03 2016 +0200
@@ -47,10 +47,13 @@
* service (including the service attribute, include attribute, characteristic attribute,
* characteristic value attribute and characteristic descriptor attribute). Handle of the
* created service is returned.
+ * @note Service declaration is taken from the service pool. The attributes for characteristics and descriptors
+ * are allocated from the attribute pool.
* @param service_uuid_type Type of service UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types".
* @param[in] service_uuid 16-bit or 128-bit UUID based on the UUID Type field
* @param service_type Primary or secondary service. See @ref Service_type "Service Type".
* @param max_attr_records Maximum number of attribute records that can be added to this service
+ * (including the service declaration itself)
* @param[out] serviceHandle Handle of the Service. When this service is added to the service,
* a handle is allocated by the server to this service. Server also
* allocates a range of handles for this service from serviceHandle to
@@ -227,7 +230,7 @@
uint16_t charHandle,
uint8_t charValOffset,
uint8_t charValueLen,
- const uint8_t *charValue);
+ const void *charValue);
/**
* @brief Delete the specified characteristic from the service.
* @param servHandle Handle of the service to which characteristic belongs
@@ -704,7 +707,7 @@
uint16_t charDescHandle,
uint16_t charDescValOffset,
uint8_t charDescValueLen,
- const uint8_t *charDescValue);
+ const void *charDescValue);
/**
* @brief Reads the value of the attribute handle specified from the local GATT database.
@@ -1035,6 +1038,28 @@
} PACKED evt_gatt_read_multi_permit_req;
/**
+ * This event is raised when the number of available TX buffers is above a threshold TH (TH = 2).
+ * The event will be given only if a previous ACI command returned with BLE_STATUS_INSUFFICIENT_RESOURCES.
+ * On receiving this event, the application can continue to send notifications by calling aci_gatt_update_char_value().
+ * See @ref evt_gatt_tx_pool_vailable.
+ *
+ */
+#define EVT_BLUE_GATT_TX_POOL_AVAILABLE_IDB05A1 (0x0C16)
+typedef __packed struct _evt_gatt_tx_pool_available{
+ uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */
+ uint16_t available_buffers; /**< Length of data field. */
+} PACKED evt_gatt_tx_pool_available;
+
+/**
+ * This event is raised on the server when the client confirms the reception of an indication.
+ */
+#define EVT_BLUE_GATT_SERVER_CONFIRMATION_EVENT_IDB05A1 (0x0C17)
+typedef __packed struct _evt_gatt_server_confirmation{
+ uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */
+ uint16_t reserved; /**< Not used. */
+} PACKED evt_gatt_server_confirmation;
+
+/**
* @}
*/
--- a/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_hal_aci.h Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_hal_aci.h Mon May 16 17:22:03 2016 +0200
@@ -43,6 +43,18 @@
const uint8_t *val);
/**
+ * @brief This command requests the value in the low level configure data structure.
+ * The number of read bytes changes for different Offset.
+ * @param offset Offset in the data structure. The starting member in the data structure will have an offset 0.\n
+ * See @ref Config_vals.
+ * @param data_len Length of the data buffer
+ * @param[out] data_len_out_p length of the data returned by the read.
+ * @param[out] data Read data
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_read_config_data(uint8_t offset, uint16_t data_len, uint8_t *data_len_out_p, uint8_t *data);
+
+/**
* @brief This command sets the TX power level of the BlueNRG.
* @note By controlling the EN_HIGH_POWER and the PA_LEVEL, the combination of the 2 determines
* the output power level (dBm).
@@ -63,6 +75,18 @@
tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level);
/**
+ * @brief This command returns the number of packets sent in Direct Test Mode.
+ * @note When the Direct TX test is started, a 32-bit counter is used to count how many packets
+ * have been transmitted. This command can be used to check how many packets have been sent
+ * during the Direct TX test.\n
+ * The counter starts from 0 and counts upwards. The counter can wrap and start from 0 again.
+ * The counter is not cleared until the next Direct TX test starts.
+ * @param[out] number_of_packets Number of packets sent during the last Direct TX test.
+ * @return Value indicating success or error code.
+ */
+tBleStatus aci_hal_le_tx_test_packet_number(uint32_t *number_of_packets);
+
+/**
* @brief Put the device in standby mode.
* @note Normally the BlueNRG will automatically enter sleep mode to save power. This command puts the
* device into the Standby mode instead of the sleep mode. The difference is that, in sleep mode,
@@ -119,6 +143,8 @@
It can be written only if aci_hal_write_config_data() is the first command
after reset. */
+#define CONFIG_DATA_RANDOM_ADDRESS_IDB05A1 (0x80) /**< Stored static random address. Read-only (IDB05A1 only) */
+
/**
* Select the BlueNRG roles and mode configurations.\n
* @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB)
--- a/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_l2cap_aci.h Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_l2cap_aci.h Mon May 16 17:22:03 2016 +0200
@@ -123,6 +123,10 @@
* within 30 seconds.
*/
#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801)
+typedef __packed struct _evt_l2cap_procedure_timeout{
+ uint16_t conn_handle; /**< The connection handle related to the event. */
+ uint8_t event_data_length; /**< Length of following data. It should be always 0 for this event. */
+} PACKED evt_l2cap_procedure_timeout;
/**
* The event is given by the L2CAP layer when a connection update request is received from the slave.
--- a/x-nucleo-idb0xa1/bluenrg-hci/hci.h Tue Apr 26 14:44:54 2016 +0200
+++ b/x-nucleo-idb0xa1/bluenrg-hci/hci.h Mon May 16 17:22:03 2016 +0200
@@ -163,6 +163,8 @@
const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval,
uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length);
+int hci_le_create_connection_cancel(void);
+
int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t *tx_level);
int hci_read_rssi(uint16_t *conn_handle, int8_t *rssi);
--- a/x-nucleo-idb0xa1/bluenrg-hci/hci_const.h Tue Apr 26 14:44:54 2016 +0200 +++ b/x-nucleo-idb0xa1/bluenrg-hci/hci_const.h Mon May 16 17:22:03 2016 +0200 @@ -14,7 +14,6 @@ #include "hal_types.h" #include "clock.h" #include "link_layer.h" - #include "hci.h" #define DEFAULT_TIMEOUT (CLOCK_SECOND/10) @@ -287,7 +286,7 @@ uint8_t status; uint16_t handle; uint8_t map[5]; -} le_read_channel_map_rp; +} PACKED le_read_channel_map_rp; #define LE_READ_CHANNEL_MAP_RP_SIZE 8 #define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016
--- a/x-nucleo-idb0xa1/platform/stm32_bluenrg_ble_dma_lp.h Tue Apr 26 14:44:54 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,152 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32_bluenrg_ble_dma_lp.h
- * @author CL
- * @version V1.0.0
- * @date 04-July-2014
- * @brief
- ******************************************************************************
- * @attention
- *
- * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32_BLUENRG_BLE_DMA_LP_H
-#define __STM32_BLUENRG_BLE_DMA_LP_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#ifdef USE_STM32F4XX_NUCLEO
- #include "stm32f4xx_hal.h"
- #include "stm32f4xx_nucleo.h"
- #include "stm32f4xx_nucleo_bluenrg_dma_lp.h"
- #include "stm32f4xx_hal_bluenrg_gpio.h"
- #include "stm32f4xx_hal_bluenrg_spi.h"
- #include "stm32f4xx_hal_bluenrg_dma.h"
-#endif /* USE_STM32F4XX_NUCLEO */
-
-#ifdef USE_STM32L0XX_NUCLEO
- #include "stm32l0xx_hal.h"
- #include "stm32l0xx_nucleo.h"
- #include "stm32l0xx_nucleo_bluenrg_dma_lp.h"
- #include "stm32l0xx_hal_bluenrg_gpio.h"
- #include "stm32l0xx_hal_bluenrg_spi.h"
- #include "stm32l0xx_hal_bluenrg_dma.h"
-#endif /* USE_STM32L0XX_NUCLEO */
-
-#include "stm32xx_lpm.h"
-#include "stm32xx_timerserver.h"
-
-/** @addtogroup BSP
- * @{
- */
-
-/** @addtogroup X-NUCLEO-IDB04A1
- * @{
- */
-
-/** @addtogroup STM32_BLUENRG_BLE_DMA_LP
- * @{
- */
-
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Exported_Constants
- * @{
- */
-
-#define SPI_END_RECEIVE_FIX 1 /**< Need some delay after receiving an event to prevent dummy read */
-
- /**
- * All timeout below are given in term of Ticks of the TimerServer.
- * The tick of the timerserver depends on the LPO clock used as input and the
- * prescaler of the wakeup timer.
- * In order to get the most efficient implementation, the wakeuptimer prescaler should divide
- * the input clock by 2
- *
- * The values below are based on the LSI clock @37Kz.
- * For this, the tick is 54us
- */
-#define SPI_FIX_TIMEOUT 2 /**< 150 us - Note: 2 ticks result into more than 2*54us due to some inaccuracies and latencies */
-#define SPI_TX_TIMEOUT 3 /**< Value to be tuned to prevent trying to send a command to BlueNRG if it is not yet woken up */
-#define SPI_END_RECEIVE_FIX_TIMEOUT 2
-#define BLUENRG_HOLD_TIME_IN_RESET 1
-#define BLUENRG_HOLD_TIME_AFTER_RESET 93 /**< 5ms */
-
-/**
- * When the SPI does not have any FIFO (STM32L0, etc...), this parameter should be set to 1
- * When the SPI does have a FIFO, this parameter shall be set to the size of the FIFO in bytes (STM32L4 = 4)
- */
-#define SPI_FIFO_RX_DEPTH 1
-
-/**
- * @}
- */
-
-/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Exported_Functions
- * @{
- */
-// FIXME: add prototypes for BlueNRG here
-void BNRG_SPI_Close(void);
-void BNRG_SPI_Init(void);
-void BlueNRG_RST(void);
-void BlueNRG_SPI_Write(uint8_t* header_data,
- uint8_t* payload_data,
- uint8_t header_size,
- uint8_t payload_size);
-void BlueNRG_SPI_Request_Events(uint8_t *buffer, uint8_t buff_size);
-void BlueNRG_DMA_RxCallback(void);
-void BlueNRG_DMA_TxCallback(void);
-void BlueNRG_SPI_IRQ_Callback(void);
-void BNRG_MSP_SPI_Init(SPI_HandleTypeDef * hspi);
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32_BLUENRG_BLE_DMA_LP_H */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-
