test
Dependents: BLE_HeartRate_IDB0XA1_EPUDEE_Avril2018
Fork of X_NUCLEO_IDB0XA1 by
Revision 132:51056160fa4a, committed 2015-10-07
- Comitter:
- Wolfgang Betz
- Date:
- Wed Oct 07 08:39:04 2015 +0200
- Parent:
- 131:e09947216ccb
- Child:
- 133:1bb8df697f7f
- Commit message:
- Andrea's version as of mail from 10/06/2015 05:56 PM
From: Andrea PALMIERI <andrea.palmieri@st.com>
To: Wolfgang BETZ <wolfgang.betz@st.com>, Rohit Grover <rohit.grover@arm.com>,
Antonio VILEI <antonio.vilei@st.com>, Mihail Stoyanov
<Mihail.Stoyanov@arm.com>
CC: Nicola CAPOVILLA <nicola.capovilla@st.com>, Silvio Lucio OLIVA
<silvio.oliva@st.com>, "jonathan.austin@arm.com" <jonathan.austin@arm.com>
Content-Class: urn:content-classes:message
Date: Tue, 6 Oct 2015 17:56:34 +0200
Subject: RE: Arduino Compatibility of X-NUCLEO-IDB04A1
Changed in this revision
--- a/module.json Tue Oct 06 15:19:19 2015 +0200 +++ b/module.json Wed Oct 07 08:39:04 2015 +0200 @@ -18,14 +18,14 @@ "type": "Apache-2.0" } ], - "extraIncludes": [ + "extraIncludes": [ "x-nucleo-idb0xa1", - "x-nucleo-idb0xa1/utils/inc", - "x-nucleo-idb0xa1/platform/inc", - "x-nucleo-idb0xa1/BlueNRG_HCI/includes", - "x-nucleo-idb0xa1/platform/X-NUCLEO-IDB04A1" + "x-nucleo-idb0xa1/utils", + "x-nucleo-idb0xa1/platform", + "x-nucleo-idb0xa1/bluenrg-hci" ], "dependencies": { - "ble": "*" + "ble": "*", + "core-util": "~0.2.0" } }
--- a/source/BlueNRGDevice.cpp Tue Oct 06 15:19:19 2015 +0200 +++ b/source/BlueNRGDevice.cpp Wed Oct 07 08:39:04 2015 +0200 @@ -133,7 +133,8 @@ irq_.rise(&HCI_Isr); /* ToDo: Clear memory contents, reset the SD, etc. */ - btle_init(BlueNRGGap::getInstance().getIsSetAddress()); + // By default, we set the device GAP role to PERIPHERAL + btle_init(BlueNRGGap::getInstance().getIsSetAddress(), GAP_PERIPHERAL_ROLE_IDB04A1); isInitialized = true;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/BlueNRGDiscoveredCharacteristic.cpp Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,60 @@ +/* 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(); +}
--- a/source/BlueNRGGap.cpp Tue Oct 06 15:19:19 2015 +0200 +++ b/source/BlueNRGGap.cpp Wed Oct 07 08:39:04 2015 +0200 @@ -44,6 +44,7 @@ #include "mbed.h" #include "Payload.h" #include "Utils.h" +#include "debug.h" //Local Variables //const char *local_name = NULL; @@ -101,7 +102,7 @@ /**************************************************************************/ ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) { - DEBUG("BlueNRGGap::setAdvertisingData\n\r"); + PRINTF("BlueNRGGap::setAdvertisingData\n\r"); /* Make sure we don't exceed the advertising payload length */ if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) { return BLE_ERROR_BUFFER_OVERFLOW; @@ -115,17 +116,17 @@ for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) { loadPtr.getUnitAtIndex(index); - DEBUG("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr())); - DEBUG("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr())); + PRINTF("adData[%d].length=%d\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getLenPtr())); + PRINTF("adData[%d].AdType=0x%x\n\r", index,(uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr())); switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) { case GapAdvertisingData::FLAGS: /* ref *Flags */ { - DEBUG("Advertising type: FLAGS\n\r"); + PRINTF("Advertising type: FLAGS\n\r"); //Check if Flags are OK. BlueNRG only supports LE Mode. uint8_t *flags = loadPtr.getUnitAtIndex(index).getDataPtr(); if((*flags & GapAdvertisingData::BREDR_NOT_SUPPORTED) != GapAdvertisingData::BREDR_NOT_SUPPORTED) { - DEBUG("BlueNRG does not support BR/EDR Mode"); + PRINTF("BlueNRG does not support BR/EDR Mode"); return BLE_ERROR_PARAM_OUT_OF_RANGE; } @@ -134,7 +135,7 @@ case GapAdvertisingData::INCOMPLETE_LIST_16BIT_SERVICE_IDS: /**< Incomplete list of 16-bit Service IDs */ case GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS: /**< Complete list of 16-bit Service IDs */ { - DEBUG("Advertising type: INCOMPLETE_LIST_16BIT_SERVICE_IDS/COMPLETE_LIST_16BIT_SERVICE_IDS\n\r"); + PRINTF("Advertising type: INCOMPLETE_LIST_16BIT_SERVICE_IDS/COMPLETE_LIST_16BIT_SERVICE_IDS\n\r"); uint8_t buffSize = *loadPtr.getUnitAtIndex(index).getLenPtr()-1; // The total lenght should include the Data Type Value @@ -145,38 +146,38 @@ servUuidlength = buffSize+1; // +1 to include the Data Type Value servUuidData[0] = (uint8_t)(*loadPtr.getUnitAtIndex(index).getAdTypePtr()); //Data Type Value - DEBUG("servUuidlength=%d servUuidData[0]=%d buffSize=%d\n\r", servUuidlength, servUuidData[0], buffSize); + PRINTF("servUuidlength=%d servUuidData[0]=%d buffSize=%d\n\r", servUuidlength, servUuidData[0], buffSize); // Save the Service UUID list just after the Data Type Value field memcpy(servUuidData+1, loadPtr.getUnitAtIndex(index).getDataPtr(), buffSize); for(unsigned i=0; i<servUuidlength; i++) { - DEBUG("servUuidData[%d] = 0x%x\n\r", i, servUuidData[i]); + PRINTF("servUuidData[%d] = 0x%x\n\r", i, servUuidData[i]); } for(unsigned i=0; i<buffSize; i++) { - DEBUG("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]); } break; } case GapAdvertisingData::INCOMPLETE_LIST_32BIT_SERVICE_IDS: /**< Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */ { - DEBUG("Advertising type: INCOMPLETE_LIST_32BIT_SERVICE_IDS\n\r"); + PRINTF("Advertising type: INCOMPLETE_LIST_32BIT_SERVICE_IDS\n\r"); return BLE_ERROR_NOT_IMPLEMENTED; } case GapAdvertisingData::COMPLETE_LIST_32BIT_SERVICE_IDS: /**< Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */ { - DEBUG("Advertising type: COMPLETE_LIST_32BIT_SERVICE_IDS\n\r"); + PRINTF("Advertising type: COMPLETE_LIST_32BIT_SERVICE_IDS\n\r"); return BLE_ERROR_NOT_IMPLEMENTED; } case GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS: /**< Incomplete list of 128-bit Service IDs */ { - DEBUG("Advertising type: INCOMPLETE_LIST_128BIT_SERVICE_IDS\n\r"); + PRINTF("Advertising type: INCOMPLETE_LIST_128BIT_SERVICE_IDS\n\r"); return BLE_ERROR_NOT_IMPLEMENTED; } case GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS: /**< Complete list of 128-bit Service IDs */ { - DEBUG("Advertising type: COMPLETE_LIST_128BIT_SERVICE_IDS\n\r"); + PRINTF("Advertising type: COMPLETE_LIST_128BIT_SERVICE_IDS\n\r"); return BLE_ERROR_NOT_IMPLEMENTED; } case GapAdvertisingData::SHORTENED_LOCAL_NAME: /**< Shortened Local Name */ @@ -185,27 +186,27 @@ } case GapAdvertisingData::COMPLETE_LOCAL_NAME: /**< Complete Local Name */ { - DEBUG("Advertising type: COMPLETE_LOCAL_NAME\n\r"); + 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(); - DEBUG("Advertising type: COMPLETE_LOCAL_NAME local_name=%s\n\r", local_name); + 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?) - DEBUG("device_name length=%d\n\r", local_name_length); + PRINTF("device_name length=%d\n\r", local_name_length); break; } case GapAdvertisingData::TX_POWER_LEVEL: /**< TX Power Level (in dBm) */ { - DEBUG("Advertising type: TX_POWER_LEVEL\n\r"); + PRINTF("Advertising type: TX_POWER_LEVEL\n\r"); int8_t enHighPower = 0; int8_t paLevel = 0; -#if NEED_CONSOLE_OUTPUT +#ifdef DEBUG int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr(); int8_t dbmActuallySet = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel); #endif - DEBUG("dbm=%d, dbmActuallySet=%d\n\r", dbm, dbmActuallySet); - DEBUG("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); + PRINTF("dbm=%d, dbmActuallySet=%d\n\r", dbm, dbmActuallySet); + PRINTF("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); aci_hal_set_tx_power_level(enHighPower, paLevel); break; } @@ -219,15 +220,15 @@ } case GapAdvertisingData::SERVICE_DATA: /**< Service Data */ { - DEBUG("Advertising type: SERVICE_DATA\n\r"); + PRINTF("Advertising type: SERVICE_DATA\n\r"); uint8_t buffSize = *loadPtr.getUnitAtIndex(index).getLenPtr()-1; - DEBUG("Advertising type: SERVICE_DATA (buffSize=%d)\n\r", buffSize); + PRINTF("Advertising type: SERVICE_DATA (buffSize=%d)\n\r", buffSize); // the total ADV DATA LEN should include two more bytes: the buffer size byte; and the Service Data Type Value byte if(buffSize>ADV_DATA_MAX_SIZE-2) { return BLE_ERROR_PARAM_OUT_OF_RANGE; } for(int i=0; i<buffSize+1; i++) { - DEBUG("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]); } 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) @@ -241,26 +242,26 @@ Tested with GapAdvertisingData::GENERIC_PHONE. for other appearances BLE Scanner android app is not behaving properly */ - DEBUG("Advertising type: APPEARANCE\n\r"); + 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 -#if NEED_CONSOLE_OUTPUT +#ifdef DEBUG uint8_t Appearance[2] = {0, 0}; uint16_t devP = (uint16_t)*deviceAppearance; STORE_LE_16(Appearance, (uint16_t)devP); #endif - DEBUG("input: deviceAppearance= 0x%x 0x%x..., strlen(deviceAppearance)=%d\n\r", Appearance[1], Appearance[0], (uint8_t)*loadPtr.getUnitAtIndex(index).getLenPtr()-1); /**< \ref Appearance */ + 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 */ { - DEBUG("Advertising type: ADVERTISING_INTERVAL\n\r"); + PRINTF("Advertising type: ADVERTISING_INTERVAL\n\r"); advtInterval = (uint16_t)(*loadPtr.getUnitAtIndex(index).getDataPtr()); - DEBUG("advtInterval=%d\n\r", advtInterval); + PRINTF("advtInterval=%d\n\r", advtInterval); break; } case GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA: /**< Manufacturer Specific Data */ @@ -287,6 +288,20 @@ /* * ADV timeout callback */ +// ANDREA: mbedOS +#ifdef YOTTA_CFG +static void advTimeoutCB(void) +{ + Gap::GapState_t state; + + state = BlueNRGGap::getInstance().getState(); + if (state.advertising == 1) { + + BlueNRGGap::getInstance().stopAdvertising(); + + } +} +#else static void advTimeoutCB(void) { Gap::GapState_t state; @@ -301,7 +316,7 @@ } } - +#endif /* YOTTA_CFG */ /**************************************************************************/ /*! @@ -375,7 +390,7 @@ uint8_t nameLen = 0; if(local_name!=NULL) { name = (char*)local_name; - DEBUG("name=%s\n\r", name); + PRINTF("name=%s\n\r", name); nameLen = local_name_length; } else { char str[] = "ST_BLE_DEV"; @@ -383,8 +398,8 @@ name[0] = AD_TYPE_COMPLETE_LOCAL_NAME; strcpy(name+1, str); nameLen = strlen(name); - DEBUG("nameLen=%d\n\r", nameLen); - DEBUG("name=%s\n\r", name); + PRINTF("nameLen=%d\n\r", nameLen); + PRINTF("name=%s\n\r", name); } advtInterval = params.getIntervalInADVUnits(); // set advtInterval in case it is not already set by user application @@ -401,35 +416,35 @@ 0); // Slave_Conn_Interval_Max - DEBUG("!!!setting discoverable (servUuidlength=0x%x)\n", servUuidlength); + PRINTF("!!!setting discoverable (servUuidlength=0x%x)\n", servUuidlength); if(BLE_STATUS_SUCCESS!=ret) { - DEBUG("error occurred while setting discoverable (ret=0x%x)\n", ret); + PRINTF("error occurred while setting discoverable (ret=0x%x)\n", ret); return BLE_ERROR_PARAM_OUT_OF_RANGE; // no other suitable error code is available } // Before updating the ADV data, delete COMPLETE_LOCAL_NAME and TX_POWER_LEVEL fields (if present) if(AdvLen>0) { if(name!=NULL) { - DEBUG("!!!calling aci_gap_delete_ad_type AD_TYPE_COMPLETE_LOCAL_NAME!!!\n"); + PRINTF("!!!calling aci_gap_delete_ad_type AD_TYPE_COMPLETE_LOCAL_NAME!!!\n"); ret = aci_gap_delete_ad_type(AD_TYPE_COMPLETE_LOCAL_NAME); if (ret != BLE_STATUS_SUCCESS){ - DEBUG("aci_gap_delete_ad_type failed return=%d\n", ret); + PRINTF("aci_gap_delete_ad_type failed return=%d\n", ret); return BLE_ERROR_PARAM_OUT_OF_RANGE; } } if(txPowerAdType) { - DEBUG("!!!calling aci_gap_delete_ad_type(AD_TYPE_TX_POWER_LEVEL)!!!\n", AdvLen); + 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 (ret != BLE_STATUS_SUCCESS){ - DEBUG("aci_gap_delete_ad_type failed return=%d\n", ret); + PRINTF("aci_gap_delete_ad_type failed return=%d\n", ret); return BLE_ERROR_PARAM_OUT_OF_RANGE; } } ret = aci_gap_update_adv_data(AdvLen, AdvData); if(BLE_STATUS_SUCCESS!=ret) { - DEBUG("error occurred while adding adv data (ret=0x%x)\n", ret); + PRINTF("error occurred while adding adv data (ret=0x%x)\n", ret); return BLE_ERROR_PARAM_OUT_OF_RANGE; // no other suitable error code is available } @@ -439,8 +454,13 @@ AdvToFlag = false; if(params.getTimeout() != 0) { - DEBUG("!!! attaching to!!!\n"); + PRINTF("!!! attaching to!!!\n"); + // ANDREA: mbedOS +#ifdef YOTTA_CFG + minar::Scheduler::postCallback(advTimeoutCB).delay(minar::milliseconds(params.getTimeout())); +#else advTimeout.attach(advTimeoutCB, params.getTimeout()); +#endif } return BLE_ERROR_NONE; @@ -471,11 +491,11 @@ ret = aci_gap_set_non_discoverable(); if (ret != BLE_STATUS_SUCCESS){ - DEBUG("Error in stopping advertisement (ret=0x%x)!!\n\r", ret) ; + PRINTF("Error in stopping advertisement (ret=0x%x)!!\n\r", ret) ; return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value //FIXME: Define Error values equivalent to BlueNRG Error Codes. } - DEBUG("Advertisement stopped!!\n\r") ; + PRINTF("Advertisement stopped!!\n\r") ; //Set GapState_t::advertising state state.advertising = 0; } @@ -511,12 +531,12 @@ ret = aci_gap_terminate(m_connectionHandle, 0x16);//0x16 Connection Terminated by Local Host. if (ret != BLE_STATUS_SUCCESS){ - DEBUG("Error in GAP termination!!\n\r") ; + PRINTF("Error in GAP termination!!\n\r") ; return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value //FIXME: Define Error values equivalent to BlueNRG Error Codes. } - //DEBUG("Disconnected from localhost!!\n\r") ; + //PRINTF("Disconnected from localhost!!\n\r") ; m_connectionHandle = BLE_CONN_HANDLE_INVALID; } @@ -551,12 +571,12 @@ ret = aci_gap_terminate(connectionHandle, 0x16);//0x16 Connection Terminated by Local Host. if (ret != BLE_STATUS_SUCCESS){ - DEBUG("Error in GAP termination!!\n\r") ; + PRINTF("Error in GAP termination!!\n\r") ; return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value //FIXME: Define Error values equivalent to BlueNRG Error Codes. } - //DEBUG("Disconnected from localhost!!\n\r") ; + //PRINTF("Disconnected from localhost!!\n\r") ; m_connectionHandle = BLE_CONN_HANDLE_INVALID; } @@ -613,28 +633,21 @@ @endcode */ /**************************************************************************/ -ble_error_t BlueNRGGap::setAddress(addr_type_t type, const Address_t address) +ble_error_t BlueNRGGap::setAddress(AddressType_t type, const Address_t address) { - //tBleStatus ret; - if (type > ADDR_TYPE_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]; - //DEBUG("i[%d]:0x%x\n\r",i,bdaddr[i]); + //PRINTF("i[%d]:0x%x\n\r",i,bdaddr[i]); } if(!isSetAddress) isSetAddress = true; - //Re-Init the BTLE Device with SetAddress as true - //if(BlueNRGDevice::getIsInitialized())//Re-init only initialization is already done - // ANDREA - //btle_init(isSetAddress, D11, D12, D3); - - //if (ret==BLE_STATUS_SUCCESS) return BLE_ERROR_NONE; } @@ -672,13 +685,13 @@ /**************************************************************************/ ble_error_t BlueNRGGap::getAddress(AddressType_t *typeP, Address_t address) { - *typeP = Gap::ADDR_TYPE_PUBLIC; + *typeP = addr_type;//Gap::ADDR_TYPE_PUBLIC; if(isSetAddress) { for(int i=0; i<BDADDR_SIZE; i++) { address[i] = bdaddr[i]; - //DEBUG("i[%d]:0x%x\n\r",i,bdaddr[i]); + //PRINTF("i[%d]:0x%x\n\r",i,bdaddr[i]); } } @@ -765,10 +778,10 @@ uint8_t nameLen = 0; DeviceName = (uint8_t *)deviceName; - //DEBUG("SetDeviceName=%s\n\r", DeviceName); + //PRINTF("SetDeviceName=%s\n\r", DeviceName); nameLen = strlen((const char*)DeviceName); - //DEBUG("DeviceName Size=%d\n\r", nameLen); + //PRINTF("DeviceName Size=%d\n\r", nameLen); ret = aci_gatt_update_char_value(g_gap_service_handle, g_device_name_char_handle, @@ -777,7 +790,7 @@ (uint8_t *)DeviceName); if(ret){ - DEBUG("device set name failed\n\r"); + PRINTF("device set name failed\n\r"); return BLE_ERROR_PARAM_OUT_OF_RANGE;//TODO:Wrong error code } @@ -814,10 +827,10 @@ return BLE_ERROR_PARAM_OUT_OF_RANGE; strcpy((char*)deviceName, (const char*)DeviceName); - //DEBUG("GetDeviceName=%s\n\r", deviceName); + //PRINTF("GetDeviceName=%s\n\r", deviceName); *lengthP = strlen((const char*)DeviceName); - //DEBUG("DeviceName Size=%d\n\r", *lengthP); + //PRINTF("DeviceName Size=%d\n\r", *lengthP); return BLE_ERROR_NONE; } @@ -849,7 +862,7 @@ */ //char deviceAppearance[2]; STORE_LE_16(deviceAppearance, appearance); - DEBUG("input: incoming = %d deviceAppearance= 0x%x 0x%x\n\r", appearance, deviceAppearance[1], deviceAppearance[0]); + PRINTF("input: incoming = %d deviceAppearance= 0x%x 0x%x\n\r", appearance, deviceAppearance[1], deviceAppearance[0]); aci_gatt_update_char_value(g_gap_service_handle, g_appearance_char_handle, 0, 2, (uint8_t *)deviceAppearance); @@ -944,14 +957,101 @@ } // ANDREA -ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams) { - // Empty by now +void BlueNRGGap::Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t *addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI) +{ + + switch (reason) { + case DEVICE_FOUND: + { + GapAdvertisingParams::AdvertisingType_t type; + bool isScanResponse = false; + switch(adv_type) { + case ADV_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED; + break; + case ADV_DIRECT_IND: + type = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED; + break; + case ADV_SCAN_IND: + case SCAN_RSP: + type = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED; + isScanResponse = true; + break; + case ADV_NONCONN_IND: + type = GapAdvertisingParams::ADV_NON_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); + } + break; + + 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. + _scanning = false; + + if(_connecting) { + // We need to wait for a while before creating a connection due to + // BlueNRG process queue handling + Clock_Wait(10); + makeConnection(); + + } else { + startRadioScan(_scanningParams); + } + + break; + } +} + +ble_error_t BlueNRGGap::startRadioScan(const GapScanningParams &scanningParams) +{ + + uint8_t ret = BLE_STATUS_SUCCESS; + + // 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 + btle_init(isSetAddress, GAP_CENTRAL_ROLE_IDB04A1); + + PRINTF("BTLE re-init\n\r"); + + 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"); + _scanning = true; return BLE_ERROR_NONE; + } } ble_error_t BlueNRGGap::stopScan() { - // Empty by now + uint8_t ret = BLE_STATUS_SUCCESS; + + ret = aci_gap_terminate_gap_procedure(GENERAL_DISCOVERY_PROCEDURE); + + if (ret != BLE_STATUS_SUCCESS) { + printf("GAP Terminate Gap Procedure failed\n"); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Discovery Procedure Terminated\n"); return BLE_ERROR_NONE; + } } /**************************************************************************/ @@ -967,12 +1067,12 @@ int8_t enHighPower = 0; int8_t paLevel = 0; -#if NEED_CONSOLE_OUTPUT +#ifdef DEBUG int8_t dbmActuallySet = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel); #endif - DEBUG("txPower=%d, dbmActuallySet=%d\n\r", txPower, dbmActuallySet); - DEBUG("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); + 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; @@ -997,3 +1097,48 @@ *valueArrayPP = permittedTxValues; *countP = sizeof(permittedTxValues) / sizeof(int8_t); } + +ble_error_t BlueNRGGap::makeConnection () +{ + tBleStatus ret; + + _connecting = false; + + /* + 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, (unsigned char*)_peerAddr, PUBLIC_ADDR, CONN_P1, CONN_P2, 0, + SUPERV_TIMEOUT, CONN_L1 , CONN_L2); + + + if (ret != BLE_STATUS_SUCCESS){ + printf("Error while starting connection (ret=0x%02X).\n\r", ret); + return BLE_ERROR_UNSPECIFIED; + } else { + PRINTF("Connection started.\n"); + return BLE_ERROR_NONE; + } +} + +ble_error_t BlueNRGGap::connect (const Gap::Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) +{ + // Save the peer address + for(int i=0; i<BDADDR_SIZE; i++) { + _peerAddr[i] = peerAddr[i]; + } + + _connecting = true; + + if(_scanning) { + stopScan(); + } else { + //PRINTF("Calling makeConnection from connect()\n\r"); + return makeConnection(); + } + + return BLE_ERROR_NONE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/BlueNRGGattClient.cpp Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,594 @@ +/* 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; + + 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-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned j = 0; j < UUID::LENGTH_OF_LONG_UUID; j++) { + PRINTF("%02x", longUUIDBytes[j]); + } + 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; + + 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-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); + } + + // 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-"); + const uint8_t *longUUIDBytes = uuid.getBaseUUID(); + for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) { + PRINTF("%02X", longUUIDBytes[i]); + } + PRINTF("\r\n"); + } + + // 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; + uint8_t short_uuid[2]; + uint8_t *uuid; + + 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; + uint8_t short_uuid[2]; + uint8_t *uuid; + 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) +{ + 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) +{ + 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 +{ + 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; + + 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) +{ + // 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) +{ + 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 +{ + 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; + } + +}
--- a/source/BlueNRGGattServer.cpp Tue Oct 06 15:19:19 2015 +0200 +++ b/source/BlueNRGGattServer.cpp Wed Oct 07 08:39:04 2015 +0200 @@ -43,6 +43,7 @@ #include "mbed.h" #include "BlueNRGGap.h" #include "Utils.h" +#include "debug.h" /**************************************************************************/ /*! @@ -82,7 +83,7 @@ uint8_t maxAttrRecords = 0; type = (service.getUUID()).shortOrLong(); - DEBUG("AddService(): Type:%d\n\r", type); + PRINTF("AddService(): Type:%d\n\r", type); /* Add the service to the BlueNRG */ short_uuid = (service.getUUID()).getShortUUID(); @@ -105,7 +106,7 @@ PRIMARY_SERVICE, maxAttrRecords/*7*/, &servHandle); - DEBUG("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); + PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); } else if(type==UUID::UUID_TYPE_LONG) { ret = aci_gatt_add_serv(UUID_TYPE_128, @@ -113,12 +114,12 @@ PRIMARY_SERVICE, maxAttrRecords/*7*/, &servHandle); - DEBUG("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); + PRINTF("aci_gatt_add_serv UUID_TYPE_LONG ret=%d\n\r", ret); } service.setHandle(servHandle); //serviceHandleVector.push_back(servHandle); - DEBUG("added servHandle handle =%u\n\r", servHandle); + PRINTF("added servHandle handle =%u\n\r", servHandle); uint16_t bleCharacteristic; //iterate to include all characteristics @@ -136,7 +137,7 @@ base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],int_8_uuid[1],int_8_uuid[0],base_char_uuid[1],base_char_uuid[0]); } - DEBUG("Char Properties 0x%x\n\r", p_char->getProperties()); + PRINTF("Char Properties 0x%x\n\r", p_char->getProperties()); /* * Gatt_Evt_Mask -> HardCoded (0) * Encryption_Key_Size -> Hardcoded (16) @@ -147,13 +148,13 @@ if((p_char->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) { - DEBUG("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r"); + PRINTF("Setting up Gatt GATT_NOTIFY_ATTRIBUTE_WRITE Mask\n\r"); Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_ATTRIBUTE_WRITE; } if((p_char->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY| GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { - DEBUG("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r"); + PRINTF("Setting up Gatt GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP Mask\n\r"); Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP; } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check. @@ -169,7 +170,7 @@ 1 /*isVariable*/, &bleCharacteristic); - DEBUG("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(), @@ -183,7 +184,7 @@ 1 /*isVariable*/, &bleCharacteristic); - DEBUG("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 */ @@ -193,7 +194,7 @@ p_characteristics[characteristicCount++] = p_char; p_char->getValueAttribute().setHandle(bleCharacteristic); //Set the characteristic count as the corresponding char handle - DEBUG("added bleCharacteristic handle =%u\n\r", bleCharacteristic); + PRINTF("added bleCharacteristic handle =%u\n\r", bleCharacteristic); if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getInitialLength() > 0)) { write(p_char->getValueAttribute().getHandle(), p_char->getValueAttribute().getValuePtr(), p_char->getValueAttribute().getInitialLength(), false /* localOnly */); @@ -201,7 +202,7 @@ // add descriptors now uint16_t descHandle = 0; - DEBUG("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount()); + PRINTF("p_char->getDescriptorCount()=%d\n\r", p_char->getDescriptorCount()); for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) { GattAttribute *descriptor = p_char->getDescriptor(descIndex); @@ -211,9 +212,9 @@ CHAR_DESC_TYPE_16_BIT, uuidArray, descriptor->getMaxLength(), descriptor->getInitialLength(), descriptor->getValuePtr(), CHAR_DESC_SECURITY_PERMISSION, CHAR_DESC_ACCESS_PERMISSION, GATT_NOTIFY_ATTRIBUTE_WRITE, MIN_ENCRY_KEY_SIZE, CHAR_ATTRIBUTE_LEN_IS_FIXED, &descHandle); - DEBUG("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret); + PRINTF("Adding Descriptor descriptor handle=%d ret=%d\n\r", descHandle, ret); if(ret==(tBleStatus)0) { - DEBUG("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); + PRINTF("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); descriptor->setHandle(descHandle); } } @@ -255,7 +256,7 @@ /**************************************************************************/ ble_error_t BlueNRGGattServer::readValue(uint16_t charHandle, uint8_t buffer[], uint16_t *const lengthP) { - DEBUG("ReadValue() Not Supported\n\r"); + PRINTF("ReadValue() Not Supported\n\r"); return BLE_ERROR_NONE; } @@ -300,16 +301,16 @@ tBleStatus ret; //uint8_t buff[2]; - DEBUG("updating bleCharacteristic charHandle =%u, corresponding serviceHanle= %u len=%d\n\r", charHandle, bleCharHanldeMap.find(charHandle)->second, len); + PRINTF("updating bleCharacteristic charHandle =%u, corresponding serviceHanle= %u len=%d\n\r", charHandle, bleCharHanldeMap.find(charHandle)->second, len); /* for(int i=0; i<len; i++) { - DEBUG("buffer[%d]=%d\n\r", i, buffer[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 (ret != BLE_STATUS_SUCCESS){ - DEBUG("Error while updating characteristic (ret=0x%x).\n\r", ret) ; + PRINTF("Error while updating characteristic (ret=0x%x).\n\r", ret) ; return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value //FIXME: Define Error values equivalent to BlueNRG Error Codes. } @@ -319,7 +320,7 @@ GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(charHandle); if(p_char->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) { - DEBUG("Generate event after updating\n\r"); + PRINTF("Generate event after updating\n\r"); BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_SENT, charHandle); } @@ -353,12 +354,12 @@ GattReadCallbackParams readParams; readParams.handle = handle; - //DEBUG("readParams.charHandle = %d\n\r", readParams.charHandle); + //PRINTF("readParams.charHandle = %d\n\r", readParams.charHandle); HCIDataReadEvent(&readParams); //EXIT: if(gapConnectionHandle != 0){ - //DEBUG("Calling aci_gatt_allow_read\n\r"); + //PRINTF("Calling aci_gatt_allow_read\n\r"); aci_gatt_allow_read(gapConnectionHandle); } @@ -390,17 +391,17 @@ int i; uint16_t handle, handle_1; - DEBUG("BlueNRGGattServer::getCharacteristicFromHandle()>>Attribute Handle received %d\n\r",attrHandle); + PRINTF("BlueNRGGattServer::getCharacteristicFromHandle()>>Attribute Handle received %d\n\r",attrHandle); for(i=0; i<characteristicCount; i++) { handle = p_characteristics[i]->getValueAttribute().getHandle(); - DEBUG("handle(%d)=%d\n\r", i, handle); + PRINTF("handle(%d)=%d\n\r", i, handle); if(i==characteristicCount-1)//Last Characteristic check { if(attrHandle>=handle) { p_char = p_characteristics[i]; - DEBUG("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle); + PRINTF("Found Characteristic Properties 0x%x (handle=%d)\n\r",p_char->getProperties(), handle); break; } } @@ -410,7 +411,7 @@ if(attrHandle>=handle && attrHandle<handle_1) { p_char = p_characteristics[i]; - DEBUG("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1); + PRINTF("Found Characteristic Properties 0x%x (handle=%d handle_1=%d)\n\r",p_char->getProperties(), handle, handle_1); break; } else continue; } @@ -424,7 +425,7 @@ } void BlueNRGGattServer::HCIDataReadEvent(const GattReadCallbackParams *params) { - DEBUG("Called HCIDataReadEvent\n\r"); + PRINTF("Called HCIDataReadEvent\n\r"); this->handleDataReadEvent(params); }
--- a/source/BlueNRG_HCI/hci/controller/bluenrg_IFR.c Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,361 +0,0 @@ -#ifndef __MBED__ - -#include "hal.h" -#include "hal_types.h" -#include "ble_status.h" -#include "bluenrg_updater_aci.h" -#include "bluenrg_utils.h" - -/************** Do not change this define section ************/ - -#define BLUENRG_32_MHZ 1 -#define BLUENRG_32_MHZ_RO 2 -#define BLUENRG_16_MHZ 3 -#define BLUENRG_16_MHZ_RO 4 -#define BLUENRG_CUSTOM_CONFIG 5 - -#define MASTER_SCA_500ppm 0 // 251 ppm to 500 ppm -#define MASTER_SCA_250ppm 1 // 151 ppm to 250 ppm -#define MASTER_SCA_150ppm 2 // 101 ppm to 150 ppm -#define MASTER_SCA_100ppm 3 // 76 ppm to 100 ppm -#define MASTER_SCA_75ppm 4 // 51 ppm to 75 ppm -#define MASTER_SCA_50ppm 5 // 31 ppm to 50 ppm -#define MASTER_SCA_30ppm 6 // 21 ppm to 30 ppm -#define MASTER_SCA_20ppm 7 // 0 ppm to 20 ppm - -#define SMPS_4MHz 0 -#define SMPS_8MHz 1 - -#ifndef SMPS_FREQUENCY -#define SMPS_FREQUENCY SMPS_4MHz -#endif - -#if !BLUENRG_MS && (SMPS_FREQUENCY == SMPS_8MHz) -#error Unsupported SMPS_FREQUENCY -#endif - -/************************************************************/ - - -/************** Definitions that can be changed. ************/ - -#define STACK_MODE 2 -#define SLAVE_SCA_PPM 100 -#define MASTER_SCA MASTER_SCA_100ppm -#define HS_STARTUP_TIME_US 512 -#define DAY 11 -#define MONTH 02 -#define YEAR 15 -/************************************************************/ - -/* - * IMPORTANT! - * This IFR configurations are only for BlueNRG Firmware v6.4 and 7.1. - */ - -#if BLUENRG_CONFIG == BLUENRG_32_MHZ - -const IFR_config_TypeDef IFR_config = { -#if BLUENRG_MS -#if SMPS_FREQUENCY == SMPS_4MHz - 0x02,0x3A,0x44,0x02, - 0x34,0x5B,0x02,0x39, - 0xA2,0x02,0x3C,0x20, - 0x00,0xFF,0xFF,0xFF, -#elif SMPS_FREQUENCY == SMPS_8MHz - 0x02,0x3A,0x44,0x02, - 0x34,0x5B,0x02,0x39, - 0xAE,0x00,0xFF,0xFF, - 0x00,0xFF,0xFF,0xFF, -#else -#error Incorrect SMPS_FREQUENCY -#endif /* SMPS_FREQUENCY */ -#else - 0x02,0x3A,0x5C,0x02, - 0x39,0xA2,0x02,0x34, - 0x5B,0x00,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, -#endif /* BLUENRG_MS */ - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - - 0x02,0x1C,0x43,0x02, - 0x20,0xEC,0x02,0x1F, - 0xAF,0x00,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - - STACK_MODE, - 0xFF,0xFF,0xFF, - 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, - 0xFFFFFFFF, - htobl(0x00190000), - htobl(0x0028F5C2), - htobs(SLAVE_SCA_PPM), - MASTER_SCA, - 0xFF, - htobs(FROM_US_TO_SYS_TIME(HS_STARTUP_TIME_US)), - 0xFF,0xFF, - 0xFFFFFFFF, - 0xFF, - INT_TO_BCD(YEAR),INT_TO_BCD(MONTH),INT_TO_BCD(DAY), - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF -}; - -#elif BLUENRG_CONFIG == BLUENRG_32_MHZ_RO - -const IFR_config_TypeDef IFR_config = { -#if BLUENRG_MS -#if SMPS_FREQUENCY == SMPS_4MHz - 0x02,0x3A,0x44,0x02, - 0x34,0x1B,0x02,0x39, - 0xA2,0x02,0x3C,0x20, - 0x00,0xFF,0xFF,0xFF, -#elif SMPS_FREQUENCY == SMPS_8MHz - 0x02,0x3A,0x44,0x02, - 0x34,0x1B,0x02,0x39, - 0xAE,0x00,0xFF,0xFF, - 0x00,0xFF,0xFF,0xFF, -#else -#error Incorrect SMPS_FREQUENCY -#endif /* SMPS_FREQUENCY */ -#else - 0x02,0x3A,0x5C,0x02, - 0x39,0xA2,0x02,0x34, - 0x1B,0x00,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, -#endif /* BLUENRG_MS */ - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - - 0x02,0x1C,0x43,0x02, - 0x20,0xEC,0x02,0x1F, - 0xAF,0x00,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - - STACK_MODE, - 0xFF,0xFF,0xFF, - 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - htobs(0x01F4), - 0x00, - 0xFF, - htobs(FROM_US_TO_SYS_TIME(HS_STARTUP_TIME_US)), - 0xFF,0xFF, - 0xFFFFFFFF, - 0xFF, - INT_TO_BCD(YEAR),INT_TO_BCD(MONTH),INT_TO_BCD(DAY), - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF -}; - -#elif BLUENRG_CONFIG == BLUENRG_16_MHZ - -const IFR_config_TypeDef IFR_config = { -#if BLUENRG_MS -#if SMPS_FREQUENCY == SMPS_4MHz - 0x02,0x3A,0x40,0x02, - 0x34,0x5B,0x02,0x39, - 0xA2,0x02,0x3C,0x20, - 0x00,0xFF,0xFF,0xFF, -#elif SMPS_FREQUENCY == SMPS_8MHz - 0x02,0x3A,0x40,0x02, - 0x34,0x5B,0x02,0x39, - 0xAE,0x00,0xFF,0xFF, - 0x00,0xFF,0xFF,0xFF, -#else -#error Incorrect SMPS_FREQUENCY -#endif /* SMPS_FREQUENCY */ -#else - 0x02,0x3A,0x58,0x02, - 0x39,0xA2,0x02,0x34, - 0x5B,0x00,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, -#endif /* BLUENRG_MS */ - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - - 0x02,0x1C,0x43,0x02, - 0x20,0xEC,0x02,0x1F, - 0xAF,0x00,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - - STACK_MODE, - 0xFF,0xFF,0xFF, - 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, - 0xFFFFFFFF, - htobl(0x00190000), - htobl(0x0028F5C2), - htobs(SLAVE_SCA_PPM), - MASTER_SCA, - 0xFF, - htobs(FROM_US_TO_SYS_TIME(HS_STARTUP_TIME_US)), - 0xFF,0xFF, - 0xFFFFFFFF, - 0xFF, - INT_TO_BCD(YEAR),INT_TO_BCD(MONTH),INT_TO_BCD(DAY), - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF - -}; - -#elif BLUENRG_CONFIG == BLUENRG_16_MHZ_RO - -const IFR_config_TypeDef IFR_config = { -#if BLUENRG_MS -#if SMPS_FREQUENCY == SMPS_4MHz - 0x02,0x3A,0x40,0x02, - 0x34,0x1B,0x02,0x39, - 0xA2,0x02,0x3C,0x20, - 0x00,0xFF,0xFF,0xFF, -#elif SMPS_FREQUENCY == SMPS_8MHz - 0x02,0x3A,0x40,0x02, - 0x34,0x1B,0x02,0x39, - 0xAE,0x00,0xFF,0xFF, - 0x00,0xFF,0xFF,0xFF, -#else -#error Incorrect SMPS_FREQUENCY -#endif /* SMPS_FREQUENCY */ -#else - 0x02,0x3A,0x58,0x02, - 0x39,0xA2,0x02,0x34, - 0x1B,0x00,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, -#endif /* BLUENRG_MS */ - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - - 0x02,0x1C,0x43,0x02, - 0x20,0xEC,0x02,0x1F, - 0xAF,0x00,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF, - - STACK_MODE, - 0xFF,0xFF,0xFF, - 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - htobs(0x01F4), - 0x00, - 0xFF, - htobs(FROM_US_TO_SYS_TIME(HS_STARTUP_TIME_US)), - 0xFF,0xFF, - 0xFFFFFFFF, - 0xFF, - INT_TO_BCD(YEAR),INT_TO_BCD(MONTH),INT_TO_BCD(DAY), - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF, - 0xFFFFFFFF -}; - -#elif BLUENRG_CONFIG == BLUENRG_CUSTOM_CONFIG -/* Copy and paste here your custom IFR_config structure. It can be generated - * with BlueNRG GUI. - */ -#else -#warning BLUENRG_CONFIG not valid -#endif - -#endif // !__MBED__
--- a/source/BlueNRG_HCI/hci/controller/bluenrg_gap_aci.c Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1306 +0,0 @@ -/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** -* File Name : bluenrg_hci.c -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 4-Oct-2013 -* Description : File with HCI commands for BlueNRG FW6.0 and above. -******************************************************************************** -* 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. -*******************************************************************************/ - -#include "hal_types.h" -#include "osal.h" -#include "ble_status.h" -#include "hal.h" -#include "osal.h" -#include "hci_const.h" -#include "bluenrg_aci_const.h" -#include "bluenrg_gap_aci.h" -#include "bluenrg_gatt_server.h" -#include "bluenrg_gap.h" - -#define MIN(a,b) ((a) < (b) )? (a) : (b) -#define MAX(a,b) ((a) > (b) )? (a) : (b) - -tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, uint8_t device_name_char_len, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) -{ - struct hci_request rq; - gap_init_cp_IDB05A1 cp; - gap_init_rp resp; - - cp.role = role; - cp.privacy_enabled = privacy_enabled; - cp.device_name_char_len = device_name_char_len; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_INIT; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &resp; - rq.rlen = GAP_INIT_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - if (resp.status) { - return resp.status; - } - - *service_handle = btohs(resp.service_handle); - *dev_name_char_handle = btohs(resp.dev_name_char_handle); - *appearance_char_handle = btohs(resp.appearance_char_handle); - - return 0; -} -tBleStatus aci_gap_init_IDB04A1(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) -{ - struct hci_request rq; - gap_init_cp_IDB04A1 cp; - gap_init_rp resp; - - cp.role = role; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_INIT; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &resp; - rq.rlen = GAP_INIT_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - if (resp.status) { - return resp.status; - } - - *service_handle = btohs(resp.service_handle); - *dev_name_char_handle = btohs(resp.dev_name_char_handle); - *appearance_char_handle = btohs(resp.appearance_char_handle); - - return 0; -} - -tBleStatus aci_gap_set_non_discoverable(void) -{ - struct hci_request rq; - uint8_t status; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, - uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, - const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, - uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) -{ - struct hci_request rq; - uint8_t status; - uint8_t buffer[40]; - uint8_t indx = 0; - - if((unsigned int)(LocalNameLen + ServiceUUIDLen + 14) > sizeof(buffer)) - return BLE_STATUS_INVALID_PARAMS; - - buffer[indx] = AdvType; - indx++; - - AdvIntervMin = htobs(AdvIntervMin); - Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); - indx += 2; - - AdvIntervMax = htobs(AdvIntervMax); - Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); - indx += 2; - - buffer[indx] = OwnAddrType; - indx++; - - buffer[indx] = AdvFilterPolicy; - indx++; - - buffer[indx] = LocalNameLen; - indx++; - - Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); - indx += LocalNameLen; - - buffer[indx] = ServiceUUIDLen; - indx++; - - Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); - indx += ServiceUUIDLen; - - Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); - indx += 2; - - Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); - indx += 2; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_SET_LIMITED_DISCOVERABLE; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, - uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, - const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, - uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) -{ - struct hci_request rq; - uint8_t status; - uint8_t buffer[40]; - uint8_t indx = 0; - - if ((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) - return BLE_STATUS_INVALID_PARAMS; - - buffer[indx] = AdvType; - indx++; - - AdvIntervMin = htobs(AdvIntervMin); - Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); - indx += 2; - - AdvIntervMax = htobs(AdvIntervMax); - Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); - indx += 2; - - buffer[indx] = OwnAddrType; - indx++; - - buffer[indx] = AdvFilterPolicy; - indx++; - - buffer[indx] = LocalNameLen; - indx++; - - Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); - indx += LocalNameLen; - - buffer[indx] = ServiceUUIDLen; - indx++; - - Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); - indx += ServiceUUIDLen; - - SlaveConnIntervMin = htobs(SlaveConnIntervMin); - Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); - indx += 2; - - SlaveConnIntervMax = htobs(SlaveConnIntervMax); - Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); - indx += 2; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_SET_DISCOVERABLE; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - if (status) { - return status; - } - - return 0; -} - -tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr) -{ - struct hci_request rq; - gap_set_direct_conectable_cp_IDB05A1 cp; - uint8_t status; - - cp.own_bdaddr_type = own_addr_type; - cp.directed_adv_type = directed_adv_type; - cp.direct_bdaddr_type = initiator_addr_type; - Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr) -{ - struct hci_request rq; - gap_set_direct_conectable_cp_IDB04A1 cp; - uint8_t status; - - cp.own_bdaddr_type = own_addr_type; - cp.direct_bdaddr_type = initiator_addr_type; - Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_set_io_capability(uint8_t io_capability) -{ - struct hci_request rq; - uint8_t status; - gap_set_io_capability_cp cp; - - cp.io_capability = io_capability; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_SET_IO_CAPABILITY; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, - uint8_t oob_enable, - uint8_t oob_data[16], - uint8_t min_encryption_key_size, - uint8_t max_encryption_key_size, - uint8_t use_fixed_pin, - uint32_t fixed_pin, - uint8_t bonding_mode) -{ - struct hci_request rq; - gap_set_auth_requirement_cp cp; - uint8_t status; - - cp.mitm_mode = mitm_mode; - cp.oob_enable = oob_enable; - Osal_MemCpy(cp.oob_data, oob_data, 16); - cp.min_encryption_key_size = min_encryption_key_size; - cp.max_encryption_key_size = max_encryption_key_size; - cp.use_fixed_pin = use_fixed_pin; - cp.fixed_pin = htobl(fixed_pin); - cp.bonding_mode = bonding_mode; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - if (status) { - return status; - } - - return 0; -} - -tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable) -{ - struct hci_request rq; - gap_set_author_requirement_cp cp; - uint8_t status; - - cp.conn_handle = htobs(conn_handle); - cp.authorization_enable = authorization_enable; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_SET_AUTHOR_REQUIREMENT; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey) -{ - struct hci_request rq; - gap_passkey_response_cp cp; - uint8_t status; - - cp.conn_handle = htobs(conn_handle); - cp.passkey = htobl(passkey); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_PASSKEY_RESPONSE; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize) -{ - struct hci_request rq; - gap_authorization_response_cp cp; - uint8_t status; - - cp.conn_handle = htobs(conn_handle); - cp.authorize = authorize; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_AUTHORIZATION_RESPONSE; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type) -{ - struct hci_request rq; - gap_set_non_connectable_cp_IDB05A1 cp; - uint8_t status; - - cp.advertising_event_type = adv_type; - cp.own_address_type = own_address_type; - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type) -{ - struct hci_request rq; - gap_set_non_connectable_cp_IDB04A1 cp; - uint8_t status; - - cp.advertising_event_type = adv_type; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy) -{ - struct hci_request rq; - gap_set_undirected_connectable_cp cp; - uint8_t status; - - cp.own_addr_type = own_addr_type; - cp.adv_filter_policy = adv_filter_policy; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_SET_UNDIRECTED_CONNECTABLE; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection) -{ - struct hci_request rq; - gap_slave_security_request_cp cp; - uint8_t status; - - cp.conn_handle = htobs(conn_handle); - cp.bonding = bonding; - cp.mitm_protection = mitm_protection; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_SLAVE_SECURITY_REQUEST; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; - -} - -tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData) -{ - struct hci_request rq; - uint8_t status; - uint8_t buffer[32]; - uint8_t indx = 0; - - if (AdvLen > (sizeof(buffer)-1)) - return BLE_STATUS_INVALID_PARAMS; - - buffer[indx] = AdvLen; - indx++; - - Osal_MemCpy(buffer + indx, AdvData, AdvLen); - indx += AdvLen; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_UPDATE_ADV_DATA; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_delete_ad_type(uint8_t ad_type) -{ - struct hci_request rq; - gap_delete_ad_type_cp cp; - uint8_t status; - - cp.ad_type = ad_type; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_DELETE_AD_TYPE; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, - uint8_t* oob_data, uint8_t* passkey_required) -{ - struct hci_request rq; - gap_get_security_level_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_GET_SECURITY_LEVEL; - rq.rparam = &resp; - rq.rlen = GAP_GET_SECURITY_LEVEL_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - if (resp.status) { - return resp.status; - } - - *mitm_protection = resp.mitm_protection; - *bonding = resp.bonding; - *oob_data = resp.oob_data; - *passkey_required = resp.passkey_required; - - return resp.status; -} - -tBleStatus aci_gap_configure_whitelist(void) -{ - struct hci_request rq; - uint8_t status; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_CONFIGURE_WHITELIST; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason) -{ - struct hci_request rq; - gap_terminate_cp cp; - uint8_t status; - - cp.handle = htobs(conn_handle); - cp.reason = reason; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_TERMINATE; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_clear_security_database(void) -{ - struct hci_request rq; - uint8_t status; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_CLEAR_SECURITY_DB; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle) -{ - struct hci_request rq; - gap_allow_rebond_cp_IDB05A1 cp; - uint8_t status; - - cp.conn_handle = conn_handle; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_ALLOW_REBOND_DB; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} -tBleStatus aci_gap_allow_rebond_IDB04A1(void) -{ - struct hci_request rq; - uint8_t status; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_ALLOW_REBOND_DB; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, - uint8_t own_address_type, uint8_t filterDuplicates) -{ - struct hci_request rq; - gap_start_limited_discovery_proc_cp cp; - uint8_t status; - - cp.scanInterval = htobs(scanInterval); - cp.scanWindow = htobs(scanWindow); - cp.own_address_type = own_address_type; - cp.filterDuplicates = filterDuplicates; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, - uint8_t own_address_type, uint8_t filterDuplicates) -{ - struct hci_request rq; - gap_start_general_discovery_proc_cp cp; - uint8_t status; - - cp.scanInterval = htobs(scanInterval); - cp.scanWindow = htobs(scanWindow); - cp.own_address_type = own_address_type; - cp.filterDuplicates = filterDuplicates; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - - -tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, - uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, - uint8_t own_bdaddr_type, uint16_t conn_min_interval, - uint16_t conn_max_interval, uint16_t conn_latency, - uint16_t supervision_timeout, uint16_t min_conn_length, - uint16_t max_conn_length) -{ - struct hci_request rq; - gap_start_name_discovery_proc_cp cp; - uint8_t status; - - cp.scanInterval = htobs(scanInterval); - cp.scanWindow = htobs(scanWindow); - cp.peer_bdaddr_type = peer_bdaddr_type; - Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); - cp.own_bdaddr_type = own_bdaddr_type; - cp.conn_min_interval = htobs(conn_min_interval); - cp.conn_max_interval = htobs(conn_max_interval); - cp.conn_latency = htobs(conn_latency); - cp.supervision_timeout = htobs(supervision_timeout); - cp.min_conn_length = htobs(min_conn_length); - cp.max_conn_length = htobs(max_conn_length); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_START_NAME_DISCOVERY_PROC; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, - uint8_t own_bdaddr_type, uint16_t conn_min_interval, - uint16_t conn_max_interval, uint16_t conn_latency, - uint16_t supervision_timeout, uint16_t min_conn_length, - uint16_t max_conn_length, - uint8_t num_whitelist_entries, - const uint8_t *addr_array) -{ - struct hci_request rq; - uint8_t status; - uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; - uint8_t indx = 0; - - if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) - return BLE_STATUS_INVALID_PARAMS; - - scanInterval = htobs(scanInterval); - Osal_MemCpy(buffer + indx, &scanInterval, 2); - indx += 2; - - scanWindow = htobs(scanWindow); - Osal_MemCpy(buffer + indx, &scanWindow, 2); - indx += 2; - - buffer[indx] = own_bdaddr_type; - indx++; - - conn_min_interval = htobs(conn_min_interval); - Osal_MemCpy(buffer + indx, &conn_min_interval, 2); - indx += 2; - - conn_max_interval = htobs(conn_max_interval); - Osal_MemCpy(buffer + indx, &conn_max_interval, 2); - indx += 2; - - conn_latency = htobs(conn_latency); - Osal_MemCpy(buffer + indx, &conn_latency, 2); - indx += 2; - - supervision_timeout = htobs(supervision_timeout); - Osal_MemCpy(buffer + indx, &supervision_timeout, 2); - indx += 2; - - min_conn_length = htobs(min_conn_length); - Osal_MemCpy(buffer + indx, &min_conn_length, 2); - indx += 2; - - max_conn_length = htobs(max_conn_length); - Osal_MemCpy(buffer + indx, &max_conn_length, 2); - indx += 2; - - buffer[indx] = num_whitelist_entries; - indx++; - - Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); - indx += num_whitelist_entries * 7; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, - uint8_t own_bdaddr_type, uint16_t conn_min_interval, - uint16_t conn_max_interval, uint16_t conn_latency, - uint16_t supervision_timeout, uint16_t min_conn_length, - uint16_t max_conn_length, - uint8_t use_reconn_addr, - const tBDAddr reconn_addr, - uint8_t num_whitelist_entries, - const uint8_t *addr_array) -{ - struct hci_request rq; - uint8_t status; - uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; - uint8_t indx = 0; - - if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) - return BLE_STATUS_INVALID_PARAMS; - - scanInterval = htobs(scanInterval); - Osal_MemCpy(buffer + indx, &scanInterval, 2); - indx += 2; - - scanWindow = htobs(scanWindow); - Osal_MemCpy(buffer + indx, &scanWindow, 2); - indx += 2; - - buffer[indx] = own_bdaddr_type; - indx++; - - conn_min_interval = htobs(conn_min_interval); - Osal_MemCpy(buffer + indx, &conn_min_interval, 2); - indx += 2; - - conn_max_interval = htobs(conn_max_interval); - Osal_MemCpy(buffer + indx, &conn_max_interval, 2); - indx += 2; - - conn_latency = htobs(conn_latency); - Osal_MemCpy(buffer + indx, &conn_latency, 2); - indx += 2; - - supervision_timeout = htobs(supervision_timeout); - Osal_MemCpy(buffer + indx, &supervision_timeout, 2); - indx += 2; - - min_conn_length = htobs(min_conn_length); - Osal_MemCpy(buffer + indx, &min_conn_length, 2); - indx += 2; - - max_conn_length = htobs(max_conn_length); - Osal_MemCpy(buffer + indx, &max_conn_length, 2); - indx += 2; - - buffer[indx] = use_reconn_addr; - indx++; - - Osal_MemCpy(buffer + indx, reconn_addr, 6); - indx += 6; - - buffer[indx] = num_whitelist_entries; - indx++; - - Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); - indx += num_whitelist_entries * 7; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, - uint8_t own_address_type, uint8_t filter_duplicates) -{ - struct hci_request rq; - gap_start_general_conn_establish_proc_cp_IDB05A1 cp; - uint8_t status; - - cp.scan_type = scan_type; - cp.scan_interval = htobs(scan_interval); - cp.scan_window = htobs(scan_window); - cp.own_address_type = own_address_type; - cp.filter_duplicates = filter_duplicates; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} -tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, - uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr) -{ - struct hci_request rq; - gap_start_general_conn_establish_proc_cp_IDB04A1 cp; - uint8_t status; - - cp.scan_type = scan_type; - cp.scan_interval = htobs(scan_interval); - cp.scan_window = htobs(scan_window); - cp.own_address_type = own_address_type; - cp.filter_duplicates = filter_duplicates; - cp.use_reconn_addr = use_reconn_addr; - Osal_MemCpy(cp.reconn_addr, reconn_addr, 6); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, - uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, - const uint8_t *addr_array) -{ - struct hci_request rq; - gap_start_selective_conn_establish_proc_cp cp; - uint8_t status; - - if (((num_whitelist_entries*7)+GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE) > HCI_MAX_PAYLOAD_SIZE) - return BLE_STATUS_INVALID_PARAMS; - - cp.scan_type = scan_type; - cp.scan_interval = htobs(scan_interval); - cp.scan_window = htobs(scan_window); - cp.own_address_type = own_address_type; - cp.filter_duplicates = filter_duplicates; - cp.num_whitelist_entries = num_whitelist_entries; - - Osal_MemCpy(cp.addr_array, addr_array, (num_whitelist_entries*7)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC; - rq.cparam = &cp; - rq.clen = GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE + (num_whitelist_entries*7); - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, - uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, - uint8_t own_bdaddr_type, uint16_t conn_min_interval, - uint16_t conn_max_interval, uint16_t conn_latency, - uint16_t supervision_timeout, uint16_t min_conn_length, - uint16_t max_conn_length) -{ - struct hci_request rq; - gap_create_connection_cp cp; - uint8_t status; - - cp.scanInterval = htobs(scanInterval); - cp.scanWindow = htobs(scanWindow); - cp.peer_bdaddr_type = peer_bdaddr_type; - Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); - cp.own_bdaddr_type = own_bdaddr_type; - cp.conn_min_interval = htobs(conn_min_interval); - cp.conn_max_interval = htobs(conn_max_interval); - cp.conn_latency = htobs(conn_latency); - cp.supervision_timeout = htobs(supervision_timeout); - cp.min_conn_length = htobs(min_conn_length); - cp.max_conn_length = htobs(max_conn_length); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_CREATE_CONNECTION; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code) -{ - struct hci_request rq; - uint8_t status; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE; - rq.cparam = &procedure_code; - rq.clen = 1; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; - -} - -tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, - uint16_t conn_max_interval, uint16_t conn_latency, - uint16_t supervision_timeout, uint16_t min_conn_length, - uint16_t max_conn_length) -{ - struct hci_request rq; - gap_start_connection_update_cp cp; - uint8_t status; - - cp.conn_handle = htobs(conn_handle); - cp.conn_min_interval = htobs(conn_min_interval); - cp.conn_max_interval = htobs(conn_max_interval); - cp.conn_latency = htobs(conn_latency); - cp.supervision_timeout = htobs(supervision_timeout); - cp.min_conn_length = htobs(min_conn_length); - cp.max_conn_length = htobs(max_conn_length); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_START_CONNECTION_UPDATE; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond) -{ - struct hci_request rq; - gap_send_pairing_request_cp cp; - uint8_t status; - - cp.conn_handle = htobs(conn_handle); - cp.force_rebond = force_rebond; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_SEND_PAIRING_REQUEST; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address) -{ - struct hci_request rq; - gap_resolve_private_address_cp cp; - gap_resolve_private_address_rp rp; - - Osal_MemCpy(cp.address, private_address, 6); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; - 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; - - Osal_MemCpy(actual_address, rp.address, sizeof(actual_address)); - - return 0; -} -tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address) -{ - struct hci_request rq; - gap_resolve_private_address_cp cp; - uint8_t status; - - Osal_MemCpy(cp.address, address, 6); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, - uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, - const uint8_t *addr_array) -{ - struct hci_request rq; - gap_set_broadcast_mode_cp cp; - uint8_t status; - uint8_t indx = 0; - uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7; - - if (variable_size > sizeof(cp.var_len_data) ) - return BLE_STATUS_INVALID_PARAMS; - - cp.adv_interv_min = htobs(adv_interv_min); - cp.adv_interv_max = htobs(adv_interv_max); - cp.adv_type = adv_type; - cp.own_addr_type = own_addr_type; - - cp.var_len_data[indx] = adv_data_length; - indx++; - Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length); - indx += adv_data_length; - cp.var_len_data[indx] = num_whitelist_entries; - indx ++; - Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_SET_BROADCAST_MODE; - rq.cparam = &cp; - rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -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) -{ - struct hci_request rq; - gap_start_observation_proc_cp cp; - uint8_t status; - - cp.scan_interval = scan_interval; - cp.scan_window = scan_window; - cp.scan_type = scan_type; - cp.own_address_type = own_address_type; - cp.filter_duplicates = filter_duplicates; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_START_OBSERVATION_PROC; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address) -{ - struct hci_request rq; - gap_is_device_bonded_cp cp; - uint8_t status; - - cp.peer_address_type = peer_address_type; - Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_IS_DEVICE_BONDED; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size) -{ - struct hci_request rq; - gap_get_bonded_devices_rp rp; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GAP_GET_BONDED_DEVICES; - rq.rparam = &rp; - rq.rlen = sizeof(rp); - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - if (rp.status) { - return rp.status; - } - - *num_devices = rp.num_addr; - Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7)); - - return 0; -}
--- a/source/BlueNRG_HCI/hci/controller/bluenrg_gatt_aci.c Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1472 +0,0 @@ -/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** -* File Name : bluenrg_gatt_aci.c -* Author : AMS - AAS -* Version : V1.0.0 -* Date : 26-Jun-2014 -* Description : File with GATT commands for BlueNRG FW6.3. -******************************************************************************** -* 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. -*******************************************************************************/ - -#include "hal_types.h" -#include "osal.h" -#include "ble_status.h" -#include "hal.h" -#include "osal.h" -#include "hci_const.h" -#include "bluenrg_aci_const.h" -#include "bluenrg_gatt_aci.h" -#include "bluenrg_gatt_server.h" -#include "bluenrg_gap.h" - -#define MIN(a,b) ((a) < (b) )? (a) : (b) -#define MAX(a,b) ((a) > (b) )? (a) : (b) - - -tBleStatus aci_gatt_init(void) -{ - struct hci_request rq; - uint8_t status; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_INIT; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle) -{ - struct hci_request rq; - gatt_add_serv_rp resp; - uint8_t buffer[19]; - uint8_t uuid_len; - uint8_t indx = 0; - - buffer[indx] = service_uuid_type; - indx++; - - if(service_uuid_type == UUID_TYPE_16){ - uuid_len = 2; - } - else { - uuid_len = 16; - } - Osal_MemCpy(buffer + indx, service_uuid, uuid_len); - indx += uuid_len; - - buffer[indx] = service_type; - indx++; - - buffer[indx] = max_attr_records; - indx++; - - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_ADD_SERV; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.rparam = &resp; - rq.rlen = GATT_ADD_SERV_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - if (resp.status) { - return resp.status; - } - - *serviceHandle = btohs(resp.handle); - - return 0; -} - -tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, - uint16_t included_end_handle, uint8_t included_uuid_type, - const uint8_t* included_uuid, uint16_t *included_handle) -{ - struct hci_request rq; - gatt_include_serv_rp resp; - uint8_t buffer[23]; - uint8_t uuid_len; - uint8_t indx = 0; - - service_handle = htobs(service_handle); - Osal_MemCpy(buffer, &service_handle, 2); - indx += 2; - - included_start_handle = htobs(included_start_handle); - Osal_MemCpy(buffer+indx, &included_start_handle, 2); - indx += 2; - - included_end_handle = htobs(included_end_handle); - Osal_MemCpy(buffer+indx, &included_end_handle, 2); - indx += 2; - - if(included_uuid_type == UUID_TYPE_16){ - uuid_len = 2; - } else { - uuid_len = 16; - } - - buffer[indx] = included_uuid_type; - indx++; - - Osal_MemCpy(buffer + indx, included_uuid, uuid_len); - indx += uuid_len; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_INCLUDE_SERV; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.rparam = &resp; - rq.rlen = GATT_INCLUDE_SERV_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - if (resp.status) { - return resp.status; - } - - *included_handle = btohs(resp.handle); - - return 0; -} - -tBleStatus aci_gatt_add_char(uint16_t serviceHandle, - uint8_t charUuidType, - const uint8_t* charUuid, - uint8_t charValueLen, - uint8_t charProperties, - uint8_t secPermissions, - uint8_t gattEvtMask, - uint8_t encryKeySize, - uint8_t isVariable, - uint16_t* charHandle) -{ - struct hci_request rq; - gatt_add_serv_rp resp; - uint8_t buffer[25]; - uint8_t uuid_len; - uint8_t indx = 0; - - serviceHandle = htobs(serviceHandle); - Osal_MemCpy(buffer + indx, &serviceHandle, 2); - indx += 2; - - buffer[indx] = charUuidType; - indx++; - - if(charUuidType == UUID_TYPE_16){ - uuid_len = 2; - } - else { - uuid_len = 16; - } - Osal_MemCpy(buffer + indx, charUuid, uuid_len); - indx += uuid_len; - - buffer[indx] = charValueLen; - indx++; - - buffer[indx] = charProperties; - indx++; - - buffer[indx] = secPermissions; - indx++; - - buffer[indx] = gattEvtMask; - indx++; - - buffer[indx] = encryKeySize; - indx++; - - buffer[indx] = isVariable; - indx++; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_ADD_CHAR; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.rparam = &resp; - rq.rlen = GATT_ADD_CHAR_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - if (resp.status) { - return resp.status; - } - - *charHandle = btohs(resp.handle); - - return 0; -} - -tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, - uint16_t charHandle, - uint8_t descUuidType, - const uint8_t* uuid, - uint8_t descValueMaxLen, - uint8_t descValueLen, - const void* descValue, - uint8_t secPermissions, - uint8_t accPermissions, - uint8_t gattEvtMask, - uint8_t encryKeySize, - uint8_t isVariable, - uint16_t* descHandle) -{ - struct hci_request rq; - gatt_add_char_desc_rp resp; - uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; - uint8_t uuid_len; - uint8_t indx = 0; - - serviceHandle = htobs(serviceHandle); - Osal_MemCpy(buffer + indx, &serviceHandle, 2); - indx += 2; - - charHandle = htobs(charHandle); - Osal_MemCpy(buffer + indx, &charHandle, 2); - indx += 2; - - buffer[indx] = descUuidType; - indx++; - - if(descUuidType == UUID_TYPE_16){ - uuid_len = 2; - } - else { - uuid_len = 16; - } - Osal_MemCpy(buffer + indx, uuid, uuid_len); - indx += uuid_len; - - buffer[indx] = descValueMaxLen; - indx++; - - buffer[indx] = descValueLen; - indx++; - - if ((descValueLen+indx+5) > HCI_MAX_PAYLOAD_SIZE) - return BLE_STATUS_INVALID_PARAMS; - - Osal_MemCpy(buffer + indx, descValue, descValueLen); - indx += descValueLen; - - buffer[indx] = secPermissions; - indx++; - - buffer[indx] = accPermissions; - indx++; - - buffer[indx] = gattEvtMask; - indx++; - - buffer[indx] = encryKeySize; - indx++; - - buffer[indx] = isVariable; - indx++; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_ADD_CHAR_DESC; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.rparam = &resp; - rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - if (resp.status) { - return resp.status; - } - - *descHandle = btohs(resp.handle); - - return 0; -} - - -tBleStatus aci_gatt_update_char_value(uint16_t servHandle, - uint16_t charHandle, - uint8_t charValOffset, - uint8_t charValueLen, - const uint8_t *charValue) -{ - struct hci_request rq; - uint8_t status; - uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; - uint8_t indx = 0; - - if ((charValueLen+6) > HCI_MAX_PAYLOAD_SIZE) - return BLE_STATUS_INVALID_PARAMS; - - servHandle = htobs(servHandle); - Osal_MemCpy(buffer + indx, &servHandle, 2); - indx += 2; - - charHandle = htobs(charHandle); - Osal_MemCpy(buffer + indx, &charHandle, 2); - indx += 2; - - buffer[indx] = charValOffset; - indx++; - - buffer[indx] = charValueLen; - indx++; - - Osal_MemCpy(buffer + indx, charValue, charValueLen); - indx += charValueLen; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_UPD_CHAR_VAL; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - if (status) { - return status; - } - - return 0; -} - -tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle) -{ - struct hci_request rq; - uint8_t status; - gatt_del_char_cp cp; - - cp.service_handle = htobs(servHandle); - cp.char_handle = htobs(charHandle); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_DEL_CHAR; - rq.cparam = &cp; - rq.clen = GATT_DEL_CHAR_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_del_service(uint16_t servHandle) -{ - struct hci_request rq; - uint8_t status; - gatt_del_serv_cp cp; - - cp.service_handle = htobs(servHandle); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_DEL_SERV; - rq.cparam = &cp; - rq.clen = GATT_DEL_SERV_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle) -{ - struct hci_request rq; - uint8_t status; - gatt_del_inc_serv_cp cp; - - cp.service_handle = htobs(servHandle); - cp.inc_serv_handle = htobs(includeServHandle); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_DEL_INC_SERV; - rq.cparam = &cp; - rq.clen = GATT_DEL_INC_SERV_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_set_event_mask(uint32_t event_mask) -{ - struct hci_request rq; - uint8_t status; - gatt_set_evt_mask_cp cp; - - cp.evt_mask = htobs(event_mask); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_SET_EVT_MASK; - rq.cparam = &cp; - rq.clen = GATT_SET_EVT_MASK_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle) -{ - struct hci_request rq; - uint8_t status; - gatt_exchange_config_cp cp; - - cp.conn_handle = htobs(conn_handle); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_EXCHANGE_CONFIG; - rq.cparam = &cp; - rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle) -{ - struct hci_request rq; - uint8_t status; - att_find_info_req_cp cp; - - cp.conn_handle = htobs(conn_handle); - cp.start_handle = htobs(start_handle); - cp.end_handle = htobs(end_handle); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_ATT_FIND_INFO_REQ; - rq.cparam = &cp; - rq.clen = ATT_FIND_INFO_REQ_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, - uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val) -{ - struct hci_request rq; - uint8_t status; - att_find_by_type_value_req_cp cp; - - if(attr_val_len > sizeof(cp.attr_val)) - return BLE_STATUS_INVALID_PARAMS; - - cp.conn_handle = htobs(conn_handle); - cp.start_handle = htobs(start_handle); - cp.end_handle = htobs(end_handle); - Osal_MemCpy(cp.uuid, uuid, 2); - cp.attr_val_len = attr_val_len; - Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ; - rq.cparam = &cp; - rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, - uint8_t uuid_type, uint8_t* uuid) -{ - struct hci_request rq; - uint8_t status; - att_read_by_type_req_cp cp; - uint8_t uuid_len; - - if(uuid_type == UUID_TYPE_16){ - uuid_len = 2; - } - else{ - uuid_len = 16; - } - - cp.conn_handle = htobs(conn_handle); - cp.start_handle = htobs(start_handle); - cp.end_handle = htobs(end_handle); - cp.uuid_type = uuid_type; - Osal_MemCpy(cp.uuid, uuid, uuid_len); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_ATT_READ_BY_TYPE_REQ; - rq.cparam = &cp; - rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, - uint8_t uuid_type, uint8_t* uuid) -{ - struct hci_request rq; - uint8_t status; - att_read_by_group_type_req_cp cp; - uint8_t uuid_len; - - if(uuid_type == UUID_TYPE_16){ - uuid_len = 2; - } - else{ - uuid_len = 16; - } - - cp.conn_handle = htobs(conn_handle); - cp.start_handle = htobs(start_handle); - cp.end_handle = htobs(end_handle); - cp.uuid_type = uuid_type; - Osal_MemCpy(cp.uuid, uuid, uuid_len); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ; - rq.cparam = &cp; - rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, - uint8_t attr_val_len, uint8_t* attr_val) -{ - struct hci_request rq; - uint8_t status; - att_prepare_write_req_cp cp; - - if(attr_val_len > sizeof(cp.attr_val)) - return BLE_STATUS_INVALID_PARAMS; - - cp.conn_handle = htobs(conn_handle); - cp.attr_handle = htobs(attr_handle); - cp.value_offset = htobs(value_offset); - cp.attr_val_len = attr_val_len; - Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_ATT_PREPARE_WRITE_REQ; - rq.cparam = &cp; - rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute) -{ - struct hci_request rq; - uint8_t status; - att_execute_write_req_cp cp; - - cp.conn_handle = htobs(conn_handle); - cp.execute = execute; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ; - rq.cparam = &cp; - rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle) -{ - struct hci_request rq; - uint8_t status; - gatt_disc_all_prim_services_cp cp; - - cp.conn_handle = htobs(conn_handle); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES; - rq.cparam = &cp; - rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid) -{ - struct hci_request rq; - uint8_t status; - gatt_disc_prim_service_by_uuid_cp cp; - uint8_t uuid_len; - - if(uuid_type == UUID_TYPE_16){ - uuid_len = 2; - } - else{ - uuid_len = 16; - } - - cp.conn_handle = htobs(conn_handle); - cp.uuid_type = uuid_type; - Osal_MemCpy(cp.uuid, uuid, uuid_len); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID; - rq.cparam = &cp; - rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, - uint16_t end_service_handle) -{ - struct hci_request rq; - uint8_t status; - gatt_find_included_services_cp cp; - - cp.conn_handle = htobs(conn_handle); - cp.start_handle = htobs(start_service_handle); - cp.end_handle = htobs(end_service_handle); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES; - rq.cparam = &cp; - rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, - uint16_t end_attr_handle) -{ - struct hci_request rq; - uint8_t status; - gatt_disc_all_charac_of_serv_cp cp; - - cp.conn_handle = htobs(conn_handle); - cp.start_attr_handle = htobs(start_attr_handle); - cp.end_attr_handle = htobs(end_attr_handle); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV; - rq.cparam = &cp; - rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, - uint16_t end_handle, uint8_t charUuidType, - const uint8_t* charUuid) -{ - struct hci_request rq; - uint8_t status; - - uint8_t buffer[23]; - uint8_t uuid_len; - uint8_t indx = 0; - - conn_handle = htobs(conn_handle); - Osal_MemCpy(buffer + indx, &conn_handle, 2); - indx += 2; - - start_handle = htobs(start_handle); - Osal_MemCpy(buffer + indx, &start_handle, 2); - indx += 2; - - end_handle = htobs(end_handle); - Osal_MemCpy(buffer + indx, &end_handle, 2); - indx += 2; - - buffer[indx] = charUuidType; - indx++; - - if(charUuidType == 0x01){ - uuid_len = 2; - } - else { - uuid_len = 16; - } - Osal_MemCpy(buffer + indx, charUuid, uuid_len); - indx += uuid_len; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, - uint16_t char_end_handle) -{ - struct hci_request rq; - uint8_t status; - gatt_disc_all_charac_descriptors_cp cp; - - cp.conn_handle = htobs(conn_handle); - cp.char_val_handle = htobs(char_val_handle); - cp.char_end_handle = htobs(char_end_handle); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS; - rq.cparam = &cp; - rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle) -{ - struct hci_request rq; - uint8_t status; - gatt_read_charac_val_cp cp; - - cp.conn_handle = htobs(conn_handle); - cp.attr_handle = htobs(attr_handle); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_READ_CHARAC_VAL; - rq.cparam = &cp; - rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, - uint8_t uuid_type, uint8_t* uuid) -{ - struct hci_request rq; - uint8_t status; - gatt_read_using_charac_uuid_cp cp; - uint8_t uuid_len; - - if(uuid_type == UUID_TYPE_16){ - uuid_len = 2; - } - else{ - uuid_len = 16; - } - - cp.conn_handle = htobs(conn_handle); - cp.start_handle = htobs(start_handle); - cp.end_handle = htobs(end_handle); - cp.uuid_type = uuid_type; - Osal_MemCpy(cp.uuid, uuid, uuid_len); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID; - rq.cparam = &cp; - rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, - uint16_t val_offset) -{ - struct hci_request rq; - uint8_t status; - gatt_read_long_charac_val_cp cp; - - cp.conn_handle = htobs(conn_handle); - cp.attr_handle = htobs(attr_handle); - cp.val_offset = htobs(val_offset); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL; - rq.cparam = &cp; - rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, - uint8_t* set_of_handles) -{ - struct hci_request rq; - uint8_t status; - gatt_read_multiple_charac_val_cp cp; - - if(num_handles*2 > sizeof(cp.set_of_handles)) - return BLE_STATUS_INVALID_PARAMS; - - cp.conn_handle = htobs(conn_handle); - cp.num_handles = htobs(num_handles); - Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL; - rq.cparam = &cp; - rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - - - -tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, - uint8_t value_len, uint8_t *attr_value) -{ - struct hci_request rq; - uint8_t status; - uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; - uint8_t indx = 0; - - if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) - return BLE_STATUS_INVALID_PARAMS; - - conn_handle = htobs(conn_handle); - Osal_MemCpy(buffer + indx, &conn_handle, 2); - indx += 2; - - attr_handle = htobs(attr_handle); - Osal_MemCpy(buffer + indx, &attr_handle, 2); - indx += 2; - - buffer[indx] = value_len; - indx++; - - Osal_MemCpy(buffer + indx, attr_value, value_len); - indx += value_len; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_WRITE_CHAR_VALUE; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, - uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val) -{ - struct hci_request rq; - uint8_t status; - gatt_write_long_charac_val_cp cp; - - if(val_len > sizeof(cp.attr_val)) - return BLE_STATUS_INVALID_PARAMS; - - cp.conn_handle = htobs(conn_handle); - cp.attr_handle = htobs(attr_handle); - cp.val_offset = htobs(val_offset); - cp.val_len = val_len; - Osal_MemCpy(cp.attr_val, attr_val, val_len); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL; - rq.cparam = &cp; - rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, - uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) -{ - struct hci_request rq; - uint8_t status; - gatt_write_charac_reliable_cp cp; - - if(val_len > sizeof(cp.attr_val)) - return BLE_STATUS_INVALID_PARAMS; - - cp.conn_handle = htobs(conn_handle); - cp.attr_handle = htobs(attr_handle); - cp.val_offset = htobs(val_offset); - cp.val_len = val_len; - Osal_MemCpy(cp.attr_val, attr_val, val_len); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE; - rq.cparam = &cp; - rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, - uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) -{ - struct hci_request rq; - uint8_t status; - gatt_write_charac_reliable_cp cp; - - if(val_len > sizeof(cp.attr_val)) - return BLE_STATUS_INVALID_PARAMS; - - cp.conn_handle = htobs(conn_handle); - cp.attr_handle = htobs(attr_handle); - cp.val_offset = htobs(val_offset); - cp.val_len = val_len; - Osal_MemCpy(cp.attr_val, attr_val, val_len); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC; - rq.cparam = &cp; - rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, - uint16_t val_offset) -{ - struct hci_request rq; - uint8_t status; - gatt_read_long_charac_desc_cp cp; - - cp.conn_handle = htobs(conn_handle); - cp.attr_handle = htobs(attr_handle); - cp.val_offset = htobs(val_offset); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC; - rq.cparam = &cp; - rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, - uint8_t value_len, uint8_t *attr_value) -{ - struct hci_request rq; - uint8_t status; - uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; - uint8_t indx = 0; - - if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) - return BLE_STATUS_INVALID_PARAMS; - - conn_handle = htobs(conn_handle); - Osal_MemCpy(buffer + indx, &conn_handle, 2); - indx += 2; - - attr_handle = htobs(attr_handle); - Osal_MemCpy(buffer + indx, &attr_handle, 2); - indx += 2; - - buffer[indx] = value_len; - indx++; - - Osal_MemCpy(buffer + indx, attr_value, value_len); - indx += value_len; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle) -{ - struct hci_request rq; - uint8_t status; - gatt_read_long_charac_desc_cp cp; - - cp.conn_handle = htobs(conn_handle); - cp.attr_handle = htobs(attr_handle); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR; - rq.cparam = &cp; - rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, - uint8_t val_len, const uint8_t* attr_val) -{ - struct hci_request rq; - uint8_t status; - gatt_write_without_resp_cp cp; - - if(val_len > sizeof(cp.attr_val)) - return BLE_STATUS_INVALID_PARAMS; - - cp.conn_handle = htobs(conn_handle); - cp.attr_handle = htobs(attr_handle); - cp.val_len = val_len; - Osal_MemCpy(cp.attr_val, attr_val, val_len); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE; - rq.cparam = &cp; - rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, - uint8_t val_len, uint8_t* attr_val) -{ - struct hci_request rq; - uint8_t status; - gatt_signed_write_without_resp_cp cp; - - if(val_len > sizeof(cp.attr_val)) - return BLE_STATUS_INVALID_PARAMS; - - cp.conn_handle = htobs(conn_handle); - cp.attr_handle = htobs(attr_handle); - cp.val_len = val_len; - Osal_MemCpy(cp.attr_val, attr_val, val_len); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE; - rq.cparam = &cp; - rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle) -{ - struct hci_request rq; - uint8_t status; - gatt_confirm_indication_cp cp; - - cp.conn_handle = htobs(conn_handle); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_CONFIRM_INDICATION; - rq.cparam = &cp; - rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_write_response(uint16_t conn_handle, - uint16_t attr_handle, - uint8_t write_status, - uint8_t err_code, - uint8_t att_val_len, - uint8_t *att_val) -{ - struct hci_request rq; - uint8_t status; - uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; - uint8_t indx = 0; - - if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE) - return BLE_STATUS_INVALID_PARAMS; - - conn_handle = htobs(conn_handle); - Osal_MemCpy(buffer + indx, &conn_handle, 2); - indx += 2; - - attr_handle = htobs(attr_handle); - Osal_MemCpy(buffer + indx, &attr_handle, 2); - indx += 2; - - buffer[indx] = write_status; - indx += 1; - - buffer[indx] = err_code; - indx += 1; - - buffer[indx] = att_val_len; - indx += 1; - - Osal_MemCpy(buffer + indx, att_val, att_val_len); - indx += att_val_len; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_WRITE_RESPONSE; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - if (status) { - return status; - } - - return 0; -} - -tBleStatus aci_gatt_allow_read(uint16_t conn_handle) -{ - struct hci_request rq; - gatt_allow_read_cp cp; - uint8_t status; - - cp.conn_handle = htobs(conn_handle); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_ALLOW_READ; - rq.cparam = &cp; - rq.clen = GATT_ALLOW_READ_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, - uint8_t security_permission) -{ - struct hci_request rq; - gatt_set_security_permission_cp cp; - uint8_t status; - - cp.service_handle = htobs(service_handle); - cp.attr_handle = htobs(attr_handle); - cp.security_permission = security_permission; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION; - rq.cparam = &cp; - rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, - uint16_t charHandle, - uint16_t charDescHandle, - uint16_t charDescValOffset, - uint8_t charDescValueLen, - const uint8_t *charDescValue) -{ - struct hci_request rq; - uint8_t status; - uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; - uint8_t indx = 0; - - if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE) - return BLE_STATUS_INVALID_PARAMS; - - servHandle = htobs(servHandle); - Osal_MemCpy(buffer + indx, &servHandle, 2); - indx += 2; - - charHandle = htobs(charHandle); - Osal_MemCpy(buffer + indx, &charHandle, 2); - indx += 2; - - charDescHandle = htobs(charDescHandle); - Osal_MemCpy(buffer + indx, &charDescHandle, 2); - indx += 2; - - Osal_MemCpy(buffer + indx, &charDescValOffset, 2); - indx += 2; - - buffer[indx] = charDescValueLen; - indx++; - - Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen); - indx += charDescValueLen; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_SET_DESC_VAL; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) -{ - struct hci_request rq; - gatt_read_handle_val_cp cp; - gatt_read_handle_val_rp rp; - - if(data_len > sizeof(rp.value)) - return BLE_STATUS_INVALID_PARAMS; - - cp.attr_handle = htobs(attr_handle); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_READ_HANDLE_VALUE; - 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 = btohs(rp.value_len); - - Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); - - return 0; -} - -tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) -{ - struct hci_request rq; - gatt_read_handle_val_offset_cp cp; - gatt_read_handle_val_offset_rp rp; - - if(data_len > sizeof(rp.value)) - return BLE_STATUS_INVALID_PARAMS; - - cp.attr_handle = htobs(attr_handle); - cp.offset = offset; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET; - 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 = rp.value_len; - - Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); - - return 0; -}
--- a/source/BlueNRG_HCI/hci/controller/bluenrg_hal_aci.c Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,154 +0,0 @@ -/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** -* File Name : bluenrg_hci.c -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 4-Oct-2013 -* Description : File with HCI commands for BlueNRG FW6.0 and above. -******************************************************************************** -* 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. -*******************************************************************************/ - -#include "hal_types.h" -#include "osal.h" -#include "ble_status.h" -#include "hal.h" -#include "osal.h" -#include "hci_const.h" -#include "bluenrg_aci_const.h" -#include "bluenrg_hal_aci.h" -#include "bluenrg_gatt_server.h" -#include "bluenrg_gap.h" - -#define MIN(a,b) ((a) < (b) )? (a) : (b) -#define MAX(a,b) ((a) > (b) )? (a) : (b) - - -tBleStatus aci_hal_write_config_data(uint8_t offset, - uint8_t len, - const uint8_t *val) -{ - struct hci_request rq; - uint8_t status; - uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; - uint8_t indx = 0; - - if ((len+2) > HCI_MAX_PAYLOAD_SIZE) - return BLE_STATUS_INVALID_PARAMS; - - buffer[indx] = offset; - indx++; - - buffer[indx] = len; - indx++; - - Osal_MemCpy(buffer + indx, val, len); - indx += len; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_HAL_WRITE_CONFIG_DATA; - rq.cparam = (void *)buffer; - rq.clen = indx; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - if (status) { - return status; - } - - return 0; -} - -tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level) -{ - struct hci_request rq; - hal_set_tx_power_level_cp cp; - uint8_t status; - - cp.en_high_power = en_high_power; - cp.pa_level = pa_level; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL; - rq.cparam = &cp; - rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - if (status) { - return status; - } - - return 0; -} - -tBleStatus aci_hal_device_standby(void) -{ - struct hci_request rq; - uint8_t status; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_HAL_DEVICE_STANDBY; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_hal_tone_start(uint8_t rf_channel) -{ - struct hci_request rq; - hal_tone_start_cp cp; - uint8_t status; - - cp.rf_channel = rf_channel; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_HAL_TONE_START; - rq.cparam = &cp; - rq.clen = HAL_TONE_START_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_hal_tone_stop(void) -{ - struct hci_request rq; - uint8_t status; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_HAL_TONE_STOP; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - - -
--- a/source/BlueNRG_HCI/hci/controller/bluenrg_l2cap_aci.c Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,118 +0,0 @@ -/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** -* File Name : bluenrg_hci.c -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 4-Oct-2013 -* Description : File with HCI commands for BlueNRG FW6.0 and above. -******************************************************************************** -* 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. -*******************************************************************************/ - -#include "hal_types.h" -#include "osal.h" -#include "ble_status.h" -#include "hal.h" -#include "osal.h" -#include "hci_const.h" -#include "bluenrg_aci_const.h" -#include "bluenrg_hal_aci.h" -#include "bluenrg_gap.h" - -#define MIN(a,b) ((a) < (b) )? (a) : (b) -#define MAX(a,b) ((a) > (b) )? (a) : (b) - -tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, - uint16_t interval_max, uint16_t slave_latency, - uint16_t timeout_multiplier) -{ - struct hci_request rq; - uint8_t status; - l2cap_conn_param_update_req_cp cp; - - cp.conn_handle = htobs(conn_handle); - cp.interval_min = htobs(interval_min); - cp.interval_max = htobs(interval_max); - cp.slave_latency = htobs(slave_latency); - cp.timeout_multiplier = htobs(timeout_multiplier); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ; - rq.cparam = &cp; - rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, - uint16_t interval_max, uint16_t slave_latency, - uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, - uint8_t id, uint8_t accept) -{ - struct hci_request rq; - uint8_t status; - l2cap_conn_param_update_resp_cp_IDB05A1 cp; - - cp.conn_handle = htobs(conn_handle); - cp.interval_min = htobs(interval_min); - cp.interval_max = htobs(interval_max); - cp.slave_latency = htobs(slave_latency); - cp.timeout_multiplier = htobs(timeout_multiplier); - cp.min_ce_length = htobs(min_ce_length); - cp.max_ce_length = htobs(max_ce_length); - cp.id = id; - cp.accept = accept; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} -tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, - uint16_t interval_max, uint16_t slave_latency, - uint16_t timeout_multiplier, uint8_t id, uint8_t accept) -{ - struct hci_request rq; - uint8_t status; - l2cap_conn_param_update_resp_cp_IDB04A1 cp; - - cp.conn_handle = htobs(conn_handle); - cp.interval_min = htobs(interval_min); - cp.interval_max = htobs(interval_max); - cp.slave_latency = htobs(slave_latency); - cp.timeout_multiplier = htobs(timeout_multiplier); - cp.id = id; - cp.accept = accept; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; - rq.cparam = &cp; - rq.clen = sizeof(cp); - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -}
--- a/source/BlueNRG_HCI/hci/controller/bluenrg_updater_aci.c Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,270 +0,0 @@ -/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** -* File Name : bluenrg_hci.c -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 4-Oct-2013 -* Description : File with HCI commands for BlueNRG FW6.0 and above. -******************************************************************************** -* 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. -*******************************************************************************/ - -#include "hal_types.h" -#include "osal.h" -#include "ble_status.h" -#include "hal.h" -#include "osal.h" -#include "hci_const.h" -#include "bluenrg_aci_const.h" -#include "bluenrg_updater_aci.h" - -#define MIN(a,b) ((a) < (b) )? (a) : (b) -#define MAX(a,b) ((a) > (b) )? (a) : (b) - -tBleStatus aci_updater_start(void) -{ - struct hci_request rq; - uint8_t status = 0; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_UPDATER_START; - rq.rparam = &status; - rq.rlen = 1; - - hci_send_req(&rq, FALSE); // No command complete is sent. - - return status; -} - -tBleStatus aci_updater_reboot(void) -{ - struct hci_request rq; - uint8_t status = 0; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_UPDATER_REBOOT; - rq.rparam = &status; - rq.rlen = 1; - - hci_send_req(&rq, FALSE); // No command complete is sent. - - return status; -} - -tBleStatus aci_get_updater_version(uint8_t *version) -{ - struct hci_request rq; - get_updater_version_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GET_UPDATER_VERSION; - rq.rparam = &resp; - rq.rlen = GET_UPDATER_VERSION_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - *version = resp.version; - - return resp.status; -} - -tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size) -{ - struct hci_request rq; - get_updater_bufsize_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_GET_UPDATER_BUFSIZE; - rq.rparam = &resp; - rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - *buffer_size = resp.buffer_size; - - return resp.status; -} - -tBleStatus aci_erase_blue_flag(void) -{ - struct hci_request rq; - uint8_t status; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_reset_blue_flag(void) -{ - struct hci_request rq; - uint8_t status; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_updater_erase_sector(uint32_t address) -{ - struct hci_request rq; - updater_erase_sector_cp cp; - uint8_t status; - - cp.address = htobl(address); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_UPDATER_ERASE_SECTOR; - rq.cparam = &cp; - rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_updater_program_data_block(uint32_t address, - uint16_t len, - const uint8_t *data) -{ - struct hci_request rq; - uint8_t status; - updater_prog_data_block_cp cp; - - if( len > sizeof(cp.data)) - return BLE_STATUS_INVALID_PARAMS; - - cp.address = htobl(address); - cp.data_len = htobs(len); - Osal_MemCpy(cp.data, data, len); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK; - rq.cparam = &cp; - rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -tBleStatus aci_updater_read_data_block(uint32_t address, - uint16_t data_len, - uint8_t *data) -{ - struct hci_request rq; - updater_read_data_block_cp cp; - uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; - - if((data_len+1) > HCI_MAX_PAYLOAD_SIZE) - return BLE_STATUS_INVALID_PARAMS; - - cp.address = htobl(address); - cp.data_len = htobs(data_len); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_UPDATER_READ_DATA_BLOCK; - rq.cparam = &cp; - rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE; - rq.rparam = buffer; - rq.rlen = data_len + 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - // First byte is status - Osal_MemCpy(data, buffer+1, data_len); - - return buffer[0]; -} - -tBleStatus aci_updater_calc_crc(uint32_t address, - uint8_t num_sectors, - uint32_t *crc) -{ - struct hci_request rq; - updater_calc_crc_cp cp; - updater_calc_crc_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - cp.address = htobl(address); - cp.num_sectors = num_sectors; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_UPDATER_CALC_CRC; - rq.cparam = &cp; - rq.clen = UPDATER_CALC_CRC_CP_SIZE; - rq.rparam = &resp; - rq.rlen = UPDATER_CALC_CRC_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - *crc = btohl(resp.crc); - - return resp.status; -} - -tBleStatus aci_updater_hw_version(uint8_t *version) -{ - struct hci_request rq; - updater_hw_version_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_VENDOR_CMD; - rq.ocf = OCF_UPDATER_HW_VERSION; - rq.rparam = &resp; - rq.rlen = UPDATER_HW_VERSION_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - *version = resp.version; - - return resp.status; -} - - - -
--- a/source/BlueNRG_HCI/hci/controller/bluenrg_utils.c Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,403 +0,0 @@ - -#include "hal.h" -#include "hal_types.h" -#include "ble_status.h" -#include "bluenrg_aci.h" -#include "bluenrg_utils.h" -#include "hci.h" -#include "osal.h" -#include "string.h" -#include "stm32_bluenrg_ble.h" - -#define SUPPORTED_BOOTLOADER_VERSION_MIN 3 -#define SUPPORTED_BOOTLOADER_VERSION_MAX 5 - -#define BASE_ADDRESS 0x10010000 - -#define FW_OFFSET (2*1024) // 2 KB -#define FULL_STACK_SIZE (66*1024) // 66 KB -#define BOOTLOADER_SIZE (2*1024) // 2 kB -#define SECTOR_SIZE (2*1024) // 2 KB -#define DATA_SIZE 64 // 64 bytes - -// x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 + -// x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0 -#define CRC_POLY 0x04C11DB7 // the poly without the x**32 - -#define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC - -#define IFR_SIZE 192 -#define IFR_BASE_ADDRESS 0x10020000 -#define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data - -#if BLUENRG_MS -#define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET -#else -#define IFR_WRITE_OFFSET_BEGIN 0 -#endif - - -#define BLUE_FLAG_OFFSET 0x8C0 -#define MAX_ERASE_RETRIES 2 -#define MAX_WRITE_RETRIES 2 -#define MIN_WRITE_BLOCK_SIZE 4 - -#define RETRY_COMMAND(func, num_ret, error) \ -{ \ - uint8_t num_retries; \ - num_retries = 0; \ - error = 0; \ - while (num_retries++ < num_ret) { \ - if (func == BLE_STATUS_SUCCESS) \ - break; \ - if (num_retries == num_ret) \ - error = BLE_UTIL_ACI_ERROR; \ - } \ -} - -typedef struct{ - uint8_t cold_ana_act_config_table[64]; -}cold_table_TypeDef; - -/* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size, - they are extended with 0xFF until sector size is reached -*/ -static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes) -{ - uint32_t i, j, a1; - uint32_t crc, value; - - crc = 0; - for (i = 0; i < SECTOR_SIZE; i += 4) { - uint8_t *dataw = (uint8_t *) &value; - - dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF; - dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF; - dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF; - dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF; - - crc = crc ^ value; - for (j = 0; j < 32; j ++) { - a1 = (crc >> 31) & 0x1; - crc = (crc << 1) ^ (a1 * CRC_POLY); - } - } - - return crc; -} - -int program_device(const uint8_t *fw_image, uint32_t fw_size) -{ - uint8_t version, num_erase_retries=0, status, data_size; - uint8_t number_sectors, module; - uint32_t address, j; - uint32_t crc, crc2, crc_size; - - BlueNRG_HW_Bootloader(); - HCI_Process(); // To receive the EVT_INITIALIZED - - if(aci_get_updater_version(&version)) - return BLE_UTIL_ACI_ERROR; - - if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) - return BLE_UTIL_UNSUPPORTED_VERSION; - - if (fw_size != FULL_STACK_SIZE) - return BLE_UTIL_WRONG_IMAGE_SIZE; - - if (fw_size % MIN_WRITE_BLOCK_SIZE) - return BLE_UTIL_WRONG_IMAGE_SIZE; - - /* Calculate the number of sectors necessary to contain the fw image.*/ - number_sectors = ((fw_size + SECTOR_SIZE - 1) / SECTOR_SIZE); - - /*********************************************************************** - * Erase BLUE flag - ************************************************************************/ - RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status); - if (status != BLE_STATUS_SUCCESS) - return status; - - /*********************************************************************** - * Erase and Program sectors - ************************************************************************/ - for(unsigned int i = FW_OFFSET; i < (number_sectors * SECTOR_SIZE); i += SECTOR_SIZE) { - num_erase_retries = 0; - while (num_erase_retries++ < MAX_ERASE_RETRIES) { - aci_updater_erase_sector(BASE_ADDRESS + i); - if ((i/SECTOR_SIZE) < (unsigned int)(number_sectors-1)) - data_size = DATA_SIZE; - else - data_size = MIN_WRITE_BLOCK_SIZE; - for (j=i; ((j<SECTOR_SIZE+i)&&(j<fw_size)); j += data_size) { - RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, data_size, fw_image+j), MAX_WRITE_RETRIES, status); - if (status != BLE_STATUS_SUCCESS) - break; - } - if (status == BLE_STATUS_SUCCESS) - break; - } - if (num_erase_retries == MAX_ERASE_RETRIES) - return BLE_UTIL_ACI_ERROR; - } - - /*********************************************************************** - * Verify firmware - ************************************************************************/ - module = fw_size % SECTOR_SIZE; - crc_size = SECTOR_SIZE; - for(int i = SECTOR_SIZE; i < (number_sectors*SECTOR_SIZE); i += SECTOR_SIZE){ - address = BASE_ADDRESS + i; - if(aci_updater_calc_crc(address, 1, &crc)) - return BLE_UTIL_ACI_ERROR; - - if ((module != 0) && ((i/SECTOR_SIZE) == (number_sectors-1))) - crc_size = module; - - crc2 = updater_calc_crc(fw_image+i,crc_size); - if(crc!=crc2) - return BLE_UTIL_CRC_ERROR; - } - - /*********************************************************************** - * Write BLUE flag - ************************************************************************/ - RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status); - if (status != BLE_STATUS_SUCCESS) - return status; - - BlueNRG_RST(); - HCI_Process(); // To receive the EVT_INITIALIZED - - return BLE_STATUS_SUCCESS; -} - -int read_IFR(uint8_t *data) -{ - uint8_t version, offset; - tBleStatus ret; - - offset = 0; - aci_updater_start(); - if(aci_get_updater_version(&version)) - return BLE_UTIL_ACI_ERROR; - - if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) - return BLE_UTIL_UNSUPPORTED_VERSION; - - /*********************************************************************** - * Reading last 3 IFR 64-byte blocks - ************************************************************************/ - for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += DATA_SIZE){ - ret = aci_updater_read_data_block(BASE_ADDRESS+i, DATA_SIZE, (data+offset)); - offset += DATA_SIZE; - if(ret) return BLE_UTIL_ACI_ERROR; - } - - BlueNRG_RST(); - HCI_Process(); // To receive the EVT_INITIALIZED - - return BLE_STATUS_SUCCESS; - -} - -void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config) -{ - IFR_config->stack_mode = data[0]; - IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28); - IFR_config->master_sca = data[30]; - IFR_config->hs_startup_time = LE_TO_HOST_16(data+32); - IFR_config->year = BCD_TO_INT(data[41]); - IFR_config->month = BCD_TO_INT(data[42]); - IFR_config->day = BCD_TO_INT(data[43]); -} - -int IFR_validate(IFR_config2_TypeDef *IFR_config) -{ - if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) - return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode - if(IFR_config->master_sca > 7) - return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA - if(IFR_config->month > 12 || IFR_config->month < 1) - return BLE_UTIL_PARSE_ERROR; // Invalid date - if(IFR_config->day > 31 || IFR_config->day < 1) - return BLE_UTIL_PARSE_ERROR; // Invalid date - if(IFR_config->month > 12 || IFR_config->month < 1) - return BLE_UTIL_PARSE_ERROR; // Invalid date - - return BLE_STATUS_SUCCESS; -} - -/* TODO: Function to generate data from given options. */ - -void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]) -{ - data[0] = IFR_config->stack_mode; - HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm); - data[30] = IFR_config->master_sca; - HOST_TO_LE_16(data+32, IFR_config->hs_startup_time); - data[41] = INT_TO_BCD(IFR_config->year); - data[42] = INT_TO_BCD(IFR_config->month); - data[43] = INT_TO_BCD(IFR_config->day); -} - - -int program_IFR(const IFR_config_TypeDef *ifr_image) -{ - uint8_t version, num_erase_retries; - tBleStatus ret; -#if BLUENRG_MS - const uint8_t *ifr_data = (uint8_t *)ifr_image; -#else - uint8_t ifr_data[SECTOR_SIZE]; -#endif - uint8_t hwVersion; - uint16_t fwVersion; - - if(getBlueNRGVersion(&hwVersion, &fwVersion)) - return BLE_UTIL_ACI_ERROR; - - BlueNRG_HW_Bootloader(); - HCI_Process(); // To receive the EVT_INITIALIZED - - if(aci_get_updater_version(&version)) - return BLE_UTIL_ACI_ERROR; - - if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) - return BLE_UTIL_UNSUPPORTED_VERSION; - -#ifndef BLUENRG_MS - /*********************************************************************** - * READ IFR data - ************************************************************************/ - for(int i = 0; i < SECTOR_SIZE; i += DATA_SIZE){ - ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, DATA_SIZE, ifr_data+i); - if(ret != BLE_STATUS_SUCCESS){ - return ret; - } - } -#endif - - /*********************************************************************** - * Erase & Flashing IFR sectors - ************************************************************************/ -#ifndef BLUENRG_MS - Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE); -#endif - num_erase_retries = 0; - while (num_erase_retries++ < MAX_ERASE_RETRIES) { - aci_updater_erase_sector(IFR_BASE_ADDRESS); - for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += DATA_SIZE, j += DATA_SIZE) { - RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, DATA_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret); - if (ret != BLE_STATUS_SUCCESS) - break; - } - if (ret == BLE_STATUS_SUCCESS) - break; - } - if (num_erase_retries == MAX_ERASE_RETRIES) - return BLE_UTIL_ACI_ERROR; - - /*********************************************************************** - * Verify IFR - ************************************************************************/ - { - uint8_t ifr_updated[DATA_SIZE]; - for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += DATA_SIZE, j += DATA_SIZE){ - ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, DATA_SIZE, ifr_updated); - if(ret != BLE_STATUS_SUCCESS){ - return ret; - } - if (memcmp(ifr_updated, ifr_data+j, DATA_SIZE) != 0) - return BLE_UTIL_WRONG_VERIFY; - } - } - - BlueNRG_RST(); - HCI_Process(); // To receive the EVT_INITIALIZED - - return BLE_STATUS_SUCCESS; -} - -uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data) -{ - uint8_t ifr_updated[DATA_SIZE]; - uint8_t version, ret = BLE_STATUS_SUCCESS; - - aci_updater_start(); - if(aci_get_updater_version(&version)) - return BLE_UTIL_ACI_ERROR; - for(int i = 0; i < IFR_SIZE; i += DATA_SIZE){ - ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, DATA_SIZE, ifr_updated); - if(ret != BLE_STATUS_SUCCESS){ - return ret; - } - if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, DATA_SIZE) != 0) - { - ret = BLE_UTIL_WRONG_VERIFY; - break; - } - } - - BlueNRG_RST(); - HCI_Process(); // To receive the EVT_INITIALIZED - - return ret; -} - -uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion) -{ - uint8_t status; - uint8_t hci_version, lmp_pal_version; - uint16_t hci_revision, manufacturer_name, lmp_pal_subversion; - - status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, - &manufacturer_name, &lmp_pal_subversion); - - if (status == BLE_STATUS_SUCCESS) { - *hwVersion = hci_revision >> 8; - *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number - *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number - *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number - } - - HCI_Process(); // To receive the BlueNRG EVT - - return status; -} - -uint8_t getBlueNRGUpdaterVersion(uint8_t *version) -{ - - BlueNRG_HW_Bootloader(); - HCI_Process(); // To receive the EVT_INITIALIZED - - if(aci_get_updater_version(version)) - return BLE_UTIL_ACI_ERROR; - - if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX) - return BLE_UTIL_UNSUPPORTED_VERSION; - - BlueNRG_RST(); - HCI_Process(); // To receive the EVT_INITIALIZED - - return BLE_STATUS_SUCCESS; -} - -uint8_t isHWBootloader_Patched(void) -{ - uint8_t status, version; - uint32_t crc, address = 0x10010000; - - if(aci_get_updater_version(&version)) - return BLE_UTIL_ACI_ERROR; - - RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status); - if (status != BLE_STATUS_SUCCESS) - return 0; - - if (crc == BOOTLOADER_CRC_NOT_PATCHED) - return 0; - - return 1; -}
--- a/source/BlueNRG_HCI/hci/hci.c Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1147 +0,0 @@ -/** - ****************************************************************************** - * @file hci.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> - */ - -#include "hal_types.h" -#include "osal.h" -#include "ble_status.h" -#include "hal.h" -#include "hci_const.h" -#include "gp_timer.h" - -#include "stm32_bluenrg_ble.h" - -#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) - -tListNode hciReadPktPool; -tListNode hciReadPktRxQueue; -/* pool of hci read packets */ -static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; - -static volatile uint8_t readPacketListFull=FALSE; - -static volatile uint8_t hci_timer_id; -static volatile uint8_t hci_timeout; - -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 - -/** - * Verify if HCI packet is correctly formatted.. - * - * @param[in] hciReadPacket The packet that is received from HCI interface. - * @return 0 if HCI packet is as expected - */ -int HCI_verify(const tHciDataPacket * hciReadPacket) -{ - const uint8_t *hci_pckt = hciReadPacket->dataBuff; - - if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT) - return 1; /* Incorrect type. */ - - if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE)) - return 2; /* Wrong length (packet truncated or too long). */ - - return 0; -} - -void HCI_Process(void) -{ - uint8_t data_len; - uint8_t buffer[HCI_READ_PACKET_SIZE]; - tHciDataPacket * hciReadPacket = NULL; - - Disable_SPI_IRQ(); - uint8_t list_empty = list_is_empty(&hciReadPktRxQueue); - /* process any pending events read */ - while(list_empty == FALSE) - { - list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket); - Enable_SPI_IRQ(); - HCI_Event_CB(hciReadPacket->dataBuff); - Disable_SPI_IRQ(); - list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); - list_empty = list_is_empty(&hciReadPktRxQueue); - } - if (readPacketListFull) { - while(BlueNRG_DataPresent()) { - data_len = BlueNRG_SPI_Read_All(buffer, HCI_READ_PACKET_SIZE); - if(data_len > 0) - HCI_Event_CB(buffer); - } - readPacketListFull = FALSE; - } - - Enable_SPI_IRQ(); -} - -BOOL HCI_Queue_Empty(void) -{ - return list_is_empty(&hciReadPktRxQueue); -} - -void HCI_Isr(void) -{ - tHciDataPacket * hciReadPacket = NULL; - uint8_t data_len; - - Clear_SPI_EXTI_Flag(); - while(BlueNRG_DataPresent()){ - if (list_is_empty (&hciReadPktPool) == FALSE){ - - /* enqueueing a packet for read */ - list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); - - data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE); - if(data_len > 0){ - hciReadPacket->data_len = data_len; - if(HCI_verify(hciReadPacket) == 0) - list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket); - else - list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); - } - else { - // Insert the packet back into the pool. - list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); - } - - } - else{ - // HCI Read Packet Pool is empty, wait for a free packet. - readPacketListFull = TRUE; - Clear_SPI_EXTI_Flag(); - return; - } - - Clear_SPI_EXTI_Flag(); - } -} - -void hci_write(const void* data1, const void* data2, uint8_t n_bytes1, uint8_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 void move_list(tListNode * dest_list, tListNode * src_list) -{ - pListNode tmp_node; - - while(!list_is_empty(src_list)){ - list_remove_head(src_list, &tmp_node); - list_insert_tail(dest_list, tmp_node); - } -} - -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 to = DEFAULT_TIMEOUT; - struct timer t; - tHciDataPacket * hciReadPacket = NULL; - tListNode hciTempQueue; - - list_init_head(&hciTempQueue); - - hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam); - - if(async){ - goto done; - } - - /* Minimum timeout is 1. */ - if(to == 0) - to = 1; - - Timer_Set(&t, to); - - while(1) { - evt_cmd_complete *cc; - evt_cmd_status *cs; - evt_le_meta_event *me; - int len; - -#if ENABLE_MICRO_SLEEP - while(1){ - ATOMIC_SECTION_BEGIN(); - if(Timer_Expired(&t)){ - ATOMIC_SECTION_END(); - goto failed; - } - if(!HCI_Queue_Empty()){ - ATOMIC_SECTION_END(); - break; - } - Enter_Sleep_Mode(); - ATOMIC_SECTION_END(); - } -#else - while(1){ - if(Timer_Expired(&t)){ - goto failed; - } - if(!HCI_Queue_Empty()){ - break; - } - } -#endif - - /* Extract packet from HCI event queue. */ - Disable_SPI_IRQ(); - list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket); - - hci_hdr = (void *)hciReadPacket->dataBuff; - if(hci_hdr->type != HCI_EVENT_PKT){ - list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); // See comment below - Enable_SPI_IRQ(); - continue; - } - - event_pckt = (void *) (hci_hdr->data); - - ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE); - len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE); - - switch (event_pckt->evt) { - - case EVT_CMD_STATUS: - cs = (void *) ptr; - - if (cs->opcode != opcode) - goto failed; - - 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) - goto failed; - - 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. - In this case, insert the packet in a different queue. These packets will be - inserted back in the main queue just before exiting from send_req(). - */ - list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); - /* Be sure there is at list one packet in the pool to process the expected event. */ - if(list_is_empty(&hciReadPktPool)){ - pListNode tmp_node; - list_remove_head(&hciReadPktRxQueue, &tmp_node); - list_insert_tail(&hciReadPktPool, tmp_node); - } - - Enable_SPI_IRQ(); - - } - -failed: - move_list(&hciReadPktRxQueue, &hciTempQueue); - Enable_SPI_IRQ(); - return -1; - -done: - // Insert the packet back into the pool. - list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); - move_list(&hciReadPktRxQueue, &hciTempQueue); - - Enable_SPI_IRQ(); - 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 BLE_STATUS_TIMEOUT; - - return status; -} - -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 BLE_STATUS_TIMEOUT; - - return status; -} - -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 BLE_STATUS_TIMEOUT; - - if (resp.status) { - return resp.status; - } - - - *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 BLE_STATUS_TIMEOUT; - - if (resp.status) { - return resp.status; - } - - *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 BLE_STATUS_TIMEOUT; - - return status; -} - -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 BLE_STATUS_TIMEOUT; - - return status; -} - -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 BLE_STATUS_TIMEOUT; - - return status; -} - -int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, - uint16_t window, uint8_t own_bdaddr_type, - uint8_t filter) -{ - struct hci_request rq; - le_set_scan_parameters_cp scan_cp; - uint8_t status; - - Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); - scan_cp.type = type; - scan_cp.interval = interval; - scan_cp.window = window; - scan_cp.own_bdaddr_type = own_bdaddr_type; - scan_cp.filter = filter; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_SET_SCAN_PARAMETERS; - rq.cparam = &scan_cp; - rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup) -{ - struct hci_request rq; - le_set_scan_enable_cp scan_cp; - uint8_t status; - - Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); - scan_cp.enable = enable?1:0; - scan_cp.filter_dup = filter_dup; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_SET_SCAN_ENABLE; - rq.cparam = &scan_cp; - rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return BLE_STATUS_TIMEOUT; - - return status; -} - -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 BLE_STATUS_TIMEOUT; - - if (resp.status) { - return resp.status; - } - - 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 BLE_STATUS_TIMEOUT; - - return status; -} - -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 BLE_STATUS_TIMEOUT; - - if (resp.status) { - return resp.status; - } - - *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 BLE_STATUS_TIMEOUT; - - return status; -} - -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 BLE_STATUS_TIMEOUT; - - if (resp.status) { - return resp.status; - } - 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 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; - 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 BLE_STATUS_TIMEOUT; - } - - if (resp.status) { - return resp.status; - } - - 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 BLE_STATUS_TIMEOUT; - - return resp.status; -} - -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 BLE_STATUS_TIMEOUT; - - return resp.status; -} - -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 BLE_STATUS_TIMEOUT; - } - - if (resp.status) { - return resp.status; - } - - *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 BLE_STATUS_TIMEOUT; - } - - return status; -} - -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 BLE_STATUS_TIMEOUT; - } - - return status; -} - -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 BLE_STATUS_TIMEOUT; - } - - return status; -} - -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 BLE_STATUS_TIMEOUT; - } - - if (resp.status) { - return resp.status; - } - - *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 BLE_STATUS_TIMEOUT; - } - - if (resp.status) { - return resp.status; - } - - *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 BLE_STATUS_TIMEOUT; - } - - if (resp.status) { - return resp.status; - } - - 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 BLE_STATUS_TIMEOUT; - } - - if (resp.status) { - return resp.status; - } - - 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 BLE_STATUS_TIMEOUT; - } - - if (resp.status) { - return resp.status; - } - - 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 BLE_STATUS_TIMEOUT; - } - - return status; -} - -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 BLE_STATUS_TIMEOUT; - } - - return status; -} - -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 BLE_STATUS_TIMEOUT; - } - - if (resp.status) { - return resp.status; - } - - *num_pkts = resp.num_pkts; - - return 0; -} -
--- a/source/BlueNRG_HCI/hci/hci_dma_lp.c Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1194 +0,0 @@ -/** - ****************************************************************************** - * @file hci_dma_lp.c - * @author AMS/HESA Application Team - * @brief Function for managing HCI interface. - ****************************************************************************** - * - * - * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS - * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE - * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY - * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING - * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE - * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. - * - * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> - */ - -// ANDREA -- FIXME: to exclude from building when DMA is disabled -#ifdef __DMA_LP__ - -#include "hal_types.h" -#include "osal.h" -#include "ble_status.h" -#include "hal.h" -#include "hci_const.h" -#include "gp_timer.h" - -#include "bluenrg_interface.h" -#include "stm32xx_timerserver.h" - -extern SPI_HandleTypeDef SpiHandle; - -#if BLE_CONFIG_DBG_ENABLE -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - -#define HCI_LOG_ON 0 - -#define HCI_READ_PACKET_NUM_MAX (5) - -#define MIN(a,b) ((a) < (b) )? (a) : (b) -#define MAX(a,b) ((a) > (b) )? (a) : (b) - -static void enqueue_packet(tHciDataPacket * hciReadPacket); -static void hci_timeout_callback(void); - -tListNode hciReadPktPool; -tListNode hciReadPktRxQueue; -/* pool of hci read packets */ -static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; - -static volatile uint8_t readPacketListFull=FALSE; - -static uint8_t *hci_buffer = NULL; -static volatile uint16_t hci_pckt_len; -static volatile uint8_t hci_timer_id; -static volatile uint8_t hci_timeout; - -uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE]; - -void hci_timeout_callback(void) -{ - hci_timeout = 1; - - return; -} - -void HCI_Init(void) -{ - uint8_t index; - - /* Initialize list heads of ready and free hci data packet queues */ - list_init_head (&hciReadPktPool); - list_init_head (&hciReadPktRxQueue); - - /* Initialize the queue of free hci data packets */ - for (index = 0; index < HCI_READ_PACKET_NUM_MAX; index++) - { - list_insert_tail(&hciReadPktPool, (tListNode *)&hciReadPacketBuffer[index]); - } -} - -#define HCI_PCK_TYPE_OFFSET 0 -#define EVENT_PARAMETER_TOT_LEN_OFFSET 2 - -void Hal_Init_Event_Request(void) -{ - tHciDataPacket * hciReadPacket = NULL; - - list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); - - Hal_Event_Request ((uint8_t*)hciReadPacket, HCI_READ_PACKET_SIZE); -} - -static volatile hci_packet_complete_callback packet_complete_callback = NULL; - -static void hci_set_packet_complete_callback(hci_packet_complete_callback cb) -{ - packet_complete_callback = cb; -} - -void HCI_Input(tHciDataPacket * hciReadPacket) -{ - uint8_t byte; - hci_acl_hdr *acl_hdr; - - static hci_state state = WAITING_TYPE; - - uint16_t collected_payload_len = 0; - uint16_t payload_len; - - hci_buffer = hciReadPacket->dataBuff; - - if(state == WAITING_TYPE) - hci_pckt_len = 0; - - while(hci_pckt_len < HCI_READ_PACKET_SIZE){ - - byte = hci_buffer[hci_pckt_len++]; - - if(state == WAITING_TYPE){ - /* Only ACL Data and Events packets are accepted. */ - if(byte == HCI_EVENT_PKT){ - state = WAITING_EVENT_CODE; - } -// else if(byte == HCI_ACLDATA_PKT){ -// state = WAITING_HANDLE; -// } - else{ - /* Incorrect type. Reset state machine. */ - state = WAITING_TYPE; - break; - } - } - else if(state == WAITING_EVENT_CODE) - state = WAITING_PARAM_LEN; - else if(state == WAITING_HANDLE) - state = WAITING_HANDLE_FLAG; - else if(state == WAITING_HANDLE_FLAG) - state = WAITING_DATA_LEN1; - else if(state == WAITING_DATA_LEN1) - state = WAITING_DATA_LEN2; - - else if(state == WAITING_DATA_LEN2){ - acl_hdr = (void *)&hci_buffer[HCI_HDR_SIZE]; - payload_len = acl_hdr->dlen; - collected_payload_len = 0; - state = WAITING_PAYLOAD; - } - else if(state == WAITING_PARAM_LEN){ - payload_len = byte; - collected_payload_len = 0; - state = WAITING_PAYLOAD; - } - else if(state == WAITING_PAYLOAD){ - collected_payload_len += 1; - if(collected_payload_len >= payload_len){ - /* Reset state machine. */ - state = WAITING_TYPE; - enqueue_packet(hciReadPacket); - - if(packet_complete_callback){ - uint16_t len = hci_pckt_len; - packet_complete_callback(hci_buffer, len); - } - break; - } - } - } -} - -void enqueue_packet(tHciDataPacket * hciReadPacket) -{ - hci_uart_pckt *hci_pckt = (void*)hciReadPacket->dataBuff; - hci_event_pckt *event_pckt = (void*)hci_pckt->data; - - // Do not enqueue Command Complete or Command Status events - - if((hci_pckt->type != HCI_EVENT_PKT) || - event_pckt->evt == EVT_CMD_COMPLETE || - event_pckt->evt == EVT_CMD_STATUS){ - // Insert the packet back into the pool. - list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); - } - else { - // Insert the packet into the queue of events to be processed. - list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket); - HCI_Process_Notification_Request(); - } -} - -void HCI_Process(void) -{ - //uint8_t data_len; - //uint8_t buffer[HCI_PACKET_SIZE]; - tHciDataPacket * hciReadPacket = NULL; - - uint8_t list_empty = list_is_empty(&hciReadPktRxQueue); - /* process any pending events read */ - while(list_empty == FALSE) - { - list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket); - HCI_Event_CB(hciReadPacket->dataBuff); - list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); - list_empty = list_is_empty(&hciReadPktRxQueue); - } -} - -BOOL HCI_Queue_Empty(void) -{ - return list_is_empty(&hciReadPktRxQueue); -} - -void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len) -{ - tHciDataPacket * hciReadPacket = NULL; - - if (list_is_empty (&hciReadPktPool) == FALSE){ - - list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); - - Hal_Event_Request ((uint8_t*)hciReadPacket, HCI_READ_PACKET_SIZE); - } - - if(event_payload_len > 0){ - - HCI_Input((tHciDataPacket*)buffer); - // Packet will be inserted to te correct queue by - } - else { - // Insert the packet back into the pool. - list_insert_head(&hciReadPktPool, (tListNode*)buffer); - } -} - -void hci_write(const void* data1, const void* data2, uint16_t n_bytes1, uint16_t n_bytes2){ -#if HCI_LOG_ON - PRINTF("HCI <- "); - for(int i=0; i < n_bytes1; i++) - PRINTF("%02X ", *((uint8_t*)data1 + i)); - for(int i=0; i < n_bytes2; i++) - PRINTF("%02X ", *((uint8_t*)data2 + i)); - PRINTF("\n"); -#endif - - Hal_Write_Serial(data1, data2, n_bytes1, n_bytes2); -} - -void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param) -{ - hci_command_hdr hc; - - hc.opcode = htobs(cmd_opcode_pack(ogf, ocf)); - hc.plen= plen; - - //uint8_t header[HCI_HDR_SIZE + HCI_COMMAND_HDR_SIZE]; - header[0] = HCI_COMMAND_PKT; - Osal_MemCpy(header+1, &hc, sizeof(hc)); - - hci_write(header, param, sizeof(header), plen); -} - -static uint8_t new_packet; - -void new_hci_event(void *pckt, uint16_t len) -{ - - new_packet = TRUE; -} - -/** - * FIXME: Param async is unused, it has been introduced to align the interface - * to DK 1.6.0 HCI stack - */ -/* 'to' is timeout in system clock ticks. */ -int hci_send_req(struct hci_request *r, BOOL async) -{ - uint8_t *ptr; - uint16_t opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); - hci_event_pckt *event_pckt; - hci_uart_pckt *hci_hdr; - int try; - uint32_t to = DEFAULT_TIMEOUT; - - new_packet = FALSE; - HCI_Cmd_Status(BUSY); - hci_set_packet_complete_callback(new_hci_event); - hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam); - - try = 10; - while (try--) { - evt_cmd_complete *cc; - evt_cmd_status *cs; - evt_le_meta_event *me; - int len; - - /* Minimum timeout is 1. */ - if(to == 0) - to = 1; - - hci_timeout = 0; - Blue_NRG_HCI_Timer_Start(to, hci_timeout_callback, (uint8_t*)&hci_timer_id); - - while(1){ - if(hci_timeout){ - Blue_NRG_HCI_Timer_Stop(hci_timer_id); - goto failed; - } - if(new_packet){ - Blue_NRG_HCI_Timer_Stop(hci_timer_id); - break; - } - HCI_Wait_For_Response(); - } - - hci_hdr = (void *)hci_buffer; - if(hci_hdr->type != HCI_EVENT_PKT){ - new_packet = FALSE; - continue; - } - - event_pckt = (void *) (hci_hdr->data); - - ptr = hci_buffer + (1 + HCI_EVENT_HDR_SIZE); - len = hci_pckt_len - (1 + HCI_EVENT_HDR_SIZE); - - switch (event_pckt->evt) { - - case EVT_CMD_STATUS: - cs = (void *) ptr; - - if (cs->opcode != opcode) - break; - - if (r->event != EVT_CMD_STATUS) { - if (cs->status) { - goto failed; - } - break; - } - - r->rlen = MIN(len, r->rlen); - Osal_MemCpy(r->rparam, ptr, r->rlen); - goto done; - - case EVT_CMD_COMPLETE: - cc = (void *) ptr; - - if (cc->opcode != opcode) - break; - - ptr += EVT_CMD_COMPLETE_SIZE; - len -= EVT_CMD_COMPLETE_SIZE; - - r->rlen = MIN(len, r->rlen); - Osal_MemCpy(r->rparam, ptr, r->rlen); - goto done; - - case EVT_LE_META_EVENT: - me = (void *) ptr; - - if (me->subevent != r->event) - break; - - len -= 1; - r->rlen = MIN(len, r->rlen); - Osal_MemCpy(r->rparam, me->data, r->rlen); - goto done; - - case EVT_HARDWARE_ERROR: - goto failed; - - default: - break; // In the meantime there could be other events from the controller. - } - - new_packet = FALSE; - - } - -failed: - hci_set_packet_complete_callback(NULL); - return -1; - -done: - hci_set_packet_complete_callback(NULL); - HCI_Cmd_Status(AVAILABLE); - return 0; -} - -int hci_reset() -{ - struct hci_request rq; - uint8_t status; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_RESET; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return -1; - - if (status) { - return -1; - } - - return 0; -} - -int hci_disconnect(uint16_t handle, uint8_t reason) -{ - struct hci_request rq; - disconnect_cp cp; - uint8_t status; - - cp.handle = handle; - cp.reason = reason; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LINK_CTL; - rq.ocf = OCF_DISCONNECT; - rq.cparam = &cp; - rq.clen = DISCONNECT_CP_SIZE; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return -1; - - if (status) { - return -1; - } - - return 0; -} - -int hci_le_read_local_version(uint8_t *hci_version, uint16_t *hci_revision, uint8_t *lmp_pal_version, - uint16_t *manufacturer_name, uint16_t *lmp_pal_subversion) -{ - struct hci_request rq; - read_local_version_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_INFO_PARAM; - rq.ocf = OCF_READ_LOCAL_VERSION; - rq.cparam = NULL; - rq.clen = 0; - rq.rparam = &resp; - rq.rlen = READ_LOCAL_VERSION_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return -1; - - if (resp.status) { - return -1; - } - - - *hci_version = resp.hci_version; - *hci_revision = btohs(resp.hci_revision); - *lmp_pal_version = resp.lmp_pal_version; - *manufacturer_name = btohs(resp.manufacturer_name); - *lmp_pal_subversion = btohs(resp.lmp_pal_subversion); - - return 0; -} - -int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt) -{ - struct hci_request rq; - le_read_buffer_size_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_READ_BUFFER_SIZE; - rq.cparam = NULL; - rq.clen = 0; - rq.rparam = &resp; - rq.rlen = LE_READ_BUFFER_SIZE_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return -1; - - if (resp.status) { - return -1; - } - - *pkt_len = resp.pkt_len; - *max_pkt = resp.max_pkt; - - return 0; -} - -int hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t advtype, - uint8_t own_bdaddr_type, uint8_t direct_bdaddr_type, const tBDAddr direct_bdaddr, uint8_t chan_map, - uint8_t filter) -{ - struct hci_request rq; - le_set_adv_parameters_cp adv_cp; - uint8_t status; - - Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); - adv_cp.min_interval = min_interval; - adv_cp.max_interval = max_interval; - adv_cp.advtype = advtype; - adv_cp.own_bdaddr_type = own_bdaddr_type; - adv_cp.direct_bdaddr_type = direct_bdaddr_type; - Osal_MemCpy(adv_cp.direct_bdaddr,direct_bdaddr,sizeof(adv_cp.direct_bdaddr)); - adv_cp.chan_map = chan_map; - adv_cp.filter = filter; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_SET_ADV_PARAMETERS; - rq.cparam = &adv_cp; - rq.clen = LE_SET_ADV_PARAMETERS_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return -1; - - if (status) { - return -1; - } - - return 0; -} - -int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]) -{ - struct hci_request rq; - le_set_adv_data_cp adv_cp; - uint8_t status; - - Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); - adv_cp.length = length; - Osal_MemCpy(adv_cp.data, data, MIN(31,length)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_SET_ADV_DATA; - rq.cparam = &adv_cp; - rq.clen = LE_SET_ADV_DATA_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return -1; - - if (status) { - return -1; - } - - return 0; -} - -int hci_le_set_advertise_enable(uint8_t enable) -{ - struct hci_request rq; - le_set_advertise_enable_cp adv_cp; - uint8_t status; - - Osal_MemSet(&adv_cp, 0, sizeof(adv_cp)); - adv_cp.enable = enable?1:0; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_SET_ADVERTISE_ENABLE; - rq.cparam = &adv_cp; - rq.clen = LE_SET_ADVERTISE_ENABLE_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return -1; - - if (status) { - return -1; - } - - return 0; -} - -int hci_le_rand(uint8_t random_number[8]) -{ - struct hci_request rq; - le_rand_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_RAND; - rq.cparam = NULL; - rq.clen = 0; - rq.rparam = &resp; - rq.rlen = LE_RAND_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return -1; - - if (resp.status) { - return -1; - } - - Osal_MemCpy(random_number, resp.random, 8); - - return 0; -} - -int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]) -{ - struct hci_request rq; - le_set_scan_response_data_cp scan_resp_cp; - uint8_t status; - - Osal_MemSet(&scan_resp_cp, 0, sizeof(scan_resp_cp)); - scan_resp_cp.length = length; - Osal_MemCpy(scan_resp_cp.data, data, MIN(31,length)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_SET_SCAN_RESPONSE_DATA; - rq.cparam = &scan_resp_cp; - rq.clen = LE_SET_SCAN_RESPONSE_DATA_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return -1; - - if (status) { - return -1; - } - - return 0; -} - -int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level) -{ - struct hci_request rq; - le_read_adv_channel_tx_power_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_READ_ADV_CHANNEL_TX_POWER; - rq.cparam = NULL; - rq.clen = 0; - rq.rparam = &resp; - rq.rlen = LE_RAND_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return -1; - - if (resp.status) { - return -1; - } - - *tx_power_level = resp.level; - - return 0; -} - -int hci_le_set_random_address(tBDAddr bdaddr) -{ - struct hci_request rq; - le_set_random_address_cp set_rand_addr_cp; - uint8_t status; - - Osal_MemSet(&set_rand_addr_cp, 0, sizeof(set_rand_addr_cp)); - Osal_MemCpy(set_rand_addr_cp.bdaddr, bdaddr, sizeof(tBDAddr)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_SET_RANDOM_ADDRESS; - rq.cparam = &set_rand_addr_cp; - rq.clen = LE_SET_RANDOM_ADDRESS_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return -1; - - if (status) { - return -1; - } - - return 0; -} - -int hci_read_bd_addr(tBDAddr bdaddr) -{ - struct hci_request rq; - read_bd_addr_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_INFO_PARAM; - rq.ocf = OCF_READ_BD_ADDR; - rq.cparam = NULL; - rq.clen = 0; - rq.rparam = &resp; - rq.rlen = READ_BD_ADDR_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return -1; - - if (resp.status) { - return -1; - } - Osal_MemCpy(bdaddr, resp.bdaddr, sizeof(tBDAddr)); - - return 0; -} - -int hci_le_create_connection(uint16_t interval, uint16_t window, uint8_t initiator_filter, uint8_t peer_bdaddr_type, - const tBDAddr peer_bdaddr, uint8_t own_bdaddr_type, uint16_t min_interval, uint16_t max_interval, - uint16_t latency, uint16_t supervision_timeout, uint16_t min_ce_length, uint16_t max_ce_length) -{ - struct hci_request rq; - le_create_connection_cp create_cp; - uint8_t status; - - Osal_MemSet(&create_cp, 0, sizeof(create_cp)); - create_cp.interval = interval; - create_cp.window = window; - create_cp.initiator_filter = initiator_filter; - create_cp.peer_bdaddr_type = peer_bdaddr_type; - Osal_MemCpy(create_cp.peer_bdaddr, peer_bdaddr, sizeof(tBDAddr)); - create_cp.own_bdaddr_type = own_bdaddr_type; - create_cp.min_interval=min_interval; - create_cp.max_interval=max_interval; - create_cp.latency = latency; - create_cp.supervision_timeout=supervision_timeout; - create_cp.min_ce_length=min_ce_length; - create_cp.max_ce_length=max_ce_length; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_CREATE_CONN; - rq.cparam = &create_cp; - rq.clen = LE_CREATE_CONN_CP_SIZE; - rq.event = EVT_CMD_STATUS; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0) - return -1; - - if (status) { - return -1; - } - - return 0; -} - -int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]) -{ - struct hci_request rq; - le_encrypt_cp params; - le_encrypt_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemCpy(params.key, key, 16); - Osal_MemCpy(params.plaintext, plaintextData, 16); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_ENCRYPT; - rq.cparam = ¶ms; - rq.clen = LE_ENCRYPT_CP_SIZE; - rq.rparam = &resp; - rq.rlen = LE_ENCRYPT_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0){ - return -1; - } - - if (resp.status) { - return -1; - } - - Osal_MemCpy(encryptedData, resp.encdata, 16); - - return 0; -} - -int hci_le_ltk_request_reply(uint8_t key[16]) -{ - struct hci_request rq; - le_ltk_reply_cp params; - le_ltk_reply_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - params.handle = 1; - Osal_MemCpy(params.key, key, 16); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_LTK_REPLY; - rq.cparam = ¶ms; - rq.clen = LE_LTK_REPLY_CP_SIZE; - rq.rparam = &resp; - rq.rlen = LE_LTK_REPLY_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return -1; - - if (resp.status) { - return -1; - } - - return 0; -} - -int hci_le_ltk_request_neg_reply() -{ - struct hci_request rq; - le_ltk_neg_reply_cp params; - le_ltk_neg_reply_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - params.handle = 1; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_LTK_NEG_REPLY; - rq.cparam = ¶ms; - rq.clen = LE_LTK_NEG_REPLY_CP_SIZE; - rq.rparam = &resp; - rq.rlen = LE_LTK_NEG_REPLY_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0) - return -1; - - if (resp.status) { - return -1; - } - - return 0; -} - -int hci_le_read_white_list_size(uint8_t *size) -{ - struct hci_request rq; - le_read_white_list_size_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_READ_WHITE_LIST_SIZE; - rq.rparam = &resp; - rq.rlen = LE_READ_WHITE_LIST_SIZE_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0){ - return -1; - } - - if (resp.status) { - return -1; - } - - *size = resp.size; - - return 0; -} - -int hci_le_clear_white_list() -{ - struct hci_request rq; - uint8_t status; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_CLEAR_WHITE_LIST; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0){ - return -1; - } - - if (status) { - return -1; - } - - return 0; -} - -int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) -{ - struct hci_request rq; - le_add_device_to_white_list_cp params; - uint8_t status; - - params.bdaddr_type = bdaddr_type; - Osal_MemCpy(params.bdaddr, bdaddr, 6); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_ADD_DEVICE_TO_WHITE_LIST; - rq.cparam = ¶ms; - rq.clen = LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0){ - return -1; - } - - if (status) { - return -1; - } - - return 0; -} - -int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr) -{ - struct hci_request rq; - le_remove_device_from_white_list_cp params; - uint8_t status; - - params.bdaddr_type = bdaddr_type; - Osal_MemCpy(params.bdaddr, bdaddr, 6); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST; - rq.cparam = ¶ms; - rq.clen = LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0){ - return -1; - } - - if (status) { - return -1; - } - - return 0; -} - -int hci_read_transmit_power_level(uint16_t *conn_handle, uint8_t type, int8_t * tx_level) -{ - struct hci_request rq; - read_transmit_power_level_cp params; - read_transmit_power_level_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - params.handle = *conn_handle; - params.type = type; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_HOST_CTL; - rq.ocf = OCF_READ_TRANSMIT_POWER_LEVEL; - rq.cparam = ¶ms; - rq.clen = READ_TRANSMIT_POWER_LEVEL_CP_SIZE; - rq.rparam = &resp; - rq.rlen = READ_TRANSMIT_POWER_LEVEL_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0){ - return -1; - } - - if (resp.status) { - return -1; - } - - *conn_handle = resp.handle; - *tx_level = resp.level; - - return 0; -} - -int hci_read_rssi(uint16_t *conn_handle, int8_t * rssi) -{ - struct hci_request rq; - read_rssi_cp params; - read_rssi_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - params.handle = *conn_handle; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_STATUS_PARAM; - rq.ocf = OCF_READ_RSSI; - rq.cparam = ¶ms; - rq.clen = READ_RSSI_CP_SIZE; - rq.rparam = &resp; - rq.rlen = READ_RSSI_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0){ - return -1; - } - - if (resp.status) { - return -1; - } - - *conn_handle = resp.handle; - *rssi = resp.rssi; - - return 0; -} - -int hci_le_read_local_supported_features(uint8_t *features) -{ - struct hci_request rq; - le_read_local_supported_features_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_READ_LOCAL_SUPPORTED_FEATURES; - rq.rparam = &resp; - rq.rlen = LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0){ - return -1; - } - - if (resp.status) { - return -1; - } - - Osal_MemCpy(features, resp.features, sizeof(resp.features)); - - return 0; -} - -int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]) -{ - struct hci_request rq; - le_read_channel_map_cp params; - le_read_channel_map_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - params.handle = conn_handle; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_READ_CHANNEL_MAP; - rq.cparam = ¶ms; - rq.clen = LE_READ_CHANNEL_MAP_CP_SIZE; - rq.rparam = &resp; - rq.rlen = LE_READ_CHANNEL_MAP_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0){ - return -1; - } - - if (resp.status) { - return -1; - } - - Osal_MemCpy(ch_map, resp.map, 5); - - return 0; -} - -int hci_le_read_supported_states(uint8_t states[8]) -{ - struct hci_request rq; - le_read_supported_states_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_READ_SUPPORTED_STATES; - rq.rparam = &resp; - rq.rlen = LE_READ_SUPPORTED_STATES_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0){ - return -1; - } - - if (resp.status) { - return -1; - } - - Osal_MemCpy(states, resp.states, 8); - - return 0; -} - -int hci_le_receiver_test(uint8_t frequency) -{ - struct hci_request rq; - le_receiver_test_cp params; - uint8_t status; - - params.frequency = frequency; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_RECEIVER_TEST; - rq.cparam = ¶ms; - rq.clen = LE_RECEIVER_TEST_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0){ - return -1; - } - - if (status) { - return -1; - } - - return 0; -} - -int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload) -{ - struct hci_request rq; - le_transmitter_test_cp params; - uint8_t status; - - params.frequency = frequency; - params.length = length; - params.payload = payload; - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_TRANSMITTER_TEST; - rq.cparam = ¶ms; - rq.clen = LE_TRANSMITTER_TEST_CP_SIZE; - rq.rparam = &status; - rq.rlen = 1; - - if (hci_send_req(&rq, FALSE) < 0){ - return -1; - } - - if (status) { - return -1; - } - - return 0; -} - -int hci_le_test_end(uint16_t *num_pkts) -{ - struct hci_request rq; - le_test_end_rp resp; - - Osal_MemSet(&resp, 0, sizeof(resp)); - - Osal_MemSet(&rq, 0, sizeof(rq)); - rq.ogf = OGF_LE_CTL; - rq.ocf = OCF_LE_TEST_END; - rq.rparam = &resp; - rq.rlen = LE_TEST_END_RP_SIZE; - - if (hci_send_req(&rq, FALSE) < 0){ - return -1; - } - - if (resp.status) { - return -1; - } - - *num_pkts = resp.num_pkts; - - return 0; -} - -#endif /* __DMA_LP__ */ \ No newline at end of file
--- a/source/BlueNRG_HCI/utils/gp_timer.c Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2004, Swedish Institute of Computer Science. - * All rights reserved. - * - * 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 the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * This file is part of the Contiki operating system. - * - * Author: Adam Dunkels <adam@sics.se> - * - */ - -#include "clock.h" -#include "gp_timer.h" - -/*---------------------------------------------------------------------------*/ -/** - * Set a timer. - * - * This function sets a timer for a time sometime in the - * future. The function timer_expired() will evaluate to true after - * the timer has expired. - * - * @param[in] t A pointer to the timer - * @param[in] interval The interval before the timer expires. - * - */ -void -Timer_Set(struct timer *t, tClockTime interval) -{ - t->interval = interval; - t->start = Clock_Time(); -} -/*---------------------------------------------------------------------------*/ -/** - * Reset the timer with the same interval. - * - * This function resets the timer with the same interval that was - * given to the timer_set() function. The start point of the interval - * is the exact time that the timer last expired. Therefore, this - * function will cause the timer to be stable over time, unlike the - * timer_restart() function. - * - * \param t A pointer to the timer. - * - * \sa timer_restart() - */ -void -Timer_Reset(struct timer *t) -{ - t->start += t->interval; -} -/*---------------------------------------------------------------------------*/ -/** - * Restart the timer from the current point in time - * - * This function restarts a timer with the same interval that was - * given to the timer_set() function. The timer will start at the - * current time. - * - * \note A periodic timer will drift if this function is used to reset - * it. For preioric timers, use the timer_reset() function instead. - * - * \param t A pointer to the timer. - * - * \sa timer_reset() - */ -void -Timer_Restart(struct timer *t) -{ - t->start = Clock_Time(); -} -/*---------------------------------------------------------------------------*/ -/** - * Check if a timer has expired. - * - * This function tests if a timer has expired and returns true or - * false depending on its status. - * - * \param t A pointer to the timer - * - * \return Non-zero if the timer has expired, zero otherwise. - * - */ -int -Timer_Expired(struct timer *t) -{ - /* Note: Can not return diff >= t->interval so we add 1 to diff and return - t->interval < diff - required to avoid an internal error in mspgcc. */ - tClockTime diff = (Clock_Time() - t->start) + 1; - return t->interval < diff; - -} -/*---------------------------------------------------------------------------*/ -/** - * The time until the timer expires - * - * This function returns the time until the timer expires. - * - * \param t A pointer to the timer - * - * \return The time until the timer expires - * - */ -tClockTime -Timer_Remaining(struct timer *t) -{ - return t->start + t->interval - Clock_Time(); -} -/*---------------------------------------------------------------------------*/ -#ifdef __DMA_LP__ - -tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, - TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, - uint8_t *timerID) -{ - TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot, - (pf_TIMER_TimerCallBack_t) timercb); - TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE); - - return (BLE_STATUS_SUCCESS); -} - -/*---------------------------------------------------------------------------*/ -tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID) -{ - TIMER_Delete(timerID); - - return (BLE_STATUS_SUCCESS); -} - -#endif /* __DMA_LP__ */ -/*---------------------------------------------------------------------------*/
--- a/source/BlueNRG_HCI/utils/list.c Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,119 +0,0 @@ -/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** -* File Name : list.c -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 19-July-2012 -* Description : Circular Linked List Implementation. -******************************************************************************** -* 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. -*******************************************************************************/ - -/****************************************************************************** - * Include Files -******************************************************************************/ -#include <hal_types.h> -#include "list.h" - -/****************************************************************************** - * Function Definitions -******************************************************************************/ -void list_init_head (tListNode * listHead) -{ - listHead->next = listHead; - listHead->prev = listHead; -} - -uint8_t list_is_empty (tListNode * listHead) -{ - return ((listHead->next == listHead)? TRUE:FALSE); -} - -void list_insert_head (tListNode * listHead, tListNode * node) -{ - node->next = listHead->next; - node->prev = listHead; - listHead->next = node; - (node->next)->prev = node; -} - - -void list_insert_tail (tListNode * listHead, tListNode * node) -{ - node->next = listHead; - node->prev = listHead->prev; - listHead->prev = node; - (node->prev)->next = node; -} - - -void list_remove_node (tListNode * node) -{ - (node->prev)->next = node->next; - (node->next)->prev = node->prev; -} - - -void list_remove_head (tListNode * listHead, tListNode ** node ) -{ - *node = listHead->next; - list_remove_node (listHead->next); - (*node)->next = NULL; - (*node)->prev = NULL; -} - - -void list_remove_tail (tListNode * listHead, tListNode ** node ) -{ - *node = listHead->prev; - list_remove_node (listHead->prev); - (*node)->next = NULL; - (*node)->prev = NULL; -} - - -void list_insert_node_after (tListNode * node, tListNode * ref_node) -{ - node->next = ref_node->next; - node->prev = ref_node; - ref_node->next = node; - (node->next)->prev = node; -} - - -void list_insert_node_before (tListNode * node, tListNode * ref_node) -{ - node->next = ref_node; - node->prev = ref_node->prev; - ref_node->prev = node; - (node->prev)->next = node; -} - - -int list_get_size (tListNode * listHead) -{ - int size = 0; - tListNode * temp = listHead->next; - while (temp != listHead) - { - size++; - temp = temp->next; - } - return (size); -} - -void list_get_next_node (tListNode * ref_node, tListNode ** node) -{ - *node = ref_node->next; -} - - -void list_get_prev_node (tListNode * ref_node, tListNode ** node) -{ - *node = ref_node->prev; -} -
--- a/source/BlueNRG_HCI/utils/osal.c Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -/** -****************************************************************************** -* @file osal.c -* @author AMS - HEA&RF BU / CL -* @version V1.0.0 -* @date 04-July-2014 -* @brief Implementation of OS abstraction layer functions used by the -* library. -****************************************************************************** -* @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. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include <string.h> -#include <osal.h> - - /** - * @brief Osal_MemCpy - * @param dest: Pointer to the destination buffer - * @param src : Pointer to the source buffer - * @param size: Number of bytes to copy from the source to the destination - * buffer - * @retval Pointer to the destination buffer - */ -void* Osal_MemCpy(void *dest, const void *src, unsigned int size) -{ - return(memcpy(dest,src,size)); -} - -/** - * @brief Osal_MemSet - * @param ptr : Pointer to block of memory to fill - * @param value: Value to assign to each byte of the memory block - * @param size : Number of bytes to be set to "value" - * @retval Pointer to the filled block of memory - */ -void* Osal_MemSet(void *ptr, int value, unsigned int size) -{ - return(memset(ptr,value,size)); -} - -/****************************************************************************** - * local Functions - *****************************************************************************/ - - /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/bluenrg-hci/hci/controller/bluenrg_gap_aci.c Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,1306 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* 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. +*******************************************************************************/ + +#include "hal_types.h" +#include "osal.h" +#include "ble_status.h" +#include "hal.h" +#include "osal.h" +#include "hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, uint8_t device_name_char_len, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB05A1 cp; + gap_init_rp resp; + + cp.role = role; + cp.privacy_enabled = privacy_enabled; + cp.device_name_char_len = device_name_char_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} +tBleStatus aci_gap_init_IDB04A1(uint8_t role, uint16_t* service_handle, uint16_t* dev_name_char_handle, uint16_t* appearance_char_handle) +{ + struct hci_request rq; + gap_init_cp_IDB04A1 cp; + gap_init_rp resp; + + cp.role = role; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_INIT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *service_handle = btohs(resp.service_handle); + *dev_name_char_handle = btohs(resp.dev_name_char_handle); + *appearance_char_handle = btohs(resp.appearance_char_handle); + + return 0; +} + +tBleStatus aci_gap_set_non_discoverable(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_DISCOVERABLE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if((unsigned int)(LocalNameLen + ServiceUUIDLen + 14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_LIMITED_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[40]; + uint8_t indx = 0; + + if ((unsigned int)(LocalNameLen+ServiceUUIDLen+14) > sizeof(buffer)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvType; + indx++; + + AdvIntervMin = htobs(AdvIntervMin); + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + AdvIntervMax = htobs(AdvIntervMax); + Osal_MemCpy(buffer + indx, &AdvIntervMax, 2); + indx += 2; + + buffer[indx] = OwnAddrType; + indx++; + + buffer[indx] = AdvFilterPolicy; + indx++; + + buffer[indx] = LocalNameLen; + indx++; + + Osal_MemCpy(buffer + indx, LocalName, LocalNameLen); + indx += LocalNameLen; + + buffer[indx] = ServiceUUIDLen; + indx++; + + Osal_MemCpy(buffer + indx, ServiceUUIDList, ServiceUUIDLen); + indx += ServiceUUIDLen; + + SlaveConnIntervMin = htobs(SlaveConnIntervMin); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMin, 2); + indx += 2; + + SlaveConnIntervMax = htobs(SlaveConnIntervMax); + Osal_MemCpy(buffer + indx, &SlaveConnIntervMax, 2); + indx += 2; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB05A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.directed_adv_type = directed_adv_type; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr) +{ + struct hci_request rq; + gap_set_direct_conectable_cp_IDB04A1 cp; + uint8_t status; + + cp.own_bdaddr_type = own_addr_type; + cp.direct_bdaddr_type = initiator_addr_type; + Osal_MemCpy(cp.direct_bdaddr, initiator_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_DIRECT_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_io_capability(uint8_t io_capability) +{ + struct hci_request rq; + uint8_t status; + gap_set_io_capability_cp cp; + + cp.io_capability = io_capability; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_IO_CAPABILITY; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode) +{ + struct hci_request rq; + gap_set_auth_requirement_cp cp; + uint8_t status; + + cp.mitm_mode = mitm_mode; + cp.oob_enable = oob_enable; + Osal_MemCpy(cp.oob_data, oob_data, 16); + cp.min_encryption_key_size = min_encryption_key_size; + cp.max_encryption_key_size = max_encryption_key_size; + cp.use_fixed_pin = use_fixed_pin; + cp.fixed_pin = htobl(fixed_pin); + cp.bonding_mode = bonding_mode; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTH_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable) +{ + struct hci_request rq; + gap_set_author_requirement_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorization_enable = authorization_enable; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_AUTHOR_REQUIREMENT; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey) +{ + struct hci_request rq; + gap_passkey_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.passkey = htobl(passkey); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_PASSKEY_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize) +{ + struct hci_request rq; + gap_authorization_response_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.authorize = authorize; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_AUTHORIZATION_RESPONSE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB05A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + cp.own_address_type = own_address_type; + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type) +{ + struct hci_request rq; + gap_set_non_connectable_cp_IDB04A1 cp; + uint8_t status; + + cp.advertising_event_type = adv_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_NON_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy) +{ + struct hci_request rq; + gap_set_undirected_connectable_cp cp; + uint8_t status; + + cp.own_addr_type = own_addr_type; + cp.adv_filter_policy = adv_filter_policy; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_UNDIRECTED_CONNECTABLE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection) +{ + struct hci_request rq; + gap_slave_security_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.bonding = bonding; + cp.mitm_protection = mitm_protection; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SLAVE_SECURITY_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[32]; + uint8_t indx = 0; + + if (AdvLen > (sizeof(buffer)-1)) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = AdvLen; + indx++; + + Osal_MemCpy(buffer + indx, AdvData, AdvLen); + indx += AdvLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_UPDATE_ADV_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type) +{ + struct hci_request rq; + gap_delete_ad_type_cp cp; + uint8_t status; + + cp.ad_type = ad_type; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_DELETE_AD_TYPE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required) +{ + struct hci_request rq; + gap_get_security_level_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_SECURITY_LEVEL; + rq.rparam = &resp; + rq.rlen = GAP_GET_SECURITY_LEVEL_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *mitm_protection = resp.mitm_protection; + *bonding = resp.bonding; + *oob_data = resp.oob_data; + *passkey_required = resp.passkey_required; + + return resp.status; +} + +tBleStatus aci_gap_configure_whitelist(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CONFIGURE_WHITELIST; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason) +{ + struct hci_request rq; + gap_terminate_cp cp; + uint8_t status; + + cp.handle = htobs(conn_handle); + cp.reason = reason; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_clear_security_database(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CLEAR_SECURITY_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle) +{ + struct hci_request rq; + gap_allow_rebond_cp_IDB05A1 cp; + uint8_t status; + + cp.conn_handle = conn_handle; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_allow_rebond_IDB04A1(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_ALLOW_REBOND_DB; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_limited_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_LIMITED_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates) +{ + struct hci_request rq; + gap_start_general_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.own_address_type = own_address_type; + cp.filterDuplicates = filterDuplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_name_discovery_proc_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_NAME_DISCOVERY_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if (((num_whitelist_entries*7)+25) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + scanInterval = htobs(scanInterval); + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + scanWindow = htobs(scanWindow); + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + conn_min_interval = htobs(conn_min_interval); + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + conn_max_interval = htobs(conn_max_interval); + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + conn_latency = htobs(conn_latency); + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + supervision_timeout = htobs(supervision_timeout); + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + min_conn_length = htobs(min_conn_length); + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + max_conn_length = htobs(max_conn_length); + Osal_MemCpy(buffer + indx, &max_conn_length, 2); + indx += 2; + + buffer[indx] = use_reconn_addr; + indx++; + + Osal_MemCpy(buffer + indx, reconn_addr, 6); + indx += 6; + + buffer[indx] = num_whitelist_entries; + indx++; + + Osal_MemCpy(buffer + indx, addr_array, (num_whitelist_entries*7)); + indx += num_whitelist_entries * 7; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB05A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr) +{ + struct hci_request rq; + gap_start_general_conn_establish_proc_cp_IDB04A1 cp; + uint8_t status; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.use_reconn_addr = use_reconn_addr; + Osal_MemCpy(cp.reconn_addr, reconn_addr, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_start_selective_conn_establish_proc_cp cp; + uint8_t status; + + if (((num_whitelist_entries*7)+GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.scan_type = scan_type; + cp.scan_interval = htobs(scan_interval); + cp.scan_window = htobs(scan_window); + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + cp.num_whitelist_entries = num_whitelist_entries; + + Osal_MemCpy(cp.addr_array, addr_array, (num_whitelist_entries*7)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC; + rq.cparam = &cp; + rq.clen = GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE + (num_whitelist_entries*7); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_create_connection_cp cp; + uint8_t status; + + cp.scanInterval = htobs(scanInterval); + cp.scanWindow = htobs(scanWindow); + cp.peer_bdaddr_type = peer_bdaddr_type; + Osal_MemCpy(cp.peer_bdaddr, peer_bdaddr, 6); + cp.own_bdaddr_type = own_bdaddr_type; + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_CREATE_CONNECTION; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_TERMINATE_GAP_PROCEDURE; + rq.cparam = &procedure_code; + rq.clen = 1; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; + +} + +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length) +{ + struct hci_request rq; + gap_start_connection_update_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.conn_min_interval = htobs(conn_min_interval); + cp.conn_max_interval = htobs(conn_max_interval); + cp.conn_latency = htobs(conn_latency); + cp.supervision_timeout = htobs(supervision_timeout); + cp.min_conn_length = htobs(min_conn_length); + cp.max_conn_length = htobs(max_conn_length); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_CONNECTION_UPDATE; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond) +{ + struct hci_request rq; + gap_send_pairing_request_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + cp.force_rebond = force_rebond; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SEND_PAIRING_REQUEST; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + gap_resolve_private_address_rp rp; + + Osal_MemCpy(cp.address, private_address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + 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; + + Osal_MemCpy(actual_address, rp.address, sizeof(actual_address)); + + return 0; +} +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr address) +{ + struct hci_request rq; + gap_resolve_private_address_cp cp; + uint8_t status; + + Osal_MemCpy(cp.address, address, 6); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_RESOLVE_PRIVATE_ADDRESS; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_set_broadcast_mode(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array) +{ + struct hci_request rq; + gap_set_broadcast_mode_cp cp; + uint8_t status; + uint8_t indx = 0; + uint8_t variable_size = 1 + adv_data_length + 1 + num_whitelist_entries*7; + + if (variable_size > sizeof(cp.var_len_data) ) + return BLE_STATUS_INVALID_PARAMS; + + cp.adv_interv_min = htobs(adv_interv_min); + cp.adv_interv_max = htobs(adv_interv_max); + cp.adv_type = adv_type; + cp.own_addr_type = own_addr_type; + + cp.var_len_data[indx] = adv_data_length; + indx++; + Osal_MemCpy(cp.var_len_data + indx, adv_data, adv_data_length); + indx += adv_data_length; + cp.var_len_data[indx] = num_whitelist_entries; + indx ++; + Osal_MemCpy(cp.var_len_data + indx, addr_array, num_whitelist_entries*7); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_SET_BROADCAST_MODE; + rq.cparam = &cp; + rq.clen = GAP_SET_BROADCAST_MODE_CP_SIZE + variable_size; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +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) +{ + struct hci_request rq; + gap_start_observation_proc_cp cp; + uint8_t status; + + cp.scan_interval = scan_interval; + cp.scan_window = scan_window; + cp.scan_type = scan_type; + cp.own_address_type = own_address_type; + cp.filter_duplicates = filter_duplicates; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_START_OBSERVATION_PROC; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_is_device_bonded(uint8_t peer_address_type, const tBDAddr peer_address) +{ + struct hci_request rq; + gap_is_device_bonded_cp cp; + uint8_t status; + + cp.peer_address_type = peer_address_type; + Osal_MemCpy(cp.peer_address, peer_address, sizeof(cp.peer_address)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_IS_DEVICE_BONDED; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size) +{ + struct hci_request rq; + gap_get_bonded_devices_rp rp; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GAP_GET_BONDED_DEVICES; + rq.rparam = &rp; + rq.rlen = sizeof(rp); + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (rp.status) { + return rp.status; + } + + *num_devices = rp.num_addr; + Osal_MemCpy(device_list, rp.dev_list, MIN(device_list_size,rp.num_addr*7)); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/bluenrg-hci/hci/controller/bluenrg_gatt_aci.c Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,1472 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.c +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : File with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* 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. +*******************************************************************************/ + +#include "hal_types.h" +#include "osal.h" +#include "ble_status.h" +#include "hal.h" +#include "osal.h" +#include "hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + + +tBleStatus aci_gatt_init(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INIT; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, const uint8_t* service_uuid, uint8_t service_type, uint8_t max_attr_records, uint16_t *serviceHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[19]; + uint8_t uuid_len; + uint8_t indx = 0; + + buffer[indx] = service_uuid_type; + indx++; + + if(service_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, service_uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = service_type; + indx++; + + buffer[indx] = max_attr_records; + indx++; + + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *serviceHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle) +{ + struct hci_request rq; + gatt_include_serv_rp resp; + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + service_handle = htobs(service_handle); + Osal_MemCpy(buffer, &service_handle, 2); + indx += 2; + + included_start_handle = htobs(included_start_handle); + Osal_MemCpy(buffer+indx, &included_start_handle, 2); + indx += 2; + + included_end_handle = htobs(included_end_handle); + Osal_MemCpy(buffer+indx, &included_end_handle, 2); + indx += 2; + + if(included_uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } else { + uuid_len = 16; + } + + buffer[indx] = included_uuid_type; + indx++; + + Osal_MemCpy(buffer + indx, included_uuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_INCLUDE_SERV; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_INCLUDE_SERV_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *included_handle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[25]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + buffer[indx] = charValueLen; + indx++; + + buffer[indx] = charProperties; + indx++; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *charHandle = btohs(resp.handle); + + return 0; +} + +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle) +{ + struct hci_request rq; + gatt_add_char_desc_rp resp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t uuid_len; + uint8_t indx = 0; + + serviceHandle = htobs(serviceHandle); + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = descUuidType; + indx++; + + if(descUuidType == UUID_TYPE_16){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, uuid, uuid_len); + indx += uuid_len; + + buffer[indx] = descValueMaxLen; + indx++; + + buffer[indx] = descValueLen; + indx++; + + if ((descValueLen+indx+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + Osal_MemCpy(buffer + indx, descValue, descValueLen); + indx += descValueLen; + + buffer[indx] = secPermissions; + indx++; + + buffer[indx] = accPermissions; + indx++; + + buffer[indx] = gattEvtMask; + indx++; + + buffer[indx] = encryKeySize; + indx++; + + buffer[indx] = isVariable; + indx++; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ADD_CHAR_DESC; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &resp; + rq.rlen = GATT_ADD_CHAR_DESC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *descHandle = btohs(resp.handle); + + return 0; +} + + +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const uint8_t *charValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charValueLen+6) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = charValOffset; + indx++; + + buffer[indx] = charValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charValue, charValueLen); + indx += charValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_UPD_CHAR_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_char_cp cp; + + cp.service_handle = htobs(servHandle); + cp.char_handle = htobs(charHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_CHAR; + rq.cparam = &cp; + rq.clen = GATT_DEL_CHAR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_service(uint16_t servHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_serv_cp cp; + + cp.service_handle = htobs(servHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle) +{ + struct hci_request rq; + uint8_t status; + gatt_del_inc_serv_cp cp; + + cp.service_handle = htobs(servHandle); + cp.inc_serv_handle = htobs(includeServHandle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DEL_INC_SERV; + rq.cparam = &cp; + rq.clen = GATT_DEL_INC_SERV_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_event_mask(uint32_t event_mask) +{ + struct hci_request rq; + uint8_t status; + gatt_set_evt_mask_cp cp; + + cp.evt_mask = htobs(event_mask); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_EVT_MASK; + rq.cparam = &cp; + rq.clen = GATT_SET_EVT_MASK_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_exchange_config_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_EXCHANGE_CONFIG; + rq.cparam = &cp; + rq.clen = GATT_EXCHANGE_CONFIG_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle) +{ + struct hci_request rq; + uint8_t status; + att_find_info_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_INFO_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_INFO_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_find_by_type_value_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + Osal_MemCpy(cp.uuid, uuid, 2); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_FIND_BY_TYPE_VALUE_REQ; + rq.cparam = &cp; + rq.clen = ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + att_read_by_group_type_req_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_READ_BY_GROUP_TYPE_REQ; + rq.cparam = &cp; + rq.clen = ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + att_prepare_write_req_cp cp; + + if(attr_val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.value_offset = htobs(value_offset); + cp.attr_val_len = attr_val_len; + Osal_MemCpy(cp.attr_val, attr_val, attr_val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_PREPARE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_PREPARE_WRITE_REQ_CP_SIZE + attr_val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute) +{ + struct hci_request rq; + uint8_t status; + att_execute_write_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.execute = execute; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_ATT_EXECUTE_WRITE_REQ; + rq.cparam = &cp; + rq.clen = ATT_EXECUTE_WRITE_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_prim_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_PRIM_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_prim_service_by_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_PRIM_SERVICE_BY_UUID; + rq.cparam = &cp; + rq.clen = GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE + uuid_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_service_handle, + uint16_t end_service_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_find_included_services_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_service_handle); + cp.end_handle = htobs(end_service_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_FIND_INCLUDED_SERVICES; + rq.cparam = &cp; + rq.clen = GATT_FIND_INCLUDED_SERVICES_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_of_serv_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.start_attr_handle = htobs(start_attr_handle); + cp.end_attr_handle = htobs(end_attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_OF_SERV; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t charUuidType, + const uint8_t* charUuid) +{ + struct hci_request rq; + uint8_t status; + + uint8_t buffer[23]; + uint8_t uuid_len; + uint8_t indx = 0; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + start_handle = htobs(start_handle); + Osal_MemCpy(buffer + indx, &start_handle, 2); + indx += 2; + + end_handle = htobs(end_handle); + Osal_MemCpy(buffer + indx, &end_handle, 2); + indx += 2; + + buffer[indx] = charUuidType; + indx++; + + if(charUuidType == 0x01){ + uuid_len = 2; + } + else { + uuid_len = 16; + } + Osal_MemCpy(buffer + indx, charUuid, uuid_len); + indx += uuid_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_CHARAC_BY_UUID; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_disc_all_charac_descriptors_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.char_val_handle = htobs(char_val_handle); + cp.char_end_handle = htobs(char_end_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS; + rq.cparam = &cp; + rq.clen = GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid) +{ + struct hci_request rq; + uint8_t status; + gatt_read_using_charac_uuid_cp cp; + uint8_t uuid_len; + + if(uuid_type == UUID_TYPE_16){ + uuid_len = 2; + } + else{ + uuid_len = 16; + } + + cp.conn_handle = htobs(conn_handle); + cp.start_handle = htobs(start_handle); + cp.end_handle = htobs(end_handle); + cp.uuid_type = uuid_type; + Osal_MemCpy(cp.uuid, uuid, uuid_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_USING_CHARAC_UUID; + rq.cparam = &cp; + rq.clen = GATT_READ_USING_CHARAC_UUID_CP_SIZE + uuid_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_val_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_VAL_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles) +{ + struct hci_request rq; + uint8_t status; + gatt_read_multiple_charac_val_cp cp; + + if(num_handles*2 > sizeof(cp.set_of_handles)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.num_handles = htobs(num_handles); + Osal_MemCpy(cp.set_of_handles, set_of_handles, 2*num_handles); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_MULTIPLE_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE + 2*num_handles; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + + +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_VALUE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_long_charac_val_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_VAL; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHARAC_RELIABLE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_CHARAC_RELIABLE_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_charac_reliable_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE + val_len; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_offset = htobs(val_offset); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_LONG_CHARAC_DESC; + rq.cparam = &cp; + rq.clen = GATT_READ_LONG_CHARAC_DESC_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((value_len+5) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = value_len; + indx++; + + Osal_MemCpy(buffer + indx, attr_value, value_len); + indx += value_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_CHAR_DESCRIPTOR; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_read_long_charac_desc_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_CHAR_DESCRIPTOR; + rq.cparam = &cp; + rq.clen = GATT_READ_CHAR_DESCRIPTOR_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val) +{ + struct hci_request rq; + uint8_t status; + gatt_signed_write_without_resp_cp cp; + + if(val_len > sizeof(cp.attr_val)) + return BLE_STATUS_INVALID_PARAMS; + + cp.conn_handle = htobs(conn_handle); + cp.attr_handle = htobs(attr_handle); + cp.val_len = val_len; + Osal_MemCpy(cp.attr_val, attr_val, val_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE; + rq.cparam = &cp; + rq.clen = GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE + val_len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle) +{ + struct hci_request rq; + uint8_t status; + gatt_confirm_indication_cp cp; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_CONFIRM_INDICATION; + rq.cparam = &cp; + rq.clen = GATT_CONFIRM_INDICATION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((att_val_len+7) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + conn_handle = htobs(conn_handle); + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + attr_handle = htobs(attr_handle); + Osal_MemCpy(buffer + indx, &attr_handle, 2); + indx += 2; + + buffer[indx] = write_status; + indx += 1; + + buffer[indx] = err_code; + indx += 1; + + buffer[indx] = att_val_len; + indx += 1; + + Osal_MemCpy(buffer + indx, att_val, att_val_len); + indx += att_val_len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_WRITE_RESPONSE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_allow_read(uint16_t conn_handle) +{ + struct hci_request rq; + gatt_allow_read_cp cp; + uint8_t status; + + cp.conn_handle = htobs(conn_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_ALLOW_READ; + rq.cparam = &cp; + rq.clen = GATT_ALLOW_READ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission) +{ + struct hci_request rq; + gatt_set_security_permission_cp cp; + uint8_t status; + + cp.service_handle = htobs(service_handle); + cp.attr_handle = htobs(attr_handle); + cp.security_permission = security_permission; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_SECURITY_PERMISSION; + rq.cparam = &cp; + rq.clen = GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const uint8_t *charDescValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((charDescValueLen+9) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + servHandle = htobs(servHandle); + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + charHandle = htobs(charHandle); + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + charDescHandle = htobs(charDescHandle); + Osal_MemCpy(buffer + indx, &charDescHandle, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &charDescValOffset, 2); + indx += 2; + + buffer[indx] = charDescValueLen; + indx++; + + Osal_MemCpy(buffer + indx, charDescValue, charDescValueLen); + indx += charDescValueLen; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_SET_DESC_VAL; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_cp cp; + gatt_read_handle_val_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE; + 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 = btohs(rp.value_len); + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +} + +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data) +{ + struct hci_request rq; + gatt_read_handle_val_offset_cp cp; + gatt_read_handle_val_offset_rp rp; + + if(data_len > sizeof(rp.value)) + return BLE_STATUS_INVALID_PARAMS; + + cp.attr_handle = htobs(attr_handle); + cp.offset = offset; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GATT_READ_HANDLE_VALUE_OFFSET; + 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 = rp.value_len; + + Osal_MemCpy(data, rp.value, MIN(data_len, *data_len_out_p)); + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/bluenrg-hci/hci/controller/bluenrg_hal_aci.c Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,154 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* 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. +*******************************************************************************/ + +#include "hal_types.h" +#include "osal.h" +#include "ble_status.h" +#include "hal.h" +#include "osal.h" +#include "hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gatt_server.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + + +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + uint8_t indx = 0; + + if ((len+2) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + buffer[indx] = offset; + indx++; + + buffer[indx] = len; + indx++; + + Osal_MemCpy(buffer + indx, val, len); + indx += len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_WRITE_CONFIG_DATA; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level) +{ + struct hci_request rq; + hal_set_tx_power_level_cp cp; + uint8_t status; + + cp.en_high_power = en_high_power; + cp.pa_level = pa_level; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_SET_TX_POWER_LEVEL; + rq.cparam = &cp; + rq.clen = HAL_SET_TX_POWER_LEVEL_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_hal_device_standby(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_DEVICE_STANDBY; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_start(uint8_t rf_channel) +{ + struct hci_request rq; + hal_tone_start_cp cp; + uint8_t status; + + cp.rf_channel = rf_channel; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_START; + rq.cparam = &cp; + rq.clen = HAL_TONE_START_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_hal_tone_stop(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_HAL_TONE_STOP; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/bluenrg-hci/hci/controller/bluenrg_l2cap_aci.c Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,118 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* 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. +*******************************************************************************/ + +#include "hal_types.h" +#include "osal.h" +#include "ble_status.h" +#include "hal.h" +#include "osal.h" +#include "hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_req_cp cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_REQ; + rq.cparam = &cp; + rq.clen = L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB05A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.min_ce_length = htobs(min_ce_length); + cp.max_ce_length = htobs(max_ce_length); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept) +{ + struct hci_request rq; + uint8_t status; + l2cap_conn_param_update_resp_cp_IDB04A1 cp; + + cp.conn_handle = htobs(conn_handle); + cp.interval_min = htobs(interval_min); + cp.interval_max = htobs(interval_max); + cp.slave_latency = htobs(slave_latency); + cp.timeout_multiplier = htobs(timeout_multiplier); + cp.id = id; + cp.accept = accept; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPDATE_RESP; + rq.cparam = &cp; + rq.clen = sizeof(cp); + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/bluenrg-hci/hci/controller/bluenrg_updater_aci.c Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,270 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : File with HCI commands for BlueNRG FW6.0 and above. +******************************************************************************** +* 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. +*******************************************************************************/ + +#include "hal_types.h" +#include "osal.h" +#include "ble_status.h" +#include "hal.h" +#include "osal.h" +#include "hci_const.h" +#include "bluenrg_aci_const.h" +#include "bluenrg_updater_aci.h" + +#define MIN(a,b) ((a) < (b) )? (a) : (b) +#define MAX(a,b) ((a) > (b) )? (a) : (b) + +tBleStatus aci_updater_start(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_START; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_updater_reboot(void) +{ + struct hci_request rq; + uint8_t status = 0; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_REBOOT; + rq.rparam = &status; + rq.rlen = 1; + + hci_send_req(&rq, FALSE); // No command complete is sent. + + return status; +} + +tBleStatus aci_get_updater_version(uint8_t *version) +{ + struct hci_request rq; + get_updater_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_VERSION; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size) +{ + struct hci_request rq; + get_updater_bufsize_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_GET_UPDATER_BUFSIZE; + rq.rparam = &resp; + rq.rlen = GET_UPDATER_BUFSIZE_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *buffer_size = resp.buffer_size; + + return resp.status; +} + +tBleStatus aci_erase_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_reset_blue_flag(void) +{ + struct hci_request rq; + uint8_t status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_RESET_BLUE_FLAG; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_erase_sector(uint32_t address) +{ + struct hci_request rq; + updater_erase_sector_cp cp; + uint8_t status; + + cp.address = htobl(address); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_ERASE_SECTOR; + rq.cparam = &cp; + rq.clen = UPDATER_ERASE_SECTOR_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_program_data_block(uint32_t address, + uint16_t len, + const uint8_t *data) +{ + struct hci_request rq; + uint8_t status; + updater_prog_data_block_cp cp; + + if( len > sizeof(cp.data)) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(len); + Osal_MemCpy(cp.data, data, len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_PROG_DATA_BLOCK_CP_SIZE+len; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +tBleStatus aci_updater_read_data_block(uint32_t address, + uint16_t data_len, + uint8_t *data) +{ + struct hci_request rq; + updater_read_data_block_cp cp; + uint8_t buffer[HCI_MAX_PAYLOAD_SIZE]; + + if((data_len+1) > HCI_MAX_PAYLOAD_SIZE) + return BLE_STATUS_INVALID_PARAMS; + + cp.address = htobl(address); + cp.data_len = htobs(data_len); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_READ_DATA_BLOCK; + rq.cparam = &cp; + rq.clen = UPDATER_READ_DATA_BLOCK_CP_SIZE; + rq.rparam = buffer; + rq.rlen = data_len + 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + // First byte is status + Osal_MemCpy(data, buffer+1, data_len); + + return buffer[0]; +} + +tBleStatus aci_updater_calc_crc(uint32_t address, + uint8_t num_sectors, + uint32_t *crc) +{ + struct hci_request rq; + updater_calc_crc_cp cp; + updater_calc_crc_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + cp.address = htobl(address); + cp.num_sectors = num_sectors; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_CALC_CRC; + rq.cparam = &cp; + rq.clen = UPDATER_CALC_CRC_CP_SIZE; + rq.rparam = &resp; + rq.rlen = UPDATER_CALC_CRC_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *crc = btohl(resp.crc); + + return resp.status; +} + +tBleStatus aci_updater_hw_version(uint8_t *version) +{ + struct hci_request rq; + updater_hw_version_rp resp; + + Osal_MemSet(&resp, 0, sizeof(resp)); + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_HW_VERSION; + rq.rparam = &resp; + rq.rlen = UPDATER_HW_VERSION_RP_SIZE; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + *version = resp.version; + + return resp.status; +} + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/bluenrg-hci/hci/controller/bluenrg_utils.c Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,403 @@ + +#include "hal.h" +#include "hal_types.h" +#include "ble_status.h" +#include "bluenrg_aci.h" +#include "bluenrg_utils.h" +#include "hci.h" +#include "osal.h" +#include "string.h" +#include "stm32_bluenrg_ble.h" + +#define SUPPORTED_BOOTLOADER_VERSION_MIN 3 +#define SUPPORTED_BOOTLOADER_VERSION_MAX 5 + +#define BASE_ADDRESS 0x10010000 + +#define FW_OFFSET (2*1024) // 2 KB +#define FULL_STACK_SIZE (66*1024) // 66 KB +#define BOOTLOADER_SIZE (2*1024) // 2 kB +#define SECTOR_SIZE (2*1024) // 2 KB +#define DATA_SIZE 64 // 64 bytes + +// x**32 + x**26 + x**23 + x ** 22 + x**16 + x**12 + x**11 + +// x**10 + x**8 + x**7 + x**5 + x**4 + x**2 + x**1 + x**0 +#define CRC_POLY 0x04C11DB7 // the poly without the x**32 + +#define BOOTLOADER_CRC_NOT_PATCHED 0x878FB3FC + +#define IFR_SIZE 192 +#define IFR_BASE_ADDRESS 0x10020000 +#define IFR_CONFIG_DATA_OFFSET (SECTOR_SIZE-IFR_SIZE) // Offset in IFR sector containing configuration data + +#if BLUENRG_MS +#define IFR_WRITE_OFFSET_BEGIN IFR_CONFIG_DATA_OFFSET +#else +#define IFR_WRITE_OFFSET_BEGIN 0 +#endif + + +#define BLUE_FLAG_OFFSET 0x8C0 +#define MAX_ERASE_RETRIES 2 +#define MAX_WRITE_RETRIES 2 +#define MIN_WRITE_BLOCK_SIZE 4 + +#define RETRY_COMMAND(func, num_ret, error) \ +{ \ + uint8_t num_retries; \ + num_retries = 0; \ + error = 0; \ + while (num_retries++ < num_ret) { \ + if (func == BLE_STATUS_SUCCESS) \ + break; \ + if (num_retries == num_ret) \ + error = BLE_UTIL_ACI_ERROR; \ + } \ +} + +typedef struct{ + uint8_t cold_ana_act_config_table[64]; +}cold_table_TypeDef; + +/* This function calculates the CRC of a sector of flash, if bytes passed are less than sector size, + they are extended with 0xFF until sector size is reached +*/ +static uint32_t updater_calc_crc(const uint8_t* data, uint16_t nr_of_bytes) +{ + uint32_t i, j, a1; + uint32_t crc, value; + + crc = 0; + for (i = 0; i < SECTOR_SIZE; i += 4) { + uint8_t *dataw = (uint8_t *) &value; + + dataw[0] = (i < nr_of_bytes) ? data[i] : 0xFF; + dataw[1] = ((i + 1) < nr_of_bytes) ? data[i+1] : 0xFF; + dataw[2] = ((i + 2) < nr_of_bytes) ? data[i+2] : 0xFF; + dataw[3] = ((i + 3) < nr_of_bytes) ? data[i+3] : 0xFF; + + crc = crc ^ value; + for (j = 0; j < 32; j ++) { + a1 = (crc >> 31) & 0x1; + crc = (crc << 1) ^ (a1 * CRC_POLY); + } + } + + return crc; +} + +int program_device(const uint8_t *fw_image, uint32_t fw_size) +{ + uint8_t version, num_erase_retries=0, status, data_size; + uint8_t number_sectors, module; + uint32_t address, j; + uint32_t crc, crc2, crc_size; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + if (fw_size != FULL_STACK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + if (fw_size % MIN_WRITE_BLOCK_SIZE) + return BLE_UTIL_WRONG_IMAGE_SIZE; + + /* Calculate the number of sectors necessary to contain the fw image.*/ + number_sectors = ((fw_size + SECTOR_SIZE - 1) / SECTOR_SIZE); + + /*********************************************************************** + * Erase BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_erase_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + /*********************************************************************** + * Erase and Program sectors + ************************************************************************/ + for(unsigned int i = FW_OFFSET; i < (number_sectors * SECTOR_SIZE); i += SECTOR_SIZE) { + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(BASE_ADDRESS + i); + if ((i/SECTOR_SIZE) < (unsigned int)(number_sectors-1)) + data_size = DATA_SIZE; + else + data_size = MIN_WRITE_BLOCK_SIZE; + for (j=i; ((j<SECTOR_SIZE+i)&&(j<fw_size)); j += data_size) { + RETRY_COMMAND(aci_updater_program_data_block(BASE_ADDRESS+j, data_size, fw_image+j), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + break; + } + if (status == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + } + + /*********************************************************************** + * Verify firmware + ************************************************************************/ + module = fw_size % SECTOR_SIZE; + crc_size = SECTOR_SIZE; + for(int i = SECTOR_SIZE; i < (number_sectors*SECTOR_SIZE); i += SECTOR_SIZE){ + address = BASE_ADDRESS + i; + if(aci_updater_calc_crc(address, 1, &crc)) + return BLE_UTIL_ACI_ERROR; + + if ((module != 0) && ((i/SECTOR_SIZE) == (number_sectors-1))) + crc_size = module; + + crc2 = updater_calc_crc(fw_image+i,crc_size); + if(crc!=crc2) + return BLE_UTIL_CRC_ERROR; + } + + /*********************************************************************** + * Write BLUE flag + ************************************************************************/ + RETRY_COMMAND(aci_reset_blue_flag(), MAX_WRITE_RETRIES, status); + if (status != BLE_STATUS_SUCCESS) + return status; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +int read_IFR(uint8_t *data) +{ + uint8_t version, offset; + tBleStatus ret; + + offset = 0; + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + /*********************************************************************** + * Reading last 3 IFR 64-byte blocks + ************************************************************************/ + for(int i = (FULL_STACK_SIZE - IFR_SIZE); i < FULL_STACK_SIZE; i += DATA_SIZE){ + ret = aci_updater_read_data_block(BASE_ADDRESS+i, DATA_SIZE, (data+offset)); + offset += DATA_SIZE; + if(ret) return BLE_UTIL_ACI_ERROR; + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; + +} + +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config) +{ + IFR_config->stack_mode = data[0]; + IFR_config->slave_sca_ppm = LE_TO_HOST_16(data+28); + IFR_config->master_sca = data[30]; + IFR_config->hs_startup_time = LE_TO_HOST_16(data+32); + IFR_config->year = BCD_TO_INT(data[41]); + IFR_config->month = BCD_TO_INT(data[42]); + IFR_config->day = BCD_TO_INT(data[43]); +} + +int IFR_validate(IFR_config2_TypeDef *IFR_config) +{ + if(IFR_config->stack_mode < 1 || IFR_config->stack_mode > 3) + return BLE_UTIL_PARSE_ERROR; // Unknown Stack Mode + if(IFR_config->master_sca > 7) + return BLE_UTIL_PARSE_ERROR; // Invalid Master SCA + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->day > 31 || IFR_config->day < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + if(IFR_config->month > 12 || IFR_config->month < 1) + return BLE_UTIL_PARSE_ERROR; // Invalid date + + return BLE_STATUS_SUCCESS; +} + +/* TODO: Function to generate data from given options. */ + +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]) +{ + data[0] = IFR_config->stack_mode; + HOST_TO_LE_16(data+28, IFR_config->slave_sca_ppm); + data[30] = IFR_config->master_sca; + HOST_TO_LE_16(data+32, IFR_config->hs_startup_time); + data[41] = INT_TO_BCD(IFR_config->year); + data[42] = INT_TO_BCD(IFR_config->month); + data[43] = INT_TO_BCD(IFR_config->day); +} + + +int program_IFR(const IFR_config_TypeDef *ifr_image) +{ + uint8_t version, num_erase_retries; + tBleStatus ret; +#if BLUENRG_MS + const uint8_t *ifr_data = (uint8_t *)ifr_image; +#else + uint8_t ifr_data[SECTOR_SIZE]; +#endif + uint8_t hwVersion; + uint16_t fwVersion; + + if(getBlueNRGVersion(&hwVersion, &fwVersion)) + return BLE_UTIL_ACI_ERROR; + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + if(version < SUPPORTED_BOOTLOADER_VERSION_MIN || version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + +#ifndef BLUENRG_MS + /*********************************************************************** + * READ IFR data + ************************************************************************/ + for(int i = 0; i < SECTOR_SIZE; i += DATA_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, DATA_SIZE, ifr_data+i); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + } +#endif + + /*********************************************************************** + * Erase & Flashing IFR sectors + ************************************************************************/ +#ifndef BLUENRG_MS + Osal_MemCpy(&ifr_data[SECTOR_SIZE-IFR_SIZE], ifr_image, IFR_SIZE); +#endif + num_erase_retries = 0; + while (num_erase_retries++ < MAX_ERASE_RETRIES) { + aci_updater_erase_sector(IFR_BASE_ADDRESS); + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += DATA_SIZE, j += DATA_SIZE) { + RETRY_COMMAND(aci_updater_program_data_block(IFR_BASE_ADDRESS+i, DATA_SIZE, ifr_data+j), MAX_WRITE_RETRIES, ret); + if (ret != BLE_STATUS_SUCCESS) + break; + } + if (ret == BLE_STATUS_SUCCESS) + break; + } + if (num_erase_retries == MAX_ERASE_RETRIES) + return BLE_UTIL_ACI_ERROR; + + /*********************************************************************** + * Verify IFR + ************************************************************************/ + { + uint8_t ifr_updated[DATA_SIZE]; + for(int i = IFR_WRITE_OFFSET_BEGIN, j = 0; i < SECTOR_SIZE; i += DATA_SIZE, j += DATA_SIZE){ + ret = aci_updater_read_data_block(IFR_BASE_ADDRESS+i, DATA_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ifr_data+j, DATA_SIZE) != 0) + return BLE_UTIL_WRONG_VERIFY; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data) +{ + uint8_t ifr_updated[DATA_SIZE]; + uint8_t version, ret = BLE_STATUS_SUCCESS; + + aci_updater_start(); + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + for(int i = 0; i < IFR_SIZE; i += DATA_SIZE){ + ret = aci_updater_read_data_block((IFR_BASE_ADDRESS+SECTOR_SIZE-IFR_SIZE)+i, DATA_SIZE, ifr_updated); + if(ret != BLE_STATUS_SUCCESS){ + return ret; + } + if (memcmp(ifr_updated, ((uint8_t*)ifr_data)+i, DATA_SIZE) != 0) + { + ret = BLE_UTIL_WRONG_VERIFY; + break; + } + } + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return ret; +} + +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion) +{ + uint8_t status; + uint8_t hci_version, lmp_pal_version; + uint16_t hci_revision, manufacturer_name, lmp_pal_subversion; + + status = hci_le_read_local_version(&hci_version, &hci_revision, &lmp_pal_version, + &manufacturer_name, &lmp_pal_subversion); + + if (status == BLE_STATUS_SUCCESS) { + *hwVersion = hci_revision >> 8; + *fwVersion = (hci_revision & 0xFF) << 8; // Major Version Number + *fwVersion |= ((lmp_pal_subversion >> 4) & 0xF) << 4; // Minor Version Number + *fwVersion |= lmp_pal_subversion & 0xF; // Patch Version Number + } + + HCI_Process(); // To receive the BlueNRG EVT + + return status; +} + +uint8_t getBlueNRGUpdaterVersion(uint8_t *version) +{ + + BlueNRG_HW_Bootloader(); + HCI_Process(); // To receive the EVT_INITIALIZED + + if(aci_get_updater_version(version)) + return BLE_UTIL_ACI_ERROR; + + if(*version < SUPPORTED_BOOTLOADER_VERSION_MIN || *version > SUPPORTED_BOOTLOADER_VERSION_MAX) + return BLE_UTIL_UNSUPPORTED_VERSION; + + BlueNRG_RST(); + HCI_Process(); // To receive the EVT_INITIALIZED + + return BLE_STATUS_SUCCESS; +} + +uint8_t isHWBootloader_Patched(void) +{ + uint8_t status, version; + uint32_t crc, address = 0x10010000; + + if(aci_get_updater_version(&version)) + return BLE_UTIL_ACI_ERROR; + + RETRY_COMMAND(aci_updater_calc_crc(address, 1, &crc), 2, status); + if (status != BLE_STATUS_SUCCESS) + return 0; + + if (crc == BOOTLOADER_CRC_NOT_PATCHED) + return 0; + + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/bluenrg-hci/hci/hci.c Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,1147 @@ +/** + ****************************************************************************** + * @file hci.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> + */ + +#include "hal_types.h" +#include "osal.h" +#include "ble_status.h" +#include "hal.h" +#include "hci_const.h" +#include "gp_timer.h" + +#include "stm32_bluenrg_ble.h" + +#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) + +tListNode hciReadPktPool; +tListNode hciReadPktRxQueue; +/* pool of hci read packets */ +static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; + +static volatile uint8_t readPacketListFull=FALSE; + +static volatile uint8_t hci_timer_id; +static volatile uint8_t hci_timeout; + +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 + +/** + * Verify if HCI packet is correctly formatted.. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * @return 0 if HCI packet is as expected + */ +int HCI_verify(const tHciDataPacket * hciReadPacket) +{ + const uint8_t *hci_pckt = hciReadPacket->dataBuff; + + if(hci_pckt[HCI_PCK_TYPE_OFFSET] != HCI_EVENT_PKT) + return 1; /* Incorrect type. */ + + if(hci_pckt[EVENT_PARAMETER_TOT_LEN_OFFSET] != hciReadPacket->data_len - (1+HCI_EVENT_HDR_SIZE)) + return 2; /* Wrong length (packet truncated or too long). */ + + return 0; +} + +void HCI_Process(void) +{ + uint8_t data_len; + uint8_t buffer[HCI_READ_PACKET_SIZE]; + tHciDataPacket * hciReadPacket = NULL; + + Disable_SPI_IRQ(); + uint8_t list_empty = list_is_empty(&hciReadPktRxQueue); + /* process any pending events read */ + while(list_empty == FALSE) + { + list_remove_head (&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + Enable_SPI_IRQ(); + HCI_Event_CB(hciReadPacket->dataBuff); + Disable_SPI_IRQ(); + list_insert_tail(&hciReadPktPool, (tListNode *)hciReadPacket); + list_empty = list_is_empty(&hciReadPktRxQueue); + } + if (readPacketListFull) { + while(BlueNRG_DataPresent()) { + data_len = BlueNRG_SPI_Read_All(buffer, HCI_READ_PACKET_SIZE); + if(data_len > 0) + HCI_Event_CB(buffer); + } + readPacketListFull = FALSE; + } + + Enable_SPI_IRQ(); +} + +BOOL HCI_Queue_Empty(void) +{ + return list_is_empty(&hciReadPktRxQueue); +} + +void HCI_Isr(void) +{ + tHciDataPacket * hciReadPacket = NULL; + uint8_t data_len; + + Clear_SPI_EXTI_Flag(); + while(BlueNRG_DataPresent()){ + if (list_is_empty (&hciReadPktPool) == FALSE){ + + /* enqueueing a packet for read */ + list_remove_head (&hciReadPktPool, (tListNode **)&hciReadPacket); + + data_len = BlueNRG_SPI_Read_All(hciReadPacket->dataBuff, HCI_READ_PACKET_SIZE); + if(data_len > 0){ + hciReadPacket->data_len = data_len; + if(HCI_verify(hciReadPacket) == 0) + list_insert_tail(&hciReadPktRxQueue, (tListNode *)hciReadPacket); + else + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); + } + else { + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); + } + + } + else{ + // HCI Read Packet Pool is empty, wait for a free packet. + readPacketListFull = TRUE; + Clear_SPI_EXTI_Flag(); + return; + } + + Clear_SPI_EXTI_Flag(); + } +} + +void hci_write(const void* data1, const void* data2, uint8_t n_bytes1, uint8_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 void move_list(tListNode * dest_list, tListNode * src_list) +{ + pListNode tmp_node; + + while(!list_is_empty(src_list)){ + list_remove_head(src_list, &tmp_node); + list_insert_tail(dest_list, tmp_node); + } +} + +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 to = DEFAULT_TIMEOUT; + struct timer t; + tHciDataPacket * hciReadPacket = NULL; + tListNode hciTempQueue; + + list_init_head(&hciTempQueue); + + hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam); + + if(async){ + goto done; + } + + /* Minimum timeout is 1. */ + if(to == 0) + to = 1; + + Timer_Set(&t, to); + + while(1) { + evt_cmd_complete *cc; + evt_cmd_status *cs; + evt_le_meta_event *me; + int len; + +#if ENABLE_MICRO_SLEEP + while(1){ + ATOMIC_SECTION_BEGIN(); + if(Timer_Expired(&t)){ + ATOMIC_SECTION_END(); + goto failed; + } + if(!HCI_Queue_Empty()){ + ATOMIC_SECTION_END(); + break; + } + Enter_Sleep_Mode(); + ATOMIC_SECTION_END(); + } +#else + while(1){ + if(Timer_Expired(&t)){ + goto failed; + } + if(!HCI_Queue_Empty()){ + break; + } + } +#endif + + /* Extract packet from HCI event queue. */ + Disable_SPI_IRQ(); + list_remove_head(&hciReadPktRxQueue, (tListNode **)&hciReadPacket); + + hci_hdr = (void *)hciReadPacket->dataBuff; + if(hci_hdr->type != HCI_EVENT_PKT){ + list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); // See comment below + Enable_SPI_IRQ(); + continue; + } + + event_pckt = (void *) (hci_hdr->data); + + ptr = hciReadPacket->dataBuff + (1 + HCI_EVENT_HDR_SIZE); + len = hciReadPacket->data_len - (1 + HCI_EVENT_HDR_SIZE); + + switch (event_pckt->evt) { + + case EVT_CMD_STATUS: + cs = (void *) ptr; + + if (cs->opcode != opcode) + goto failed; + + 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) + goto failed; + + 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. + In this case, insert the packet in a different queue. These packets will be + inserted back in the main queue just before exiting from send_req(). + */ + list_insert_tail(&hciTempQueue, (tListNode *)hciReadPacket); + /* Be sure there is at list one packet in the pool to process the expected event. */ + if(list_is_empty(&hciReadPktPool)){ + pListNode tmp_node; + list_remove_head(&hciReadPktRxQueue, &tmp_node); + list_insert_tail(&hciReadPktPool, tmp_node); + } + + Enable_SPI_IRQ(); + + } + +failed: + move_list(&hciReadPktRxQueue, &hciTempQueue); + Enable_SPI_IRQ(); + return -1; + +done: + // Insert the packet back into the pool. + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); + move_list(&hciReadPktRxQueue, &hciTempQueue); + + Enable_SPI_IRQ(); + 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 BLE_STATUS_TIMEOUT; + + return status; +} + +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 BLE_STATUS_TIMEOUT; + + return status; +} + +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 BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + + *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 BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *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 BLE_STATUS_TIMEOUT; + + return status; +} + +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 BLE_STATUS_TIMEOUT; + + return status; +} + +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 BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter) +{ + struct hci_request rq; + le_set_scan_parameters_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.type = type; + scan_cp.interval = interval; + scan_cp.window = window; + scan_cp.own_bdaddr_type = own_bdaddr_type; + scan_cp.filter = filter; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_PARAMETERS; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_PARAMETERS_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup) +{ + struct hci_request rq; + le_set_scan_enable_cp scan_cp; + uint8_t status; + + Osal_MemSet(&scan_cp, 0, sizeof(scan_cp)); + scan_cp.enable = enable?1:0; + scan_cp.filter_dup = filter_dup; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_LE_CTL; + rq.ocf = OCF_LE_SET_SCAN_ENABLE; + rq.cparam = &scan_cp; + rq.clen = LE_SET_SCAN_ENABLE_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq, FALSE) < 0) + return BLE_STATUS_TIMEOUT; + + return status; +} + +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 BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + 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 BLE_STATUS_TIMEOUT; + + return status; +} + +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 BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + + *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 BLE_STATUS_TIMEOUT; + + return status; +} + +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 BLE_STATUS_TIMEOUT; + + if (resp.status) { + return resp.status; + } + 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 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; + 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 BLE_STATUS_TIMEOUT; + } + + if (resp.status) { + return resp.status; + } + + 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 BLE_STATUS_TIMEOUT; + + return resp.status; +} + +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 BLE_STATUS_TIMEOUT; + + return resp.status; +} + +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 BLE_STATUS_TIMEOUT; + } + + if (resp.status) { + return resp.status; + } + + *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 BLE_STATUS_TIMEOUT; + } + + return status; +} + +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 BLE_STATUS_TIMEOUT; + } + + return status; +} + +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 BLE_STATUS_TIMEOUT; + } + + return status; +} + +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 BLE_STATUS_TIMEOUT; + } + + if (resp.status) { + return resp.status; + } + + *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 BLE_STATUS_TIMEOUT; + } + + if (resp.status) { + return resp.status; + } + + *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 BLE_STATUS_TIMEOUT; + } + + if (resp.status) { + return resp.status; + } + + 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 BLE_STATUS_TIMEOUT; + } + + if (resp.status) { + return resp.status; + } + + 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 BLE_STATUS_TIMEOUT; + } + + if (resp.status) { + return resp.status; + } + + 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 BLE_STATUS_TIMEOUT; + } + + return status; +} + +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 BLE_STATUS_TIMEOUT; + } + + return status; +} + +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 BLE_STATUS_TIMEOUT; + } + + if (resp.status) { + return resp.status; + } + + *num_pkts = resp.num_pkts; + + return 0; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/bluenrg-hci/hci/hci_dma_lp.c Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,1194 @@ +/** + ****************************************************************************** + * @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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/bluenrg-hci/utils/gp_timer.c Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * 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 the Institute 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 INSTITUTE 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 INSTITUTE 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. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels <adam@sics.se> + * + */ + +#include "clock.h" +#include "gp_timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function sets a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * @param[in] t A pointer to the timer + * @param[in] interval The interval before the timer expires. + * + */ +void +Timer_Set(struct timer *t, tClockTime interval) +{ + t->interval = interval; + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_restart() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +Timer_Reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +Timer_Restart(struct timer *t) +{ + t->start = Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +Timer_Expired(struct timer *t) +{ + /* Note: Can not return diff >= t->interval so we add 1 to diff and return + t->interval < diff - required to avoid an internal error in mspgcc. */ + tClockTime diff = (Clock_Time() - t->start) + 1; + return t->interval < diff; + +} +/*---------------------------------------------------------------------------*/ +/** + * The time until the timer expires + * + * This function returns the time until the timer expires. + * + * \param t A pointer to the timer + * + * \return The time until the timer expires + * + */ +tClockTime +Timer_Remaining(struct timer *t) +{ + return t->start + t->interval - Clock_Time(); +} +/*---------------------------------------------------------------------------*/ +#ifdef __DMA_LP__ + +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID) +{ + TIMER_Create(eTimerModuleID_BlueNRG_HCI, timerID, eTimerMode_SingleShot, + (pf_TIMER_TimerCallBack_t) timercb); + TIMER_Start(*timerID, expiryTime*1000/TIMERSERVER_TICK_VALUE); + + return (BLE_STATUS_SUCCESS); +} + +/*---------------------------------------------------------------------------*/ +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID) +{ + TIMER_Delete(timerID); + + return (BLE_STATUS_SUCCESS); +} + +#endif /* __DMA_LP__ */ +/*---------------------------------------------------------------------------*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/bluenrg-hci/utils/list.c Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,119 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : list.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Circular Linked List Implementation. +******************************************************************************** +* 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. +*******************************************************************************/ + +/****************************************************************************** + * Include Files +******************************************************************************/ +#include <hal_types.h> +#include "list.h" + +/****************************************************************************** + * Function Definitions +******************************************************************************/ +void list_init_head (tListNode * listHead) +{ + listHead->next = listHead; + listHead->prev = listHead; +} + +uint8_t list_is_empty (tListNode * listHead) +{ + return ((listHead->next == listHead)? TRUE:FALSE); +} + +void list_insert_head (tListNode * listHead, tListNode * node) +{ + node->next = listHead->next; + node->prev = listHead; + listHead->next = node; + (node->next)->prev = node; +} + + +void list_insert_tail (tListNode * listHead, tListNode * node) +{ + node->next = listHead; + node->prev = listHead->prev; + listHead->prev = node; + (node->prev)->next = node; +} + + +void list_remove_node (tListNode * node) +{ + (node->prev)->next = node->next; + (node->next)->prev = node->prev; +} + + +void list_remove_head (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->next; + list_remove_node (listHead->next); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_remove_tail (tListNode * listHead, tListNode ** node ) +{ + *node = listHead->prev; + list_remove_node (listHead->prev); + (*node)->next = NULL; + (*node)->prev = NULL; +} + + +void list_insert_node_after (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node->next; + node->prev = ref_node; + ref_node->next = node; + (node->next)->prev = node; +} + + +void list_insert_node_before (tListNode * node, tListNode * ref_node) +{ + node->next = ref_node; + node->prev = ref_node->prev; + ref_node->prev = node; + (node->prev)->next = node; +} + + +int list_get_size (tListNode * listHead) +{ + int size = 0; + tListNode * temp = listHead->next; + while (temp != listHead) + { + size++; + temp = temp->next; + } + return (size); +} + +void list_get_next_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->next; +} + + +void list_get_prev_node (tListNode * ref_node, tListNode ** node) +{ + *node = ref_node->prev; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/bluenrg-hci/utils/osal.c Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,72 @@ +/** +****************************************************************************** +* @file osal.c +* @author AMS - HEA&RF BU / CL +* @version V1.0.0 +* @date 04-July-2014 +* @brief Implementation of OS abstraction layer functions used by the +* library. +****************************************************************************** +* @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> +#include <osal.h> + + /** + * @brief Osal_MemCpy + * @param dest: Pointer to the destination buffer + * @param src : Pointer to the source buffer + * @param size: Number of bytes to copy from the source to the destination + * buffer + * @retval Pointer to the destination buffer + */ +void* Osal_MemCpy(void *dest, const void *src, unsigned int size) +{ + return(memcpy(dest,src,size)); +} + +/** + * @brief Osal_MemSet + * @param ptr : Pointer to block of memory to fill + * @param value: Value to assign to each byte of the memory block + * @param size : Number of bytes to be set to "value" + * @retval Pointer to the filled block of memory + */ +void* Osal_MemSet(void *ptr, int value, unsigned int size) +{ + return(memset(ptr,value,size)); +} + +/****************************************************************************** + * local Functions + *****************************************************************************/ + + /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- a/source/platform/X-NUCLEO-IDB04A1/stm32_bluenrg_ble.cpp Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,205 +0,0 @@ -/** - ****************************************************************************** - * @file stm32_bluenrg_ble.cpp - * @author CL - * @version V1.0.0 - * @date 15-June-2015 - * @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. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "BlueNRGGap.h" -#include "BlueNRGDevice.h" -#include "Utils.h" - -// FIXME: find a better way to get the instance of the BlueNRG device -extern BlueNRGDevice bluenrgDeviceInstance; - - -//////////////////////////////////////// -// Start of C function wrappers -#ifdef __cplusplus -extern "C" { -#endif - -#include "stm32_bluenrg_ble.h" -#include "gp_timer.h" -#include "debug.h" - - -void BlueNRG_RST(void) -{ - bluenrgDeviceInstance.reset(); -} - -uint8_t BlueNRG_DataPresent(void) -{ - return (bluenrgDeviceInstance.dataPresent()); -} - - -/** - * @brief This function is a utility to print the log time -* in the format HH:MM:SS:MSS (DK GUI time format) - * @param None - * @retval None - */ -void print_csv_time(void){ -#ifdef PRINT_CSV_FORMAT - uint32_t ms = 0;//ms_counter; - PRINT_CSV("%02d:%02d:%02d.%03d", ms/(60*60*1000)%24, ms/(60*1000)%60, (ms/1000)%60, ms%1000); -#endif -} - -/** - * @brief Writes data to a serial interface. - * @param data1 : 1st buffer - * @param data2 : 2nd buffer - * @param n_bytes1: number of bytes in 1st buffer - * @param n_bytes2: number of bytes in 2nd buffer - * @retval None - */ -void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, - int32_t n_bytes2) -{ - struct timer t; - - Timer_Set(&t, CLOCK_SECOND/10); - -#ifdef PRINT_CSV_FORMAT - print_csv_time(); - for (int i=0; i<n_bytes1; i++) { - PRINT_CSV(" %02x", ((uint8_t *)data1)[i]); - } - for (int i=0; i<n_bytes2; i++) { - PRINT_CSV(" %02x", ((uint8_t *)data2)[i]); - } - PRINT_CSV("\n"); -#endif - - while(1){ - if(BlueNRG_SPI_Write((uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break; - if(Timer_Expired(&t)){ - break; - } - } -} - - -/** - * @brief Activate internal bootloader using pin. - * @param None - * @retval None - */ -void BlueNRG_HW_Bootloader(void) -{ - // FIXME: this is not implemented yet - while (1); -} - -/** - * @brief Reads from BlueNRG SPI buffer and store data into local buffer. - * @param buffer : Buffer where data from SPI are stored - * @param buff_size: Buffer size - * @retval int32_t : Number of read bytes - */ -int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, - uint8_t buff_size) -{ - int32_t ret = bluenrgDeviceInstance.spiRead(buffer, buff_size); - - return ret; -} - -/** - * @brief Writes data from local buffer to SPI. - * @param data1 : First data buffer to be written - * @param data2 : Second data buffer to be written - * @param Nb_bytes1: Size of first data buffer to be written - * @param Nb_bytes2: Size of second data buffer to be written - * @retval Number of read bytes - */ -int32_t BlueNRG_SPI_Write(uint8_t* data1, - uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) -{ - int32_t ret = bluenrgDeviceInstance.spiWrite(data1, data2, Nb_bytes1, Nb_bytes2); - - return ret; -} - -/** - * @brief Enable SPI IRQ. - * @param None - * @retval None - */ -void Enable_SPI_IRQ(void) -{ - bluenrgDeviceInstance.enable_irq(); -} - -/** - * @brief Disable SPI IRQ. - * @param None - * @retval None - */ -void Disable_SPI_IRQ(void) -{ - bluenrgDeviceInstance.disable_irq(); -} - -/** - * @brief Clear Pending SPI IRQ. - * @param None - * @retval None - */ -void Clear_SPI_IRQ(void) -{ -} - -/** - * @brief Clear EXTI (External Interrupt) line for SPI IRQ. - * @param None - * @retval None - */ -void Clear_SPI_EXTI_Flag(void) -{ -} - - - - -#ifdef __cplusplus -} -#endif -// End of C function wrappers -//////////////////////////////////////// - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- a/source/platform/X-NUCLEO-IDB04A1/stm32_bluenrg_ble_dma_lp.c Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,989 +0,0 @@ -/** - ****************************************************************************** - * @file stm32_bluenrg_ble_dma_lp.c - * @author CL - * @version V1.0.0 - * @date 04-July-2014 - * @brief - ****************************************************************************** - * @attention - * - * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** - */ - -// ANDREA -- FIXME: to exclude from building when DMA is disabled -#ifdef __DMA_LP__ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32_bluenrg_ble_dma_lp.h" -#include "hci_const.h" - -/** @addtogroup BSP - * @{ - */ - -/** @addtogroup X-NUCLEO-IDB04A1 - * @{ - */ - -/** @defgroup STM32_BLUENRG_BLE_DMA_LP - * @{ - */ - -/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Defines - * @{ - */ - -#define TEST_TX_BUFFER_LIMITATION 0 -#define MAX_TX_BUFFER_SIZE 0x7F -#define BLUENRG_READY_STATE 0x02 - -#define HEADER_SIZE 5 -#define MAX_BUFFER_SIZE 255 - -/** - * @} - */ - -/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Types -* @{ -*/ - -typedef enum -{ - SPI_HEADER_TRANSMIT, - SPI_PAYLOAD_TRANSMIT -} SPI_TRANSMIT_REQUEST_t; - -typedef enum -{ - SPI_HEADER_TRANSMITTED, - SPI_PAYLOAD_TRANSMITTED -} SPI_TRANSMIT_EVENT_t; - -typedef enum -{ - SPI_REQUEST_VALID_HEADER_FOR_RX, - SPI_REQUEST_VALID_HEADER_FOR_TX, - SPI_REQUEST_PAYLOAD -} SPI_RECEIVE_REQUEST_t; - -typedef enum -{ - SPI_CHECK_RECEIVED_HEADER_FOR_RX, - SPI_CHECK_RECEIVED_HEADER_FOR_TX, - SPI_RECEIVE_END -} SPI_RECEIVE_EVENT_t; - -typedef enum -{ - SPI_AVAILABLE, - SPI_BUSY -} SPI_PERIPHERAL_STATUS_t; - -typedef struct -{ - SPI_TRANSMIT_EVENT_t Spi_Transmit_Event; - uint8_t* header_data; - uint8_t* payload_data; - uint8_t header_size; - uint8_t payload_size; - uint8_t payload_size_to_transmit; - uint8_t packet_cont; - uint8_t RequestPending; -} SPI_Transmit_Context_t; - -typedef struct -{ - SPI_RECEIVE_EVENT_t Spi_Receive_Event; - uint16_t payload_len; - uint8_t* buffer; - uint8_t buffer_size; -} SPI_Receive_Context_t; - -typedef struct -{ - SPI_HandleTypeDef *hspi; - SPI_PERIPHERAL_STATUS_t Spi_Peripheral_State; - SPI_Receive_Context_t SPI_Receive_Context; - SPI_Transmit_Context_t SPI_Transmit_Context; -} SPI_Context_t; - -/** - * @} - */ - -/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Variables - * @{ - */ - -SPI_HandleTypeDef SpiHandle; -SPI_Context_t SPI_Context; - -const uint8_t Write_Header_CMD[HEADER_SIZE] = {0x0a, 0x00, 0x00, 0x00, 0x00}; -const uint8_t Read_Header_CMD[HEADER_SIZE] = {0x0b, 0x00, 0x00, 0x00, 0x00}; -const uint8_t dummy_bytes = 0xFF; - -uint8_t Received_Header[HEADER_SIZE]; - -#ifdef ENABLE_SPI_FIX -static uint8_t StartupTimerId; -#endif -static uint8_t TxRxTimerId; -volatile uint8_t ubnRFresetTimerLock; -pf_TIMER_TimerCallBack_t pTimerTxRxCallback; - -/** - * @} - */ - -/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Extern_Variables - * @{ - */ -extern uint8_t* HCI_read_packet; - -/** - * @} - */ - -/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Private_Function_Prototypes - * @{ - */ - -/* Private function prototypes -----------------------------------------------*/ -static void SPI_Transmit_Manager(SPI_TRANSMIT_REQUEST_t TransmitRequest); -static void SPI_Receive_Manager(SPI_RECEIVE_REQUEST_t ReceiveRequest); -static void set_irq_as_output(void); -static void set_irq_as_input(void); -static void Disable_SPI_Receiving_Path(void); -static void Enable_SPI_Receiving_Path(void); -static void Enable_SPI_CS(void); -static void Disable_SPI_CS(void); -static void DisableEnable_SPI_CS(void); -static void TransmitClosure(void); -static void ReceiveClosure(void); -static void ReceiveHeader(SPI_RECEIVE_EVENT_t ReceiveEvent, uint8_t * DataHeader); -static void WakeupBlueNRG(void); -static void TimerStartupCallback(void); -static void TimerTransmitCallback(void); -static void pf_nRFResetTimerCallBack(void); -static void TimerTxRxCallback(void); -static void ProcessEndOfReceive(void); - -/** - * @} - */ - -/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Exported_Functions - * @{ - */ - -/** - * @brief This function notify when then BlueNRG nRESET may be released - * @param None - * @retval None - */ -static void pf_nRFResetTimerCallBack(void) -{ - ubnRFresetTimerLock = 0; - - return; -} - -/** - * @brief Timer callback to handle RxTx Timers - * @param None - * @retval None - */ -static void TimerTxRxCallback(void) -{ - pTimerTxRxCallback(); - - return; -} - -/** - * @brief Close the receiver path - * @param None - * @retval None - */ -static void ReceiveClosure(void) -{ - /* - * Disable both DMA - */ - __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx); - __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx); - - /* - * Check if a command is pending - */ - __disable_irq(); - if(SPI_Context.SPI_Transmit_Context.RequestPending == TRUE) - { - SPI_Context.SPI_Transmit_Context.RequestPending = FALSE; - SPI_Context.Spi_Peripheral_State = SPI_BUSY; - Disable_SPI_Receiving_Path(); - __enable_irq(); - WakeupBlueNRG(); - } - else - { - SPI_Context.Spi_Peripheral_State = SPI_AVAILABLE; - __enable_irq(); - } - - return; -} - -/** - * @brief Delay Notification to the App to prevent dummy event read - * @param None - * @retval None - */ -static void ProcessEndOfReceive(void) -{ - ReceiveClosure(); - - HCI_Isr(HCI_read_packet, SPI_Context.SPI_Receive_Context.payload_len); - - return; -} - -/** - * @brief Timer callback to apply timeout SPI FIX - * @param None - * @retval None - */ -static void TimerTransmitCallback(void) -{ - SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_TX); /**< BlueNRG not ready for writing */ - LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_Sleep); - - return; -} - -/** - * @brief Closes the SPI when BLE is disabled by the application - * Releases allocated resources - * @param None - * @retval None - */ -void BNRG_SPI_Close(void) -{ -#ifdef ENABLE_SPI_FIX - TIMER_Delete(StartupTimerId); -#endif - TIMER_Delete(TxRxTimerId); - - return; -} - -/** - * @brief Initializes the SPI communication with the BlueNRG Shield. - * @param None - * @retval None - */ -void BNRG_SPI_Init(void) -{ - BNRG_MSP_SPI_Init(&SpiHandle); - - SPI_Context.hspi = &SpiHandle; - - SPI_Context.Spi_Peripheral_State = SPI_AVAILABLE; - SPI_Context.SPI_Transmit_Context.RequestPending = FALSE; - - __HAL_BLUENRG_SPI_ENABLE_DMAREQ(&SpiHandle, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN); - - __HAL_SPI_ENABLE(&SpiHandle); - -#ifdef ENABLE_SPI_FIX - TIMER_Create(eTimerModuleID_Interrupt, &StartupTimerId, eTimerMode_SingleShot, TimerStartupCallback); -#endif - TIMER_Create(eTimerModuleID_Interrupt, &TxRxTimerId, eTimerMode_SingleShot, TimerTxRxCallback); - return; -} - -/** - * @brief Initializes the SPI communication with the BlueNRG Shield - * @param None - * @retval None - */ -void BNRG_MSP_SPI_Init(SPI_HandleTypeDef * hspi) -{ - hspi->Instance = BNRG_SPI_INSTANCE; - hspi->Init.Mode = BNRG_SPI_MODE; - hspi->Init.Direction = BNRG_SPI_DIRECTION; - hspi->Init.DataSize = BNRG_SPI_DATASIZE; - hspi->Init.CLKPolarity = BNRG_SPI_CLKPOLARITY; - hspi->Init.CLKPhase = BNRG_SPI_CLKPHASE; - hspi->Init.NSS = BNRG_SPI_NSS; - hspi->Init.FirstBit = BNRG_SPI_FIRSTBIT; - hspi->Init.TIMode = BNRG_SPI_TIMODE; - hspi->Init.CRCPolynomial = BNRG_SPI_CRCPOLYNOMIAL; - hspi->Init.BaudRatePrescaler = BNRG_SPI_BAUDRATEPRESCALER; - hspi->Init.CRCCalculation = BNRG_SPI_CRCCALCULATION; - - HAL_SPI_Init(hspi); - - return; -} - -/** - * @brief Resets the BlueNRG. - * @param None - * @retval None - */ -void BlueNRG_RST(void) -{ - uint8_t ubnRFResetTimerID; - - GPIO_InitTypeDef GPIO_InitStruct; - - GPIO_InitStruct.Pin = BNRG_SPI_RESET_PIN; - GPIO_InitStruct.Speed = BNRG_SPI_RESET_SPEED; - TIMER_Create(eTimerModuleID_Interrupt, &ubnRFResetTimerID, eTimerMode_SingleShot, pf_nRFResetTimerCallBack); - - BNRG_SPI_RESET_CLK_ENABLE(); - - HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_RESET); - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct); - - TIMER_Start(ubnRFResetTimerID, BLUENRG_HOLD_TIME_IN_RESET); - ubnRFresetTimerLock = 1; - while(ubnRFresetTimerLock == 1); - - HAL_GPIO_WritePin(BNRG_SPI_RESET_PORT, BNRG_SPI_RESET_PIN, GPIO_PIN_SET); - -#if 1 - /* - * Limitation in HAL V1.1.0 - * The HAL_GPIO_Init() is first configuring the Mode of the IO before the Pull UP configuration - * To avoid glitch on the IO, the configuration shall go through an extra step OUTPUT/PULLUP - * to set upfront the PULL UP configuration. - */ - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_PULLUP; - HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct); -#endif - - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Pull = GPIO_PULLUP; - HAL_GPIO_Init(BNRG_SPI_RESET_PORT, &GPIO_InitStruct); - - TIMER_Start(ubnRFResetTimerID, BLUENRG_HOLD_TIME_AFTER_RESET); - ubnRFresetTimerLock = 1; - while(ubnRFresetTimerLock == 1); - TIMER_Delete(ubnRFResetTimerID); - - return; -} - -/** - * @brief Writes data from local buffer to SPI. - * @param hspi: SPI handle - * @param header_data: First data buffer to be written - * @param payload_data: Second data buffer to be written - * @param header_size: Size of first data buffer to be written - * @param payload_size: Size of second data buffer to be written - * @retval Number of read bytes - */ -void BlueNRG_SPI_Write(uint8_t* header_data, uint8_t* payload_data, uint8_t header_size, uint8_t payload_size) -{ - SPI_Context.SPI_Transmit_Context.header_data = header_data; - SPI_Context.SPI_Transmit_Context.payload_data = payload_data; - SPI_Context.SPI_Transmit_Context.header_size = header_size; - SPI_Context.SPI_Transmit_Context.payload_size = payload_size; - - SPI_Context.SPI_Transmit_Context.packet_cont = FALSE; - - __disable_irq(); - if(SPI_Context.Spi_Peripheral_State == SPI_AVAILABLE) - { - SPI_Context.Spi_Peripheral_State = SPI_BUSY; - Disable_SPI_Receiving_Path(); - __enable_irq(); - WakeupBlueNRG(); - } - else - { - SPI_Context.SPI_Transmit_Context.RequestPending = TRUE; - __enable_irq(); - } - - return; -} - -/** - * @brief Set in Output mode the IRQ. - * @param None - * @retval None - */ -static void set_irq_as_output(void) -{ - HAL_GPIO_WritePin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN, GPIO_PIN_SET); - HAL_LPPUART_GPIO_Set_Mode(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN_POSITION, GPIO_MODE_OUTPUT_PP); - __HAL_GPIO_EXTI_CLEAR_IT(BNRG_SPI_IRQ_PIN); -} - -/** - * @brief Set the IRQ in input mode. - * @param None - * @retval None - */ -static void set_irq_as_input(void) -{ - HAL_GPIO_WritePin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN, GPIO_PIN_RESET); // WARNING: it may conflict with BlueNRG driving High - HAL_LPPUART_GPIO_Set_Mode(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN_POSITION, GPIO_MODE_INPUT); -} - -/** - * @brief Enable SPI IRQ. - * @param None - * @retval None - */ -static void Enable_SPI_Receiving_Path(void) -{ - __HAL_GPIO_EXTI_CLEAR_IT(BNRG_SPI_EXTI_PIN); - HAL_NVIC_ClearPendingIRQ(BNRG_SPI_EXTI_IRQn); - HAL_NVIC_EnableIRQ(BNRG_SPI_EXTI_IRQn); - - if (HAL_GPIO_ReadPin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN) == GPIO_PIN_SET) - { - __HAL_GPIO_EXTI_GENERATE_SWIT(BNRG_SPI_IRQ_PIN); - } -} - -/** - * @brief Disable SPI IRQ. - * @param None - * @retval None - */ -static void Disable_SPI_Receiving_Path(void) -{ - HAL_NVIC_DisableIRQ(BNRG_SPI_EXTI_IRQn); -} - -/** - * @brief Enable SPI CS. - * @param None - * @retval None - */ -static void Enable_SPI_CS(void) -{ - /* CS reset */ - HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET); -} - -/** - * @brief Disable SPI CS. - * @param None - * @retval None - */ -static void Disable_SPI_CS(void) -{ - while (__HAL_SPI_GET_FLAG(SPI_Context.hspi,SPI_FLAG_BSY) == SET); - - /* CS set */ - HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); -} - -/** - * @brief Disable and Enable SPI CS. - * @param None - * @retval None - */ -static void DisableEnable_SPI_CS(void) -{ - while (__HAL_SPI_GET_FLAG(SPI_Context.hspi,SPI_FLAG_BSY) == SET); - - /* CS set */ - HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_SET); - - /* CS reset */ - HAL_GPIO_WritePin(BNRG_SPI_CS_PORT, BNRG_SPI_CS_PIN, GPIO_PIN_RESET); -} - -/** - * @brief Tx and Rx Transfer completed callbacks - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -void BlueNRG_DMA_RxCallback(void) -{ - uint16_t byte_count; - uint8_t ready_state; - - __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmarx, BNRG_SPI_RX_DMA_TC_FLAG); - - /** - * The TCIF shall be cleared to be able to start a new DMA transmission later on when required. - * When receiving data, the TCIE is not set as there is no need to handle the interrupt - * handler of the DMA_Tx. - * The TCIF clearing is mandatory on STM32F4 but not on STM32L0. - * In order to keep code identical across platform, the TCIF clearing may be kept as well on - * the STM32L0 and all other MCUs. - */ - __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmatx, BNRG_SPI_TX_DMA_TC_FLAG); - switch (SPI_Context.SPI_Receive_Context.Spi_Receive_Event) - { - case SPI_CHECK_RECEIVED_HEADER_FOR_RX: - byte_count = (Received_Header[4]<<8)|Received_Header[3]; - ready_state = Received_Header[0]; - - if ((byte_count == 0) || (ready_state != BLUENRG_READY_STATE)) - { - if (HAL_GPIO_ReadPin(BNRG_SPI_IRQ_PORT, BNRG_SPI_IRQ_PIN) == GPIO_PIN_RESET) - { - /** - * This USE CASE shall never happen as this may break the IRQ/CS specification - * The IRQ line shall never be low when CS is low to avoid BlueNRG race condition when - * entering low power mode - * the SPI_END_RECEIVE_FIX has been implemented to make sure this USE CASE never occurs - * However, even when the behavior is not compliant to the specification, the BlueNRG - * may not fail so it is increasing robustness by adding this checking just in case the - * timeout define in the workaround is too short which will end up to marginally brake - * the specification. - * This checking will poping BluenRG for a dummy even - */ - - /* Release CS line */ - Disable_SPI_CS(); - - LPM_Mode_Request(eLPM_SPI_RX, eLPM_Mode_LP_Stop); - - ReceiveClosure(); - } - else - { - DisableEnable_SPI_CS(); - SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_RX); /**< BlueNRG not ready for reading */ - } - } - else - { - SPI_Receive_Manager(SPI_REQUEST_PAYLOAD); /**< BlueNRG is ready for reading */ - } - break; - - case SPI_RECEIVE_END: - /* Release CS line */ - Disable_SPI_CS(); - - LPM_Mode_Request(eLPM_SPI_RX, eLPM_Mode_LP_Stop); - -#if (SPI_END_RECEIVE_FIX == 1) - pTimerTxRxCallback = ProcessEndOfReceive; - TIMER_Start(TxRxTimerId, SPI_END_RECEIVE_FIX_TIMEOUT); -#else - ProcessEndOfReceive(); -#endif - break; - - case SPI_CHECK_RECEIVED_HEADER_FOR_TX: - byte_count = (Received_Header[2]<<8)|Received_Header[1]; - ready_state = Received_Header[0]; - - if ((byte_count == 0) || (ready_state != BLUENRG_READY_STATE)) - { - DisableEnable_SPI_CS(); - SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_TX); /**< BlueNRG not ready for writing */ - } - else - { -#if (TEST_TX_BUFFER_LIMITATION == 1) - if(byte_count > MAX_TX_BUFFER_SIZE) - { - byte_count = MAX_TX_BUFFER_SIZE; - } -#endif - - if(SPI_Context.SPI_Transmit_Context.packet_cont != TRUE) - { - if( byte_count < (SPI_Context.SPI_Transmit_Context.header_size + SPI_Context.SPI_Transmit_Context.payload_size)) - { - SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = byte_count - SPI_Context.SPI_Transmit_Context.header_size; - SPI_Context.SPI_Transmit_Context.payload_size -= SPI_Context.SPI_Transmit_Context.payload_size_to_transmit; - SPI_Context.SPI_Transmit_Context.packet_cont = TRUE; - } - else - { - SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = SPI_Context.SPI_Transmit_Context.payload_size; - } - - SPI_Transmit_Manager(SPI_HEADER_TRANSMIT); - } - else - { - if( byte_count < SPI_Context.SPI_Transmit_Context.payload_size) - { - SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = byte_count; - SPI_Context.SPI_Transmit_Context.payload_size -= SPI_Context.SPI_Transmit_Context.payload_size_to_transmit; - } - else - { - SPI_Context.SPI_Transmit_Context.payload_size_to_transmit = SPI_Context.SPI_Transmit_Context.payload_size; - SPI_Context.SPI_Transmit_Context.payload_size = 0; - } - - SPI_Transmit_Manager(SPI_PAYLOAD_TRANSMIT); - } - } - - break; - - default: - break; - } -} - -#ifdef ENABLE_SPI_FIX -/** - * @brief Wakeup BlueNRG - * @param None - * @retval None - */ -static void WakeupBlueNRG(void) -{ - Disable_SPI_Receiving_Path(); - pTimerTxRxCallback = TimerTransmitCallback; - set_irq_as_output(); - TIMER_Start(StartupTimerId, SPI_FIX_TIMEOUT); - TIMER_Start(TxRxTimerId, SPI_FIX_TIMEOUT+SPI_TX_TIMEOUT); - LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_LP_Stop); - - return; -} - -/** - * @brief Timer callback to apply timeout SPI FIX - * @param None - * @retval None - */ -static void TimerStartupCallback(void) -{ - Enable_SPI_CS(); - - return; -} - -#else -/** - * @brief Wakeup BlueNRG - * @param None - * @retval None - */ -static void WakeupBlueNRG(void) -{ - Disable_SPI_Receiving_Path(); - pTimerTxRxCallback = TimerTransmitCallback; - Enable_SPI_CS(); - TIMER_Start(TxRxTimerId, SPI_TX_TIMEOUT); - LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_LP_Stop); - - return; -} -#endif /* ENABLE_SPI_FIX */ - -/** - * @brief Tx and Rx Transfer completed callbacks - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -void BlueNRG_DMA_TxCallback(void) -{ - __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmatx, BNRG_SPI_TX_DMA_TC_FLAG); - - switch (SPI_Context.SPI_Transmit_Context.Spi_Transmit_Event) - { - case SPI_HEADER_TRANSMITTED: - if(SPI_Context.SPI_Transmit_Context.payload_size_to_transmit != 0) - { - SPI_Transmit_Manager(SPI_PAYLOAD_TRANSMIT); - } - else - { - TransmitClosure(); - } - break; - - case SPI_PAYLOAD_TRANSMITTED: - if( (SPI_Context.SPI_Transmit_Context.packet_cont == TRUE) && (SPI_Context.SPI_Transmit_Context.payload_size != 0)) - { - SPI_Context.SPI_Transmit_Context.payload_data += SPI_Context.SPI_Transmit_Context.payload_size_to_transmit; - DisableEnable_SPI_CS(); - SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_TX); - } - else - { - TransmitClosure(); - } - break; - - default: - break; - } - - return; -} - -/** - * @brief Close the transmit mechanism after packet has been sent - * Wait for the event to come back - * @param None - * @retval None - */ -static void TransmitClosure(void) -{ - LPM_Mode_Request(eLPM_SPI_TX, eLPM_Mode_LP_Stop); - SPI_Context.Spi_Peripheral_State = SPI_AVAILABLE; - Disable_SPI_CS(); - /* - * Disable both DMA - */ - __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx); - __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx); - Enable_SPI_Receiving_Path(); - - return; -} - -/** - * @brief Manage the SPI transmit - * @param TransmitRequest: the transmit request - * @retval None - */ -static void SPI_Transmit_Manager(SPI_TRANSMIT_REQUEST_t TransmitRequest) -{ - /* - * Disable both DMA - */ - __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx); - __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx); - - __HAL_DMA_DISABLE_IT(SPI_Context.hspi->hdmarx, DMA_IT_TC); /**< Disable Receive packet notification */ - - __HAL_DMA_CLEAR_FLAG(SPI_Context.hspi->hdmatx, BNRG_SPI_TX_DMA_TC_FLAG); /**< Clear flag in DMA */ - HAL_NVIC_ClearPendingIRQ(BNRG_SPI_DMA_TX_IRQn); /**< Clear DMA pending bit in NVIC */ - __HAL_DMA_ENABLE_IT(SPI_Context.hspi->hdmatx, DMA_IT_TC); /**< Enable Transmit packet notification */ - - __HAL_BLUENRG_DMA_SET_MINC(SPI_Context.hspi->hdmatx); /**< Configure DMA to send Tx packet */ - - switch (TransmitRequest) - { - case SPI_HEADER_TRANSMIT: - SPI_Context.SPI_Transmit_Context.Spi_Transmit_Event = SPI_HEADER_TRANSMITTED; - -#ifdef ENABLE_SPI_FIX - set_irq_as_input(); -#endif - - __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, SPI_Context.SPI_Transmit_Context.header_size); /**< Set counter in DMA TX */ - __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)SPI_Context.SPI_Transmit_Context.header_data); /**< Set memory address in DMA TX */ - break; - - case SPI_PAYLOAD_TRANSMIT: - SPI_Context.SPI_Transmit_Context.Spi_Transmit_Event = SPI_PAYLOAD_TRANSMITTED; - - __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, SPI_Context.SPI_Transmit_Context.payload_size_to_transmit); /**< Set counter in DMA TX */ - __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)SPI_Context.SPI_Transmit_Context.payload_data); /**< Set memory address in DMA TX */ - break; - - default: - break; - } - - __HAL_DMA_ENABLE(SPI_Context.hspi->hdmatx); /**< Enable DMA TX */ - -} - -/** - * @brief Manage the SPI receive - * @param ReceiveRequest: the receive request - * @retval None - */ -static void SPI_Receive_Manager(SPI_RECEIVE_REQUEST_t ReceiveRequest) -{ - uint16_t byte_count; - uint8_t localloop; - - /* - * Disable both DMA - */ - __HAL_DMA_DISABLE(SPI_Context.hspi->hdmatx); - __HAL_DMA_DISABLE(SPI_Context.hspi->hdmarx); - - /** - * Flush the Rx register or FIFO - */ - for (localloop = 0 ; localloop < SPI_FIFO_RX_DEPTH ; localloop++) - { - *(volatile uint8_t*)__HAL_BLUENRG_SPI_GET_RX_DATA_REGISTER_ADDRESS(SPI_Context.hspi); - } - - __HAL_DMA_ENABLE_IT(SPI_Context.hspi->hdmarx, DMA_IT_TC); /**< Enable Receive packet notification */ - __HAL_DMA_DISABLE_IT(SPI_Context.hspi->hdmatx, DMA_IT_TC); /**< Disable Transmit packet notification */ - - switch (ReceiveRequest) - { - case SPI_REQUEST_VALID_HEADER_FOR_RX: - ReceiveHeader(SPI_CHECK_RECEIVED_HEADER_FOR_RX, (uint8_t *)Read_Header_CMD); - break; - - case SPI_REQUEST_VALID_HEADER_FOR_TX: - ReceiveHeader(SPI_CHECK_RECEIVED_HEADER_FOR_TX, (uint8_t *)Write_Header_CMD); - break; - - case SPI_REQUEST_PAYLOAD: - SPI_Context.SPI_Receive_Context.Spi_Receive_Event = SPI_RECEIVE_END; - - /* - * Check data to received is not available buffer size - */ - byte_count = (Received_Header[4]<<8)|Received_Header[3]; - if (byte_count > SPI_Context.SPI_Receive_Context.buffer_size) - { - byte_count = SPI_Context.SPI_Receive_Context.buffer_size; - } - SPI_Context.SPI_Receive_Context.payload_len = byte_count; - - __HAL_BLUENRG_DMA_CLEAR_MINC(SPI_Context.hspi->hdmatx); /**< Configure DMA to send same Byte */ - - /* - * Set counter in both DMA - */ - __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmarx, byte_count); - __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, byte_count); - - /* - * Set memory address in both DMA - */ - __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmarx, (uint32_t)SPI_Context.SPI_Receive_Context.buffer); - __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)&dummy_bytes); - break; - - default: - break; - } - - /* - * Enable both DMA - Rx First - */ - __HAL_DMA_ENABLE(SPI_Context.hspi->hdmarx); - __HAL_DMA_ENABLE(SPI_Context.hspi->hdmatx); - - return; -} - -/** - * @brief Receive header - * @param hspi: pointer to a SPI_HandleTypeDef structure that contains - * the configuration information for SPI module. - * @retval None - */ -static void ReceiveHeader(SPI_RECEIVE_EVENT_t ReceiveEvent, uint8_t * DataHeader) -{ - SPI_Context.SPI_Receive_Context.Spi_Receive_Event = ReceiveEvent; - - __HAL_BLUENRG_DMA_SET_MINC(SPI_Context.hspi->hdmatx); /**< Configure DMA to send Tx packet */ - - /* - * Set counter in both DMA - */ - __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmatx, HEADER_SIZE); - __HAL_BLUENRG_DMA_SET_COUNTER(SPI_Context.hspi->hdmarx, HEADER_SIZE); - - /* - * Set memory address in both DMA - */ - __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmarx, (uint32_t)Received_Header); - __HAL_BLUENRG_DMA_SET_MEMORY_ADDRESS(SPI_Context.hspi->hdmatx, (uint32_t)DataHeader); - - return; -} - -/** - * @brief BlueNRG SPI request event - * @param buffer: the event - * @param buff_size: the event size - * @retval None - */ -void BlueNRG_SPI_Request_Events(uint8_t *buffer, uint8_t buff_size) -{ - SPI_Context.SPI_Receive_Context.buffer = buffer; - SPI_Context.SPI_Receive_Context.buffer_size = buff_size; - - Enable_SPI_Receiving_Path(); - - return; -} - -/** - * @brief BlueNRG SPI IRQ Callback - * @param None - * @retval None - */ -void BlueNRG_SPI_IRQ_Callback(void) -{ - __disable_irq(); - if(SPI_Context.Spi_Peripheral_State == SPI_AVAILABLE) - { - SPI_Context.Spi_Peripheral_State = SPI_BUSY; - __enable_irq(); - Enable_SPI_CS(); - SPI_Receive_Manager(SPI_REQUEST_VALID_HEADER_FOR_RX); - LPM_Mode_Request(eLPM_SPI_RX, eLPM_Mode_Sleep); - } - else - { - __enable_irq(); - } -} - -#endif /* __DMA_LP__ */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/platform/btle.cpp Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,558 @@ +/* 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 btle.cpp + * @author STMicroelectronics + * @brief Implementation BlueNRG Init and helper functions. + ****************************************************************************** + * @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> + */ + + +#include "btle.h" +#include "ble/Gap.h" +#include "ble/GapEvents.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" +#include "Utils.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" +#include "hci_const.h" +#include "bluenrg_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_gap.h" +#include "bluenrg_utils.h" + +#include "hal_types.h" +#include "hal.h" +#include "gp_timer.h" +#include "osal.h" +#include "sm.h" +#include "debug.h" + +#ifdef __cplusplus +} +#endif + +#define IDB04A1 0 +#define IDB05A1 1 + +#ifdef YOTTA_CFG +static void btle_handler(void); +#endif + +void HCI_Input(tHciDataPacket * hciReadPacket); + +//#define BDADDR_SIZE 6 +//tHalUint8 bdaddr[BDADDR_SIZE]= {0xaa, 0x00, 0x00, 0xE1, 0x80, 0x02}; + +uint16_t g_gap_service_handle = 0; +uint16_t g_appearance_char_handle = 0; +uint16_t g_device_name_char_handle = 0; + +/* Private variables ---------------------------------------------------------*/ +volatile uint8_t set_connectable = 1; +// ANDREA +uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */ + +Gap::Address_t bleAddr; +Gap::AddressType_t addr_type = Gap::ADDR_TYPE_PUBLIC; + +/**************************************************************************/ +/*! + @brief Initialises BTLE and the underlying HW/Device + @param isSetAddress boolean if address has been set + @param mosi MOSI Pin + @param miso MISO Pin + @param sclk clock Pin + @returns void +*/ +/**************************************************************************/ +void btle_init(bool isSetAddress, uint8_t role) +{ + PRINTF("btle_init>>\n\r"); + + int ret; + uint8_t hwVersion; + uint16_t fwVersion; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + /* Delay needed only to be able to acces the JTAG interface after reset + if it will be disabled later. */ + Clock_Wait(500); + + /* Initialize the BlueNRG HCI */ + HCI_Init(); + + /* Reset BlueNRG SPI interface */ + BlueNRG_RST(); + + /* get the BlueNRG HW and FW versions */ + getBlueNRGVersion(&hwVersion, &fwVersion); + + /* + * Reset BlueNRG again otherwise we won't + * be able to change its MAC address. + * aci_hal_write_config_data() must be the first + * command after reset otherwise it will fail. + */ + BlueNRG_RST(); + + if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */ + bnrg_expansion_board = IDB05A1; + } + + /* The Nucleo board must be configured as SERVER */ + //check if isSetAddress is set than set address. + // ANDREA + if(isSetAddress) + { + 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); + } else { + + const Gap::Address_t BLE_address_BE = {0xFD,0x00,0x25,0xAA,0x02,0x04}; + BlueNRGGap::getInstance().setAddress(Gap::ADDR_TYPE_PUBLIC, BLE_address_BE); + + ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET, + CONFIG_DATA_PUBADDR_LEN, + 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); + } else { + ret = aci_gap_init_IDB04A1(role, &service_handle, &dev_name_char_handle, &appearance_char_handle); + } + + if(ret != BLE_STATUS_SUCCESS){ + PRINTF("GAP_Init failed.\n"); + } + + //ANDREA -- FIXME: Security and passkey set by default + ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED, + OOB_AUTH_DATA_ABSENT, + NULL, + 7, + 16, + USE_FIXED_PIN_FOR_PAIRING, + 123456, + BONDING); + if (ret == BLE_STATUS_SUCCESS) { + PRINTF("Auth Req set successfully.\n"); + } + + aci_hal_set_tx_power_level(1,4); + + g_gap_service_handle = service_handle; + g_appearance_char_handle = appearance_char_handle; + g_device_name_char_handle = dev_name_char_handle; + //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API + /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, + strlen(name), (tHalUint8 *)name);*/ + + // Andrea: mbedOS +#ifdef YOTTA_CFG + minar::Scheduler::postCallback(btle_handler); +#endif + return; +} + +/**************************************************************************/ +/*! + @brief Andrea: mbedOS + + @param[in] void + + @returns +*/ +/**************************************************************************/ +#ifdef YOTTA_CFG +static void btle_handler(void) +{ + HCI_Process(); + + // reschedule myself + minar::Scheduler::postCallback(btle_handler); +} +#endif + + +/*! + @brief Not Used + + @param[in] void + + @returns +*/ +void SPI_Poll(void) +{ + //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN); + return; +} + +void Attribute_Modified_CB(uint16_t attr_handle, uint8_t data_length, uint8_t *att_data, uint8_t offset) +{ + //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(); + 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) { + currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE; + } + + if(attr_handle == charHandle+CHAR_DESC_OFFSET) { + currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE; + } + PRINTF("currentHandle %d\n\r", currentHandle); + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) && + currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) { + + 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()); + } else { + //PRINTF("Notify DISABLED\n\r"); + BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, p_char->getValueAttribute().getHandle()); + } + } + + //Check is attr handle property is WRITEABLE, if yes, 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) { + + PRINTF("*****WRITE CASE\n\r"); + + GattWriteCallbackParams writeParams; + 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; + } + BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); + + //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, evt->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().getInitialLength() > 0)) { + BlueNRGGattServer::getInstance().write(p_char->getValueAttribute().getHandle(), (uint8_t*)att_data, data_length, false); + } + } + } + +} + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************************/ + /*! + @brief Handle HCI Stack Event + + @param[in] pckt + Event Packet sent by the stack to be decoded + + @returns + */ + /**************************************************************************/ + extern void HCI_Event_CB(void *pckt) { + hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt; + hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data; + + if(hci_pckt->type != HCI_EVENT_PKT) + return; + + switch(event_pckt->evt){ + + case EVT_DISCONN_COMPLETE: + { + PRINTF("EVT_DISCONN_COMPLETE\n"); + + evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt; + + BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, BlueNRGGap::REMOTE_USER_TERMINATED_CONNECTION); + } + break; + + case EVT_LE_META_EVENT: + { + PRINTF("EVT_LE_META_EVENT\n"); + + 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 = Gap::ADDR_TYPE_PUBLIC; + Gap::Role_t role; + + evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data; + + BlueNRGGap::getInstance().setConnectionHandle(cc->handle); + BlueNRGGap::ConnectionParams_t connectionParams; + BlueNRGGap::getInstance().getPreferredConnectionParams(&connectionParams); + switch (cc->peer_bdaddr_type) { + case PUBLIC_ADDR: + peerAddrType = Gap::ADDR_TYPE_PUBLIC; + break; + case STATIC_RANDOM_ADDR: + peerAddrType = Gap::ADDR_TYPE_RANDOM_STATIC; + break; + case RESOLVABLE_PRIVATE_ADDR: + peerAddrType = Gap::ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE; + break; + case NON_RESOLVABLE_PRIVATE_ADDR: + peerAddrType = Gap::ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE; + break; + } + //PRINTF("EVT_LE_CONN_COMPLETE LL role=%d\n", cc->role); + switch (cc->role) { + case 0: //master + role = Gap::CENTRAL; + break; + case 1: + role = Gap::PERIPHERAL; + 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); + } + break; + + case EVT_LE_ADVERTISING_REPORT: + PRINTF("EVT_LE_ADVERTISING_REPORT\n\r"); + /* FIXME: comment this otherwise it will be obscure and error prone if BlueNRG FW will be updated */ + // This event is generated only by X-NUCLEO-IDB05A1 version but not by X-NUCLEO-IDB04A1 (which generates DEVICE_FOUND EVT) + // Formally the structure related to both events are identical except that for the ADV REPORT + // there is one more field (number of reports) which is not forwarded to upper layer. + // Thus we need to move one byte over (((uint8_t*)evt->data)+1) before persing the ADV REPORT. + le_advertising_info *pr = (le_advertising_info*) (((uint8_t*)evt->data)+1); + PRINTF("EVT_LE_ADVERTISING_REPORT evt_type=%d\n\r", pr->evt_type); + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DEVICE_FOUND, + pr->evt_type, + &pr->bdaddr_type, + pr->bdaddr, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + break; + } + } + break; + + case EVT_VENDOR: + { + evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data; + //PRINTF("EVT_VENDOR %d\n", blue_evt->ecode); + + switch(blue_evt->ecode){ + + case EVT_BLUE_GATT_READ_PERMIT_REQ: + { + 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); + } + break; + + case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED: + { + 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); + } + } + break; + + //Any cases for Data Sent Notifications? + case EVT_BLUE_GATT_NOTIFICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_NOTIFICATION"); + break; + case EVT_BLUE_GATT_INDICATION: + //This is only relevant for Client Side Event + PRINTF("EVT_BLUE_GATT_INDICATION"); + break; + + case EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP\n\r"); + evt_att_read_by_group_resp *pr = (evt_att_read_by_group_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServicesCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_data_length, + pr->attribute_data_list); + } + break; + case EVT_BLUE_ATT_READ_BY_TYPE_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_BY_TYPE_RESP\n\r"); + evt_att_read_by_type_resp *pr = (evt_att_read_by_type_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharsCB(pr->conn_handle, + pr->event_data_length, + pr->handle_value_pair_length, + pr->handle_value_pair); + } + break; + case EVT_BLUE_ATT_READ_RESP: + { + PRINTF("EVT_BLUE_ATT_READ_RESP\n\r"); + evt_att_read_resp *pr = (evt_att_read_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charReadCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_value); + } + break; + case EVT_BLUE_ATT_EXEC_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_EXEC_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWriteExecCB(pr->conn_handle, + pr->event_data_length); + } + break; + case EVT_BLUE_ATT_PREPARE_WRITE_RESP: + { + PRINTF("EVT_BLUE_ATT_PREPARE_WRITE_RESP\n\r"); + evt_att_prepare_write_resp *pr = (evt_att_prepare_write_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().charWritePrepareCB(pr->conn_handle, + pr->event_data_length, + pr->attribute_handle, + pr->offset, + pr->part_attr_value); + } + break; + case EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP: + { + PRINTF("EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP\n\r"); + evt_gatt_disc_read_char_by_uuid_resp *pr = (evt_gatt_disc_read_char_by_uuid_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().serviceCharByUUIDCB(pr->conn_handle, + pr->event_data_length, + pr->attr_handle, + pr->attr_value); + } + break; + case EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP: + { + PRINTF("EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP\n\r"); + evt_att_find_by_type_val_resp *pr = (evt_att_find_by_type_val_resp*)blue_evt->data; + BlueNRGGattClient::getInstance().primaryServiceCB(pr->conn_handle, + pr->event_data_length, + pr->handles_info_list); + } + break; + case EVT_BLUE_GATT_PROCEDURE_COMPLETE: + { + //PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE\n\r"); + evt_gatt_procedure_complete *evt = (evt_gatt_procedure_complete*)blue_evt->data; + PRINTF("EVT_BLUE_GATT_PROCEDURE_COMPLETE error_code=%d\n\r", evt->error_code); + BlueNRGGattClient::getInstance().gattProcedureCompleteCB(evt->conn_handle, evt->error_code); + } + break; + + 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, + &pr->data_length, + &pr->data_RSSI[0], + &pr->data_RSSI[pr->data_length]); + } + break; + + 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); + + switch(pr->procedure_code) { + case GAP_LIMITED_DISCOVERY_PROC: + case GAP_GENERAL_DISCOVERY_PROC: + + BlueNRGGap::getInstance().Discovery_CB(BlueNRGGap::DISCOVERY_COMPLETE, 0, NULL, NULL, NULL, NULL, NULL); + break; + } + } + break; + } + } + break; + } + return ; + } + + +#ifdef __cplusplus +} +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/platform/clock.c Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,34 @@ + +#include "clock.h" +#include "wait_api.h" +#include "rtc_time.h" + +const uint32_t CLOCK_SECOND = 1000; + +/*---------------------------------------------------------------------------*/ + +void Clock_Init(void) +{ + //Not Used +} + +/*---------------------------------------------------------------------------*/ + +tClockTime Clock_Time(void) +{ + return clock(); +} + +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 1 ms. + * + */ +void Clock_Wait(uint32_t i) +{ + wait_ms(i); +} +/*---------------------------------------------------------------------------*/ + + +
--- a/source/platform/src/btle.cpp Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,440 +0,0 @@ -/* 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 btle.cpp - * @author STMicroelectronics - * @brief Implementation BlueNRG Init and helper functions. - ****************************************************************************** - * @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> - */ - - -#include "btle.h" -#include "ble/Gap.h" -#include "ble/GapEvents.h" -#include "BlueNRGGap.h" -#include "BlueNRGGattServer.h" -#include "Utils.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" -#include "hci_const.h" -#include "bluenrg_aci.h" -#include "bluenrg_hal_aci.h" -#include "bluenrg_gap.h" -#include "bluenrg_utils.h" - -#include "hal_types.h" -#include "hal.h" -#include "gp_timer.h" -#include "osal.h" -#include "sm.h" -#include "debug_platform.h" - -#ifdef __cplusplus -} -#endif - -#define IDB04A1 0 -#define IDB05A1 1 - -// static void btle_handler(/*ble_evt_t * p_ble_evt*/); -void HCI_Input(tHciDataPacket * hciReadPacket); - -//#define BDADDR_SIZE 6 -//tHalUint8 bdaddr[BDADDR_SIZE]= {0xaa, 0x00, 0x00, 0xE1, 0x80, 0x02}; - -uint16_t g_gap_service_handle = 0; -uint16_t g_appearance_char_handle = 0; -uint16_t g_device_name_char_handle = 0; - -/* Private variables ---------------------------------------------------------*/ -volatile uint8_t set_connectable = 1; -// ANDREA -uint8_t bnrg_expansion_board = IDB04A1; /* at startup, suppose the X-NUCLEO-IDB04A1 is used */ - -Gap::Address_t bleAddr; -Gap::AddressType_t addr_type = Gap::ADDR_TYPE_PUBLIC; - -/**************************************************************************/ -/*! - @brief Initialises BTLE and the underlying HW/Device - @param isSetAddress boolean if address has been set - @param mosi MOSI Pin - @param miso MISO Pin - @param sclk clock Pin - @returns void -*/ -/**************************************************************************/ -void btle_init(bool isSetAddress) -{ - DEBUG("btle_init>>\n\r"); - - int ret; - uint8_t hwVersion; - uint16_t fwVersion; - uint16_t service_handle, dev_name_char_handle, appearance_char_handle; - - /* Delay needed only to be able to acces the JTAG interface after reset - if it will be disabled later. */ - Clock_Wait(500); - - /* Initialize the BlueNRG HCI */ - HCI_Init(); - - /* Reset BlueNRG SPI interface */ - BlueNRG_RST(); - - /* get the BlueNRG HW and FW versions */ - getBlueNRGVersion(&hwVersion, &fwVersion); - - /* - * Reset BlueNRG again otherwise we won't - * be able to change its MAC address. - * aci_hal_write_config_data() must be the first - * command after reset otherwise it will fail. - */ - BlueNRG_RST(); - - if (hwVersion > 0x30) { /* X-NUCLEO-IDB05A1 expansion board is used */ - bnrg_expansion_board = IDB05A1; - } - - /* The Nucleo board must be configured as SERVER */ - //check if isSetAddress is set than set address. - // ANDREA - if(isSetAddress) - { - 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); - } else { - - const Gap::Address_t BLE_address_BE = {0xFD,0x00,0x25,0xAA,0x02,0x04}; - BlueNRGGap::getInstance().setAddress(Gap::ADDR_TYPE_PUBLIC, BLE_address_BE); - - ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET, - CONFIG_DATA_PUBADDR_LEN, - BLE_address_BE); - } - - ret = aci_gatt_init(); - if(ret){ - PRINTF("GATT_Init failed.\n"); - } - //GAP is always in PERIPHERAL _ROLE as mbed does not support Master role at the moment - if (bnrg_expansion_board == IDB05A1) { - ret = aci_gap_init_IDB05A1(GAP_PERIPHERAL_ROLE_IDB05A1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle); - } else { - ret = aci_gap_init_IDB04A1(GAP_PERIPHERAL_ROLE_IDB04A1, &service_handle, &dev_name_char_handle, &appearance_char_handle); - } - - if(ret != BLE_STATUS_SUCCESS){ - PRINTF("GAP_Init failed.\n"); - } - - //ANDREA -- FIXME: Security and passkey set by default - ret = aci_gap_set_auth_requirement(MITM_PROTECTION_REQUIRED, - OOB_AUTH_DATA_ABSENT, - NULL, - 7, - 16, - USE_FIXED_PIN_FOR_PAIRING, - 123456, - BONDING); - if (ret == BLE_STATUS_SUCCESS) { - DEBUG("Auth Req set successfully.\n"); - } - - aci_hal_set_tx_power_level(1,4); - - g_gap_service_handle = service_handle; - g_appearance_char_handle = appearance_char_handle; - g_device_name_char_handle = dev_name_char_handle; - //Device Name is set from Accumulate Adv Data Payload or through setDeviceName API - /*ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, - strlen(name), (tHalUint8 *)name);*/ - - return; -} - -void User_Process() -{ - if(set_connectable){ - setConnectable(); - set_connectable = FALSE; - } -} - -void setConnectable(void) -{ - tBleStatus ret; - - const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; - - /* disable scan response */ - hci_le_set_scan_resp_data(0,NULL); - - //int t = BlueNRGGap::getInstance()::ADV_IND;// advType; - - ret = aci_gap_set_discoverable(BlueNRGGap::getInstance().ADV_IND, 0, 0, PUBLIC_ADDR, NO_WHITE_LIST_USE, - sizeof(local_name), local_name, 0, NULL, 0, 0); - if (ret != BLE_STATUS_SUCCESS) { - DEBUG("Error while setting discoverable mode (%d)\n", ret); - } - -} - -/**************************************************************************/ -/*! - @brief Not Used - - @param[in] void - - @returns -*/ -/**************************************************************************/ -/* -static void btle_handler() -{ - -} -*/ - -/*! - @brief Not Used - - @param[in] void - - @returns -*/ -void SPI_Poll(void) -{ - //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN); - return; -} - -void Attribute_Modified_CB(uint16_t attr_handle, uint8_t data_length, uint8_t *att_data, uint8_t offset) -{ - //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(); - BlueNRGGattServer::HandleEnum_t currentHandle = BlueNRGGattServer::CHAR_HANDLE; - DEBUG("CharHandle %d, length: %d, Data: %d\n\r", charHandle, data_length, (uint16_t)att_data[0]); - DEBUG("getProperties 0x%x\n\r",p_char->getProperties()); - if(attr_handle == charHandle+CHAR_VALUE_OFFSET) { - currentHandle = BlueNRGGattServer::CHAR_VALUE_HANDLE; - } - - if(attr_handle == charHandle+CHAR_DESC_OFFSET) { - currentHandle = BlueNRGGattServer::CHAR_DESC_HANDLE; - } - DEBUG("currentHandle %d\n\r", currentHandle); - if((p_char->getProperties() & - (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) && - currentHandle == BlueNRGGattServer::CHAR_DESC_HANDLE) { - - DEBUG("*****NOTIFICATION CASE\n\r"); - //Now Check if data written in Enable or Disable - if((uint16_t)att_data[0]==1) { - //DEBUG("Notify ENABLED\n\r"); - BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, p_char->getValueAttribute().getHandle()); - } else { - //DEBUG("Notify DISABLED\n\r"); - BlueNRGGattServer::getInstance().HCIEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, p_char->getValueAttribute().getHandle()); - } - } - - //Check is attr handle property is WRITEABLE, if yes, 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) { - - DEBUG("*****WRITE CASE\n\r"); - - GattWriteCallbackParams writeParams; - 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; - } - BlueNRGGattServer::getInstance().HCIDataWrittenEvent(&writeParams); - - //BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, evt->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().getInitialLength() > 0)) { - BlueNRGGattServer::getInstance().write(p_char->getValueAttribute().getHandle(), (uint8_t*)att_data, data_length, false); - } - } - } - -} - -#ifdef __cplusplus -extern "C" { -#endif - - /**************************************************************************/ - /*! - @brief Handle HCI Stack Event - - @param[in] pckt - Event Packet sent by the stack to be decoded - - @returns - */ - /**************************************************************************/ - extern void HCI_Event_CB(void *pckt) { - hci_uart_pckt *hci_pckt = (hci_uart_pckt*)pckt; - hci_event_pckt *event_pckt = (hci_event_pckt*)hci_pckt->data; - - if(hci_pckt->type != HCI_EVENT_PKT) - return; - - switch(event_pckt->evt){ - - case EVT_DISCONN_COMPLETE: - { - DEBUG("EVT_DISCONN_COMPLETE\n"); - - evt_disconn_complete *evt = (evt_disconn_complete*)event_pckt; - - BlueNRGGap::getInstance().processDisconnectionEvent(evt->handle, BlueNRGGap::REMOTE_USER_TERMINATED_CONNECTION); - } - break; - - case EVT_LE_META_EVENT: - { - DEBUG("EVT_LE_META_EVENT\n"); - - evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data; - - switch(evt->subevent){ - // ANDREA - case EVT_LE_CONN_COMPLETE: - { - Gap::AddressType_t peerAddrType = Gap::ADDR_TYPE_PUBLIC; - DEBUG("EVT_LE_CONN_COMPLETE\n"); - - evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data; - - BlueNRGGap::getInstance().setConnectionHandle(cc->handle); - BlueNRGGap::ConnectionParams_t connectionParams; - BlueNRGGap::getInstance().getPreferredConnectionParams(&connectionParams); - switch (cc->peer_bdaddr_type) { - case PUBLIC_ADDR: - peerAddrType = Gap::ADDR_TYPE_PUBLIC; - break; - case STATIC_RANDOM_ADDR: - peerAddrType = Gap::ADDR_TYPE_RANDOM_STATIC; - break; - case RESOLVABLE_PRIVATE_ADDR: - peerAddrType = Gap::ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE; - break; - case NON_RESOLVABLE_PRIVATE_ADDR: - peerAddrType = Gap::ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE; - break; - } - BlueNRGGap::getInstance().processConnectionEvent(cc->handle, Gap::PERIPHERAL, peerAddrType, cc->peer_bdaddr, addr_type, bleAddr, (const BlueNRGGap::ConnectionParams_t *)&connectionParams); - } - break; - } - } - break; - - case EVT_VENDOR: - { - evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data; - //DEBUG("EVT_VENDOR %d\n", blue_evt->ecode); - - switch(blue_evt->ecode){ - - case EVT_BLUE_GATT_READ_PERMIT_REQ: - { - DEBUG("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); - } - break; - - case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED: - { - DEBUG("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); - } - } - break; - - //Any cases for Data Sent Notifications? - case EVT_BLUE_GATT_NOTIFICATION: - //This is only relevant for Client Side Event - DEBUG("EVT_BLUE_GATT_NOTIFICATION"); - break; - case EVT_BLUE_GATT_INDICATION: - //This is only relevant for Client Side Event - DEBUG("EVT_BLUE_GATT_INDICATION"); - break; - - case EVT_BLUE_GATT_PROCEDURE_COMPLETE: - DEBUG("EVT_BLUE_GATT_PROCEDURE_COMPLETE"); - break; - } - } - break; - } - - return ; - } - - -#ifdef __cplusplus -} -#endif
--- a/source/platform/src/clock.c Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ - -#include "clock.h" -#include "wait_api.h" -#include "rtc_time.h" - -const uint32_t CLOCK_SECOND = 1000; - -/*---------------------------------------------------------------------------*/ - -void Clock_Init(void) -{ - //Not Used -} - -/*---------------------------------------------------------------------------*/ - -tClockTime Clock_Time(void) -{ - return clock(); -} - -/*---------------------------------------------------------------------------*/ -/** - * Wait for a multiple of 1 ms. - * - */ -void Clock_Wait(uint32_t i) -{ - wait_ms(i); -} -/*---------------------------------------------------------------------------*/ - - -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/platform/stm32_bluenrg_ble.cpp Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,205 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.cpp + * @author CL + * @version V1.0.0 + * @date 15-June-2015 + * @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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "BlueNRGGap.h" +#include "BlueNRGDevice.h" +#include "Utils.h" + +// FIXME: find a better way to get the instance of the BlueNRG device +extern BlueNRGDevice bluenrgDeviceInstance; + + +//////////////////////////////////////// +// Start of C function wrappers +#ifdef __cplusplus +extern "C" { +#endif + +#include "stm32_bluenrg_ble.h" +#include "gp_timer.h" +#include "debug.h" + + +void BlueNRG_RST(void) +{ + bluenrgDeviceInstance.reset(); +} + +uint8_t BlueNRG_DataPresent(void) +{ + return (bluenrgDeviceInstance.dataPresent()); +} + + +/** + * @brief This function is a utility to print the log time +* in the format HH:MM:SS:MSS (DK GUI time format) + * @param None + * @retval None + */ +void print_csv_time(void){ +#ifdef PRINT_CSV_FORMAT + uint32_t ms = 0;//ms_counter; + PRINT_CSV("%02d:%02d:%02d.%03d", ms/(60*60*1000)%24, ms/(60*1000)%60, (ms/1000)%60, ms%1000); +#endif +} + +/** + * @brief Writes data to a serial interface. + * @param data1 : 1st buffer + * @param data2 : 2nd buffer + * @param n_bytes1: number of bytes in 1st buffer + * @param n_bytes2: number of bytes in 2nd buffer + * @retval None + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, + int32_t n_bytes2) +{ + struct timer t; + + Timer_Set(&t, CLOCK_SECOND/10); + +#ifdef PRINT_CSV_FORMAT + print_csv_time(); + for (int i=0; i<n_bytes1; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data1)[i]); + } + for (int i=0; i<n_bytes2; i++) { + PRINT_CSV(" %02x", ((uint8_t *)data2)[i]); + } + PRINT_CSV("\n"); +#endif + + while(1){ + if(BlueNRG_SPI_Write((uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break; + if(Timer_Expired(&t)){ + break; + } + } +} + + +/** + * @brief Activate internal bootloader using pin. + * @param None + * @retval None + */ +void BlueNRG_HW_Bootloader(void) +{ + // FIXME: this is not implemented yet + while (1); +} + +/** + * @brief Reads from BlueNRG SPI buffer and store data into local buffer. + * @param buffer : Buffer where data from SPI are stored + * @param buff_size: Buffer size + * @retval int32_t : Number of read bytes + */ +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size) +{ + int32_t ret = bluenrgDeviceInstance.spiRead(buffer, buff_size); + + return ret; +} + +/** + * @brief Writes data from local buffer to SPI. + * @param data1 : First data buffer to be written + * @param data2 : Second data buffer to be written + * @param Nb_bytes1: Size of first data buffer to be written + * @param Nb_bytes2: Size of second data buffer to be written + * @retval Number of read bytes + */ +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, uint8_t Nb_bytes1, uint8_t Nb_bytes2) +{ + int32_t ret = bluenrgDeviceInstance.spiWrite(data1, data2, Nb_bytes1, Nb_bytes2); + + return ret; +} + +/** + * @brief Enable SPI IRQ. + * @param None + * @retval None + */ +void Enable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.enable_irq(); +} + +/** + * @brief Disable SPI IRQ. + * @param None + * @retval None + */ +void Disable_SPI_IRQ(void) +{ + bluenrgDeviceInstance.disable_irq(); +} + +/** + * @brief Clear Pending SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_IRQ(void) +{ +} + +/** + * @brief Clear EXTI (External Interrupt) line for SPI IRQ. + * @param None + * @retval None + */ +void Clear_SPI_EXTI_Flag(void) +{ +} + + + + +#ifdef __cplusplus +} +#endif +// End of C function wrappers +//////////////////////////////////////// + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/platform/stm32_bluenrg_ble_dma_lp.c Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,989 @@ +/** + ****************************************************************************** + * @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****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/utils/Payload.cpp Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,101 @@ +/* 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 <Payload.h> + +Payload::Payload() { + stringLength = 0; + payloadUnitCount = 0; + payload = NULL; +} + +Payload::Payload(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + stringLength = string_ength; + payloadUnitCount = 0; + payload = NULL; + + int index = 0; + while( index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + UnitPayload *obj = new UnitPayload[payloadUnitCount]; + int i=0; + int c=0; + int j,k; + + while(i<payloadUnitCount) + { + obj[i].length=tokenString[c]; + obj[i].id=tokenString[c+1]; + + obj[i].data = new uint8_t[obj[i].length]; + for(j=c+2,k=0;(j<(c+obj[i].length+1))&&(k<obj[i].length-1);j++,k++) + { + obj[i].data[k]=tokenString[j]; + + } + + c=c+obj[i].length+1; + i++; + + } + payload = obj; +} + +uint8_t Payload::getPayloadUnitCount() { + return payloadUnitCount; +} + +uint8_t Payload::getIDAtIndex(int index) { + return payload[index].get_id(); +} + +uint8_t Payload::getLengthAtIndex(int index) { + return payload[index].get_length(); +} + +uint8_t* Payload::getDataAtIndex(int index) { + return payload[index].get_data(); +} + +int8_t Payload::getInt8AtIndex(int index) { + uint8_t* str = payload[index].get_data(); + int8_t value = (int8_t)str[0]; + return value; +} + +uint16_t Payload::getUint16AtIndex(int index) { + uint16_t* str = (uint16_t*)payload[index].get_data(); + uint16_t value = str[0]; + return value; +} + +uint8_t* Payload::getSerializedAdDataAtIndex(int index) { + uint8_t length = payload[index].get_length(); + uint8_t* data = payload[index].get_data(); + uint8_t id = payload[index].get_id(); + uint8_t *serializedAdData = new uint8_t[length]; + + serializedAdData[0] = id; + for(int i=0; i<length-1; i++) { + serializedAdData[i+1] = data[i]; + } + return serializedAdData; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/utils/Utils.cpp Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,125 @@ +/* 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 "Utils.h" + +/**************************************************************************/ +/*! + @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; + EN_HIGH_POWER = 0; + PA_LEVEL = 0; + } + else if(dbm>8.0) { + dbm = 8; + EN_HIGH_POWER = 1; + PA_LEVEL = 7; + } + + // 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; + PA_LEVEL = 0; + } + else if((dbm>-15) && (dbm<=-14.7)) { + // set tx power to -14.7dBM + EN_HIGH_POWER = 0; + PA_LEVEL = 1; + } + else if((dbm>-14.7) && (dbm<=-11.7)) { + // set tx power to -11.7dBM + EN_HIGH_POWER = 1; + PA_LEVEL = 1; + } + else if((dbm>-11.7) && (dbm<=-11.4)) { + // set tx power to -11.4dBM + EN_HIGH_POWER = 0; + PA_LEVEL = 2; + } + else if((dbm>-11.4) && (dbm<=-8.4)) { + // set tx power to -8.4dBM + 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; + } + else if((dbm>-8.1) && (dbm<=-5.1)) { + // set tx power to -5.1dBM + 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; + } + else if((dbm>-4.9) && (dbm<=-2.1)) { + // set tx power to -2.1dBM + EN_HIGH_POWER = 1; + 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 + EN_HIGH_POWER = 0; + PA_LEVEL = 6; + } + else if((dbm>1.7) && (dbm<=4.7)) { + // set tx power to 4.7dBM + EN_HIGH_POWER = 1; + PA_LEVEL = 6; + } + else if((dbm>4.7) && (dbm<=5.0)) { + // set tx power to 5.0dBM + EN_HIGH_POWER = 0; + PA_LEVEL = 7; + } + else if((dbm>5.0) && (dbm<=8)) { + // set tx power to 8.0dBM + EN_HIGH_POWER = 1; + PA_LEVEL = 7; + } + + return dbm; +}
--- a/source/utils/src/Payload.cpp Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -/* 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 <Payload.h> - -Payload::Payload() { - stringLength = 0; - payloadUnitCount = 0; - payload = NULL; -} - -Payload::Payload(const uint8_t *tokenString, uint8_t string_ength) { - // initialize private data members - stringLength = string_ength; - payloadUnitCount = 0; - payload = NULL; - - int index = 0; - while( index!=stringLength) { - int len=tokenString[index]; - index=index+1+len; - payloadUnitCount++; - } - - UnitPayload *obj = new UnitPayload[payloadUnitCount]; - int i=0; - int c=0; - int j,k; - - while(i<payloadUnitCount) - { - obj[i].length=tokenString[c]; - obj[i].id=tokenString[c+1]; - - obj[i].data = new uint8_t[obj[i].length]; - for(j=c+2,k=0;(j<(c+obj[i].length+1))&&(k<obj[i].length-1);j++,k++) - { - obj[i].data[k]=tokenString[j]; - - } - - c=c+obj[i].length+1; - i++; - - } - payload = obj; -} - -uint8_t Payload::getPayloadUnitCount() { - return payloadUnitCount; -} - -uint8_t Payload::getIDAtIndex(int index) { - return payload[index].get_id(); -} - -uint8_t Payload::getLengthAtIndex(int index) { - return payload[index].get_length(); -} - -uint8_t* Payload::getDataAtIndex(int index) { - return payload[index].get_data(); -} - -int8_t Payload::getInt8AtIndex(int index) { - uint8_t* str = payload[index].get_data(); - int8_t value = (int8_t)str[0]; - return value; -} - -uint16_t Payload::getUint16AtIndex(int index) { - uint16_t* str = (uint16_t*)payload[index].get_data(); - uint16_t value = str[0]; - return value; -} - -uint8_t* Payload::getSerializedAdDataAtIndex(int index) { - uint8_t length = payload[index].get_length(); - uint8_t* data = payload[index].get_data(); - uint8_t id = payload[index].get_id(); - uint8_t *serializedAdData = new uint8_t[length]; - - serializedAdData[0] = id; - for(int i=0; i<length-1; i++) { - serializedAdData[i+1] = data[i]; - } - return serializedAdData; -}
--- a/source/utils/src/Utils.cpp Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -/* 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 "Utils.h" - -#if NEED_CONSOLE_OUTPUT -Serial pc(USBTX, USBRX); -#endif /* #if NEED_CONSOLE_OUTPUT */ - -/**************************************************************************/ -/*! - @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; - EN_HIGH_POWER = 0; - PA_LEVEL = 0; - } - else if(dbm>8.0) { - dbm = 8; - EN_HIGH_POWER = 1; - PA_LEVEL = 7; - } - - // 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; - PA_LEVEL = 0; - } - else if((dbm>-15) && (dbm<=-14.7)) { - // set tx power to -14.7dBM - EN_HIGH_POWER = 0; - PA_LEVEL = 1; - } - else if((dbm>-14.7) && (dbm<=-11.7)) { - // set tx power to -11.7dBM - EN_HIGH_POWER = 1; - PA_LEVEL = 1; - } - else if((dbm>-11.7) && (dbm<=-11.4)) { - // set tx power to -11.4dBM - EN_HIGH_POWER = 0; - PA_LEVEL = 2; - } - else if((dbm>-11.4) && (dbm<=-8.4)) { - // set tx power to -8.4dBM - 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; - } - else if((dbm>-8.1) && (dbm<=-5.1)) { - // set tx power to -5.1dBM - 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; - } - else if((dbm>-4.9) && (dbm<=-2.1)) { - // set tx power to -2.1dBM - EN_HIGH_POWER = 1; - 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 - EN_HIGH_POWER = 0; - PA_LEVEL = 6; - } - else if((dbm>1.7) && (dbm<=4.7)) { - // set tx power to 4.7dBM - EN_HIGH_POWER = 1; - PA_LEVEL = 6; - } - else if((dbm>4.7) && (dbm<=5.0)) { - // set tx power to 5.0dBM - EN_HIGH_POWER = 0; - PA_LEVEL = 7; - } - else if((dbm>5.0) && (dbm<=8)) { - // set tx power to 8.0dBM - EN_HIGH_POWER = 1; - PA_LEVEL = 7; - } - - return dbm; -}
--- a/x-nucleo-idb0xa1/BlueNRGDevice.h Tue Oct 06 15:19:19 2015 +0200 +++ b/x-nucleo-idb0xa1/BlueNRGDevice.h Wed Oct 07 08:39:04 2015 +0200 @@ -45,6 +45,7 @@ #include "ble/BLE.h" #include "BlueNRGGap.h" #include "BlueNRGGattServer.h" +#include "BlueNRGGattClient.h" class BlueNRGDevice : public BLEInstanceBase @@ -64,7 +65,7 @@ virtual void waitForEvent(void); virtual GattClient& getGattClient() { - return *gattClient; + return BlueNRGGattClient::getInstance(); } virtual SecurityManager& getSecurityManager() { @@ -93,7 +94,6 @@ //FIXME: TBI (by now just placeholders to let build /*** betzw: placeholders ***/ - GattClient *gattClient; SecurityManager *sm; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/BlueNRGDiscoveredCharacteristic.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,41 @@ +/* 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__ */
--- a/x-nucleo-idb0xa1/BlueNRGGap.h Tue Oct 06 15:19:19 2015 +0200 +++ b/x-nucleo-idb0xa1/BlueNRGGap.h Wed Oct 07 08:39:04 2015 +0200 @@ -40,7 +40,7 @@ #include "btle.h" #include "ble/GapAdvertisingParams.h" #include "ble/GapAdvertisingData.h" -#include <ble/Gap.h> +#include "ble/Gap.h" #define BLE_CONN_HANDLE_INVALID 0x0 #define BDADDR_SIZE 6 @@ -49,6 +49,19 @@ #define BLUENRG_GAP_ADV_INTERVAL_MAX (0) #define BLE_GAP_ADV_NONCON_INTERVAL_MIN (0) +// Scanning and Connection Params used by Central for creating connection +#define LIMITED_DISCOVERY_PROCEDURE 0x01 +#define GENERAL_DISCOVERY_PROCEDURE 0x02 + +#define SCAN_P (0x4000) +#define SCAN_L (0x4000) +#define SUPERV_TIMEOUT (600) +#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 UUID_BUFFER_SIZE 13 //6*2(16-bit UUIDs)+1 #define ADV_DATA_MAX_SIZE 31 @@ -67,12 +80,18 @@ } // <<<ANDREA>>> + /* enum AdvType_t { ADV_IND = GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED,//Gap::ADV_IND, ADV_DIRECT_IND = GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED,//Gap::ADV_DIRECT_IND, ADV_SCAN_IND = GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED,//Gap::ADV_SCAN_IND, ADV_NONCONN_IND = GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED//Gap::ADV_NONCONN_IND }; + */ + enum Reason_t { + DEVICE_FOUND, + DISCOVERY_COMPLETE + }; /* Functions that must be implemented from Gap */ virtual ble_error_t setAddress(addr_type_t type, const Address_t address); @@ -98,12 +117,23 @@ 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); + void Discovery_CB(Reason_t reason, + uint8_t adv_type, + uint8_t *addr_type, + uint8_t *addr, + uint8_t *data_length, + uint8_t *data, + uint8_t *RSSI); + ble_error_t makeConnection(void); void setConnectionHandle(uint16_t con_handle); uint16_t getConnectionHandle(void); - //tHalUint8* getAddress(); bool getIsSetAddress(); Timeout getAdvTimeout(void) const { @@ -121,7 +151,11 @@ private: uint16_t m_connectionHandle; + AddressType_t addr_type; + Address_t _peerAddr; uint8_t bdaddr[BDADDR_SIZE]; + bool _scanning; + bool _connecting; bool isSetAddress; tBleStatus ret; // FIXME: delete this uint8_t *DeviceName; @@ -143,6 +177,7 @@ BlueNRGGap() { m_connectionHandle = BLE_CONN_HANDLE_INVALID; + addr_type = Gap::ADDR_TYPE_PUBLIC; isSetAddress = false; DeviceName = NULL; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/BlueNRGGattClient.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,162 @@ +/* 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__ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/ble_status.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,115 +0,0 @@ -/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** -* File Name : ble_status.h -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 19-July-2012 -* Description : Header file with BLE Stack status codes. -******************************************************************************** -* 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. -*******************************************************************************/ -#ifndef __BLE_STATUS_H__ -#define __BLE_STATUS_H__ - -#include <hal_types.h> - - -/** @defgroup ble_status Bluetooth Status/Error Codes - * @{ - */ - -typedef uint8_t tBleStatus; - -/* Error Codes as specified by the specification - * according to the spec the error codes range - * from 0x00 to 0x3F - */ -#define ERR_CMD_SUCCESS (0x00) -#define BLE_STATUS_SUCCESS (0x00) -#define ERR_UNKNOWN_HCI_COMMAND (0x01) -#define ERR_UNKNOWN_CONN_IDENTIFIER (0x02) - -#define ERR_AUTH_FAILURE (0x05) -#define ERR_PIN_OR_KEY_MISSING (0x06) -#define ERR_MEM_CAPACITY_EXCEEDED (0x07) -#define ERR_CONNECTION_TIMEOUT (0x08) - -#define ERR_COMMAND_DISALLOWED (0x0C) - -#define ERR_UNSUPPORTED_FEATURE (0x11) -#define ERR_INVALID_HCI_CMD_PARAMS (0x12) -#define ERR_RMT_USR_TERM_CONN (0x13) -#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES (0x14) -#define ERR_RMT_DEV_TERM_CONN_POWER_OFF (0x15) -#define ERR_LOCAL_HOST_TERM_CONN (0x16) - -#define ERR_UNSUPP_RMT_FEATURE (0x1A) - -#define ERR_INVALID_LMP_PARAM (0x1E) -#define ERR_UNSPECIFIED_ERROR (0x1F) - -#define ERR_LL_RESP_TIMEOUT (0x22) -#define ERR_LMP_PDU_NOT_ALLOWED (0x24) - -#define ERR_INSTANT_PASSED (0x28) - -#define ERR_PAIR_UNIT_KEY_NOT_SUPP (0x29) -#define ERR_CONTROLLER_BUSY (0x3A) - -#define ERR_DIRECTED_ADV_TIMEOUT (0x3C) - -#define ERR_CONN_END_WITH_MIC_FAILURE (0x3D) - -#define ERR_CONN_FAILED_TO_ESTABLISH (0x3E) - - -#define BLE_STATUS_FAILED (0x41) -#define BLE_STATUS_INVALID_PARAMS (0x42) -#define BLE_STATUS_BUSY (0x43) -#define BLE_STATUS_INVALID_LEN_PDU (0x44) -#define BLE_STATUS_PENDING (0x45) -#define BLE_STATUS_NOT_ALLOWED (0x46) -#define BLE_STATUS_ERROR (0x47) -#define BLE_STATUS_ADDR_NOT_RESOLVED (0x48) - -#define FLASH_READ_FAILED (0x49) -#define FLASH_WRITE_FAILED (0x4A) -#define FLASH_ERASE_FAILED (0x4B) - -#define BLE_STATUS_INVALID_CID (0x50) - -#define TIMER_NOT_VALID_LAYER (0x54) -#define TIMER_INSUFFICIENT_RESOURCES (0x55) - -#define BLE_STATUS_CSRK_NOT_FOUND (0x5A) -#define BLE_STATUS_IRK_NOT_FOUND (0x5B) -#define BLE_STATUS_DEV_NOT_FOUND_IN_DB (0x5C) -#define BLE_STATUS_SEC_DB_FULL (0x5D) -#define BLE_STATUS_DEV_NOT_BONDED (0x5E) -#define BLE_STATUS_DEV_IN_BLACKLIST (0x5F) - -#define BLE_STATUS_INVALID_HANDLE (0x60) -#define BLE_STATUS_INVALID_PARAMETER (0x61) -#define BLE_STATUS_OUT_OF_HANDLE (0x62) -#define BLE_STATUS_INVALID_OPERATION (0x63) -#define BLE_STATUS_INSUFFICIENT_RESOURCES (0x64) -#define BLE_INSUFFICIENT_ENC_KEYSIZE (0x65) -#define BLE_STATUS_CHARAC_ALREADY_EXISTS (0x66) - - /* - * Library Error Codes - */ -#define BLE_STATUS_TIMEOUT (0xFF) -#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED (0xF0) -#define BLE_STATUS_NULL_PARAM (0xF1) - -/** - * @} - */ - - -#endif /* __BLE_STATUS_H__ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_aci.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** -* File Name : bluenrg_hci.h -* Author : AMS - AAS -* Version : V1.0.0 -* Date : 26-Jun-2014 -* Description : Header file that includes commands and events for BlueNRG -* FW6.3. -******************************************************************************** -* 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. -*******************************************************************************/ - -#ifndef __BLUENRG_ACI_H__ -#define __BLUENRG_ACI_H__ - -#include "bluenrg_aci_const.h" -#include "bluenrg_gap_aci.h" -#include "bluenrg_gatt_aci.h" -#include "bluenrg_l2cap_aci.h" -#include "bluenrg_hal_aci.h" -#include "bluenrg_updater_aci.h" - -#endif /* __BLUENRG_ACI_H__ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_aci_const.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,764 +0,0 @@ -/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** -* File Name : bluenrg_aci_const.h -* Author : AMS - AAS -* Version : V1.0.0 -* Date : 26-Jun-2014 -* Description : Header file with ACI definitions for BlueNRG FW6.3. -******************************************************************************** -* 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. -*******************************************************************************/ - -#ifndef __BLUENRG_ACI_CONST_H_ -#define __BLUENRG_ACI_CONST_H_ - -#include "compiler.h" -#include "link_layer.h" -#include "hci_const.h" -#include "bluenrg_gatt_server.h" - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -#define OCF_HAL_WRITE_CONFIG_DATA 0x000C - -#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F -typedef __packed struct _hal_set_tx_power_level_cp{ - uint8_t en_high_power; - uint8_t pa_level; -} PACKED hal_set_tx_power_level_cp; -#define HAL_SET_TX_POWER_LEVEL_CP_SIZE 2 - -#define OCF_HAL_DEVICE_STANDBY 0x0013 - -#define OCF_HAL_TONE_START 0x0015 -typedef __packed struct _hal_tone_start_cp{ - uint8_t rf_channel; -} PACKED hal_tone_start_cp; -#define HAL_TONE_START_CP_SIZE 1 - -#define OCF_HAL_TONE_STOP 0x0016 - -#define OCF_UPDATER_START 0x0020 -#define OCF_UPDATER_REBOOT 0x0021 - -#define OCF_GET_UPDATER_VERSION 0x0022 -typedef __packed struct _get_updater_version_rp{ - uint8_t status; - uint8_t version; -} PACKED get_updater_version_rp; -#define GET_UPDATER_VERSION_RP_SIZE 2 - -#define OCF_GET_UPDATER_BUFSIZE 0x0023 -typedef __packed struct _get_updater_bufsize_rp{ - uint8_t status; - uint8_t buffer_size; -} PACKED get_updater_bufsize_rp; -#define GET_UPDATER_BUFSIZE_RP_SIZE 2 - -#define OCF_UPDATER_ERASE_BLUE_FLAG 0x0024 - -#define OCF_UPDATER_RESET_BLUE_FLAG 0x0025 - -#define OCF_UPDATER_ERASE_SECTOR 0x0026 -typedef __packed struct _updater_erase_sector_cp{ - uint32_t address; -} PACKED updater_erase_sector_cp; -#define UPDATER_ERASE_SECTOR_CP_SIZE 4 - -#define OCF_UPDATER_PROG_DATA_BLOCK 0x0027 -#define UPDATER_PROG_DATA_BLOCK_CP_SIZE 6 -typedef __packed struct _updater_prog_data_block_cp{ - uint32_t address; - uint16_t data_len; - uint8_t data[HCI_MAX_PAYLOAD_SIZE-UPDATER_PROG_DATA_BLOCK_CP_SIZE]; -} PACKED updater_prog_data_block_cp; - -#define OCF_UPDATER_READ_DATA_BLOCK 0x0028 -typedef __packed struct _updater_read_data_block_cp{ - uint32_t address; - uint16_t data_len; -} PACKED updater_read_data_block_cp; -#define UPDATER_READ_DATA_BLOCK_CP_SIZE 6 -typedef __packed struct _updater_read_data_block_rp{ - uint8_t status; - uint8_t data[VARIABLE_SIZE]; -} PACKED updater_read_data_block_rp; -#define GET_UPDATER_BUFSIZE_RP_SIZE 2 - -#define OCF_UPDATER_CALC_CRC 0x0029 -typedef __packed struct _updater_calc_crc_cp{ - uint32_t address; - uint8_t num_sectors; -} PACKED updater_calc_crc_cp; -#define UPDATER_CALC_CRC_CP_SIZE 5 -typedef __packed struct _updater_calc_crc_rp{ - uint8_t status; - uint32_t crc; -} PACKED updater_calc_crc_rp; -#define UPDATER_CALC_CRC_RP_SIZE 5 - -#define OCF_UPDATER_HW_VERSION 0x002A -typedef __packed struct _updater_hw_version_rp{ - uint8_t status; - uint8_t version; -} PACKED updater_hw_version_rp; -#define UPDATER_HW_VERSION_RP_SIZE 2 - -#define OCF_GAP_SET_NON_DISCOVERABLE 0x0081 - -#define OCF_GAP_SET_LIMITED_DISCOVERABLE 0x0082 - -#define OCF_GAP_SET_DISCOVERABLE 0x0083 - -#define OCF_GAP_SET_DIRECT_CONNECTABLE 0x0084 -typedef __packed struct _gap_set_direct_conectable_cp_IDB05A1{ - uint8_t own_bdaddr_type; - uint8_t directed_adv_type; - uint8_t direct_bdaddr_type; - tBDAddr direct_bdaddr; -} PACKED gap_set_direct_conectable_cp_IDB05A1; - -typedef __packed struct _gap_set_direct_conectable_cp_IDB04A1{ - uint8_t own_bdaddr_type; - uint8_t direct_bdaddr_type; - tBDAddr direct_bdaddr; -} PACKED gap_set_direct_conectable_cp_IDB04A1; -#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8 - -#define OCF_GAP_SET_IO_CAPABILITY 0x0085 -typedef __packed struct _gap_set_io_capability_cp{ - uint8_t io_capability; -} PACKED gap_set_io_capability_cp; -#define GAP_SET_IO_CAPABILITY_CP_SIZE 1 - -#define OCF_GAP_SET_AUTH_REQUIREMENT 0x0086 -typedef __packed struct _gap_set_auth_requirement_cp{ - uint8_t mitm_mode; - uint8_t oob_enable; - uint8_t oob_data[16]; - uint8_t min_encryption_key_size; - uint8_t max_encryption_key_size; - uint8_t use_fixed_pin; - uint32_t fixed_pin; - uint8_t bonding_mode; -} PACKED gap_set_auth_requirement_cp; -#define GAP_SET_AUTH_REQUIREMENT_CP_SIZE 26 - -#define OCF_GAP_SET_AUTHOR_REQUIREMENT 0x0087 -typedef __packed struct _gap_set_author_requirement_cp{ - uint16_t conn_handle; - uint8_t authorization_enable; -} PACKED gap_set_author_requirement_cp; -#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 3 - -#define OCF_GAP_PASSKEY_RESPONSE 0x0088 -typedef __packed struct _gap_passkey_response_cp{ - uint16_t conn_handle; - uint32_t passkey; -} PACKED gap_passkey_response_cp; -#define GAP_PASSKEY_RESPONSE_CP_SIZE 6 - -#define OCF_GAP_AUTHORIZATION_RESPONSE 0x0089 -typedef __packed struct _gap_authorization_response_cp{ - uint16_t conn_handle; - uint8_t authorize; -} PACKED gap_authorization_response_cp; -#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 3 - -#define OCF_GAP_INIT 0x008A -typedef __packed struct _gap_init_cp_IDB05A1{ - uint8_t role; - uint8_t privacy_enabled; - uint8_t device_name_char_len; -} PACKED gap_init_cp_IDB05A1; -#define GAP_INIT_CP_SIZE_IDB05A1 3 - -typedef __packed struct _gap_init_cp_IDB04A1{ - uint8_t role; -} PACKED gap_init_cp_IDB04A1; -#define GAP_INIT_CP_SIZE_IDB04A1 1 -typedef __packed struct _gap_init_rp{ - uint8_t status; - uint16_t service_handle; - uint16_t dev_name_char_handle; - uint16_t appearance_char_handle; -} PACKED gap_init_rp; -#define GAP_INIT_RP_SIZE 7 - -#define OCF_GAP_SET_NON_CONNECTABLE 0x008B -typedef __packed struct _gap_set_non_connectable_cp_IDB05A1{ - uint8_t advertising_event_type; - uint8_t own_address_type; -#endif -} PACKED gap_set_non_connectable_cp_IDB05A1; - -typedef __packed struct _gap_set_non_connectable_cp_IDB04A1{ - uint8_t advertising_event_type; -} PACKED gap_set_non_connectable_cp_IDB04A1; - -#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE 0x008C -typedef __packed struct _gap_set_undirected_connectable_cp{ - uint8_t adv_filter_policy; - uint8_t own_addr_type; -} PACKED gap_set_undirected_connectable_cp; -#define GAP_SET_UNDIRECTED_CONNECTABLE_CP_SIZE 2 - -#define OCF_GAP_SLAVE_SECURITY_REQUEST 0x008D -typedef __packed struct _gap_slave_security_request_cp{ - uint16_t conn_handle; - uint8_t bonding; - uint8_t mitm_protection; -} PACKED gap_slave_security_request_cp; -#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 4 - -#define OCF_GAP_UPDATE_ADV_DATA 0x008E - -#define OCF_GAP_DELETE_AD_TYPE 0x008F -typedef __packed struct _gap_delete_ad_type_cp{ - uint8_t ad_type; -} PACKED gap_delete_ad_type_cp; -#define GAP_DELETE_AD_TYPE_CP_SIZE 1 - -#define OCF_GAP_GET_SECURITY_LEVEL 0x0090 -typedef __packed struct _gap_get_security_level_rp{ - uint8_t status; - uint8_t mitm_protection; - uint8_t bonding; - uint8_t oob_data; - uint8_t passkey_required; -} PACKED gap_get_security_level_rp; -#define GAP_GET_SECURITY_LEVEL_RP_SIZE 5 - -#define OCF_GAP_SET_EVT_MASK 0x0091 -typedef __packed struct _gap_set_evt_mask_cp{ - uint16_t evt_mask; -} PACKED gap_set_evt_mask_cp; -#define GAP_SET_EVT_MASK_CP_SIZE 2 - -#define OCF_GAP_CONFIGURE_WHITELIST 0x0092 - -#define OCF_GAP_TERMINATE 0x0093 -typedef __packed struct _gap_terminate_cp{ - uint16_t handle; - uint8_t reason; -} PACKED gap_terminate_cp; -#define GAP_TERMINATE_CP_SIZE 3 - -#define OCF_GAP_CLEAR_SECURITY_DB 0x0094 - -#define OCF_GAP_ALLOW_REBOND_DB 0x0095 - -typedef __packed struct _gap_allow_rebond_cp_IDB05A1{ - uint16_t conn_handle; -} PACKED gap_allow_rebond_cp_IDB05A1; - -#define OCF_GAP_START_LIMITED_DISCOVERY_PROC 0x0096 -typedef __packed struct _gap_start_limited_discovery_proc_cp{ - uint16_t scanInterval; - uint16_t scanWindow; - uint8_t own_address_type; - uint8_t filterDuplicates; -} PACKED gap_start_limited_discovery_proc_cp; -#define GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE 6 - -#define OCF_GAP_START_GENERAL_DISCOVERY_PROC 0x0097 -typedef __packed struct _gap_start_general_discovery_proc_cp{ - uint16_t scanInterval; - uint16_t scanWindow; - uint8_t own_address_type; - uint8_t filterDuplicates; -} PACKED gap_start_general_discovery_proc_cp; -#define GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE 6 - -#define OCF_GAP_START_NAME_DISCOVERY_PROC 0x0098 -typedef __packed struct _gap_start_name_discovery_proc_cp{ - uint16_t scanInterval; - uint16_t scanWindow; - uint8_t peer_bdaddr_type; - tBDAddr peer_bdaddr; - uint8_t own_bdaddr_type; - uint16_t conn_min_interval; - uint16_t conn_max_interval; - uint16_t conn_latency; - uint16_t supervision_timeout; - uint16_t min_conn_length; - uint16_t max_conn_length; -} PACKED gap_start_name_discovery_proc_cp; -#define GAP_START_NAME_DISCOVERY_PROC_CP_SIZE 24 - -#define OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC 0x0099 - -#define OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC 0x009A -typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB05A1{ - uint8_t scan_type; - uint16_t scan_interval; - uint16_t scan_window; - uint8_t own_address_type; - uint8_t filter_duplicates; -} PACKED gap_start_general_conn_establish_proc_cp_IDB05A1; - -typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB04A1{ - uint8_t scan_type; - uint16_t scan_interval; - uint16_t scan_window; - uint8_t own_address_type; - uint8_t filter_duplicates; - uint8_t use_reconn_addr; - tBDAddr reconn_addr; -} PACKED gap_start_general_conn_establish_proc_cp_IDB04A1; - -#define OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC 0x009B -#define GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE 8 -typedef __packed struct _gap_start_selective_conn_establish_proc_cp{ - uint8_t scan_type; - uint16_t scan_interval; - uint16_t scan_window; - uint8_t own_address_type; - uint8_t filter_duplicates; - uint8_t num_whitelist_entries; - uint8_t addr_array[HCI_MAX_PAYLOAD_SIZE-GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE]; -} PACKED gap_start_selective_conn_establish_proc_cp; - -#define OCF_GAP_CREATE_CONNECTION 0x009C -typedef __packed struct _gap_create_connection_cp{ - uint16_t scanInterval; - uint16_t scanWindow; - uint8_t peer_bdaddr_type; - tBDAddr peer_bdaddr; - uint8_t own_bdaddr_type; - uint16_t conn_min_interval; - uint16_t conn_max_interval; - uint16_t conn_latency; - uint16_t supervision_timeout; - uint16_t min_conn_length; - uint16_t max_conn_length; -} PACKED gap_create_connection_cp; -#define GAP_CREATE_CONNECTION_CP_SIZE 24 - -#define OCF_GAP_TERMINATE_GAP_PROCEDURE 0x009D - -#define OCF_GAP_START_CONNECTION_UPDATE 0x009E -typedef __packed struct _gap_start_connection_update_cp{ - uint16_t conn_handle; - uint16_t conn_min_interval; - uint16_t conn_max_interval; - uint16_t conn_latency; - uint16_t supervision_timeout; - uint16_t min_conn_length; - uint16_t max_conn_length; -} PACKED gap_start_connection_update_cp; -#define GAP_START_CONNECTION_UPDATE_CP_SIZE 14 - -#define OCF_GAP_SEND_PAIRING_REQUEST 0x009F -typedef __packed struct _gap_send_pairing_request_cp{ - uint16_t conn_handle; - uint8_t force_rebond; -} PACKED gap_send_pairing_request_cp; -#define GAP_GAP_SEND_PAIRING_REQUEST_CP_SIZE 3 - -#define OCF_GAP_RESOLVE_PRIVATE_ADDRESS 0x00A0 -typedef __packed struct _gap_resolve_private_address_cp{ - tBDAddr address; -} PACKED gap_resolve_private_address_cp; -#define GAP_RESOLVE_PRIVATE_ADDRESS_CP_SIZE 6 -typedef __packed struct _gap_resolve_private_address_rp{ - uint8_t status; - tBDAddr address; -} PACKED gap_resolve_private_address_rp; - -#define OCF_GAP_SET_BROADCAST_MODE 0x00A1 -#define GAP_SET_BROADCAST_MODE_CP_SIZE 6 -typedef __packed struct _gap_set_broadcast_mode_cp{ - uint16_t adv_interv_min; - uint16_t adv_interv_max; - uint8_t adv_type; - uint8_t own_addr_type; - uint8_t var_len_data[HCI_MAX_PAYLOAD_SIZE-GAP_SET_BROADCAST_MODE_CP_SIZE]; -} PACKED gap_set_broadcast_mode_cp; - -#define OCF_GAP_START_OBSERVATION_PROC 0x00A2 -typedef __packed struct _gap_start_observation_proc_cp{ - uint16_t scan_interval; - uint16_t scan_window; - uint8_t scan_type; - uint8_t own_address_type; - uint8_t filter_duplicates; -} PACKED gap_start_observation_proc_cp; - -#define OCF_GAP_GET_BONDED_DEVICES 0x00A3 -typedef __packed struct _gap_get_bonded_devices_rp{ - uint8_t status; - uint8_t num_addr; - uint8_t dev_list[HCI_MAX_PAYLOAD_SIZE-HCI_EVENT_HDR_SIZE-EVT_CMD_COMPLETE_SIZE-1]; -} PACKED gap_get_bonded_devices_rp; - -#define OCF_GAP_IS_DEVICE_BONDED 0x00A4 -typedef __packed struct _gap_is_device_bonded_cp{ - uint8_t peer_address_type; - tBDAddr peer_address; -} PACKED gap_is_device_bonded_cp; - - -#define OCF_GATT_INIT 0x0101 - -#define OCF_GATT_ADD_SERV 0x0102 -typedef __packed struct _gatt_add_serv_rp{ - uint8_t status; - uint16_t handle; -} PACKED gatt_add_serv_rp; -#define GATT_ADD_SERV_RP_SIZE 3 - -#define OCF_GATT_INCLUDE_SERV 0x0103 -typedef __packed struct _gatt_include_serv_rp{ - uint8_t status; - uint16_t handle; -} PACKED gatt_include_serv_rp; -#define GATT_INCLUDE_SERV_RP_SIZE 3 - -#define OCF_GATT_ADD_CHAR 0x0104 -typedef __packed struct _gatt_add_char_rp{ - uint8_t status; - uint16_t handle; -} PACKED gatt_add_char_rp; -#define GATT_ADD_CHAR_RP_SIZE 3 - -#define OCF_GATT_ADD_CHAR_DESC 0x0105 -typedef __packed struct _gatt_add_char_desc_rp{ - uint8_t status; - uint16_t handle; -} PACKED gatt_add_char_desc_rp; -#define GATT_ADD_CHAR_DESC_RP_SIZE 3 - -#define OCF_GATT_UPD_CHAR_VAL 0x0106 - -#define OCF_GATT_DEL_CHAR 0x0107 -typedef __packed struct _gatt_del_char_cp{ - uint16_t service_handle; - uint16_t char_handle; -} PACKED gatt_del_char_cp; -#define GATT_DEL_CHAR_CP_SIZE 4 - -#define OCF_GATT_DEL_SERV 0x0108 -typedef __packed struct _gatt_del_serv_cp{ - uint16_t service_handle; -} PACKED gatt_del_serv_cp; -#define GATT_DEL_SERV_CP_SIZE 2 - -#define OCF_GATT_DEL_INC_SERV 0x0109 -typedef __packed struct _gatt_del_inc_serv_cp{ - uint16_t service_handle; - uint16_t inc_serv_handle; -} PACKED gatt_del_inc_serv_cp; -#define GATT_DEL_INC_SERV_CP_SIZE 4 - -#define OCF_GATT_SET_EVT_MASK 0x010A -typedef __packed struct _gatt_set_evt_mask_cp{ - uint32_t evt_mask; -} PACKED gatt_set_evt_mask_cp; -#define GATT_SET_EVT_MASK_CP_SIZE 4 - -#define OCF_GATT_EXCHANGE_CONFIG 0x010B -typedef __packed struct _gatt_exchange_config_cp{ - uint16_t conn_handle; -} PACKED gatt_exchange_config_cp; -#define GATT_EXCHANGE_CONFIG_CP_SIZE 2 - -#define OCF_ATT_FIND_INFO_REQ 0x010C -typedef __packed struct _att_find_info_req_cp{ - uint16_t conn_handle; - uint16_t start_handle; - uint16_t end_handle; -} PACKED att_find_info_req_cp; -#define ATT_FIND_INFO_REQ_CP_SIZE 6 - -#define OCF_ATT_FIND_BY_TYPE_VALUE_REQ 0x010D -#define ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE 9 -typedef __packed struct _att_find_by_type_value_req_cp{ - uint16_t conn_handle; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid[2]; - uint8_t attr_val_len; - uint8_t attr_val[ATT_MTU - 7]; -} PACKED att_find_by_type_value_req_cp; - -#define OCF_ATT_READ_BY_TYPE_REQ 0x010E -#define ATT_READ_BY_TYPE_REQ_CP_SIZE 7 // without UUID -typedef __packed struct _att_read_by_type_req_cp{ - uint16_t conn_handle; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_type; - uint8_t uuid[16]; -} PACKED att_read_by_type_req_cp; - -#define OCF_ATT_READ_BY_GROUP_TYPE_REQ 0x010F -#define ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE 7 // without UUID -typedef __packed struct _att_read_by_group_type_req_cp{ - uint16_t conn_handle; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_type; - uint8_t uuid[16]; -} PACKED att_read_by_group_type_req_cp; - -#define OCF_ATT_PREPARE_WRITE_REQ 0x0110 -#define ATT_PREPARE_WRITE_REQ_CP_SIZE 7 // without attr_val -typedef __packed struct _att_prepare_write_req_cp{ - uint16_t conn_handle; - uint16_t attr_handle; - uint16_t value_offset; - uint8_t attr_val_len; - uint8_t attr_val[ATT_MTU-5]; -} PACKED att_prepare_write_req_cp; - -#define OCF_ATT_EXECUTE_WRITE_REQ 0x0111 -typedef __packed struct _att_execute_write_req_cp{ - uint16_t conn_handle; - uint8_t execute; -} PACKED att_execute_write_req_cp; -#define ATT_EXECUTE_WRITE_REQ_CP_SIZE 3 - -#define OCF_GATT_DISC_ALL_PRIM_SERVICES 0X0112 -typedef __packed struct _gatt_disc_all_prim_serivces_cp{ - uint16_t conn_handle; -} PACKED gatt_disc_all_prim_services_cp; -#define GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE 2 - -#define OCF_GATT_DISC_PRIM_SERVICE_BY_UUID 0x0113 -typedef __packed struct _gatt_disc_prim_service_by_uuid_cp{ - uint16_t conn_handle; - uint8_t uuid_type; - uint8_t uuid[16]; -} PACKED gatt_disc_prim_service_by_uuid_cp; -#define GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE 3 // Without uuid - -#define OCF_GATT_FIND_INCLUDED_SERVICES 0X0114 -typedef __packed struct _gatt_disc_find_included_services_cp{ - uint16_t conn_handle; - uint16_t start_handle; - uint16_t end_handle; -} PACKED gatt_find_included_services_cp; -#define GATT_FIND_INCLUDED_SERVICES_CP_SIZE 6 - -#define OCF_GATT_DISC_ALL_CHARAC_OF_SERV 0X0115 -typedef __packed struct _gatt_disc_all_charac_of_serv_cp{ - uint16_t conn_handle; - uint16_t start_attr_handle; - uint16_t end_attr_handle; -} PACKED gatt_disc_all_charac_of_serv_cp; -#define GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE 6 - -#define OCF_GATT_DISC_CHARAC_BY_UUID 0X0116 - -#define OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS 0X0117 -typedef __packed struct _gatt_disc_all_charac_descriptors_cp{ - uint16_t conn_handle; - uint16_t char_val_handle; - uint16_t char_end_handle; -} PACKED gatt_disc_all_charac_descriptors_cp; -#define GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE 6 - -#define OCF_GATT_READ_CHARAC_VAL 0x0118 -typedef __packed struct _gatt_read_charac_val_cp{ - uint16_t conn_handle; - uint16_t attr_handle; -} PACKED gatt_read_charac_val_cp; -#define GATT_READ_CHARAC_VAL_CP_SIZE 4 - -#define OCF_GATT_READ_USING_CHARAC_UUID 0x0109 -typedef __packed struct _gatt_read_using_charac_uuid_cp{ - uint16_t conn_handle; - uint16_t start_handle; - uint16_t end_handle; - uint8_t uuid_type; - uint8_t uuid[16]; -} PACKED gatt_read_using_charac_uuid_cp; -#define GATT_READ_USING_CHARAC_UUID_CP_SIZE 7 // without UUID - -#define OCF_GATT_READ_LONG_CHARAC_VAL 0x011A -typedef __packed struct _gatt_read_long_charac_val_cp{ - uint16_t conn_handle; - uint16_t attr_handle; - uint16_t val_offset; -} PACKED gatt_read_long_charac_val_cp; -#define GATT_READ_LONG_CHARAC_VAL_CP_SIZE 6 - -#define OCF_GATT_READ_MULTIPLE_CHARAC_VAL 0x011B -#define GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE 3 // without set_of_handles -typedef __packed struct _gatt_read_multiple_charac_val_cp{ - uint16_t conn_handle; - uint8_t num_handles; - uint8_t set_of_handles[HCI_MAX_PAYLOAD_SIZE-GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE]; -} PACKED gatt_read_multiple_charac_val_cp; - -#define OCF_GATT_WRITE_CHAR_VALUE 0x011C - -#define OCF_GATT_WRITE_LONG_CHARAC_VAL 0x011D -#define GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE 7 // without set_of_handles -typedef __packed struct _gatt_write_long_charac_val_cp{ - uint16_t conn_handle; - uint16_t attr_handle; - uint16_t val_offset; - uint8_t val_len; - uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE]; -} PACKED gatt_write_long_charac_val_cp; - -#define OCF_GATT_WRITE_CHARAC_RELIABLE 0x011E -#define GATT_WRITE_CHARAC_RELIABLE_CP_SIZE 7 // without set_of_handles -typedef __packed struct _gatt_write_charac_reliable_cp{ - uint16_t conn_handle; - uint16_t attr_handle; - uint16_t val_offset; - uint8_t val_len; - uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_CHARAC_RELIABLE_CP_SIZE]; -} PACKED gatt_write_charac_reliable_cp; - -#define OCF_GATT_WRITE_LONG_CHARAC_DESC 0x011F -#define GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE 7 // without set_of_handles -typedef __packed struct _gatt_write_long_charac_desc_cp{ - uint16_t conn_handle; - uint16_t attr_handle; - uint16_t val_offset; - uint8_t val_len; - uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE]; -} PACKED gatt_write_long_charac_desc_cp; - -#define OCF_GATT_READ_LONG_CHARAC_DESC 0x0120 -typedef __packed struct _gatt_read_long_charac_desc_cp{ - uint16_t conn_handle; - uint16_t attr_handle; - uint16_t val_offset; -} PACKED gatt_read_long_charac_desc_cp; -#define GATT_READ_LONG_CHARAC_DESC_CP_SIZE 6 - -#define OCF_GATT_WRITE_CHAR_DESCRIPTOR 0x0121 - -#define OCF_GATT_READ_CHAR_DESCRIPTOR 0x0122 -typedef __packed struct _gatt_read_charac_desc_cp{ - uint16_t conn_handle; - uint16_t attr_handle; -} PACKED gatt_read_charac_desc_cp; -#define GATT_READ_CHAR_DESCRIPTOR_CP_SIZE 4 - -#define OCF_GATT_WRITE_WITHOUT_RESPONSE 0x0123 -#define GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val -typedef __packed struct _gatt_write_without_resp_cp{ - uint16_t conn_handle; - uint16_t attr_handle; - uint8_t val_len; - uint8_t attr_val[ATT_MTU - 3]; -} PACKED gatt_write_without_resp_cp; - -#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE 0x0124 -#define GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val -typedef __packed struct _gatt_signed_write_without_resp_cp{ - uint16_t conn_handle; - uint16_t attr_handle; - uint8_t val_len; - uint8_t attr_val[ATT_MTU - 13]; -} PACKED gatt_signed_write_without_resp_cp; - -#define OCF_GATT_CONFIRM_INDICATION 0x0125 -typedef __packed struct _gatt_confirm_indication_cp{ - uint16_t conn_handle; -} PACKED gatt_confirm_indication_cp; -#define GATT_CONFIRM_INDICATION_CP_SIZE 2 - -#define OCF_GATT_WRITE_RESPONSE 0x0126 - -#define OCF_GATT_ALLOW_READ 0x0127 -typedef __packed struct _gatt_allow_read_cp{ - uint16_t conn_handle; -} PACKED gatt_allow_read_cp; -#define GATT_ALLOW_READ_CP_SIZE 2 - -#define OCF_GATT_SET_SECURITY_PERMISSION 0x0128 -typedef __packed struct _gatt_set_security_permission_cp{ - uint16_t service_handle; - uint16_t attr_handle; - uint8_t security_permission; -} PACKED gatt_set_security_permission_cp; -#define GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE 5 - -#define OCF_GATT_SET_DESC_VAL 0x0129 - -#define OCF_GATT_READ_HANDLE_VALUE 0x012A -typedef __packed struct _gatt_read_handle_val_cp{ - uint16_t attr_handle; -} PACKED gatt_read_handle_val_cp; -#define GATT_READ_HANDLE_VALUE_RP_SIZE 3 -typedef __packed struct _gatt_read_handle_val_rp{ - uint8_t status; - uint16_t value_len; - uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_RP_SIZE]; -} PACKED gatt_read_handle_val_rp; - -#define OCF_GATT_READ_HANDLE_VALUE_OFFSET 0x012B -typedef __packed struct _gatt_read_handle_val_offset_cp{ - uint16_t attr_handle; - uint8_t offset; -} PACKED gatt_read_handle_val_offset_cp; -#define GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE 2 -typedef __packed struct _gatt_read_handle_val_offset_rp{ - uint8_t status; - uint8_t value_len; - uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE]; -} PACKED gatt_read_handle_val_offset_rp; - -#define OCF_L2CAP_CONN_PARAM_UPDATE_REQ 0x0181 -typedef __packed struct _l2cap_conn_param_update_req_cp{ - uint16_t conn_handle; - uint16_t interval_min; - uint16_t interval_max; - uint16_t slave_latency; - uint16_t timeout_multiplier; -} PACKED l2cap_conn_param_update_req_cp; -#define L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE 10 - -#define OCF_L2CAP_CONN_PARAM_UPDATE_RESP 0x0182 -typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB05A1{ - uint16_t conn_handle; - uint16_t interval_min; - uint16_t interval_max; - uint16_t slave_latency; - uint16_t timeout_multiplier; - uint16_t min_ce_length; - uint16_t max_ce_length; - uint8_t id; - uint8_t accept; -} PACKED l2cap_conn_param_update_resp_cp_IDB05A1; - -typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB04A1{ - uint16_t conn_handle; - uint16_t interval_min; - uint16_t interval_max; - uint16_t slave_latency; - uint16_t timeout_multiplier; - uint8_t id; - uint8_t accept; -} PACKED l2cap_conn_param_update_resp_cp_IDB04A1; - -/** - * @defgroup BlueNRG_Events BlueNRG events (vendor specific) - * @{ - */ - -/** - * Vendor specific event for BlueNRG. - */ -typedef __packed struct _evt_blue_aci{ - uint16_t ecode; /**< One of the BlueNRG event codes. */ - uint8_t data[VARIABLE_SIZE]; -} PACKED evt_blue_aci; - - -/** - * @} - */ - -#endif /* __BLUENRG_ACI_CONST_H_ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_gap.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,224 +0,0 @@ -/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** -* File Name : bluenrg_gap.h -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 19-July-2012 -* Description : Header file for BlueNRG's GAP layer. -******************************************************************************** -* 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. -*******************************************************************************/ -#ifndef __BNRG_GAP_H__ -#define __BNRG_GAP_H__ - -#include <link_layer.h> - -/** - *@addtogroup GAP GAP - *@brief API for GAP layer. - *@{ - */ - -/** - * @name GAP UUIDs - * @{ - */ -#define GAP_SERVICE_UUID (0x1800) -#define DEVICE_NAME_UUID (0x2A00) -#define APPEARANCE_UUID (0x2A01) -#define PERIPHERAL_PRIVACY_FLAG_UUID (0x2A02) -#define RECONNECTION_ADDR_UUID (0x2A03) -#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID (0x2A04) -/** - * @} - */ - -/** - * @name Characteristic value lengths - * @{ - */ -#define DEVICE_NAME_CHARACTERISTIC_LEN (8) -#define APPEARANCE_CHARACTERISTIC_LEN (2) -#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN (1) -#define RECONNECTION_ADDR_CHARACTERISTIC_LEN (6) -#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN (8) -/** - * @} - */ - -/*------------- AD types for adv data and scan response data ----------------*/ - -/** - * @defgroup AD_Types AD Types - * @brief AD Types - * @{ - */ - -/* FLAGS AD type */ -#define AD_TYPE_FLAGS (0x01) -/* flag bits */ -/** - * @anchor Flags_AD_Type_bits - * @name Flags AD Type bits - * @brief Bits in Flags AD Type - * @{ - */ -#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE (0x01) -#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE (0x02) -#define FLAG_BIT_BR_EDR_NOT_SUPPORTED (0x04) -#define FLAG_BIT_LE_BR_EDR_CONTROLLER (0x08) -#define FLAG_BIT_LE_BR_EDR_HOST (0x10) -/** - * @} - */ - -/** - * @name Service UUID AD types - * @{ - */ -#define AD_TYPE_16_BIT_SERV_UUID (0x02) -#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST (0x03) -#define AD_TYPE_32_BIT_SERV_UUID (0x04) -#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST (0x05) -#define AD_TYPE_128_BIT_SERV_UUID (0x06) -#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST (0x07) -/** - * @} - */ - -/* LOCAL NAME AD types */ -/** - * @name Local name AD types - * @{ - */ -#define AD_TYPE_SHORTENED_LOCAL_NAME (0x08) -#define AD_TYPE_COMPLETE_LOCAL_NAME (0x09) -/** - * @} - */ - -/* TX power level AD type*/ -#define AD_TYPE_TX_POWER_LEVEL (0x0A) - -/* Class of device */ -#define AD_TYPE_CLASS_OF_DEVICE (0x0D) - -/* security manager TK value AD type */ -#define AD_TYPE_SEC_MGR_TK_VALUE (0x10) - -/* security manager OOB flags */ -#define AD_TYPE_SEC_MGR_OOB_FLAGS (0x11) - -/* slave connection interval AD type */ -#define AD_TYPE_SLAVE_CONN_INTERVAL (0x12) - -/* service solicitation UUID list Ad types*/ -/** - * @name Service solicitation UUID list AD types - * @{ - */ -#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST (0x14) -#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST (0x1F) -#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST (0x15) -/** - * @} - */ - -/* service data AD type */ -#define AD_TYPE_SERVICE_DATA (0x16) - -/* manufaturer specific data AD type */ -#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF) - -/** - * @} - */ - -#define MAX_ADV_DATA_LEN (31) - -#define DEVICE_NAME_LEN (7) -#define BD_ADDR_SIZE (6) - -/** - * @name Privacy flag values - * @{ - */ -#define PRIVACY_ENABLED (0x01) -#define PRIVACY_DISABLED (0x00) -/** - * @} - */ - -/** - * @name Intervals - * Intervals in terms of 625 micro sec - * @{ - */ -#define DIR_CONN_ADV_INT_MIN (0x190)/*250ms*/ -#define DIR_CONN_ADV_INT_MAX (0x320)/*500ms*/ -#define UNDIR_CONN_ADV_INT_MIN (0x800)/*1.28s*/ -#define UNDIR_CONN_ADV_INT_MAX (0x1000)/*2.56s*/ -#define LIM_DISC_ADV_INT_MIN (0x190)/*250ms*/ -#define LIM_DISC_ADV_INT_MAX (0x320)/*500ms*/ -#define GEN_DISC_ADV_INT_MIN (0x800)/*1.28s*/ -#define GEN_DISC_ADV_INT_MAX (0x1000)/*2.56s*/ -/** - * @} - */ - -/** - * @name Timeout values - * @{ - */ -#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */ -#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */ -/** - * @} - */ - -/** - * @anchor gap_roles - * @name GAP Roles - * @{ -*/ -#define GAP_PERIPHERAL_ROLE_IDB05A1 (0x01) -#define GAP_BROADCASTER_ROLE_IDB05A1 (0x02) -#define GAP_CENTRAL_ROLE_IDB05A1 (0x04) -#define GAP_OBSERVER_ROLE_IDB05A1 (0x08) - -#define GAP_PERIPHERAL_ROLE_IDB04A1 (0x01) -#define GAP_BROADCASTER_ROLE_IDB04A1 (0x02) -#define GAP_CENTRAL_ROLE_IDB04A1 (0x03) -#define GAP_OBSERVER_ROLE_IDB04A1 (0x04) -/** - * @} - */ - -/** - * @anchor gap_procedure_codes - * @name GAP procedure codes - * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event - * and aci_gap_terminate_gap_procedure() command. - * @{ - */ -#define GAP_LIMITED_DISCOVERY_PROC (0x01) -#define GAP_GENERAL_DISCOVERY_PROC (0x02) -#define GAP_NAME_DISCOVERY_PROC (0x04) -#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC (0x08) -#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC (0x10) -#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20) -#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC (0x40) -#define GAP_OBSERVATION_PROC_IDB05A1 (0x80) -/** - * @} - */ - -/** - * @} - */ - -#endif /* __BNRG_GAP_H__ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_gap_aci.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1211 +0,0 @@ -/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** -* File Name : bluenrg_gap_aci.h -* Author : AMS - AAS -* Version : V1.0.0 -* Date : 26-Jun-2014 -* Description : Header file with GAP commands for BlueNRG FW6.3. -******************************************************************************** -* 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. -*******************************************************************************/ - -#ifndef __BLUENRG_GAP_ACI_H__ -#define __BLUENRG_GAP_ACI_H__ - -/** - *@addtogroup GAP GAP - *@brief GAP layer. - *@{ - */ - -/** - *@defgroup GAP_Functions GAP functions - *@brief API for GAP layer. - *@{ - */ - -/** - * @brief Initialize the GAP layer. - * @note Register the GAP service with the GATT. - * All the standard GAP characteristics will also be added: - * @li Device Name - * @li Appearance - * @li Peripheral Preferred Connection Parameters (peripheral role only) - * @code - - tBleStatus ret; - uint16_t service_handle, dev_name_char_handle, appearance_char_handle; - - ret = aci_gap_init_IDB05A1(1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle); - if(ret){ - PRINTF("GAP_Init failed.\n"); - reboot(); - } - const char *name = "BlueNRG"; - ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); - if(ret){ - PRINTF("aci_gatt_update_char_value failed.\n"); - } - * @endcode - * @param role Bitmap of allowed roles: see @ref gap_roles "GAP roles". - * @param privacy_enabled Enable (1) or disable (0) privacy. - * @param device_name_char_len Length of the device name characteristic - * @param[out] service_handle Handle of the GAP service. - * @param[out] dev_name_char_handle Device Name Characteristic handle - * @param[out] appearance_char_handle Appearance Characteristic handle - * @retval tBleStatus Value indicating success or error code. - */ -tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, - uint8_t device_name_char_len, - uint16_t* service_handle, - uint16_t* dev_name_char_handle, - uint16_t* appearance_char_handle); -/** - * @brief Initialize the GAP layer. - * @note Register the GAP service with the GATT. - * All the standard GAP characteristics will also be added: - * @li Device Name - * @li Appearance - * @li Peripheral Privacy Flag (peripheral role only) - * @li Reconnection Address (peripheral role only) - * @li Peripheral Preferred Connection Parameters (peripheral role only) - * @code - - tBleStatus ret; - uint16_t service_handle, dev_name_char_handle, appearance_char_handle; - - ret = aci_gap_init_IDB04A1(1, &service_handle, &dev_name_char_handle, &appearance_char_handle); - if(ret){ - PRINTF("GAP_Init failed.\n"); - reboot(); - } - const char *name = "BlueNRG"; - ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); - if(ret){ - PRINTF("aci_gatt_update_char_value failed.\n"); - } - * @endcode - * @param role One of the allowed roles: @ref GAP_PERIPHERAL_ROLE or @ref GAP_CENTRAL_ROLE. See @ref gap_roles "GAP roles". - * @param[out] service_handle Handle of the GAP service. - * @param[out] dev_name_char_handle Device Name Characteristic handle - * @param[out] appearance_char_handle Appearance Characteristic handle - * @retval tBleStatus Value indicating success or error code. - */ -tBleStatus aci_gap_init_IDB04A1(uint8_t role, - uint16_t* service_handle, - uint16_t* dev_name_char_handle, - uint16_t* appearance_char_handle); - -/** - * @brief Set the Device in non-discoverable mode. - * @note This command will disable the LL advertising. - * @retval tBleStatus Value indicating success or error code. - */ -tBleStatus aci_gap_set_non_discoverable(void); - -/** - * @brief Put the device in limited discoverable mode - * (as defined in GAP specification volume 3, section 9.2.3). - * @note The device will be discoverable for TGAP (lim_adv_timeout) = 180 seconds. - * The advertising can be disabled at any time by issuing - * aci_gap_set_non_discoverable() command. - * The AdvIntervMin and AdvIntervMax parameters are optional. If both - * are set to 0, the GAP will use default values (250 ms and 500 ms respectively). - * Host can set the Local Name, a Service UUID list and the Slave Connection - * Minimum and Maximum. 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. - * The total size of data in advertising packet cannot exceed 31 bytes. - * With this command, the BLE Stack will also add automatically the following - * standard AD types: - * @li AD Flags - * @li TX Power Level - * - * When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates - * @ref EVT_BLUE_GAP_LIMITED_DISCOVERABLE event. - * - * Example: - * @code - * - * #define ADV_INTERVAL_MIN_MS 100 - * #define ADV_INTERVAL_MAX_MS 200 - * - * tBleStatus ret; - * - * 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_limited_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625, - * (ADV_INTERVAL_MAX_MS*1000)/0.625, - * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, - * sizeof(local_name), local_name, - * sizeof(serviceUUIDList), serviceUUIDList, - * 0, 0); - * @endcode - * - * @param AdvType One of the advertising types: - * @arg @ref ADV_IND Connectable undirected advertising - * @arg @ref ADV_SCAN_IND Scannable undirected advertising - * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising - * @param AdvIntervMin Minimum advertising interval. - * Range: 0x0020 to 0x4000 - * Default: 250 ms - * Time = N * 0.625 msec - * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). - * @param AdvIntervMax Maximum advertising interval. - * Range: 0x0020 to 0x4000 - * Default: 500 ms - * Time = N * 0.625 msec - * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). - * @param OwnAddrType Type of our address used during advertising - * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). - * @param AdvFilterPolicy Filter policy: - * @arg NO_WHITE_LIST_USE - * @arg WHITE_LIST_FOR_ONLY_SCAN - * @arg WHITE_LIST_FOR_ONLY_CONN - * @arg WHITE_LIST_FOR_ALL - * @param LocalNameLen Length of LocalName array. - * @param LocalName Array containing the Local Name AD data. First byte is the AD type: - * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. - * @param ServiceUUIDLen Length of ServiceUUIDList array. - * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, - * Section 11.1.1 of GAP Specification. First byte is the AD Type. - * @arg @ref AD_TYPE_16_BIT_SERV_UUID - * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST - * @arg @ref AD_TYPE_128_BIT_SERV_UUID - * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST - * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. - * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, - * Slave Connection Interval Range AD structure will be added in advertising - * data. - * Connection interval is defined in the following manner: - * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms - * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 - * Value of 0xFFFF indicates no specific minimum. - * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. - * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, - * Slave Connection Interval Range AD structure will be added in advertising - * data. - * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms - * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 - * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. - * Value of 0xFFFF indicates no specific maximum. - * - * @retval tBleStatus Value indicating success or error code. - */ -tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, - uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, - const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, - uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); -/** - * @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). - * 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. - * The total size of data in advertising packet cannot exceed 31 bytes. - * With this command, the BLE Stack will also add automatically the following standard AD types: - * @li AD Flags - * @li TX Power Level - * - * Usage example: - * - * @code - * - * #define ADV_INTERVAL_MIN_MS 800 - * #define ADV_INTERVAL_MAX_MS 900 - * #define CONN_INTERVAL_MIN_MS 100 - * #define CONN_INTERVAL_MAX_MS 300 - * - * tBleStatus ret; - * - * 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, - * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, - * sizeof(local_name), local_name, - * 0, NULL, - * (CONN_INTERVAL_MIN_MS*1000)/1250, - * (CONN_INTERVAL_MAX_MS*1000)/1250); - * @endcode - * - * @param AdvType One of the advertising types: - * @arg @ref ADV_IND Connectable undirected advertising - * @arg @ref ADV_SCAN_IND Scannable undirected advertising - * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising - * @param AdvIntervMin Minimum advertising interval. - * Range: 0x0020 to 0x4000 - * Default: 1.28 s - * Time = N * 0.625 msec - * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). - * @param AdvIntervMax Maximum advertising interval. - * Range: 0x0020 to 0x4000 - * Default: 2.56 s - * Time = N * 0.625 msec - * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). - * @param OwnAddrType Type of our address used during advertising - * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). - * @param AdvFilterPolicy Filter policy: - * @arg @ref NO_WHITE_LIST_USE - * @arg @ref WHITE_LIST_FOR_ONLY_SCAN - * @arg @ref WHITE_LIST_FOR_ONLY_CONN - * @arg @ref WHITE_LIST_FOR_ALL - * @param LocalNameLen Length of LocalName array. - * @param LocalName Array containing the Local Name AD data. First byte is the AD type: - * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. - * @param ServiceUUIDLen Length of ServiceUUIDList array. - * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, - * Section 11.1.1 of GAP Specification. First byte is the AD Type. - * @arg @ref AD_TYPE_16_BIT_SERV_UUID - * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST - * @arg @ref AD_TYPE_128_BIT_SERV_UUID - * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST - * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. - * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, - * Slave Connection Interval Range AD structure will be added in advertising - * data. - * Connection interval is defined in the following manner: - * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms - * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 - * Value of 0xFFFF indicates no specific minimum. - * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. - * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, - * Slave Connection Interval Range AD structure will be added in advertising - * data. - * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms - * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 - * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. - * Value of 0xFFFF indicates no specific maximum. - * - * @retval tBleStatus Value indicating success or error code. - */ -tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, - uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, - const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, - uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); - -/** - * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). - * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address - * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only - * for 1.28 seconds. If no connection is established within this duration, the device enters non - * discoverable mode and advertising will have to be again enabled explicitly. - * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT - * if the connection was not established and 0x00 if the connection was successfully established. - * - * Usage example: - * @code - * - * tBleStatus ret; - * - * const uint8_t central_address[] = {0x43,0x27,0x84,0xE1,0x80,0x02}; - * ret = aci_gap_set_direct_connectable_IDB05A1(PUBLIC_ADDR, HIGH_DUTY_CYCLE_DIRECTED_ADV, PUBLIC_ADDR, central_address); - * @endcode - * - * - * - * @param OwnAddrType Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). - * @param directed_adv_type Type of directed advertising (@ref HIGH_DUTY_CYCLE_DIRECTED_ADV, @ref LOW_DUTY_CYCLE_DIRECTED_ADV). - * @param InitiatorAddrType Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). - * @param InitiatorAddr Initiator's address (Little Endian). - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr); -/** - * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). - * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address - * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only - * for 1.28 seconds. If no connection is established within this duration, the device enters non - * discoverable mode and advertising will have to be again enabled explicitly. - * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT - * if the connection was not established and 0x00 if the connection was successfully established. - * - * Usage example: - * @code - * - * tBleStatus ret; - * - * const uint8_t central_address = {0x43,0x27,0x84,0xE1,0x80,0x02}; - * ret = aci_gap_set_direct_connectable_IDB04A1(PUBLIC_ADDR, PUBLIC_ADDR, central_address); - * @endcode - * - * - * - * @param OwnAddrType Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). - * @param InitiatorAddrType Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). - * @param InitiatorAddr Initiator's address (Little Endian). - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr); - -/** - * @brief Set the IO capabilities of the device. - * @note This command has to be given only when the device is not in a connected state. - * @param io_capability One of the allowed codes for IO Capability: - * @arg @ref IO_CAP_DISPLAY_ONLY - * @arg @ref IO_CAP_DISPLAY_YES_NO - * @arg @ref IO_CAP_KEYBOARD_ONLY - * @arg @ref IO_CAP_NO_INPUT_NO_OUTPUT - * @arg @ref IO_CAP_KEYBOARD_DISPLAY - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_io_capability(uint8_t io_capability); - -/** - * @brief Set the authentication requirements for the device. - * @note If the oob_enable is set to 0, oob_data will be ignored. - * This command has to be given only when the device is not in a connected state. - * @param mitm_mode MITM mode: - * @arg @ref MITM_PROTECTION_NOT_REQUIRED - * @arg @ref MITM_PROTECTION_REQUIRED - * @param oob_enable If OOB data are present or not: - * @arg @ref OOB_AUTH_DATA_ABSENT - * @arg @ref OOB_AUTH_DATA_PRESENT - * @param oob_data Out-Of-Band data - * @param min_encryption_key_size Minimum size of the encryption key to be used during the pairing process - * @param max_encryption_key_size Maximum size of the encryption key to be used during the pairing process - * @param use_fixed_pin If application wants to use a fixed pin or not: - * @arg @ref USE_FIXED_PIN_FOR_PAIRING - * @arg @ref DONOT_USE_FIXED_PIN_FOR_PAIRING - * If a fixed pin is not used, it has to be provided by the application with - * aci_gap_pass_key_response() after @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. - * @param fixed_pin If use_fixed_pin is USE_FIXED_PIN_FOR_PAIRING, this is the value of the pin that will - * be used during pairing if MIMT protection is enabled. Any value between 0 to 999999 is - * accepted. - * @param bonding_mode One of the bonding modes: - * @arg @ref BONDING - * @arg @ref NO_BONDING - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, - uint8_t oob_enable, - uint8_t oob_data[16], - uint8_t min_encryption_key_size, - uint8_t max_encryption_key_size, - uint8_t use_fixed_pin, - uint32_t fixed_pin, - uint8_t bonding_mode); - /** - * @brief Set the authorization requirements of the device. - * @note This command has to be given only when the device is not in a connected state. - * @param conn_handle Handle of the connection in case BlueNRG is configured as a master (otherwise it can be also 0). - * @param authorization_enable @arg @ref AUTHORIZATION_NOT_REQUIRED : Authorization not required - * @arg @ref AUTHORIZATION_REQUIRED : Authorization required. This enables - * the authorization requirement in the device and when a remote device - * tries to connect to GATT server, @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST event - * will be sent to the Host. - * - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable); - -/** - * @brief Provide the pass key that will be used during pairing. - * @note This command should be sent by the Host in response to @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. - * @param conn_handle Connection handle - * @param passkey Pass key that will be used during the pairing process. Must be a number between - * 0 and 999999. - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey); - -/** - * @brief Authorize a device to access attributes. - * @note Application should send this command after it has received a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST. - * - * @param conn_handle Connection handle - * @param authorize @arg @ref CONNECTION_AUTHORIZED : Authorize (accept connection) - * @arg @ref CONNECTION_REJECTED : Reject (reject connection) - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize); - -/** - * @brief Put the device into non-connectable mode. - * @param adv_type One of the allowed advertising types: - * @arg @ref ADV_SCAN_IND : Scannable undirected advertising - * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising - * @param own_address_type If Privacy is disabled, then the peripheral address can be - * @arg @ref PUBLIC_ADDR. - * @arg @ref STATIC_RANDOM_ADDR. - * If Privacy is enabled, then the peripheral address can be - * @arg @ref RESOLVABLE_PRIVATE_ADDR - * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type); -/** - * @brief Put the device into non-connectable mode. - * @param adv_type One of the allowed advertising types: - * @arg @ref ADV_SCAN_IND : Scannable undirected advertising - * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type); - -/** - * @brief Put the device into undirected connectable mode. - * @note If privacy is enabled in the device, a resolvable private address is generated and used - * as the advertiser's address. If not, the address of the type specified in own_addr_type - * is used for advertising. - * @param own_addr_type Type of our address used during advertising: - * if BLUENRG (IDB04A1) - * @arg @ref PUBLIC_ADDR. - * @arg @ref STATIC_RANDOM_ADDR. - * else if BLUENRG_MS (IDB05A1) - * If Privacy is disabled: - * @arg @ref PUBLIC_ADDR. - * @arg @ref STATIC_RANDOM_ADDR. - * If Privacy is enabled: - * @arg @ref RESOLVABLE_PRIVATE_ADDR - * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR - * @param adv_filter_policy Filter policy: - * @arg @ref NO_WHITE_LIST_USE - * @arg @ref WHITE_LIST_FOR_ALL - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy); - -/** - * @brief Send a slave security request to the master. - * @note This command has to be issued to notify the master of the security requirements of the slave. - * The master may encrypt the link, initiate the pairing procedure, or reject the request. - * @param conn_handle Connection handle - * @param bonding One of the bonding modes: - * @arg @ref BONDING - * @arg @ref NO_BONDING - * @param mitm_protection If MITM protection is required or not: - * @arg @ref MITM_PROTECTION_NOT_REQUIRED - * @arg @ref MITM_PROTECTION_REQUIRED - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection); - -/** - * @brief Update advertising data. - * @note This command can be used to update the advertising data for a particular AD type. - * If the AD type specified does not exist, then it is added to the advertising data. - * If the overall advertising data length is more than 31 octets after the update, then - * the command is rejected and the old data is retained. - * @param AdvLen Length of AdvData array - * @param AdvData Advertisement Data, formatted as specified in Bluetooth specification - * (Volume 3, Part C, 11), including data length. It can contain more than one AD type. - * Example - * @code - * tBleStatus ret; - * 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}; - * const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01}; - * - * ret = aci_gap_set_discoverable(ADV_IND, 0, 0, STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, - * 8, local_name, 3, serviceUUIDList, 0, 0); - * ret = aci_gap_update_adv_data(5, manuf_data); - * @endcode - * - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData); - -/** - * @brief Delete an AD Type - * @note This command can be used to delete the specified AD type from the advertisement data if - * present. - * @param ad_type One of the allowed AD types (see @ref AD_Types) - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_delete_ad_type(uint8_t ad_type); - -/** - * @brief Get the current security settings - * @note This command can be used to get the current security settings of the device. - * @param mitm_protection @arg 0: Not required - * @arg 1: Required - * @param bonding @arg 0: No bonding mode - * @arg 1: Bonding mode - * @param oob_data @arg 0: Data absent - * @arg 1: Data present - * @param passkey_required @arg 0: Not required - * @arg 1: Fixed pin is present which is being used - * @arg 2: Passkey required for pairing. An event will be generated - * when required. - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, - uint8_t* oob_data, uint8_t* passkey_required); - -/** - * @brief Add addresses of bonded devices into the controller's whitelist. - * @note The command will return an error if there are no devices in the database or if it was unable - * to add the device into the whitelist. - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_configure_whitelist(void); - -/** - * @brief Terminate a connection. - * @note A @ref EVT_DISCONN_COMPLETE event will be generated when the link is disconnected. - * @param conn_handle Connection handle - * @param reason Reason for requesting disconnection. The error code can be any of ones as specified - * for the disconnected command in the HCI specification (See @ref HCI_Error_codes). - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason); - -/** - * @brief Clear the security database. - * @note All the devices in the security database will be removed. - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_clear_security_database(void); - -/** - * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. - * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. - * @param conn_handle - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle); -/** - * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. - * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_allow_rebond_IDB04A1(void); - -/** - * @brief Start the limited discovery procedure. - * @note The controller is commanded to start active scanning. When this procedure is started, - * only the devices in limited discoverable mode are returned to the upper layers. - * The procedure is terminated when either the upper layers issue a command to terminate the - * procedure by issuing the command aci_gap_terminate_gap_procedure() with the procedure code - * set to @ref GAP_LIMITED_DISCOVERY_PROC 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_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. - * @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. - * For a number N, Time = N x 0.625 msec. - * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than - * or equal to Scan_Interval. The scan window should be a number in the range - * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. - * For a number N, Time = N x 0.625 msec. - * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). - * @param filterDuplicates Duplicate filtering enabled or not. - * @arg 0x00: Do not filter the duplicates - * @arg 0x01: Filter duplicates - * - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, - uint8_t own_address_type, uint8_t filterDuplicates); - -/** - * @brief Start the general discovery procedure. - * @note The controller is commanded to start active scanning. The procedure is terminated when - * either the upper layers issue a command to terminate the procedure by issuing the command - * aci_gap_terminate_gap_procedure() with the procedure code set to GAP_GENERAL_DISCOVERY_PROC - * 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. - * @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. - * For a number N, Time = N x 0.625 msec. - * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than - * or equal to Scan_Interval. The scan window should be a number in the range - * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. - * For a number N, Time = N x 0.625 msec. - * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). - * @param filterDuplicates Duplicate filtering enabled or not. - * @arg 0x00: Do not filter the duplicates - * @arg 0x01: Filter duplicates - * - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, - uint8_t own_address_type, uint8_t filterDuplicates); - -/** - * @brief Start the name discovery procedure. - * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter - * policy set to ignore whitelist and process connectable advertising packets only for the - * specified device. Once a connection is established, GATT procedure is started to read the - * device name characteristic. When the read is completed (successfully or unsuccessfully), - * a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is given to the upper layer. The event also - * contains the name of the device if the device name was read successfully. - * @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. - * For a number N, Time = N x 0.625 msec. - * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than - * or equal to Scan_Interval. The scan window should be a number in the range - * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. - * For a number N, Time = N x 0.625 msec. - * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). - * @param peer_bdaddr Address of the peer device with which a connection has to be established. - * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). - * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or - * equal to Conn_Interval_Max.\n - * Range: 0x0006 to 0x0C80\n - * Time = N x 1.25 msec\n - * Time Range: 7.5 msec to 4 seconds - * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or - * equal to Conn_Interval_Min.\n - * Range: 0x0006 to 0x0C80\n - * Time = N x 1.25 msec\n - * Time Range: 7.5 msec to 4 seconds - * @param conn_latency Slave latency for the connection in number of connection events.\n - * Range: 0x0000 to 0x01F4 - * @param supervision_timeout Supervision timeout for the LE Link.\n - * Range: 0x000A to 0x0C80\n - * Time = N x 10 msec\n - * Time Range: 100 msec to 32 seconds - * @param min_conn_length Minimum length of connection needed for the LE connection.\n - * Range: 0x0000 - 0xFFFF\n - * Time = N x 0.625 msec. - * @param max_conn_length Maximum length of connection needed for the LE connection.\n - * Range: 0x0000 - 0xFFFF\n - * Time = N x 0.625 msec. - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, - uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, - uint8_t own_bdaddr_type, uint16_t conn_min_interval, - uint16_t conn_max_interval, uint16_t conn_latency, - uint16_t supervision_timeout, uint16_t min_conn_length, - uint16_t max_conn_length); - -/** - * @brief Start the auto connection establishment procedure. - * @note The devices specified are added to the white list of the controller and a LE_Create_Connection - * call will be made to the controller by GAP with the initiator filter policy set to - * use whitelist to determine which advertiser to connect to. When a command is issued to - * terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the - * controller by GAP. - * The procedure is terminated when either a connection is successfully established with one of - * the specified devices in the white list or the procedure is explicitly terminated by issuing - * the command aci_gap_terminate_gap_procedure() with the procedure code set to - * @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. A @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with - * the procedure code set to @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. - * @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. - * For a number N, Time = N x 0.625 msec. - * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than - * or equal to Scan_Interval. The scan window should be a number in the range - * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. - * For a number N, Time = N x 0.625 msec. - * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). - * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or - * equal to Conn_Interval_Max.\n - * Range: 0x0006 to 0x0C80\n - * Time = N x 1.25 msec\n - * Time Range: 7.5 msec to 4 seconds - * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or - * equal to Conn_Interval_Min.\n - * Range: 0x0006 to 0x0C80\n - * Time = N x 1.25 msec\n - * Time Range: 7.5 msec to 4 seconds - * @param conn_latency Slave latency for the connection in number of connection events.\n - * Range: 0x0000 to 0x01F4 - * @param supervision_timeout Supervision timeout for the LE Link.\n - * Range: 0x000A to 0x0C80\n - * Time = N x 10 msec\n - * Time Range: 100 msec to 32 seconds - * @param min_conn_length Minimum length of connection needed for the LE connection.\n - * Range: 0x0000 - 0xFFFF\n - * Time = N x 0.625 msec. - * @param max_conn_length Maximum length of connection needed for the LE connection.\n - * Range: 0x0000 - 0xFFFF\n - * Time = N x 0.625 msec. - * @cond BLUENRG - * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address - * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n - * @param reconn_addr Reconnection address used if use_reconn_addr is 1. - * @endcond - * @param num_whitelist_entries Number of devices that have to be added to the whitelist. - * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The - * format of the addr_array should be: address type followed by address. - * Example: - * @code - * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, - * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; - * @endcode - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, - uint8_t own_bdaddr_type, uint16_t conn_min_interval, - uint16_t conn_max_interval, uint16_t conn_latency, - uint16_t supervision_timeout, uint16_t min_conn_length, - uint16_t max_conn_length, - uint8_t num_whitelist_entries, - const uint8_t *addr_array); -tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, - uint8_t own_bdaddr_type, uint16_t conn_min_interval, - uint16_t conn_max_interval, uint16_t conn_latency, - uint16_t supervision_timeout, uint16_t min_conn_length, - uint16_t max_conn_length, - uint8_t use_reconn_addr, - const tBDAddr reconn_addr, - uint8_t num_whitelist_entries, - const uint8_t *addr_array); - -/** - * @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. - * 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 - * issuing the command aci_gap_terminate_gap_procedure() with the procedure code set to - * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. On completion of the procedure a - * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated with the procedure code set to - * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. - * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) - * @param scan_interval 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. - * For a number N, Time = N x 0.625 msec. - * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than - * or equal to Scan_Interval. The scan window should be a number in the range - * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. - * For a number N, Time = N x 0.625 msec. - * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). - * @param filter_duplicates Duplicate filtering enabled or not. - * @arg 0x00: Do not filter the duplicates - * @arg 0x01: Filter duplicates - * @cond BLUENRG - * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address - * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n - * @param reconn_addr Reconnection address used if use_reconn_addr is 1. - * @endcond - * - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, - uint8_t own_address_type, uint8_t filter_duplicates); -tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, - uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr); - -/** - * @brief Start a selective connection establishment procedure. - * @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 - * 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. - * The procedure is terminated when a connection is established or the upper layer terminates - * the procedure by issuing the command aci_gap_terminate_gap_procedure with the procedure - * code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. - * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) - * @param scan_interval 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. - * For a number N, Time = N x 0.625 msec. - * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than - * or equal to Scan_Interval. The scan window should be a number in the range - * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. - * For a number N, Time = N x 0.625 msec. - * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). - * @param filter_duplicates Duplicate filtering enabled or not. - * @arg 0x00: Do not filter the duplicates - * @arg 0x01: Filter duplicates - * @param num_whitelist_entries Number of devices that have to be added to the whitelist. - * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The - * format of the addr_array should be: address type followed by address. - * Example: - * @code - * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, - * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; - * @endcode - * - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, - uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, - const uint8_t *addr_array); - -/** - * @brief Start the direct connection establishment procedure. - * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter - * policy set to ignore whitelist and process connectable advertising packets only for the - * specified device. The procedure can be terminated explicitly by the upper layer by issuing - * the command aci_gap_terminate_gap_procedure(). When a command is issued to terminate the - * procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller - * by GAP. - * On termination of the procedure, a @ref EVT_LE_CONN_COMPLETE event is returned. The procedure can - * be explicitly terminated by the upper layer by issuing the command - * aci_gap_terminate_gap_procedure() with the procedure_code set to @ref GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC. - * @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. - * For a number N, Time = N x 0.625 msec. - * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than - * or equal to Scan_Interval. The scan window should be a number in the range - * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. - * For a number N, Time = N x 0.625 msec. - * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). - * @param peer_bdaddr Address of the peer device with which a connection has to be established. - * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). - * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or - * equal to Conn_Interval_Max.\n - * Range: 0x0006 to 0x0C80\n - * Time = N x 1.25 msec\n - * Time Range: 7.5 msec to 4 seconds - * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or - * equal to Conn_Interval_Min.\n - * Range: 0x0006 to 0x0C80\n - * Time = N x 1.25 msec\n - * Time Range: 7.5 msec to 4 seconds - * @param conn_latency Slave latency for the connection in number of connection events.\n - * Range: 0x0000 to 0x01F4 - * @param supervision_timeout Supervision timeout for the LE Link.\n - * Range: 0x000A to 0x0C80\n - * Time = N x 10 msec\n - * Time Range: 100 msec to 32 seconds - * @param min_conn_length Minimum length of connection needed for the LE connection.\n - * Range: 0x0000 - 0xFFFF\n - * Time = N x 0.625 msec. - * @param max_conn_length Maximum length of connection needed for the LE connection.\n - * Range: 0x0000 - 0xFFFF\n - * Time = N x 0.625 msec. - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, - uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, - uint8_t own_bdaddr_type, uint16_t conn_min_interval, - uint16_t conn_max_interval, uint16_t conn_latency, - uint16_t supervision_timeout, uint16_t min_conn_length, - uint16_t max_conn_length); - -/** - * @brief Terminate the specified GATT 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. - */ -tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code); - -/** - * @brief Start the connection parameter update procedure. - * @note Allowed by the Central to update the connection parameter of the specified connection. - * A Link Layer Connection Update procedure is started on the controller. - * On completion of the procedure, a @ref EVT_LE_CONN_UPDATE_COMPLETE event is returned to - * the upper layer. - * @param conn_handle Handle of the connection for which the update procedure has to be started. - * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or - * equal to Conn_Interval_Max.\n - * Range: 0x0006 to 0x0C80\n - * Time = N x 1.25 msec\n - * Time Range: 7.5 msec to 4 seconds - * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or - * equal to Conn_Interval_Min.\n - * Range: 0x0006 to 0x0C80\n - * Time = N x 1.25 msec\n - * Time Range: 7.5 msec to 4 seconds - * @param conn_latency Slave latency for the connection in number of connection events.\n - * Range: 0x0000 to 0x01F4 - * @param supervision_timeout Supervision timeout for the LE Link.\n - * Range: 0x000A to 0x0C80\n - * Time = N x 10 msec\n - * Time Range: 100 msec to 32 seconds - * @param min_conn_length Minimum length of connection needed for the LE connection.\n - * Range: 0x0000 - 0xFFFF\n - * Time = N x 0.625 msec. - * @param max_conn_length Maximum length of connection needed for the LE connection.\n - * Range: 0x0000 - 0xFFFF\n - * Time = N x 0.625 msec. - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, - uint16_t conn_max_interval, uint16_t conn_latency, - uint16_t supervision_timeout, uint16_t min_conn_length, - uint16_t max_conn_length); - -/** - * @brief Send a pairing request. - * @note Send the SM pairing request to start a pairing process from a Central. The authentication - * requirements and IO capabilities should be set before issuing this command using - * aci_gap_set_io_capability() and aci_gap_set_auth_requirement(). - * A @ref EVT_BLUE_GAP_PAIRING_CMPLT event is returned after the pairing process is completed. - * @param conn_handle Handle of the connection for which the pairing request has to be sent. - * @param force_rebond @arg 0x00: Pairing request is sent only if the device has not previously bonded - * @arg 0x01: Pairing request will be sent even if the device was previously bonded - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond); - -/** - * @brief Resolve a private address. - * @note This command tries to resolve the address provided with the IRKs present in its database. If - * the address is resolved successfully with any one of the IRKs present in the database, it - * returns success. - * @param address Address to be resolved. - * @param[in] actual_address The public or static random address of the peer device, distributed during pairing phase. - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address); - -/** - * @brief Resolve a private address. - * @note This command tries to resolve the address provided with the IRKs present in its database. If - * the address is resolved successfully with any one of the IRKs present in the database, it - * returns success. - * @param address Address to be resolved. - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr private_address); - -/** - * @brief This command gets the list of bonded devices. - * @note It returns the number of addresses and the corresponding address types and values. - * Example: - * @code - * tBleStatus ret; - * uint8_t num_devices = 0; - * uint8_t device_list[12*7]; - * ret = aci_gap_get_bonded_devices(&num_devices, device_list, sizeof(device_list)); - * for(int i = 0; i < num_devices; i+=7){ - * uint8_t addr_type = device_list[i]; - * uint8_t addr = device_list[i+1]; - * printf("Type: %d, Addr: %02X%02X%02X%02X%02X%02X\n",addr_type,addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]); - * } - * @endcode - * - * @param[in] num_devices The number of bonded devices. - * @param[in] device_list List of addresses. It contains a sequence of [address type, address] pairs, where address - * type can be @ref PUBLIC_ADDR or @arg @ref STATIC_RANDOM_ADDR. - * @param device_list_size Maximum size of the device_list buffer used to return the device list. - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size); - -/** - * @brief Puts the device into broadcast mode - * @note A privacy enabled device uses either a resolvable private address or a non-resolvable private address - * as specified in the own_addr_type parameter of the command. - * @param adv_interv_min Minimum advertising interval. - * Range: 0x00A0 to 0x4000 - * Time = N * 0.625 msec - * Time Range: 100 ms to 10.24 sec - * @param adv_interv_max Maximum advertising interval. - * Range: 0x00A0 to 0x4000 - * Time = N * 0.625 msec - * Time Range: 100 ms to 10.24 sec - * @param adv_type One of the allowed advertising types: - * @arg @ref ADV_SCAN_IND Scannable undirected advertising - * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising - * @param own_address_type If Privacy is disabled, the broadcaster address can be - * @arg @ref PUBLIC_ADDR. - * @arg @ref STATIC_RANDOM_ADDR. - * If Privacy is enabled, then the broadcaster address can be - * @arg @ref RESOLVABLE_PRIVATE_ADDR - * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR - * @param adv_data_length Length of the advertising data in the advertising packet - * @param adv_data Advertising data used by the device while advertising - * @param num_whitelist_entries Number of devices to be added to whitelist - * @param addr_array It will contain the addresses that have to be added into the whitelist. The - * format of the addr_array should be: address type followed by address. - * Example: - * @code - * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, - * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; - * @endcode - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_set_broadcast_mode_IDB05A1(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, - uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, - const uint8_t *addr_array); - -/** - * @brief Starts an observation procedure, when the device is in Observer role. - * @note The host enables scanning in the controller. The advertising reports are sent to the upper layer - * using standard @ref EVT_LE_ADVERTISING_REPORT subevent in @ref EVT_LE_META_EVENT. See Bluetooth - * Core v4.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event. - * @param scan_interval 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 from 2.5 msec - * to 10240 msec. For a number N, Time = N * 0.625 msec. - * @param scan_window Amount of time for the duration of the LE scan. scan_window shall be less than or equal to scan_interval. - * The scan window should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec - * to 10240 msec. For a number N, Time = N * 0.625 msec. - * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) - * @param own_address_type If Privacy is disabled, then the scanner address can be - * @arg @ref PUBLIC_ADDR. - * @arg @ref STATIC_RANDOM_ADDR. - * If Privacy is enabled, then the scanner address can be - * @arg @ref RESOLVABLE_PRIVATE_ADDR - * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR - * @param filter_duplicates Duplicate filtering enabled or not. - * @arg 0x00: Do not filter the duplicates - * @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, - uint8_t own_address_type, uint8_t filter_duplicates); - -/** - * @brief The command finds whether a device is bonded. - * @note If the device is using a resolvable private address and it has been bonded, then the command will return - * BLE_STATUS_SUCCESS. - * @param peer_address_type The address type of the peer device - * @arg @ref PUBLIC_ADDR. - * @arg @ref RANDOM_ADDR. - * @param peer_address Address used by the peer device while advertising. - * @return Value indicating success or error code. - */ -tBleStatus aci_gap_is_device_bonded_IDB05A1(uint8_t peer_address_type, const tBDAddr peer_address); - - -/** - * @} - */ - -/** - * @defgroup GAP_Events GAP events - * @{ - */ - -/** - * This event is generated by the controller when the limited discoverable - * mode ends due to timeout (180 seconds). No parameters in the event. - */ -#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE (0x0400) - - -/** - * This event is generated when the pairing process has completed successfully - * or a pairing procedure timeout has occurred or the pairing has failed. - * This is to notify the application that we have paired with a remote device - * so that it can take further actions or to notify that a timeout has occurred - * so that the upper layer can decide to disconnect the link. See @ref _evt_gap_pairing_cmplt. - */ -#define EVT_BLUE_GAP_PAIRING_CMPLT (0x0401) -typedef __packed struct _evt_gap_pairing_cmplt{ - uint16_t conn_handle; /**< Connection handle on which the pairing procedure completed */ - /** - * 0x00: Pairing Success. Pairing with a remote device was successful\n - * 0x01: Pairing Timeout. The SMP timeout has elapsed and no further SMP commands will be processed until reconnection\n - * 0x02: Pairing Failed. The pairing failed with the remote device. - */ - uint8_t status; -} PACKED evt_gap_pairing_cmplt; - - -/** - * This event is generated by the Security manager to the application when a pass key is required for pairing. - * When this event is received, the application has to respond with the aci_gap_pass_key_response() command. - * See @ref _evt_gap_pass_key_req. - */ -#define EVT_BLUE_GAP_PASS_KEY_REQUEST (0x0402) -typedef __packed struct _evt_gap_pass_key_req{ - uint16_t conn_handle; /**< Connection handle for which the passkey has been requested. */ -} PACKED evt_gap_pass_key_req; - - -/** - * This event is generated by the Security manager to the application when the application - * has set that authorization is required for reading/writing of attributes. This event will - * be generated as soon as the pairing is complete. When this event is received, - * aci_gap_authorization_response() command should be used by the application. - * See @ref _evt_gap_author_req. - */ -#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST (0x0403) -typedef __packed struct _evt_gap_author_req{ - uint16_t conn_handle; /**< Connection handle for which authorization has been requested. */ -} PACKED evt_gap_author_req; - -/** - * This event is generated when the slave security request is successfully sent to the master. - * No parameters for this event. - */ -#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED (0X0404) - -/** - * This event is generated when a pairing request is issued in response to a slave security - * request from a master which has previously bonded with the slave. When this event is received, - * the upper layer has to issue the command aci_gap_allow_rebond() in order to allow the slave - * to continue the pairing process with the master. No parameters for this event - */ -#define EVT_BLUE_GAP_BOND_LOST (0X0405) - -/** - * The event is given by the GAP layer to the upper layers when a device is discovered during scanning - * as a consequence of one of the GAP procedures started by the upper layers. See @ref _evt_gap_device_found. - */ -#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406) -typedef __packed struct _evt_gap_device_found{ - uint8_t evt_type; /**< Type of event (@ref ADV_IND, @ref ADV_DIRECT_IND, @ref ADV_SCAN_IND, @ref ADV_NONCONN_IND, @ref SCAN_RSP) */ - uint8_t bdaddr_type; /**< Type of the peer address (@ref PUBLIC_ADDR, @ref RANDOM_ADDR). */ - tBDAddr bdaddr; /**< Address of the peer device found during scanning. */ - uint8_t data_length; /**< Length of advertising or scan response data. */ - uint8_t data_RSSI[VARIABLE_SIZE]; /**< Advertising or scan response data + RSSI. RSSI is last octect (signed integer). */ -} PACKED evt_gap_device_found; - -/** - * This event is sent by the GAP to the upper layers when a procedure previously started has been terminated - * by the upper layer or has completed for any other reason. See @ref _evt_gap_procedure_complete. - */ -#define EVT_BLUE_GAP_PROCEDURE_COMPLETE (0x0407) -typedef __packed struct _evt_gap_procedure_complete{ - uint8_t procedure_code; /**< Terminated procedure. See @ref gap_procedure_codes "GAP procedure codes". */ - /** - * @ref BLE_STATUS_SUCCESS, @ref BLE_STATUS_FAILED or @ref ERR_AUTH_FAILURE (procedure failed - * due to authentication requirements). - */ - uint8_t status; - /** - * Procedure specific data.\n - * @li For Name Discovery Procedure:\n - * the name of the peer device if the procedure completed successfully. - * @li For General Connection Establishment Procedure:\n - * The reconnection address written to the peripheral device if the peripheral is privacy enabled - */ - uint8_t data[VARIABLE_SIZE]; -} PACKED evt_gap_procedure_complete; - -/** - * This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral - * is not able to resolve the private address of the peer device after connecting to it. - */ -#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_IDB05A1 (0x0408) -typedef __packed struct _evt_gap_addr_not_resolved_IDB05A1{ - uint16_t conn_handle; /**< Connection handle for which the private address could not be resolved with any of the stored IRK's. */ -} PACKED evt_gap_addr_not_resolved_IDB05A1; -/** - * This event is raised when the reconnection address is generated during the general connection - * establishment procedure. The same address is set into the peer device also as a part of the general - * connection establishment procedure. In order to make use of the reconnection address the next time - * while connecting to the bonded peripheral, the application needs to use this reconnection address - * as its own address as well as the peer address to which it wants to connect. See aci_gap_start_general_conn_establish_proc() - * and aci_gap_start_auto_conn_establish_proc(). - */ -#define EVT_BLUE_GAP_RECONNECTION_ADDRESS_IDB04A1 (0x0408) -typedef __packed struct _evt_gap_reconnection_addr_IDB04A1{ - uint8_t reconnection_address[6]; /**< 6 bytes of reconnection address that has been generated */ -} PACKED evt_gap_reconnection_addr_IDB04A1; - -/** - * @} - */ - -/** - * @} - */ - - -#endif /* __BLUENRG_GAP_ACI_H__ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_gatt_aci.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1045 +0,0 @@ -/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** -* File Name : bluenrg_gatt_aci.h -* Author : AMS - AAS -* Version : V1.0.0 -* Date : 26-Jun-2014 -* Description : Header file with GATT commands for BlueNRG FW6.3. -******************************************************************************** -* 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. -*******************************************************************************/ - -#ifndef __BLUENRG_GATT_ACI_H__ -#define __BLUENRG_GATT_ACI_H__ - -#include "bluenrg_gatt_server.h" - -/** - *@addtogroup GATT GATT - *@brief GATT layer. - *@{ - */ - -/** - *@defgroup GATT_Functions GATT functions - *@brief API for GATT layer. - *@{ - */ - -/** - * @brief Initialize the GATT layer for server and client roles. - * @note It adds also the GATT service with Service Changed Characteristic. - * Until this command is issued the GATT channel will not process any commands - * even if the connection is opened. This command has to be given - * before using any of the GAP features. - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_init(void); - -/** - * @brief Add a service to the GATT Server. When a service is created in the server, the Host needs - * to reserve the handle ranges for this service using max_attr_records parameter. This - * parameter specifies the maximum number of attribute records that can be added to this - * service (including the service attribute, include attribute, characteristic attribute, - * characteristic value attribute and characteristic descriptor attribute). Handle of the - * created service is returned. - * @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 - * @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 - * <serviceHandle + max_attr_records>. - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, - const uint8_t* service_uuid, - uint8_t service_type, - uint8_t max_attr_records, - uint16_t *serviceHandle); - -/** - * @brief Include a service given by included_start_handle and included_end_handle to another service - * given by service_handle. Attribute server creates an INCLUDE definition attribute and return - * the handle of this attribute in included_handle. - * @param service_handle Handle of the service to which another service has to be included - * @param included_start_handle Start Handle of the service which has to be included in service - * @param included_end_handle End Handle of the service which has to be included in service - * @param included_uuid_type Type of UUID for included service (16-bit or 128-bit). See @ref Well-Known_UUIDs "Well-Known UUIDs". - * @param[in] included_uuid 16-bit or 128-bit UUID. - * @param[out] included_handle Handle of the include declaration. - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, - uint16_t included_end_handle, uint8_t included_uuid_type, - const uint8_t* included_uuid, uint16_t *included_handle); - -/** - * @brief Add a characteristic to a service. - * @param serviceHandle Handle of the service to which the characteristic has to be added. - * @param charUuidType Type of characteristic UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". - * @arg @ref UUID_TYPE_16 - * @arg @ref UUID_TYPE_128 - * @param charUuid 16-bit or 128-bit UUID. - * @param charValueLen Maximum length of the characteristic value. - * @param charProperties Bitwise OR values of Characteristic Properties (defined in Volume 3, - * Section 3.3.3.1 of Bluetooth Specification 4.0). See @ref Char_properties "Characteristic properties". - * @param secPermissions Security permissions for the added characteristic. See @ref Security_permissions "Security permissions". - * @arg ATTR_PERMISSION_NONE - * @arg ATTR_PERMISSION_AUTHEN_READ - * @arg ATTR_PERMISSION_AUTHOR_READ - * @arg ATTR_PERMISSION_ENCRY_READ - * @arg ATTR_PERMISSION_AUTHEN_WRITE - * @arg ATTR_PERMISSION_AUTHOR_WRITE - * @arg ATTR_PERMISSION_ENCRY_WRITE - * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server - * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". - * @arg GATT_DONT_NOTIFY_EVENTS - * @arg GATT_NOTIFY_ATTRIBUTE_WRITE - * @arg GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP - * @arg GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP - * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. - * @param isVariable If the attribute has a variable length value field (1) or not (0). - * @param charHandle Handle of the Characteristic that has been added. It is the handle of the characteristic declaration. - * The attribute that holds the characteristic value is allocated at the next handle, followed by the Client - * Characteristic Configuration descriptor if the characteristic has @ref CHAR_PROP_NOTIFY or @ref CHAR_PROP_INDICATE - * properties. - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_add_char(uint16_t serviceHandle, - uint8_t charUuidType, - const uint8_t* charUuid, - uint8_t charValueLen, - uint8_t charProperties, - uint8_t secPermissions, - uint8_t gattEvtMask, - uint8_t encryKeySize, - uint8_t isVariable, - uint16_t* charHandle); - -/** - * Add a characteristic descriptor to a service. - * @param serviceHandle Handle of the service to which the characteristic belongs - * @param charHandle Handle of the characteristic to which description has to be added. - * @param descUuidType 16-bit or 128-bit UUID. See @ref UUID_Types "UUID Types". - * @arg @ref UUID_TYPE_16 - * @arg @ref UUID_TYPE_128 - * @param[in] uuid UUID of the Characteristic descriptor. It can be one of the UUID assigned by Bluetooth SIG - * (Well_known_UUIDs) or a user-defined one. - * @param descValueMaxLen The maximum length of the descriptor value - * @param descValueLen Current Length of the characteristic descriptor value - * @param[in] descValue Value of the characteristic description - * @param secPermissions Security permissions for the added descriptor. See @ref Security_permissions "Security permissions". - * @arg ATTR_PERMISSION_NONE - * @arg ATTR_PERMISSION_AUTHEN_READ - * @arg ATTR_PERMISSION_AUTHOR_READ - * @arg ATTR_PERMISSION_ENCRY_READ - * @arg ATTR_PERMISSION_AUTHEN_WRITE - * @arg ATTR_PERMISSION_AUTHOR_WRITE - * @arg ATTR_PERMISSION_ENCRY_WRITE - * @param accPermissions Access permissions for the added descriptor. See @ref Access_permissions "Access permissions". - * @arg ATTR_NO_ACCESS - * @arg ATTR_ACCESS_READ_ONLY - * @arg ATTR_ACCESS_WRITE_REQ_ONLY - * @arg ATTR_ACCESS_READ_WRITE - * @arg ATTR_ACCESS_WRITE_WITHOUT_RESPONSE - * @arg ATTR_ACCESS_SIGNED_WRITE_ALLOWED - * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server - * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". - * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. - * @param isVariable If the attribute has a variable length value field (1) or not (0). - * @param[out] descHandle Handle of the Characteristic Descriptor. - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, - uint16_t charHandle, - uint8_t descUuidType, - const uint8_t* uuid, - uint8_t descValueMaxLen, - uint8_t descValueLen, - const void* descValue, - uint8_t secPermissions, - uint8_t accPermissions, - uint8_t gattEvtMask, - uint8_t encryKeySize, - uint8_t isVariable, - uint16_t* descHandle); - -/** - * @brief Update a characteristic value in a service. - * @note 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. The command is queued into the - * BlueNRG command queue. If the buffer is full, because previous commands could not be still processed, - * the function will return @ref BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or - * indications) are enabled and the application calls aci_gatt_update_char_value() at an higher rate - * than what is allowed by the link. Throughput on BLE link depends on connection interval and - * connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request() - * for more info on how to suggest new connection parameters from a slave). If the application does not - * want to lose notifications because BlueNRG buffer becomes full, it has to retry again till the function - * returns @ref BLE_STATUS_SUCCESS or any other error code.\n - * Example:\n - * Here if BlueNRG buffer become full because BlueNRG was not able to send packets for a while, some - * notifications will be lost. - * @code - * tBleStatus Free_Fall_Notify(void) - * { - * uint8_t val; - * tBleStatus ret; - * - * val = 0x01; - * ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, &val); - * - * if (ret != BLE_STATUS_SUCCESS){ - * PRINTF("Error while updating ACC characteristic.\n") ; - * return BLE_STATUS_ERROR ; - * } - * return BLE_STATUS_SUCCESS; - * } - * @endcode - * Here if BlueNRG buffer become full, the application try again to send the notification. - * @code - * struct timer t; - * Timer_Set(&t, CLOCK_SECOND*10); - * while(aci_gatt_update_char_value(chatServHandle,TXCharHandle,0,len,array_val)==BLE_STATUS_INSUFFICIENT_RESOURCES){ - * // Radio is busy (buffer full). - * if(Timer_Expired(&t)) - * break; - * } - * @endcode - * - * @param servHandle Handle of the service to which characteristic belongs - * @param charHandle Handle of the characteristic - * @param charValOffset The offset from which the attribute value has to be updated. If this is set to 0, - * and the attribute value is of variable length, then the length of the attribute will - * be set to the charValueLen. If the charValOffset is set to a value greater than 0, - * then the length of the attribute will be set to the maximum length as specified for - * the attribute while adding the characteristic. - * @param charValueLen Length of the characteristic value in octets - * @param[in] charValue Characteristic value - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_update_char_value(uint16_t servHandle, - uint16_t charHandle, - uint8_t charValOffset, - uint8_t charValueLen, - const uint8_t *charValue); -/** - * @brief Delete the specified characteristic from the service. - * @param servHandle Handle of the service to which characteristic belongs - * @param charHandle Handle of the characteristic to be deleted - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle); - -/** - * @brief Delete the specified service from the GATT server database. - * @param servHandle Handle of the service to be deleted - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_del_service(uint16_t servHandle); - -/** - * @brief Delete the Include definition from the service. - * @param servHandle Handle of the service to which Include definition belongs - * @param includeServHandle Handle of the Included definition to be deleted - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle); - -/** - * @brief Perform an ATT MTU exchange procedure. - * @note When the ATT MTU exchange procedure is completed, a @ref EVT_BLUE_ATT_EXCHANGE_MTU_RESP - * event is generated. A @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is also generated - * to indicate the end of the procedure. - * @param conn_handle Connection handle for which the command is given. - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle); - -/** - * @brief Send a @a Find @a Information @a Request. - * @note This command is used to obtain the mapping of attribute handles with their associated - * types. The responses of the procedure are given through the - * @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. The end of the procedure is indicated by - * a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. - * @param conn_handle Connection handle for which the command is given - * @param start_handle Starting handle of the range of attributes to be discovered on the server - * @param end_handle Ending handle of the range of attributes to be discovered on the server - * @return Value indicating success or error code. - */ -tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle); - -/** - * @brief Send a @a Find @a By @a Type @a Value @a Request - * @note The Find By Type Value Request is used to obtain the handles of attributes that - * have a given 16-bit UUID attribute type and a given attribute value. - * The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. - * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. - * @param conn_handle Connection handle for which the command is given. - * @param start_handle First requested handle number - * @param end_handle Last requested handle number - * @param uuid 2 octet UUID to find (little-endian) - * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 7). - * @param attr_val Attribute value to find - * @return Value indicating success or error code. - */ -tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, - uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val); - -/** - * @brief Send a @a Read @a By @a Type @a Request - * @note The Read By Type Request is used to obtain the values of attributes where the attribute type - * is known but the handle is not known. - * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. - * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. - * @param conn_handle Connection handle for which the command is given. - * @param start_handle First requested handle number - * @param end_handle Last requested handle number - * @param uuid_type @arg @ref UUID_TYPE_16 - * @arg @ref UUID_TYPE_128 - * @param uuid 2 or 16 octet UUID - * @return Value indicating success or error code. - */ -tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, - uint8_t uuid_type, uint8_t* uuid); - -/** - * @brief Send a @a Read @a By @a Group @a Type @a Request - * @note The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute - * type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping - * attribute types are: «Primary Service», «Secondary Service» and «Characteristic». - * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. - * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. - * @param conn_handle Connection handle for which the command is given. - * @param start_handle First requested handle number - * @param end_handle Last requested handle number - * @param uuid_type @arg @ref UUID_TYPE_16 - * @arg @ref UUID_TYPE_128 - * @param uuid 2 or 16 octet UUID - * @return Value indicating success or error code. - */ -tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, - uint8_t uuid_type, uint8_t* uuid); - -/** - * @brief Send a @a Prepare @a Write @a Request - * @note The Prepare Write Request is used to request the server to prepare to write the value of an attribute. - * The responses of the procedure are given through the @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP event. - * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. - * @param conn_handle Connection handle for which the command is given. - * @param attr_handle The handle of the attribute to be written - * @param value_offset The offset of the first octet to be written - * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 5). - * @param attr_val The value of the attribute to be written - * @return Value indicating success or error code. - */ -tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, - uint8_t attr_val_len, uint8_t* attr_val); - -/** - * @brief Send an @a Execute @a Write @a Request - * @note The Execute Write Request is used to request the server to write or cancel the write of all the - * prepared values currently held in the prepare queue from this client. - * The result of the procedure is given through the @ref EVT_BLUE_ATT_EXEC_WRITE_RESP event. - * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. - * @param conn_handle Connection handle for which the command is given. - * @param execute @arg 0x00 Cancel all prepared writes - * @arg 0x01 Immediately write all pending prepared values. - * @return Value indicating success or error code. - */ -tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute); - -/** - * @brief This command will start the GATT client procedure to discover all primary services on the server. - * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. - * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. - * @param conn_handle Connection handle for which the command is given. - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle); - -/** - * @brief Start the procedure to discover the primary services of the specified UUID on the server. - * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. - * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. - * @param conn_handle Connection handle for which the command is given. - * @param uuid_type @arg @ref UUID_TYPE_16 - * @arg @ref UUID_TYPE_128 - * @param uuid 2 or 16 octet UUID - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid); - -/** - * @brief Start the procedure to find all included services. - * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. - * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. - * @param conn_handle Connection handle for which the command is given. - * @param start_handle Start handle of the service - * @param end_handle End handle of the service - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle, - uint16_t end_handle); - -/** - * @brief Start the procedure to discover all the characteristics of a given service. - * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. - * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. - * @param conn_handle Connection handle for which the command is given - * @param start_attr_handle Start attribute handle of the service - * @param end_attr_handle End attribute handle of the service - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, - uint16_t end_attr_handle); - -/** - * @brief Start the procedure to discover all the characteristics specified by a UUID. - * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. - * Before procedure completion the response packets are given through - * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. - * @param conn_handle Connection handle for which the command is given - * @param start_handle Start attribute handle of the service - * @param end_handle End attribute handle of the service - * @param uuid_type @arg @ref UUID_TYPE_16 - * @arg @ref UUID_TYPE_128 - * @param uuid 2 or 16 octet UUID - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, - uint16_t end_handle, uint8_t uuid_type, const uint8_t* uuid); - -/** - * @brief Start the procedure to discover all characteristic descriptors on the server. - * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. - * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. - * @param conn_handle Connection handle for which the command is given. - * @param char_val_handle Starting handle of the characteristic - * @param char_end_handle End handle of the characteristic - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, - uint16_t char_end_handle); - -/** - * @brief Start the procedure to read the attribute value. - * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. - * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. - * @param conn_handle Connection handle for which the command is given - * @param attr_handle Handle of the characteristic to be read - * @return Value indicating success or error code.\n - * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n - * - If the exchange has already taken place\n - * - If GATT is expecting response for previous request\n - * - Already a request is in the queue to be sent\n - * - Channel not open\n - * - Already one GATT procedure is started - */ -tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle); - -/** - * @brief Start the procedure to read all the characteristics specified by the UUID. - * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. - * Before procedure completion the response packets are given through - * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. - * @param conn_handle Connection handle for which the command is given - * @param start_handle Starting handle of the range to be searched - * @param end_handle End handle of the range to be searched - * @param uuid_type @arg @ref UUID_TYPE_16 - * @arg @ref UUID_TYPE_128 - * @param uuid 2 or 16 octet UUID - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, - uint8_t uuid_type, uint8_t* uuid); - -/** - * @brief Start the procedure to read a long characteristic value. - * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. - * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP event. - * @param conn_handle Connection handle for which the command is given - * @param attr_handle Handle of the characteristic to be read - * @param val_offset Offset from which the value needs to be read - * @return Value indicating success or error code.\n - * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n - * - If the exchange has already taken place\n - * - If GATT is expecting response for previous request\n - * - Already a request is in the queue to be sent\n - * - Channel not open\n - * - Already one GATT procedure is started - */ -tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, - uint16_t val_offset); - -/** - * @brief Start a procedure to read multiple characteristic values from a server. - * @note This sub-procedure is used to read multiple Characteristic Values from a server when the - * client knows the Characteristic Value Handles. - * When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. - * Before procedure completion the response packets are given through - * @ref EVT_BLUE_ATT_READ_MULTIPLE_RESP event. - * @param conn_handle Connection handle for which the command is given - * @param num_handles The number of handles for which the value has to be read - * @param set_of_handles The handles for which the attribute value has to be read - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, - uint8_t* set_of_handles); - -/** - * @brief Start the procedure to write a characteristic value. - * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. - * @param conn_handle Connection handle for which the command is given - * @param attr_handle Handle of the characteristic to be written - * @param value_len Length of the value to be written - * @param[in] attr_value Value to be written - * @return Value indicating success or error code.\n - * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n - * - If the exchange has already taken place\n - * - If GATT is expecting response for previous request\n - * - Already a request is in the queue to be sent\n - * - Channel not open\n - * - Already one GATT procedure is started - */ -tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, - uint8_t value_len, uint8_t *attr_value); - -/** - * @brief Start the procedure to write a long characteristic value. - * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. - * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP - * events are raised. - * @param conn_handle Connection handle for which the command is given - * @param attr_handle Handle of the attribute to be written - * @param val_offset Offset at which the attribute has to be written - * @param val_len Length of the value to be written - * @param attr_val Value to be written - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, - uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val); - -/** - * @brief Start the procedure to write a characteristic reliably. - * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. - * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP - * events are raised. - * @param conn_handle Connection handle for which the command is given - * @param attr_handle Handle of the attribute to be written - * @param val_offset Offset at which the attribute has to be written - * @param val_len Length of the value to be written - * @param attr_val Value to be written - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, - uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); - -/** - * @brief Start the procedure to write a long characteristic descriptor. - * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. - * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP - * events are raised. - * @param conn_handle Connection handle for which the command is given - * @param attr_handle Handle of the attribute to be written - * @param val_offset Offset at which the attribute has to be written - * @param val_len Length of the value to be written - * @param attr_val Value to be written - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, - uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); - -/** - * @brief Start the procedure to read a long characteristic value. - * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. - * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP - * event. - * @param conn_handle Connection handle for which the command is given - * @param attr_handle Handle of the characteristic descriptor - * @param val_offset Offset from which the value needs to be read - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, - uint16_t val_offset); - -/** - * @brief Start the procedure to write a characteristic descriptor. - * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. - * @param conn_handle Connection handle for which the command is given - * @param attr_handle Handle of the attribute to be written - * @param value_len Length of the value to be written - * @param[in] attr_value Value to be written - * @return Value indicating success or error code.\n - * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n - * - If the exchange has already taken place\n - * - If GATT is expecting response for previous request\n - * - Already a request is in the queue to be sent\n - * - Channel not open\n - * - Already one GATT procedure is started - */ -tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, - uint8_t value_len, uint8_t *attr_value); - -/** - * @brief Start the procedure to read the descriptor specified. - * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. - * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. - * @param conn_handle Connection handle for which the command is given - * @param attr_handle Handle of the descriptor to be read - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle); - -/** - * @brief Start the procedure to write a characteristic value without waiting for any response from the server. - * @note No events are generated after this command is executed. - * @param conn_handle Connection handle for which the command is given - * @param attr_handle Handle of the attribute to be written - * @param val_len Length of the value to be written (up to ATT_MTU - 3) - * @param[in] attr_val Value to be written - * @return Value indicating success or error code.\n - * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n - * - If the exchange has already taken place\n - * - If GATT is expecting response for previous request\n - * - Already a request is in the queue to be sent\n - * - Channel not open\n - * - Already one GATT procedure is started - */ -tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, - uint8_t val_len, const uint8_t* attr_val); - -/** - * @brief Start a signed write without response from the server. - * @note The procedure i used to write a characteristic value with an authentication signature without waiting - * for any response from the server. It cannot be used when the link is encrypted. - * @param conn_handle Connection handle for which the command is given - * @param attr_handle Handle of the attribute to be written - * @param val_len Length of the value to be written (up to ATT_MTU - 13). - * @param attr_val Value to be written - * @return Value indicating success or error code - */ -tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, - uint8_t val_len, uint8_t* attr_val); - -/** - * @brief Confirm an indication - * @note This command has to be sent when the application receives the event @ref EVT_BLUE_GATT_INDICATION. - * @param conn_handle Connection handle for which the command is given. - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle); - -/** - * @brief Allow or reject a write request from a client. - * @note This command has to be sent by the application when it receives the @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. - * If the write is allowed, then the status and error code has to be set to 0. If the write is not allowed, - * then the status has to be set to 1 and the error code has to be set to the error code that has to be - * passed to the client. - * @param conn_handle Connection handle for which the command is given - * @param attr_handle Handle of the attribute that was passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. - * @param write_status 0x00: The value can be written to the attribute specified by attr_handle\n - * 0x01: The value cannot be written to the attribute specified by the attr_handle. - * @param err_code The error code that has to be passed to the client in case the write has to be rejected. - * @param att_val_len Length of the value to be written as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. - * @param att_val Value as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_write_response(uint16_t conn_handle, - uint16_t attr_handle, - uint8_t write_status, - uint8_t err_code, - uint8_t att_val_len, - uint8_t *att_val); - -/** - * @brief Allow the GATT server to send a response to a read request from a client. - * @note The application has to send this command when it receives the @ref EVT_BLUE_GATT_READ_PERMIT_REQ - * or @ref EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ. This command indicates to the stack that the response - * can be sent to the client. So if the application wishes to update any of the attributes before - * they are read by the client, it has to update the characteristic values using the aci_gatt_update_char_value - * and then give this command. The application should perform the required operations within 30 seconds, - * otherwise the GATT procedure will go to timeout. - * @param conn_handle Connection handle for which the command is given. - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_allow_read(uint16_t conn_handle); - -/** - * @brief Set the security permission for the attribute handle specified. - * @note Currently the setting of security permission is allowed only for client configuration descriptor. - * @param service_handle Handle of the service which contains the attribute whose security - * permission has to be modified. - * @param attr_handle Handle of the attribute whose security permission has to be modified. - * @param security_permission Security permissions for the descriptor. See @ref Security_permissions "Security permissions". - * @arg ATTR_PERMISSION_NONE - * @arg ATTR_PERMISSION_AUTHEN_READ - * @arg ATTR_PERMISSION_AUTHOR_READ - * @arg ATTR_PERMISSION_ENCRY_READ - * @arg ATTR_PERMISSION_AUTHEN_WRITE - * @arg ATTR_PERMISSION_AUTHOR_WRITE - * @arg ATTR_PERMISSION_ENCRY_WRITE - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, - uint8_t security_permission); - -/** - * @brief This command sets the value of the descriptor specified by charDescHandle. - * @param servHandle Handle of the service which contains the descriptor. - * @param charHandle Handle of the characteristic which contains the descriptor. - * @param charDescHandle Handle of the descriptor whose value has to be set. - * @param charDescValOffset Offset from which the descriptor value has to be updated. - * @param charDescValueLen Length of the descriptor value - * @param[in] charDescValue descriptor value - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, - uint16_t charHandle, - uint16_t charDescHandle, - uint16_t charDescValOffset, - uint8_t charDescValueLen, - const uint8_t *charDescValue); - -/** - * @brief Reads the value of the attribute handle specified from the local GATT database. - * @param attr_handle Handle of the attribute to read - * @param data_len Length of the data buffer. - * @param[in] data_len_out_p Length of the read attribute. - * @param[in] data Pointer to the buffer that will contain the read value. - * The buffer will be filled with the attribute value. - * The length will be the minimum between the provided data_len and the actual length of the - * attribute (in data_len_out_p). - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); - - /** - * @brief Reads the value of the attribute handle specified from the local GATT database, starting from a given offset. - * @param attr_handle Handle of the attribute to read - * @param offset Offset from which the value needs to be read - * @param data_len Length of the data buffer. - * @param[in] data_len_out_p Length of the read attribute. - * @param[in] data Pointer to the buffer that will contain the read value. - * The buffer will be filled with the attribute value. - * The length will be the minimum between the provided data_len and the actual length of the - * attribute (in data_len_out_p). - * @return Value indicating success or error code. - */ -tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); - -/** - * @} - */ - - -/** - * @defgroup GATT_Events GATT events - * The structures are the data field of @ref evt_blue_aci. - * @{ - */ - -/** - * This event is raised to the application by the GATT server when a client modifies any attribute on the server, - * if event is enabled (see @ref Gatt_Event_Mask "Gatt Event Mask"). - * See @ref _evt_gatt_attr_modified_IDB04A1 or @ref _evt_gatt_attr_modified__IDB05A1. - */ -#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED (0x0C01) -typedef __packed struct _evt_gatt_attr_modified_IDB05A1{ - uint16_t conn_handle; /**< The connection handle which modified the attribute. */ - uint16_t attr_handle; /**< Handle of the attribute that was modified. */ - uint8_t data_length; /**< The length of the data */ - uint16_t offset; /**< Offset from which the write has been performed by the peer device */ - uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ -} PACKED evt_gatt_attr_modified_IDB05A1; - -typedef __packed struct _evt_gatt_attr_modified_IDB04A1{ - uint16_t conn_handle; /**< The connection handle which modified the attribute. */ - uint16_t attr_handle; /**< Handle of the attribute that was modified. */ - uint8_t data_length; /**< The length of the data */ - uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ -} PACKED evt_gatt_attr_modified_IDB04A1; - -/** - * This event is generated by the client/server to the application on a GATT timeout (30 seconds). - * See @ref _evt_gatt_procedure_timeout. - */ -#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT (0x0C02) -typedef __packed struct _evt_gatt_procedure_timeout{ - uint16_t conn_handle; /**< The connection handle on which the GATT procedure has timed out */ -} PACKED evt_gatt_procedure_timeout; - -/** - * This event is generated in response to an Exchange MTU request. See aci_gatt_exchange_configuration(). - * See @ref _evt_att_exchange_mtu_resp. - */ -#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP (0x0C03) -typedef __packed struct _evt_att_exchange_mtu_resp{ - uint16_t conn_handle; /**< The connection handle related to the response */ - uint8_t event_data_length; /**< Length of following data (always 1). */ - uint16_t server_rx_mtu; /**< Attribute server receive MTU size */ -} PACKED evt_att_exchange_mtu_resp; - -/** - * This event is generated in response to a @a Find @a Information @a Request. See aci_att_find_information_req() and - * Find Information Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_information_resp. - */ -#define EVT_BLUE_ATT_FIND_INFORMATION_RESP (0x0C04) -typedef __packed struct _evt_att_find_information_resp{ - uint16_t conn_handle; /**< The connection handle related to the response */ - uint8_t event_data_length; /**< Length of following data. */ - uint8_t format; /**< The format of the handle_uuid_pair. @arg 1: 16-bit UUIDs @arg 2: 128-bit UUIDs */ - /** - * A sequence of handle-uuid pairs.\n - * @li if format=1, each pair is:\n - * [2 octets for handle, 2 octets for UUIDs] \n - * @li if format=2, each pair is:\n - * [2 octets for handle, 16 octets for UUIDs] - */ - uint8_t handle_uuid_pair[VARIABLE_SIZE]; -} PACKED evt_att_find_information_resp; - -/** - * This event is generated in response to a @a Find @a By @a Type @a Value @a Request. See - * Find By Type Value Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_by_type_val_resp. - */ -#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP (0x0C05) -typedef __packed struct _evt_att_find_by_type_val_resp{ - uint16_t conn_handle; /**< The connection handle related to the response */ - uint8_t event_data_length; /**< Length of following data. */ - /** - * Handles Information List as defined in Bluetooth Core v4.0 spec. - * A sequence of handle pairs: [2 octets for Found Attribute Handle, 2 octets for Group End Handle] - */ - uint8_t handles_info_list[VARIABLE_SIZE]; -} PACKED evt_att_find_by_type_val_resp; - -/** - * This event is generated in response to a @a Read @a By @a Type @a Request. See aci_gatt_find_included_services() and - * aci_gatt_disc_all_charac_of_serv(). - * For more info see Read By Type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_type_resp. - */ -#define EVT_BLUE_ATT_READ_BY_TYPE_RESP (0x0C06) -typedef __packed struct _evt_att_read_by_type_resp{ - uint16_t conn_handle; /**< The connection handle related to the response */ - uint8_t event_data_length; /**< Length of following data. */ - uint8_t handle_value_pair_length; /**< The size of each attribute handle-value pair */ - /** - * Attribute Data List as defined in Bluetooth Core v4.0 spec. - * A sequence of handle-value pairs: [2 octets for Attribute Handle, (handle_value_pair_length - 2 octets) for Attribute Value] - */ - uint8_t handle_value_pair[VARIABLE_SIZE]; -} PACKED evt_att_read_by_type_resp; - -/** - * This event is generated in response to a @a Read @a Request. See aci_gatt_read_charac_val(). - * For more info see Read Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_resp. - */ -#define EVT_BLUE_ATT_READ_RESP (0x0C07) -typedef __packed struct _evt_att_read_resp{ - uint16_t conn_handle; /**< The connection handle related to the response. */ - uint8_t event_data_length; /**< Length of following data. */ - uint8_t attribute_value[VARIABLE_SIZE]; /**< The value of the attribute. */ -} PACKED evt_att_read_resp; - -/** - * This event is generated in response to a @a Read @a Blob @a Request. See aci_gatt_read_long_charac_val(). - * For more info see Read Blob Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_blob_resp. - */ -#define EVT_BLUE_ATT_READ_BLOB_RESP (0x0C08) -typedef __packed struct _evt_att_read_blob_resp{ - uint16_t conn_handle; /**< The connection handle related to the response. */ - uint8_t event_data_length; /**< Length of following data. */ - uint8_t part_attribute_value[VARIABLE_SIZE]; /**< Part of the attribute value. */ -} PACKED evt_att_read_blob_resp; - -/** - * This event is generated in response to a @a Read @a Multiple @a Request. - * For more info see Read Multiple Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_mult_resp. - */ -#define EVT_BLUE_ATT_READ_MULTIPLE_RESP (0x0C09) -typedef __packed struct _evt_att_read_mult_resp{ - uint16_t conn_handle; /**< The connection handle related to the response. */ - uint8_t event_data_length; /**< Length of following data. */ - uint8_t set_of_values[VARIABLE_SIZE]; /**< A set of two or more values.*/ -} PACKED evt_att_read_mult_resp; - -/** - * This event is generated in response to a @a Read @a By @a Group @a Type @a Request. See aci_gatt_disc_all_prim_services(). - * For more info see Read By Group type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_group_resp. - */ -#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP (0x0C0A) -typedef __packed struct _evt_att_read_by_group_resp{ - uint16_t conn_handle; /**< The connection handle related to the response. */ - uint8_t event_data_length; /**< Length of following data. */ - uint8_t attribute_data_length; /**< The size of each Attribute Data. */ - /** - * A list of Attribute Data where the attribute data is composed by: - * @li 2 octets for Attribute Handle - * @li 2 octets for End Group Handle - * @li (attribute_data_length - 4) octets for Attribute Value - */ - uint8_t attribute_data_list[VARIABLE_SIZE]; -} PACKED evt_att_read_by_group_resp; - -/** - * This event is generated in response to a @a Prepare @a Write @a Request. - * For more info see Prepare Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_prepare_write_resp. - */ -#define EVT_BLUE_ATT_PREPARE_WRITE_RESP (0x0C0C) -typedef __packed struct _evt_att_prepare_write_resp{ - uint16_t conn_handle; /**< The connection handle related to the response. */ - uint8_t event_data_length; /**< Length of following data. */ - uint16_t attribute_handle; /**< The handle of the attribute to be written. */ - uint16_t offset; /**< The offset of the first octet to be written. */ - uint8_t part_attr_value[VARIABLE_SIZE]; /**< The value of the attribute to be written. */ -} PACKED evt_att_prepare_write_resp; - -/** - * This event is generated in response to an @a Execute @a Write @a Request. - * For more info see Execute Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_exec_write_resp. - */ -#define EVT_BLUE_ATT_EXEC_WRITE_RESP (0x0C0D) -typedef __packed struct _evt_att_exec_write_resp{ - uint16_t conn_handle; /**< The connection handle related to the response. */ - uint8_t event_data_length; /**< Always 0. */ -} PACKED evt_att_exec_write_resp; - -/** - * This event is generated when an indication is received from the server. - * For more info see Handle Value Indication in Bluetooth Core v4.0 spec. See @ref _evt_gatt_indication. - */ -#define EVT_BLUE_GATT_INDICATION (0x0C0E) -typedef __packed struct _evt_gatt_indication{ - uint16_t conn_handle; /**< The connection handle related to the event. */ - uint8_t event_data_length; /**< Length of following data. */ - uint16_t attr_handle; /**< The handle of the attribute. */ - uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ -} PACKED evt_gatt_indication; - -/** - * This event is generated when a notification is received from the server. - * For more info see Handle Value Notification in Bluetooth Core v4.0 spec. See @ref _evt_gatt_notification. - */ -#define EVT_BLUE_GATT_NOTIFICATION (0x0C0F) -typedef __packed struct _evt_gatt_notification{ - uint16_t conn_handle; /**< The connection handle related to the event. */ - uint8_t event_data_length; /**< Length of following data. */ - uint16_t attr_handle; /**< The handle of the attribute. */ - uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ -} PACKED evt_gatt_attr_notification; - -/** - * This event is generated when a GATT client procedure completes either with error or successfully. - * See @ref _evt_gatt_procedure_complete. - */ -#define EVT_BLUE_GATT_PROCEDURE_COMPLETE (0x0C10) -typedef __packed struct _evt_gatt_procedure_complete{ - uint16_t conn_handle; /**< The connection handle on which the GATT procedure has completed */ - uint8_t data_length; /**< Length of error_code field (always 1). */ - /** - * Indicates whether the procedure completed with error (BLE_STATUS_FAILED) or was successful (BLE_STATUS_SUCCESS). - */ - uint8_t error_code; -} PACKED evt_gatt_procedure_complete; - -/** - * This event is generated when an Error Response is received from the server. The error response can be given - * by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended - * with an error, but this error event is part of the procedure itself. See @ref _evt_gatt_error_resp. - */ -#define EVT_BLUE_GATT_ERROR_RESP (0x0C11) -typedef __packed struct _evt_gatt_error_resp{ - uint16_t conn_handle; /**< The connection handle related to the event. */ - uint8_t event_data_length; /**< Length of following data. */ - uint8_t req_opcode; /**< The request that generated this error response. */ - uint16_t attr_handle; /**< The attribute handle that generated this error response. */ - uint8_t error_code; /**< The reason why the request has generated an error response. See Error Response in Bluetooth Core v4.0 spec. */ -} PACKED evt_gatt_error_resp; - -/** - * This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using - * Characteristic UUID" procedure. - * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), - * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a - * "Read using Characteristic UUID" has been performed. See @ref _evt_gatt_disc_read_char_by_uuid_resp. - */ -#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12) -typedef __packed struct _evt_gatt_disc_read_char_by_uuid_resp{ - uint16_t conn_handle; /**< The connection handle related to the event. */ - uint8_t event_data_length; /**< Length of following data. */ - uint16_t attr_handle; /**< The handle of the attribute. */ - /** - * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), - * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a - * "Read using Characteristic UUID" has been performed. - */ - uint8_t attr_value[VARIABLE_SIZE]; -} PACKED evt_gatt_disc_read_char_by_uuid_resp; - -/** - * This event is given to the application when a write request, write command or signed write command - * is received by the server from the client. This event will be given to the application only if the - * event bit for this event generation is set when the characteristic was added. - * When this event is received, the application has to check whether the value being requested for write - * is allowed to be written and respond with the command aci_gatt_write_response(). - * If the write is rejected by the application, then the value of the attribute will not be modified. - * In case of a write request, an error response will be sent to the client, with the error code as specified by the application. - * In case of write/signed write commands, no response is sent to the client but the attribute is not modified. - * See @ref evt_gatt_write_permit_req. - */ -#define EVT_BLUE_GATT_WRITE_PERMIT_REQ (0x0C13) -typedef __packed struct _evt_gatt_write_permit_req{ - uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ - uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ - uint8_t data_length; /**< Length of data field. */ - uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ -} PACKED evt_gatt_write_permit_req; - -/** - * This event is given to the application when a read request or read blob request is received by the server - * from the client. This event will be given to the application only if the event bit for this event generation - * is set when the characteristic was added. - * On receiving this event, the application can update the value of the handle if it desires and when done - * it has to use the aci_gatt_allow_read() command to indicate to the stack that it can send the response to the client. - * See @ref evt_gatt_read_permit_req. - * - */ -#define EVT_BLUE_GATT_READ_PERMIT_REQ (0x0C14) -typedef __packed struct _evt_gatt_read_permit_req{ - uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ - uint16_t attr_handle; /**< The handle of the attribute for which the read request has been made by the client */ - uint8_t data_length; /**< Length of offset field. (always 1). */ - uint8_t offset; /**< Contains the offset from which the read has been requested */ -} PACKED evt_gatt_read_permit_req; - -/** - * This event is given to the application when a read multiple request or read by type request is received - * by the server from the client. This event will be given to the application only if the event bit for this - * event generation is set when the characteristic was added. - * On receiving this event, the application can update the values of the handles if it desires and when done - * it has to send the aci_gatt_allow_read command to indicate to the stack that it can send the response to the client. - * See @ref evt_gatt_read_multi_permit_req. - * - */ -#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ (0x0C15) -typedef __packed struct _evt_gatt_read_multi_permit_req{ - uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ - uint8_t data_length; /**< Length of data field. */ - uint8_t data[VARIABLE_SIZE]; /**< The handles of the attributes that have been requested by the client for a read. */ -} PACKED evt_gatt_read_multi_permit_req; - -/** - * @} - */ - -/** - * @} - */ - -#endif /* __BLUENRG_GATT_ACI_H__ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_gatt_server.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,223 +0,0 @@ -/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** -* File Name : bluenrg_gatt_server.h -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 19-July-2012 -* Description : Header file for BlueNRG's GATT server layer. -******************************************************************************** -* 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. -*******************************************************************************/ - -#ifndef __BNRG_GATT_SERVER_H__ -#define __BNRG_GATT_SERVER_H__ - -#include "compiler.h" -#include "ble_status.h" - -/** - *@addtogroup GATT GATT - *@{ - */ - -/** - * @anchor Well-Known_UUIDs - * @name Well-Known UUIDs - * @{ - */ -#define PRIMARY_SERVICE_UUID (0x2800) -#define SECONDARY_SERVICE_UUID (0x2801) -#define INCLUDE_SERVICE_UUID (0x2802) -#define CHARACTERISTIC_UUID (0x2803) -#define CHAR_EXTENDED_PROP_DESC_UUID (0x2900) -#define CHAR_USER_DESC_UUID (0x2901) -#define CHAR_CLIENT_CONFIG_DESC_UUID (0x2902) -#define CHAR_SERVER_CONFIG_DESC_UUID (0x2903) -#define CHAR_FORMAT_DESC_UUID (0x2904) -#define CHAR_AGGR_FMT_DESC_UUID (0x2905) -#define GATT_SERVICE_UUID (0x1801) -#define GAP_SERVICE_UUID (0x1800) -#define SERVICE_CHANGED_UUID (0x2A05) -/** - * @} - */ - -/** - * @anchor Access_permissions - * @name Access permissions - * Access permissions for an attribute - * @{ - */ -#define ATTR_NO_ACCESS (0x00) -#define ATTR_ACCESS_READ_ONLY (0x01) -#define ATTR_ACCESS_WRITE_REQ_ONLY (0x02) -#define ATTR_ACCESS_READ_WRITE (0x03) -#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE (0x04) -#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED (0x08) -/** - * Allows all write procedures - */ -#define ATTR_ACCESS_WRITE_ANY (0x0E) -/** - * @} - */ - -/** - * @anchor Char_properties - * @name Characteristic properties. - * @{ - */ -#define CHAR_PROP_BROADCAST (0x01) -#define CHAR_PROP_READ (0x02) -#define CHAR_PROP_WRITE_WITHOUT_RESP (0x04) -#define CHAR_PROP_WRITE (0x08) -#define CHAR_PROP_NOTIFY (0x10) -#define CHAR_PROP_INDICATE (0x20) -#define CHAR_PROP_SIGNED_WRITE (0x40) -#define CHAR_PROP_EXT (0x80) -/** - * @} - */ - - -/** - * @anchor Security_permissions - * @name Security permissions for an attribute. - * @{ - */ -#define ATTR_PERMISSION_NONE (0x00) /**< No security. */ -#define ATTR_PERMISSION_AUTHEN_READ (0x01) /**< Need authentication to read */ -#define ATTR_PERMISSION_AUTHOR_READ (0x02) /**< Need authorization to read */ -#define ATTR_PERMISSION_ENCRY_READ (0x04) /**< Link must be encrypted to read */ -#define ATTR_PERMISSION_AUTHEN_WRITE (0x08) /**< Need authentication to write */ -#define ATTR_PERMISSION_AUTHOR_WRITE (0x10) /**< Need authorization to write */ -#define ATTR_PERMISSION_ENCRY_WRITE (0x20) /**< Link must be encrypted for write */ -/** - * @} - */ - -/** - * @anchor UUID_Types - * @name Type of UUID (16 bit or 128 bit). - * @{ - */ -#define UUID_TYPE_16 (0x01) -#define UUID_TYPE_128 (0x02) -/** - * @} - */ - -/** - * @anchor Service_type - * @name Type of service (primary or secondary) - * @{ - */ -#define PRIMARY_SERVICE (0x01) -#define SECONDARY_SERVICE (0x02) -/** - * @} - */ - -/** - * @anchor Gatt_Event_Mask - * @name Gatt Event Mask - * Type of event generated by GATT server - * @{ - */ -#define GATT_DONT_NOTIFY_EVENTS (0x00) /**< Do not notify events. */ -#define GATT_NOTIFY_ATTRIBUTE_WRITE (0x01) /**< The application will be notified when a client writes to this attribute. - An @ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued. */ -#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP (0x02) /**< The application will be notified when a write request, a write cmd - or a signed write cmd are received by the server for this attribute. - An @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ will be issued. */ -#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP (0x04) /**< The application will be notified when a read request of any type is - received for this attribute. An @ref EVT_BLUE_GATT_READ_PERMIT_REQ will be issued. */ -/** - * @} - */ - -/** - * @name Type of characteristic length - * See aci_gatt_add_char() - * @{ - */ -#define CHAR_VALUE_LEN_CONSTANT (0x00) -#define CHAR_VALUE_LEN_VARIABLE (0x01) -/** - * @} - */ - - -/** - * @name Encryption key size - * @{ - */ -/** - * Minimum encryption key size - */ -#define MIN_ENCRY_KEY_SIZE (7) - -/** - * Maximum encryption key size - */ -#define MAX_ENCRY_KEY_SIZE (0x10) -/** - * @} - */ - -/** - * @name Characteristic Presentation Format - * @{ - */ -typedef __packed struct _charactFormat { - uint8_t format; - int8_t exp; - uint16_t unit; - uint8_t name_space; - uint16_t desc; -} PACKED charactFormat; - -/** - * @} - */ - -/** - * @name Format - * @{ - */ -#define FORMAT_UINT8 0x04 -#define FORMAT_UINT16 0x06 -#define FORMAT_SINT16 0x0E -#define FORMAT_SINT24 0x0F -/** - * @} - */ - -/** - * @name Unit - * @{ - */ -#define UNIT_UNITLESS 0x2700 -#define UNIT_TEMP_CELSIUS 0x272F -#define UNIT_PRESSURE_BAR 0x2780 -/** - * @} - */ - - -/** - * ATT MTU size - */ -#define ATT_MTU (23) - -/** - * @} - */ - - - -#endif /* __BNRG_GATT_SERVER_H__ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_hal_aci.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** -* File Name : bluenrg_hal_aci.h -* Author : AMS - AAS -* Version : V1.0.0 -* Date : 26-Jun-2014 -* Description : Header file with HCI commands for BlueNRG FW6.3. -******************************************************************************** -* 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. -*******************************************************************************/ - -#ifndef __BLUENRG_HAL_ACI_H__ -#define __BLUENRG_HAL_ACI_H__ - -/** - *@addtogroup HAL HAL - *@brief Hardware Abstraction Layer. - *@{ - */ - -/** - * @defgroup HAL_Functions HAL functions - * @brief API for BlueNRG HAL layer. - * @{ - */ - -/** - * @brief This command writes a value to a low level configure data structure. - * @note It is useful to setup directly some low level parameters for the system at runtime. - * @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 len Length of data to be written - * @param[out] val Data to be written - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_write_config_data(uint8_t offset, - uint8_t len, - const uint8_t *val); - -/** - * @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). - * When the system starts up or reboots, the default TX power level will be used, which is - * the maximum value of 8dBm. Once this command is given, the output power will be changed - * instantly, regardless if there is Bluetooth communication going on or not. For example, - * for debugging purpose, the BlueNRG can be set to advertise all the time and use this - * command to observe the signal strength changing. The system will keep the last received - * TX power level from the command, i.e. the 2nd command overwrites the previous TX power - * level. The new TX power level remains until another Set TX Power command, or the system - * reboots.\n - * @param en_high_power Can be only 0 or 1. Set high power bit on or off. It is strongly adviced to use the - * right value, depending on the selected hardware configuration for the RF network: - * normal mode or high power mode. - * @param pa_level Can be from 0 to 7. Set the PA level value. - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level); - -/** - * @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, - * the device can still wake up itself with the internal timer. But in standby mode, this timer is - * disabled. So the only possibility to wake up the device is by external signals, e.g. a HCI command - * sent via SPI bus. - * The command is only accepted when there is no other Bluetooth activity. Otherwise an error code - * ERR_COMMAND_DISALLOWED will be returned. - * - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_device_standby(void); - -/** - * @brief This command starts a carrier frequency, i.e. a tone, on a specific channel. - * @note The frequency sine wave at the specific channel may be used for test purpose only. - * The channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402GHz, 1 for 2.404GHz etc. - * This command shouldn't be used when normal Bluetooth activities are ongoing. - * The tone should be stopped by aci_hal_tone_stop() command. - * - * @param rf_channel BLE Channel ID, from 0 to 39 meaning (2.402 + 2*N) GHz. Actually the tone will be emitted at the - * channel central frequency minus 250 kHz. - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_tone_start(uint8_t rf_channel); - -/** - * This command is used to stop the previously started aci_hal_tone_start() command. - * @return Value indicating success or error code. - */ -tBleStatus aci_hal_tone_stop(void); - -/** - * @} - */ - -/** - * @defgroup Config_vals Offsets and lengths for configuration values. - * @brief Offsets and lengths for configuration values. - * See aci_hal_write_config_data(). - * @{ - */ - -/** - * @name Configuration values. - * See @ref aci_hal_write_config_data(). - * @{ - */ -#define CONFIG_DATA_PUBADDR_OFFSET (0x00) /**< Bluetooth public address */ -#define CONFIG_DATA_DIV_OFFSET (0x06) /**< DIV used to derive CSRK */ -#define CONFIG_DATA_ER_OFFSET (0x08) /**< Encryption root key used to derive LTK and CSRK */ -#define CONFIG_DATA_IR_OFFSET (0x18) /**< Identity root key used to derive LTK and CSRK */ -#define CONFIG_DATA_LL_WITHOUT_HOST (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host. - It can be written only if aci_hal_write_config_data() is the first command - after reset. */ - -/** - * Select the BlueNRG roles and mode configurations.\n - * @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB) - * @li Mode 2: slave or master, 1 connection, RAM1 and RAM2 (large GATT DB) - * @li Mode 3: master only, 8 connections, RAM1 and RAM2. - */ -#define CONFIG_DATA_ROLE (0x2D) -/** - * @} - */ - -/** - * @name Length for configuration values. - * See @ref aci_hal_write_config_data(). - * @{ - */ -#define CONFIG_DATA_PUBADDR_LEN (6) -#define CONFIG_DATA_DIV_LEN (2) -#define CONFIG_DATA_ER_LEN (16) -#define CONFIG_DATA_IR_LEN (16) -#define CONFIG_DATA_LL_WITHOUT_HOST_LEN (1) -#define CONFIG_DATA_ROLE_LEN (1) -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - - -#endif /* __BLUENRG_HAL_ACI_H__ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_l2cap_aci.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,162 +0,0 @@ -/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** -* File Name : bluenrg_l2cap_aci.h -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 26-Jun-2014 -* Description : Header file with L2CAP commands for BlueNRG FW6.3. -******************************************************************************** -* 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. -*******************************************************************************/ - -#ifndef __BLUENRG_L2CAP_ACI_H__ -#define __BLUENRG_L2CAP_ACI_H__ - -/** - *@addtogroup L2CAP L2CAP - *@brief L2CAP layer. - *@{ - */ - -/** - *@defgroup L2CAP_Functions L2CAP functions - *@brief API for L2CAP layer. - *@{ - */ - -/** - * @brief Send an L2CAP Connection Parameter Update request from the slave to the master. - * @note An @ref EVT_BLUE_L2CAP_CONN_UPD_RESP event will be raised when the master will respond to the request - * (accepts or rejects). - * @param conn_handle Connection handle on which the connection parameter update request has to be sent. - * @param interval_min Defines minimum value for the connection event interval in the following manner: - * connIntervalMin = interval_min x 1.25ms - * @param interval_max Defines maximum value for the connection event interval in the following manner: - * connIntervalMax = interval_max x 1.25ms - * @param slave_latency Defines the slave latency parameter (number of connection events that can be skipped). - * @param timeout_multiplier Defines connection timeout parameter in the following manner: - * timeout_multiplier x 10ms. - * @return Value indicating success or error code. - */ -tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, - uint16_t interval_max, uint16_t slave_latency, - uint16_t timeout_multiplier); -/** - * @brief Accept or reject a connection update. - * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. - * The accept parameter has to be set if the connection parameters given in the event are acceptable. - * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. - * @param interval_min The connection interval parameter as received in the l2cap connection update request event - * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. - * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. - * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. - * @param min_ce_length Minimum length of connection event needed for the LE connection.\n - * Range: 0x0000 - 0xFFFF\n - * Time = N x 0.625 msec. - * @param max_ce_length Maximum length of connection event needed for the LE connection.\n - * Range: 0x0000 - 0xFFFF\n - * Time = N x 0.625 msec. - * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. - * @param accept @arg 0x00: The connection update parameters are not acceptable. - * @arg 0x01: The connection update parameters are acceptable. - * @return Value indicating success or error code. - */ -tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, - uint16_t interval_max, uint16_t slave_latency, - uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, - uint8_t id, uint8_t accept); - /** - * @brief Accept or reject a connection update. - * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. - * The accept parameter has to be set if the connection parameters given in the event are acceptable. - * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. - * @param interval_min The connection interval parameter as received in the l2cap connection update request event - * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. - * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. - * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. - * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. - * @param accept @arg 0x00: The connection update parameters are not acceptable. - * @arg 0x01: The connection update parameters are acceptable. - * @return Value indicating success or error code. - */ -tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, - uint16_t interval_max, uint16_t slave_latency, - uint16_t timeout_multiplier, uint8_t id, uint8_t accept); - -/** - * @} - */ - -/** - * @defgroup L2CAP_Events L2CAP events - * @{ - */ - -/** - * This event is generated when the master responds to the L2CAP connection update request packet. - * For more info see CONNECTION PARAMETER UPDATE RESPONSE and COMMAND REJECT in Bluetooth Core v4.0 spec. - */ -#define EVT_BLUE_L2CAP_CONN_UPD_RESP (0x0800) -typedef __packed struct _evt_l2cap_conn_upd_resp{ - uint16_t conn_handle; /**< The connection handle related to the event. */ - uint8_t event_data_length; /**< Length of following data. */ -/** - * @li 0x13 in case of valid L2CAP Connection Parameter Update Response packet. - * @li 0x01 in case of Command Reject. - */ - uint8_t code; - uint8_t identifier; /**< Identifier of the response. It is equal to the request. */ - uint16_t l2cap_length; /**< Length of following data. It should always be 2 */ -/** - * Result code (parameters accepted or rejected) in case of Connection Parameter Update - * Response (code=0x13) or reason code for rejection in case of Command Reject (code=0x01). - */ - uint16_t result; -} PACKED evt_l2cap_conn_upd_resp; - -/** - * This event is generated when the master does not respond to the connection update request - * within 30 seconds. - */ -#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801) - -/** - * The event is given by the L2CAP layer when a connection update request is received from the slave. - * The application has to respond by calling aci_l2cap_connection_parameter_update_response(). - */ -#define EVT_BLUE_L2CAP_CONN_UPD_REQ (0x0802) -typedef __packed struct _evt_l2cap_conn_upd_req{ -/** - * Handle of the connection for which the connection update request has been received. - * The same handle has to be returned while responding to the event with the command - * aci_l2cap_connection_parameter_update_response(). - */ - uint16_t conn_handle; - uint8_t event_data_length; /**< Length of following data. */ -/** - * This is the identifier which associates the request to the - * response. The same identifier has to be returned by the upper - * layer in the command aci_l2cap_connection_parameter_update_response(). - */ - uint8_t identifier; - uint16_t l2cap_length; /**< Length of the L2CAP connection update request. */ - uint16_t interval_min; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ - uint16_t interval_max; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ - uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ - uint16_t timeout_mult; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ -} PACKED evt_l2cap_conn_upd_req; - -/** - * @} - */ - -/** - * @} - */ - - -#endif /* __BLUENRG_L2CAP_ACI_H__ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_updater_aci.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** -* File Name : bluenrg_updater_aci.h -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 26-Jun-2014 -* Description : Header file with updater commands for BlueNRG FW6.3. -******************************************************************************** -* 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. -*******************************************************************************/ - -#ifndef __BLUENRG_UPDATER_ACI_H__ -#define __BLUENRG_UPDATER_ACI_H__ - -#include <compiler.h> - -/** - * @defgroup Updater Updater - * @brief Updater. - * @{ - */ - -/** - * @defgroup Updater_Functions Updater functions - * @brief API for BlueNRG Updater. - * @{ - */ - -tBleStatus aci_updater_start(void); - -tBleStatus aci_updater_reboot(void); - -tBleStatus aci_get_updater_version(uint8_t *version); - -tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size); - -tBleStatus aci_erase_blue_flag(void); - -tBleStatus aci_reset_blue_flag(void); - -tBleStatus aci_updater_erase_sector(uint32_t address); - -tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data); - -tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data); - -tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc); - -tBleStatus aci_updater_hw_version(uint8_t *version); - -/** - * @} - */ - -/** - * @defgroup Updater_Events Updater events - * @{ - */ -/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ -#define EVT_BLUE_INITIALIZED (0x0001) -typedef __packed struct _evt_blue_initialized{ - uint8_t reason_code; -} PACKED evt_blue_initialized; -/** - * @} - */ - -/** - * @} - */ - - - -#endif /* __BLUENRG_UPDATER_ACI_H__ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/bluenrg_utils.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,197 +0,0 @@ -/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** -* File Name : bluenrg_utils.h -* Author : AMS - VMA, RF Application Team -* Version : V1.0.1 -* Date : 03-October-2014 -* Description : Header file for BlueNRG utility functions -******************************************************************************** -* 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. -*******************************************************************************/ -/** - * @file bluenrg_utils.h - * @brief BlueNRG IFR updater & BlueNRG stack updater utility APIs description - * - * <!-- Copyright 2014 by STMicroelectronics. All rights reserved. *80*--> -**/ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __BLUENRG_UTILS_H -#define __BLUENRG_UTILS_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "hal_types.h" -#include "compiler.h" - -/* Exported types ------------------------------------------------------------*/ -typedef struct{ - uint8_t stack_mode; - uint8_t day; - uint8_t month; - uint8_t year; - uint16_t slave_sca_ppm; - uint8_t master_sca; - uint16_t hs_startup_time; /* In system time units*/ -} IFR_config2_TypeDef; - -/** - * Structure inside IFR for configuration options. - */ -typedef __packed struct{ - uint8_t cold_ana_act_config_table[64]; - uint8_t hot_ana_config_table[64]; - uint8_t stack_mode; - uint8_t gpio_config; - uint8_t rsrvd1[2]; - uint32_t rsrvd2[3]; - uint32_t max_conn_event_time; - uint32_t ls_crystal_period; - uint32_t ls_crystal_freq; - uint16_t slave_sca_ppm; - uint8_t master_sca; - uint8_t rsrvd3; - uint16_t hs_startup_time; /* In system time units*/ - uint8_t rsrvd4[2]; - uint32_t uid; - uint8_t rsrvd5; - uint8_t year; - uint8_t month; - uint8_t day; - uint32_t unused[5]; -} PACKED IFR_config_TypeDef; - -/* Exported constants --------------------------------------------------------*/ -extern const IFR_config_TypeDef IFR_config; - -/* Exported macros -----------------------------------------------------------*/ -#define FROM_US_TO_SYS_TIME(us) ((uint16_t)(us/2.4414)) -#define FROM_SYS_TIME_TO_US(sys) ((uint16_t)(sys*2.4414)) - -/* Convert 2 digit BCD number to an integer */ -#define BCD_TO_INT(bcd) ((bcd & 0xF) + ((bcd & 0xF0) >> 4)*10) - -/* Convert 2 digit number to a BCD number */ -#define INT_TO_BCD(n) ((((uint8_t)n/10)<<4) + (uint8_t)n%10) - -/** - * Return values - */ -#define BLE_UTIL_SUCCESS 0 -#define BLE_UTIL_UNSUPPORTED_VERSION 1 -#define BLE_UTIL_WRONG_IMAGE_SIZE 2 -#define BLE_UTIL_ACI_ERROR 3 -#define BLE_UTIL_CRC_ERROR 4 -#define BLE_UTIL_PARSE_ERROR 5 -#define BLE_UTIL_WRONG_VERIFY 6 - -/* Exported functions ------------------------------------------------------- */ -/** - * @brief Flash a new firmware using internal bootloader. - * @param fw_image Pointer to the firmware image (raw binary data, - * little-endian). - * @param fw_size Size of the firmware image. The firmware image size shall - * be multiple of 4 bytes. - * @retval int It returns 0 if successful, or a number not equal to 0 in - * case of error (ACI_ERROR, UNSUPPORTED_VERSION, - * WRONG_IMAGE_SIZE, CRC_ERROR) - */ -int program_device(const uint8_t *fw_image, uint32_t fw_size); - -/** - * @brief Read raw data from IFR (3 64-bytes blocks). - * @param data Pointer to the buffer that will contain the read data. - * Its size must be 192 bytes. This data can be parsed by - * parse_IFR_data_config(). - * @retval int It returns 0 if successful, or a number not equal to 0 in - * case of error (ACI_ERROR, UNSUPPORTED_VERSION) - */ -int read_IFR(uint8_t data[192]); - -/** - * @brief Verify raw data from IFR (3 64-bytes blocks). - * @param ifr_data Pointer to the buffer that will contain the data to verify. - * Its size must be 192 bytes. - * @retval int It returns 0 if successful, or a number not equal to 0 in - case of error (ACI_ERROR, BLE_UTIL_WRONG_VERIFY) - */ -uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data); - -/** - * @brief Program raw data to IFR (3 64-bytes blocks). - * @param ifr_image Pointer to the buffer that will contain the data to program. - * Its size must be 192 bytes. - * @retval int It returns 0 if successful - */ -int program_IFR(const IFR_config_TypeDef *ifr_image); - -/** - * @brief Parse IFR raw data. - * @param data Pointer to the raw data: last 64 bytes read from IFR sector. - * @param IFR_config Data structure that will be filled with parsed data. - * @retval None - */ -void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config); - -/** - * @brief Check for the correctness of parsed data. - * @param IFR_config Data structure filled with parsed data. - * @retval int It returns 0 if successful, or PARSE_ERROR in case data is - * not correct. - */ -int IFR_validate(IFR_config2_TypeDef *IFR_config); - -/** - * @brief Modify IFR data. (Last 64-bytes block). - * @param IFR_config Structure that contains the new parameters inside the - * IFR configuration data. - * @note It is highly recommended to parse the IFR configuration from - * a working IFR block (this should be done with parse_IFR_data_config()). - * Then it is possible to write the new parameters inside the IFR_config - * structure. - * @param data Pointer to the buffer that contains the original data. It - * will be modified according to the new data in the IFR_config - * structure. Then this data must be written in the last - * 64-byte block in the IFR. - * Its size must be 64 bytes. - * @retval None - */ -void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]); - -/** - * @brief Get BlueNRG hardware and firmware version - * @param hwVersion This parameter returns the Hardware Version (i.e. CUT 3.0 = 0x30, CUT 3.1 = 0x31). - * @param fwVersion This parameter returns the Firmware Version in the format 0xJJMN - * where JJ = Major Version number, M = Minor Version number and N = Patch Version number. - * @retval Status of the call - */ -uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion); - -/** - * @brief Get BlueNRG updater version - * @param version This parameter returns the updater version. If the updadter version is 0x03 - * the chip has the updater old, needs to update the bootloader. - * @retval Status of the call - */ -uint8_t getBlueNRGUpdaterVersion(uint8_t *version); - -/** - * @brief Verifies if the bootloader is patched or not. This function shall be used to fix a bug on - * the HW bootloader related to the 32 MHz external crystal oscillator. - * @retval TRUE if the HW bootloader is already patched, FALSE otherwise - */ -uint8_t isHWBootloader_Patched(void); - -#ifdef __cplusplus -} -#endif - -#endif /*__BLUENRG_UTILS_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/clock.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** -* File Name : clock.h -* Author : AMS - HEA&RF BU -* Version : V1.0.1 -* Date : 19-July-2012 -* Description : Header file for clock library, that gives a simple time -* reference to the BLE Stack. -******************************************************************************** -* 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. -*******************************************************************************/ - -#ifndef __CLOCK_H__ -#define __CLOCK_H__ - -#include <hal_types.h> - -/** - * Number of clocks in one seconds. - * This value must be set by each platorm implementation, basing on its needs. - */ -extern const uint32_t CLOCK_SECOND; - -typedef uint32_t tClockTime; - -/** - * This function initializes the clock library and should be called before - * any other Stack functions. - * - */ -void Clock_Init(void); - -/** - * This function returns the current system clock time. it is used by - * the host stack and has to be implemented. - * - * @return The current clock time, measured in system ticks. - */ -tClockTime Clock_Time(void); - -/** - * This function waits for a given number of milliseconds. - * - */ -void Clock_Wait(uint32_t i); - -/** - * It suspends system clock. - * - */ -void Clock_Suspend(void); - - -#endif /* __CLOCK_H__ */ -
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/compiler.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** -* File Name : compiler.h -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 19-July-2012 -* Description : Compiler-dependent macros. -******************************************************************************** -* 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. -*******************************************************************************/ - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - -#ifdef __ICCARM__ -#define PACKED -#else -#ifdef __GNUC__ -#undef __packed -#define __packed -#define PACKED __attribute__((packed)) -#else -#define PACKED -#define __packed -#endif -#endif - -/* Change this define to 1 if zero-length arrays are not supported by your compiler. */ -#define VARIABLE_SIZE 1 - -#endif /* DOXYGEN_SHOULD_SKIP_THIS */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/debug.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/** - ****************************************************************************** - * @file debug.h - * @author CL - * @version V1.0.0 - * @date 04-July-2014 - * @brief This file defines print functions for debug purposes. - ****************************************************************************** - * @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 __DEBUG_H -#define __DEBUG_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include <string.h> - -/* Exported macro ------------------------------------------------------------*/ -//#define DEBUG -#ifdef DEBUG -#include <stdio.h> -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif - -/* Print the data travelling over the SPI in the .csv format for the GUI*/ -//#define PRINT_CSV_FORMAT -#ifdef PRINT_CSV_FORMAT -#include <stdio.h> -#define PRINT_CSV(...) printf(__VA_ARGS__) -#else -#define PRINT_CSV(...) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __DEBUG_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/gp_timer.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +0,0 @@ -/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** -* File Name : gp_timer.h -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 19-July-2012 -* Description : General purpose timer library. -******************************************************************************** -* 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. -*******************************************************************************/ - -#ifndef __GP_TIMER_H__ -#define __GP_TIMER_H__ - -#include "clock.h" -#include "ble_status.h" -#ifdef __DMA_LP__ -#include "stm32xx_timerserver.h" -#endif /* __DMA_LP__ */ - -/** - * timer - * - * A structure that represents a timer. Use Timer_Set() to set the timer. - * - */ -struct timer { - -#ifndef DOXYGEN_SHOULD_SKIP_THIS - - tClockTime start; - tClockTime interval; - -#endif -}; - -typedef void (* TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE)(void); - -/** - * Timer_Set - * - * @param[in] t Pointer to a timer structure - * @param[in] interval timeout value - * - * This function sets the timeout value of a timer. - * - */ -void Timer_Set(struct timer *t, tClockTime interval); - -/** - * Timer_Reset - * - * @param[in] t Pointer to a timer structure - * - * This function resets the timer with the same interval given - * with Timer_Set, starting from the time it previously expired. - * - */ -void Timer_Reset(struct timer *t); - -/** - * Timer_Restart - * - * @param[in] t Pointer to a timer structure - * - * This function resets the timer with the same interval given - * with Timer_Set, starting from the current time. - * - */ -void Timer_Restart(struct timer *t); - -/** - * Timer_Expired - * - * @param[in] t Pointer to a timer structure - * - * This function returns TRUE if timer is expired, FALSE otherwise. - * - */ -int Timer_Expired(struct timer *t); - -/** - * Timer_Expired - * - * @param[in] t Pointer to a timer structure - * - * This function returns the time needed for expiration. - * - * @return Time before timer's expiration. - */ -tClockTime Timer_Remaining(struct timer *t); - -#ifdef __DMA_LP__ -tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, - TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, - uint8_t *timerID); - -tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID); -#endif /* __DMA_LP__ */ - -#endif /* __GP_TIMER_H__ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/hal.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** -* File Name : hal.h -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 19-July-2012 -* Description : Header file which defines Hardware abstraction layer APIs -* used by the BLE stack. It defines the set of functions -* which needs to be ported to the target platform. -******************************************************************************** -* 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. -*******************************************************************************/ -#ifndef __HAL_H__ -#define __HAL_H__ - -/****************************************************************************** - * Includes - *****************************************************************************/ -#include <hal_types.h> -#include <ble_status.h> - - -/****************************************************************************** - * Macros - *****************************************************************************/ -/* Little Endian buffer to host endianess conversion */ -#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ - *((uint8_t *)ptr)) | \ - ((uint16_t) \ - *((uint8_t *)ptr + 1) << 8 ) ) - -#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ - *((uint8_t *)ptr)) | \ - ((uint32_t) \ - *((uint8_t *)ptr + 1) << 8) | \ - ((uint32_t) \ - *((uint8_t *)ptr + 2) << 16) | \ - ((uint32_t) \ - *((uint8_t *)ptr + 3) << 24) ) - -/* Big Endian buffer to host endianess conversion */ -#define BE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ - *((uint8_t *)ptr)) << 8 | \ - ((uint16_t) \ - *((uint8_t *)ptr + 1) ) ) - -/* Store Value into a buffer in Little Endian Format */ -#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ - ((buf)[1] = (uint8_t) (val>>8) ) ) - -#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ - ((buf)[1] = (uint8_t) (val>>8) ) , \ - ((buf)[2] = (uint8_t) (val>>16) ) , \ - ((buf)[3] = (uint8_t) (val>>24) ) ) - - -/* Store Value into a buffer in Big Endian Format */ -#define HOST_TO_BE_16(buf, val) ( ((buf)[1] = (uint8_t) (val) ) , \ - ((buf)[0] = (uint8_t) (val>>8) ) ) - -#define DISABLE_INTERRUPTS() __disable_interrupt() -#define ENABLE_INTERRUPTS() __enable_interrupt() -#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK() -#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ - __disable_interrupt(); \ -/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */ -#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) - -/****************************************************************************** - * Types - *****************************************************************************/ - -/****************************************************************************** - * Function Prototypes - *****************************************************************************/ - -/** - * Writes data to a serial interface. - * - * @param[in] data1 1st buffer - * @param[in] data2 2nd buffer - * @param[in] n_bytes1 number of bytes in 1st buffer - * @param[in] n_bytes2 number of bytes in 2nd buffer - */ -void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); - -/** - * Enable interrupts from HCI controller. - */ -void Enable_SPI_IRQ(void); - -/** - * Disable interrupts from BLE controller. - */ -void Disable_SPI_IRQ(void); - -void Hal_Init_Timer(void); -uint32_t Hal_Get_Timer_Value(void); -void Hal_Start_Timer(uint32_t timeout); -void Hal_Stop_Timer(void); - -#endif /* __HAL_H__ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/hal.h.orig Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** -* File Name : hal.h -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 19-July-2012 -* Description : Header file which defines Hardware abstraction layer APIs -* used by the BLE stack. It defines the set of functions -* which needs to be ported to the target platform. -******************************************************************************** -* 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. -*******************************************************************************/ -#ifndef __HAL_H__ -#define __HAL_H__ - -/****************************************************************************** - * Includes - *****************************************************************************/ -#include <hal_types.h> -#include <ble_status.h> - - -/****************************************************************************** - * Macros - *****************************************************************************/ -/* Little Endian buffer to host endianess conversion */ -#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ - *((uint8_t *)ptr)) | \ - ((uint16_t) \ - *((uint8_t *)ptr + 1) << 8 ) ) - -#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ - *((uint8_t *)ptr)) | \ - ((uint32_t) \ - *((uint8_t *)ptr + 1) << 8) | \ - ((uint32_t) \ - *((uint8_t *)ptr + 2) << 16) | \ - ((uint32_t) \ - *((uint8_t *)ptr + 3) << 24) ) - -/* Big Endian buffer to host endianess conversion */ -#define BE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ - *((uint8_t *)ptr)) << 8 | \ - ((uint16_t) \ - *((uint8_t *)ptr + 1) ) ) - -/* Store Value into a buffer in Little Endian Format */ -#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ - ((buf)[1] = (uint8_t) (val>>8) ) ) - -#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ - ((buf)[1] = (uint8_t) (val>>8) ) , \ - ((buf)[2] = (uint8_t) (val>>16) ) , \ - ((buf)[3] = (uint8_t) (val>>24) ) ) - - -/* Store Value into a buffer in Big Endian Format */ -#define HOST_TO_BE_16(buf, val) ( ((buf)[1] = (uint8_t) (val) ) , \ - ((buf)[0] = (uint8_t) (val>>8) ) ) - -#define DISABLE_INTERRUPTS() __disable_interrupt() -#define ENABLE_INTERRUPTS() __enable_interrupt() -#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK() -#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ - __disable_interrupt(); \ -/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */ -#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) - -/****************************************************************************** - * Types - *****************************************************************************/ - -/****************************************************************************** - * Function Prototypes - *****************************************************************************/ - -/** - * Writes data to a serial interface. - * - * @param[in] data1 1st buffer - * @param[in] data2 2nd buffer - * @param[in] n_bytes1 number of bytes in 1st buffer - * @param[in] n_bytes2 number of bytes in 2nd buffer - */ -<<<<<<< HEAD -//void Hal_Write_Serial(const void* data1, const void* data2, uint16_t n_bytes1, uint16_t n_bytes2); -======= ->>>>>>> 28b9b0106ee91324c03989cd8e448f4f4073ef81 -void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); - -/** - * Enable interrupts from HCI controller. - */ -void Enable_SPI_IRQ(void); - -/** - * Disable interrupts from BLE controller. - */ -void Disable_SPI_IRQ(void); - -void Hal_Init_Timer(void); -uint32_t Hal_Get_Timer_Value(void); -void Hal_Start_Timer(uint32_t timeout); -void Hal_Stop_Timer(void); - -#endif /* __HAL_H__ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/hal_types.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** -* File Name : hal_types.h -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 19-July-2012 -* Description : This header file defines the basic data types used by the -* BLE stack. -******************************************************************************** -* 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. -*******************************************************************************/ -#ifndef __HAL_TYPES_H__ -#define __HAL_TYPES_H__ - -#include <stdint.h> - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#ifndef __LITTLE_ENDIAN -#define __LITTLE_ENDIAN 0 -#define __BIG_ENDIAN 1 -#endif - -/* Byte order conversions */ -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define htobs(d) (d) -#define htobl(d) (d) -#define btohs(d) (d) -#define btohl(d) (d) -#elif __BYTE_ORDER == __BIG_ENDIAN -#define htobs(d) (d<<8|d>>8) -#define htobl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) -#define btohs(d) (d<<8|d>>8) -#define btohl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) -#else -#error "Unknown byte order" -#endif - -typedef uint8_t BOOL; - -#ifndef TRUE -#define TRUE (1) -#endif - -#ifndef FALSE -#define FALSE (0) -#endif - - - -#endif /* __HAL_TYPES_H__ */ -
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/hci.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,239 +0,0 @@ -/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** -* File Name : hci.h -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 19-July-2012 -* Description : Constants and functions for HCI layer. See Bluetooth Core -* v 4.0, Vol. 2, Part E. -******************************************************************************** -* 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. -*******************************************************************************/ - -#ifndef __HCI_H_ -#define __HCI_H_ - -#include "hal_types.h" -#include "link_layer.h" -#include <list.h> - -#define HCI_READ_PACKET_SIZE 128 //71 - -/*** Data types ***/ - -/* structure used to read received data */ -typedef struct _tHciDataPacket -{ - tListNode currentNode; - uint8_t dataBuff[HCI_READ_PACKET_SIZE]; - uint8_t data_len; -} tHciDataPacket; - -typedef enum -{ - BUSY, - AVAILABLE -} HCI_CMD_STATUS_t; - -/** - * @defgroup HCI_Error_codes HCI Error codes - * @{ - */ -#define HCI_UNKNOWN_COMMAND 0x01 -#define HCI_NO_CONNECTION 0x02 -#define HCI_HARDWARE_FAILURE 0x03 -#define HCI_PAGE_TIMEOUT 0x04 -#define HCI_AUTHENTICATION_FAILURE 0x05 -#define HCI_PIN_OR_KEY_MISSING 0x06 -#define HCI_MEMORY_FULL 0x07 -#define HCI_CONNECTION_TIMEOUT 0x08 -#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09 -#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a -#define HCI_ACL_CONNECTION_EXISTS 0x0b -#define HCI_COMMAND_DISALLOWED 0x0c -#define HCI_REJECTED_LIMITED_RESOURCES 0x0d -#define HCI_REJECTED_SECURITY 0x0e -#define HCI_REJECTED_PERSONAL 0x0f -#define HCI_HOST_TIMEOUT 0x10 -#define HCI_UNSUPPORTED_FEATURE 0x11 -#define HCI_INVALID_PARAMETERS 0x12 -#define HCI_OE_USER_ENDED_CONNECTION 0x13 -#define HCI_OE_LOW_RESOURCES 0x14 -#define HCI_OE_POWER_OFF 0x15 -#define HCI_CONNECTION_TERMINATED 0x16 -#define HCI_REPEATED_ATTEMPTS 0x17 -#define HCI_PAIRING_NOT_ALLOWED 0x18 -#define HCI_UNKNOWN_LMP_PDU 0x19 -#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a -#define HCI_SCO_OFFSET_REJECTED 0x1b -#define HCI_SCO_INTERVAL_REJECTED 0x1c -#define HCI_AIR_MODE_REJECTED 0x1d -#define HCI_INVALID_LMP_PARAMETERS 0x1e -#define HCI_UNSPECIFIED_ERROR 0x1f -#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20 -#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21 -#define HCI_LMP_RESPONSE_TIMEOUT 0x22 -#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23 -#define HCI_LMP_PDU_NOT_ALLOWED 0x24 -#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25 -#define HCI_UNIT_LINK_KEY_USED 0x26 -#define HCI_QOS_NOT_SUPPORTED 0x27 -#define HCI_INSTANT_PASSED 0x28 -#define HCI_PAIRING_NOT_SUPPORTED 0x29 -#define HCI_TRANSACTION_COLLISION 0x2a -#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c -#define HCI_QOS_REJECTED 0x2d -#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e -#define HCI_INSUFFICIENT_SECURITY 0x2f -#define HCI_PARAMETER_OUT_OF_RANGE 0x30 -#define HCI_ROLE_SWITCH_PENDING 0x32 -#define HCI_SLOT_VIOLATION 0x34 -#define HCI_ROLE_SWITCH_FAILED 0x35 -#define HCI_EIR_TOO_LARGE 0x36 -#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 -#define HCI_HOST_BUSY_PAIRING 0x38 -#define HCI_CONN_REJ_NO_CH_FOUND 0x39 -#define HCI_CONTROLLER_BUSY 0x3A -#define HCI_UNACCEPTABLE_CONN_INTERV 0x3B -#define HCI_DIRECTED_ADV_TIMEOUT 0x3C -#define HCI_CONN_TERM_MIC_FAIL 0x3D -#define HCI_CONN_FAIL_TO_BE_ESTABL 0x3E -#define HCI_MAC_CONN_FAILED 0x3F -/** - * @} - */ - - -/* - * HCI library functions. - * Each function returns 0 in case of success, otherwise one of the error codes. - */ - -int hci_reset(void); - -int hci_disconnect(uint16_t handle, uint8_t reason); - -int hci_le_set_advertise_enable(uint8_t enable); - -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); - -int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, - uint16_t window, uint8_t own_bdaddr_type, - uint8_t filter); - -int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup); - -int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]); - -int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]); - -int hci_le_rand(uint8_t random_number[8]); - -int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level); - -int hci_acl_data(const uint8_t * data, uint16_t len); - -int hci_le_set_random_address(tBDAddr bdaddr); - -int hci_read_bd_addr(tBDAddr bdaddr); - -int hci_le_read_white_list_size(uint8_t *size); - -int hci_le_clear_white_list(void); - -int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); - -int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); - -int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]); - -int hci_le_ltk_request_reply(uint8_t key[16]); - -int hci_le_ltk_request_neg_reply(void); - -int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt); - -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); - -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); - -int hci_le_read_local_supported_features(uint8_t *features); - -int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]); - -int hci_le_read_supported_states(uint8_t states[8]); - -int hci_le_receiver_test(uint8_t frequency); - -int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload); - -int hci_le_test_end(uint16_t *num_pkts); - -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); - -/** - * This function must be used to pass the packet received from the HCI - * interface to the BLE Stack HCI state machine. - * - * @param[in] hciReadPacket The packet that is received from HCI interface. - * - */ -void HCI_Input(tHciDataPacket *hciReadPacket); - -/** - * Initialization function. Must be done before any data can be received from - * BLE controller. - */ -void HCI_Init(void); - -/** - * Callback used to pass events to application. - * - * @param[in] pckt The event. - * - */ -extern void HCI_Event_CB(void *pckt); - -/** - * Processing function that must be called after an event is received from - * HCI interface. Must be called outside ISR. It will call HCI_Event_CB if - * necessary. -*/ -void HCI_Process(void); - -/** - * @brief Check if queue of HCI event is empty or not. - * @note This funtion can be used to check if the event queue from BlueNRG is empty. This - * is useful when checking if it is safe to go to sleep. - * @return TRUE if event queue is empty. FALSE otherwhise. - */ -BOOL HCI_Queue_Empty(void); -/** - * Iterrupt service routine that must be called when the BlueNRG - * reports a packet received or an event to the host through the - * BlueNRG interrupt line. - */ -#ifdef __DMA_LP__ -void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len); -void HCI_Process_Notification_Request(void); -void HCI_Cmd_Status(HCI_CMD_STATUS_t Hci_Cmd_Status); -void HCI_Wait_For_Response(void); -#else -void HCI_Isr(void); -#endif /* __DMA_LP__ */ - -extern tListNode hciReadPktPool; -extern tListNode hciReadPktRxQueue; - -#endif /* __HCI_H_ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/hci_const.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,564 +0,0 @@ -/****************************************************************************** -* -* File Description -* --------------------- -* This file defines constants and functions for HCI layer. -* See Bluetooth Core v 4.0, Vol. 2, Part E. -* -*******************************************************************************/ - -#ifndef __HCI_INTERNAL_H_ -#define __HCI_INTERNAL_H_ - -#include "compiler.h" -#include "hal_types.h" -#include "clock.h" -#include "link_layer.h" - -#include "hci.h" - -#define DEFAULT_TIMEOUT (CLOCK_SECOND/10) - -/** - * Maximum payload of HCI commands that can be sent. Change this value if needed. - * This value can be up to 255. - */ -#define HCI_MAX_PAYLOAD_SIZE 128 - -/* HCI Packet types */ -#define HCI_COMMAND_PKT 0x01 -#define HCI_ACLDATA_PKT 0x02 -#define HCI_SCODATA_PKT 0x03 -#define HCI_EVENT_PKT 0x04 -#define HCI_VENDOR_PKT 0xff - -typedef __packed struct _hci_uart_pckt{ - uint8_t type; - uint8_t data[VARIABLE_SIZE]; -} PACKED hci_uart_pckt; -#define HCI_HDR_SIZE 1 - -typedef __packed struct _hci_command_hdr{ - uint16_t opcode; /* OCF & OGF */ - uint8_t plen; -} PACKED hci_command_hdr; -#define HCI_COMMAND_HDR_SIZE 3 - -typedef __packed struct _hci_event_pckt{ - uint8_t evt; - uint8_t plen; - uint8_t data[VARIABLE_SIZE]; -} PACKED hci_event_pckt; -#define HCI_EVENT_HDR_SIZE 2 - -typedef __packed struct _hci_acl_hdr{ - uint16_t handle; /* Handle & Flags(PB, BC) */ - uint16_t dlen; -} PACKED hci_acl_hdr; -#define HCI_ACL_HDR_SIZE 4 - -/* Link Control */ -#define OGF_LINK_CTL 0x01 - -#define OCF_DISCONNECT 0x0006 -typedef __packed struct _disconnect_cp{ - uint16_t handle; - uint8_t reason; -} PACKED disconnect_cp; -#define DISCONNECT_CP_SIZE 3 - -/* Host Controller and Baseband */ -#define OGF_HOST_CTL 0x03 - -#define OCF_SET_EVENT_MASK 0x0001 -#define OCF_RESET 0x0003 - -#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D -typedef __packed struct _read_transmit_power_level_cp{ - uint16_t handle; - uint8_t type; -} PACKED read_transmit_power_level_cp; -#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 -typedef __packed struct _read_transmit_power_level_rp{ - uint8_t status; - uint16_t handle; - int8_t level; -} PACKED read_transmit_power_level_rp; -#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 - -#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031 -#define OCF_HOST_BUFFER_SIZE 0x0033 -#define OCF_HOST_NUM_COMP_PKTS 0x0035 - -/* Informational Parameters */ -#define OGF_INFO_PARAM 0x04 - -#define OCF_READ_LOCAL_VERSION 0x0001 -typedef __packed struct _read_local_version_rp{ - uint8_t status; - uint8_t hci_version; - uint16_t hci_revision; - uint8_t lmp_pal_version; - uint16_t manufacturer_name; - uint16_t lmp_pal_subversion; -} PACKED read_local_version_rp; -#define READ_LOCAL_VERSION_RP_SIZE 9 - -#define OCF_READ_LOCAL_COMMANDS 0x0002 -#define OCF_READ_LOCAL_FEATURES 0x0003 - -#define OCF_READ_BD_ADDR 0x0009 -typedef __packed struct _read_bd_addr_rp{ - uint8_t status; - tBDAddr bdaddr; -} PACKED read_bd_addr_rp; -#define READ_BD_ADDR_RP_SIZE 7 - -/* Status params */ -#define OGF_STATUS_PARAM 0x05 - -#define OCF_READ_RSSI 0x0005 -typedef __packed struct _read_rssi_cp{ - uint16_t handle; -} PACKED read_rssi_cp; -#define READ_RSSI_CP_SIZE 2 -typedef __packed struct _read_rssi_rp{ - uint8_t status; - uint16_t handle; - int8_t rssi; -} PACKED read_rssi_rp; -#define READ_RSSI_RP_SIZE 4 - - -/* LE commands */ -#define OGF_LE_CTL 0x08 - -#define OCF_LE_SET_EVENT_MASK 0x0001 -typedef __packed struct _le_set_event_mask_cp{ - uint8_t mask[8]; -} PACKED le_set_event_mask_cp; -#define LE_SET_EVENT_MASK_CP_SIZE 8 - -#define OCF_LE_READ_BUFFER_SIZE 0x0002 -typedef __packed struct _le_read_buffer_size_rp{ - uint8_t status; - uint16_t pkt_len; - uint8_t max_pkt; -} PACKED le_read_buffer_size_rp; -#define LE_READ_BUFFER_SIZE_RP_SIZE 4 - -#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES 0x0003 -typedef __packed struct _le_read_local_supported_features_rp{ - uint8_t status; - uint8_t features[8]; -} PACKED le_read_local_supported_features_rp; -#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9 - -#define OCF_LE_SET_RANDOM_ADDRESS 0x0005 -typedef __packed struct _le_set_random_address_cp{ - tBDAddr bdaddr; -} PACKED le_set_random_address_cp; -#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6 - -#define OCF_LE_SET_ADV_PARAMETERS 0x0006 -typedef __packed struct _le_set_adv_parameters_cp{ - uint16_t min_interval; - uint16_t max_interval; - uint8_t advtype; - uint8_t own_bdaddr_type; - uint8_t direct_bdaddr_type; - tBDAddr direct_bdaddr; - uint8_t chan_map; - uint8_t filter; -} PACKED le_set_adv_parameters_cp; -#define LE_SET_ADV_PARAMETERS_CP_SIZE 15 - -#define OCF_LE_READ_ADV_CHANNEL_TX_POWER 0x0007 -typedef __packed struct _le_read_adv_channel_tx_power_rp{ - uint8_t status; - int8_t level; -} PACKED le_read_adv_channel_tx_power_rp; -#define LE_READ_ADV_CHANNEL_TX_POWER_RP_SIZE 2 - -#define OCF_LE_SET_ADV_DATA 0x0008 -typedef __packed struct _le_set_adv_data_cp{ - uint8_t length; - uint8_t data[31]; -} PACKED le_set_adv_data_cp; -#define LE_SET_ADV_DATA_CP_SIZE 32 - -#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009 -typedef __packed struct _le_set_scan_response_data_cp{ - uint8_t length; - uint8_t data[31]; -} PACKED le_set_scan_response_data_cp; -#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32 - -#define OCF_LE_SET_ADVERTISE_ENABLE 0x000A -typedef __packed struct _le_set_advertise_enable_cp{ - uint8_t enable; -} PACKED le_set_advertise_enable_cp; -#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1 - -#define OCF_LE_SET_SCAN_PARAMETERS 0x000B -typedef __packed struct _le_set_scan_parameters_cp{ - uint8_t type; - uint16_t interval; - uint16_t window; - uint8_t own_bdaddr_type; - uint8_t filter; -} PACKED le_set_scan_parameters_cp; -#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7 - -#define OCF_LE_SET_SCAN_ENABLE 0x000C -typedef __packed struct _le_set_scan_enable_cp{ - uint8_t enable; - uint8_t filter_dup; -} PACKED le_set_scan_enable_cp; -#define LE_SET_SCAN_ENABLE_CP_SIZE 2 - -#define OCF_LE_CREATE_CONN 0x000D -typedef __packed struct _le_create_connection_cp{ - uint16_t interval; - uint16_t window; - uint8_t initiator_filter; - uint8_t peer_bdaddr_type; - 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; -} PACKED le_create_connection_cp; -#define LE_CREATE_CONN_CP_SIZE 25 - -#define OCF_LE_CREATE_CONN_CANCEL 0x000E - -#define OCF_LE_READ_WHITE_LIST_SIZE 0x000F -typedef __packed struct _le_read_white_list_size_rp{ - uint8_t status; - uint8_t size; -} PACKED le_read_white_list_size_rp; -#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2 - -#define OCF_LE_CLEAR_WHITE_LIST 0x0010 - -#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST 0x0011 -typedef __packed struct _le_add_device_to_white_list_cp{ - uint8_t bdaddr_type; - tBDAddr bdaddr; -} PACKED le_add_device_to_white_list_cp; -#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7 - -#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST 0x0012 -typedef __packed struct _le_remove_device_from_white_list_cp{ - uint8_t bdaddr_type; - tBDAddr bdaddr; -} PACKED le_remove_device_from_white_list_cp; -#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7 - -#define OCF_LE_CONN_UPDATE 0x0013 -typedef __packed struct _le_connection_update_cp{ - uint16_t handle; - 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; -} PACKED le_connection_update_cp; -#define LE_CONN_UPDATE_CP_SIZE 14 - -#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x0014 -typedef __packed struct _le_set_host_channel_classification_cp{ - uint8_t map[5]; -} PACKED le_set_host_channel_classification_cp; -#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5 - -#define OCF_LE_READ_CHANNEL_MAP 0x0015 -typedef __packed struct _le_read_channel_map_cp{ - uint16_t handle; -} PACKED le_read_channel_map_cp; -#define LE_READ_CHANNEL_MAP_CP_SIZE 2 - -typedef __packed struct _le_read_channel_map_rp{ - uint8_t status; - uint16_t handle; - uint8_t map[5]; -} le_read_channel_map_rp; -#define LE_READ_CHANNEL_MAP_RP_SIZE 8 - -#define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016 -typedef __packed struct _le_read_remote_used_features_cp{ - uint16_t handle; -} PACKED le_read_remote_used_features_cp; -#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2 - -#define OCF_LE_ENCRYPT 0x0017 -typedef __packed struct _le_encrypt_cp{ - uint8_t key[16]; - uint8_t plaintext[16]; -} PACKED le_encrypt_cp; -#define LE_ENCRYPT_CP_SIZE 32 - -typedef __packed struct _le_encrypt_rp{ - uint8_t status; - uint8_t encdata[16]; -} PACKED le_encrypt_rp; -#define LE_ENCRYPT_RP_SIZE 17 - -#define OCF_LE_RAND 0x0018 -typedef __packed struct _le_rand_rp{ - uint8_t status; - uint8_t random[8]; -} PACKED le_rand_rp; -#define LE_RAND_RP_SIZE 9 - -#define OCF_LE_START_ENCRYPTION 0x0019 -typedef __packed struct _le_start_encryption_cp{ - uint16_t handle; - uint8_t random[8]; - uint16_t diversifier; - uint8_t key[16]; -} PACKED le_start_encryption_cp; -#define LE_START_ENCRYPTION_CP_SIZE 28 - -#define OCF_LE_LTK_REPLY 0x001A -typedef __packed struct _le_ltk_reply_cp{ - uint16_t handle; - uint8_t key[16]; -} PACKED le_ltk_reply_cp; -#define LE_LTK_REPLY_CP_SIZE 18 - -typedef __packed struct _le_ltk_reply_rp{ - uint8_t status; - uint16_t handle; -} PACKED le_ltk_reply_rp; -#define LE_LTK_REPLY_RP_SIZE 3 - -#define OCF_LE_LTK_NEG_REPLY 0x001B -typedef __packed struct _le_ltk_neg_reply_cp{ - uint16_t handle; -} PACKED le_ltk_neg_reply_cp; -#define LE_LTK_NEG_REPLY_CP_SIZE 2 - -typedef __packed struct _le_ltk_neg_reply_rp{ - uint8_t status; - uint16_t handle; -} PACKED le_ltk_neg_reply_rp; -#define LE_LTK_NEG_REPLY_RP_SIZE 3 - -#define OCF_LE_READ_SUPPORTED_STATES 0x001C -typedef __packed struct _le_read_supported_states_rp{ - uint8_t status; - uint8_t states[8]; -} PACKED le_read_supported_states_rp; -#define LE_READ_SUPPORTED_STATES_RP_SIZE 9 - -#define OCF_LE_RECEIVER_TEST 0x001D -typedef __packed struct _le_receiver_test_cp{ - uint8_t frequency; -} PACKED le_receiver_test_cp; -#define LE_RECEIVER_TEST_CP_SIZE 1 - -#define OCF_LE_TRANSMITTER_TEST 0x001E -typedef __packed struct _le_transmitter_test_cp{ - uint8_t frequency; - uint8_t length; - uint8_t payload; -} PACKED le_transmitter_test_cp; -#define LE_TRANSMITTER_TEST_CP_SIZE 3 - -#define OCF_LE_TEST_END 0x001F -typedef __packed struct _le_test_end_rp{ - uint8_t status; - uint16_t num_pkts; -} PACKED le_test_end_rp; -#define LE_TEST_END_RP_SIZE 3 - -/* Vendor specific commands */ -#define OGF_VENDOR_CMD 0x3f - - -/*------------- Events -------------*/ -#define EVT_CONN_COMPLETE 0x03 -typedef __packed struct _evt_conn_complete{ - uint8_t status; - uint16_t handle; - tBDAddr bdaddr; - uint8_t link_type; - uint8_t encr_mode; -} PACKED evt_conn_complete; -#define EVT_CONN_COMPLETE_SIZE 13 - -#define EVT_DISCONN_COMPLETE 0x05 -typedef __packed struct _evt_disconn_complete{ - uint8_t status; - uint16_t handle; - uint8_t reason; -} PACKED evt_disconn_complete; -#define EVT_DISCONN_COMPLETE_SIZE 4 - -#define EVT_ENCRYPT_CHANGE 0x08 -typedef __packed struct _evt_encrypt_change{ - uint8_t status; - uint16_t handle; - uint8_t encrypt; -} PACKED evt_encrypt_change; -#define EVT_ENCRYPT_CHANGE_SIZE 5 - -#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C - -#define EVT_CMD_COMPLETE 0x0E -typedef __packed struct _evt_cmd_complete{ - uint8_t ncmd; - uint16_t opcode; -} PACKED evt_cmd_complete; -#define EVT_CMD_COMPLETE_SIZE 3 - -#define EVT_CMD_STATUS 0x0F -typedef __packed struct _evt_cmd_status{ - uint8_t status; - uint8_t ncmd; - uint16_t opcode; -} PACKED evt_cmd_status; -#define EVT_CMD_STATUS_SIZE 4 - -#define EVT_HARDWARE_ERROR 0x10 -typedef __packed struct _evt_hardware_error{ - uint8_t code; -} PACKED evt_hardware_error; -#define EVT_HARDWARE_ERROR_SIZE 1 - -#define EVT_NUM_COMP_PKTS 0x13 -typedef __packed struct _evt_num_comp_pkts{ - uint8_t num_hndl; - /* variable length part */ -} PACKED evt_num_comp_pkts; -#define EVT_NUM_COMP_PKTS_SIZE 1 - -/* variable length part of evt_num_comp_pkts. */ -typedef __packed struct _evt_num_comp_pkts_param{ - uint16_t hndl; - uint16_t num_comp_pkts; -} PACKED evt_num_comp_pkts_param; -#define EVT_NUM_COMP_PKTS_PARAM_SIZE 1 - -#define EVT_DATA_BUFFER_OVERFLOW 0x1A -typedef __packed struct _evt_data_buffer_overflow{ - uint8_t link_type; -} PACKED evt_data_buffer_overflow; -#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 - -#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 -typedef __packed struct _evt_encryption_key_refresh_complete{ - uint8_t status; - uint16_t handle; -} PACKED evt_encryption_key_refresh_complete; -#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3 - -#define EVT_LE_META_EVENT 0x3E -typedef __packed struct _evt_le_meta_event{ - uint8_t subevent; - uint8_t data[VARIABLE_SIZE]; -} PACKED evt_le_meta_event; -#define EVT_LE_META_EVENT_SIZE 1 - -#define EVT_LE_CONN_COMPLETE 0x01 -typedef __packed struct _evt_le_connection_complete{ - uint8_t status; - uint16_t handle; - uint8_t role; - uint8_t peer_bdaddr_type; - tBDAddr peer_bdaddr; - uint16_t interval; - uint16_t latency; - uint16_t supervision_timeout; - uint8_t master_clock_accuracy; -} PACKED evt_le_connection_complete; -#define EVT_LE_CONN_COMPLETE_SIZE 18 - -#define EVT_LE_ADVERTISING_REPORT 0x02 -typedef __packed struct _le_advertising_info{ - uint8_t evt_type; - uint8_t bdaddr_type; - tBDAddr bdaddr; - uint8_t data_length; - uint8_t data_RSSI[VARIABLE_SIZE]; // RSSI is last octect (signed integer). -} PACKED le_advertising_info; -#define LE_ADVERTISING_INFO_SIZE 9 - -#define EVT_LE_CONN_UPDATE_COMPLETE 0x03 -typedef __packed struct _evt_le_connection_update_complete{ - uint8_t status; - uint16_t handle; - uint16_t interval; - uint16_t latency; - uint16_t supervision_timeout; -} PACKED evt_le_connection_update_complete; -#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9 - -#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 -typedef __packed struct _evt_le_read_remote_used_features_complete{ - uint8_t status; - uint16_t handle; - uint8_t features[8]; -} PACKED evt_le_read_remote_used_features_complete; -#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11 - -#define EVT_LE_LTK_REQUEST 0x05 -typedef __packed struct _evt_le_long_term_key_request{ - uint16_t handle; - uint8_t random[8]; - uint16_t ediv; -} PACKED evt_le_long_term_key_request; -#define EVT_LE_LTK_REQUEST_SIZE 12 - -/** -* The event code in the @ref hci_event_pckt structure. If event code is EVT_VENDOR, -* application can use @ref evt_blue_aci structure to parse the packet. -*/ -#define EVT_VENDOR 0xFF - - -/* Command opcode pack/unpack */ -#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10)) -#define cmd_opcode_ogf(op) (op >> 10) -#define cmd_opcode_ocf(op) (op & 0x03ff) - - -struct hci_request { - uint16_t ogf; - uint16_t ocf; - int event; - void *cparam; - int clen; - void *rparam; - int rlen; -}; - -void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param); - -typedef enum { - WAITING_TYPE, - WAITING_OPCODE1, - WAITING_OPCODE2, - WAITING_EVENT_CODE, - WAITING_HANDLE, - WAITING_HANDLE_FLAG, - WAITING_PARAM_LEN, - WAITING_DATA_LEN1, - WAITING_DATA_LEN2, - WAITING_PAYLOAD -}hci_state; - -typedef void (*hci_packet_complete_callback)(void *pckt, uint16_t len); - -/* HCI library functions. */ -void hci_init(void); - -int hci_send_req(struct hci_request *r, BOOL async); - -#endif /* __HCI_INTERNAL_H_ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/link_layer.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,163 +0,0 @@ -/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** -* File Name : link_layer.h -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 19-July-2012 -* Description : Header file for BlueNRG's link layer. It contains -* definition of functions for link layer, most of which are -* mapped to HCI commands. -******************************************************************************** -* 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. -*******************************************************************************/ - -#ifndef _LINK_LAYER_H -#define _LINK_LAYER_H - -#include <ble_status.h> - -/** - *@addtogroup GAP GAP - *@brief API for GAP layer. - *@{ - */ - -/** - *@name Advertising filter - *Advertising policy for filtering (white list related) - *@{ - */ -#define NO_WHITE_LIST_USE (0x00) /**< Process scan and connection requests from all devices (i.e., the White List is not in use) */ -#define WHITE_LIST_FOR_ONLY_SCAN (0x01) /**< Process connection requests from all devices and only scan requests from devices that are in the White List */ -#define WHITE_LIST_FOR_ONLY_CONN (0x02) /**< Process scan requests from all devices and only connection requests from devices that are in the White List */ -#define WHITE_LIST_FOR_ALL (0x03) /**< Process scan and connection requests only from devices in the White List. */ -/** - * @} - */ - - -/** - * Bluetooth 48 bit address (in little-endian order). - */ -typedef uint8_t tBDAddr[6]; - - -/** - *@name Bluetooth address types - * Bluetooth address types - *@{ - */ -#define PUBLIC_ADDR (0) -#define RANDOM_ADDR (1) -#define STATIC_RANDOM_ADDR (1) -#define RESOLVABLE_PRIVATE_ADDR (2) -#define NON_RESOLVABLE_PRIVATE_ADDR (3) -/** - * @} - */ - -/** - *@name Directed advertising types - * Type of advertising during directed advertising - *@{ - */ -#define HIGH_DUTY_CYCLE_DIRECTED_ADV (1) -#define LOW_DUTY_CYCLE_DIRECTED_ADV (4) -/** - * @} - */ - -/** - * @name Advertising type - * @{ - */ - -// <<<ANDREA: commented defines (see BlueNRGGap.h)>>> -/** - * undirected scannable and connectable - */ -//#define ADV_IND (0x00) - -/** - * directed non scannable - */ -//#define ADV_DIRECT_IND (0x01) - -/** - * scannable non connectable - */ -//#define ADV_SCAN_IND (0x02) - -/** - * non-connectable and no scan response (used for passive scan) - */ -//#define ADV_NONCONN_IND (0x03) - -/** - * scan response - */ -//#define SCAN_RSP (0x04) -// <<<ANDREA>>> - -/** - * @} - */ - -/* 0X05-0XFF RESERVED */ - -/** - * @name Advertising ranges - * @{ - */ - -/** - * lowest allowed interval value for connectable types(20ms)..multiple of 625us - */ -#define ADV_INTERVAL_LOWEST_CONN (0X0020) - -/** - * highest allowed interval value (10.24s)..multiple of 625us. - */ -#define ADV_INTERVAL_HIGHEST (0X4000) - -/** - * lowest allowed interval value for non connectable types - * (100ms)..multiple of 625us. - */ -#define ADV_INTERVAL_LOWEST_NONCONN (0X00a0) - -/** - * @} - */ - -/** - * @name Advertising channels - * @{ - */ -#define ADV_CH_37 0x01 -#define ADV_CH_38 0x02 -#define ADV_CH_39 0x04 -/** - * @} - */ - -/** - * @name Scan_types Scan types - * @{ - */ -#define PASSIVE_SCAN 0 -#define ACTIVE_SCAN 1 -/** - * @} - */ - -/** - * @} - */ - - -#endif /* _LINK_LAYER_H */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/list.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** -* File Name : list.h -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 19-July-2012 -* Description : Header file for linked list library. -******************************************************************************** -* 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. -*******************************************************************************/ -#ifndef _LIST_H_ -#define _LIST_H_ - -typedef struct _tListNode { - struct _tListNode * next; - struct _tListNode * prev; -}tListNode, *pListNode; - -void list_init_head (tListNode * listHead); - -uint8_t list_is_empty (tListNode * listHead); - -void list_insert_head (tListNode * listHead, tListNode * node); - -void list_insert_tail (tListNode * listHead, tListNode * node); - -void list_remove_node (tListNode * node); - -void list_remove_head (tListNode * listHead, tListNode ** node ); - -void list_remove_tail (tListNode * listHead, tListNode ** node ); - -void list_insert_node_after (tListNode * node, tListNode * ref_node); - -void list_insert_node_before (tListNode * node, tListNode * ref_node); - -int list_get_size (tListNode * listHead); - -void list_get_next_node (tListNode * ref_node, tListNode ** node); - -void list_get_prev_node (tListNode * ref_node, tListNode ** node); - -#endif /* _LIST_H_ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/osal.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** -* File Name : osal.h -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 19-July-2012 -* Description : This header file defines the OS abstraction layer used by -* the BLE stack. OSAL defines the set of functions -* which needs to be ported to target operating system and -* target platform. -******************************************************************************** -* 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. -*******************************************************************************/ - -#ifndef __OSAL_H__ -#define __OSAL_H__ - -/****************************************************************************** - * Includes - *****************************************************************************/ -#include <hal_types.h> -#ifdef __ICCARM__ -#include <intrinsics.h> -#endif - -/****************************************************************************** - * Macros - *****************************************************************************/ - - -/****************************************************************************** - * Function Prototypes - *****************************************************************************/ - -/** - * This function copies size number of bytes from a - * memory location pointed by src to a destination - * memory location pointed by dest - * - * @param[in] dest Destination address - * @param[in] src Source address - * @param[in] size size in the bytes - * - * @return Address of the destination - */ - -extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size); - - -/** - * This function sets first number of bytes, specified - * by size, to the destination memory pointed by ptr - * to the specified value - * - * @param[in] ptr Destination address - * @param[in] value Value to be set - * @param[in] size Size in the bytes - * - * @return Address of the destination - */ - -extern void* Osal_MemSet(void *ptr, int value, unsigned int size); - -/** - * Osal_Get_Cur_Time - * - * returns the current time in milliseconds - */ -/** - * Returns the number of ticks (1 tick = 1 millisecond) - * - * @return Time in milliseconds - */ -uint32_t Osal_Get_Cur_Time(void); - - -#endif /* __OSAL_H__ */
--- a/x-nucleo-idb0xa1/BlueNRG_HCI/includes/sm.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,158 +0,0 @@ -/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** -* File Name : sm.h -* Author : AMS - HEA&RF BU -* Version : V1.0.0 -* Date : 19-July-2012 -* Description : Header file for BlueNRG's security manager. -******************************************************************************** -* 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. -*******************************************************************************/ - -#ifndef __SM_H__ -#define __SM_H__ - -/****************************************************************************** -* Macros -*****************************************************************************/ - -/** - *@addtogroup GAP GAP - *@brief API for GAP layer. - *@{ - */ - -/* IO capabilities */ -/** - * @anchor IO_capabilities - * @name IO capabilities - * @{ - */ -#define IO_CAP_DISPLAY_ONLY (0x00) -#define IO_CAP_DISPLAY_YES_NO (0x01) -#define IO_CAP_KEYBOARD_ONLY (0x02) -#define IO_CAP_NO_INPUT_NO_OUTPUT (0x03) -#define IO_CAP_KEYBOARD_DISPLAY (0x04) -/** - * @} - */ - -/** - * @anchor Auth_req - * @name Authentication requirements - * @{ - */ -#define BONDING (0x01) -#define NO_BONDING (0x00) -/** - * @} - */ - -/** - * @anchor MITM_req - * @name MITM protection requirements - * @{ - */ -#define MITM_PROTECTION_NOT_REQUIRED (0x00) -#define MITM_PROTECTION_REQUIRED (0x01) -/** - * @} - */ - -/** - * @anchor OOB_Data - * @name Out-Of-Band data - * @{ - */ -#define OOB_AUTH_DATA_ABSENT (0x00) -#define OOB_AUTH_DATA_PRESENT (0x01) -/** - * @} - */ - -/** - * @anchor Author_req - * @name Authorization requirements - * @{ - */ -#define AUTHORIZATION_NOT_REQUIRED (0x00) -#define AUTHORIZATION_REQUIRED (0x01) -/** - * @} - */ - -/** - * @anchor Conn_authorization - * @name Connection authorization - * @{ - */ -#define CONNECTION_AUTHORIZED (0x01) -#define CONNECTION_REJECTED (0x02) -/** - * @} - */ - -/** - * @anchor Use_fixed_pin - * @name Use fixed pin - * @{ - */ -#define USE_FIXED_PIN_FOR_PAIRING (0x0) -#define DONOT_USE_FIXED_PIN_FOR_PAIRING (0x01) -/** - * @} - */ - -/** - * @anchor link_security_status - * @name Link security status - * @{ - */ -#define SM_LINK_AUTHENTICATED (0x01) -#define SM_LINK_AUTHORIZED (0x02) -#define SM_LINK_ENCRYPTED (0x04) -/** - * @} - */ - -/** - * @anchor SMP_pairing_failed_codes - * @name SMP pairing failed reason codes - * @{ - */ -#define PASSKEY_ENTRY_FAILED (0x01) -#define OOB_NOT_AVAILABLE (0x02) -#define AUTH_REQ_CANNOT_BE_MET (0x03) -#define CONFIRM_VALUE_FAILED (0x04) -#define PAIRING_NOT_SUPPORTED (0x05) -#define INSUFF_ENCRYPTION_KEY_SIZE (0x06) -#define CMD_NOT_SUPPORTED (0x07) -#define UNSPECIFIED_REASON (0x08) -#define VERY_EARLY_NEXT_ATTEMPT (0x09) -#define SM_INVALID_PARAMS (0x0A) -/** - * @} - */ - -/** - * @anchor pairing_failed_codes - * @name Pairing failed error codes - * Error codes in @ref EVT_BLUE_GAP_PAIRING_CMPLT event - * @{ - */ -#define SM_PAIRING_SUCCESS (0x00) -#define SM_PAIRING_TIMEOUT (0x01) -#define SM_PAIRING_FAILED (0x02) -/** - * @} - */ - -/** - * @} - */ - -#endif /* __SM_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/ble_status.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,115 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : ble_status.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file with BLE Stack status codes. +******************************************************************************** +* 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. +*******************************************************************************/ +#ifndef __BLE_STATUS_H__ +#define __BLE_STATUS_H__ + +#include <hal_types.h> + + +/** @defgroup ble_status Bluetooth Status/Error Codes + * @{ + */ + +typedef uint8_t tBleStatus; + +/* Error Codes as specified by the specification + * according to the spec the error codes range + * from 0x00 to 0x3F + */ +#define ERR_CMD_SUCCESS (0x00) +#define BLE_STATUS_SUCCESS (0x00) +#define ERR_UNKNOWN_HCI_COMMAND (0x01) +#define ERR_UNKNOWN_CONN_IDENTIFIER (0x02) + +#define ERR_AUTH_FAILURE (0x05) +#define ERR_PIN_OR_KEY_MISSING (0x06) +#define ERR_MEM_CAPACITY_EXCEEDED (0x07) +#define ERR_CONNECTION_TIMEOUT (0x08) + +#define ERR_COMMAND_DISALLOWED (0x0C) + +#define ERR_UNSUPPORTED_FEATURE (0x11) +#define ERR_INVALID_HCI_CMD_PARAMS (0x12) +#define ERR_RMT_USR_TERM_CONN (0x13) +#define ERR_RMT_DEV_TERM_CONN_LOW_RESRCES (0x14) +#define ERR_RMT_DEV_TERM_CONN_POWER_OFF (0x15) +#define ERR_LOCAL_HOST_TERM_CONN (0x16) + +#define ERR_UNSUPP_RMT_FEATURE (0x1A) + +#define ERR_INVALID_LMP_PARAM (0x1E) +#define ERR_UNSPECIFIED_ERROR (0x1F) + +#define ERR_LL_RESP_TIMEOUT (0x22) +#define ERR_LMP_PDU_NOT_ALLOWED (0x24) + +#define ERR_INSTANT_PASSED (0x28) + +#define ERR_PAIR_UNIT_KEY_NOT_SUPP (0x29) +#define ERR_CONTROLLER_BUSY (0x3A) + +#define ERR_DIRECTED_ADV_TIMEOUT (0x3C) + +#define ERR_CONN_END_WITH_MIC_FAILURE (0x3D) + +#define ERR_CONN_FAILED_TO_ESTABLISH (0x3E) + + +#define BLE_STATUS_FAILED (0x41) +#define BLE_STATUS_INVALID_PARAMS (0x42) +#define BLE_STATUS_BUSY (0x43) +#define BLE_STATUS_INVALID_LEN_PDU (0x44) +#define BLE_STATUS_PENDING (0x45) +#define BLE_STATUS_NOT_ALLOWED (0x46) +#define BLE_STATUS_ERROR (0x47) +#define BLE_STATUS_ADDR_NOT_RESOLVED (0x48) + +#define FLASH_READ_FAILED (0x49) +#define FLASH_WRITE_FAILED (0x4A) +#define FLASH_ERASE_FAILED (0x4B) + +#define BLE_STATUS_INVALID_CID (0x50) + +#define TIMER_NOT_VALID_LAYER (0x54) +#define TIMER_INSUFFICIENT_RESOURCES (0x55) + +#define BLE_STATUS_CSRK_NOT_FOUND (0x5A) +#define BLE_STATUS_IRK_NOT_FOUND (0x5B) +#define BLE_STATUS_DEV_NOT_FOUND_IN_DB (0x5C) +#define BLE_STATUS_SEC_DB_FULL (0x5D) +#define BLE_STATUS_DEV_NOT_BONDED (0x5E) +#define BLE_STATUS_DEV_IN_BLACKLIST (0x5F) + +#define BLE_STATUS_INVALID_HANDLE (0x60) +#define BLE_STATUS_INVALID_PARAMETER (0x61) +#define BLE_STATUS_OUT_OF_HANDLE (0x62) +#define BLE_STATUS_INVALID_OPERATION (0x63) +#define BLE_STATUS_INSUFFICIENT_RESOURCES (0x64) +#define BLE_INSUFFICIENT_ENC_KEYSIZE (0x65) +#define BLE_STATUS_CHARAC_ALREADY_EXISTS (0x66) + + /* + * Library Error Codes + */ +#define BLE_STATUS_TIMEOUT (0xFF) +#define BLE_STATUS_PROFILE_ALREADY_INITIALIZED (0xF0) +#define BLE_STATUS_NULL_PARAM (0xF1) + +/** + * @} + */ + + +#endif /* __BLE_STATUS_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_aci.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,27 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file that includes commands and events for BlueNRG +* FW6.3. +******************************************************************************** +* 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. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_H__ +#define __BLUENRG_ACI_H__ + +#include "bluenrg_aci_const.h" +#include "bluenrg_gap_aci.h" +#include "bluenrg_gatt_aci.h" +#include "bluenrg_l2cap_aci.h" +#include "bluenrg_hal_aci.h" +#include "bluenrg_updater_aci.h" + +#endif /* __BLUENRG_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_aci_const.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,764 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_aci_const.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with ACI definitions for BlueNRG FW6.3. +******************************************************************************** +* 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. +*******************************************************************************/ + +#ifndef __BLUENRG_ACI_CONST_H_ +#define __BLUENRG_ACI_CONST_H_ + +#include "compiler.h" +#include "link_layer.h" +#include "hci_const.h" +#include "bluenrg_gatt_server.h" + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#define OCF_HAL_WRITE_CONFIG_DATA 0x000C + +#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F +typedef __packed struct _hal_set_tx_power_level_cp{ + uint8_t en_high_power; + uint8_t pa_level; +} PACKED hal_set_tx_power_level_cp; +#define HAL_SET_TX_POWER_LEVEL_CP_SIZE 2 + +#define OCF_HAL_DEVICE_STANDBY 0x0013 + +#define OCF_HAL_TONE_START 0x0015 +typedef __packed struct _hal_tone_start_cp{ + uint8_t rf_channel; +} PACKED hal_tone_start_cp; +#define HAL_TONE_START_CP_SIZE 1 + +#define OCF_HAL_TONE_STOP 0x0016 + +#define OCF_UPDATER_START 0x0020 +#define OCF_UPDATER_REBOOT 0x0021 + +#define OCF_GET_UPDATER_VERSION 0x0022 +typedef __packed struct _get_updater_version_rp{ + uint8_t status; + uint8_t version; +} PACKED get_updater_version_rp; +#define GET_UPDATER_VERSION_RP_SIZE 2 + +#define OCF_GET_UPDATER_BUFSIZE 0x0023 +typedef __packed struct _get_updater_bufsize_rp{ + uint8_t status; + uint8_t buffer_size; +} PACKED get_updater_bufsize_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_ERASE_BLUE_FLAG 0x0024 + +#define OCF_UPDATER_RESET_BLUE_FLAG 0x0025 + +#define OCF_UPDATER_ERASE_SECTOR 0x0026 +typedef __packed struct _updater_erase_sector_cp{ + uint32_t address; +} PACKED updater_erase_sector_cp; +#define UPDATER_ERASE_SECTOR_CP_SIZE 4 + +#define OCF_UPDATER_PROG_DATA_BLOCK 0x0027 +#define UPDATER_PROG_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_prog_data_block_cp{ + uint32_t address; + uint16_t data_len; + uint8_t data[HCI_MAX_PAYLOAD_SIZE-UPDATER_PROG_DATA_BLOCK_CP_SIZE]; +} PACKED updater_prog_data_block_cp; + +#define OCF_UPDATER_READ_DATA_BLOCK 0x0028 +typedef __packed struct _updater_read_data_block_cp{ + uint32_t address; + uint16_t data_len; +} PACKED updater_read_data_block_cp; +#define UPDATER_READ_DATA_BLOCK_CP_SIZE 6 +typedef __packed struct _updater_read_data_block_rp{ + uint8_t status; + uint8_t data[VARIABLE_SIZE]; +} PACKED updater_read_data_block_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_CALC_CRC 0x0029 +typedef __packed struct _updater_calc_crc_cp{ + uint32_t address; + uint8_t num_sectors; +} PACKED updater_calc_crc_cp; +#define UPDATER_CALC_CRC_CP_SIZE 5 +typedef __packed struct _updater_calc_crc_rp{ + uint8_t status; + uint32_t crc; +} PACKED updater_calc_crc_rp; +#define UPDATER_CALC_CRC_RP_SIZE 5 + +#define OCF_UPDATER_HW_VERSION 0x002A +typedef __packed struct _updater_hw_version_rp{ + uint8_t status; + uint8_t version; +} PACKED updater_hw_version_rp; +#define UPDATER_HW_VERSION_RP_SIZE 2 + +#define OCF_GAP_SET_NON_DISCOVERABLE 0x0081 + +#define OCF_GAP_SET_LIMITED_DISCOVERABLE 0x0082 + +#define OCF_GAP_SET_DISCOVERABLE 0x0083 + +#define OCF_GAP_SET_DIRECT_CONNECTABLE 0x0084 +typedef __packed struct _gap_set_direct_conectable_cp_IDB05A1{ + uint8_t own_bdaddr_type; + uint8_t directed_adv_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; +} PACKED gap_set_direct_conectable_cp_IDB05A1; + +typedef __packed struct _gap_set_direct_conectable_cp_IDB04A1{ + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; +} PACKED gap_set_direct_conectable_cp_IDB04A1; +#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8 + +#define OCF_GAP_SET_IO_CAPABILITY 0x0085 +typedef __packed struct _gap_set_io_capability_cp{ + uint8_t io_capability; +} PACKED gap_set_io_capability_cp; +#define GAP_SET_IO_CAPABILITY_CP_SIZE 1 + +#define OCF_GAP_SET_AUTH_REQUIREMENT 0x0086 +typedef __packed struct _gap_set_auth_requirement_cp{ + uint8_t mitm_mode; + uint8_t oob_enable; + uint8_t oob_data[16]; + uint8_t min_encryption_key_size; + uint8_t max_encryption_key_size; + uint8_t use_fixed_pin; + uint32_t fixed_pin; + uint8_t bonding_mode; +} PACKED gap_set_auth_requirement_cp; +#define GAP_SET_AUTH_REQUIREMENT_CP_SIZE 26 + +#define OCF_GAP_SET_AUTHOR_REQUIREMENT 0x0087 +typedef __packed struct _gap_set_author_requirement_cp{ + uint16_t conn_handle; + uint8_t authorization_enable; +} PACKED gap_set_author_requirement_cp; +#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 3 + +#define OCF_GAP_PASSKEY_RESPONSE 0x0088 +typedef __packed struct _gap_passkey_response_cp{ + uint16_t conn_handle; + uint32_t passkey; +} PACKED gap_passkey_response_cp; +#define GAP_PASSKEY_RESPONSE_CP_SIZE 6 + +#define OCF_GAP_AUTHORIZATION_RESPONSE 0x0089 +typedef __packed struct _gap_authorization_response_cp{ + uint16_t conn_handle; + uint8_t authorize; +} PACKED gap_authorization_response_cp; +#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 3 + +#define OCF_GAP_INIT 0x008A +typedef __packed struct _gap_init_cp_IDB05A1{ + uint8_t role; + uint8_t privacy_enabled; + uint8_t device_name_char_len; +} PACKED gap_init_cp_IDB05A1; +#define GAP_INIT_CP_SIZE_IDB05A1 3 + +typedef __packed struct _gap_init_cp_IDB04A1{ + uint8_t role; +} PACKED gap_init_cp_IDB04A1; +#define GAP_INIT_CP_SIZE_IDB04A1 1 +typedef __packed struct _gap_init_rp{ + uint8_t status; + uint16_t service_handle; + uint16_t dev_name_char_handle; + uint16_t appearance_char_handle; +} PACKED gap_init_rp; +#define GAP_INIT_RP_SIZE 7 + +#define OCF_GAP_SET_NON_CONNECTABLE 0x008B +typedef __packed struct _gap_set_non_connectable_cp_IDB05A1{ + uint8_t advertising_event_type; + uint8_t own_address_type; +#endif +} PACKED gap_set_non_connectable_cp_IDB05A1; + +typedef __packed struct _gap_set_non_connectable_cp_IDB04A1{ + uint8_t advertising_event_type; +} PACKED gap_set_non_connectable_cp_IDB04A1; + +#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE 0x008C +typedef __packed struct _gap_set_undirected_connectable_cp{ + uint8_t adv_filter_policy; + uint8_t own_addr_type; +} PACKED gap_set_undirected_connectable_cp; +#define GAP_SET_UNDIRECTED_CONNECTABLE_CP_SIZE 2 + +#define OCF_GAP_SLAVE_SECURITY_REQUEST 0x008D +typedef __packed struct _gap_slave_security_request_cp{ + uint16_t conn_handle; + uint8_t bonding; + uint8_t mitm_protection; +} PACKED gap_slave_security_request_cp; +#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 4 + +#define OCF_GAP_UPDATE_ADV_DATA 0x008E + +#define OCF_GAP_DELETE_AD_TYPE 0x008F +typedef __packed struct _gap_delete_ad_type_cp{ + uint8_t ad_type; +} PACKED gap_delete_ad_type_cp; +#define GAP_DELETE_AD_TYPE_CP_SIZE 1 + +#define OCF_GAP_GET_SECURITY_LEVEL 0x0090 +typedef __packed struct _gap_get_security_level_rp{ + uint8_t status; + uint8_t mitm_protection; + uint8_t bonding; + uint8_t oob_data; + uint8_t passkey_required; +} PACKED gap_get_security_level_rp; +#define GAP_GET_SECURITY_LEVEL_RP_SIZE 5 + +#define OCF_GAP_SET_EVT_MASK 0x0091 +typedef __packed struct _gap_set_evt_mask_cp{ + uint16_t evt_mask; +} PACKED gap_set_evt_mask_cp; +#define GAP_SET_EVT_MASK_CP_SIZE 2 + +#define OCF_GAP_CONFIGURE_WHITELIST 0x0092 + +#define OCF_GAP_TERMINATE 0x0093 +typedef __packed struct _gap_terminate_cp{ + uint16_t handle; + uint8_t reason; +} PACKED gap_terminate_cp; +#define GAP_TERMINATE_CP_SIZE 3 + +#define OCF_GAP_CLEAR_SECURITY_DB 0x0094 + +#define OCF_GAP_ALLOW_REBOND_DB 0x0095 + +typedef __packed struct _gap_allow_rebond_cp_IDB05A1{ + uint16_t conn_handle; +} PACKED gap_allow_rebond_cp_IDB05A1; + +#define OCF_GAP_START_LIMITED_DISCOVERY_PROC 0x0096 +typedef __packed struct _gap_start_limited_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_limited_discovery_proc_cp; +#define GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_GENERAL_DISCOVERY_PROC 0x0097 +typedef __packed struct _gap_start_general_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t own_address_type; + uint8_t filterDuplicates; +} PACKED gap_start_general_discovery_proc_cp; +#define GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE 6 + +#define OCF_GAP_START_NAME_DISCOVERY_PROC 0x0098 +typedef __packed struct _gap_start_name_discovery_proc_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_name_discovery_proc_cp; +#define GAP_START_NAME_DISCOVERY_PROC_CP_SIZE 24 + +#define OCF_GAP_START_AUTO_CONN_ESTABLISH_PROC 0x0099 + +#define OCF_GAP_START_GENERAL_CONN_ESTABLISH_PROC 0x009A +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB05A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_general_conn_establish_proc_cp_IDB05A1; + +typedef __packed struct _gap_start_general_conn_establish_proc_cp_IDB04A1{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t use_reconn_addr; + tBDAddr reconn_addr; +} PACKED gap_start_general_conn_establish_proc_cp_IDB04A1; + +#define OCF_GAP_START_SELECTIVE_CONN_ESTABLISH_PROC 0x009B +#define GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE 8 +typedef __packed struct _gap_start_selective_conn_establish_proc_cp{ + uint8_t scan_type; + uint16_t scan_interval; + uint16_t scan_window; + uint8_t own_address_type; + uint8_t filter_duplicates; + uint8_t num_whitelist_entries; + uint8_t addr_array[HCI_MAX_PAYLOAD_SIZE-GAP_START_SELECTIVE_CONN_ESTABLISH_PROC_CP_SIZE]; +} PACKED gap_start_selective_conn_establish_proc_cp; + +#define OCF_GAP_CREATE_CONNECTION 0x009C +typedef __packed struct _gap_create_connection_cp{ + uint16_t scanInterval; + uint16_t scanWindow; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint8_t own_bdaddr_type; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_create_connection_cp; +#define GAP_CREATE_CONNECTION_CP_SIZE 24 + +#define OCF_GAP_TERMINATE_GAP_PROCEDURE 0x009D + +#define OCF_GAP_START_CONNECTION_UPDATE 0x009E +typedef __packed struct _gap_start_connection_update_cp{ + uint16_t conn_handle; + uint16_t conn_min_interval; + uint16_t conn_max_interval; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_conn_length; + uint16_t max_conn_length; +} PACKED gap_start_connection_update_cp; +#define GAP_START_CONNECTION_UPDATE_CP_SIZE 14 + +#define OCF_GAP_SEND_PAIRING_REQUEST 0x009F +typedef __packed struct _gap_send_pairing_request_cp{ + uint16_t conn_handle; + uint8_t force_rebond; +} PACKED gap_send_pairing_request_cp; +#define GAP_GAP_SEND_PAIRING_REQUEST_CP_SIZE 3 + +#define OCF_GAP_RESOLVE_PRIVATE_ADDRESS 0x00A0 +typedef __packed struct _gap_resolve_private_address_cp{ + tBDAddr address; +} PACKED gap_resolve_private_address_cp; +#define GAP_RESOLVE_PRIVATE_ADDRESS_CP_SIZE 6 +typedef __packed struct _gap_resolve_private_address_rp{ + uint8_t status; + tBDAddr address; +} PACKED gap_resolve_private_address_rp; + +#define OCF_GAP_SET_BROADCAST_MODE 0x00A1 +#define GAP_SET_BROADCAST_MODE_CP_SIZE 6 +typedef __packed struct _gap_set_broadcast_mode_cp{ + uint16_t adv_interv_min; + uint16_t adv_interv_max; + uint8_t adv_type; + uint8_t own_addr_type; + uint8_t var_len_data[HCI_MAX_PAYLOAD_SIZE-GAP_SET_BROADCAST_MODE_CP_SIZE]; +} PACKED gap_set_broadcast_mode_cp; + +#define OCF_GAP_START_OBSERVATION_PROC 0x00A2 +typedef __packed struct _gap_start_observation_proc_cp{ + uint16_t scan_interval; + uint16_t scan_window; + uint8_t scan_type; + uint8_t own_address_type; + uint8_t filter_duplicates; +} PACKED gap_start_observation_proc_cp; + +#define OCF_GAP_GET_BONDED_DEVICES 0x00A3 +typedef __packed struct _gap_get_bonded_devices_rp{ + uint8_t status; + uint8_t num_addr; + uint8_t dev_list[HCI_MAX_PAYLOAD_SIZE-HCI_EVENT_HDR_SIZE-EVT_CMD_COMPLETE_SIZE-1]; +} PACKED gap_get_bonded_devices_rp; + +#define OCF_GAP_IS_DEVICE_BONDED 0x00A4 +typedef __packed struct _gap_is_device_bonded_cp{ + uint8_t peer_address_type; + tBDAddr peer_address; +} PACKED gap_is_device_bonded_cp; + + +#define OCF_GATT_INIT 0x0101 + +#define OCF_GATT_ADD_SERV 0x0102 +typedef __packed struct _gatt_add_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_serv_rp; +#define GATT_ADD_SERV_RP_SIZE 3 + +#define OCF_GATT_INCLUDE_SERV 0x0103 +typedef __packed struct _gatt_include_serv_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_include_serv_rp; +#define GATT_INCLUDE_SERV_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR 0x0104 +typedef __packed struct _gatt_add_char_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_rp; +#define GATT_ADD_CHAR_RP_SIZE 3 + +#define OCF_GATT_ADD_CHAR_DESC 0x0105 +typedef __packed struct _gatt_add_char_desc_rp{ + uint8_t status; + uint16_t handle; +} PACKED gatt_add_char_desc_rp; +#define GATT_ADD_CHAR_DESC_RP_SIZE 3 + +#define OCF_GATT_UPD_CHAR_VAL 0x0106 + +#define OCF_GATT_DEL_CHAR 0x0107 +typedef __packed struct _gatt_del_char_cp{ + uint16_t service_handle; + uint16_t char_handle; +} PACKED gatt_del_char_cp; +#define GATT_DEL_CHAR_CP_SIZE 4 + +#define OCF_GATT_DEL_SERV 0x0108 +typedef __packed struct _gatt_del_serv_cp{ + uint16_t service_handle; +} PACKED gatt_del_serv_cp; +#define GATT_DEL_SERV_CP_SIZE 2 + +#define OCF_GATT_DEL_INC_SERV 0x0109 +typedef __packed struct _gatt_del_inc_serv_cp{ + uint16_t service_handle; + uint16_t inc_serv_handle; +} PACKED gatt_del_inc_serv_cp; +#define GATT_DEL_INC_SERV_CP_SIZE 4 + +#define OCF_GATT_SET_EVT_MASK 0x010A +typedef __packed struct _gatt_set_evt_mask_cp{ + uint32_t evt_mask; +} PACKED gatt_set_evt_mask_cp; +#define GATT_SET_EVT_MASK_CP_SIZE 4 + +#define OCF_GATT_EXCHANGE_CONFIG 0x010B +typedef __packed struct _gatt_exchange_config_cp{ + uint16_t conn_handle; +} PACKED gatt_exchange_config_cp; +#define GATT_EXCHANGE_CONFIG_CP_SIZE 2 + +#define OCF_ATT_FIND_INFO_REQ 0x010C +typedef __packed struct _att_find_info_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED att_find_info_req_cp; +#define ATT_FIND_INFO_REQ_CP_SIZE 6 + +#define OCF_ATT_FIND_BY_TYPE_VALUE_REQ 0x010D +#define ATT_FIND_BY_TYPE_VALUE_REQ_CP_SIZE 9 +typedef __packed struct _att_find_by_type_value_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid[2]; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU - 7]; +} PACKED att_find_by_type_value_req_cp; + +#define OCF_ATT_READ_BY_TYPE_REQ 0x010E +#define ATT_READ_BY_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_type_req_cp; + +#define OCF_ATT_READ_BY_GROUP_TYPE_REQ 0x010F +#define ATT_READ_BY_GROUP_TYPE_REQ_CP_SIZE 7 // without UUID +typedef __packed struct _att_read_by_group_type_req_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED att_read_by_group_type_req_cp; + +#define OCF_ATT_PREPARE_WRITE_REQ 0x0110 +#define ATT_PREPARE_WRITE_REQ_CP_SIZE 7 // without attr_val +typedef __packed struct _att_prepare_write_req_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t value_offset; + uint8_t attr_val_len; + uint8_t attr_val[ATT_MTU-5]; +} PACKED att_prepare_write_req_cp; + +#define OCF_ATT_EXECUTE_WRITE_REQ 0x0111 +typedef __packed struct _att_execute_write_req_cp{ + uint16_t conn_handle; + uint8_t execute; +} PACKED att_execute_write_req_cp; +#define ATT_EXECUTE_WRITE_REQ_CP_SIZE 3 + +#define OCF_GATT_DISC_ALL_PRIM_SERVICES 0X0112 +typedef __packed struct _gatt_disc_all_prim_serivces_cp{ + uint16_t conn_handle; +} PACKED gatt_disc_all_prim_services_cp; +#define GATT_DISC_ALL_PRIM_SERVICES_CP_SIZE 2 + +#define OCF_GATT_DISC_PRIM_SERVICE_BY_UUID 0x0113 +typedef __packed struct _gatt_disc_prim_service_by_uuid_cp{ + uint16_t conn_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_disc_prim_service_by_uuid_cp; +#define GATT_DISC_PRIM_SERVICE_BY_UUID_CP_SIZE 3 // Without uuid + +#define OCF_GATT_FIND_INCLUDED_SERVICES 0X0114 +typedef __packed struct _gatt_disc_find_included_services_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; +} PACKED gatt_find_included_services_cp; +#define GATT_FIND_INCLUDED_SERVICES_CP_SIZE 6 + +#define OCF_GATT_DISC_ALL_CHARAC_OF_SERV 0X0115 +typedef __packed struct _gatt_disc_all_charac_of_serv_cp{ + uint16_t conn_handle; + uint16_t start_attr_handle; + uint16_t end_attr_handle; +} PACKED gatt_disc_all_charac_of_serv_cp; +#define GATT_DISC_ALL_CHARAC_OF_SERV_CP_SIZE 6 + +#define OCF_GATT_DISC_CHARAC_BY_UUID 0X0116 + +#define OCF_GATT_DISC_ALL_CHARAC_DESCRIPTORS 0X0117 +typedef __packed struct _gatt_disc_all_charac_descriptors_cp{ + uint16_t conn_handle; + uint16_t char_val_handle; + uint16_t char_end_handle; +} PACKED gatt_disc_all_charac_descriptors_cp; +#define GATT_DISC_ALL_CHARAC_DESCRIPTORS_CP_SIZE 6 + +#define OCF_GATT_READ_CHARAC_VAL 0x0118 +typedef __packed struct _gatt_read_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_val_cp; +#define GATT_READ_CHARAC_VAL_CP_SIZE 4 + +#define OCF_GATT_READ_USING_CHARAC_UUID 0x0109 +typedef __packed struct _gatt_read_using_charac_uuid_cp{ + uint16_t conn_handle; + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid_type; + uint8_t uuid[16]; +} PACKED gatt_read_using_charac_uuid_cp; +#define GATT_READ_USING_CHARAC_UUID_CP_SIZE 7 // without UUID + +#define OCF_GATT_READ_LONG_CHARAC_VAL 0x011A +typedef __packed struct _gatt_read_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_val_cp; +#define GATT_READ_LONG_CHARAC_VAL_CP_SIZE 6 + +#define OCF_GATT_READ_MULTIPLE_CHARAC_VAL 0x011B +#define GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE 3 // without set_of_handles +typedef __packed struct _gatt_read_multiple_charac_val_cp{ + uint16_t conn_handle; + uint8_t num_handles; + uint8_t set_of_handles[HCI_MAX_PAYLOAD_SIZE-GATT_READ_MULTIPLE_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_read_multiple_charac_val_cp; + +#define OCF_GATT_WRITE_CHAR_VALUE 0x011C + +#define OCF_GATT_WRITE_LONG_CHARAC_VAL 0x011D +#define GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_val_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_VAL_CP_SIZE]; +} PACKED gatt_write_long_charac_val_cp; + +#define OCF_GATT_WRITE_CHARAC_RELIABLE 0x011E +#define GATT_WRITE_CHARAC_RELIABLE_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_charac_reliable_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_CHARAC_RELIABLE_CP_SIZE]; +} PACKED gatt_write_charac_reliable_cp; + +#define OCF_GATT_WRITE_LONG_CHARAC_DESC 0x011F +#define GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE 7 // without set_of_handles +typedef __packed struct _gatt_write_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; + uint8_t val_len; + uint8_t attr_val[HCI_MAX_PAYLOAD_SIZE-GATT_WRITE_LONG_CHARAC_DESC_CP_SIZE]; +} PACKED gatt_write_long_charac_desc_cp; + +#define OCF_GATT_READ_LONG_CHARAC_DESC 0x0120 +typedef __packed struct _gatt_read_long_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint16_t val_offset; +} PACKED gatt_read_long_charac_desc_cp; +#define GATT_READ_LONG_CHARAC_DESC_CP_SIZE 6 + +#define OCF_GATT_WRITE_CHAR_DESCRIPTOR 0x0121 + +#define OCF_GATT_READ_CHAR_DESCRIPTOR 0x0122 +typedef __packed struct _gatt_read_charac_desc_cp{ + uint16_t conn_handle; + uint16_t attr_handle; +} PACKED gatt_read_charac_desc_cp; +#define GATT_READ_CHAR_DESCRIPTOR_CP_SIZE 4 + +#define OCF_GATT_WRITE_WITHOUT_RESPONSE 0x0123 +#define GATT_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 3]; +} PACKED gatt_write_without_resp_cp; + +#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE 0x0124 +#define GATT_SIGNED_WRITE_WITHOUT_RESPONSE_CP_SIZE 5 // without attr_val +typedef __packed struct _gatt_signed_write_without_resp_cp{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t val_len; + uint8_t attr_val[ATT_MTU - 13]; +} PACKED gatt_signed_write_without_resp_cp; + +#define OCF_GATT_CONFIRM_INDICATION 0x0125 +typedef __packed struct _gatt_confirm_indication_cp{ + uint16_t conn_handle; +} PACKED gatt_confirm_indication_cp; +#define GATT_CONFIRM_INDICATION_CP_SIZE 2 + +#define OCF_GATT_WRITE_RESPONSE 0x0126 + +#define OCF_GATT_ALLOW_READ 0x0127 +typedef __packed struct _gatt_allow_read_cp{ + uint16_t conn_handle; +} PACKED gatt_allow_read_cp; +#define GATT_ALLOW_READ_CP_SIZE 2 + +#define OCF_GATT_SET_SECURITY_PERMISSION 0x0128 +typedef __packed struct _gatt_set_security_permission_cp{ + uint16_t service_handle; + uint16_t attr_handle; + uint8_t security_permission; +} PACKED gatt_set_security_permission_cp; +#define GATT_GATT_SET_SECURITY_PERMISSION_CP_SIZE 5 + +#define OCF_GATT_SET_DESC_VAL 0x0129 + +#define OCF_GATT_READ_HANDLE_VALUE 0x012A +typedef __packed struct _gatt_read_handle_val_cp{ + uint16_t attr_handle; +} PACKED gatt_read_handle_val_cp; +#define GATT_READ_HANDLE_VALUE_RP_SIZE 3 +typedef __packed struct _gatt_read_handle_val_rp{ + uint8_t status; + uint16_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_RP_SIZE]; +} PACKED gatt_read_handle_val_rp; + +#define OCF_GATT_READ_HANDLE_VALUE_OFFSET 0x012B +typedef __packed struct _gatt_read_handle_val_offset_cp{ + uint16_t attr_handle; + uint8_t offset; +} PACKED gatt_read_handle_val_offset_cp; +#define GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE 2 +typedef __packed struct _gatt_read_handle_val_offset_rp{ + uint8_t status; + uint8_t value_len; + uint8_t value[HCI_MAX_PAYLOAD_SIZE-GATT_READ_HANDLE_VALUE_OFFSET_RP_SIZE]; +} PACKED gatt_read_handle_val_offset_rp; + +#define OCF_L2CAP_CONN_PARAM_UPDATE_REQ 0x0181 +typedef __packed struct _l2cap_conn_param_update_req_cp{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; +} PACKED l2cap_conn_param_update_req_cp; +#define L2CAP_CONN_PARAM_UPDATE_REQ_CP_SIZE 10 + +#define OCF_L2CAP_CONN_PARAM_UPDATE_RESP 0x0182 +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB05A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint16_t min_ce_length; + uint16_t max_ce_length; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB05A1; + +typedef __packed struct _l2cap_conn_param_update_resp_cp_IDB04A1{ + uint16_t conn_handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; + uint8_t id; + uint8_t accept; +} PACKED l2cap_conn_param_update_resp_cp_IDB04A1; + +/** + * @defgroup BlueNRG_Events BlueNRG events (vendor specific) + * @{ + */ + +/** + * Vendor specific event for BlueNRG. + */ +typedef __packed struct _evt_blue_aci{ + uint16_t ecode; /**< One of the BlueNRG event codes. */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_blue_aci; + + +/** + * @} + */ + +#endif /* __BLUENRG_ACI_CONST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gap.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,224 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gap.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GAP layer. +******************************************************************************** +* 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. +*******************************************************************************/ +#ifndef __BNRG_GAP_H__ +#define __BNRG_GAP_H__ + +#include <link_layer.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + * @name GAP UUIDs + * @{ + */ +#define GAP_SERVICE_UUID (0x1800) +#define DEVICE_NAME_UUID (0x2A00) +#define APPEARANCE_UUID (0x2A01) +#define PERIPHERAL_PRIVACY_FLAG_UUID (0x2A02) +#define RECONNECTION_ADDR_UUID (0x2A03) +#define PERIPHERAL_PREFERRED_CONN_PARAMS_UUID (0x2A04) +/** + * @} + */ + +/** + * @name Characteristic value lengths + * @{ + */ +#define DEVICE_NAME_CHARACTERISTIC_LEN (8) +#define APPEARANCE_CHARACTERISTIC_LEN (2) +#define PERIPHERAL_PRIVACY_CHARACTERISTIC_LEN (1) +#define RECONNECTION_ADDR_CHARACTERISTIC_LEN (6) +#define PERIPHERAL_PREF_CONN_PARAMS_CHARACTERISTIC_LEN (8) +/** + * @} + */ + +/*------------- AD types for adv data and scan response data ----------------*/ + +/** + * @defgroup AD_Types AD Types + * @brief AD Types + * @{ + */ + +/* FLAGS AD type */ +#define AD_TYPE_FLAGS (0x01) +/* flag bits */ +/** + * @anchor Flags_AD_Type_bits + * @name Flags AD Type bits + * @brief Bits in Flags AD Type + * @{ + */ +#define FLAG_BIT_LE_LIMITED_DISCOVERABLE_MODE (0x01) +#define FLAG_BIT_LE_GENERAL_DISCOVERABLE_MODE (0x02) +#define FLAG_BIT_BR_EDR_NOT_SUPPORTED (0x04) +#define FLAG_BIT_LE_BR_EDR_CONTROLLER (0x08) +#define FLAG_BIT_LE_BR_EDR_HOST (0x10) +/** + * @} + */ + +/** + * @name Service UUID AD types + * @{ + */ +#define AD_TYPE_16_BIT_SERV_UUID (0x02) +#define AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST (0x03) +#define AD_TYPE_32_BIT_SERV_UUID (0x04) +#define AD_TYPE_32_BIT_SERV_UUID_CMPLT_LIST (0x05) +#define AD_TYPE_128_BIT_SERV_UUID (0x06) +#define AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST (0x07) +/** + * @} + */ + +/* LOCAL NAME AD types */ +/** + * @name Local name AD types + * @{ + */ +#define AD_TYPE_SHORTENED_LOCAL_NAME (0x08) +#define AD_TYPE_COMPLETE_LOCAL_NAME (0x09) +/** + * @} + */ + +/* TX power level AD type*/ +#define AD_TYPE_TX_POWER_LEVEL (0x0A) + +/* Class of device */ +#define AD_TYPE_CLASS_OF_DEVICE (0x0D) + +/* security manager TK value AD type */ +#define AD_TYPE_SEC_MGR_TK_VALUE (0x10) + +/* security manager OOB flags */ +#define AD_TYPE_SEC_MGR_OOB_FLAGS (0x11) + +/* slave connection interval AD type */ +#define AD_TYPE_SLAVE_CONN_INTERVAL (0x12) + +/* service solicitation UUID list Ad types*/ +/** + * @name Service solicitation UUID list AD types + * @{ + */ +#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST (0x14) +#define AD_TYPE_SERV_SOLICIT_32_BIT_UUID_LIST (0x1F) +#define AD_TYPE_SERV_SOLICIT_128_BIT_UUID_LIST (0x15) +/** + * @} + */ + +/* service data AD type */ +#define AD_TYPE_SERVICE_DATA (0x16) + +/* manufaturer specific data AD type */ +#define AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF) + +/** + * @} + */ + +#define MAX_ADV_DATA_LEN (31) + +#define DEVICE_NAME_LEN (7) +#define BD_ADDR_SIZE (6) + +/** + * @name Privacy flag values + * @{ + */ +#define PRIVACY_ENABLED (0x01) +#define PRIVACY_DISABLED (0x00) +/** + * @} + */ + +/** + * @name Intervals + * Intervals in terms of 625 micro sec + * @{ + */ +#define DIR_CONN_ADV_INT_MIN (0x190)/*250ms*/ +#define DIR_CONN_ADV_INT_MAX (0x320)/*500ms*/ +#define UNDIR_CONN_ADV_INT_MIN (0x800)/*1.28s*/ +#define UNDIR_CONN_ADV_INT_MAX (0x1000)/*2.56s*/ +#define LIM_DISC_ADV_INT_MIN (0x190)/*250ms*/ +#define LIM_DISC_ADV_INT_MAX (0x320)/*500ms*/ +#define GEN_DISC_ADV_INT_MIN (0x800)/*1.28s*/ +#define GEN_DISC_ADV_INT_MAX (0x1000)/*2.56s*/ +/** + * @} + */ + +/** + * @name Timeout values + * @{ + */ +#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */ +#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */ +/** + * @} + */ + +/** + * @anchor gap_roles + * @name GAP Roles + * @{ +*/ +#define GAP_PERIPHERAL_ROLE_IDB05A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB05A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB05A1 (0x04) +#define GAP_OBSERVER_ROLE_IDB05A1 (0x08) + +#define GAP_PERIPHERAL_ROLE_IDB04A1 (0x01) +#define GAP_BROADCASTER_ROLE_IDB04A1 (0x02) +#define GAP_CENTRAL_ROLE_IDB04A1 (0x03) +#define GAP_OBSERVER_ROLE_IDB04A1 (0x04) +/** + * @} + */ + +/** + * @anchor gap_procedure_codes + * @name GAP procedure codes + * Procedure codes for EVT_BLUE_GAP_PROCEDURE_COMPLETE event + * and aci_gap_terminate_gap_procedure() command. + * @{ + */ +#define GAP_LIMITED_DISCOVERY_PROC (0x01) +#define GAP_GENERAL_DISCOVERY_PROC (0x02) +#define GAP_NAME_DISCOVERY_PROC (0x04) +#define GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC (0x08) +#define GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC (0x10) +#define GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC (0x20) +#define GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC (0x40) +#define GAP_OBSERVATION_PROC_IDB05A1 (0x80) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BNRG_GAP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gap_aci.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,1211 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gap_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GAP commands for BlueNRG FW6.3. +******************************************************************************** +* 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. +*******************************************************************************/ + +#ifndef __BLUENRG_GAP_ACI_H__ +#define __BLUENRG_GAP_ACI_H__ + +/** + *@addtogroup GAP GAP + *@brief GAP layer. + *@{ + */ + +/** + *@defgroup GAP_Functions GAP functions + *@brief API for GAP layer. + *@{ + */ + +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB05A1(1, 0, 0x07, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role Bitmap of allowed roles: see @ref gap_roles "GAP roles". + * @param privacy_enabled Enable (1) or disable (0) privacy. + * @param device_name_char_len Length of the device name characteristic + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB05A1(uint8_t role, uint8_t privacy_enabled, + uint8_t device_name_char_len, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); +/** + * @brief Initialize the GAP layer. + * @note Register the GAP service with the GATT. + * All the standard GAP characteristics will also be added: + * @li Device Name + * @li Appearance + * @li Peripheral Privacy Flag (peripheral role only) + * @li Reconnection Address (peripheral role only) + * @li Peripheral Preferred Connection Parameters (peripheral role only) + * @code + + tBleStatus ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + ret = aci_gap_init_IDB04A1(1, &service_handle, &dev_name_char_handle, &appearance_char_handle); + if(ret){ + PRINTF("GAP_Init failed.\n"); + reboot(); + } + const char *name = "BlueNRG"; + ret = aci_gatt_update_char_value(service_handle, dev_name_char_handle, 0, strlen(name), (uint8_t *)name); + if(ret){ + PRINTF("aci_gatt_update_char_value failed.\n"); + } + * @endcode + * @param role One of the allowed roles: @ref GAP_PERIPHERAL_ROLE or @ref GAP_CENTRAL_ROLE. See @ref gap_roles "GAP roles". + * @param[out] service_handle Handle of the GAP service. + * @param[out] dev_name_char_handle Device Name Characteristic handle + * @param[out] appearance_char_handle Appearance Characteristic handle + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_init_IDB04A1(uint8_t role, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); + +/** + * @brief Set the Device in non-discoverable mode. + * @note This command will disable the LL advertising. + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_discoverable(void); + +/** + * @brief Put the device in limited discoverable mode + * (as defined in GAP specification volume 3, section 9.2.3). + * @note The device will be discoverable for TGAP (lim_adv_timeout) = 180 seconds. + * The advertising can be disabled at any time by issuing + * aci_gap_set_non_discoverable() command. + * The AdvIntervMin and AdvIntervMax parameters are optional. If both + * are set to 0, the GAP will use default values (250 ms and 500 ms respectively). + * Host can set the Local Name, a Service UUID list and the Slave Connection + * Minimum and Maximum. 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. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following + * standard AD types: + * @li AD Flags + * @li TX Power Level + * + * When advertising timeout happens (i.e. limited discovery period has elapsed), controller generates + * @ref EVT_BLUE_GAP_LIMITED_DISCOVERABLE event. + * + * Example: + * @code + * + * #define ADV_INTERVAL_MIN_MS 100 + * #define ADV_INTERVAL_MAX_MS 200 + * + * tBleStatus ret; + * + * 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_limited_discoverable(ADV_IND, (ADV_INTERVAL_MIN_MS*1000)/0.625, + * (ADV_INTERVAL_MAX_MS*1000)/0.625, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * sizeof(serviceUUIDList), serviceUUIDList, + * 0, 0); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 250 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 500 ms + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg NO_WHITE_LIST_USE + * @arg WHITE_LIST_FOR_ONLY_SCAN + * @arg WHITE_LIST_FOR_ONLY_CONN + * @arg WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_limited_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); +/** + * @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). + * 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. + * The total size of data in advertising packet cannot exceed 31 bytes. + * With this command, the BLE Stack will also add automatically the following standard AD types: + * @li AD Flags + * @li TX Power Level + * + * Usage example: + * + * @code + * + * #define ADV_INTERVAL_MIN_MS 800 + * #define ADV_INTERVAL_MAX_MS 900 + * #define CONN_INTERVAL_MIN_MS 100 + * #define CONN_INTERVAL_MAX_MS 300 + * + * tBleStatus ret; + * + * 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, + * STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * sizeof(local_name), local_name, + * 0, NULL, + * (CONN_INTERVAL_MIN_MS*1000)/1250, + * (CONN_INTERVAL_MAX_MS*1000)/1250); + * @endcode + * + * @param AdvType One of the advertising types: + * @arg @ref ADV_IND Connectable undirected advertising + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param AdvIntervMin Minimum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 1.28 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param AdvIntervMax Maximum advertising interval. + * Range: 0x0020 to 0x4000 + * Default: 2.56 s + * Time = N * 0.625 msec + * Time Range: 20 ms to 10.24 sec (minimum 100 ms for ADV_SCAN_IND or ADV_NONCONN_IND). + * @param OwnAddrType Type of our address used during advertising + * (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param AdvFilterPolicy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ONLY_SCAN + * @arg @ref WHITE_LIST_FOR_ONLY_CONN + * @arg @ref WHITE_LIST_FOR_ALL + * @param LocalNameLen Length of LocalName array. + * @param LocalName Array containing the Local Name AD data. First byte is the AD type: + * @ref AD_TYPE_SHORTENED_LOCAL_NAME or @ref AD_TYPE_COMPLETE_LOCAL_NAME. + * @param ServiceUUIDLen Length of ServiceUUIDList array. + * @param ServiceUUIDList This is the list of the UUIDs AD Types as defined in Volume 3, + * Section 11.1.1 of GAP Specification. First byte is the AD Type. + * @arg @ref AD_TYPE_16_BIT_SERV_UUID + * @arg @ref AD_TYPE_16_BIT_SERV_UUID_CMPLT_LIST + * @arg @ref AD_TYPE_128_BIT_SERV_UUID + * @arg @ref AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST + * @param SlaveConnIntervMin Slave connection interval minimum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * Connection interval is defined in the following manner: + * connIntervalmin = Slave_Conn_Interval_Min x 1.25ms + * Slave_Conn_Interval_Min range: 0x0006 to 0x0C80 + * Value of 0xFFFF indicates no specific minimum. + * @param SlaveConnIntervMax Slave connection interval maximum value suggested by Peripheral. + * If SlaveConnIntervMin and SlaveConnIntervMax are not 0x0000, + * Slave Connection Interval Range AD structure will be added in advertising + * data. + * ConnIntervalmax = Slave_Conn_Interval_Max x 1.25ms + * Slave_Conn_Interval_Max range: 0x0006 to 0x0C80 + * Slave_ Conn_Interval_Max shall be equal to or greater than the Slave_Conn_Interval_Min. + * Value of 0xFFFF indicates no specific maximum. + * + * @retval tBleStatus Value indicating success or error code. + */ +tBleStatus aci_gap_set_discoverable(uint8_t AdvType, uint16_t AdvIntervMin, uint16_t AdvIntervMax, + uint8_t OwnAddrType, uint8_t AdvFilterPolicy, uint8_t LocalNameLen, + const char *LocalName, uint8_t ServiceUUIDLen, uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); + +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address[] = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB05A1(PUBLIC_ADDR, HIGH_DUTY_CYCLE_DIRECTED_ADV, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param OwnAddrType Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param directed_adv_type Type of directed advertising (@ref HIGH_DUTY_CYCLE_DIRECTED_ADV, @ref LOW_DUTY_CYCLE_DIRECTED_ADV). + * @param InitiatorAddrType Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param InitiatorAddr Initiator's address (Little Endian). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB05A1(uint8_t own_addr_type, uint8_t directed_adv_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr); +/** + * @brief Set the Device in direct connectable mode (as defined in GAP specification Volume 3, Section 9.3.3). + * @note If the privacy is enabled, the reconnection address is used for advertising, otherwise the address + * of the type specified in OwnAddrType is used. The device will be in directed connectable mode only + * for 1.28 seconds. If no connection is established within this duration, the device enters non + * discoverable mode and advertising will have to be again enabled explicitly. + * The controller generates a @ref EVT_LE_CONN_COMPLETE event with the status set to @ref HCI_DIRECTED_ADV_TIMEOUT + * if the connection was not established and 0x00 if the connection was successfully established. + * + * Usage example: + * @code + * + * tBleStatus ret; + * + * const uint8_t central_address = {0x43,0x27,0x84,0xE1,0x80,0x02}; + * ret = aci_gap_set_direct_connectable_IDB04A1(PUBLIC_ADDR, PUBLIC_ADDR, central_address); + * @endcode + * + * + * + * @param OwnAddrType Type of our address used during advertising (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param InitiatorAddrType Type of peer address (@ref PUBLIC_ADDR,@ref STATIC_RANDOM_ADDR). + * @param InitiatorAddr Initiator's address (Little Endian). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_direct_connectable_IDB04A1(uint8_t own_addr_type, uint8_t initiator_addr_type, const uint8_t *initiator_addr); + +/** + * @brief Set the IO capabilities of the device. + * @note This command has to be given only when the device is not in a connected state. + * @param io_capability One of the allowed codes for IO Capability: + * @arg @ref IO_CAP_DISPLAY_ONLY + * @arg @ref IO_CAP_DISPLAY_YES_NO + * @arg @ref IO_CAP_KEYBOARD_ONLY + * @arg @ref IO_CAP_NO_INPUT_NO_OUTPUT + * @arg @ref IO_CAP_KEYBOARD_DISPLAY + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_io_capability(uint8_t io_capability); + +/** + * @brief Set the authentication requirements for the device. + * @note If the oob_enable is set to 0, oob_data will be ignored. + * This command has to be given only when the device is not in a connected state. + * @param mitm_mode MITM mode: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @param oob_enable If OOB data are present or not: + * @arg @ref OOB_AUTH_DATA_ABSENT + * @arg @ref OOB_AUTH_DATA_PRESENT + * @param oob_data Out-Of-Band data + * @param min_encryption_key_size Minimum size of the encryption key to be used during the pairing process + * @param max_encryption_key_size Maximum size of the encryption key to be used during the pairing process + * @param use_fixed_pin If application wants to use a fixed pin or not: + * @arg @ref USE_FIXED_PIN_FOR_PAIRING + * @arg @ref DONOT_USE_FIXED_PIN_FOR_PAIRING + * If a fixed pin is not used, it has to be provided by the application with + * aci_gap_pass_key_response() after @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param fixed_pin If use_fixed_pin is USE_FIXED_PIN_FOR_PAIRING, this is the value of the pin that will + * be used during pairing if MIMT protection is enabled. Any value between 0 to 999999 is + * accepted. + * @param bonding_mode One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_auth_requirement(uint8_t mitm_mode, + uint8_t oob_enable, + uint8_t oob_data[16], + uint8_t min_encryption_key_size, + uint8_t max_encryption_key_size, + uint8_t use_fixed_pin, + uint32_t fixed_pin, + uint8_t bonding_mode); + /** + * @brief Set the authorization requirements of the device. + * @note This command has to be given only when the device is not in a connected state. + * @param conn_handle Handle of the connection in case BlueNRG is configured as a master (otherwise it can be also 0). + * @param authorization_enable @arg @ref AUTHORIZATION_NOT_REQUIRED : Authorization not required + * @arg @ref AUTHORIZATION_REQUIRED : Authorization required. This enables + * the authorization requirement in the device and when a remote device + * tries to connect to GATT server, @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST event + * will be sent to the Host. + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_author_requirement(uint16_t conn_handle, uint8_t authorization_enable); + +/** + * @brief Provide the pass key that will be used during pairing. + * @note This command should be sent by the Host in response to @ref EVT_BLUE_GAP_PASS_KEY_REQUEST event. + * @param conn_handle Connection handle + * @param passkey Pass key that will be used during the pairing process. Must be a number between + * 0 and 999999. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_pass_key_response(uint16_t conn_handle, uint32_t passkey); + +/** + * @brief Authorize a device to access attributes. + * @note Application should send this command after it has received a @ref EVT_BLUE_GAP_AUTHORIZATION_REQUEST. + * + * @param conn_handle Connection handle + * @param authorize @arg @ref CONNECTION_AUTHORIZED : Authorize (accept connection) + * @arg @ref CONNECTION_REJECTED : Reject (reject connection) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_authorization_response(uint16_t conn_handle, uint8_t authorize); + +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @param own_address_type If Privacy is disabled, then the peripheral address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the peripheral address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB05A1(uint8_t adv_type, uint8_t own_address_type); +/** + * @brief Put the device into non-connectable mode. + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND : Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND : Non-connectable undirected advertising + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_non_connectable_IDB04A1(uint8_t adv_type); + +/** + * @brief Put the device into undirected connectable mode. + * @note If privacy is enabled in the device, a resolvable private address is generated and used + * as the advertiser's address. If not, the address of the type specified in own_addr_type + * is used for advertising. + * @param own_addr_type Type of our address used during advertising: + * if BLUENRG (IDB04A1) + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * else if BLUENRG_MS (IDB05A1) + * If Privacy is disabled: + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled: + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_filter_policy Filter policy: + * @arg @ref NO_WHITE_LIST_USE + * @arg @ref WHITE_LIST_FOR_ALL + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_undirected_connectable(uint8_t own_addr_type, uint8_t adv_filter_policy); + +/** + * @brief Send a slave security request to the master. + * @note This command has to be issued to notify the master of the security requirements of the slave. + * The master may encrypt the link, initiate the pairing procedure, or reject the request. + * @param conn_handle Connection handle + * @param bonding One of the bonding modes: + * @arg @ref BONDING + * @arg @ref NO_BONDING + * @param mitm_protection If MITM protection is required or not: + * @arg @ref MITM_PROTECTION_NOT_REQUIRED + * @arg @ref MITM_PROTECTION_REQUIRED + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_slave_security_request(uint16_t conn_handle, uint8_t bonding, uint8_t mitm_protection); + +/** + * @brief Update advertising data. + * @note This command can be used to update the advertising data for a particular AD type. + * If the AD type specified does not exist, then it is added to the advertising data. + * If the overall advertising data length is more than 31 octets after the update, then + * the command is rejected and the old data is retained. + * @param AdvLen Length of AdvData array + * @param AdvData Advertisement Data, formatted as specified in Bluetooth specification + * (Volume 3, Part C, 11), including data length. It can contain more than one AD type. + * Example + * @code + * tBleStatus ret; + * 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}; + * const uint8_t manuf_data[] = {4, AD_TYPE_MANUFACTURER_SPECIFIC_DATA, 0x05, 0x02, 0x01}; + * + * ret = aci_gap_set_discoverable(ADV_IND, 0, 0, STATIC_RANDOM_ADDR, NO_WHITE_LIST_USE, + * 8, local_name, 3, serviceUUIDList, 0, 0); + * ret = aci_gap_update_adv_data(5, manuf_data); + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData); + +/** + * @brief Delete an AD Type + * @note This command can be used to delete the specified AD type from the advertisement data if + * present. + * @param ad_type One of the allowed AD types (see @ref AD_Types) + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_delete_ad_type(uint8_t ad_type); + +/** + * @brief Get the current security settings + * @note This command can be used to get the current security settings of the device. + * @param mitm_protection @arg 0: Not required + * @arg 1: Required + * @param bonding @arg 0: No bonding mode + * @arg 1: Bonding mode + * @param oob_data @arg 0: Data absent + * @arg 1: Data present + * @param passkey_required @arg 0: Not required + * @arg 1: Fixed pin is present which is being used + * @arg 2: Passkey required for pairing. An event will be generated + * when required. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_security_level(uint8_t* mitm_protection, uint8_t* bonding, + uint8_t* oob_data, uint8_t* passkey_required); + +/** + * @brief Add addresses of bonded devices into the controller's whitelist. + * @note The command will return an error if there are no devices in the database or if it was unable + * to add the device into the whitelist. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_configure_whitelist(void); + +/** + * @brief Terminate a connection. + * @note A @ref EVT_DISCONN_COMPLETE event will be generated when the link is disconnected. + * @param conn_handle Connection handle + * @param reason Reason for requesting disconnection. The error code can be any of ones as specified + * for the disconnected command in the HCI specification (See @ref HCI_Error_codes). + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason); + +/** + * @brief Clear the security database. + * @note All the devices in the security database will be removed. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_clear_security_database(void); + +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @param conn_handle + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB05A1(uint16_t conn_handle); +/** + * @brief Allows the security manager to complete the pairing procedure and re-bond with the master. + * @note This command can be issued by the application if a @ref EVT_BLUE_GAP_BOND_LOST event is generated. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_allow_rebond_IDB04A1(void); + +/** + * @brief Start the limited discovery procedure. + * @note The controller is commanded to start active scanning. When this procedure is started, + * only the devices in limited discoverable mode are returned to the upper layers. + * The procedure is terminated when either the upper layers issue a command to terminate the + * procedure by issuing the command aci_gap_terminate_gap_procedure() with the procedure code + * set to @ref GAP_LIMITED_DISCOVERY_PROC 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_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. + * @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. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the general discovery procedure. + * @note The controller is commanded to start active scanning. The procedure is terminated when + * either the upper layers issue a command to terminate the procedure by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure code set to GAP_GENERAL_DISCOVERY_PROC + * 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. + * @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. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during advertising (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filterDuplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); + +/** + * @brief Start the name discovery procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. Once a connection is established, GATT procedure is started to read the + * device name characteristic. When the read is completed (successfully or unsuccessfully), + * a @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is given to the upper layer. The event also + * contains the name of the device if the device name was read successfully. + * @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. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_name_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Start the auto connection establishment procedure. + * @note The devices specified are added to the white list of the controller and a LE_Create_Connection + * call will be made to the controller by GAP with the initiator filter policy set to + * use whitelist to determine which advertiser to connect to. When a command is issued to + * terminate the procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the + * controller by GAP. + * The procedure is terminated when either a connection is successfully established with one of + * the specified devices in the white list or the procedure is explicitly terminated by issuing + * the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. A @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is returned with + * the procedure code set to @ref GAP_AUTO_CONNECTION_ESTABLISHMENT_PROC. + * @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. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB05A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); +tBleStatus aci_gap_start_auto_conn_establish_proc_IDB04A1(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length, + uint8_t use_reconn_addr, + const tBDAddr reconn_addr, + uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @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. + * 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 + * issuing the command aci_gap_terminate_gap_procedure() with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. On completion of the procedure a + * @ref EVT_BLUE_GAP_PROCEDURE_COMPLETE event is generated with the procedure code set to + * @ref GAP_GENERAL_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval 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. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @cond BLUENRG + * @param use_reconn_addr If 1, the provided reconnection address is used as our address during the procedure (the address + * has been previously notified to the application through @ref EVT_BLUE_GAP_RECONNECTION_ADDRESS event).\n + * @param reconn_addr Reconnection address used if use_reconn_addr is 1. + * @endcond + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_general_conn_establish_proc_IDB05A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates); +tBleStatus aci_gap_start_general_conn_establish_proc_IDB04A1(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t use_reconn_addr, const tBDAddr reconn_addr); + +/** + * @brief Start a selective connection establishment procedure. + * @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 + * 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. + * The procedure is terminated when a connection is established or the upper layer terminates + * the procedure by issuing the command aci_gap_terminate_gap_procedure with the procedure + * code set to @ref GAP_SELECTIVE_CONNECTION_ESTABLISHMENT_PROC. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param scan_interval 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. + * For a number N, Time = N x 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param own_address_type Type of our address used during active scanning (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @arg 0x01: Filter duplicates + * @param num_whitelist_entries Number of devices that have to be added to the whitelist. + * @param addr_array addr_array will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_selective_conn_establish_proc(uint8_t scan_type, uint16_t scan_interval, uint16_t scan_window, + uint8_t own_address_type, uint8_t filter_duplicates, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Start the direct connection establishment procedure. + * @note A LE_Create_Connection call will be made to the controller by GAP with the initiator filter + * policy set to ignore whitelist and process connectable advertising packets only for the + * specified device. The procedure can be terminated explicitly by the upper layer by issuing + * the command aci_gap_terminate_gap_procedure(). When a command is issued to terminate the + * procedure by upper layer, a LE_Create_Connection_Cancel call will be made to the controller + * by GAP. + * On termination of the procedure, a @ref EVT_LE_CONN_COMPLETE event is returned. The procedure can + * be explicitly terminated by the upper layer by issuing the command + * aci_gap_terminate_gap_procedure() with the procedure_code set to @ref GAP_DIRECT_CONNECTION_ESTABLISHMENT_PROC. + * @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. + * For a number N, Time = N x 0.625 msec. + * @param scanWindow Amount of time for the duration of the LE scan. Scan_Window shall be less than + * or equal to Scan_Interval. The scan window should be a number in the range + * 0x0004 to 0x4000. This corresponds to a time range 2.5 msec to 10240 msec. + * For a number N, Time = N x 0.625 msec. + * @param peer_bdaddr_type Type of the peer address (@ref PUBLIC_ADDR, @ref STATIC_RANDOM_ADDR). + * @param peer_bdaddr Address of the peer device with which a connection has to be established. + * @param own_bdaddr_type Type of our address used during advertising (PUBLIC_ADDR,STATIC_RANDOM_ADDR). + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_create_connection(uint16_t scanInterval, uint16_t scanWindow, + uint8_t peer_bdaddr_type, tBDAddr peer_bdaddr, + uint8_t own_bdaddr_type, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Terminate the specified GATT 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. + */ +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code); + +/** + * @brief Start the connection parameter update procedure. + * @note Allowed by the Central to update the connection parameter of the specified connection. + * A Link Layer Connection Update procedure is started on the controller. + * On completion of the procedure, a @ref EVT_LE_CONN_UPDATE_COMPLETE event is returned to + * the upper layer. + * @param conn_handle Handle of the connection for which the update procedure has to be started. + * @param conn_min_interval Minimum value for the connection event interval. This shall be less than or + * equal to Conn_Interval_Max.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_max_interval Maximum value for the connection event interval. This shall be greater than or + * equal to Conn_Interval_Min.\n + * Range: 0x0006 to 0x0C80\n + * Time = N x 1.25 msec\n + * Time Range: 7.5 msec to 4 seconds + * @param conn_latency Slave latency for the connection in number of connection events.\n + * Range: 0x0000 to 0x01F4 + * @param supervision_timeout Supervision timeout for the LE Link.\n + * Range: 0x000A to 0x0C80\n + * Time = N x 10 msec\n + * Time Range: 100 msec to 32 seconds + * @param min_conn_length Minimum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_conn_length Maximum length of connection needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_start_connection_update(uint16_t conn_handle, uint16_t conn_min_interval, + uint16_t conn_max_interval, uint16_t conn_latency, + uint16_t supervision_timeout, uint16_t min_conn_length, + uint16_t max_conn_length); + +/** + * @brief Send a pairing request. + * @note Send the SM pairing request to start a pairing process from a Central. The authentication + * requirements and IO capabilities should be set before issuing this command using + * aci_gap_set_io_capability() and aci_gap_set_auth_requirement(). + * A @ref EVT_BLUE_GAP_PAIRING_CMPLT event is returned after the pairing process is completed. + * @param conn_handle Handle of the connection for which the pairing request has to be sent. + * @param force_rebond @arg 0x00: Pairing request is sent only if the device has not previously bonded + * @arg 0x01: Pairing request will be sent even if the device was previously bonded + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_send_pairing_request(uint16_t conn_handle, uint8_t force_rebond); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param address Address to be resolved. + * @param[in] actual_address The public or static random address of the peer device, distributed during pairing phase. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB05A1(const tBDAddr private_address, tBDAddr actual_address); + +/** + * @brief Resolve a private address. + * @note This command tries to resolve the address provided with the IRKs present in its database. If + * the address is resolved successfully with any one of the IRKs present in the database, it + * returns success. + * @param address Address to be resolved. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_resolve_private_address_IDB04A1(const tBDAddr private_address); + +/** + * @brief This command gets the list of bonded devices. + * @note It returns the number of addresses and the corresponding address types and values. + * Example: + * @code + * tBleStatus ret; + * uint8_t num_devices = 0; + * uint8_t device_list[12*7]; + * ret = aci_gap_get_bonded_devices(&num_devices, device_list, sizeof(device_list)); + * for(int i = 0; i < num_devices; i+=7){ + * uint8_t addr_type = device_list[i]; + * uint8_t addr = device_list[i+1]; + * printf("Type: %d, Addr: %02X%02X%02X%02X%02X%02X\n",addr_type,addr[5],addr[4],addr[3],addr[2],addr[1],addr[0]); + * } + * @endcode + * + * @param[in] num_devices The number of bonded devices. + * @param[in] device_list List of addresses. It contains a sequence of [address type, address] pairs, where address + * type can be @ref PUBLIC_ADDR or @arg @ref STATIC_RANDOM_ADDR. + * @param device_list_size Maximum size of the device_list buffer used to return the device list. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_get_bonded_devices(uint8_t *num_devices, uint8_t *device_list, uint8_t device_list_size); + +/** + * @brief Puts the device into broadcast mode + * @note A privacy enabled device uses either a resolvable private address or a non-resolvable private address + * as specified in the own_addr_type parameter of the command. + * @param adv_interv_min Minimum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_interv_max Maximum advertising interval. + * Range: 0x00A0 to 0x4000 + * Time = N * 0.625 msec + * Time Range: 100 ms to 10.24 sec + * @param adv_type One of the allowed advertising types: + * @arg @ref ADV_SCAN_IND Scannable undirected advertising + * @arg @ref ADV_NONCONN_IND Non connectable undirected advertising + * @param own_address_type If Privacy is disabled, the broadcaster address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the broadcaster address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param adv_data_length Length of the advertising data in the advertising packet + * @param adv_data Advertising data used by the device while advertising + * @param num_whitelist_entries Number of devices to be added to whitelist + * @param addr_array It will contain the addresses that have to be added into the whitelist. The + * format of the addr_array should be: address type followed by address. + * Example: + * @code + * uint8_t addr_array[] = {PUBLIC_ADDR,0x01,0x00,0x00,0xe1,0x80,0x02, + * PUBLIC_ADDR,0x02,0x00,0x00,0xe1,0x80,0x02}; + * @endcode + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_set_broadcast_mode_IDB05A1(uint16_t adv_interv_min, uint16_t adv_interv_max, uint8_t adv_type, + uint8_t own_addr_type, uint8_t adv_data_length, const uint8_t *adv_data, uint8_t num_whitelist_entries, + const uint8_t *addr_array); + +/** + * @brief Starts an observation procedure, when the device is in Observer role. + * @note The host enables scanning in the controller. The advertising reports are sent to the upper layer + * using standard @ref EVT_LE_ADVERTISING_REPORT subevent in @ref EVT_LE_META_EVENT. See Bluetooth + * Core v4.0, Vol. 2, part E, Ch. 7.7.65.2, LE Advertising Report Event. + * @param scan_interval 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 from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_window Amount of time for the duration of the LE scan. scan_window shall be less than or equal to scan_interval. + * The scan window should be a number in the range 0x0004 to 0x4000. This corresponds to a time range from 2.5 msec + * to 10240 msec. For a number N, Time = N * 0.625 msec. + * @param scan_type Passive or active scanning (@ref PASSIVE_SCAN, @ref ACTIVE_SCAN) + * @param own_address_type If Privacy is disabled, then the scanner address can be + * @arg @ref PUBLIC_ADDR. + * @arg @ref STATIC_RANDOM_ADDR. + * If Privacy is enabled, then the scanner address can be + * @arg @ref RESOLVABLE_PRIVATE_ADDR + * @arg @ref NON_RESOLVABLE_PRIVATE_ADDR + * @param filter_duplicates Duplicate filtering enabled or not. + * @arg 0x00: Do not filter the duplicates + * @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, + uint8_t own_address_type, uint8_t filter_duplicates); + +/** + * @brief The command finds whether a device is bonded. + * @note If the device is using a resolvable private address and it has been bonded, then the command will return + * BLE_STATUS_SUCCESS. + * @param peer_address_type The address type of the peer device + * @arg @ref PUBLIC_ADDR. + * @arg @ref RANDOM_ADDR. + * @param peer_address Address used by the peer device while advertising. + * @return Value indicating success or error code. + */ +tBleStatus aci_gap_is_device_bonded_IDB05A1(uint8_t peer_address_type, const tBDAddr peer_address); + + +/** + * @} + */ + +/** + * @defgroup GAP_Events GAP events + * @{ + */ + +/** + * This event is generated by the controller when the limited discoverable + * mode ends due to timeout (180 seconds). No parameters in the event. + */ +#define EVT_BLUE_GAP_LIMITED_DISCOVERABLE (0x0400) + + +/** + * This event is generated when the pairing process has completed successfully + * or a pairing procedure timeout has occurred or the pairing has failed. + * This is to notify the application that we have paired with a remote device + * so that it can take further actions or to notify that a timeout has occurred + * so that the upper layer can decide to disconnect the link. See @ref _evt_gap_pairing_cmplt. + */ +#define EVT_BLUE_GAP_PAIRING_CMPLT (0x0401) +typedef __packed struct _evt_gap_pairing_cmplt{ + uint16_t conn_handle; /**< Connection handle on which the pairing procedure completed */ + /** + * 0x00: Pairing Success. Pairing with a remote device was successful\n + * 0x01: Pairing Timeout. The SMP timeout has elapsed and no further SMP commands will be processed until reconnection\n + * 0x02: Pairing Failed. The pairing failed with the remote device. + */ + uint8_t status; +} PACKED evt_gap_pairing_cmplt; + + +/** + * This event is generated by the Security manager to the application when a pass key is required for pairing. + * When this event is received, the application has to respond with the aci_gap_pass_key_response() command. + * See @ref _evt_gap_pass_key_req. + */ +#define EVT_BLUE_GAP_PASS_KEY_REQUEST (0x0402) +typedef __packed struct _evt_gap_pass_key_req{ + uint16_t conn_handle; /**< Connection handle for which the passkey has been requested. */ +} PACKED evt_gap_pass_key_req; + + +/** + * This event is generated by the Security manager to the application when the application + * has set that authorization is required for reading/writing of attributes. This event will + * be generated as soon as the pairing is complete. When this event is received, + * aci_gap_authorization_response() command should be used by the application. + * See @ref _evt_gap_author_req. + */ +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST (0x0403) +typedef __packed struct _evt_gap_author_req{ + uint16_t conn_handle; /**< Connection handle for which authorization has been requested. */ +} PACKED evt_gap_author_req; + +/** + * This event is generated when the slave security request is successfully sent to the master. + * No parameters for this event. + */ +#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED (0X0404) + +/** + * This event is generated when a pairing request is issued in response to a slave security + * request from a master which has previously bonded with the slave. When this event is received, + * the upper layer has to issue the command aci_gap_allow_rebond() in order to allow the slave + * to continue the pairing process with the master. No parameters for this event + */ +#define EVT_BLUE_GAP_BOND_LOST (0X0405) + +/** + * The event is given by the GAP layer to the upper layers when a device is discovered during scanning + * as a consequence of one of the GAP procedures started by the upper layers. See @ref _evt_gap_device_found. + */ +#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406) +typedef __packed struct _evt_gap_device_found{ + uint8_t evt_type; /**< Type of event (@ref ADV_IND, @ref ADV_DIRECT_IND, @ref ADV_SCAN_IND, @ref ADV_NONCONN_IND, @ref SCAN_RSP) */ + uint8_t bdaddr_type; /**< Type of the peer address (@ref PUBLIC_ADDR, @ref RANDOM_ADDR). */ + tBDAddr bdaddr; /**< Address of the peer device found during scanning. */ + uint8_t data_length; /**< Length of advertising or scan response data. */ + uint8_t data_RSSI[VARIABLE_SIZE]; /**< Advertising or scan response data + RSSI. RSSI is last octect (signed integer). */ +} PACKED evt_gap_device_found; + +/** + * This event is sent by the GAP to the upper layers when a procedure previously started has been terminated + * by the upper layer or has completed for any other reason. See @ref _evt_gap_procedure_complete. + */ +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE (0x0407) +typedef __packed struct _evt_gap_procedure_complete{ + uint8_t procedure_code; /**< Terminated procedure. See @ref gap_procedure_codes "GAP procedure codes". */ + /** + * @ref BLE_STATUS_SUCCESS, @ref BLE_STATUS_FAILED or @ref ERR_AUTH_FAILURE (procedure failed + * due to authentication requirements). + */ + uint8_t status; + /** + * Procedure specific data.\n + * @li For Name Discovery Procedure:\n + * the name of the peer device if the procedure completed successfully. + * @li For General Connection Establishment Procedure:\n + * The reconnection address written to the peripheral device if the peripheral is privacy enabled + */ + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_gap_procedure_complete; + +/** + * This event is sent only by a privacy enabled Peripheral. The event is sent to the upper layers when the peripheral + * is not able to resolve the private address of the peer device after connecting to it. + */ +#define EVT_BLUE_GAP_ADDR_NOT_RESOLVED_IDB05A1 (0x0408) +typedef __packed struct _evt_gap_addr_not_resolved_IDB05A1{ + uint16_t conn_handle; /**< Connection handle for which the private address could not be resolved with any of the stored IRK's. */ +} PACKED evt_gap_addr_not_resolved_IDB05A1; +/** + * This event is raised when the reconnection address is generated during the general connection + * establishment procedure. The same address is set into the peer device also as a part of the general + * connection establishment procedure. In order to make use of the reconnection address the next time + * while connecting to the bonded peripheral, the application needs to use this reconnection address + * as its own address as well as the peer address to which it wants to connect. See aci_gap_start_general_conn_establish_proc() + * and aci_gap_start_auto_conn_establish_proc(). + */ +#define EVT_BLUE_GAP_RECONNECTION_ADDRESS_IDB04A1 (0x0408) +typedef __packed struct _evt_gap_reconnection_addr_IDB04A1{ + uint8_t reconnection_address[6]; /**< 6 bytes of reconnection address that has been generated */ +} PACKED evt_gap_reconnection_addr_IDB04A1; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_GAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gatt_aci.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,1045 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_gatt_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with GATT commands for BlueNRG FW6.3. +******************************************************************************** +* 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. +*******************************************************************************/ + +#ifndef __BLUENRG_GATT_ACI_H__ +#define __BLUENRG_GATT_ACI_H__ + +#include "bluenrg_gatt_server.h" + +/** + *@addtogroup GATT GATT + *@brief GATT layer. + *@{ + */ + +/** + *@defgroup GATT_Functions GATT functions + *@brief API for GATT layer. + *@{ + */ + +/** + * @brief Initialize the GATT layer for server and client roles. + * @note It adds also the GATT service with Service Changed Characteristic. + * Until this command is issued the GATT channel will not process any commands + * even if the connection is opened. This command has to be given + * before using any of the GAP features. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_init(void); + +/** + * @brief Add a service to the GATT Server. When a service is created in the server, the Host needs + * to reserve the handle ranges for this service using max_attr_records parameter. This + * parameter specifies the maximum number of attribute records that can be added to this + * service (including the service attribute, include attribute, characteristic attribute, + * characteristic value attribute and characteristic descriptor attribute). Handle of the + * created service is returned. + * @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 + * @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 + * <serviceHandle + max_attr_records>. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_serv(uint8_t service_uuid_type, + const uint8_t* service_uuid, + uint8_t service_type, + uint8_t max_attr_records, + uint16_t *serviceHandle); + +/** + * @brief Include a service given by included_start_handle and included_end_handle to another service + * given by service_handle. Attribute server creates an INCLUDE definition attribute and return + * the handle of this attribute in included_handle. + * @param service_handle Handle of the service to which another service has to be included + * @param included_start_handle Start Handle of the service which has to be included in service + * @param included_end_handle End Handle of the service which has to be included in service + * @param included_uuid_type Type of UUID for included service (16-bit or 128-bit). See @ref Well-Known_UUIDs "Well-Known UUIDs". + * @param[in] included_uuid 16-bit or 128-bit UUID. + * @param[out] included_handle Handle of the include declaration. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_include_service(uint16_t service_handle, uint16_t included_start_handle, + uint16_t included_end_handle, uint8_t included_uuid_type, + const uint8_t* included_uuid, uint16_t *included_handle); + +/** + * @brief Add a characteristic to a service. + * @param serviceHandle Handle of the service to which the characteristic has to be added. + * @param charUuidType Type of characteristic UUID (16-bit or 128-bit). See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param charUuid 16-bit or 128-bit UUID. + * @param charValueLen Maximum length of the characteristic value. + * @param charProperties Bitwise OR values of Characteristic Properties (defined in Volume 3, + * Section 3.3.3.1 of Bluetooth Specification 4.0). See @ref Char_properties "Characteristic properties". + * @param secPermissions Security permissions for the added characteristic. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @arg GATT_DONT_NOTIFY_EVENTS + * @arg GATT_NOTIFY_ATTRIBUTE_WRITE + * @arg GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP + * @arg GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param charHandle Handle of the Characteristic that has been added. It is the handle of the characteristic declaration. + * The attribute that holds the characteristic value is allocated at the next handle, followed by the Client + * Characteristic Configuration descriptor if the characteristic has @ref CHAR_PROP_NOTIFY or @ref CHAR_PROP_INDICATE + * properties. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char(uint16_t serviceHandle, + uint8_t charUuidType, + const uint8_t* charUuid, + uint8_t charValueLen, + uint8_t charProperties, + uint8_t secPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* charHandle); + +/** + * Add a characteristic descriptor to a service. + * @param serviceHandle Handle of the service to which the characteristic belongs + * @param charHandle Handle of the characteristic to which description has to be added. + * @param descUuidType 16-bit or 128-bit UUID. See @ref UUID_Types "UUID Types". + * @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param[in] uuid UUID of the Characteristic descriptor. It can be one of the UUID assigned by Bluetooth SIG + * (Well_known_UUIDs) or a user-defined one. + * @param descValueMaxLen The maximum length of the descriptor value + * @param descValueLen Current Length of the characteristic descriptor value + * @param[in] descValue Value of the characteristic description + * @param secPermissions Security permissions for the added descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @param accPermissions Access permissions for the added descriptor. See @ref Access_permissions "Access permissions". + * @arg ATTR_NO_ACCESS + * @arg ATTR_ACCESS_READ_ONLY + * @arg ATTR_ACCESS_WRITE_REQ_ONLY + * @arg ATTR_ACCESS_READ_WRITE + * @arg ATTR_ACCESS_WRITE_WITHOUT_RESPONSE + * @arg ATTR_ACCESS_SIGNED_WRITE_ALLOWED + * @param gattEvtMask Bit mask that enables events that will be sent to the application by the GATT server + * on certain ATT requests. See @ref Gatt_Event_Mask "Gatt Event Mask". + * @param encryKeySize The minimum encryption key size requirement for this attribute. Valid Range: 7 to 16. + * @param isVariable If the attribute has a variable length value field (1) or not (0). + * @param[out] descHandle Handle of the Characteristic Descriptor. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_add_char_desc(uint16_t serviceHandle, + uint16_t charHandle, + uint8_t descUuidType, + const uint8_t* uuid, + uint8_t descValueMaxLen, + uint8_t descValueLen, + const void* descValue, + uint8_t secPermissions, + uint8_t accPermissions, + uint8_t gattEvtMask, + uint8_t encryKeySize, + uint8_t isVariable, + uint16_t* descHandle); + +/** + * @brief Update a characteristic value in a service. + * @note 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. The command is queued into the + * BlueNRG command queue. If the buffer is full, because previous commands could not be still processed, + * the function will return @ref BLE_STATUS_INSUFFICIENT_RESOURCES. This will happen if notifications (or + * indications) are enabled and the application calls aci_gatt_update_char_value() at an higher rate + * than what is allowed by the link. Throughput on BLE link depends on connection interval and + * connection length parameters (decided by the master, see aci_l2cap_connection_parameter_update_request() + * for more info on how to suggest new connection parameters from a slave). If the application does not + * want to lose notifications because BlueNRG buffer becomes full, it has to retry again till the function + * returns @ref BLE_STATUS_SUCCESS or any other error code.\n + * Example:\n + * Here if BlueNRG buffer become full because BlueNRG was not able to send packets for a while, some + * notifications will be lost. + * @code + * tBleStatus Free_Fall_Notify(void) + * { + * uint8_t val; + * tBleStatus ret; + * + * val = 0x01; + * ret = aci_gatt_update_char_value(accServHandle, freeFallCharHandle, 0, 1, &val); + * + * if (ret != BLE_STATUS_SUCCESS){ + * PRINTF("Error while updating ACC characteristic.\n") ; + * return BLE_STATUS_ERROR ; + * } + * return BLE_STATUS_SUCCESS; + * } + * @endcode + * Here if BlueNRG buffer become full, the application try again to send the notification. + * @code + * struct timer t; + * Timer_Set(&t, CLOCK_SECOND*10); + * while(aci_gatt_update_char_value(chatServHandle,TXCharHandle,0,len,array_val)==BLE_STATUS_INSUFFICIENT_RESOURCES){ + * // Radio is busy (buffer full). + * if(Timer_Expired(&t)) + * break; + * } + * @endcode + * + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic + * @param charValOffset The offset from which the attribute value has to be updated. If this is set to 0, + * and the attribute value is of variable length, then the length of the attribute will + * be set to the charValueLen. If the charValOffset is set to a value greater than 0, + * then the length of the attribute will be set to the maximum length as specified for + * the attribute while adding the characteristic. + * @param charValueLen Length of the characteristic value in octets + * @param[in] charValue Characteristic value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_update_char_value(uint16_t servHandle, + uint16_t charHandle, + uint8_t charValOffset, + uint8_t charValueLen, + const uint8_t *charValue); +/** + * @brief Delete the specified characteristic from the service. + * @param servHandle Handle of the service to which characteristic belongs + * @param charHandle Handle of the characteristic to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_char(uint16_t servHandle, uint16_t charHandle); + +/** + * @brief Delete the specified service from the GATT server database. + * @param servHandle Handle of the service to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_service(uint16_t servHandle); + +/** + * @brief Delete the Include definition from the service. + * @param servHandle Handle of the service to which Include definition belongs + * @param includeServHandle Handle of the Included definition to be deleted + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_del_include_service(uint16_t servHandle, uint16_t includeServHandle); + +/** + * @brief Perform an ATT MTU exchange procedure. + * @note When the ATT MTU exchange procedure is completed, a @ref EVT_BLUE_ATT_EXCHANGE_MTU_RESP + * event is generated. A @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is also generated + * to indicate the end of the procedure. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_exchange_configuration(uint16_t conn_handle); + +/** + * @brief Send a @a Find @a Information @a Request. + * @note This command is used to obtain the mapping of attribute handles with their associated + * types. The responses of the procedure are given through the + * @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. The end of the procedure is indicated by + * a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range of attributes to be discovered on the server + * @param end_handle Ending handle of the range of attributes to be discovered on the server + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_information_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle); + +/** + * @brief Send a @a Find @a By @a Type @a Value @a Request + * @note The Find By Type Value Request is used to obtain the handles of attributes that + * have a given 16-bit UUID attribute type and a given attribute value. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid 2 octet UUID to find (little-endian) + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 7). + * @param attr_val Attribute value to find + * @return Value indicating success or error code. + */ +tBleStatus aci_att_find_by_type_value_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t* uuid, uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send a @a Read @a By @a Type @a Request + * @note The Read By Type Request is used to obtain the values of attributes where the attribute type + * is known but the handle is not known. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Read @a By @a Group @a Type @a Request + * @note The Read By Group Type Request is used to obtain the values of grouping attributes where the attribute + * type is known but the handle is not known. Grouping attributes are defined at GATT layer. The grouping + * attribute types are: «Primary Service», «Secondary Service» and «Characteristic». + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle First requested handle number + * @param end_handle Last requested handle number + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_att_read_by_group_type_req(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Send a @a Prepare @a Write @a Request + * @note The Prepare Write Request is used to request the server to prepare to write the value of an attribute. + * The responses of the procedure are given through the @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE. + * @param conn_handle Connection handle for which the command is given. + * @param attr_handle The handle of the attribute to be written + * @param value_offset The offset of the first octet to be written + * @param attr_val_len Length of attribute value (maximum value is ATT_MTU - 5). + * @param attr_val The value of the attribute to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_att_prepare_write_req(uint16_t conn_handle, uint16_t attr_handle, uint16_t value_offset, + uint8_t attr_val_len, uint8_t* attr_val); + +/** + * @brief Send an @a Execute @a Write @a Request + * @note The Execute Write Request is used to request the server to write or cancel the write of all the + * prepared values currently held in the prepare queue from this client. + * The result of the procedure is given through the @ref EVT_BLUE_ATT_EXEC_WRITE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param execute @arg 0x00 Cancel all prepared writes + * @arg 0x01 Immediately write all pending prepared values. + * @return Value indicating success or error code. + */ +tBleStatus aci_att_execute_write_req(uint16_t conn_handle, uint8_t execute); + +/** + * @brief This command will start the GATT client procedure to discover all primary services on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle); + +/** + * @brief Start the procedure to discover the primary services of the specified UUID on the server. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_prim_service_by_uuid(uint16_t conn_handle, uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to find all included services. + * @note The responses of the procedure are given through the @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * The end of the procedure is indicated by a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event. + * @param conn_handle Connection handle for which the command is given. + * @param start_handle Start handle of the service + * @param end_handle End handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle); + +/** + * @brief Start the procedure to discover all the characteristics of a given service. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BY_TYPE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_attr_handle Start attribute handle of the service + * @param end_attr_handle End attribute handle of the service + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle); + +/** + * @brief Start the procedure to discover all the characteristics specified by a UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Start attribute handle of the service + * @param end_handle End attribute handle of the service + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_charac_by_uuid(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle, uint8_t uuid_type, const uint8_t* uuid); + +/** + * @brief Start the procedure to discover all characteristic descriptors on the server. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_FIND_INFORMATION_RESP event. + * @param conn_handle Connection handle for which the command is given. + * @param char_val_handle Starting handle of the characteristic + * @param char_end_handle End handle of the characteristic + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle); + +/** + * @brief Start the procedure to read the attribute value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to read all the characteristics specified by the UUID. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param start_handle Starting handle of the range to be searched + * @param end_handle End handle of the range to be searched + * @param uuid_type @arg @ref UUID_TYPE_16 + * @arg @ref UUID_TYPE_128 + * @param uuid 2 or 16 octet UUID + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_using_charac_uuid(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle, + uint8_t uuid_type, uint8_t* uuid); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be read + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start a procedure to read multiple characteristic values from a server. + * @note This sub-procedure is used to read multiple Characteristic Values from a server when the + * client knows the Characteristic Value Handles. + * When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through + * @ref EVT_BLUE_ATT_READ_MULTIPLE_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param num_handles The number of handles for which the value has to be read + * @param set_of_handles The handles for which the attribute value has to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_multiple_charac_val(uint16_t conn_handle, uint8_t num_handles, + uint8_t* set_of_handles); + +/** + * @brief Start the procedure to write a characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to write a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start the procedure to write a characteristic reliably. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_charac_reliable(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to write a long characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * During the procedure, @ref EVT_BLUE_ATT_PREPARE_WRITE_RESP and @ref EVT_BLUE_ATT_EXEC_WRITE_RESP + * events are raised. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_offset Offset at which the attribute has to be written + * @param val_len Length of the value to be written + * @param attr_val Value to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset, uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Start the procedure to read a long characteristic value. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packets are given through @ref EVT_BLUE_ATT_READ_BLOB_RESP + * event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the characteristic descriptor + * @param val_offset Offset from which the value needs to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_long_charac_desc(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +/** + * @brief Start the procedure to write a characteristic descriptor. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param value_len Length of the value to be written + * @param[in] attr_value Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +/** + * @brief Start the procedure to read the descriptor specified. + * @note When the procedure is completed, a @ref EVT_BLUE_GATT_PROCEDURE_COMPLETE event is generated. + * Before procedure completion the response packet is given through @ref EVT_BLUE_ATT_READ_RESP event. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the descriptor to be read + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_charac_desc(uint16_t conn_handle, uint16_t attr_handle); + +/** + * @brief Start the procedure to write a characteristic value without waiting for any response from the server. + * @note No events are generated after this command is executed. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 3) + * @param[in] attr_val Value to be written + * @return Value indicating success or error code.\n + * It can be @ref BLE_STATUS_NOT_ALLOWED in the following cases:\n + * - If the exchange has already taken place\n + * - If GATT is expecting response for previous request\n + * - Already a request is in the queue to be sent\n + * - Channel not open\n + * - Already one GATT procedure is started + */ +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, const uint8_t* attr_val); + +/** + * @brief Start a signed write without response from the server. + * @note The procedure i used to write a characteristic value with an authentication signature without waiting + * for any response from the server. It cannot be used when the link is encrypted. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute to be written + * @param val_len Length of the value to be written (up to ATT_MTU - 13). + * @param attr_val Value to be written + * @return Value indicating success or error code + */ +tBleStatus aci_gatt_signed_write_without_resp(uint16_t conn_handle, uint16_t attr_handle, + uint8_t val_len, uint8_t* attr_val); + +/** + * @brief Confirm an indication + * @note This command has to be sent when the application receives the event @ref EVT_BLUE_GATT_INDICATION. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_confirm_indication(uint16_t conn_handle); + +/** + * @brief Allow or reject a write request from a client. + * @note This command has to be sent by the application when it receives the @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * If the write is allowed, then the status and error code has to be set to 0. If the write is not allowed, + * then the status has to be set to 1 and the error code has to be set to the error code that has to be + * passed to the client. + * @param conn_handle Connection handle for which the command is given + * @param attr_handle Handle of the attribute that was passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param write_status 0x00: The value can be written to the attribute specified by attr_handle\n + * 0x01: The value cannot be written to the attribute specified by the attr_handle. + * @param err_code The error code that has to be passed to the client in case the write has to be rejected. + * @param att_val_len Length of the value to be written as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @param att_val Value as passed in the event @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_write_response(uint16_t conn_handle, + uint16_t attr_handle, + uint8_t write_status, + uint8_t err_code, + uint8_t att_val_len, + uint8_t *att_val); + +/** + * @brief Allow the GATT server to send a response to a read request from a client. + * @note The application has to send this command when it receives the @ref EVT_BLUE_GATT_READ_PERMIT_REQ + * or @ref EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ. This command indicates to the stack that the response + * can be sent to the client. So if the application wishes to update any of the attributes before + * they are read by the client, it has to update the characteristic values using the aci_gatt_update_char_value + * and then give this command. The application should perform the required operations within 30 seconds, + * otherwise the GATT procedure will go to timeout. + * @param conn_handle Connection handle for which the command is given. + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_allow_read(uint16_t conn_handle); + +/** + * @brief Set the security permission for the attribute handle specified. + * @note Currently the setting of security permission is allowed only for client configuration descriptor. + * @param service_handle Handle of the service which contains the attribute whose security + * permission has to be modified. + * @param attr_handle Handle of the attribute whose security permission has to be modified. + * @param security_permission Security permissions for the descriptor. See @ref Security_permissions "Security permissions". + * @arg ATTR_PERMISSION_NONE + * @arg ATTR_PERMISSION_AUTHEN_READ + * @arg ATTR_PERMISSION_AUTHOR_READ + * @arg ATTR_PERMISSION_ENCRY_READ + * @arg ATTR_PERMISSION_AUTHEN_WRITE + * @arg ATTR_PERMISSION_AUTHOR_WRITE + * @arg ATTR_PERMISSION_ENCRY_WRITE + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_security_permission(uint16_t service_handle, uint16_t attr_handle, + uint8_t security_permission); + +/** + * @brief This command sets the value of the descriptor specified by charDescHandle. + * @param servHandle Handle of the service which contains the descriptor. + * @param charHandle Handle of the characteristic which contains the descriptor. + * @param charDescHandle Handle of the descriptor whose value has to be set. + * @param charDescValOffset Offset from which the descriptor value has to be updated. + * @param charDescValueLen Length of the descriptor value + * @param[in] charDescValue descriptor value + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_set_desc_value(uint16_t servHandle, + uint16_t charHandle, + uint16_t charDescHandle, + uint16_t charDescValOffset, + uint8_t charDescValueLen, + const uint8_t *charDescValue); + +/** + * @brief Reads the value of the attribute handle specified from the local GATT database. + * @param attr_handle Handle of the attribute to read + * @param data_len Length of the data buffer. + * @param[in] data_len_out_p Length of the read attribute. + * @param[in] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value(uint16_t attr_handle, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); + + /** + * @brief Reads the value of the attribute handle specified from the local GATT database, starting from a given offset. + * @param attr_handle Handle of the attribute to read + * @param offset Offset from which the value needs to be read + * @param data_len Length of the data buffer. + * @param[in] data_len_out_p Length of the read attribute. + * @param[in] data Pointer to the buffer that will contain the read value. + * The buffer will be filled with the attribute value. + * The length will be the minimum between the provided data_len and the actual length of the + * attribute (in data_len_out_p). + * @return Value indicating success or error code. + */ +tBleStatus aci_gatt_read_handle_value_offset_IDB05A1(uint16_t attr_handle, uint8_t offset, uint16_t data_len, uint16_t *data_len_out_p, uint8_t *data); + +/** + * @} + */ + + +/** + * @defgroup GATT_Events GATT events + * The structures are the data field of @ref evt_blue_aci. + * @{ + */ + +/** + * This event is raised to the application by the GATT server when a client modifies any attribute on the server, + * if event is enabled (see @ref Gatt_Event_Mask "Gatt Event Mask"). + * See @ref _evt_gatt_attr_modified_IDB04A1 or @ref _evt_gatt_attr_modified__IDB05A1. + */ +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED (0x0C01) +typedef __packed struct _evt_gatt_attr_modified_IDB05A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint16_t offset; /**< Offset from which the write has been performed by the peer device */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB05A1; + +typedef __packed struct _evt_gatt_attr_modified_IDB04A1{ + uint16_t conn_handle; /**< The connection handle which modified the attribute. */ + uint16_t attr_handle; /**< Handle of the attribute that was modified. */ + uint8_t data_length; /**< The length of the data */ + uint8_t att_data[VARIABLE_SIZE]; /**< The new value (length is data_length) */ +} PACKED evt_gatt_attr_modified_IDB04A1; + +/** + * This event is generated by the client/server to the application on a GATT timeout (30 seconds). + * See @ref _evt_gatt_procedure_timeout. + */ +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT (0x0C02) +typedef __packed struct _evt_gatt_procedure_timeout{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has timed out */ +} PACKED evt_gatt_procedure_timeout; + +/** + * This event is generated in response to an Exchange MTU request. See aci_gatt_exchange_configuration(). + * See @ref _evt_att_exchange_mtu_resp. + */ +#define EVT_BLUE_ATT_EXCHANGE_MTU_RESP (0x0C03) +typedef __packed struct _evt_att_exchange_mtu_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data (always 1). */ + uint16_t server_rx_mtu; /**< Attribute server receive MTU size */ +} PACKED evt_att_exchange_mtu_resp; + +/** + * This event is generated in response to a @a Find @a Information @a Request. See aci_att_find_information_req() and + * Find Information Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_information_resp. + */ +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP (0x0C04) +typedef __packed struct _evt_att_find_information_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t format; /**< The format of the handle_uuid_pair. @arg 1: 16-bit UUIDs @arg 2: 128-bit UUIDs */ + /** + * A sequence of handle-uuid pairs.\n + * @li if format=1, each pair is:\n + * [2 octets for handle, 2 octets for UUIDs] \n + * @li if format=2, each pair is:\n + * [2 octets for handle, 16 octets for UUIDs] + */ + uint8_t handle_uuid_pair[VARIABLE_SIZE]; +} PACKED evt_att_find_information_resp; + +/** + * This event is generated in response to a @a Find @a By @a Type @a Value @a Request. See + * Find By Type Value Response in Bluetooth Core v4.0 spec. See @ref _evt_att_find_by_type_val_resp. + */ +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP (0x0C05) +typedef __packed struct _evt_att_find_by_type_val_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + /** + * Handles Information List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle pairs: [2 octets for Found Attribute Handle, 2 octets for Group End Handle] + */ + uint8_t handles_info_list[VARIABLE_SIZE]; +} PACKED evt_att_find_by_type_val_resp; + +/** + * This event is generated in response to a @a Read @a By @a Type @a Request. See aci_gatt_find_included_services() and + * aci_gatt_disc_all_charac_of_serv(). + * For more info see Read By Type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_type_resp. + */ +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP (0x0C06) +typedef __packed struct _evt_att_read_by_type_resp{ + uint16_t conn_handle; /**< The connection handle related to the response */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t handle_value_pair_length; /**< The size of each attribute handle-value pair */ + /** + * Attribute Data List as defined in Bluetooth Core v4.0 spec. + * A sequence of handle-value pairs: [2 octets for Attribute Handle, (handle_value_pair_length - 2 octets) for Attribute Value] + */ + uint8_t handle_value_pair[VARIABLE_SIZE]; +} PACKED evt_att_read_by_type_resp; + +/** + * This event is generated in response to a @a Read @a Request. See aci_gatt_read_charac_val(). + * For more info see Read Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_resp. + */ +#define EVT_BLUE_ATT_READ_RESP (0x0C07) +typedef __packed struct _evt_att_read_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_value[VARIABLE_SIZE]; /**< The value of the attribute. */ +} PACKED evt_att_read_resp; + +/** + * This event is generated in response to a @a Read @a Blob @a Request. See aci_gatt_read_long_charac_val(). + * For more info see Read Blob Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_blob_resp. + */ +#define EVT_BLUE_ATT_READ_BLOB_RESP (0x0C08) +typedef __packed struct _evt_att_read_blob_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t part_attribute_value[VARIABLE_SIZE]; /**< Part of the attribute value. */ +} PACKED evt_att_read_blob_resp; + +/** + * This event is generated in response to a @a Read @a Multiple @a Request. + * For more info see Read Multiple Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_mult_resp. + */ +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP (0x0C09) +typedef __packed struct _evt_att_read_mult_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t set_of_values[VARIABLE_SIZE]; /**< A set of two or more values.*/ +} PACKED evt_att_read_mult_resp; + +/** + * This event is generated in response to a @a Read @a By @a Group @a Type @a Request. See aci_gatt_disc_all_prim_services(). + * For more info see Read By Group type Response in Bluetooth Core v4.0 spec. See @ref _evt_att_read_by_group_resp. + */ +#define EVT_BLUE_ATT_READ_BY_GROUP_TYPE_RESP (0x0C0A) +typedef __packed struct _evt_att_read_by_group_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t attribute_data_length; /**< The size of each Attribute Data. */ + /** + * A list of Attribute Data where the attribute data is composed by: + * @li 2 octets for Attribute Handle + * @li 2 octets for End Group Handle + * @li (attribute_data_length - 4) octets for Attribute Value + */ + uint8_t attribute_data_list[VARIABLE_SIZE]; +} PACKED evt_att_read_by_group_resp; + +/** + * This event is generated in response to a @a Prepare @a Write @a Request. + * For more info see Prepare Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_prepare_write_resp. + */ +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP (0x0C0C) +typedef __packed struct _evt_att_prepare_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attribute_handle; /**< The handle of the attribute to be written. */ + uint16_t offset; /**< The offset of the first octet to be written. */ + uint8_t part_attr_value[VARIABLE_SIZE]; /**< The value of the attribute to be written. */ +} PACKED evt_att_prepare_write_resp; + +/** + * This event is generated in response to an @a Execute @a Write @a Request. + * For more info see Execute Write Response in Bluetooth Core v4.0 spec. See @ref _evt_att_exec_write_resp. + */ +#define EVT_BLUE_ATT_EXEC_WRITE_RESP (0x0C0D) +typedef __packed struct _evt_att_exec_write_resp{ + uint16_t conn_handle; /**< The connection handle related to the response. */ + uint8_t event_data_length; /**< Always 0. */ +} PACKED evt_att_exec_write_resp; + +/** + * This event is generated when an indication is received from the server. + * For more info see Handle Value Indication in Bluetooth Core v4.0 spec. See @ref _evt_gatt_indication. + */ +#define EVT_BLUE_GATT_INDICATION (0x0C0E) +typedef __packed struct _evt_gatt_indication{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_indication; + +/** + * This event is generated when a notification is received from the server. + * For more info see Handle Value Notification in Bluetooth Core v4.0 spec. See @ref _evt_gatt_notification. + */ +#define EVT_BLUE_GATT_NOTIFICATION (0x0C0F) +typedef __packed struct _evt_gatt_notification{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + uint8_t attr_value[VARIABLE_SIZE]; /**< The current value of the attribute. */ +} PACKED evt_gatt_attr_notification; + +/** + * This event is generated when a GATT client procedure completes either with error or successfully. + * See @ref _evt_gatt_procedure_complete. + */ +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE (0x0C10) +typedef __packed struct _evt_gatt_procedure_complete{ + uint16_t conn_handle; /**< The connection handle on which the GATT procedure has completed */ + uint8_t data_length; /**< Length of error_code field (always 1). */ + /** + * Indicates whether the procedure completed with error (BLE_STATUS_FAILED) or was successful (BLE_STATUS_SUCCESS). + */ + uint8_t error_code; +} PACKED evt_gatt_procedure_complete; + +/** + * This event is generated when an Error Response is received from the server. The error response can be given + * by the server at the end of one of the GATT discovery procedures. This does not mean that the procedure ended + * with an error, but this error event is part of the procedure itself. See @ref _evt_gatt_error_resp. + */ +#define EVT_BLUE_GATT_ERROR_RESP (0x0C11) +typedef __packed struct _evt_gatt_error_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint8_t req_opcode; /**< The request that generated this error response. */ + uint16_t attr_handle; /**< The attribute handle that generated this error response. */ + uint8_t error_code; /**< The reason why the request has generated an error response. See Error Response in Bluetooth Core v4.0 spec. */ +} PACKED evt_gatt_error_resp; + +/** + * This event can be generated during a "Discover Characteristics By UUID" procedure or a "Read using + * Characteristic UUID" procedure. + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. See @ref _evt_gatt_disc_read_char_by_uuid_resp. + */ +#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12) +typedef __packed struct _evt_gatt_disc_read_char_by_uuid_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ + uint16_t attr_handle; /**< The handle of the attribute. */ + /** + * The attribute value will be a service declaration as defined in Bluetooth Core v4.0 spec (vol.3, Part G, ch. 3.3.1), + * when a "Discover Characteristics By UUID" has been started. It will be the value of the Characteristic if a + * "Read using Characteristic UUID" has been performed. + */ + uint8_t attr_value[VARIABLE_SIZE]; +} PACKED evt_gatt_disc_read_char_by_uuid_resp; + +/** + * This event is given to the application when a write request, write command or signed write command + * is received by the server from the client. This event will be given to the application only if the + * event bit for this event generation is set when the characteristic was added. + * When this event is received, the application has to check whether the value being requested for write + * is allowed to be written and respond with the command aci_gatt_write_response(). + * If the write is rejected by the application, then the value of the attribute will not be modified. + * In case of a write request, an error response will be sent to the client, with the error code as specified by the application. + * In case of write/signed write commands, no response is sent to the client but the attribute is not modified. + * See @ref evt_gatt_write_permit_req. + */ +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ (0x0C13) +typedef __packed struct _evt_gatt_write_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to write the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the write request has been made by the client */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The data that the client has requested to write */ +} PACKED evt_gatt_write_permit_req; + +/** + * This event is given to the application when a read request or read blob request is received by the server + * from the client. This event will be given to the application only if the event bit for this event generation + * is set when the characteristic was added. + * On receiving this event, the application can update the value of the handle if it desires and when done + * it has to use the aci_gatt_allow_read() command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_PERMIT_REQ (0x0C14) +typedef __packed struct _evt_gatt_read_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint16_t attr_handle; /**< The handle of the attribute for which the read request has been made by the client */ + uint8_t data_length; /**< Length of offset field. (always 1). */ + uint8_t offset; /**< Contains the offset from which the read has been requested */ +} PACKED evt_gatt_read_permit_req; + +/** + * This event is given to the application when a read multiple request or read by type request is received + * by the server from the client. This event will be given to the application only if the event bit for this + * event generation is set when the characteristic was added. + * On receiving this event, the application can update the values of the handles if it desires and when done + * it has to send the aci_gatt_allow_read command to indicate to the stack that it can send the response to the client. + * See @ref evt_gatt_read_multi_permit_req. + * + */ +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ (0x0C15) +typedef __packed struct _evt_gatt_read_multi_permit_req{ + uint16_t conn_handle; /**< Handle of the connection on which there was the request to read the attribute. */ + uint8_t data_length; /**< Length of data field. */ + uint8_t data[VARIABLE_SIZE]; /**< The handles of the attributes that have been requested by the client for a read. */ +} PACKED evt_gatt_read_multi_permit_req; + +/** + * @} + */ + +/** + * @} + */ + +#endif /* __BLUENRG_GATT_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_gatt_server.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,223 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : bluenrg_gatt_server.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's GATT server layer. +******************************************************************************** +* 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. +*******************************************************************************/ + +#ifndef __BNRG_GATT_SERVER_H__ +#define __BNRG_GATT_SERVER_H__ + +#include "compiler.h" +#include "ble_status.h" + +/** + *@addtogroup GATT GATT + *@{ + */ + +/** + * @anchor Well-Known_UUIDs + * @name Well-Known UUIDs + * @{ + */ +#define PRIMARY_SERVICE_UUID (0x2800) +#define SECONDARY_SERVICE_UUID (0x2801) +#define INCLUDE_SERVICE_UUID (0x2802) +#define CHARACTERISTIC_UUID (0x2803) +#define CHAR_EXTENDED_PROP_DESC_UUID (0x2900) +#define CHAR_USER_DESC_UUID (0x2901) +#define CHAR_CLIENT_CONFIG_DESC_UUID (0x2902) +#define CHAR_SERVER_CONFIG_DESC_UUID (0x2903) +#define CHAR_FORMAT_DESC_UUID (0x2904) +#define CHAR_AGGR_FMT_DESC_UUID (0x2905) +#define GATT_SERVICE_UUID (0x1801) +#define GAP_SERVICE_UUID (0x1800) +#define SERVICE_CHANGED_UUID (0x2A05) +/** + * @} + */ + +/** + * @anchor Access_permissions + * @name Access permissions + * Access permissions for an attribute + * @{ + */ +#define ATTR_NO_ACCESS (0x00) +#define ATTR_ACCESS_READ_ONLY (0x01) +#define ATTR_ACCESS_WRITE_REQ_ONLY (0x02) +#define ATTR_ACCESS_READ_WRITE (0x03) +#define ATTR_ACCESS_WRITE_WITHOUT_RESPONSE (0x04) +#define ATTR_ACCESS_SIGNED_WRITE_ALLOWED (0x08) +/** + * Allows all write procedures + */ +#define ATTR_ACCESS_WRITE_ANY (0x0E) +/** + * @} + */ + +/** + * @anchor Char_properties + * @name Characteristic properties. + * @{ + */ +#define CHAR_PROP_BROADCAST (0x01) +#define CHAR_PROP_READ (0x02) +#define CHAR_PROP_WRITE_WITHOUT_RESP (0x04) +#define CHAR_PROP_WRITE (0x08) +#define CHAR_PROP_NOTIFY (0x10) +#define CHAR_PROP_INDICATE (0x20) +#define CHAR_PROP_SIGNED_WRITE (0x40) +#define CHAR_PROP_EXT (0x80) +/** + * @} + */ + + +/** + * @anchor Security_permissions + * @name Security permissions for an attribute. + * @{ + */ +#define ATTR_PERMISSION_NONE (0x00) /**< No security. */ +#define ATTR_PERMISSION_AUTHEN_READ (0x01) /**< Need authentication to read */ +#define ATTR_PERMISSION_AUTHOR_READ (0x02) /**< Need authorization to read */ +#define ATTR_PERMISSION_ENCRY_READ (0x04) /**< Link must be encrypted to read */ +#define ATTR_PERMISSION_AUTHEN_WRITE (0x08) /**< Need authentication to write */ +#define ATTR_PERMISSION_AUTHOR_WRITE (0x10) /**< Need authorization to write */ +#define ATTR_PERMISSION_ENCRY_WRITE (0x20) /**< Link must be encrypted for write */ +/** + * @} + */ + +/** + * @anchor UUID_Types + * @name Type of UUID (16 bit or 128 bit). + * @{ + */ +#define UUID_TYPE_16 (0x01) +#define UUID_TYPE_128 (0x02) +/** + * @} + */ + +/** + * @anchor Service_type + * @name Type of service (primary or secondary) + * @{ + */ +#define PRIMARY_SERVICE (0x01) +#define SECONDARY_SERVICE (0x02) +/** + * @} + */ + +/** + * @anchor Gatt_Event_Mask + * @name Gatt Event Mask + * Type of event generated by GATT server + * @{ + */ +#define GATT_DONT_NOTIFY_EVENTS (0x00) /**< Do not notify events. */ +#define GATT_NOTIFY_ATTRIBUTE_WRITE (0x01) /**< The application will be notified when a client writes to this attribute. + An @ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued. */ +#define GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP (0x02) /**< The application will be notified when a write request, a write cmd + or a signed write cmd are received by the server for this attribute. + An @ref EVT_BLUE_GATT_WRITE_PERMIT_REQ will be issued. */ +#define GATT_NOTIFY_READ_REQ_AND_WAIT_FOR_APPL_RESP (0x04) /**< The application will be notified when a read request of any type is + received for this attribute. An @ref EVT_BLUE_GATT_READ_PERMIT_REQ will be issued. */ +/** + * @} + */ + +/** + * @name Type of characteristic length + * See aci_gatt_add_char() + * @{ + */ +#define CHAR_VALUE_LEN_CONSTANT (0x00) +#define CHAR_VALUE_LEN_VARIABLE (0x01) +/** + * @} + */ + + +/** + * @name Encryption key size + * @{ + */ +/** + * Minimum encryption key size + */ +#define MIN_ENCRY_KEY_SIZE (7) + +/** + * Maximum encryption key size + */ +#define MAX_ENCRY_KEY_SIZE (0x10) +/** + * @} + */ + +/** + * @name Characteristic Presentation Format + * @{ + */ +typedef __packed struct _charactFormat { + uint8_t format; + int8_t exp; + uint16_t unit; + uint8_t name_space; + uint16_t desc; +} PACKED charactFormat; + +/** + * @} + */ + +/** + * @name Format + * @{ + */ +#define FORMAT_UINT8 0x04 +#define FORMAT_UINT16 0x06 +#define FORMAT_SINT16 0x0E +#define FORMAT_SINT24 0x0F +/** + * @} + */ + +/** + * @name Unit + * @{ + */ +#define UNIT_UNITLESS 0x2700 +#define UNIT_TEMP_CELSIUS 0x272F +#define UNIT_PRESSURE_BAR 0x2780 +/** + * @} + */ + + +/** + * ATT MTU size + */ +#define ATT_MTU (23) + +/** + * @} + */ + + + +#endif /* __BNRG_GATT_SERVER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_hal_aci.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,157 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_hal_aci.h +* Author : AMS - AAS +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with HCI commands for BlueNRG FW6.3. +******************************************************************************** +* 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. +*******************************************************************************/ + +#ifndef __BLUENRG_HAL_ACI_H__ +#define __BLUENRG_HAL_ACI_H__ + +/** + *@addtogroup HAL HAL + *@brief Hardware Abstraction Layer. + *@{ + */ + +/** + * @defgroup HAL_Functions HAL functions + * @brief API for BlueNRG HAL layer. + * @{ + */ + +/** + * @brief This command writes a value to a low level configure data structure. + * @note It is useful to setup directly some low level parameters for the system at runtime. + * @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 len Length of data to be written + * @param[out] val Data to be written + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_write_config_data(uint8_t offset, + uint8_t len, + const uint8_t *val); + +/** + * @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). + * When the system starts up or reboots, the default TX power level will be used, which is + * the maximum value of 8dBm. Once this command is given, the output power will be changed + * instantly, regardless if there is Bluetooth communication going on or not. For example, + * for debugging purpose, the BlueNRG can be set to advertise all the time and use this + * command to observe the signal strength changing. The system will keep the last received + * TX power level from the command, i.e. the 2nd command overwrites the previous TX power + * level. The new TX power level remains until another Set TX Power command, or the system + * reboots.\n + * @param en_high_power Can be only 0 or 1. Set high power bit on or off. It is strongly adviced to use the + * right value, depending on the selected hardware configuration for the RF network: + * normal mode or high power mode. + * @param pa_level Can be from 0 to 7. Set the PA level value. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level); + +/** + * @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, + * the device can still wake up itself with the internal timer. But in standby mode, this timer is + * disabled. So the only possibility to wake up the device is by external signals, e.g. a HCI command + * sent via SPI bus. + * The command is only accepted when there is no other Bluetooth activity. Otherwise an error code + * ERR_COMMAND_DISALLOWED will be returned. + * + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_device_standby(void); + +/** + * @brief This command starts a carrier frequency, i.e. a tone, on a specific channel. + * @note The frequency sine wave at the specific channel may be used for test purpose only. + * The channel ID is a parameter from 0 to 39 for the 40 BLE channels, e.g. 0 for 2.402GHz, 1 for 2.404GHz etc. + * This command shouldn't be used when normal Bluetooth activities are ongoing. + * The tone should be stopped by aci_hal_tone_stop() command. + * + * @param rf_channel BLE Channel ID, from 0 to 39 meaning (2.402 + 2*N) GHz. Actually the tone will be emitted at the + * channel central frequency minus 250 kHz. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_start(uint8_t rf_channel); + +/** + * This command is used to stop the previously started aci_hal_tone_start() command. + * @return Value indicating success or error code. + */ +tBleStatus aci_hal_tone_stop(void); + +/** + * @} + */ + +/** + * @defgroup Config_vals Offsets and lengths for configuration values. + * @brief Offsets and lengths for configuration values. + * See aci_hal_write_config_data(). + * @{ + */ + +/** + * @name Configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_OFFSET (0x00) /**< Bluetooth public address */ +#define CONFIG_DATA_DIV_OFFSET (0x06) /**< DIV used to derive CSRK */ +#define CONFIG_DATA_ER_OFFSET (0x08) /**< Encryption root key used to derive LTK and CSRK */ +#define CONFIG_DATA_IR_OFFSET (0x18) /**< Identity root key used to derive LTK and CSRK */ +#define CONFIG_DATA_LL_WITHOUT_HOST (0x2C) /**< Switch on/off Link Layer only mode. Set to 1 to disable Host. + It can be written only if aci_hal_write_config_data() is the first command + after reset. */ + +/** + * Select the BlueNRG roles and mode configurations.\n + * @li Mode 1: slave or master, 1 connection, RAM1 only (small GATT DB) + * @li Mode 2: slave or master, 1 connection, RAM1 and RAM2 (large GATT DB) + * @li Mode 3: master only, 8 connections, RAM1 and RAM2. + */ +#define CONFIG_DATA_ROLE (0x2D) +/** + * @} + */ + +/** + * @name Length for configuration values. + * See @ref aci_hal_write_config_data(). + * @{ + */ +#define CONFIG_DATA_PUBADDR_LEN (6) +#define CONFIG_DATA_DIV_LEN (2) +#define CONFIG_DATA_ER_LEN (16) +#define CONFIG_DATA_IR_LEN (16) +#define CONFIG_DATA_LL_WITHOUT_HOST_LEN (1) +#define CONFIG_DATA_ROLE_LEN (1) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_HAL_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_l2cap_aci.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,162 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_l2cap_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with L2CAP commands for BlueNRG FW6.3. +******************************************************************************** +* 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. +*******************************************************************************/ + +#ifndef __BLUENRG_L2CAP_ACI_H__ +#define __BLUENRG_L2CAP_ACI_H__ + +/** + *@addtogroup L2CAP L2CAP + *@brief L2CAP layer. + *@{ + */ + +/** + *@defgroup L2CAP_Functions L2CAP functions + *@brief API for L2CAP layer. + *@{ + */ + +/** + * @brief Send an L2CAP Connection Parameter Update request from the slave to the master. + * @note An @ref EVT_BLUE_L2CAP_CONN_UPD_RESP event will be raised when the master will respond to the request + * (accepts or rejects). + * @param conn_handle Connection handle on which the connection parameter update request has to be sent. + * @param interval_min Defines minimum value for the connection event interval in the following manner: + * connIntervalMin = interval_min x 1.25ms + * @param interval_max Defines maximum value for the connection event interval in the following manner: + * connIntervalMax = interval_max x 1.25ms + * @param slave_latency Defines the slave latency parameter (number of connection events that can be skipped). + * @param timeout_multiplier Defines connection timeout parameter in the following manner: + * timeout_multiplier x 10ms. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_request(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier); +/** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param min_ce_length Minimum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param max_ce_length Maximum length of connection event needed for the LE connection.\n + * Range: 0x0000 - 0xFFFF\n + * Time = N x 0.625 msec. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB05A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint16_t min_ce_length, uint16_t max_ce_length, + uint8_t id, uint8_t accept); + /** + * @brief Accept or reject a connection update. + * @note This command should be sent in response to a @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event from the controller. + * The accept parameter has to be set if the connection parameters given in the event are acceptable. + * @param conn_handle Handle received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param interval_min The connection interval parameter as received in the l2cap connection update request event + * @param interval_max The maximum connection interval parameter as received in the l2cap connection update request event. + * @param slave_latency The slave latency parameter as received in the l2cap connection update request event. + * @param timeout_multiplier The supervision connection timeout parameter as received in the l2cap connection update request event. + * @param id Identifier received in @ref EVT_BLUE_L2CAP_CONN_UPD_REQ event. + * @param accept @arg 0x00: The connection update parameters are not acceptable. + * @arg 0x01: The connection update parameters are acceptable. + * @return Value indicating success or error code. + */ +tBleStatus aci_l2cap_connection_parameter_update_response_IDB04A1(uint16_t conn_handle, uint16_t interval_min, + uint16_t interval_max, uint16_t slave_latency, + uint16_t timeout_multiplier, uint8_t id, uint8_t accept); + +/** + * @} + */ + +/** + * @defgroup L2CAP_Events L2CAP events + * @{ + */ + +/** + * This event is generated when the master responds to the L2CAP connection update request packet. + * For more info see CONNECTION PARAMETER UPDATE RESPONSE and COMMAND REJECT in Bluetooth Core v4.0 spec. + */ +#define EVT_BLUE_L2CAP_CONN_UPD_RESP (0x0800) +typedef __packed struct _evt_l2cap_conn_upd_resp{ + uint16_t conn_handle; /**< The connection handle related to the event. */ + uint8_t event_data_length; /**< Length of following data. */ +/** + * @li 0x13 in case of valid L2CAP Connection Parameter Update Response packet. + * @li 0x01 in case of Command Reject. + */ + uint8_t code; + uint8_t identifier; /**< Identifier of the response. It is equal to the request. */ + uint16_t l2cap_length; /**< Length of following data. It should always be 2 */ +/** + * Result code (parameters accepted or rejected) in case of Connection Parameter Update + * Response (code=0x13) or reason code for rejection in case of Command Reject (code=0x01). + */ + uint16_t result; +} PACKED evt_l2cap_conn_upd_resp; + +/** + * This event is generated when the master does not respond to the connection update request + * within 30 seconds. + */ +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801) + +/** + * The event is given by the L2CAP layer when a connection update request is received from the slave. + * The application has to respond by calling aci_l2cap_connection_parameter_update_response(). + */ +#define EVT_BLUE_L2CAP_CONN_UPD_REQ (0x0802) +typedef __packed struct _evt_l2cap_conn_upd_req{ +/** + * Handle of the connection for which the connection update request has been received. + * The same handle has to be returned while responding to the event with the command + * aci_l2cap_connection_parameter_update_response(). + */ + uint16_t conn_handle; + uint8_t event_data_length; /**< Length of following data. */ +/** + * This is the identifier which associates the request to the + * response. The same identifier has to be returned by the upper + * layer in the command aci_l2cap_connection_parameter_update_response(). + */ + uint8_t identifier; + uint16_t l2cap_length; /**< Length of the L2CAP connection update request. */ + uint16_t interval_min; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t interval_max; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t slave_latency; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ + uint16_t timeout_mult; /**< Value as defined in Bluetooth 4.0 spec, Volume 3, Part A 4.20. */ +} PACKED evt_l2cap_conn_upd_req; + +/** + * @} + */ + +/** + * @} + */ + + +#endif /* __BLUENRG_L2CAP_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_updater_aci.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,78 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_updater_aci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 26-Jun-2014 +* Description : Header file with updater commands for BlueNRG FW6.3. +******************************************************************************** +* 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. +*******************************************************************************/ + +#ifndef __BLUENRG_UPDATER_ACI_H__ +#define __BLUENRG_UPDATER_ACI_H__ + +#include <compiler.h> + +/** + * @defgroup Updater Updater + * @brief Updater. + * @{ + */ + +/** + * @defgroup Updater_Functions Updater functions + * @brief API for BlueNRG Updater. + * @{ + */ + +tBleStatus aci_updater_start(void); + +tBleStatus aci_updater_reboot(void); + +tBleStatus aci_get_updater_version(uint8_t *version); + +tBleStatus aci_get_updater_buffer_size(uint8_t *buffer_size); + +tBleStatus aci_erase_blue_flag(void); + +tBleStatus aci_reset_blue_flag(void); + +tBleStatus aci_updater_erase_sector(uint32_t address); + +tBleStatus aci_updater_program_data_block(uint32_t address, uint16_t len, const uint8_t *data); + +tBleStatus aci_updater_read_data_block(uint32_t address, uint16_t data_len, uint8_t *data); + +tBleStatus aci_updater_calc_crc(uint32_t address, uint8_t num_sectors, uint32_t *crc); + +tBleStatus aci_updater_hw_version(uint8_t *version); + +/** + * @} + */ + +/** + * @defgroup Updater_Events Updater events + * @{ + */ +/** HCI vendor specific event, raised at BlueNRG power-up or reboot. */ +#define EVT_BLUE_INITIALIZED (0x0001) +typedef __packed struct _evt_blue_initialized{ + uint8_t reason_code; +} PACKED evt_blue_initialized; +/** + * @} + */ + +/** + * @} + */ + + + +#endif /* __BLUENRG_UPDATER_ACI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/bluenrg_utils.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,197 @@ +/******************** (C) COPYRIGHT 2014 STMicroelectronics ******************** +* File Name : bluenrg_utils.h +* Author : AMS - VMA, RF Application Team +* Version : V1.0.1 +* Date : 03-October-2014 +* Description : Header file for BlueNRG utility functions +******************************************************************************** +* 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. +*******************************************************************************/ +/** + * @file bluenrg_utils.h + * @brief BlueNRG IFR updater & BlueNRG stack updater utility APIs description + * + * <!-- Copyright 2014 by STMicroelectronics. All rights reserved. *80*--> +**/ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __BLUENRG_UTILS_H +#define __BLUENRG_UTILS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "hal_types.h" +#include "compiler.h" + +/* Exported types ------------------------------------------------------------*/ +typedef struct{ + uint8_t stack_mode; + uint8_t day; + uint8_t month; + uint8_t year; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint16_t hs_startup_time; /* In system time units*/ +} IFR_config2_TypeDef; + +/** + * Structure inside IFR for configuration options. + */ +typedef __packed struct{ + uint8_t cold_ana_act_config_table[64]; + uint8_t hot_ana_config_table[64]; + uint8_t stack_mode; + uint8_t gpio_config; + uint8_t rsrvd1[2]; + uint32_t rsrvd2[3]; + uint32_t max_conn_event_time; + uint32_t ls_crystal_period; + uint32_t ls_crystal_freq; + uint16_t slave_sca_ppm; + uint8_t master_sca; + uint8_t rsrvd3; + uint16_t hs_startup_time; /* In system time units*/ + uint8_t rsrvd4[2]; + uint32_t uid; + uint8_t rsrvd5; + uint8_t year; + uint8_t month; + uint8_t day; + uint32_t unused[5]; +} PACKED IFR_config_TypeDef; + +/* Exported constants --------------------------------------------------------*/ +extern const IFR_config_TypeDef IFR_config; + +/* Exported macros -----------------------------------------------------------*/ +#define FROM_US_TO_SYS_TIME(us) ((uint16_t)(us/2.4414)) +#define FROM_SYS_TIME_TO_US(sys) ((uint16_t)(sys*2.4414)) + +/* Convert 2 digit BCD number to an integer */ +#define BCD_TO_INT(bcd) ((bcd & 0xF) + ((bcd & 0xF0) >> 4)*10) + +/* Convert 2 digit number to a BCD number */ +#define INT_TO_BCD(n) ((((uint8_t)n/10)<<4) + (uint8_t)n%10) + +/** + * Return values + */ +#define BLE_UTIL_SUCCESS 0 +#define BLE_UTIL_UNSUPPORTED_VERSION 1 +#define BLE_UTIL_WRONG_IMAGE_SIZE 2 +#define BLE_UTIL_ACI_ERROR 3 +#define BLE_UTIL_CRC_ERROR 4 +#define BLE_UTIL_PARSE_ERROR 5 +#define BLE_UTIL_WRONG_VERIFY 6 + +/* Exported functions ------------------------------------------------------- */ +/** + * @brief Flash a new firmware using internal bootloader. + * @param fw_image Pointer to the firmware image (raw binary data, + * little-endian). + * @param fw_size Size of the firmware image. The firmware image size shall + * be multiple of 4 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION, + * WRONG_IMAGE_SIZE, CRC_ERROR) + */ +int program_device(const uint8_t *fw_image, uint32_t fw_size); + +/** + * @brief Read raw data from IFR (3 64-bytes blocks). + * @param data Pointer to the buffer that will contain the read data. + * Its size must be 192 bytes. This data can be parsed by + * parse_IFR_data_config(). + * @retval int It returns 0 if successful, or a number not equal to 0 in + * case of error (ACI_ERROR, UNSUPPORTED_VERSION) + */ +int read_IFR(uint8_t data[192]); + +/** + * @brief Verify raw data from IFR (3 64-bytes blocks). + * @param ifr_data Pointer to the buffer that will contain the data to verify. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful, or a number not equal to 0 in + case of error (ACI_ERROR, BLE_UTIL_WRONG_VERIFY) + */ +uint8_t verify_IFR(const IFR_config_TypeDef *ifr_data); + +/** + * @brief Program raw data to IFR (3 64-bytes blocks). + * @param ifr_image Pointer to the buffer that will contain the data to program. + * Its size must be 192 bytes. + * @retval int It returns 0 if successful + */ +int program_IFR(const IFR_config_TypeDef *ifr_image); + +/** + * @brief Parse IFR raw data. + * @param data Pointer to the raw data: last 64 bytes read from IFR sector. + * @param IFR_config Data structure that will be filled with parsed data. + * @retval None + */ +void parse_IFR_data_config(const uint8_t data[64], IFR_config2_TypeDef *IFR_config); + +/** + * @brief Check for the correctness of parsed data. + * @param IFR_config Data structure filled with parsed data. + * @retval int It returns 0 if successful, or PARSE_ERROR in case data is + * not correct. + */ +int IFR_validate(IFR_config2_TypeDef *IFR_config); + +/** + * @brief Modify IFR data. (Last 64-bytes block). + * @param IFR_config Structure that contains the new parameters inside the + * IFR configuration data. + * @note It is highly recommended to parse the IFR configuration from + * a working IFR block (this should be done with parse_IFR_data_config()). + * Then it is possible to write the new parameters inside the IFR_config + * structure. + * @param data Pointer to the buffer that contains the original data. It + * will be modified according to the new data in the IFR_config + * structure. Then this data must be written in the last + * 64-byte block in the IFR. + * Its size must be 64 bytes. + * @retval None + */ +void change_IFR_data_config(IFR_config2_TypeDef *IFR_config, uint8_t data[64]); + +/** + * @brief Get BlueNRG hardware and firmware version + * @param hwVersion This parameter returns the Hardware Version (i.e. CUT 3.0 = 0x30, CUT 3.1 = 0x31). + * @param fwVersion This parameter returns the Firmware Version in the format 0xJJMN + * where JJ = Major Version number, M = Minor Version number and N = Patch Version number. + * @retval Status of the call + */ +uint8_t getBlueNRGVersion(uint8_t *hwVersion, uint16_t *fwVersion); + +/** + * @brief Get BlueNRG updater version + * @param version This parameter returns the updater version. If the updadter version is 0x03 + * the chip has the updater old, needs to update the bootloader. + * @retval Status of the call + */ +uint8_t getBlueNRGUpdaterVersion(uint8_t *version); + +/** + * @brief Verifies if the bootloader is patched or not. This function shall be used to fix a bug on + * the HW bootloader related to the 32 MHz external crystal oscillator. + * @retval TRUE if the HW bootloader is already patched, FALSE otherwise + */ +uint8_t isHWBootloader_Patched(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__BLUENRG_UTILS_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/clock.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,59 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : clock.h +* Author : AMS - HEA&RF BU +* Version : V1.0.1 +* Date : 19-July-2012 +* Description : Header file for clock library, that gives a simple time +* reference to the BLE Stack. +******************************************************************************** +* 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. +*******************************************************************************/ + +#ifndef __CLOCK_H__ +#define __CLOCK_H__ + +#include <hal_types.h> + +/** + * Number of clocks in one seconds. + * This value must be set by each platorm implementation, basing on its needs. + */ +extern const uint32_t CLOCK_SECOND; + +typedef uint32_t tClockTime; + +/** + * This function initializes the clock library and should be called before + * any other Stack functions. + * + */ +void Clock_Init(void); + +/** + * This function returns the current system clock time. it is used by + * the host stack and has to be implemented. + * + * @return The current clock time, measured in system ticks. + */ +tClockTime Clock_Time(void); + +/** + * This function waits for a given number of milliseconds. + * + */ +void Clock_Wait(uint32_t i); + +/** + * It suspends system clock. + * + */ +void Clock_Suspend(void); + + +#endif /* __CLOCK_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/compiler.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,34 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : compiler.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Compiler-dependent macros. +******************************************************************************** +* 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. +*******************************************************************************/ + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + +#ifdef __ICCARM__ +#define PACKED +#else +#ifdef __GNUC__ +#undef __packed +#define __packed +#define PACKED __attribute__((packed)) +#else +#define PACKED +#define __packed +#endif +#endif + +/* Change this define to 1 if zero-length arrays are not supported by your compiler. */ +#define VARIABLE_SIZE 1 + +#endif /* DOXYGEN_SHOULD_SKIP_THIS */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/debug.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,74 @@ +/** + ****************************************************************************** + * @file debug.h + * @author CL + * @version V1.0.0 + * @date 04-July-2014 + * @brief This file defines print functions for debug purposes. + ****************************************************************************** + * @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 __DEBUG_H +#define __DEBUG_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include <string.h> + +/* Exported macro ------------------------------------------------------------*/ +#define YOTTA_CFG +//#define DEBUG +#ifdef DEBUG +#include <stdio.h> +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/* Print the data travelling over the SPI in the .csv format for the GUI*/ +//#define PRINT_CSV_FORMAT +#ifdef PRINT_CSV_FORMAT +#include <stdio.h> +#define PRINT_CSV(...) printf(__VA_ARGS__) +#else +#define PRINT_CSV(...) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __DEBUG_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/gp_timer.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,105 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : gp_timer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : General purpose timer library. +******************************************************************************** +* 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. +*******************************************************************************/ + +#ifndef __GP_TIMER_H__ +#define __GP_TIMER_H__ + +#include "clock.h" +#include "ble_status.h" +#ifdef __DMA_LP__ +#include "stm32xx_timerserver.h" +#endif /* __DMA_LP__ */ + +/** + * timer + * + * A structure that represents a timer. Use Timer_Set() to set the timer. + * + */ +struct timer { + +#ifndef DOXYGEN_SHOULD_SKIP_THIS + + tClockTime start; + tClockTime interval; + +#endif +}; + +typedef void (* TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE)(void); + +/** + * Timer_Set + * + * @param[in] t Pointer to a timer structure + * @param[in] interval timeout value + * + * This function sets the timeout value of a timer. + * + */ +void Timer_Set(struct timer *t, tClockTime interval); + +/** + * Timer_Reset + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the time it previously expired. + * + */ +void Timer_Reset(struct timer *t); + +/** + * Timer_Restart + * + * @param[in] t Pointer to a timer structure + * + * This function resets the timer with the same interval given + * with Timer_Set, starting from the current time. + * + */ +void Timer_Restart(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns TRUE if timer is expired, FALSE otherwise. + * + */ +int Timer_Expired(struct timer *t); + +/** + * Timer_Expired + * + * @param[in] t Pointer to a timer structure + * + * This function returns the time needed for expiration. + * + * @return Time before timer's expiration. + */ +tClockTime Timer_Remaining(struct timer *t); + +#ifdef __DMA_LP__ +tBleStatus Blue_NRG_HCI_Timer_Start(uint32_t expiryTime, + TIMER_HCI_TIMEOUT_NOTIFY_CALLBACK_TYPE timercb, + uint8_t *timerID); + +tBleStatus Blue_NRG_HCI_Timer_Stop(uint8_t timerID); +#endif /* __DMA_LP__ */ + +#endif /* __GP_TIMER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/hal.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,106 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : hal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file which defines Hardware abstraction layer APIs +* used by the BLE stack. It defines the set of functions +* which needs to be ported to the target platform. +******************************************************************************** +* 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. +*******************************************************************************/ +#ifndef __HAL_H__ +#define __HAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <hal_types.h> +#include <ble_status.h> + + +/****************************************************************************** + * Macros + *****************************************************************************/ +/* Little Endian buffer to host endianess conversion */ +#define LE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) << 8 ) ) + +#define LE_TO_HOST_32(ptr) (uint32_t) ( ((uint32_t) \ + *((uint8_t *)ptr)) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 1) << 8) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 2) << 16) | \ + ((uint32_t) \ + *((uint8_t *)ptr + 3) << 24) ) + +/* Big Endian buffer to host endianess conversion */ +#define BE_TO_HOST_16(ptr) (uint16_t) ( ((uint16_t) \ + *((uint8_t *)ptr)) << 8 | \ + ((uint16_t) \ + *((uint8_t *)ptr + 1) ) ) + +/* Store Value into a buffer in Little Endian Format */ +#define HOST_TO_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define HOST_TO_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + + +/* Store Value into a buffer in Big Endian Format */ +#define HOST_TO_BE_16(buf, val) ( ((buf)[1] = (uint8_t) (val) ) , \ + ((buf)[0] = (uint8_t) (val>>8) ) ) + +#define DISABLE_INTERRUPTS() __disable_interrupt() +#define ENABLE_INTERRUPTS() __enable_interrupt() +#define SAVE_PRIMASK() uint32_t uwPRIMASK_Bit = __get_PRIMASK() +#define ATOMIC_SECTION_BEGIN() uint32_t uwPRIMASK_Bit = __get_PRIMASK(); \ + __disable_interrupt(); \ +/* Must be called in the same or in a lower scope of SUSPEND_INTERRUPTS */ +#define ATOMIC_SECTION_END() __set_PRIMASK(uwPRIMASK_Bit) + +/****************************************************************************** + * Types + *****************************************************************************/ + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * Writes data to a serial interface. + * + * @param[in] data1 1st buffer + * @param[in] data2 2nd buffer + * @param[in] n_bytes1 number of bytes in 1st buffer + * @param[in] n_bytes2 number of bytes in 2nd buffer + */ +void Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); + +/** + * Enable interrupts from HCI controller. + */ +void Enable_SPI_IRQ(void); + +/** + * Disable interrupts from BLE controller. + */ +void Disable_SPI_IRQ(void); + +void Hal_Init_Timer(void); +uint32_t Hal_Get_Timer_Value(void); +void Hal_Start_Timer(uint32_t timeout); +void Hal_Stop_Timer(void); + +#endif /* __HAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/hal_types.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,58 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : hal_types.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the basic data types used by the +* BLE stack. +******************************************************************************** +* 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. +*******************************************************************************/ +#ifndef __HAL_TYPES_H__ +#define __HAL_TYPES_H__ + +#include <stdint.h> + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef __LITTLE_ENDIAN +#define __LITTLE_ENDIAN 0 +#define __BIG_ENDIAN 1 +#endif + +/* Byte order conversions */ +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define htobs(d) (d) +#define htobl(d) (d) +#define btohs(d) (d) +#define btohl(d) (d) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define htobs(d) (d<<8|d>>8) +#define htobl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#define btohs(d) (d<<8|d>>8) +#define btohl(d) (d<<24|((d<<8)&0x00ff0000)|((d>>8)&0x0000ff00)|((d>>24)&0x000000ff)) +#else +#error "Unknown byte order" +#endif + +typedef uint8_t BOOL; + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + + + +#endif /* __HAL_TYPES_H__ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/hci.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,239 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : hci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Constants and functions for HCI layer. See Bluetooth Core +* v 4.0, Vol. 2, Part E. +******************************************************************************** +* 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. +*******************************************************************************/ + +#ifndef __HCI_H_ +#define __HCI_H_ + +#include "hal_types.h" +#include "link_layer.h" +#include <list.h> + +#define HCI_READ_PACKET_SIZE 128 //71 + +/*** Data types ***/ + +/* structure used to read received data */ +typedef struct _tHciDataPacket +{ + tListNode currentNode; + uint8_t dataBuff[HCI_READ_PACKET_SIZE]; + uint8_t data_len; +} tHciDataPacket; + +typedef enum +{ + BUSY, + AVAILABLE +} HCI_CMD_STATUS_t; + +/** + * @defgroup HCI_Error_codes HCI Error codes + * @{ + */ +#define HCI_UNKNOWN_COMMAND 0x01 +#define HCI_NO_CONNECTION 0x02 +#define HCI_HARDWARE_FAILURE 0x03 +#define HCI_PAGE_TIMEOUT 0x04 +#define HCI_AUTHENTICATION_FAILURE 0x05 +#define HCI_PIN_OR_KEY_MISSING 0x06 +#define HCI_MEMORY_FULL 0x07 +#define HCI_CONNECTION_TIMEOUT 0x08 +#define HCI_MAX_NUMBER_OF_CONNECTIONS 0x09 +#define HCI_MAX_NUMBER_OF_SCO_CONNECTIONS 0x0a +#define HCI_ACL_CONNECTION_EXISTS 0x0b +#define HCI_COMMAND_DISALLOWED 0x0c +#define HCI_REJECTED_LIMITED_RESOURCES 0x0d +#define HCI_REJECTED_SECURITY 0x0e +#define HCI_REJECTED_PERSONAL 0x0f +#define HCI_HOST_TIMEOUT 0x10 +#define HCI_UNSUPPORTED_FEATURE 0x11 +#define HCI_INVALID_PARAMETERS 0x12 +#define HCI_OE_USER_ENDED_CONNECTION 0x13 +#define HCI_OE_LOW_RESOURCES 0x14 +#define HCI_OE_POWER_OFF 0x15 +#define HCI_CONNECTION_TERMINATED 0x16 +#define HCI_REPEATED_ATTEMPTS 0x17 +#define HCI_PAIRING_NOT_ALLOWED 0x18 +#define HCI_UNKNOWN_LMP_PDU 0x19 +#define HCI_UNSUPPORTED_REMOTE_FEATURE 0x1a +#define HCI_SCO_OFFSET_REJECTED 0x1b +#define HCI_SCO_INTERVAL_REJECTED 0x1c +#define HCI_AIR_MODE_REJECTED 0x1d +#define HCI_INVALID_LMP_PARAMETERS 0x1e +#define HCI_UNSPECIFIED_ERROR 0x1f +#define HCI_UNSUPPORTED_LMP_PARAMETER_VALUE 0x20 +#define HCI_ROLE_CHANGE_NOT_ALLOWED 0x21 +#define HCI_LMP_RESPONSE_TIMEOUT 0x22 +#define HCI_LMP_ERROR_TRANSACTION_COLLISION 0x23 +#define HCI_LMP_PDU_NOT_ALLOWED 0x24 +#define HCI_ENCRYPTION_MODE_NOT_ACCEPTED 0x25 +#define HCI_UNIT_LINK_KEY_USED 0x26 +#define HCI_QOS_NOT_SUPPORTED 0x27 +#define HCI_INSTANT_PASSED 0x28 +#define HCI_PAIRING_NOT_SUPPORTED 0x29 +#define HCI_TRANSACTION_COLLISION 0x2a +#define HCI_QOS_UNACCEPTABLE_PARAMETER 0x2c +#define HCI_QOS_REJECTED 0x2d +#define HCI_CLASSIFICATION_NOT_SUPPORTED 0x2e +#define HCI_INSUFFICIENT_SECURITY 0x2f +#define HCI_PARAMETER_OUT_OF_RANGE 0x30 +#define HCI_ROLE_SWITCH_PENDING 0x32 +#define HCI_SLOT_VIOLATION 0x34 +#define HCI_ROLE_SWITCH_FAILED 0x35 +#define HCI_EIR_TOO_LARGE 0x36 +#define HCI_SIMPLE_PAIRING_NOT_SUPPORTED 0x37 +#define HCI_HOST_BUSY_PAIRING 0x38 +#define HCI_CONN_REJ_NO_CH_FOUND 0x39 +#define HCI_CONTROLLER_BUSY 0x3A +#define HCI_UNACCEPTABLE_CONN_INTERV 0x3B +#define HCI_DIRECTED_ADV_TIMEOUT 0x3C +#define HCI_CONN_TERM_MIC_FAIL 0x3D +#define HCI_CONN_FAIL_TO_BE_ESTABL 0x3E +#define HCI_MAC_CONN_FAILED 0x3F +/** + * @} + */ + + +/* + * HCI library functions. + * Each function returns 0 in case of success, otherwise one of the error codes. + */ + +int hci_reset(void); + +int hci_disconnect(uint16_t handle, uint8_t reason); + +int hci_le_set_advertise_enable(uint8_t enable); + +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); + +int hci_le_set_scan_parameters(uint8_t type, uint16_t interval, + uint16_t window, uint8_t own_bdaddr_type, + uint8_t filter); + +int hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dup); + +int hci_le_set_advertising_data(uint8_t length, const uint8_t data[]); + +int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]); + +int hci_le_rand(uint8_t random_number[8]); + +int hci_le_read_advertising_channel_tx_power(int8_t *tx_power_level); + +int hci_acl_data(const uint8_t * data, uint16_t len); + +int hci_le_set_random_address(tBDAddr bdaddr); + +int hci_read_bd_addr(tBDAddr bdaddr); + +int hci_le_read_white_list_size(uint8_t *size); + +int hci_le_clear_white_list(void); + +int hci_le_add_device_to_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_remove_device_from_white_list(uint8_t bdaddr_type, tBDAddr bdaddr); + +int hci_le_encrypt(uint8_t key[16], uint8_t plaintextData[16], uint8_t encryptedData[16]); + +int hci_le_ltk_request_reply(uint8_t key[16]); + +int hci_le_ltk_request_neg_reply(void); + +int hci_le_read_buffer_size(uint16_t *pkt_len, uint8_t *max_pkt); + +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); + +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); + +int hci_le_read_local_supported_features(uint8_t *features); + +int hci_le_read_channel_map(uint16_t conn_handle, uint8_t ch_map[5]); + +int hci_le_read_supported_states(uint8_t states[8]); + +int hci_le_receiver_test(uint8_t frequency); + +int hci_le_transmitter_test(uint8_t frequency, uint8_t length, uint8_t payload); + +int hci_le_test_end(uint16_t *num_pkts); + +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); + +/** + * This function must be used to pass the packet received from the HCI + * interface to the BLE Stack HCI state machine. + * + * @param[in] hciReadPacket The packet that is received from HCI interface. + * + */ +void HCI_Input(tHciDataPacket *hciReadPacket); + +/** + * Initialization function. Must be done before any data can be received from + * BLE controller. + */ +void HCI_Init(void); + +/** + * Callback used to pass events to application. + * + * @param[in] pckt The event. + * + */ +extern void HCI_Event_CB(void *pckt); + +/** + * Processing function that must be called after an event is received from + * HCI interface. Must be called outside ISR. It will call HCI_Event_CB if + * necessary. +*/ +void HCI_Process(void); + +/** + * @brief Check if queue of HCI event is empty or not. + * @note This funtion can be used to check if the event queue from BlueNRG is empty. This + * is useful when checking if it is safe to go to sleep. + * @return TRUE if event queue is empty. FALSE otherwhise. + */ +BOOL HCI_Queue_Empty(void); +/** + * Iterrupt service routine that must be called when the BlueNRG + * reports a packet received or an event to the host through the + * BlueNRG interrupt line. + */ +#ifdef __DMA_LP__ +void HCI_Isr(uint8_t *buffer, uint8_t event_payload_len); +void HCI_Process_Notification_Request(void); +void HCI_Cmd_Status(HCI_CMD_STATUS_t Hci_Cmd_Status); +void HCI_Wait_For_Response(void); +#else +void HCI_Isr(void); +#endif /* __DMA_LP__ */ + +extern tListNode hciReadPktPool; +extern tListNode hciReadPktRxQueue; + +#endif /* __HCI_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/hci_const.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,564 @@ +/****************************************************************************** +* +* File Description +* --------------------- +* This file defines constants and functions for HCI layer. +* See Bluetooth Core v 4.0, Vol. 2, Part E. +* +*******************************************************************************/ + +#ifndef __HCI_INTERNAL_H_ +#define __HCI_INTERNAL_H_ + +#include "compiler.h" +#include "hal_types.h" +#include "clock.h" +#include "link_layer.h" + +#include "hci.h" + +#define DEFAULT_TIMEOUT (CLOCK_SECOND/10) + +/** + * Maximum payload of HCI commands that can be sent. Change this value if needed. + * This value can be up to 255. + */ +#define HCI_MAX_PAYLOAD_SIZE 128 + +/* HCI Packet types */ +#define HCI_COMMAND_PKT 0x01 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 +#define HCI_EVENT_PKT 0x04 +#define HCI_VENDOR_PKT 0xff + +typedef __packed struct _hci_uart_pckt{ + uint8_t type; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_uart_pckt; +#define HCI_HDR_SIZE 1 + +typedef __packed struct _hci_command_hdr{ + uint16_t opcode; /* OCF & OGF */ + uint8_t plen; +} PACKED hci_command_hdr; +#define HCI_COMMAND_HDR_SIZE 3 + +typedef __packed struct _hci_event_pckt{ + uint8_t evt; + uint8_t plen; + uint8_t data[VARIABLE_SIZE]; +} PACKED hci_event_pckt; +#define HCI_EVENT_HDR_SIZE 2 + +typedef __packed struct _hci_acl_hdr{ + uint16_t handle; /* Handle & Flags(PB, BC) */ + uint16_t dlen; +} PACKED hci_acl_hdr; +#define HCI_ACL_HDR_SIZE 4 + +/* Link Control */ +#define OGF_LINK_CTL 0x01 + +#define OCF_DISCONNECT 0x0006 +typedef __packed struct _disconnect_cp{ + uint16_t handle; + uint8_t reason; +} PACKED disconnect_cp; +#define DISCONNECT_CP_SIZE 3 + +/* Host Controller and Baseband */ +#define OGF_HOST_CTL 0x03 + +#define OCF_SET_EVENT_MASK 0x0001 +#define OCF_RESET 0x0003 + +#define OCF_READ_TRANSMIT_POWER_LEVEL 0x002D +typedef __packed struct _read_transmit_power_level_cp{ + uint16_t handle; + uint8_t type; +} PACKED read_transmit_power_level_cp; +#define READ_TRANSMIT_POWER_LEVEL_CP_SIZE 3 +typedef __packed struct _read_transmit_power_level_rp{ + uint8_t status; + uint16_t handle; + int8_t level; +} PACKED read_transmit_power_level_rp; +#define READ_TRANSMIT_POWER_LEVEL_RP_SIZE 4 + +#define OCF_SET_CONTROLLER_TO_HOST_FC 0x0031 +#define OCF_HOST_BUFFER_SIZE 0x0033 +#define OCF_HOST_NUM_COMP_PKTS 0x0035 + +/* Informational Parameters */ +#define OGF_INFO_PARAM 0x04 + +#define OCF_READ_LOCAL_VERSION 0x0001 +typedef __packed struct _read_local_version_rp{ + uint8_t status; + uint8_t hci_version; + uint16_t hci_revision; + uint8_t lmp_pal_version; + uint16_t manufacturer_name; + uint16_t lmp_pal_subversion; +} PACKED read_local_version_rp; +#define READ_LOCAL_VERSION_RP_SIZE 9 + +#define OCF_READ_LOCAL_COMMANDS 0x0002 +#define OCF_READ_LOCAL_FEATURES 0x0003 + +#define OCF_READ_BD_ADDR 0x0009 +typedef __packed struct _read_bd_addr_rp{ + uint8_t status; + tBDAddr bdaddr; +} PACKED read_bd_addr_rp; +#define READ_BD_ADDR_RP_SIZE 7 + +/* Status params */ +#define OGF_STATUS_PARAM 0x05 + +#define OCF_READ_RSSI 0x0005 +typedef __packed struct _read_rssi_cp{ + uint16_t handle; +} PACKED read_rssi_cp; +#define READ_RSSI_CP_SIZE 2 +typedef __packed struct _read_rssi_rp{ + uint8_t status; + uint16_t handle; + int8_t rssi; +} PACKED read_rssi_rp; +#define READ_RSSI_RP_SIZE 4 + + +/* LE commands */ +#define OGF_LE_CTL 0x08 + +#define OCF_LE_SET_EVENT_MASK 0x0001 +typedef __packed struct _le_set_event_mask_cp{ + uint8_t mask[8]; +} PACKED le_set_event_mask_cp; +#define LE_SET_EVENT_MASK_CP_SIZE 8 + +#define OCF_LE_READ_BUFFER_SIZE 0x0002 +typedef __packed struct _le_read_buffer_size_rp{ + uint8_t status; + uint16_t pkt_len; + uint8_t max_pkt; +} PACKED le_read_buffer_size_rp; +#define LE_READ_BUFFER_SIZE_RP_SIZE 4 + +#define OCF_LE_READ_LOCAL_SUPPORTED_FEATURES 0x0003 +typedef __packed struct _le_read_local_supported_features_rp{ + uint8_t status; + uint8_t features[8]; +} PACKED le_read_local_supported_features_rp; +#define LE_READ_LOCAL_SUPPORTED_FEATURES_RP_SIZE 9 + +#define OCF_LE_SET_RANDOM_ADDRESS 0x0005 +typedef __packed struct _le_set_random_address_cp{ + tBDAddr bdaddr; +} PACKED le_set_random_address_cp; +#define LE_SET_RANDOM_ADDRESS_CP_SIZE 6 + +#define OCF_LE_SET_ADV_PARAMETERS 0x0006 +typedef __packed struct _le_set_adv_parameters_cp{ + uint16_t min_interval; + uint16_t max_interval; + uint8_t advtype; + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; + uint8_t chan_map; + uint8_t filter; +} PACKED le_set_adv_parameters_cp; +#define LE_SET_ADV_PARAMETERS_CP_SIZE 15 + +#define OCF_LE_READ_ADV_CHANNEL_TX_POWER 0x0007 +typedef __packed struct _le_read_adv_channel_tx_power_rp{ + uint8_t status; + int8_t level; +} PACKED le_read_adv_channel_tx_power_rp; +#define LE_READ_ADV_CHANNEL_TX_POWER_RP_SIZE 2 + +#define OCF_LE_SET_ADV_DATA 0x0008 +typedef __packed struct _le_set_adv_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_adv_data_cp; +#define LE_SET_ADV_DATA_CP_SIZE 32 + +#define OCF_LE_SET_SCAN_RESPONSE_DATA 0x0009 +typedef __packed struct _le_set_scan_response_data_cp{ + uint8_t length; + uint8_t data[31]; +} PACKED le_set_scan_response_data_cp; +#define LE_SET_SCAN_RESPONSE_DATA_CP_SIZE 32 + +#define OCF_LE_SET_ADVERTISE_ENABLE 0x000A +typedef __packed struct _le_set_advertise_enable_cp{ + uint8_t enable; +} PACKED le_set_advertise_enable_cp; +#define LE_SET_ADVERTISE_ENABLE_CP_SIZE 1 + +#define OCF_LE_SET_SCAN_PARAMETERS 0x000B +typedef __packed struct _le_set_scan_parameters_cp{ + uint8_t type; + uint16_t interval; + uint16_t window; + uint8_t own_bdaddr_type; + uint8_t filter; +} PACKED le_set_scan_parameters_cp; +#define LE_SET_SCAN_PARAMETERS_CP_SIZE 7 + +#define OCF_LE_SET_SCAN_ENABLE 0x000C +typedef __packed struct _le_set_scan_enable_cp{ + uint8_t enable; + uint8_t filter_dup; +} PACKED le_set_scan_enable_cp; +#define LE_SET_SCAN_ENABLE_CP_SIZE 2 + +#define OCF_LE_CREATE_CONN 0x000D +typedef __packed struct _le_create_connection_cp{ + uint16_t interval; + uint16_t window; + uint8_t initiator_filter; + uint8_t peer_bdaddr_type; + 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; +} PACKED le_create_connection_cp; +#define LE_CREATE_CONN_CP_SIZE 25 + +#define OCF_LE_CREATE_CONN_CANCEL 0x000E + +#define OCF_LE_READ_WHITE_LIST_SIZE 0x000F +typedef __packed struct _le_read_white_list_size_rp{ + uint8_t status; + uint8_t size; +} PACKED le_read_white_list_size_rp; +#define LE_READ_WHITE_LIST_SIZE_RP_SIZE 2 + +#define OCF_LE_CLEAR_WHITE_LIST 0x0010 + +#define OCF_LE_ADD_DEVICE_TO_WHITE_LIST 0x0011 +typedef __packed struct _le_add_device_to_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_add_device_to_white_list_cp; +#define LE_ADD_DEVICE_TO_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_REMOVE_DEVICE_FROM_WHITE_LIST 0x0012 +typedef __packed struct _le_remove_device_from_white_list_cp{ + uint8_t bdaddr_type; + tBDAddr bdaddr; +} PACKED le_remove_device_from_white_list_cp; +#define LE_REMOVE_DEVICE_FROM_WHITE_LIST_CP_SIZE 7 + +#define OCF_LE_CONN_UPDATE 0x0013 +typedef __packed struct _le_connection_update_cp{ + uint16_t handle; + 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; +} PACKED le_connection_update_cp; +#define LE_CONN_UPDATE_CP_SIZE 14 + +#define OCF_LE_SET_HOST_CHANNEL_CLASSIFICATION 0x0014 +typedef __packed struct _le_set_host_channel_classification_cp{ + uint8_t map[5]; +} PACKED le_set_host_channel_classification_cp; +#define LE_SET_HOST_CHANNEL_CLASSIFICATION_CP_SIZE 5 + +#define OCF_LE_READ_CHANNEL_MAP 0x0015 +typedef __packed struct _le_read_channel_map_cp{ + uint16_t handle; +} PACKED le_read_channel_map_cp; +#define LE_READ_CHANNEL_MAP_CP_SIZE 2 + +typedef __packed struct _le_read_channel_map_rp{ + uint8_t status; + uint16_t handle; + uint8_t map[5]; +} le_read_channel_map_rp; +#define LE_READ_CHANNEL_MAP_RP_SIZE 8 + +#define OCF_LE_READ_REMOTE_USED_FEATURES 0x0016 +typedef __packed struct _le_read_remote_used_features_cp{ + uint16_t handle; +} PACKED le_read_remote_used_features_cp; +#define LE_READ_REMOTE_USED_FEATURES_CP_SIZE 2 + +#define OCF_LE_ENCRYPT 0x0017 +typedef __packed struct _le_encrypt_cp{ + uint8_t key[16]; + uint8_t plaintext[16]; +} PACKED le_encrypt_cp; +#define LE_ENCRYPT_CP_SIZE 32 + +typedef __packed struct _le_encrypt_rp{ + uint8_t status; + uint8_t encdata[16]; +} PACKED le_encrypt_rp; +#define LE_ENCRYPT_RP_SIZE 17 + +#define OCF_LE_RAND 0x0018 +typedef __packed struct _le_rand_rp{ + uint8_t status; + uint8_t random[8]; +} PACKED le_rand_rp; +#define LE_RAND_RP_SIZE 9 + +#define OCF_LE_START_ENCRYPTION 0x0019 +typedef __packed struct _le_start_encryption_cp{ + uint16_t handle; + uint8_t random[8]; + uint16_t diversifier; + uint8_t key[16]; +} PACKED le_start_encryption_cp; +#define LE_START_ENCRYPTION_CP_SIZE 28 + +#define OCF_LE_LTK_REPLY 0x001A +typedef __packed struct _le_ltk_reply_cp{ + uint16_t handle; + uint8_t key[16]; +} PACKED le_ltk_reply_cp; +#define LE_LTK_REPLY_CP_SIZE 18 + +typedef __packed struct _le_ltk_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_reply_rp; +#define LE_LTK_REPLY_RP_SIZE 3 + +#define OCF_LE_LTK_NEG_REPLY 0x001B +typedef __packed struct _le_ltk_neg_reply_cp{ + uint16_t handle; +} PACKED le_ltk_neg_reply_cp; +#define LE_LTK_NEG_REPLY_CP_SIZE 2 + +typedef __packed struct _le_ltk_neg_reply_rp{ + uint8_t status; + uint16_t handle; +} PACKED le_ltk_neg_reply_rp; +#define LE_LTK_NEG_REPLY_RP_SIZE 3 + +#define OCF_LE_READ_SUPPORTED_STATES 0x001C +typedef __packed struct _le_read_supported_states_rp{ + uint8_t status; + uint8_t states[8]; +} PACKED le_read_supported_states_rp; +#define LE_READ_SUPPORTED_STATES_RP_SIZE 9 + +#define OCF_LE_RECEIVER_TEST 0x001D +typedef __packed struct _le_receiver_test_cp{ + uint8_t frequency; +} PACKED le_receiver_test_cp; +#define LE_RECEIVER_TEST_CP_SIZE 1 + +#define OCF_LE_TRANSMITTER_TEST 0x001E +typedef __packed struct _le_transmitter_test_cp{ + uint8_t frequency; + uint8_t length; + uint8_t payload; +} PACKED le_transmitter_test_cp; +#define LE_TRANSMITTER_TEST_CP_SIZE 3 + +#define OCF_LE_TEST_END 0x001F +typedef __packed struct _le_test_end_rp{ + uint8_t status; + uint16_t num_pkts; +} PACKED le_test_end_rp; +#define LE_TEST_END_RP_SIZE 3 + +/* Vendor specific commands */ +#define OGF_VENDOR_CMD 0x3f + + +/*------------- Events -------------*/ +#define EVT_CONN_COMPLETE 0x03 +typedef __packed struct _evt_conn_complete{ + uint8_t status; + uint16_t handle; + tBDAddr bdaddr; + uint8_t link_type; + uint8_t encr_mode; +} PACKED evt_conn_complete; +#define EVT_CONN_COMPLETE_SIZE 13 + +#define EVT_DISCONN_COMPLETE 0x05 +typedef __packed struct _evt_disconn_complete{ + uint8_t status; + uint16_t handle; + uint8_t reason; +} PACKED evt_disconn_complete; +#define EVT_DISCONN_COMPLETE_SIZE 4 + +#define EVT_ENCRYPT_CHANGE 0x08 +typedef __packed struct _evt_encrypt_change{ + uint8_t status; + uint16_t handle; + uint8_t encrypt; +} PACKED evt_encrypt_change; +#define EVT_ENCRYPT_CHANGE_SIZE 5 + +#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C + +#define EVT_CMD_COMPLETE 0x0E +typedef __packed struct _evt_cmd_complete{ + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_complete; +#define EVT_CMD_COMPLETE_SIZE 3 + +#define EVT_CMD_STATUS 0x0F +typedef __packed struct _evt_cmd_status{ + uint8_t status; + uint8_t ncmd; + uint16_t opcode; +} PACKED evt_cmd_status; +#define EVT_CMD_STATUS_SIZE 4 + +#define EVT_HARDWARE_ERROR 0x10 +typedef __packed struct _evt_hardware_error{ + uint8_t code; +} PACKED evt_hardware_error; +#define EVT_HARDWARE_ERROR_SIZE 1 + +#define EVT_NUM_COMP_PKTS 0x13 +typedef __packed struct _evt_num_comp_pkts{ + uint8_t num_hndl; + /* variable length part */ +} PACKED evt_num_comp_pkts; +#define EVT_NUM_COMP_PKTS_SIZE 1 + +/* variable length part of evt_num_comp_pkts. */ +typedef __packed struct _evt_num_comp_pkts_param{ + uint16_t hndl; + uint16_t num_comp_pkts; +} PACKED evt_num_comp_pkts_param; +#define EVT_NUM_COMP_PKTS_PARAM_SIZE 1 + +#define EVT_DATA_BUFFER_OVERFLOW 0x1A +typedef __packed struct _evt_data_buffer_overflow{ + uint8_t link_type; +} PACKED evt_data_buffer_overflow; +#define EVT_DATA_BUFFER_OVERFLOW_SIZE 1 + +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 +typedef __packed struct _evt_encryption_key_refresh_complete{ + uint8_t status; + uint16_t handle; +} PACKED evt_encryption_key_refresh_complete; +#define EVT_ENCRYPTION_KEY_REFRESH_COMPLETE_SIZE 3 + +#define EVT_LE_META_EVENT 0x3E +typedef __packed struct _evt_le_meta_event{ + uint8_t subevent; + uint8_t data[VARIABLE_SIZE]; +} PACKED evt_le_meta_event; +#define EVT_LE_META_EVENT_SIZE 1 + +#define EVT_LE_CONN_COMPLETE 0x01 +typedef __packed struct _evt_le_connection_complete{ + uint8_t status; + uint16_t handle; + uint8_t role; + uint8_t peer_bdaddr_type; + tBDAddr peer_bdaddr; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; + uint8_t master_clock_accuracy; +} PACKED evt_le_connection_complete; +#define EVT_LE_CONN_COMPLETE_SIZE 18 + +#define EVT_LE_ADVERTISING_REPORT 0x02 +typedef __packed struct _le_advertising_info{ + uint8_t evt_type; + uint8_t bdaddr_type; + tBDAddr bdaddr; + uint8_t data_length; + uint8_t data_RSSI[VARIABLE_SIZE]; // RSSI is last octect (signed integer). +} PACKED le_advertising_info; +#define LE_ADVERTISING_INFO_SIZE 9 + +#define EVT_LE_CONN_UPDATE_COMPLETE 0x03 +typedef __packed struct _evt_le_connection_update_complete{ + uint8_t status; + uint16_t handle; + uint16_t interval; + uint16_t latency; + uint16_t supervision_timeout; +} PACKED evt_le_connection_update_complete; +#define EVT_LE_CONN_UPDATE_COMPLETE_SIZE 9 + +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE 0x04 +typedef __packed struct _evt_le_read_remote_used_features_complete{ + uint8_t status; + uint16_t handle; + uint8_t features[8]; +} PACKED evt_le_read_remote_used_features_complete; +#define EVT_LE_READ_REMOTE_USED_FEATURES_COMPLETE_SIZE 11 + +#define EVT_LE_LTK_REQUEST 0x05 +typedef __packed struct _evt_le_long_term_key_request{ + uint16_t handle; + uint8_t random[8]; + uint16_t ediv; +} PACKED evt_le_long_term_key_request; +#define EVT_LE_LTK_REQUEST_SIZE 12 + +/** +* The event code in the @ref hci_event_pckt structure. If event code is EVT_VENDOR, +* application can use @ref evt_blue_aci structure to parse the packet. +*/ +#define EVT_VENDOR 0xFF + + +/* Command opcode pack/unpack */ +#define cmd_opcode_pack(ogf, ocf) (uint16_t)((ocf & 0x03ff)|(ogf << 10)) +#define cmd_opcode_ogf(op) (op >> 10) +#define cmd_opcode_ocf(op) (op & 0x03ff) + + +struct hci_request { + uint16_t ogf; + uint16_t ocf; + int event; + void *cparam; + int clen; + void *rparam; + int rlen; +}; + +void hci_send_cmd(uint16_t ogf, uint16_t ocf, uint8_t plen, void *param); + +typedef enum { + WAITING_TYPE, + WAITING_OPCODE1, + WAITING_OPCODE2, + WAITING_EVENT_CODE, + WAITING_HANDLE, + WAITING_HANDLE_FLAG, + WAITING_PARAM_LEN, + WAITING_DATA_LEN1, + WAITING_DATA_LEN2, + WAITING_PAYLOAD +}hci_state; + +typedef void (*hci_packet_complete_callback)(void *pckt, uint16_t len); + +/* HCI library functions. */ +void hci_init(void); + +int hci_send_req(struct hci_request *r, BOOL async); + +#endif /* __HCI_INTERNAL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/link_layer.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,161 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : link_layer.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's link layer. It contains +* definition of functions for link layer, most of which are +* mapped to HCI commands. +******************************************************************************** +* 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. +*******************************************************************************/ + +#ifndef _LINK_LAYER_H +#define _LINK_LAYER_H + +#include <ble_status.h> + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/** + *@name Advertising filter + *Advertising policy for filtering (white list related) + *@{ + */ +#define NO_WHITE_LIST_USE (0x00) /**< Process scan and connection requests from all devices (i.e., the White List is not in use) */ +#define WHITE_LIST_FOR_ONLY_SCAN (0x01) /**< Process connection requests from all devices and only scan requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ONLY_CONN (0x02) /**< Process scan requests from all devices and only connection requests from devices that are in the White List */ +#define WHITE_LIST_FOR_ALL (0x03) /**< Process scan and connection requests only from devices in the White List. */ +/** + * @} + */ + + +/** + * Bluetooth 48 bit address (in little-endian order). + */ +typedef uint8_t tBDAddr[6]; + + +/** + *@name Bluetooth address types + * Bluetooth address types + *@{ + */ +#define PUBLIC_ADDR (0) +#define RANDOM_ADDR (1) +#define STATIC_RANDOM_ADDR (1) +#define RESOLVABLE_PRIVATE_ADDR (2) +#define NON_RESOLVABLE_PRIVATE_ADDR (3) +/** + * @} + */ + +/** + *@name Directed advertising types + * Type of advertising during directed advertising + *@{ + */ +#define HIGH_DUTY_CYCLE_DIRECTED_ADV (1) +#define LOW_DUTY_CYCLE_DIRECTED_ADV (4) +/** + * @} + */ + +/** + * @name Advertising type + * @{ + */ + +/** + * undirected scannable and connectable + */ +#define ADV_IND (0x00) + +/** + * directed non scannable + */ +#define ADV_DIRECT_IND (0x01) + +/** + * scannable non connectable + */ +#define ADV_SCAN_IND (0x02) + +/** + * non-connectable and no scan response (used for passive scan) + */ +#define ADV_NONCONN_IND (0x03) + +/** + * scan response + */ +#define SCAN_RSP (0x04) + +/** + * @} + */ + +/* 0X05-0XFF RESERVED */ + +/** + * @name Advertising ranges + * @{ + */ + +/** + * lowest allowed interval value for connectable types(20ms)..multiple of 625us + */ +#define ADV_INTERVAL_LOWEST_CONN (0X0020) + +/** + * highest allowed interval value (10.24s)..multiple of 625us. + */ +#define ADV_INTERVAL_HIGHEST (0X4000) + +/** + * lowest allowed interval value for non connectable types + * (100ms)..multiple of 625us. + */ +#define ADV_INTERVAL_LOWEST_NONCONN (0X00a0) + +/** + * @} + */ + +/** + * @name Advertising channels + * @{ + */ +#define ADV_CH_37 0x01 +#define ADV_CH_38 0x02 +#define ADV_CH_39 0x04 +/** + * @} + */ + +/** + * @name Scan_types Scan types + * @{ + */ +#define PASSIVE_SCAN 0 +#define ACTIVE_SCAN 1 +/** + * @} + */ + +/** + * @} + */ + + +#endif /* _LINK_LAYER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/list.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,47 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : list.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for linked list library. +******************************************************************************** +* 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. +*******************************************************************************/ +#ifndef _LIST_H_ +#define _LIST_H_ + +typedef struct _tListNode { + struct _tListNode * next; + struct _tListNode * prev; +}tListNode, *pListNode; + +void list_init_head (tListNode * listHead); + +uint8_t list_is_empty (tListNode * listHead); + +void list_insert_head (tListNode * listHead, tListNode * node); + +void list_insert_tail (tListNode * listHead, tListNode * node); + +void list_remove_node (tListNode * node); + +void list_remove_head (tListNode * listHead, tListNode ** node ); + +void list_remove_tail (tListNode * listHead, tListNode ** node ); + +void list_insert_node_after (tListNode * node, tListNode * ref_node); + +void list_insert_node_before (tListNode * node, tListNode * ref_node); + +int list_get_size (tListNode * listHead); + +void list_get_next_node (tListNode * ref_node, tListNode ** node); + +void list_get_prev_node (tListNode * ref_node, tListNode ** node); + +#endif /* _LIST_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/osal.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,81 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : osal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : This header file defines the OS abstraction layer used by +* the BLE stack. OSAL defines the set of functions +* which needs to be ported to target operating system and +* target platform. +******************************************************************************** +* 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. +*******************************************************************************/ + +#ifndef __OSAL_H__ +#define __OSAL_H__ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <hal_types.h> +#ifdef __ICCARM__ +#include <intrinsics.h> +#endif + +/****************************************************************************** + * Macros + *****************************************************************************/ + + +/****************************************************************************** + * Function Prototypes + *****************************************************************************/ + +/** + * This function copies size number of bytes from a + * memory location pointed by src to a destination + * memory location pointed by dest + * + * @param[in] dest Destination address + * @param[in] src Source address + * @param[in] size size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemCpy(void *dest,const void *src, unsigned int size); + + +/** + * This function sets first number of bytes, specified + * by size, to the destination memory pointed by ptr + * to the specified value + * + * @param[in] ptr Destination address + * @param[in] value Value to be set + * @param[in] size Size in the bytes + * + * @return Address of the destination + */ + +extern void* Osal_MemSet(void *ptr, int value, unsigned int size); + +/** + * Osal_Get_Cur_Time + * + * returns the current time in milliseconds + */ +/** + * Returns the number of ticks (1 tick = 1 millisecond) + * + * @return Time in milliseconds + */ +uint32_t Osal_Get_Cur_Time(void); + + +#endif /* __OSAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/bluenrg-hci/sm.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,158 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : sm.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Header file for BlueNRG's security manager. +******************************************************************************** +* 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. +*******************************************************************************/ + +#ifndef __SM_H__ +#define __SM_H__ + +/****************************************************************************** +* Macros +*****************************************************************************/ + +/** + *@addtogroup GAP GAP + *@brief API for GAP layer. + *@{ + */ + +/* IO capabilities */ +/** + * @anchor IO_capabilities + * @name IO capabilities + * @{ + */ +#define IO_CAP_DISPLAY_ONLY (0x00) +#define IO_CAP_DISPLAY_YES_NO (0x01) +#define IO_CAP_KEYBOARD_ONLY (0x02) +#define IO_CAP_NO_INPUT_NO_OUTPUT (0x03) +#define IO_CAP_KEYBOARD_DISPLAY (0x04) +/** + * @} + */ + +/** + * @anchor Auth_req + * @name Authentication requirements + * @{ + */ +#define BONDING (0x01) +#define NO_BONDING (0x00) +/** + * @} + */ + +/** + * @anchor MITM_req + * @name MITM protection requirements + * @{ + */ +#define MITM_PROTECTION_NOT_REQUIRED (0x00) +#define MITM_PROTECTION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor OOB_Data + * @name Out-Of-Band data + * @{ + */ +#define OOB_AUTH_DATA_ABSENT (0x00) +#define OOB_AUTH_DATA_PRESENT (0x01) +/** + * @} + */ + +/** + * @anchor Author_req + * @name Authorization requirements + * @{ + */ +#define AUTHORIZATION_NOT_REQUIRED (0x00) +#define AUTHORIZATION_REQUIRED (0x01) +/** + * @} + */ + +/** + * @anchor Conn_authorization + * @name Connection authorization + * @{ + */ +#define CONNECTION_AUTHORIZED (0x01) +#define CONNECTION_REJECTED (0x02) +/** + * @} + */ + +/** + * @anchor Use_fixed_pin + * @name Use fixed pin + * @{ + */ +#define USE_FIXED_PIN_FOR_PAIRING (0x0) +#define DONOT_USE_FIXED_PIN_FOR_PAIRING (0x01) +/** + * @} + */ + +/** + * @anchor link_security_status + * @name Link security status + * @{ + */ +#define SM_LINK_AUTHENTICATED (0x01) +#define SM_LINK_AUTHORIZED (0x02) +#define SM_LINK_ENCRYPTED (0x04) +/** + * @} + */ + +/** + * @anchor SMP_pairing_failed_codes + * @name SMP pairing failed reason codes + * @{ + */ +#define PASSKEY_ENTRY_FAILED (0x01) +#define OOB_NOT_AVAILABLE (0x02) +#define AUTH_REQ_CANNOT_BE_MET (0x03) +#define CONFIRM_VALUE_FAILED (0x04) +#define PAIRING_NOT_SUPPORTED (0x05) +#define INSUFF_ENCRYPTION_KEY_SIZE (0x06) +#define CMD_NOT_SUPPORTED (0x07) +#define UNSPECIFIED_REASON (0x08) +#define VERY_EARLY_NEXT_ATTEMPT (0x09) +#define SM_INVALID_PARAMS (0x0A) +/** + * @} + */ + +/** + * @anchor pairing_failed_codes + * @name Pairing failed error codes + * Error codes in @ref EVT_BLUE_GAP_PAIRING_CMPLT event + * @{ + */ +#define SM_PAIRING_SUCCESS (0x00) +#define SM_PAIRING_TIMEOUT (0x01) +#define SM_PAIRING_FAILED (0x02) +/** + * @} + */ + +/** + * @} + */ + +#endif /* __SM_H__ */
--- a/x-nucleo-idb0xa1/platform/X-NUCLEO-IDB04A1/stm32_bluenrg_ble.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,104 +0,0 @@ -/** - ****************************************************************************** - * @file stm32_bluenrg_ble.h - * @author CL - * @version V1.0.1 - * @date 15-June-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_H -#define __STM32_BLUENRG_BLE_H - -#ifdef __cplusplus - extern "C" { -#endif - - -#include <stdint.h> -#include "gp_timer.h" -#include "hal.h" - -/** @addtogroup BSP - * @{ - */ - -/** @addtogroup X-NUCLEO-IDB04A1 - * @{ - */ - -/** @addtogroup STM32_BLUENRG_BLE - * @{ - */ - -/** @defgroup STM32_BLUENRG_BLE_Exported_Functions - * @{ - */ - -// FIXME: add prototypes for BlueNRG here -void BlueNRG_RST(void); -uint8_t BlueNRG_DataPresent(void); -void BlueNRG_HW_Bootloader(void); -int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, - uint8_t buff_size); -int32_t BlueNRG_SPI_Write(uint8_t* data1, - uint8_t* data2, - uint8_t Nb_bytes1, - uint8_t Nb_bytes2); -void Clear_SPI_EXTI_Flag(void); - -void print_csv_time(void); - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32_BLUENRG_BLE_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -
--- a/x-nucleo-idb0xa1/platform/X-NUCLEO-IDB04A1/stm32_bluenrg_ble_dma_lp.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +0,0 @@ -/** - ****************************************************************************** - * @file stm32_bluenrg_ble_dma_lp.h - * @author CL - * @version V1.0.0 - * @date 04-July-2014 - * @brief - ****************************************************************************** - * @attention - * - * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32_BLUENRG_BLE_DMA_LP_H -#define __STM32_BLUENRG_BLE_DMA_LP_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#ifdef USE_STM32F4XX_NUCLEO - #include "stm32f4xx_hal.h" - #include "stm32f4xx_nucleo.h" - #include "stm32f4xx_nucleo_bluenrg_dma_lp.h" - #include "stm32f4xx_hal_bluenrg_gpio.h" - #include "stm32f4xx_hal_bluenrg_spi.h" - #include "stm32f4xx_hal_bluenrg_dma.h" -#endif /* USE_STM32F4XX_NUCLEO */ - -#ifdef USE_STM32L0XX_NUCLEO - #include "stm32l0xx_hal.h" - #include "stm32l0xx_nucleo.h" - #include "stm32l0xx_nucleo_bluenrg_dma_lp.h" - #include "stm32l0xx_hal_bluenrg_gpio.h" - #include "stm32l0xx_hal_bluenrg_spi.h" - #include "stm32l0xx_hal_bluenrg_dma.h" -#endif /* USE_STM32L0XX_NUCLEO */ - -#include "stm32xx_lpm.h" -#include "stm32xx_timerserver.h" - -/** @addtogroup BSP - * @{ - */ - -/** @addtogroup X-NUCLEO-IDB04A1 - * @{ - */ - -/** @addtogroup STM32_BLUENRG_BLE_DMA_LP - * @{ - */ - -/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Exported_Constants - * @{ - */ - -#define SPI_END_RECEIVE_FIX 1 /**< Need some delay after receiving an event to prevent dummy read */ - - /** - * All timeout below are given in term of Ticks of the TimerServer. - * The tick of the timerserver depends on the LPO clock used as input and the - * prescaler of the wakeup timer. - * In order to get the most efficient implementation, the wakeuptimer prescaler should divide - * the input clock by 2 - * - * The values below are based on the LSI clock @37Kz. - * For this, the tick is 54us - */ -#define SPI_FIX_TIMEOUT 2 /**< 150 us - Note: 2 ticks result into more than 2*54us due to some inaccuracies and latencies */ -#define SPI_TX_TIMEOUT 3 /**< Value to be tuned to prevent trying to send a command to BlueNRG if it is not yet woken up */ -#define SPI_END_RECEIVE_FIX_TIMEOUT 2 -#define BLUENRG_HOLD_TIME_IN_RESET 1 -#define BLUENRG_HOLD_TIME_AFTER_RESET 93 /**< 5ms */ - -/** - * When the SPI does not have any FIFO (STM32L0, etc...), this parameter should be set to 1 - * When the SPI does have a FIFO, this parameter shall be set to the size of the FIFO in bytes (STM32L4 = 4) - */ -#define SPI_FIFO_RX_DEPTH 1 - -/** - * @} - */ - -/** @defgroup STM32_BLUENRG_BLE_DMA_LP_Exported_Functions - * @{ - */ -// FIXME: add prototypes for BlueNRG here -void BNRG_SPI_Close(void); -void BNRG_SPI_Init(void); -void BlueNRG_RST(void); -void BlueNRG_SPI_Write(uint8_t* header_data, - uint8_t* payload_data, - uint8_t header_size, - uint8_t payload_size); -void BlueNRG_SPI_Request_Events(uint8_t *buffer, uint8_t buff_size); -void BlueNRG_DMA_RxCallback(void); -void BlueNRG_DMA_TxCallback(void); -void BlueNRG_SPI_IRQ_Callback(void); -void BNRG_MSP_SPI_Init(SPI_HandleTypeDef * hspi); - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32_BLUENRG_BLE_DMA_LP_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/platform/btle.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,50 @@ +/* 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 _BTLE_H_ +#define _BTLE_H_ + + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> +#include <string.h> + +#include "hci.h" +#include "bluenrg_aci.h" +#include "hci_const.h" +#include "bluenrg_hal_aci.h" +#include "stm32_bluenrg_ble.h" +#include "bluenrg_gap.h" +#include "bluenrg_gatt_server.h" + +extern uint16_t g_gap_service_handle; +extern uint16_t g_appearance_char_handle; +extern uint16_t g_device_name_char_handle; + +void btle_init(bool isSetAddress, uint8_t role); +void SPI_Poll(void); +void User_Process(void); +void setConnectable(void); + +#ifdef __cplusplus +} +#endif + +#endif
--- a/x-nucleo-idb0xa1/platform/inc/btle.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* 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 _BTLE_H_ -#define _BTLE_H_ - - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdio.h> -#include <string.h> - -#include "hci.h" -#include "bluenrg_aci.h" -#include "hci_const.h" -#include "bluenrg_hal_aci.h" -#include "stm32_bluenrg_ble.h" -#include "bluenrg_gap.h" -#include "bluenrg_gatt_server.h" - -extern uint16_t g_gap_service_handle; -extern uint16_t g_appearance_char_handle; -extern uint16_t g_device_name_char_handle; - -void btle_init(bool isSetAddress); -void SPI_Poll(void); -void User_Process(void); -void setConnectable(void); - -#ifdef __cplusplus -} -#endif - -#endif
--- a/x-nucleo-idb0xa1/platform/inc/debug_platform.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -/****************************************************************************** - * Includes - *****************************************************************************/ -#include <string.h> - -//#define DEBUG - -#ifdef DEBUG -#include <stdio.h> -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/platform/stm32_bluenrg_ble.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,104 @@ +/** + ****************************************************************************** + * @file stm32_bluenrg_ble.h + * @author CL + * @version V1.0.1 + * @date 15-June-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_H +#define __STM32_BLUENRG_BLE_H + +#ifdef __cplusplus + extern "C" { +#endif + + +#include <stdint.h> +#include "gp_timer.h" +#include "hal.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup X-NUCLEO-IDB04A1 + * @{ + */ + +/** @addtogroup STM32_BLUENRG_BLE + * @{ + */ + +/** @defgroup STM32_BLUENRG_BLE_Exported_Functions + * @{ + */ + +// FIXME: add prototypes for BlueNRG here +void BlueNRG_RST(void); +uint8_t BlueNRG_DataPresent(void); +void BlueNRG_HW_Bootloader(void); +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, + uint8_t buff_size); +int32_t BlueNRG_SPI_Write(uint8_t* data1, + uint8_t* data2, + uint8_t Nb_bytes1, + uint8_t Nb_bytes2); +void Clear_SPI_EXTI_Flag(void); + +void print_csv_time(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32_BLUENRG_BLE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/platform/stm32_bluenrg_ble_dma_lp.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,152 @@ +/** + ****************************************************************************** + * @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****/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/utils/Payload.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,185 @@ +/* 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 "mbed.h" + +#ifndef __PAYLOAD_H__ +#define __PAYLOAD_H__ + +class UnitPayload +{ +public: + uint8_t length; + uint8_t id; + uint8_t *data; + uint8_t *idptr; + + + + void set_length(uint8_t l) { + length=l; + } + + void set_id(uint8_t i) { + id=i; + } + + void set_data(uint8_t* data1) { + for(int j=0;j<length;j++) + { + data[j]=data1[j]; + } + } + + uint8_t get_length() { + return length; + } + + uint8_t get_id() { + return id; + } + + uint8_t* get_data() { + return data; + } + +}; + +class Payload { + UnitPayload *payload; + int stringLength; + int payloadUnitCount; + +public: + Payload(const uint8_t *tokenString, uint8_t string_ength); + Payload(); + uint8_t getPayloadUnitCount(); + + uint8_t getIDAtIndex(int index); + uint8_t getLengthAtIndex(int index); + uint8_t* getDataAtIndex(int index); + int8_t getInt8AtIndex(int index); + uint16_t getUint16AtIndex(int index); + uint8_t* getSerializedAdDataAtIndex(int index); +}; + + +class PayloadUnit { +private: + uint8_t* lenPtr; + uint8_t* adTypePtr; + uint8_t* dataPtr; + +public: + PayloadUnit() { + lenPtr = NULL; + adTypePtr = NULL; + dataPtr = NULL; + } + + PayloadUnit(uint8_t *len, uint8_t *adType, uint8_t* data) { + lenPtr = len; + adTypePtr = adType; + dataPtr = data; + } + + void setLenPtr(uint8_t *len) { + lenPtr = len; + } + + void setAdTypePtr(uint8_t *adType) { + adTypePtr = adType; + } + + void setDataPtr(uint8_t *data) { + dataPtr = data; + } + + uint8_t* getLenPtr() { + return lenPtr; + } + + uint8_t* getAdTypePtr() { + return adTypePtr; + } + + uint8_t* getDataPtr() { + return dataPtr; + } + + void printDataAsHex() { + int i = 0; + printf("AdData="); + for(i=0; i<*lenPtr-1; i++) { + printf("0x%x ", dataPtr[i]); + } + printf("\n"); + } + + void printDataAsString() { + int i = 0; + printf("AdData="); + for(i=0; i<*lenPtr; i++) { + printf("%c", dataPtr[i]); + } + printf("\n"); + } + +}; + +class PayloadPtr { +private: + PayloadUnit *unit; + int payloadUnitCount; +public: + PayloadPtr(const uint8_t *tokenString, uint8_t string_ength) { + // initialize private data members + int stringLength = string_ength; + payloadUnitCount = 0; + + int index = 0; + while(index!=stringLength) { + int len=tokenString[index]; + index=index+1+len; + payloadUnitCount++; + } + + // allocate memory to unit + unit = new PayloadUnit[payloadUnitCount]; + int i = 0; + int nextUnitOffset = 0; + + while(i<payloadUnitCount) { + unit[i].setLenPtr((uint8_t *)tokenString+nextUnitOffset); + unit[i].setAdTypePtr((uint8_t *)tokenString+nextUnitOffset+1); + unit[i].setDataPtr((uint8_t *)tokenString+nextUnitOffset+2); + + nextUnitOffset += *unit[i].getLenPtr()+1; + i++; + + } + } + + PayloadUnit getUnitAtIndex(int index) { + return unit[index]; + } + + int getPayloadUnitCount() { return payloadUnitCount; } + + +}; + +#endif // __PAYLOAD_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/x-nucleo-idb0xa1/utils/Utils.h Wed Oct 07 08:39:04 2015 +0200 @@ -0,0 +1,46 @@ +/* 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. +*/ + + +// utility functions + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include "hal_types.h" +#include "mbed.h" + +#define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) ) + +#define STORE_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ + ((buf)[1] = (uint8_t) (val>>8) ) , \ + ((buf)[2] = (uint8_t) (val>>16) ) , \ + ((buf)[3] = (uint8_t) (val>>24) ) ) + +#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \ + do {\ + uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \ + uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \ + uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \ + uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \ + }while(0) + + +double getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL); + +#endif // __UTIL_H__ +
--- a/x-nucleo-idb0xa1/utils/inc/Payload.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,185 +0,0 @@ -/* 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 "mbed.h" - -#ifndef __PAYLOAD_H__ -#define __PAYLOAD_H__ - -class UnitPayload -{ -public: - uint8_t length; - uint8_t id; - uint8_t *data; - uint8_t *idptr; - - - - void set_length(uint8_t l) { - length=l; - } - - void set_id(uint8_t i) { - id=i; - } - - void set_data(uint8_t* data1) { - for(int j=0;j<length;j++) - { - data[j]=data1[j]; - } - } - - uint8_t get_length() { - return length; - } - - uint8_t get_id() { - return id; - } - - uint8_t* get_data() { - return data; - } - -}; - -class Payload { - UnitPayload *payload; - int stringLength; - int payloadUnitCount; - -public: - Payload(const uint8_t *tokenString, uint8_t string_ength); - Payload(); - uint8_t getPayloadUnitCount(); - - uint8_t getIDAtIndex(int index); - uint8_t getLengthAtIndex(int index); - uint8_t* getDataAtIndex(int index); - int8_t getInt8AtIndex(int index); - uint16_t getUint16AtIndex(int index); - uint8_t* getSerializedAdDataAtIndex(int index); -}; - - -class PayloadUnit { -private: - uint8_t* lenPtr; - uint8_t* adTypePtr; - uint8_t* dataPtr; - -public: - PayloadUnit() { - lenPtr = NULL; - adTypePtr = NULL; - dataPtr = NULL; - } - - PayloadUnit(uint8_t *len, uint8_t *adType, uint8_t* data) { - lenPtr = len; - adTypePtr = adType; - dataPtr = data; - } - - void setLenPtr(uint8_t *len) { - lenPtr = len; - } - - void setAdTypePtr(uint8_t *adType) { - adTypePtr = adType; - } - - void setDataPtr(uint8_t *data) { - dataPtr = data; - } - - uint8_t* getLenPtr() { - return lenPtr; - } - - uint8_t* getAdTypePtr() { - return adTypePtr; - } - - uint8_t* getDataPtr() { - return dataPtr; - } - - void printDataAsHex() { - int i = 0; - printf("AdData="); - for(i=0; i<*lenPtr-1; i++) { - printf("0x%x ", dataPtr[i]); - } - printf("\n"); - } - - void printDataAsString() { - int i = 0; - printf("AdData="); - for(i=0; i<*lenPtr; i++) { - printf("%c", dataPtr[i]); - } - printf("\n"); - } - -}; - -class PayloadPtr { -private: - PayloadUnit *unit; - int payloadUnitCount; -public: - PayloadPtr(const uint8_t *tokenString, uint8_t string_ength) { - // initialize private data members - int stringLength = string_ength; - payloadUnitCount = 0; - - int index = 0; - while(index!=stringLength) { - int len=tokenString[index]; - index=index+1+len; - payloadUnitCount++; - } - - // allocate memory to unit - unit = new PayloadUnit[payloadUnitCount]; - int i = 0; - int nextUnitOffset = 0; - - while(i<payloadUnitCount) { - unit[i].setLenPtr((uint8_t *)tokenString+nextUnitOffset); - unit[i].setAdTypePtr((uint8_t *)tokenString+nextUnitOffset+1); - unit[i].setDataPtr((uint8_t *)tokenString+nextUnitOffset+2); - - nextUnitOffset += *unit[i].getLenPtr()+1; - i++; - - } - } - - PayloadUnit getUnitAtIndex(int index) { - return unit[index]; - } - - int getPayloadUnitCount() { return payloadUnitCount; } - - -}; - -#endif // __PAYLOAD_H__
--- a/x-nucleo-idb0xa1/utils/inc/Utils.h Tue Oct 06 15:19:19 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,57 +0,0 @@ -/* 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. -*/ - - -// utility functions - -#ifndef __UTIL_H__ -#define __UTIL_H__ - -#include "hal_types.h" -#include "mbed.h" - -#define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console; */ - /*it will have an impact on code-size and power consumption. */ - -#if NEED_CONSOLE_OUTPUT -//Serial usb(USBTX, USBRX); // tx, rx -extern Serial pc; -#define DEBUG(...) { pc.printf(__VA_ARGS__); } -#else -#define DEBUG(...) /* nothing */ -#endif /* #if NEED_CONSOLE_OUTPUT */ - -#define STORE_LE_16(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ - ((buf)[1] = (uint8_t) (val>>8) ) ) - -#define STORE_LE_32(buf, val) ( ((buf)[0] = (uint8_t) (val) ) , \ - ((buf)[1] = (uint8_t) (val>>8) ) , \ - ((buf)[2] = (uint8_t) (val>>16) ) , \ - ((buf)[3] = (uint8_t) (val>>24) ) ) - -#define COPY_UUID_128(uuid_struct, uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7, uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0) \ - do {\ - uuid_struct[0] = uuid_0; uuid_struct[1] = uuid_1; uuid_struct[2] = uuid_2; uuid_struct[3] = uuid_3; \ - uuid_struct[4] = uuid_4; uuid_struct[5] = uuid_5; uuid_struct[6] = uuid_6; uuid_struct[7] = uuid_7; \ - uuid_struct[8] = uuid_8; uuid_struct[9] = uuid_9; uuid_struct[10] = uuid_10; uuid_struct[11] = uuid_11; \ - uuid_struct[12] = uuid_12; uuid_struct[13] = uuid_13; uuid_struct[14] = uuid_14; uuid_struct[15] = uuid_15; \ - }while(0) - - -double getHighPowerAndPALevelValue(int8_t dBMLevel, int8_t& EN_HIGH_POWER, int8_t& PA_LEVEL); - -#endif // __UTIL_H__ -