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.
Dependencies: mbed-os-example-ble-Advertising
Revision 242:058b2e731adc, committed 2016-06-20
- Comitter:
- Andrea Palmieri
- Date:
- Mon Jun 20 14:59:06 2016 +0200
- Parent:
- 215:e8fa3129410a
- Parent:
- 241:c13c2e31316d
- Child:
- 243:c56decc9c198
- Commit message:
- Merge branch 'master' into mbed_classic
Signed-off-by: Andrea Palmieri <andrea.palmieri@st.com>
Conflicts:
source/BlueNRGGap.cpp
source/BlueNRGGattClient.cpp
x-nucleo-idb0xa1/BlueNRGGattClient.h
Changed in this revision
--- a/source/BlueNRGDevice.cpp Fri Mar 18 12:10:20 2016 +0100
+++ b/source/BlueNRGDevice.cpp Mon Jun 20 14:59:06 2016 +0200
@@ -142,7 +142,7 @@
/* ToDo: Clear memory contents, reset the SD, etc. */
// By default, we set the device GAP role to PERIPHERAL
- btle_init(BlueNRGGap::getInstance().getIsSetAddress(), GAP_PERIPHERAL_ROLE_IDB04A1);
+ btleInit(BlueNRGGap::getInstance().getIsSetAddress(), GAP_PERIPHERAL_ROLE_IDB04A1);
isInitialized = true;
BLE::InitializationCompleteCallbackContext context = {
@@ -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;
}
/*!
@@ -205,14 +202,14 @@
/*!
@brief get GAP version
+ @brief Get the BLE stack version information
@param[in] void
@returns char *
+ @returns char *
*/
const char *BlueNRGDevice::getVersion(void)
{
- char *version = new char[6];
- memcpy((void *)version, "1.0.0", 5);
- return version;
+ return getVersionString();
}
/**************************************************************************/
@@ -251,12 +248,43 @@
/**************************************************************************/
/*!
- @brief shut down the the BLE device
+ @brief shut down the BLE device
@param[out] error if any
*/
/**************************************************************************/
ble_error_t BlueNRGDevice::shutdown(void) {
- return reset();
+ if (!isInitialized) {
+ return BLE_ERROR_INITIALIZATION_INCOMPLETE;
+ }
+
+ /* 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 Fri Mar 18 12:10:20 2016 +0100
+++ b/source/BlueNRGDiscoveredCharacteristic.cpp Mon Jun 20 14:59:06 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 Fri Mar 18 12:10:20 2016 +0100
+++ b/source/BlueNRGGap.cpp Mon Jun 20 14:59:06 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
@@ -49,10 +47,6 @@
//Local Variables
//const char *local_name = NULL;
//uint8_t local_name_length = 0;
-const uint8_t *scan_response_payload = NULL;
-uint8_t scan_rsp_length = 0;
-
-uint32_t advtInterval = BLUENRG_GAP_ADV_INTERVAL_MAX;
/*
* Utility to process GAP specific events (e.g., Advertising timeout)
@@ -105,14 +99,20 @@
PRINTF("BlueNRGGap::setAdvertisingData\n\r");
/* Make sure we don't exceed the advertising payload length */
if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
+ PRINTF("Exceeded the advertising payload length\n\r");
return BLE_ERROR_BUFFER_OVERFLOW;
}
/* Make sure we have a payload! */
- if (advData.getPayloadLen() <= 0) {
- return BLE_ERROR_PARAM_OUT_OF_RANGE;
- } else {
- PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen());
+ 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++) {
loadPtr.getUnitAtIndex(index);
@@ -157,7 +157,8 @@
}
for(unsigned i=0; i<buffSize; i++) {
- PRINTF("loadPtr.getUnitAtIndex(index).getDataPtr()[%d] = 0x%x\n\r", i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]);
+ PRINTF("loadPtr.getUnitAtIndex(index).getDataPtr()[%d] = 0x%x\n\r",
+ i, loadPtr.getUnitAtIndex(index).getDataPtr()[i]);
}
#endif /* DEBUG */
break;
@@ -179,13 +180,16 @@
case GapAdvertisingData::COMPLETE_LOCAL_NAME: /**< Complete Local Name */
{
PRINTF("Advertising type: COMPLETE_LOCAL_NAME\n\r");
- loadPtr.getUnitAtIndex(index).printDataAsString();
- local_name_length = *loadPtr.getUnitAtIndex(index).getLenPtr()-1;
- local_name = (uint8_t*)loadPtr.getUnitAtIndex(index).getAdTypePtr();
- PRINTF("Advertising type: COMPLETE_LOCAL_NAME local_name=%s\n\r", local_name);
- //COMPLETE_LOCAL_NAME is only advertising device name. Gatt Device Name is not the same.(Must be set right after GAP/GATT init?)
-
- PRINTF("device_name length=%d\n\r", local_name_length);
+ loadPtr.getUnitAtIndex(index).printDataAsString();
+ local_name_length = *loadPtr.getUnitAtIndex(index).getLenPtr()-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
+ memcpy(local_name+1, (uint8_t*)loadPtr.getUnitAtIndex(index).getDataPtr(), local_name_length-1);
+ PRINTF("Advertising type: COMPLETE_LOCAL_NAME local_name=%s local_name_length=%d\n\r", local_name, local_name_length);
+
break;
}
case GapAdvertisingData::TX_POWER_LEVEL: /**< TX Power Level (in dBm) */
@@ -219,41 +223,23 @@
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]);
+ 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;
memcpy(AdvData+2, loadPtr.getUnitAtIndex(index).getDataPtr(), buffSize);
break;
}
- case GapAdvertisingData::APPEARANCE:
- {
- /*
- Tested with GapAdvertisingData::GENERIC_PHONE.
- for other appearances BLE Scanner android app is not behaving properly
- */
- PRINTF("Advertising type: APPEARANCE\n\r");
- const char *deviceAppearance = NULL;
- deviceAppearance = (const char*)loadPtr.getUnitAtIndex(index).getDataPtr(); // to be set later when startAdvertising() is called
-
-#ifdef DEBUG
- uint8_t Appearance[2] = {0, 0};
- uint16_t devP = (uint16_t)*deviceAppearance;
- STORE_LE_16(Appearance, (uint16_t)devP);
-#endif
-
- PRINTF("input: deviceAppearance= 0x%x 0x%x..., strlen(deviceAppearance)=%d\n\r", Appearance[1], Appearance[0], (uint8_t)*loadPtr.getUnitAtIndex(index).getLenPtr()-1); /**< \ref Appearance */
-
- aci_gatt_update_char_value(g_gap_service_handle, g_appearance_char_handle, 0, 2, (uint8_t *)deviceAppearance);//not using array Appearance[2]
- break;
- }
+
case GapAdvertisingData::ADVERTISING_INTERVAL: /**< Advertising Interval */
{
PRINTF("Advertising type: ADVERTISING_INTERVAL\n\r");
- advtInterval = (uint16_t)(*loadPtr.getUnitAtIndex(index).getDataPtr());
- PRINTF("advtInterval=%d\n\r", (int)advtInterval);
+ //uint32_t advInt = (uint32_t)(*loadPtr.getUnitAtIndex(index).getDataPtr());
break;
}
case GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA: /**< Manufacturer Specific Data */
@@ -267,23 +253,32 @@
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;
memcpy(AdvData+2, loadPtr.getUnitAtIndex(index).getDataPtr(), buffSize);
break;
}
-
- }
- }
+ } // end switch
+
+ } //end for
+
//Set the SCAN_RSP Payload
- scan_response_payload = scanResponse.getPayload();
- scan_rsp_length = scanResponse.getPayloadLen();
-
+ if(scanResponse.getPayloadLen() > 0) {
+ scan_response_payload = scanResponse.getPayload();
+ scan_rsp_length = scanResponse.getPayloadLen();
+ }
+
+ /* Align the GAP Service Appearance Char value coherently */
+ STORE_LE_16(deviceAppearance, advData.getAppearance());
+ setAppearance((GapAdvertisingData::Appearance)(deviceAppearance[1]<<8|deviceAppearance[0]));
+
// Update the ADV data if we are already in ADV mode
if(AdvLen > 0 && state.advertising == 1) {
@@ -291,10 +286,15 @@
if(BLE_STATUS_SUCCESS!=ret) {
PRINTF("error occurred while adding adv data (ret=0x%x)\n", ret);
switch (ret) {
- case BLE_STATUS_TIMEOUT:
- return BLE_STACK_BUSY;
- default:
- return BLE_ERROR_UNSPECIFIED;
+ case BLE_STATUS_TIMEOUT:
+ return BLE_STACK_BUSY;
+ case ERR_INVALID_HCI_CMD_PARAMS:
+ case BLE_STATUS_INVALID_PARAMS:
+ return BLE_ERROR_INVALID_PARAM;
+ case BLE_STATUS_FAILED:
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ default:
+ return BLE_ERROR_UNSPECIFIED;
}
}
}
@@ -311,8 +311,7 @@
/*
* ADV timeout callback
- */
-// ANDREA: mbedOS
+ */
#ifdef AST_FOR_MBED_OS
static void advTimeoutCB(void)
{
@@ -369,10 +368,11 @@
ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams ¶ms)
{
tBleStatus ret;
+ ble_error_t rc;
/* Make sure we support the advertising type */
if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
- /* ToDo: This requires a propery security implementation, etc. */
+ /* ToDo: This requires a proper security implementation, etc. */
return BLE_ERROR_NOT_IMPLEMENTED;
}
@@ -403,56 +403,77 @@
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
- /* set scan response data */
- ret = hci_le_set_scan_resp_data(scan_rsp_length, scan_response_payload);
- if(BLE_STATUS_SUCCESS!=ret) {
- PRINTF(" error while setting scan response data (ret=0x%x)\n", ret);
- switch (ret) {
- case BLE_STATUS_TIMEOUT:
- return BLE_STACK_BUSY;
- default:
- return BLE_ERROR_UNSPECIFIED;
+ /*
+ * 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;
}
}
- /*aci_gap_set_discoverable(Advertising_Event_Type, Adv_min_intvl, Adv_Max_Intvl, Addr_Type, Adv_Filter_Policy,
- Local_Name_Length, local_name, service_uuid_length, service_uuid_list, Slave_conn_intvl_min, Slave_conn_intvl_max);*/
- /*LINK_LAYER.H DESCRIBES THE ADVERTISING TYPES*/
+ 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) {
+
+ /* set scan response data */
+ PRINTF(" setting scan response data (scan_rsp_length=%u)\n", scan_rsp_length);
+ ret = hci_le_set_scan_resp_data(scan_rsp_length, scan_response_payload);
- // Enable the else branch if you want to set default device name
- char* name = NULL;
- uint8_t nameLen = 0;
- if(local_name!=NULL) {
- name = (char*)local_name;
- PRINTF("name=%s\n\r", name);
- nameLen = local_name_length;
- } /*else {
- char str[] = "ST_BLE_DEV";
- name = new char[strlen(str)+1];
- name[0] = AD_TYPE_COMPLETE_LOCAL_NAME;
- strcpy(name+1, str);
- nameLen = strlen(name);
- PRINTF("nameLen=%d\n\r", nameLen);
- PRINTF("name=%s\n\r", name);
- }*/
+ if(BLE_STATUS_SUCCESS!=ret) {
+ PRINTF(" error while setting scan response data (ret=0x%x)\n", ret);
+ switch (ret) {
+ case BLE_STATUS_TIMEOUT:
+ return BLE_STACK_BUSY;
+ default:
+ return BLE_ERROR_UNSPECIFIED;
+ }
+ }
+ } else {
+ hci_le_set_scan_resp_data(0, NULL);
+ }
- advtInterval = params.getIntervalInADVUnits(); // set advtInterval in case it is not already set by user application
- ret = aci_gap_set_discoverable(params.getAdvertisingType(), // Advertising_Event_Type
- advtInterval, // Adv_Interval_Min
- advtInterval, // Adv_Interval_Max
- PUBLIC_ADDR, // Address_Type
- NO_WHITE_LIST_USE, // Adv_Filter_Policy
- nameLen, //local_name_length, // Local_Name_Length
- (const char*)name, //local_name, // Local_Name
- servUuidlength, //Service_Uuid_Length
- servUuidData, //Service_Uuid_List
- 0, // Slave_Conn_Interval_Min
- 0); // Slave_Conn_Interval_Max
+ //advInterval = params.getIntervalInADVUnits();
+ setAdvParameters();
+ PRINTF("advInterval=%d advType=%d\n\r", advInterval, params.getAdvertisingType());
+
+ /* Setting discoverable mode */
+ ret = aci_gap_set_discoverable(params.getAdvertisingType(), // AdvType
+ advInterval, // AdvIntervMin
+ advInterval, // AdvIntervMax
+ addr_type, // OwnAddrType
+ advFilterPolicy, // AdvFilterPolicy
+ local_name_length, // LocalNameLen
+ (const char*)local_name, // LocalName
+ servUuidlength, // ServiceUUIDLen
+ servUuidData, // ServiceUUIDList
+ 0, // SlaveConnIntervMin
+ 0); // SlaveConnIntervMax
- PRINTF("!!!setting discoverable (servUuidlength=0x%x)\n", 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", 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;
@@ -467,16 +488,45 @@
}
}
+ // Stop Advertising if an error occurs while updating ADV data
+ rc = updateAdvertisingData();
+ if(rc != BLE_ERROR_NONE) {
+ aci_gap_set_non_discoverable();
+ return rc;
+ }
+
+ state.advertising = 1;
+
+ AdvToFlag = false;
+ if(params.getTimeout() != 0) {
+ PRINTF("!!! attaching to!!!\n");
+#ifdef AST_FOR_MBED_OS
+ minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout() * 1000));
+#else
+ advTimeout.attach(advTimeoutCB, params.getTimeout() * 1000);
+#endif
+ }
+
+ return BLE_ERROR_NONE;
+}
+
+ble_error_t BlueNRGGap::updateAdvertisingData(void)
+{
+ tBleStatus ret;
+
// Before updating the ADV data, delete COMPLETE_LOCAL_NAME and TX_POWER_LEVEL fields (if present)
- if(AdvLen>0) {
- if(name!=NULL) {
- PRINTF("!!!calling aci_gap_delete_ad_type AD_TYPE_COMPLETE_LOCAL_NAME!!!\n");
+ if(AdvLen > 0) {
+ if(local_name_length > 0) {
ret = aci_gap_delete_ad_type(AD_TYPE_COMPLETE_LOCAL_NAME);
if (BLE_STATUS_SUCCESS!=ret){
PRINTF("aci_gap_delete_ad_type failed return=%d\n", ret);
switch (ret) {
case BLE_STATUS_TIMEOUT:
return BLE_STACK_BUSY;
+ case ERR_COMMAND_DISALLOWED:
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ case ERR_INVALID_HCI_CMD_PARAMS:
+ return BLE_ERROR_INVALID_PARAM;
default:
return BLE_ERROR_UNSPECIFIED;
}
@@ -486,46 +536,48 @@
// If ADV Data Type is SERVICE DATA or MANUFACTURER SPECIFIC DATA,
// we need to delete it to make the needed room in ADV payload
if(AdvData[1]==AD_TYPE_SERVICE_DATA || AdvData[1]==AD_TYPE_MANUFACTURER_SPECIFIC_DATA) {
- PRINTF("!!!calling aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL)!!!\n");
ret = aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL);
if (BLE_STATUS_SUCCESS!=ret){
PRINTF("aci_gap_delete_ad_type failed return=%d\n", ret);
switch (ret) {
case BLE_STATUS_TIMEOUT:
return BLE_STACK_BUSY;
+ case ERR_COMMAND_DISALLOWED:
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ case ERR_INVALID_HCI_CMD_PARAMS:
+ return BLE_ERROR_INVALID_PARAM;
default:
return BLE_ERROR_UNSPECIFIED;
}
}
}
-
+
ret = aci_gap_update_adv_data(AdvLen, AdvData);
if(BLE_STATUS_SUCCESS!=ret) {
- PRINTF("error occurred while adding adv data (ret=0x%x)\n", ret);
+ PRINTF("error occurred while adding adv data (ret=0x%x)\n\r", ret);
switch (ret) {
case BLE_STATUS_TIMEOUT:
return BLE_STACK_BUSY;
+ case ERR_INVALID_HCI_CMD_PARAMS:
+ case BLE_STATUS_INVALID_PARAMS:
+ return BLE_ERROR_INVALID_PARAM;
+ case BLE_STATUS_FAILED:
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
default:
return BLE_ERROR_UNSPECIFIED;
}
}
-
+
} // AdvLen>0
- state.advertising = 1;
+ if(deviceAppearance != 0) {
+ uint8_t appearance[] = {3, AD_TYPE_APPEARANCE, deviceAppearance[0], deviceAppearance[1]};
+ // just ignore error code while setting appearance
+ aci_gap_update_adv_data(4, appearance);
+ }
- 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()));
-#else
- advTimeout.attach(advTimeoutCB, params.getTimeout());
-#endif
- }
-
return BLE_ERROR_NONE;
+
}
/**************************************************************************/
@@ -547,7 +599,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();
@@ -590,31 +642,22 @@
@endcode
*/
/**************************************************************************/
-ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason)
+ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason)
{
- /* avoid compiler warnings about unused variables */
- (void)reason;
+ tBleStatus ret;
- tBleStatus ret;
- //For Reason codes check BlueTooth HCI Spec
-
- if(m_connectionHandle != BLE_CONN_HANDLE_INVALID) {
- ret = aci_gap_terminate(m_connectionHandle, 0x16);//0x16 Connection Terminated by Local Host.
+ ret = aci_gap_terminate(connectionHandle, reason);
- if (BLE_STATUS_SUCCESS != ret){
- PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ;
- switch (ret) {
- case ERR_COMMAND_DISALLOWED:
- return BLE_ERROR_OPERATION_NOT_PERMITTED;
- case BLE_STATUS_TIMEOUT:
- return BLE_STACK_BUSY;
- default:
- return BLE_ERROR_UNSPECIFIED;
- }
+ if (BLE_STATUS_SUCCESS != ret){
+ PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ;
+ switch (ret) {
+ case ERR_COMMAND_DISALLOWED:
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ case BLE_STATUS_TIMEOUT:
+ return BLE_STACK_BUSY;
+ default:
+ return BLE_ERROR_UNSPECIFIED;
}
-
- //PRINTF("Disconnected from localhost!!\n\r") ;
- m_connectionHandle = BLE_CONN_HANDLE_INVALID;
}
return BLE_ERROR_NONE;
@@ -639,49 +682,24 @@
@endcode
*/
/**************************************************************************/
-ble_error_t BlueNRGGap::disconnect(Handle_t connectionHandle, Gap::DisconnectionReason_t reason)
+ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason)
{
- /* avoid compiler warnings about unused variables */
- (void)reason;
-
- tBleStatus ret;
- //For Reason codes check BlueTooth HCI Spec
-
- if(connectionHandle != BLE_CONN_HANDLE_INVALID) {
- ret = aci_gap_terminate(connectionHandle, 0x16);//0x16 Connection Terminated by Local Host.
-
- if (BLE_STATUS_SUCCESS != ret){
- PRINTF("Error in GAP termination (ret=0x%x)!!\n\r", ret) ;
- switch (ret) {
- case ERR_COMMAND_DISALLOWED:
- return BLE_ERROR_OPERATION_NOT_PERMITTED;
- case BLE_STATUS_TIMEOUT:
- return BLE_STACK_BUSY;
- default:
- return BLE_ERROR_UNSPECIFIED;
- }
- }
-
- //PRINTF("Disconnected from localhost!!\n\r") ;
- m_connectionHandle = BLE_CONN_HANDLE_INVALID;
- }
-
- return BLE_ERROR_NONE;
+ return disconnect(m_connectionHandle, reason);
}
/**************************************************************************/
/*!
@brief Sets the 16-bit connection handle
- @param[in] con_handle
+ @param[in] conn_handle
Connection Handle which is set in the Gap Instance
@returns void
*/
/**************************************************************************/
-void BlueNRGGap::setConnectionHandle(uint16_t con_handle)
+void BlueNRGGap::setConnectionHandle(uint16_t conn_handle)
{
- m_connectionHandle = con_handle;
+ m_connectionHandle = conn_handle;
}
/**************************************************************************/
@@ -719,21 +737,28 @@
@endcode
*/
/**************************************************************************/
-ble_error_t BlueNRGGap::setAddress(AddressType_t type, const Address_t address)
+ble_error_t BlueNRGGap::setAddress(AddressType_t type, const BLEProtocol::AddressBytes_t address)
{
+ tBleStatus ret;
+
if (type > BLEProtocol::AddressType::RANDOM_PRIVATE_NON_RESOLVABLE) {
return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
addr_type = type;
- //copy address to bdAddr[6]
- for(int i=0; i<BDADDR_SIZE; i++) {
- bdaddr[i] = address[i];
- //PRINTF("i[%d]:0x%x\n\r",i,bdaddr[i]);
+
+ // If Address Type is other than PUBLIC, the given Address is ignored
+ if(addr_type == BLEProtocol::AddressType::PUBLIC){
+ ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,
+ CONFIG_DATA_PUBADDR_LEN,
+ address);
+ if(ret != BLE_STATUS_SUCCESS) {
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
+ }
+ } else {
+ return BLE_ERROR_OPERATION_NOT_PERMITTED;
}
- if(!isSetAddress) isSetAddress = true;
-
return BLE_ERROR_NONE;
}
@@ -771,14 +796,20 @@
/**************************************************************************/
ble_error_t BlueNRGGap::getAddress(AddressType_t *typeP, Address_t address)
{
- *typeP = addr_type;//Gap::ADDR_TYPE_PUBLIC;
-
- if(isSetAddress)
- {
- for(int i=0; i<BDADDR_SIZE; i++) {
- address[i] = bdaddr[i];
- //PRINTF("i[%d]:0x%x\n\r",i,bdaddr[i]);
- }
+ uint8_t bdaddr[BDADDR_SIZE];
+ uint8_t data_len_out;
+
+ if(typeP != NULL) {
+ *typeP = addr_type;
+ }
+
+ 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);
}
return BLE_ERROR_NONE;
@@ -802,7 +833,7 @@
/* avoid compiler warnings about unused variables */
(void)params;
- return BLE_ERROR_NONE;
+ return BLE_ERROR_NOT_IMPLEMENTED;
}
@@ -824,7 +855,7 @@
/* avoid compiler warnings about unused variables */
(void)params;
- return BLE_ERROR_NONE;
+ return BLE_ERROR_NOT_IMPLEMENTED;
}
/**************************************************************************/
@@ -873,17 +904,14 @@
tBleStatus ret;
uint8_t nameLen = 0;
- DeviceName = (uint8_t *)deviceName;
- //PRINTF("SetDeviceName=%s\n\r", DeviceName);
-
- nameLen = strlen((const char*)DeviceName);
- //PRINTF("DeviceName Size=%d\n\r", nameLen);
-
- ret = aci_gatt_update_char_value(g_gap_service_handle,
- g_device_name_char_handle,
- 0,
- nameLen,
- (uint8_t *)DeviceName);
+ nameLen = strlen((const char*)deviceName);
+ PRINTF("DeviceName Size=%d\n\r", nameLen);
+
+ ret = aci_gatt_update_char_value(g_gap_service_handle,
+ g_device_name_char_handle,
+ 0,
+ nameLen,
+ deviceName);
if (BLE_STATUS_SUCCESS != ret){
PRINTF("device set name failed (ret=0x%x)!!\n\r", ret) ;
@@ -925,18 +953,20 @@
@endcode
*/
/**************************************************************************/
-ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP)
-{
- if(DeviceName==NULL)
- return BLE_ERROR_UNSPECIFIED;
-
- strcpy((char*)deviceName, (const char*)DeviceName);
- //PRINTF("GetDeviceName=%s\n\r", deviceName);
-
- *lengthP = strlen((const char*)DeviceName);
- //PRINTF("DeviceName Size=%d\n\r", *lengthP);
-
- return BLE_ERROR_NONE;
+ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP)
+{
+ tBleStatus ret;
+
+ ret = aci_gatt_read_handle_value(g_device_name_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE,
+ *lengthP,
+ (uint16_t *)lengthP,
+ deviceName);
+ PRINTF("getDeviceName ret=0x%02x (lengthP=%d)\n\r", ret, *lengthP);
+ if (ret == BLE_STATUS_SUCCESS) {
+ return BLE_ERROR_NONE;
+ } else {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
}
/**************************************************************************/
@@ -961,21 +991,19 @@
ble_error_t BlueNRGGap::setAppearance(GapAdvertisingData::Appearance appearance)
{
tBleStatus ret;
+ uint8_t deviceAppearance[2];
- /*
- Tested with GapAdvertisingData::GENERIC_PHONE.
- for other appearances BLE Scanner android app is not behaving properly
- */
- //char deviceAppearance[2];
STORE_LE_16(deviceAppearance, appearance);
PRINTF("input: incoming = %d deviceAppearance= 0x%x 0x%x\n\r", appearance, deviceAppearance[1], deviceAppearance[0]);
- ret = aci_gatt_update_char_value(g_gap_service_handle, g_appearance_char_handle, 0, 2, (uint8_t *)deviceAppearance);
+ ret = aci_gatt_update_char_value(g_gap_service_handle,
+ g_appearance_char_handle,
+ 0, 2, (uint8_t *)deviceAppearance);
if (BLE_STATUS_SUCCESS == ret){
return BLE_ERROR_NONE;
}
- PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret) ;
+ PRINTF("setAppearance failed (ret=0x%x)!!\n\r", ret);
switch (ret) {
case BLE_STATUS_INVALID_HANDLE:
case BLE_STATUS_INVALID_PARAMETER:
@@ -1010,70 +1038,20 @@
/**************************************************************************/
ble_error_t BlueNRGGap::getAppearance(GapAdvertisingData::Appearance *appearanceP)
{
- uint16_t devP;
- if(!appearanceP) return BLE_ERROR_PARAM_OUT_OF_RANGE;
- devP = ((uint16_t)(0x0000|deviceAppearance[0])) | (((uint16_t)(0x0000|deviceAppearance[1]))<<8);
- strcpy((char*)appearanceP, (const char*)&devP);
-
- return BLE_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*!
- @brief Gets the value of maximum advertising interval in ms
-
- @returns uint16_t
-
- @retval value of maximum advertising interval in ms
-
- @section EXAMPLE
-
- @code
-
- @endcode
-*/
-/**************************************************************************/
-uint16_t BlueNRGGap::getMaxAdvertisingInterval(void) const {
- return advtInterval;
-}
-
-
-/**************************************************************************/
-/*!
- @brief Gets the value of minimum advertising interval in ms
+ tBleStatus ret;
+ uint16_t lengthP = 2;
- @returns uint16_t
-
- @retval value of minimum advertising interval in ms
-
- @section EXAMPLE
-
- @code
-
- @endcode
-*/
-/**************************************************************************/
-uint16_t BlueNRGGap::getMinAdvertisingInterval(void) const {
- return 0; // minimum Advertising interval is 0
-}
+ ret = aci_gatt_read_handle_value(g_appearance_char_handle+BlueNRGGattServer::CHAR_VALUE_HANDLE,
+ lengthP,
+ &lengthP,
+ (uint8_t*)appearanceP);
+ PRINTF("getAppearance ret=0x%02x (lengthP=%d)\n\r", ret, lengthP);
+ if (ret == BLE_STATUS_SUCCESS) {
+ return BLE_ERROR_NONE;
+ } else {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
-/**************************************************************************/
-/*!
- @brief Gets the value of minimum non connectable advertising interval in ms
-
- @returns uint16_t
-
- @retval value of minimum non connectable advertising interval in ms
-
- @section EXAMPLE
-
- @code
-
- @endcode
-*/
-/**************************************************************************/
-uint16_t BlueNRGGap::getMinNonConnectableAdvertisingInterval(void) const {
- return BLE_GAP_ADV_NONCON_INTERVAL_MIN;
}
GapScanningParams* BlueNRGGap::getScanningParams(void)
@@ -1081,35 +1059,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;
@@ -1129,9 +1112,11 @@
type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED;
}
- PRINTF("adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n",
- addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
- processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data);
+ PRINTF("data_length=%d adv peerAddr[%02x %02x %02x %02x %02x %02x] \r\n",
+ *data_length, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
+ if(!_connecting) {
+ processAdvertisementReport(addr, *RSSI, isScanResponse, type, *data_length, data);
+ }
PRINTF("!!!After processAdvertisementReport\n\r");
}
break;
@@ -1139,27 +1124,25 @@
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
+#endif /* AST_FOR_MBED_OS */
+
break;
}
}
@@ -1168,41 +1151,64 @@
{
tBleStatus ret = BLE_STATUS_SUCCESS;
-
- PRINTF("Scanning...\n\r");
-
- // We received a start scan request from the application level.
- // If we are on X-NUCLEO-IDB04A1 (playing a single role at time),
- // we need to re-init our expansion board to specify the GAP CENTRAL ROLE
- if(!btle_reinited) {
- btle_init(isSetAddress, GAP_CENTRAL_ROLE_IDB04A1);
- btle_reinited = true;
-
- PRINTF("BTLE re-init\n\r");
+
+ // Stop ADV before scanning
+ /*
+ if (state.advertising == 1) {
+ stopAdvertising();
+ }
+ */
+
+ /*
+ * 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 = aci_gap_start_general_discovery_proc(scanningParams.getInterval(),
- scanningParams.getWindow(),
- addr_type,
- 1); // 1 to filter duplicates
-
- if (ret != BLE_STATUS_SUCCESS) {
- printf("Start Discovery Procedure failed (0x%02X)\n\r", ret);
- return BLE_ERROR_UNSPECIFIED;
- } else {
- PRINTF("Discovery Procedure Started\n");
+
+ 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;
- return BLE_ERROR_NONE;
+ return BLE_ERROR_NONE;
}
+
+ // 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");
+ return BLE_ERROR_NOT_IMPLEMENTED;
+ default:
+ PRINTF("Observation Procedure failed (0x%02X)\n\r", ret);
+ return BLE_ERROR_UNSPECIFIED;
+ }
+
}
ble_error_t BlueNRGGap::stopScan() {
tBleStatus ret = BLE_STATUS_SUCCESS;
-
- ret = aci_gap_terminate_gap_procedure(GENERAL_DISCOVERY_PROCEDURE);
+
+ 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(ret=0x%x)\n", ret);
return BLE_ERROR_UNSPECIFIED;
} else {
PRINTF("Discovery Procedure Terminated\n");
@@ -1224,18 +1230,15 @@
int8_t enHighPower = 0;
int8_t paLevel = 0;
- int8_t dbmActuallySet = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel);
+ ret = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel);
+ if(ret!=BLE_STATUS_SUCCESS) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
-#ifndef DEBUG
- /* avoid compiler warnings about unused variables */
- (void)dbmActuallySet;
-#endif
-
- PRINTF("txPower=%d, dbmActuallySet=%d\n\r", txPower, dbmActuallySet);
PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel);
ret = aci_hal_set_tx_power_level(enHighPower, paLevel);
if(ret!=BLE_STATUS_SUCCESS) {
- return BLE_ERROR_UNSPECIFIED;
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
}
return BLE_ERROR_NONE;
@@ -1250,36 +1253,113 @@
/**************************************************************************/
void BlueNRGGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) {
static const int8_t permittedTxValues[] = {
- -18, -14, -11, -8, -4, -1, 1, 5, -15, -11, -8, -5, -2, 1, 4, 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 advertising parameters according to the current state
+ Parameters value is set taking into account guidelines of the BlueNRG
+ time slots allocation
+*/
+/**************************************************************************/
+void BlueNRGGap::setAdvParameters(void)
+{
+ uint32_t advIntMS;
+
+ if(state.connected == 1) {
+ advIntMS = (conn_min_interval*1.25)-GUARD_INT;
+ advInterval = _advParams.MSEC_TO_ADVERTISEMENT_DURATION_UNITS(advIntMS);
+ } else {
+ advInterval = _advParams.getIntervalInADVUnits();
+ }
+}
+
+/**************************************************************************/
+/*!
+ @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() < advInterval) {
+ PRINTF("state.adv=1 scanInterval<advInterval\r\n");
+ scanInterval = advInterval;
+ scanWindow = advInterval;
+ } else {
+ PRINTF("state.adv=1 scanInterval>=advInterval\r\n");
+ scanInterval = _scanningParams.getInterval();
+ scanWindow = _scanningParams.getWindow();
+ }
+
+ if(advInterval>(MAX_INT_CONN-(GUARD_INT/1.25))) { //(4000-GUARD_INT)ms
+ conn_min_interval = MAX_INT_CONN;
+ conn_max_interval = MAX_INT_CONN;
+ } else {
+ conn_min_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25;
+ conn_max_interval = (_advParams.ADVERTISEMENT_DURATION_UNITS_TO_MS(advInterval)+GUARD_INT)/1.25;
+ }
+
+ } else {
+
+ PRINTF("state.adv = 0\r\n");
+
+ scanInterval = _scanningParams.getInterval();
+ scanWindow = _scanningParams.getWindow();
+ if(SCAN_DURATION_UNITS_TO_MSEC(scanInterval)>(MAX_INT_CONN*1.25) ||
+ SCAN_DURATION_UNITS_TO_MSEC(scanInterval)<(MIN_INT_CONN*1.25)) { //(4000)ms || (7.5)ms
+ conn_min_interval = DEF_INT_CONN;
+ conn_max_interval = DEF_INT_CONN;
+ } else {
+ 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=%u[msec]\r\n",(unsigned)(conn_min_interval*1.25));
+ PRINTF("conn_max_interval=%u[msec]\r\n",(unsigned)(conn_max_interval*1.25));
+
+}
+
ble_error_t BlueNRGGap::createConnection ()
{
tBleStatus ret;
-
+
+ /*
+ 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(SCAN_P,
- SCAN_L,
- PUBLIC_ADDR,
+ ret = aci_gap_create_connection(scanInterval,
+ scanWindow,
+ _peerAddrType,
(unsigned char*)_peerAddr,
- PUBLIC_ADDR,
- CONN_P1, CONN_P2, 0,
- SUPERV_TIMEOUT, CONN_L1 , CONN_L2);
+ addr_type,
+ conn_min_interval, conn_max_interval, 0,
+ SUPERV_TIMEOUT, CONN_L1, CONN_L1);
- _connecting = false;
+ //_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");
+ _connecting = false;
return BLE_ERROR_NONE;
}
}
@@ -1290,14 +1370,14 @@
const GapScanningParams *scanParams)
{
/* avoid compiler warnings about unused variables */
- (void)peerAddrType;
(void)connectionParams;
(void)scanParams;
- // Save the peer address
+ // Save the peer address
for(int i=0; i<BDADDR_SIZE; i++) {
_peerAddr[i] = peerAddr[i];
}
+ _peerAddrType = peerAddrType;
_connecting = true;
@@ -1310,3 +1390,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 Fri Mar 18 12:10:20 2016 +0100
+++ b/source/BlueNRGGattClient.cpp Mon Jun 20 14:59:06 2016 +0200
@@ -1,630 +1,816 @@
-/* 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.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 "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();
+
+ PRINTF("Starting aci_gatt_disc_all_charac_descriptors...\n\r");
+ 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;
+}
+
+>>>>>>> master
--- a/source/BlueNRGGattServer.cpp Fri Mar 18 12:10:20 2016 +0100
+++ b/source/BlueNRGGattServer.cpp Mon Jun 20 14:59:06 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);
@@ -229,10 +244,9 @@
/**************************************************************************/
/*!
- @brief Reads the value of a characteristic, based on the service
- and characteristic index fields
+ @brief Reads the value of a characteristic, based on char handle
- @param[in] charHandle
+ @param[in] attributeHandle
The handle of the GattCharacteristic to read from
@param[in] buffer
Buffer to hold the the characteristic's value
@@ -252,11 +266,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;
@@ -271,15 +286,17 @@
/**************************************************************************/
/*!
- @brief Updates the value of a characteristic, based on the service
- and characteristic index fields
+ @brief Reads the value of a characteristic, based on the connection
+ and char handle
- @param[in] charHandle
+ @param[in] connectionHandle
+ The handle of the connection
+ @param[in] attributeHandle
The handle of the GattCharacteristic to write to
@param[in] buffer
Data to use when updating the characteristic's value
(raw byte array in LSB format)
- @param[in] len
+ @param[in] lengthP
The number of bytes in buffer
@returns ble_error_t
@@ -294,8 +311,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 +325,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 +336,24 @@
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);
+ PRINTF("updating bleCharacteristic valueHandle=%u,\
+ corresponding serviceHandle=%u len=%d\n\r",
+ attributeHandle, bleCharHandleMap.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);
+ * If notifications (or indications) are enabled on that characteristic, a notification (or indication)
+ * will be sent to the client after sending this command to the BlueNRG.
+ */
+ 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);
@@ -341,15 +366,6 @@
}
}
- //Generate Data Sent Event Here? (GattServerEvents::GATT_EVENT_DATA_SENT) //FIXME: Is this correct?
- //Check if characteristic property is NOTIFY|INDICATE, if yes generate event
- GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(charHandle);
- if(p_char->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY
- | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) {
- PRINTF("Generate event after updating\n\r");
- BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_SENT, charHandle);
- }
-
return BLE_ERROR_NONE;
}
@@ -357,8 +373,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 +388,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 +411,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 +432,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 +447,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 +483,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 Fri Mar 18 12:10:20 2016 +0100
+++ b/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Mon Jun 20 14:59:06 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 Fri Mar 18 12:10:20 2016 +0100
+++ b/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Mon Jun 20 14:59:06 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 Fri Mar 18 12:10:20 2016 +0100
+++ b/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Mon Jun 20 14:59:06 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 Fri Mar 18 12:10:20 2016 +0100
+++ b/source/bluenrg-hci/hci/hci.c Mon Jun 20 14:59:06 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 Fri Mar 18 12:10:20 2016 +0100
+++ /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 Fri Mar 18 12:10:20 2016 +0100
+++ b/source/platform/btle.cpp Mon Jun 20 14:59:06 2016 +0200
@@ -42,13 +42,14 @@
#include "BlueNRGGattClient.h"
#include "Utils.h"
+#include "x_nucleo_idb0xa1_targets.h"
+
#ifdef __cplusplus
extern "C" {
#endif
/* C File Includes ------------------------------------------------------------------*/
-// ANDREA: Updated includes and changed some types (e.g., tHalUint8 --> uint8_t)
#include <stdio.h>
#include <string.h>
#include "hci.h"
@@ -72,10 +73,10 @@
#define IDB04A1 0
#define IDB05A1 1
-void HCI_Input(tHciDataPacket * hciReadPacket);
+/* See file 'x_nucleo_idb0xa1_targets.h' for details regarding the IDB0XA1 STACK_MODE */
+#define STACK_MODE IDB0XA1_STACK_MODE
-//#define BDADDR_SIZE 6
-//tHalUint8 bdaddr[BDADDR_SIZE]= {0xaa, 0x00, 0x00, 0xE1, 0x80, 0x02};
+void HCI_Input(tHciDataPacket * hciReadPacket);
uint16_t g_gap_service_handle = 0;
uint16_t g_appearance_char_handle = 0;
@@ -83,12 +84,10 @@
/* Private variables ---------------------------------------------------------*/
volatile uint8_t set_connectable = 1;
-// ANDREA
+
+static char versionString[32];
uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */
-Gap::Address_t bleAddr;
-Gap::AddressType_t addr_type = BLEProtocol::AddressType::PUBLIC;
-
/**************************************************************************/
/*!
@brief Initialises BTLE and the underlying HW/Device
@@ -99,9 +98,11 @@
@returns void
*/
/**************************************************************************/
-void btle_init(bool isSetAddress, uint8_t role)
+void btleInit(bool isSetAddress, uint8_t role)
{
- PRINTF("btle_init>>\n\r");
+ PRINTF("btleInit>>\n\r");
+ /* Avoid compiler warnings about unused variables. */
+ (void)isSetAddress;
int ret;
uint8_t hwVersion;
@@ -133,35 +134,54 @@
bnrg_expansion_board = IDB05A1;
}
+ /* set BLE version string */
+ setVersionString(hwVersion, fwVersion);
+
+ if (bnrg_expansion_board == IDB05A1) {
+ uint8_t stackMode = STACK_MODE;
+ ret = aci_hal_write_config_data(CONFIG_DATA_ROLE,
+ CONFIG_DATA_ROLE_LEN,
+ &stackMode);
+ }
+
/* The Nucleo board must be configured as SERVER */
- //check if isSetAddress is set than set address.
- // ANDREA
+ //check if isSetAddress is set then set address.
+#if 0
if(isSetAddress)
{
+ Gap::Address_t bleAddr;
+ Gap::AddressType_t addr_type;
+
BlueNRGGap::getInstance().getAddress(&addr_type, bleAddr);
-
- Gap::Address_t bdaddr;
- Osal_MemCpy(bdaddr, bleAddr, BDADDR_SIZE);
ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,
CONFIG_DATA_PUBADDR_LEN,
- bdaddr);
+ bleAddr);
} else {
const Gap::Address_t BLE_address_BE = {0xFD,0x66,0x05,0x13,0xBE,0xBA};
- BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::PUBLIC, BLE_address_BE);
+ BlueNRGGap::getInstance().setAddress(BLEProtocol::AddressType::RANDOM_STATIC, BLE_address_BE);
ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET,
CONFIG_DATA_PUBADDR_LEN,
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, 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);
}
@@ -170,7 +190,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,
@@ -192,7 +212,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
@@ -201,7 +220,7 @@
/**************************************************************************/
/*!
- @brief Andrea: mbedOS
+ @brief mbedOS
@param[in] void
@@ -218,6 +237,47 @@
}
#endif
+/* set BLE Version string */
+void setVersionString(uint8_t hwVersion, uint16_t fwVersion)
+{
+ if(bnrg_expansion_board == IDB04A1 || bnrg_expansion_board == IDB05A1) {
+ snprintf(versionString, sizeof(versionString), "ST BLE4.1 HW v%u.%u FW v%u.%u",
+ hwVersion>>4, (hwVersion&0x0F),
+ fwVersion>>8, (fwVersion&0x00F0)>>4);
+ } else {
+ snprintf(versionString, sizeof(versionString), "ST (unknown spec)");
+ }
+}
+
+/* get BLE Version string */
+const char* getVersionString(void)
+{
+ return versionString;
+}
+
+tBleStatus btleStartRadioScan(uint8_t scan_type,
+ uint16_t scan_interval,
+ uint16_t scan_window,
+ uint8_t own_address_type)
+{
+ tBleStatus ret;
+
+ // Observer role is not supported by X-NUCLEO-IDB04A1, return BLE_ERROR_NOT_IMPLEMENTED
+ if(bnrg_expansion_board == IDB05A1) {
+ PRINTF("scan_interval=%d scan_window=%d\n\r", scan_interval, scan_window);
+ PRINTF("scan_type=%d own_address_type=%d\n\r", scan_type, own_address_type);
+ ret = aci_gap_start_observation_procedure(scan_interval,
+ scan_window,
+ scan_type,
+ own_address_type,
+ 0); // 1 to filter duplicates
+ } else {
+ ret = BLE_STATUS_INVALID_CID;
+ }
+
+ return ret;
+
+}
/*!
@brief Not Used
@@ -232,20 +292,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);
@@ -253,18 +336,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) {
@@ -272,21 +357,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);
}
}
}
@@ -312,7 +398,7 @@
hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data;
if(hci_pckt->type != HCI_EVENT_PKT)
- return;
+ return;
switch(event_pckt->evt){
@@ -320,9 +406,9 @@
{
PRINTF("EVT_DISCONN_COMPLETE\n");
- evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt;
+ evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt->data;
- BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, BlueNRGGap::REMOTE_USER_TERMINATED_CONNECTION);
+ BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, (Gap::DisconnectionReason_t)evt->reason);
}
break;
@@ -333,11 +419,15 @@
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");
- Gap::AddressType_t peerAddrType = BLEProtocol::AddressType::PUBLIC;
+ Gap::Address_t ownAddr;
+ Gap::AddressType_t ownAddrType;
+ BlueNRGGap::getInstance().getAddress(&ownAddrType, ownAddr);
+
+ Gap::AddressType_t peerAddrType = BLEProtocol::AddressType::RANDOM_STATIC;
Gap::Role_t role;
evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data;
@@ -372,7 +462,13 @@
break;
}
//PRINTF("EVT_LE_CONN_COMPLETE GAP role=%d\n", role);
- BlueNRGGap::getInstance().processConnectionEvent(cc->handle, role/*Gap::PERIPHERAL*/, peerAddrType, cc->peer_bdaddr, addr_type, bleAddr, (const BlueNRGGap::ConnectionParams_t *)&connectionParams);
+ BlueNRGGap::getInstance().processConnectionEvent(cc->handle,
+ role,
+ peerAddrType,
+ cc->peer_bdaddr,
+ ownAddrType,
+ ownAddr,
+ &connectionParams);
}
break;
@@ -388,7 +484,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],
@@ -409,7 +505,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;
@@ -418,13 +515,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;
@@ -505,9 +596,18 @@
pr->handles_info_list);
}
break;
- case EVT_BLUE_GATT_PROCEDURE_COMPLETE:
+ case EVT_BLUE_ATT_FIND_INFORMATION_RESP:
{
- //PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE\n\r");
+ 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:
+ {
evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data;
PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE error_code=%d\n\r", evt->error_code);
BlueNRGGattClient::getInstance().gattProcedureCompleteCB(evt->conn_handle, evt->error_code);
@@ -516,13 +616,12 @@
case EVT_BLUE_GAP_DEVICE_FOUND:
{
- PRINTF("EVT_BLUE_GAP_DEVICE_FOUND\n\r");
evt_gap_device_found *pr = (evt_gap_device_found*)blue_evt->data;
PRINTF("EVT_BLUE_GAP_DEVICE_FOUND evt_type=%d\n\r", pr->evt_type);
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],
@@ -533,13 +632,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_LIMITED_DISCOVERY_PROC:
- case GAP_GENERAL_DISCOVERY_PROC:
+ 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 Fri Mar 18 12:10:20 2016 +0100
+++ /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/source/utils/Payload.cpp Fri Mar 18 12:10:20 2016 +0100
+++ b/source/utils/Payload.cpp Mon Jun 20 14:59:06 2016 +0200
@@ -98,4 +98,21 @@
serializedAdData[i+1] = data[i];
}
return serializedAdData;
-}
+}
+
+Payload::~Payload() {
+ int i = 0;
+
+ if(payload) {
+ while(i<payloadUnitCount) {
+ if(payload->data) {
+ delete[] payload->data;
+ payload->data = NULL;
+ }
+ }
+ delete[] payload;
+ payload = NULL;
+ }
+
+}
+
--- a/source/utils/Utils.cpp Fri Mar 18 12:10:20 2016 +0100
+++ b/source/utils/Utils.cpp Mon Jun 20 14:59:06 2016 +0200
@@ -20,106 +20,74 @@
/*!
@brief sets values of EN_HIGH_POWER and PA_LEVEL corresponding to dBMLevel of tx power
- @returns value of tx power in dbm actually set
-
- @params[in] dBMLevel
- dBMLevel of tx power to be set
-
- @params[in] dBMLevel
- dBMLevel of tx power to be set
-
- @endcode
*/
/**************************************************************************/
-double getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) {
- double dbm = (double) dBMLevel;
- if(dbm<-18.0) {
- dbm = -18;
+tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL) {
+ tBleStatus ret = BLE_STATUS_SUCCESS;
+
+ if(dBMLevel==-18) {
EN_HIGH_POWER = 0;
PA_LEVEL = 0;
}
- else if(dbm>8.0) {
- dbm = 8;
- EN_HIGH_POWER = 1;
- PA_LEVEL = 7;
+ else if(dBMLevel==-15) {
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 1;
}
-
- // As a policy we are setting tx power level to the higher side
- if((dbm>-18.0) && (dbm<=-15)) {
- // set tx power to -15dBM
- EN_HIGH_POWER = 0;
+ else if(dBMLevel==-14) {
+ EN_HIGH_POWER = 1;
PA_LEVEL = 0;
}
- else if((dbm>-15) && (dbm<=-14.7)) {
- // set tx power to -14.7dBM
+ else if(dBMLevel==-12) {
EN_HIGH_POWER = 0;
- PA_LEVEL = 1;
+ PA_LEVEL = 2;
}
- else if((dbm>-14.7) && (dbm<=-11.7)) {
- // set tx power to -11.7dBM
+ else if(dBMLevel==-11) {
EN_HIGH_POWER = 1;
- PA_LEVEL = 1;
- }
- else if((dbm>-11.7) && (dbm<=-11.4)) {
- // set tx power to -11.4dBM
+ PA_LEVEL = 1;
+ }
+ else if(dBMLevel==-9) {
EN_HIGH_POWER = 0;
- PA_LEVEL = 2;
+ PA_LEVEL = 3;
}
- else if((dbm>-11.4) && (dbm<=-8.4)) {
- // set tx power to -8.4dBM
+ else if(dBMLevel==-8) {
EN_HIGH_POWER = 1;
- PA_LEVEL = 2;
- }
- else if((dbm>-8.4) && (dbm<=-8.1)) {
- // set tx power to -8.1dBM
- EN_HIGH_POWER = 0;
- PA_LEVEL = 3;
+ PA_LEVEL = 2;
}
- else if((dbm>-8.1) && (dbm<=-5.1)) {
- // set tx power to -5.1dBM
+ else if(dBMLevel==-6) {
+ EN_HIGH_POWER = 0;
+ PA_LEVEL = 4;
+ }
+ else if(dBMLevel==-5) {
EN_HIGH_POWER = 1;
- PA_LEVEL = 3;
- }
- else if((dbm>-5.1) && (dbm<=-4.9)) {
- // set tx power to -4.9dBM
- EN_HIGH_POWER = 0;
- PA_LEVEL = 4;
+ PA_LEVEL = 3;
}
- else if((dbm>-4.9) && (dbm<=-2.1)) {
- // set tx power to -2.1dBM
+ else if(dBMLevel==-2) {
EN_HIGH_POWER = 1;
- PA_LEVEL = 4;
+ PA_LEVEL = 4;
}
- else if((dbm>-2.1) && (dbm<=-1.6)) {
- // set tx power to -1.6dBM
- EN_HIGH_POWER = 0;
- PA_LEVEL = 5;
- }
- else if((dbm>-1.6) && (dbm<=1.4)) {
- // set tx power to -1.6dBM
- EN_HIGH_POWER = 1;
- PA_LEVEL = 5;
- }
- else if((dbm>1.4) && (dbm<=1.7)) {
- // set tx power to 1.7dBM
+ else if(dBMLevel==0) {
EN_HIGH_POWER = 0;
- PA_LEVEL = 6;
+ PA_LEVEL = 6;
}
- else if((dbm>1.7) && (dbm<=4.7)) {
- // set tx power to 4.7dBM
+ else if(dBMLevel==2) {
EN_HIGH_POWER = 1;
- PA_LEVEL = 6;
- }
- else if((dbm>4.7) && (dbm<=5.0)) {
- // set tx power to 5.0dBM
+ PA_LEVEL = 5;
+ }
+ else if(dBMLevel==4) {
+ EN_HIGH_POWER = 1;
+ PA_LEVEL = 6;
+ }
+ else if(dBMLevel==5) {
EN_HIGH_POWER = 0;
- PA_LEVEL = 7;
+ PA_LEVEL = 7;
}
- else if((dbm>5.0) && (dbm<=8)) {
- // set tx power to 8.0dBM
+ else if(dBMLevel==8) {
EN_HIGH_POWER = 1;
- PA_LEVEL = 7;
- }
-
- return dbm;
+ PA_LEVEL = 7;
+ }
+ else {
+ ret = ERR_INVALID_HCI_CMD_PARAMS;
+ }
+
+ return ret;
}
--- a/x-nucleo-idb0xa1/BlueNRGDevice.h Fri Mar 18 12:10:20 2016 +0100
+++ b/x-nucleo-idb0xa1/BlueNRGDevice.h Mon Jun 20 14:59:06 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 Fri Mar 18 12:10:20 2016 +0100
+++ b/x-nucleo-idb0xa1/BlueNRGDiscoveredCharacteristic.h Mon Jun 20 14:59:06 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 Fri Mar 18 12:10:20 2016 +0100
+++ b/x-nucleo-idb0xa1/BlueNRGGap.h Mon Jun 20 14:59:06 2016 +0200
@@ -45,25 +45,29 @@
#define BLE_CONN_HANDLE_INVALID 0x0
#define BDADDR_SIZE 6
-#define BLUENRG_GAP_ADV_INTERVAL_MIN (0)
-#define BLUENRG_GAP_ADV_INTERVAL_MAX (0)
-#define BLE_GAP_ADV_NONCON_INTERVAL_MIN (0)
+#define BLUENRG_GAP_ADV_INTERVAL_MIN (0x0020)
+#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 LIMITED_DISCOVERY_PROCEDURE 0x01
-#define GENERAL_DISCOVERY_PROCEDURE 0x02
+#define GAP_OBSERVATION_PROC (0x80)
-#define SCAN_P (0x4000)
-#define SCAN_L (0x4000)
-#define SUPERV_TIMEOUT (600)
+#define SCAN_P (0x0010)
+#define SCAN_L (0x0010)
+#define SUPERV_TIMEOUT (0xC80)
#define CONN_P(x) ((int)((x)/1.25f))
#define CONN_L(x) ((int)((x)/0.625f))
-#define CONN_P1 (CONN_P(50))//(CONN_P(1000))
-#define CONN_P2 (CONN_P(50))//(CONN_P(1000))
-#define CONN_L1 (CONN_L(5))
-#define CONN_L2 (CONN_L(5))
+#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 (0x0008)
+#define CONN_L2 (0x0008)
+#define GUARD_INT 5 //msec
+#define MIN_INT_CONN 0x0006 //=>7.5msec
+#define MAX_INT_CONN 0x0C80 //=>4000msec
+#define DEF_INT_CONN 0x0140 //=>400msec (default value for connection interval)
-#define UUID_BUFFER_SIZE 17 //Either 8*2(16-bit UUIDs) or 4*4(32-bit UUIDs) or 1*16(128-bit UUIDs) +1
+#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)
#define ADV_DATA_MAX_SIZE 31
/**************************************************************************/
@@ -80,15 +84,6 @@
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
@@ -101,9 +96,9 @@
virtual ble_error_t startAdvertising(const GapAdvertisingParams &);
virtual ble_error_t stopAdvertising(void);
virtual ble_error_t stopScan();
- virtual uint16_t getMinAdvertisingInterval(void) const;
- virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const;
- virtual uint16_t getMaxAdvertisingInterval(void) const;
+ virtual uint16_t getMinAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MIN);}
+ virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_NONCON_INTERVAL_MIN);}
+ virtual uint16_t getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLUENRG_GAP_ADV_INTERVAL_MAX);}
virtual ble_error_t disconnect(DisconnectionReason_t reason);
virtual ble_error_t disconnect(Handle_t connectionHandle, DisconnectionReason_t reason);
virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params);
@@ -114,19 +109,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,16 +157,15 @@
uint16_t m_connectionHandle;
AddressType_t addr_type;
Address_t _peerAddr;
+ AddressType_t _peerAddrType;
uint8_t bdaddr[BDADDR_SIZE];
bool _scanning;
bool _connecting;
bool isSetAddress;
- bool btle_reinited;
- uint8_t *DeviceName;
uint8_t deviceAppearance[2];
- uint8_t *local_name;
uint8_t local_name_length;
+ uint8_t local_name[LOCAL_NAME_MAX_SIZE];
uint8_t servUuidlength;
uint8_t servUuidData[UUID_BUFFER_SIZE];
@@ -176,12 +176,38 @@
Timeout advTimeout;
bool AdvToFlag;
+ const uint8_t *scan_response_payload;
+ uint8_t scan_rsp_length;
+
+ static uint16_t SCAN_DURATION_UNITS_TO_MSEC(uint16_t duration) {
+ return (duration * 625) / 1000;
+ }
+
+ uint16_t scanInterval;
+ uint16_t scanWindow;
+ uint16_t advInterval;
+ uint16_t conn_min_interval;
+ uint16_t conn_max_interval;
+ void setAdvParameters(void);
+ void setConnectionParameters(void);
+
+ Gap::AdvertisingPolicyMode_t advertisingPolicyMode;
+ Gap::ScanningPolicyMode_t scanningPolicyMode;
+
+ Whitelist_t whitelistAddresses;
+
+ ble_error_t updateAdvertisingData(void);
+
BlueNRGGap() {
m_connectionHandle = BLE_CONN_HANDLE_INVALID;
- addr_type = BLEProtocol::AddressType::PUBLIC;
+ 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_IGNORE_WHITELIST;
+
isSetAddress = false;
- btle_reinited = false;
- DeviceName = NULL;
+ memset(deviceAppearance, 0, sizeof(deviceAppearance));
}
BlueNRGGap(BlueNRGGap const &);
--- a/x-nucleo-idb0xa1/BlueNRGGattClient.h Fri Mar 18 12:10:20 2016 +0100
+++ b/x-nucleo-idb0xa1/BlueNRGGattClient.h Mon Jun 20 14:59:06 2016 +0200
@@ -1,162 +1,182 @@
-/* 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.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.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 Fri Mar 18 12:10:20 2016 +0100
+++ b/x-nucleo-idb0xa1/BlueNRGGattServer.h Mon Jun 20 14:59:06 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 Fri Mar 18 12:10:20 2016 +0100
+++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_aci_const.h Mon Jun 20 14:59:06 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.h Fri Mar 18 12:10:20 2016 +0100 +++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gap.h Mon Jun 20 14:59:06 2016 +0200 @@ -129,10 +129,13 @@ */ /* service data AD type */ -#define AD_TYPE_SERVICE_DATA (0x16) +#define AD_TYPE_SERVICE_DATA (0x16) /* manufaturer specific data AD type */ -#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF) +#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF) + +/* appearance AD type */ +#define AD_TYPE_APPEARANCE (0x19) /** * @}
--- a/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gap_aci.h Fri Mar 18 12:10:20 2016 +0100
+++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gap_aci.h Mon Jun 20 14:59:06 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.
@@ -1055,7 +1062,7 @@
* @arg 0x01: Filter duplicates
* @return Value indicating success or error code.
*/
-tBleStatus aci_gap_start_observation_procedure_IDB05A1(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type,
+tBleStatus aci_gap_start_observation_procedure(uint16_t scan_interval, uint16_t scan_window, uint8_t scan_type,
uint8_t own_address_type, uint8_t filter_duplicates);
/**
--- a/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gatt_aci.h Fri Mar 18 12:10:20 2016 +0100
+++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gatt_aci.h Mon Jun 20 14:59:06 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 Fri Mar 18 12:10:20 2016 +0100
+++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_hal_aci.h Mon Jun 20 14:59:06 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 Fri Mar 18 12:10:20 2016 +0100
+++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_l2cap_aci.h Mon Jun 20 14:59:06 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 Fri Mar 18 12:10:20 2016 +0100
+++ b/x-nucleo-idb0xa1/bluenrg-hci/hci.h Mon Jun 20 14:59:06 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 Fri Mar 18 12:10:20 2016 +0100 +++ b/x-nucleo-idb0xa1/bluenrg-hci/hci_const.h Mon Jun 20 14:59:06 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/btle.h Fri Mar 18 12:10:20 2016 +0100 +++ b/x-nucleo-idb0xa1/platform/btle.h Mon Jun 20 14:59:06 2016 +0200 @@ -38,10 +38,16 @@ extern uint16_t g_appearance_char_handle; extern uint16_t g_device_name_char_handle; -void btle_init(bool isSetAddress, uint8_t role); +void btleInit(bool isSetAddress, uint8_t role); void SPI_Poll(void); void User_Process(void); void setConnectable(void); +void setVersionString(uint8_t hwVersion, uint16_t fwVersion); +const char* getVersionString(void); +tBleStatus btleStartRadioScan(uint8_t scan_type, + uint16_t scan_interval, + uint16_t scan_window, + uint8_t own_address_type); #ifdef AST_FOR_MBED_OS extern int btle_handler_pending;
--- a/x-nucleo-idb0xa1/platform/stm32_bluenrg_ble_dma_lp.h Fri Mar 18 12:10:20 2016 +0100
+++ /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****/
-
--- a/x-nucleo-idb0xa1/utils/Payload.h Fri Mar 18 12:10:20 2016 +0100
+++ b/x-nucleo-idb0xa1/utils/Payload.h Mon Jun 20 14:59:06 2016 +0200
@@ -67,6 +67,7 @@
public:
Payload(const uint8_t *tokenString, uint8_t string_ength);
Payload();
+ ~Payload();
uint8_t getPayloadUnitCount();
uint8_t getIDAtIndex(int index);
@@ -180,7 +181,11 @@
int getPayloadUnitCount() { return payloadUnitCount; }
-
+ ~PayloadPtr() {
+ if(unit) delete[] unit;
+
+ unit = NULL;
+ }
};
#endif // __PAYLOAD_H__
--- a/x-nucleo-idb0xa1/utils/Utils.h Fri Mar 18 12:10:20 2016 +0100
+++ b/x-nucleo-idb0xa1/utils/Utils.h Mon Jun 20 14:59:06 2016 +0200
@@ -20,6 +20,7 @@
#ifndef __UTIL_H__
#define __UTIL_H__
+#include "ble_status.h"
#include "hal_types.h"
#include "mbed.h"
@@ -40,7 +41,7 @@
}while(0)
-double getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL);
+tBleStatus getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL);
#endif // __UTIL_H__
--- a/x-nucleo-idb0xa1/x_nucleo_idb0xa1_targets.h Fri Mar 18 12:10:20 2016 +0100 +++ b/x-nucleo-idb0xa1/x_nucleo_idb0xa1_targets.h Mon Jun 20 14:59:06 2016 +0200 @@ -62,4 +62,14 @@ #define IDB0XA1_PIN_SPI_SCK (D3) #endif // !defined(IDB0XA1_D13_PATCH) +/* NOTE: Stack Mode 0x04 allows Simultaneous Scanning and Advertisement (SSAdv) + Define macro 'SSADV' to enable it +*/ +//#define SSADV +#if defined(SSADV) +#define IDB0XA1_STACK_MODE (0x04) +#else +#define IDB0XA1_STACK_MODE (0x02) +#endif + #endif // _X_NUCLEO_IDB0XA1_TARGETS_H_