Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of X_NUCLEO_IDB0XA1 by
Revision 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_
