BLE_BlueNRG for Nucleo board
Dependents: Nucleo_BLE_HeartRate Nucleo_BLE_UART Nucleo_BLE_UART
Warning: Deprecated!
Supported drivers and applications can be found at this link.
Revision 0:a948f5f3904c, committed 2014-12-19
- Comitter:
- sjallouli
- Date:
- Fri Dec 19 18:56:07 2014 +0000
- Child:
- 1:be1cb4be316f
- Commit message:
- BLE_BlueNRG for Nucleo board
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BlueNRGDevice.cpp Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,232 @@ +/* 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" +#include "BlueNRGDevice.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" + +#include "btle.h" +#include "Utils.h" +#include "osal.h" + +/** +* The singleton which represents the BlueNRG transport for the BLEDevice. +*/ +static BlueNRGDevice deviceInstance; + +/** +* BLE-API requires an implementation of the following function in order to +* obtain its transport handle. +*/ +BLEDeviceInstanceBase * +createBLEDeviceInstance(void) +{ + return (&deviceInstance); +} + +/**************************************************************************/ +/*! + @brief Constructor +*/ +/**************************************************************************/ +BlueNRGDevice::BlueNRGDevice(void) +{ + isInitialized = false; +} + +/**************************************************************************/ +/*! + @brief Destructor +*/ +/**************************************************************************/ +BlueNRGDevice::~BlueNRGDevice(void) +{ +} + +/**************************************************************************/ +/*! + @brief Initialises anything required to start using BLE + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGDevice::init(void) +{ + /* ToDo: Clear memory contents, reset the SD, etc. */ + btle_init(BlueNRGGap::getInstance().getIsSetAddress()); + + isInitialized = true; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Resets the BLE HW, removing any existing services and + characteristics + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGDevice::reset(void) +{ + wait(0.5); + + /* Reset BlueNRG SPI interface */ + BlueNRG_RST(); + + /* Wait for the radio to come back up */ + wait(1); + + isInitialized = false; + + return BLE_ERROR_NONE; +} + +void BlueNRGDevice::waitForEvent(void) +{ + HCI_Process();//Send App Events?? + +} + + +/**************************************************************************/ +/*! + @brief get GAP version + + @returns char * + + @retval pointer to version string + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +const char *BlueNRGDevice::getVersion(void) +{ + char *version = new char[6]; + memcpy((void *)version, "1.0.0", 5); + return version; +} + +/**************************************************************************/ +/*! + @brief get init state + + @returns bool + + @retval + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +bool BlueNRGDevice::getIsInitialized(void) +{ + return isInitialized; +} + +/**************************************************************************/ +/*! + @brief get reference to GAP object + + @returns Gap& + + @retval reference to gap object + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +Gap &BlueNRGDevice::getGap() +{ + return BlueNRGGap::getInstance(); +} + +/**************************************************************************/ +/*! + @brief get reference to GATT server object + + @returns GattServer& + + @retval reference to GATT server object + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +GattServer &BlueNRGDevice::getGattServer() +{ + return BlueNRGGattServer::getInstance(); +} + +/**************************************************************************/ +/*! + @brief set Tx power level + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGDevice::setTxPower(int8_t txPower) +{ + int8_t enHighPower = 0; + int8_t paLevel = 0; + int8_t dbmActuallySet = getHighPowerAndPALevelValue(txPower, enHighPower, paLevel); + DEBUG("txPower=%d, dbmActuallySet=%d\n\r", txPower, dbmActuallySet); + DEBUG("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); + aci_hal_set_tx_power_level(enHighPower, paLevel); + return BLE_ERROR_NONE; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BlueNRGDevice.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,53 @@ +/* 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_H__ +#define __BLUENRG_H__ + +#define BLUENRG +#define DEBUG_BLUENRG_USER + +#include "btle.h" + +#include "mbed.h" +#include "blecommon.h" +#include "BLEDevice.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" + + +class BlueNRGDevice : public BLEDeviceInstanceBase +{ + +public: + BlueNRGDevice(void); + virtual ~BlueNRGDevice(void); + + virtual Gap &getGap(); + virtual GattServer &getGattServer(); + virtual const char *getVersion(void); + virtual ble_error_t init(void); + virtual ble_error_t reset(void); + virtual ble_error_t setTxPower(int8_t txPower); + virtual void waitForEvent(void); + + bool getIsInitialized(void); + +private: + bool isInitialized; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BlueNRGGap.cpp Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,680 @@ +/* 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 "BlueNRGDevice.h" +#include "mbed.h" +#include "Payload.h" +#include "Utils.h" + +//Local Variables +const char *local_name = NULL; +uint8_t local_name_length = 0; +const uint8_t *scan_response_payload = NULL; +uint8_t scan_rsp_length = 0; +uint8_t servUuidlength = 0; +uint8_t* servUuidData = NULL; + +uint32_t advtInterval = 0; + +/**************************************************************************/ +/*! + @brief Sets the advertising parameters and payload for the device. + Note: Some data types give error when their adv data is updated using aci_gap_update_adv_data() API + + @param[in] params + Basic advertising details, including the advertising + delay, timeout and how the device should be advertised + @params[in] advData + The primary advertising data payload + @params[in] scanResponse + The optional Scan Response payload if the advertising + type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED + in \ref GapAdveritinngParams + + @returns \ref ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @retval BLE_ERROR_BUFFER_OVERFLOW + The proposed action would cause a buffer overflow. All + advertising payloads must be <= 31 bytes, for example. + + @retval BLE_ERROR_NOT_IMPLEMENTED + A feature was requested that is not yet supported in the + nRF51 firmware or hardware. + + @retval BLE_ERROR_PARAM_OUT_OF_RANGE + One of the proposed values is outside the valid range. + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) +{ + DEBUG("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; + } + + /* Make sure we have a payload! */ + if (advData.getPayloadLen() <= 0) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } else { + PayloadPtr loadPtr(advData.getPayload(), advData.getPayloadLen()); + for(uint8_t index=0; index<loadPtr.getPayloadUnitCount(); index++) { + PayloadUnit unit = 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())); + + switch(*loadPtr.getUnitAtIndex(index).getAdTypePtr()) { + case GapAdvertisingData::FLAGS: /* ref *Flags */ + { + //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"); + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + break; + } + case GapAdvertisingData::INCOMPLETE_LIST_16BIT_SERVICE_IDS: /**< Incomplete list of 16-bit Service IDs */ + { + break; + } + case GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS: /**< Complete list of 16-bit Service IDs */ + { + DEBUG("Advertising type: COMPLETE_LIST_16BIT_SERVICE_IDS\n\r"); + DEBUG("Advertising type: COMPLETE_LIST_16BIT_SERVICE_IDS\n"); + #if 0 + int err = aci_gap_update_adv_data(*loadPtr.getUnitAtIndex(index).getLenPtr(), loadPtr.getUnitAtIndex(index).getAdTypePtr()); + if(BLE_STATUS_SUCCESS!=err) { + DEBUG("error occurred while adding adv data\n"); + return BLE_ERROR_PARAM_OUT_OF_RANGE; // no other suitable error code is available + } + #endif + break; + } + case GapAdvertisingData::INCOMPLETE_LIST_32BIT_SERVICE_IDS: /**< Incomplete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */ + { + break; + } + case GapAdvertisingData::COMPLETE_LIST_32BIT_SERVICE_IDS: /**< Complete list of 32-bit Service IDs (not relevant for Bluetooth 4.0) */ + { + break; + } + case GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS: /**< Incomplete list of 128-bit Service IDs */ + { + break; + } + case GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS: /**< Complete list of 128-bit Service IDs */ + { + break; + } + case GapAdvertisingData::SHORTENED_LOCAL_NAME: /**< Shortened Local Name */ + { + break; + } + case GapAdvertisingData::COMPLETE_LOCAL_NAME: /**< Complete Local Name */ + { + DEBUG("Advertising type: COMPLETE_LOCAL_NAME\n\r"); + loadPtr.getUnitAtIndex(index).printDataAsString(); + local_name_length = *loadPtr.getUnitAtIndex(index).getLenPtr()-1; + local_name = (const char*)loadPtr.getUnitAtIndex(index).getAdTypePtr(); + //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); + break; + } + case GapAdvertisingData::TX_POWER_LEVEL: /**< TX Power Level (in dBm) */ + { + DEBUG("Advertising type: TX_POWER_LEVEL\n\r"); + int8_t dbm = *loadPtr.getUnitAtIndex(index).getDataPtr(); + int8_t enHighPower = 0; + int8_t paLevel = 0; + int8_t dbmActuallySet = getHighPowerAndPALevelValue(dbm, enHighPower, paLevel); + DEBUG("dbm=%d, dbmActuallySet=%d\n\r", dbm, dbmActuallySet); + DEBUG("enHighPower=%d, paLevel=%d\n\r", enHighPower, paLevel); + aci_hal_set_tx_power_level(enHighPower, paLevel); + break; + } + case GapAdvertisingData::DEVICE_ID: /**< Device ID */ + { + break; + } + case GapAdvertisingData::SLAVE_CONNECTION_INTERVAL_RANGE: /**< Slave :Connection Interval Range */ + { + break; + } + case GapAdvertisingData::SERVICE_DATA: /**< Service Data */ + { + break; + } + case GapAdvertisingData::APPEARANCE: + { + /* + Tested with GapAdvertisingData::GENERIC_PHONE. + for other appearances BLE Scanner android app is not behaving properly + */ + DEBUG("Advertising type: APPEARANCE\n\r"); + const char *deviceAppearance = NULL; + deviceAppearance = (const char*)loadPtr.getUnitAtIndex(index).getDataPtr(); // to be set later when startAdvertising() is called + + uint8_t Appearance[2]; + uint16_t devP = (uint16_t)*deviceAppearance; + STORE_LE_16(Appearance, (uint16_t)devP); + + 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 */ + + aci_gatt_update_char_value(g_gap_service_handle, g_appearance_char_handle, 0, 2, (tHalUint8 *)deviceAppearance);//not using array Appearance[2] + break; + } + case GapAdvertisingData::ADVERTISING_INTERVAL: /**< Advertising Interval */ + { + advtInterval = (uint16_t)(*loadPtr.getUnitAtIndex(index).getDataPtr()); + DEBUG("advtInterval=%d\n\r", advtInterval); + break; + } + case GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA: /**< Manufacturer Specific Data */ + { + break; + } + + } + } + //Set the SCAN_RSP Payload + scan_response_payload = scanResponse.getPayload(); + scan_rsp_length = scanResponse.getPayloadLen(); + } + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Starts the BLE HW, initialising any services that were + added before this function was called. + + @note All services must be added before calling this function! + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::startAdvertising(const GapAdvertisingParams ¶ms) +{ + /* Make sure we support the advertising type */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) { + /* ToDo: This requires a propery security implementation, etc. */ + return BLE_ERROR_NOT_IMPLEMENTED; + } + + /* Check interval range */ + if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) { + /* Min delay is slightly longer for unconnectable devices */ + if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) || + (params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } else { + if ((params.getInterval() < GAP_ADV_PARAMS_INTERVAL_MIN) || + (params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + } + + /* Check timeout is zero for Connectable Directed */ + if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) { + /* Timeout must be 0 with this type, although we'll never get here */ + /* since this isn't implemented yet anyway */ + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + /* Check timeout for other advertising types */ + if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && + (params.getTimeout() > GAP_ADV_PARAMS_TIMEOUT_MAX)) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + tBleStatus ret; + const LongUUIDBytes_t HRM_SERVICE_UUID_128 = {0x18, 0x0D}; + /* set scan response data */ + hci_le_set_scan_resp_data(scan_rsp_length, scan_response_payload); /*int hci_le_set_scan_resp_data(uint8_t length, const uint8_t data[]);*/ + + /*aci_gap_set_discoverable(Advertising_Event_Type, Adv_min_intvl, Adv_Max_Intvl, Addr_Type, Adv_Filter_Policy, + Local_Name_Length, local_name, service_uuid_length, service_uuid_list, Slave_conn_intvl_min, Slave_conn_intvl_max);*/ + /*LINK_LAYER.H DESCRIBES THE ADVERTISING TYPES*/ + + char* name = NULL; + uint8_t nameLen = 0; + if(local_name!=NULL) { + name = (char*)local_name; + DEBUG("name=%s\n\r", name); + nameLen = local_name_length; + } else { + char str[] = "ST_BLE_DEV"; + name = new char[strlen(str)+1]; + name[0] = AD_TYPE_COMPLETE_LOCAL_NAME; + strcpy(name+1, str); + nameLen = strlen(name); + DEBUG("nameLen=%d\n\r", nameLen); + DEBUG("name=%s\n\r", name); + } + + + advtInterval = params.getInterval(); // set advtInterval in case it is not already set by user application + ret = aci_gap_set_discoverable(params.getAdvertisingType(), // Advertising_Event_Type + 0, // Adv_Interval_Min + advtInterval, // Adv_Interval_Max + PUBLIC_ADDR, // Address_Type + NO_WHITE_LIST_USE, // Adv_Filter_Policy + nameLen, //local_name_length, // Local_Name_Length + (const char*)name, //local_name, // Local_Name + servUuidlength, //Service_Uuid_Length + servUuidData, //Service_Uuid_List + 0, // Slave_Conn_Interval_Min + 0); // Slave_Conn_Interval_Max + + state.advertising = 1; + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Stops the BLE HW and disconnects from any devices + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::stopAdvertising(void) +{ + tBleStatus ret; + + if(state.advertising == 1) { + //Set non-discoverable to stop advertising + ret = aci_gap_set_non_discoverable(); + + if (ret != BLE_STATUS_SUCCESS){ + DEBUG("Error in stopping advertisement!!\n\r") ; + 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") ; + //Set GapState_t::advertising state + state.advertising = 0; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Disconnects if we are connected to a central device + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::disconnect(Gap::DisconnectionReason_t reason) +{ + tBleStatus ret; + //For Reason codes check BlueTooth HCI Spec + + if(m_connectionHandle != BLE_CONN_HANDLE_INVALID) { + ret = aci_gap_terminate(m_connectionHandle, 0x16);//0x16 Connection Terminated by Local Host. + + if (ret != BLE_STATUS_SUCCESS){ + DEBUG("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") ; + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Sets the 16-bit connection handle +*/ +/**************************************************************************/ +void BlueNRGGap::setConnectionHandle(uint16_t con_handle) +{ + m_connectionHandle = con_handle; +} + +/**************************************************************************/ +/*! + @brief Gets the 16-bit connection handle +*/ +/**************************************************************************/ +uint16_t BlueNRGGap::getConnectionHandle(void) +{ + return m_connectionHandle; +} + +/**************************************************************************/ +/*! + @brief Sets the BLE device address. SetAddress will reset the BLE + device and re-initialize BTLE. Will not start advertising. + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAddress(addr_type_t type, const uint8_t address[6]) +{ + tBleStatus ret; + + if (type > ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) { + return BLE_ERROR_PARAM_OUT_OF_RANGE; + } + + //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]); + } + + if(!isSetAddress) isSetAddress = true; + + //Re-Init the BTLE Device with SetAddress as true + //if(BlueNRGDevice::getIsInitialized())//Re-init only initialization is already done + btle_init(isSetAddress); + + //if (ret==BLE_STATUS_SUCCESS) + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Returns boolean if the address of the device has been set + or not + + @returns bool + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +bool BlueNRGGap::getIsSetAddress() +{ + return isSetAddress; +} + +/**************************************************************************/ +/*! + @brief Returns the address of the device if set + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +tHalUint8* BlueNRGGap::getAddress() +{ + if(isSetAddress) + return bdaddr; + else return NULL; +} + +/**************************************************************************/ +/*! + @brief obtains preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getPreferredConnectionParams(ConnectionParams_t *params) +{ + return BLE_ERROR_NONE; +} + + +/**************************************************************************/ +/*! + @brief sets preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setPreferredConnectionParams(const ConnectionParams_t *params) +{ + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief updates preferred connection params + + @returns ble_error_t + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *params) +{ + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief sets device name characteristic + + @param[in] deviceName + pointer to device name to be set + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setDeviceName(const uint8_t *deviceName) +{ + int ret; + uint8_t nameLen = 0; + + DeviceName = (uint8_t *)deviceName; + //DEBUG("SetDeviceName=%s\n\r", DeviceName); + + nameLen = strlen((const char*)DeviceName); + //DEBUG("DeviceName Size=%d\n\r", nameLen); + + ret = aci_gatt_update_char_value(g_gap_service_handle, + g_device_name_char_handle, + 0, + nameLen, + (tHalUint8 *)DeviceName); + + if(ret){ + DEBUG("device set name failed\n\r"); + return BLE_ERROR_PARAM_OUT_OF_RANGE;//TODO:Wrong error code + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief gets device name characteristic + + @param[in] deviceName + pointer to device name + + + @param[in] lengthP + pointer to device name length + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP) +{ + int ret; + + if(DeviceName==NULL) + return BLE_ERROR_PARAM_OUT_OF_RANGE; + + strcpy((char*)deviceName, (const char*)DeviceName); + //DEBUG("GetDeviceName=%s\n\r", deviceName); + + *lengthP = strlen((const char*)DeviceName); + //DEBUG("DeviceName Size=%d\n\r", *lengthP); + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief sets device appearance characteristic + + @param[in] appearance + device appearance + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::setAppearance(uint16_t appearance) +{ + /* + Tested with GapAdvertisingData::GENERIC_PHONE. + for other appearances BLE Scanner android app is not behaving properly + */ + //char deviceAppearance[2]; + STORE_LE_16(deviceAppearance, appearance); + DEBUG("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, (tHalUint8 *)deviceAppearance); + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief gets device appearance + + @param[in] appearance + pointer to device appearance value + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGap::getAppearance(uint16_t *appearanceP) +{ + uint16_t devP; + if(!appearanceP) return BLE_ERROR_PARAM_OUT_OF_RANGE; + devP = ((uint16_t)(0x0000|deviceAppearance[0])) | (((uint16_t)(0x0000|deviceAppearance[1]))<<8); + strcpy((char*)appearanceP, (const char*)&devP); + + return BLE_ERROR_NONE; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BlueNRGGap.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,86 @@ +/* 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_GAP_H__ +#define __BLUENRG_GAP_H__ + +#include "mbed.h" +#include "blecommon.h" +#include "btle.h" +#include "GapAdvertisingParams.h" +#include "GapAdvertisingData.h" +#include <public/Gap.h> + +#define BLE_CONN_HANDLE_INVALID 0x0 +#define BDADDR_SIZE 6 + +/**************************************************************************/ +/*! + \brief + +*/ +/**************************************************************************/ +class BlueNRGGap : public Gap +{ +public: + static BlueNRGGap &getInstance() { + static BlueNRGGap m_instance; + return m_instance; + } + + /* Functions that must be implemented from Gap */ + virtual ble_error_t setAddress(addr_type_t type, + const uint8_t address[6]); + virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, + const GapAdvertisingData &); + virtual ble_error_t startAdvertising(const GapAdvertisingParams &); + virtual ble_error_t stopAdvertising(void); + virtual ble_error_t disconnect(DisconnectionReason_t reason); + virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params); + virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params); + virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params); + + virtual ble_error_t setDeviceName(const uint8_t *deviceName); + virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP); + virtual ble_error_t setAppearance(uint16_t appearance); + virtual ble_error_t getAppearance(uint16_t *appearanceP); + + + void setConnectionHandle(uint16_t con_handle); + uint16_t getConnectionHandle(void); + + tHalUint8* getAddress(); + bool getIsSetAddress(); + +private: + uint16_t m_connectionHandle; + tHalUint8 bdaddr[BDADDR_SIZE]; + bool isSetAddress; + tBleStatus ret; + uint8_t *DeviceName; + uint8_t deviceAppearance[2]; + + BlueNRGGap() { + m_connectionHandle = BLE_CONN_HANDLE_INVALID; + isSetAddress = false; + DeviceName = NULL; + } + + BlueNRGGap(BlueNRGGap const &); + void operator=(BlueNRGGap const &); +}; + +#endif // ifndef __BLUENRG_GAP_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BlueNRGGattServer.cpp Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,329 @@ +/* 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 "BlueNRGGattServer.h" +#include "mbed.h" +#include "BlueNRGGap.h" +#include "Utils.h" + +/**************************************************************************/ +/*! + @brief Adds a new service to the GATT table on the peripheral + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::addService(GattService &service) +{ + /* ToDo: Make sure we don't overflow the array, etc. */ + /* ToDo: Make sure this service UUID doesn't already exist (?) */ + /* ToDo: Basic validation */ + + tBleStatus ret; + uint8_t type; + uint16_t short_uuid; + uint8_t primary_short_uuid[2]; + uint8_t primary_base_uuid[16]; + uint8_t char_base_uuid[16]; + const uint8_t *base_uuid; + const uint8_t *base_char_uuid; + + type = (service.getUUID()).shortOrLong(); + DEBUG("AddService(): Type:%d\n\r", type); + + /* Add the service to the BlueNRG */ + short_uuid = (service.getUUID()).getShortUUID(); + STORE_LE_16(primary_short_uuid, short_uuid); + + if(type==UUID::UUID_TYPE_LONG) { + base_uuid = (service.getUUID()).getBaseUUID(); + + COPY_UUID_128(primary_base_uuid, base_uuid[15],base_uuid[14],base_uuid[13],base_uuid[12],base_uuid[11],base_uuid[10],base_uuid[9], + base_uuid[8],base_uuid[7],base_uuid[6],base_uuid[5],base_uuid[4],primary_short_uuid[1],primary_short_uuid[0],base_uuid[1],base_uuid[0]); + } + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_serv(UUID_TYPE_16, primary_short_uuid, PRIMARY_SERVICE, 7, + &servHandle); + } + else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_serv(UUID_TYPE_128, primary_base_uuid, PRIMARY_SERVICE, 7, + &servHandle); + } + + service.setHandle(servHandle); + //serviceHandleVector.push_back(servHandle); + DEBUG("added servHandle handle =%u\n\r", servHandle); + tHalUint16 bleCharacteristic; + + //iterate to include all characteristics + for (uint8_t i = 0; i < service.getCharacteristicCount(); i++) { + GattCharacteristic *p_char = service.getCharacteristic(i); + uint16_t char_uuid = (p_char->getValueAttribute().getUUID()).getShortUUID(); + + uint8_t int_8_uuid[2]; + STORE_LE_16(int_8_uuid, char_uuid); + + if(type==UUID::UUID_TYPE_LONG) { + base_char_uuid = (p_char->getValueAttribute().getUUID()).getBaseUUID(); + + COPY_UUID_128(char_base_uuid, base_char_uuid[15],base_char_uuid[14],base_char_uuid[13],base_char_uuid[12],base_char_uuid[11],base_char_uuid[10],base_char_uuid[9], + base_char_uuid[8],base_char_uuid[7],base_char_uuid[6],base_char_uuid[5],base_char_uuid[4],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()); + /* + * Gatt_Evt_Mask -> HardCoded (0) + * Encryption_Key_Size -> Hardcoded (16) + * isVariable (variable length value field) -> Hardcoded (1) + */ + tGattServerEvent Gatt_Evt_Mask = 0x0; + + if((p_char->getProperties() & + (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE))) { + DEBUG("Setting up Gatt GATT_SERVER_ATTR_WRITE Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_SERVER_ATTR_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_INTIMATE_APPL_WHEN_READ_N_WAIT Mask\n\r"); + Gatt_Evt_Mask = Gatt_Evt_Mask | GATT_INTIMATE_APPL_WHEN_READ_N_WAIT; + } //This will support also GATT_SERVER_ATTR_READ_WRITE since it will be covered by previous if() check. + + if(type==UUID::UUID_TYPE_SHORT) { + ret = aci_gatt_add_char(service.getHandle(), UUID_TYPE_16, int_8_uuid, p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), ATTR_PERMISSION_NONE, Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, 1 /*isVariable*/, &bleCharacteristic); + } + else if(type==UUID::UUID_TYPE_LONG) { + ret = aci_gatt_add_char(service.getHandle(), UUID_TYPE_128, char_base_uuid, p_char->getValueAttribute().getMaxLength() /*2*/ /*Value Length*/, + p_char->getProperties(), ATTR_PERMISSION_NONE, Gatt_Evt_Mask /*Gatt_Evt_Mask*/, + 16 /*Encryption_Key_Size*/, 1 /*isVariable*/, &bleCharacteristic); + } + /* Update the characteristic handle */ + uint16_t charHandle = characteristicCount; + + bleCharHanldeMap.insert(std::pair<tHalUint16, tHalUint16>(bleCharacteristic, servHandle)); + + 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); + + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getInitialLength() > 0)) { + updateValue(p_char->getValueAttribute().getHandle(), p_char->getValueAttribute().getValuePtr(), p_char->getValueAttribute().getInitialLength(), false /* localOnly */); + } + + // add descriptors now + uint16_t descHandle = 0; + for(uint8_t descIndex=0; descIndex<p_char->getDescriptorCount(); descIndex++) { + GattAttribute *descriptor = p_char->getDescriptor(descIndex); + uint16_t shortUUID = descriptor->getUUID().getShortUUID(); + const tHalUint8 uuidArray[] = {(shortUUID>>8)&0xFF, (shortUUID&0xFF)}; + ret = aci_gatt_add_char_desc(service.getHandle(), p_char->getValueAttribute().getHandle(), + CHAR_DESC_TYPE_16_BIT, uuidArray, descriptor->getMaxLength(), descriptor->getInitialLength(), + descriptor->getValuePtr(), CHAR_DESC_SECURITY_PERMISSION, CHAR_DESC_ACCESS_PERMISSION, GATT_SERVER_ATTR_READ_WRITE, + MIN_ENCRY_KEY_SIZE, CHAR_ATTRIBUTE_LEN_IS_FIXED, &descHandle); + if(ret==(tBleStatus)0) { + DEBUG("Descriptor added successfully, descriptor handle=%d\n\r", descHandle); + descriptor->setHandle(descHandle); + } + } + } + + serviceCount++; + + //FIXME: There is no GattService pointer array in GattServer. + // There should be one? (Only the user is aware of GattServices!) Report to forum. + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Reads the value of a characteristic, based on the service + and characteristic index fields + + @param[in] charHandle + The handle of the GattCharacteristic to read from + @param[in] buffer + Buffer to hold the the characteristic's value + (raw byte array in LSB format) + @param[in] len + The number of bytes read into the buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::readValue(uint16_t charHandle, uint8_t buffer[], uint16_t *const lengthP) +{ + DEBUG("ReadValue() Not Supported\n\r"); + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Updates the value of a characteristic, based on the service + and characteristic index fields + + @param[in] charHandle + The handle of the GattCharacteristic to write to + @param[in] buffer + Data to use when updating the characteristic's value + (raw byte array in LSB format) + @param[in] len + The number of bytes in buffer + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::updateValue(uint16_t charHandle, uint8_t buffer[], uint16_t len, bool localOnly) +{ + tBleStatus ret; + tHalUint8 buff[2]; + + DEBUG("updating bleCharacteristic charHandle =%u, corresponding serviceHanle= %u\n\r", charHandle, bleCharHanldeMap.find(charHandle)->second); + + ret = aci_gatt_update_char_value(bleCharHanldeMap.find(charHandle)->second, charHandle, 0, len, buffer); + + if (ret != BLE_STATUS_SUCCESS){ + DEBUG("Error while updating characteristic.\n\r") ; + return BLE_ERROR_PARAM_OUT_OF_RANGE ; //Not correct Error Value + //FIXME: Define Error values equivalent to BlueNRG Error Codes. + } + + //Generate Data Sent Event Here? (GattServerEvents::GATT_EVENT_DATA_SENT) //FIXME: Is this correct? + //Check if characteristic property is NOTIFY|INDICATE, if yes generate event + GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(charHandle); + if(p_char->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY + | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE)) { + BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_SENT, charHandle); + } + + return BLE_ERROR_NONE; +} + +/**************************************************************************/ +/*! + @brief Reads a value according to the handle provided + + @param[in] charHandle + The handle of the GattCharacteristic to read from + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +ble_error_t BlueNRGGattServer::Read_Request_CB(tHalUint16 handle) +{ + //signed short refvalue; + uint16_t gapConnectionHandle = BlueNRGGap::getInstance().getConnectionHandle(); + + //EXIT: + if(gapConnectionHandle != 0) + aci_gatt_allow_read(gapConnectionHandle); +} + +/**************************************************************************/ +/*! + @brief Returns the GattCharacteristic according to the handle provided + + @param[in] charHandle + The handle of the GattCharacteristic + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly + + @section EXAMPLE + + @code + + @endcode +*/ +/**************************************************************************/ +GattCharacteristic* BlueNRGGattServer::getCharacteristicFromHandle(tHalUint16 attrHandle) +{ + GattCharacteristic *p_char = NULL; + int i; + uint16_t handle; + + //DEBUG("BlueNRGGattServer::getCharacteristicFromHandle()>>Attribute Handle received 0x%x\n\r",attrHandle); + for(i=0; i<characteristicCount; i++) + { + handle = p_characteristics[i]->getValueAttribute().getHandle(); + + if(i==characteristicCount-1)//Last Characteristic check + { + if(attrHandle>=bleCharacteristicHandles[handle]) + { + p_char = p_characteristics[i]; + DEBUG("Found Characteristic Properties 0x%x\n\r",p_char->getProperties()); + break; + } + } + else { + //Testing if attribute handle is between two Characteristic Handles + if(attrHandle>=bleCharacteristicHandles[handle] && attrHandle<bleCharacteristicHandles[handle+1]) + { + p_char = p_characteristics[i]; + //DEBUG("Found Characteristic Properties 0x%x\n\r",p_char->getProperties()); + break; + } else continue; + } + } + + return p_char; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/BlueNRGGattServer.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,77 @@ +/* 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_GATT_SERVER_H__ +#define __BLUENRG_GATT_SERVER_H__ + +#include "mbed.h" +#include "blecommon.h" +#include "btle.h" +#include "GattService.h" +#include "public/GattServer.h" +#include <vector> +#include <map> + +#define BLE_TOTAL_CHARACTERISTICS 10 + + +using namespace std; + +class BlueNRGGattServer : public GattServer +{ +public: + static BlueNRGGattServer &getInstance() { + static BlueNRGGattServer m_instance; + return m_instance; + } + + /* Functions that must be implemented from GattServer */ + virtual ble_error_t addService(GattService &); + virtual ble_error_t readValue(uint16_t handle, uint8_t buffer[], uint16_t *const lengthP); + virtual ble_error_t updateValue(uint16_t, uint8_t[], uint16_t, bool localOnly = false); + + /* BlueNRG Functions */ + void eventCallback(void); + //void hwCallback(void *pckt); + ble_error_t Read_Request_CB(tHalUint16 handle); + GattCharacteristic* getCharacteristicFromHandle(tHalUint16 charHandle); + +private: + static const int MAX_SERVICE_COUNT = 10; + uint8_t serviceCount; + uint8_t characteristicCount; + tHalUint16 servHandle, charHandle; + + std::map<tHalUint16, tHalUint16> bleCharHanldeMap; // 1st argument is characteristic, 2nd argument is service + GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS]; + tHalUint16 bleCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS]; + + BlueNRGGattServer() { + serviceCount = 0; + characteristicCount = 0; + }; + + BlueNRGGattServer(BlueNRGGattServer const &); + void operator=(BlueNRGGattServer const &); + + static const int CHAR_DESC_TYPE_16_BIT=0x01; + static const int CHAR_DESC_TYPE_128_BIT=0x02; + static const int CHAR_DESC_SECURITY_PERMISSION=0x00; + static const int CHAR_DESC_ACCESS_PERMISSION=0x03; + static const int CHAR_ATTRIBUTE_LEN_IS_FIXED=0x00; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/btle/inc/btle.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,48 @@ +/* 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 "hci.h" +#include "bluenrg_hci.h" +#include "hci_internal.h" +#include "bluenrg_hci_internal.h" +#include "bluenrg_shield_bsp.h" +#include "bluenrg_gap.h" +#include "gatt_service.h" +#include <stdio.h> +#include <string.h> + + void btle_init(bool isSetAddress); + void SPI_Poll(void); + void User_Process(void); + void setConnectable(void); + + extern uint16_t g_gap_service_handle; + extern uint16_t g_appearance_char_handle; + extern uint16_t g_device_name_char_handle; + +#ifdef __cplusplus +} +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/btle/src/btle.cpp Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,302 @@ +/* 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 "btle.h" +#include "public/Gap.h" +#include "public/GapEvents.h" +#include "BlueNRGGap.h" +#include "BlueNRGGattServer.h" +#include "Utils.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/* C File Includes ------------------------------------------------------------------*/ +#include "hal_types.h" +#include "hci.h" +#include "bluenrg_hci.h" +#include "gp_timer.h" +#include "hal.h" +#include "osal.h" +#include "hci_internal.h" +#include "bluenrg_hci_internal.h" +#include "bluenrg_gap.h" +#include "sm.h" +#include <stdio.h> +#include <string.h> +#include "role_type.h" +#include "debug.h" + +#ifdef __cplusplus +} +#endif + + +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; + +/**************************************************************************/ +/*! + @brief Initialises BTLE and the underlying HW/Device + + @returns +*/ +/**************************************************************************/ +void btle_init(bool isSetAddress) +{ + DEBUG("btle_init>>\n\r"); + tHalUint8 *bleAddr; + int ret; + uint16_t service_handle, dev_name_char_handle, appearance_char_handle; + + //HAL_Init(); + + /* Configure the User Button in GPIO Mode */ + //BSP_PB_Init(BUTTON_KEY, BUTTON_MODE_GPIO); + + /* Configure the system clock */ + //SystemClock_Config(); + + /* 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 SPI driver */ + BNRG_SPI_Init(); + + /* Initialize the BlueNRG HCI */ + HCI_Init(); + + /* Reset BlueNRG SPI interface */ + BlueNRG_RST(); + + /* The Nucleo board must be configured as SERVER */ + //check if issetAddress is set than set address. + if(isSetAddress) + { + bleAddr = BlueNRGGap::getInstance().getAddress(); + + tHalUint8 bdaddr[BDADDR_SIZE]; + Osal_MemCpy(bdaddr, bleAddr, BDADDR_SIZE); + + ret = aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET, + CONFIG_DATA_PUBADDR_LEN, + bdaddr); + } + + ret = aci_gatt_init(); + //GAP is always in PERIPHERAL _ROLE as mbed does not support Master role at the moment + ret = aci_gap_init(GAP_PERIPHERAL_ROLE, &service_handle, &dev_name_char_handle, &appearance_char_handle); + + 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', '1', '2'}; + + /* disable scan response */ + hci_le_set_scan_resp_data(0,NULL); + + + ret = aci_gap_set_discoverable(ADV_IND, 0, 0, PUBLIC_ADDR, NO_WHITE_LIST_USE, + 8, local_name, 0, NULL, 0, 0); + +} + +/**************************************************************************/ +/*! + @brief + + @param[in] p_ble_evt + + @returns +*/ +/**************************************************************************/ +static void btle_handler() +{ + +} + + +void SPI_Poll(void) +{ + //HAL_GPIO_EXTI_Callback_Poll(BNRG_SPI_EXTI_PIN); + return; +} + +#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: + { + 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: + { + evt_le_meta_event *evt = (evt_le_meta_event *)event_pckt->data; + + switch(evt->subevent){ + case EVT_LE_CONN_COMPLETE: + { + evt_le_connection_complete *cc = (evt_le_connection_complete *)evt->data; + + BlueNRGGap::getInstance().setConnectionHandle(cc->handle); + BlueNRGGap::ConnectionParams_t connectionParams; + BlueNRGGap::getInstance().getPreferredConnectionParams(&connectionParams); + BlueNRGGap::getInstance().processConnectionEvent(cc->handle, (const BlueNRGGap::ConnectionParams_t *)&connectionParams); + } + break; + } + } + break; + + case EVT_VENDOR: + { + evt_blue_aci *blue_evt = (evt_blue_aci*)event_pckt->data; + 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); + } + break; + + case EVT_BLUE_GATT_ATTRIBUTE_MODIFIED: + { + /* this callback is invoked when a GATT attribute is modified + extract callback data and pass to suitable handler function */ + evt_gatt_attr_modified *evt = (evt_gatt_attr_modified*)blue_evt->data; + DEBUG("EVT_BLUE_GATT_ATTRIBUTE_MODIFIED\n\r"); + //DEBUG("CharHandle 0x%x, length: 0x%x, Data: 0x%x\n\r",evt->attr_handle, evt->data_length, (uint16_t)evt->att_data[0]); + DEBUG("CharHandle %d, length: %d, Data: %d\n\r",evt->attr_handle, evt->data_length, (uint16_t)evt->att_data[0]); + + //Extract the GattCharacteristic from p_characteristics[] and find the properties mask + GattCharacteristic *p_char = BlueNRGGattServer::getInstance().getCharacteristicFromHandle(evt->attr_handle); + if(p_char!=NULL) { + DEBUG("getProperties 0x%x\n\r",p_char->getProperties()); + if((p_char->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY + | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE))) { + + //Now Check if data written in Enable or Disable + if((uint16_t)evt->att_data[0]==1) { + //DEBUG("Notify ENABLED\n\r"); + BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_UPDATES_ENABLED, evt->attr_handle); + } + else { + //DEBUG("Notify DISABLED\n\r"); + BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_UPDATES_DISABLED, evt->attr_handle); + } + } + + //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))) { + + BlueNRGGattServer::getInstance().handleEvent(GattServerEvents::GATT_EVENT_DATA_WRITTEN, evt->attr_handle); + //Write the actual Data to the Attr Handle? (uint8_1[])evt->att_data contains the data + if ((p_char->getValueAttribute().getValuePtr() != NULL) && (p_char->getValueAttribute().getInitialLength() > 0)) { + BlueNRGGattServer::getInstance().updateValue(p_char->getValueAttribute().getHandle(), + p_char->getValueAttribute().getValuePtr(), p_char->getValueAttribute().getInitialLength(), false /* localOnly */); + } + } + } + } + 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 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hci/inc/ble_status.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,131 @@ +/******************** (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 tHalUint8 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) + + +/** + * Generic/System error codes + * starts with 0x40 + */ + +#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) + +/** + * flash error codes + * starts with 0x49 + */ +#define FLASH_READ_FAILED (0x49) +#define FLASH_WRITE_FAILED (0x4A) +#define FLASH_ERASE_FAILED (0x4B) + +/** + * L2CAP error codes + * starts with 0x50 + */ +#define BLE_STATUS_INVALID_CID (0x50) + +/* + * timer error codes + * starts with 0x54 + */ +#define TIMER_NOT_VALID_LAYER (0x54) +#define TIMER_INSUFFICIENT_RESOURCES (0x55) + +/** + * SM error codes + * starts with 0x5A + */ +#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) + + /** + * Gatt Error Codes + * starts with 0x60 + */ +#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) + +/** + * @} + */ + + +#endif /* __BLE_STATUS_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hci/inc/bluenrg_gap.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,124 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : 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 __GAP_HCI_H__ +#define __GAP_HCI_H__ + +#include <link_layer.h> + +/*----------------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) + +/*----------------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 ----------------*/ + +/* FLAGS AD type */ +#define AD_TYPE_FLAGS (0x01) +/* flag bits */ +#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)/* single device supports BR/EDR and LE controller */ +#define FLAG_BIT_LE_BR_EDR_HOST (0x10)/* single device supports BR/EDR and LE host */ + +/* 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 */ +#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) + +/* 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*/ +#define AD_TYPE_SERV_SOLICIT_16_BIT_UUID_LIST (0x14) +#define AD_TYPE_SERV_SOLICIT_32_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) + +/* privacy flag values */ +#define PRIVACY_ENABLED (0x01) +#define PRIVACY_DISABLED (0x00) + +/* conection 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*/ + +/* time out values */ +#define LIM_DISC_MODE_TIMEOUT (180000)/* 180 seconds. according to the errata published */ +#define PRIVATE_ADDR_INT_TIMEOUT (900000)/* 15 minutes */ + +typedef tHalUint8 tGapRole; +#define GAP_PERIPHERAL_ROLE (0x01) +#define GAP_BROADCASTER_ROLE (0x02) +#define GAP_CENTRAL_ROLE (0x03) +#define GAP_OBSERVER_ROLE (0x04) + +typedef tHalUint8 tGapMode; +#define GAP_NON_DISC_MODE (0x01) +#define GAP_LIM_DISC_MODE (0x02) +#define GAP_GEN_DISC_MODE (0x04) +#define GAP_NON_CONN_MODE (0x08) +#define GAP_DIRECT_CONN_MODE (0x10) +#define GAP_UNDIRECTED_CONN_MODE (0x20) + +/* SECURITY MANAGER OOB FLAGS */ +#define SM_OOB_FLAGS_FIELD (0x01) +#define SM_OOB_LE_SUPPORTED (0x02) +#define SM_OOB_SIMULTANEOUS_LE_BREDR (0x04) +#define SM_OOB_ADDR_TYPE (0x08) + + +#endif /* __GAP_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hci/inc/bluenrg_hci.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,143 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : Header 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. +*******************************************************************************/ + +#ifndef __BLUENRG_HCI_H__ +#define __BLUENRG_HCI_H__ + +#include "gatt_service.h" + +tBleStatus aci_gatt_init(void); +tBleStatus aci_gap_init(uint8_t role, + uint16_t* service_handle, + uint16_t* dev_name_char_handle, + uint16_t* appearance_char_handle); +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData); +tBleStatus aci_gap_set_non_discoverable(void); +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, const uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax); +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); +tBleStatus aci_gap_start_limited_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); +tBleStatus aci_gap_start_general_discovery_proc(uint16_t scanInterval, uint16_t scanWindow, + uint8_t own_address_type, uint8_t filterDuplicates); +tBleStatus aci_gap_start_auto_conn_establishment(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, + uint8_t *addr_array); +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); +tBleStatus aci_gap_terminate_gap_procedure(uint8_t procedure_code); +tBleStatus aci_gap_terminate(uint16_t conn_handle, uint8_t reason); +tBleStatus aci_gatt_add_serv(tHalUint8 service_uuid_type, + const tHalUint8* service_uuid, + tHalUint8 service_type, + tHalUint8 max_attr_records, + tHalUint16 *serviceHandle); +tBleStatus aci_gatt_add_char(tHalUint16 serviceHandle, + tUuidType charUuidType, + const tHalUint8* charUuid, + tHalUint16 charValueLen, + tHalUint8 charProperties, + tAttrSecurityFlags secPermissions, + tGattServerEvent gattEvtMask, + tHalUint8 encryKeySize, + tHalUint8 isVariable, + tHalUint16* charHandle); +tBleStatus aci_gatt_add_char_desc(tHalUint16 serviceHandle, + tHalUint16 charHandle, + tUuidType descUuidType, + const tHalUint8* uuid, + tHalUint8 descValueMaxLen, + tHalUint8 descValueLen, + const void* descValue, + tAttrSecurityFlags secPermissions, + tAttrSecurityFlags accPermissions, + tGattServerEvent gattEvtMask, + tHalUint8 encryKeySize, + tHalUint8 isVariable, + tHalUint16* descHandle); +tBleStatus aci_gatt_update_char_value(tHalUint16 servHandle, + tHalUint16 charHandle, + tHalUint8 charValOffset, + tHalUint8 charValueLen, + const tHalUint8 *charValue); + +tBleStatus aci_gatt_set_desc_value(tHalUint16 servHandle, + tHalUint16 charHandle, + tHalUint16 charDescHandle, + tHalUint16 charDescValOffset, + tHalUint8 charDescValueLen, + const tHalUint8 *charDescValue); + +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_mult); + +tBleStatus aci_hal_set_tx_power_level(uint8_t en_high_power, uint8_t pa_level); + +tBleStatus aci_hal_write_config_data(tHalUint8 offset, + tHalUint8 len, + const tHalUint8 *val); +tBleStatus aci_hal_tone_start(uint8_t rf_channel); + +tBleStatus aci_gatt_allow_read(tHalUint16 conn_handle); + +tBleStatus aci_gatt_disc_all_prim_services(uint16_t conn_handle); + +tBleStatus aci_gatt_find_included_services(uint16_t conn_handle, uint16_t start_handle, + uint16_t end_handle); + +tBleStatus aci_gatt_disc_all_charac_of_serv(uint16_t conn_handle, uint16_t start_attr_handle, + uint16_t end_attr_handle); + +tBleStatus aci_gatt_disc_all_charac_descriptors(uint16_t conn_handle, uint16_t char_val_handle, + uint16_t char_end_handle); + +tBleStatus aci_gatt_read_charac_val(uint16_t conn_handle, uint16_t attr_handle); + +tBleStatus aci_gatt_read_long_charac_val(uint16_t conn_handle, uint16_t attr_handle, + uint16_t val_offset); + +tBleStatus aci_gatt_write_charac_value(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +tBleStatus aci_gatt_write_charac_descriptor(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +tBleStatus aci_gatt_write_without_response(uint16_t conn_handle, uint16_t attr_handle, + uint8_t value_len, uint8_t *attr_value); + +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); + +#endif /* __BLUENRG_HCI_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hci/inc/bluenrg_hci_internal.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,531 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci_internal.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : Header file with ACI definitions 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. +*******************************************************************************/ + +#ifndef __BLUENRG_HCI_INTERNAL_H_ +#define __BLUENRG_HCI_INTERNAL_H_ + +#include "compiler.h" +#include "bluenrg_hci.h" + +#define OCF_HAL_WRITE_CONFIG_DATA 0x000C + +/* Offsets and lengths for configuration values */ +#define CONFIG_DATA_PUBADDR_OFFSET (0x00) +#define CONFIG_DATA_DIV_OFFSET (0x06) +#define CONFIG_DATA_ER_OFFSET (0x08) +#define CONFIG_DATA_IR_OFFSET (0x18) + +#define CONFIG_DATA_PUBADDR_LEN (0x06) +#define CONFIG_DATA_DIV_LEN (0x02) +#define CONFIG_DATA_ER_LEN (0x10) +#define CONFIG_DATA_IR_LEN (0x10) + +#define OCF_HAL_SET_TX_POWER_LEVEL 0x000F +typedef struct __packed _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_TONE_START 0x0015 +typedef struct __packed _hal_tone_start_cp{ + uint8_t rf_channel; +} PACKED hal_tone_start_cp; +#define HAL_TONE_START_CP_SIZE 1 + +#define OCF_UPDATER_START 0x0020 +#define OCF_UPDATER_REBOOT 0x0021 + +#define OCF_GET_UPDATER_VERSION 0x0022 +typedef struct __packed _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 struct __packed _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 struct __packed _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 +/* Variable length parameters */ + +#define OCF_UPDATER_READ_DATA_BLOCK 0x0028 +typedef struct __packed _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 struct __packed _updater_read_data_block_rp{ + uint8_t status; + uint8_t data[0]; +} PACKED updater_read_data_block_rp; +#define GET_UPDATER_BUFSIZE_RP_SIZE 2 + +#define OCF_UPDATER_CALC_CRC 0x0029 +typedef struct __packed _updater_calc_crc_cp{ + uint32_t address; + uint8_t num_sectors; +} PACKED updater_calc_crc_cp; +#define UPDATER_CALC_CRC_CP_SIZE 5 +typedef struct __packed _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 struct __packed _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 struct __packed _gap_set_direct_conectable_cp{ + uint8_t own_bdaddr_type; + uint8_t direct_bdaddr_type; + tBDAddr direct_bdaddr; +} PACKED gap_set_direct_conectable_cp; +#define GAP_SET_DIRECT_CONNECTABLE_CP_SIZE 8 + +#define OCF_GAP_SET_IO_CAPABILITY 0x0085 +typedef struct __packed _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 struct __packed _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 struct __packed _gap_set_author_requirement_cp{ + uint8_t authorization_enable; +} PACKED gap_set_author_requirement_cp; +#define GAP_SET_AUTHOR_REQUIREMENT_CP_SIZE 1 + +#define OCF_GAP_PASSKEY_RESPONSE 0x0088 +typedef struct __packed _gap_passkey_response_cp{ + uint32_t passkey; +} PACKED gap_passkey_response_cp; +#define GAP_PASSKEY_RESPONSE_CP_SIZE 4 + +#define OCF_GAP_AUTHORIZATION_RESPONSE 0x0089 +typedef struct __packed _gap_authorization_response_cp{ + uint8_t authorize; +} PACKED gap_authorization_response_cp; +#define GAP_AUTHORIZATION_RESPONSE_CP_SIZE 1 + +#define OCF_GAP_INIT 0x008A +typedef struct __packed _gap_init_cp{ + uint8_t role; +} PACKED gap_init_cp; +#define GAP_INIT_CP_SIZE 1 +typedef struct __packed _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 struct __packed _gap_set_non_connectable_cp{ + uint8_t advertising_event_type; +} PACKED gap_set_non_connectable_cp; +#define GAP_SET_NON_CONNECTABLE_CP_SIZE 1 + +#define OCF_GAP_SET_UNDIRECTED_CONNECTABLE 0x008C +typedef struct __packed _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 struct __packed _gap_slave_security_request_cp{ + uint8_t bonding; + uint8_t mitm_protection; +} PACKED gap_slave_security_request_cp; +#define GAP_SLAVE_SECURITY_REQUEST_CP_SIZE 2 + +#define OCF_GAP_UPDATE_ADV_DATA 0x008E + +#define OCF_GAP_DELETE_AD_TYPE 0x008F +typedef struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 + +#define OCF_GAP_START_LIMITED_DISCOVERY_PROC 0x0096 +typedef struct __packed _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 struct __packed _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_AUTO_CONN_ESTABLISHMENT 0x0099 + +#define OCF_GAP_CREATE_CONNECTION 0x009C +typedef struct __packed _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_GATT_INIT 0x0101 + +#define OCF_GATT_ADD_SERV 0x0102 +typedef struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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_DISC_ALL_PRIM_SERVICES 0X0112 +typedef struct __packed _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_FIND_INCLUDED_SERVICES 0X0114 +typedef struct __packed _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 struct __packed _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_ALL_CHARAC_DESCRIPTORS 0X0117 +typedef struct __packed _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 struct __packed _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_LONG_CHARAC_VAL 0x011A +typedef struct __packed _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_WRITE_CHAR_VALUE 0x011C +#define OCF_GATT_WRITE_CHAR_DESCRIPTOR 0x0121 + +#define OCF_GATT_READ_CHAR_DESCRIPTOR 0x0122 + +#define OCF_GATT_WRITE_WITHOUT_RESPONSE 0x0123 + +#define OCF_GATT_SIGNED_WRITE_WITHOUT_RESPONSE 0x0124 + +#define OCF_GATT_CONFIRM_INDICATION 0x0125 + +#define OCF_GATT_WRITE_RESPONSE 0x0126 + +#define OCF_GATT_ALLOW_READ 0x0127 +typedef struct __packed _gatt_allow_read_cp{ + uint16_t conn_handle; +} PACKED gatt_allow_read_cp; +#define GATT_ALLOW_READ_CP_SIZE 2 + +#define OCF_GATT_SET_DESC_VAL 0x0129 + +#define OCF_L2CAP_CONN_PARAM_UPD_REQ 0x0181 +typedef struct __packed _l2cap_conn_param_upd_cp{ + uint16_t handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t slave_latency; + uint16_t timeout_multiplier; +} PACKED l2cap_conn_param_upd_cp; +#define L2CAP_CONN_PARAM_UPD_REQ_CP_SIZE 10 + + +/*------------- Events -------------*/ + +#define EVT_VENDOR 0xFF /* The event code in the hci_event_pckt structure */ +typedef struct __packed _evt_blue_aci{ + uint16_t ecode; + uint8_t data[0]; +} PACKED evt_blue_aci; + +/* HCI vendor specific event */ +#define EVT_BLUE_INITIALIZED (0x0001) + +/* GAP Vendor specific event codes */ +#define EVT_BLUE_GAP_SET_LIMITED_DISCOVERABLE (0x0400) +#define EVT_BLUE_GAP_PAIRING_CMPLT (0x0401) +#define EVT_BLUE_GAP_PASS_KEY_REQUEST (0x0402) +#define EVT_BLUE_GAP_AUTHORIZATION_REQUEST (0x0403) +#define EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED (0X0404) +#define EVT_BLUE_GAP_DEVICE_FOUND (0x0406) +typedef struct __packed _evt_gap_device_found{ + uint8_t peer_address_type; + uint8_t peer_address[6]; +} PACKED evt_gap_device_found; +#define EVT_BLUE_GAP_PROCEDURE_COMPLETE (0x0407) +typedef struct __packed _evt_gap_procedure_complete{ + uint8_t procedure_code; + uint8_t status; + uint8_t data[0]; +} PACKED evt_gap_procedure_complete; + +/* L2CAP vendor specific event codes */ +#define EVT_BLUE_L2CAP_CONN_UPD_RESP (0x0800) +typedef struct __packed _evt_l2cap_conn_param_upd_resp{ + uint16_t conn_handle; + uint8_t packet_length; + uint8_t code; + uint8_t id; + uint16_t l2c_lenght; + uint16_t result; +} PACKED evt_l2cap_conn_param_upd_resp; +#define EVT_L2CAP_CONN_PARAM_UPD_RESP_SIZE 9 + +#define EVT_BLUE_L2CAP_PROCEDURE_TIMEOUT (0x0801) + + +/* vendor specific debug events */ +#define EVT_BLUE_DEBUG (0x1000) + +/* GATT vendor specific event codes */ +#define EVT_BLUE_GATT_ATTRIBUTE_MODIFIED (0x0C01) +typedef struct __packed _evt_gatt_attr_modified{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t data_length; + uint8_t att_data[0]; +} PACKED evt_gatt_attr_modified; + +#define EVT_BLUE_GATT_PROCEDURE_TIMEOUT (0x0C02) +#define EVT_BLUE_EXCHANGE_MTU_RESP (0x0C03) +#define EVT_BLUE_ATT_FIND_INFORMATION_RESP (0x0C04) +typedef struct __packed _evt_att_find_information_resp{ + uint16_t conn_handle; + uint8_t event_data_length; + uint8_t format; + uint8_t handle_uuid_pair[0]; +} PACKED evt_att_find_information_resp; + +#define EVT_BLUE_ATT_FIND_BY_TYPE_VAL_RESP (0x0C05) +#define EVT_BLUE_ATT_READ_BY_TYPE_RESP (0x0C06) +typedef struct __packed _evt_att_read_by_type_resp{ + uint16_t conn_handle; + uint8_t event_data_length; + uint8_t handle_value_pair_length; + uint8_t handle_value_pair[0]; +} PACKED evt_att_read_by_type_resp; + +#define EVT_BLUE_ATT_READ_RESP (0x0C07) +#define EVT_BLUE_ATT_READ_BLOB_RESP (0x0C08) +#define EVT_BLUE_ATT_READ_MULTIPLE_RESP (0x0C09) +#define EVT_BLUE_ATT_READ_BY_GROUP_RESP (0x0C0A) +typedef struct __packed _evt_att_read_by_group_resp{ + uint16_t conn_handle; + uint8_t event_data_length; + uint8_t handle_value_pair_length; + uint8_t handle_value_pair[0]; +} PACKED evt_att_read_by_group_resp; + +#define EVT_BLUE_ATT_WRITE_RESP (0x0C0B) +#define EVT_BLUE_ATT_PREPARE_WRITE_RESP (0x0C0C) +#define EVT_BLUE_ATT_EXEC_WRITE_RESP (0x0C0D) +#define EVT_BLUE_GATT_INDICATION (0x0C0E) +#define EVT_BLUE_GATT_NOTIFICATION (0x0C0F) +typedef struct __packed _evt_gatt_notification{ + uint16_t conn_handle; + uint8_t data_length; // Lenght of attribute value + handle. + uint16_t attr_handle; + uint8_t attr_value[0]; +} PACKED evt_gatt_attr_notification; + +#define EVT_BLUE_GATT_PROCEDURE_COMPLETE (0x0C10) +typedef struct __packed _evt_gatt_procedure_complete{ + uint16_t conn_handle; + uint8_t data_length; + uint8_t data[0]; +} PACKED evt_gatt_procedure_complete; + +#define EVT_BLUE_GATT_ERROR_RESP (0x0C11) +#define EVT_BLUE_GATT_DISC_READ_CHAR_BY_UUID_RESP (0x0C12) +#define EVT_BLUE_GATT_WRITE_PERMIT_REQ (0x0C13) +typedef struct __packed _evt_gatt_write_permit_req{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t data_length; + uint8_t offset_data[0]; +} PACKED evt_gatt_write_permit_req; + +#define EVT_BLUE_GATT_READ_PERMIT_REQ (0x0C14) +typedef struct __packed _evt_gatt_read_permit_req{ + uint16_t conn_handle; + uint16_t attr_handle; + uint8_t data_length; + uint8_t offset_data[0]; +} PACKED evt_gatt_read_permit_req; + +#define EVT_BLUE_GATT_READ_MULTI_PERMIT_REQ (0x0C15) + + + +#endif /* __BLUENRG_HCI_INTERNAL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hci/inc/gatt_service.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,147 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : 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 __GATT_SERV_H__ +#define __GATT_SERV_H__ + +#include "compiler.h" +#include "ble_status.h" + +/** + * UUID table + */ +#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) + +/****************************************************************************** + * Types + *****************************************************************************/ + +/** + * Access permissions + * for an attribute + */ +typedef tHalUint8 tAttrAccessFlags; +#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) + +/** + * 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) + +/** + * Security permissions + * for an attribute + */ +typedef tHalUint8 tAttrSecurityFlags; +#define ATTR_PERMISSION_NONE (0x00) +#define ATTR_PERMISSION_AUTHEN_READ (0x01) +#define ATTR_PERMISSION_AUTHOR_READ (0x02) +#define ATTR_PERMISSION_ENCRY_READ (0x04) +#define ATTR_PERMISSION_AUTHEN_WRITE (0x08) +#define ATTR_PERMISSION_AUTHOR_WRITE (0x10) +#define ATTR_PERMISSION_ENCRY_WRITE (0x20) + +/** + * Type of UUID + * (16 bit or 128 bit) + */ +typedef tHalUint8 tUuidType; +#define UUID_TYPE_16 (0x01) +#define UUID_TYPE_128 (0x02) + +/** + * Type of service + * (primary or secondary) + */ +typedef tHalUint8 tServiceType; +#define PRIMARY_SERVICE (0x01) +#define SECONDARY_SERVICE (0x02) + +/** + * Type of event generated by + * Gatt server + */ +typedef tHalUint8 tGattServerEvent; +#define GATT_SERVER_ATTR_WRITE (0x01) +#define GATT_INTIMATE_AND_WAIT_FOR_APPL_AUTH (0x02) +#define GATT_INTIMATE_APPL_WHEN_READ_N_WAIT (0x04) +#define GATT_SERVER_ATTR_READ_WRITE GATT_SERVER_ATTR_WRITE|GATT_INTIMATE_APPL_WHEN_READ_N_WAIT + + +/** + * Min encryption key size + */ +#define MIN_ENCRY_KEY_SIZE (7) + +/** + * Max encryption key size + */ +#define MAX_ENCRY_KEY_SIZE (0x10) + +typedef struct __packed _charactFormat { + tHalUint8 format; + tHalInt8 exp; + tHalUint16 unit; + tHalUint8 name_space; + tHalUint16 desc; +} PACKED charactFormat; + +#define FORMAT_UINT8 0x04 +#define FORMAT_UINT16 0x06 +#define FORMAT_SINT16 0x0E +#define FORMAT_SINT24 0x0F + + +#define UNIT_UNITLESS 0x2700 +#define UNIT_TEMP_CELSIUS 0x272F +#define UNIT_PRESSURE_BAR 0x2780 + + +/* + * Default MTU size + */ +#define ATT_DEFAULT_MTU (23) + + +#endif /* __GATT_SERVER_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hci/inc/hal.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,84 @@ +/******************** (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 Controller Byte order conversion */ +#define LE_TO_NRG_16(ptr) (uint16) ( ((uint16) \ + *((tHalUint8 *)ptr)) | \ + ((tHalUint16) \ + *((tHalUint8 *)ptr + 1) << 8 ) ) + +#define LE_TO_NRG_32(ptr) (tHalUint32) ( ((tHalUint32) \ + *((tHalUint8 *)ptr)) | \ + ((tHalUint32) \ + *((tHalUint8 *)ptr + 1) << 8) | \ + ((tHalUint32) \ + *((tHalUint8 *)ptr + 2) << 16) | \ + ((tHalUint32) \ + *((tHalUint8 *)ptr + 3) << 24) ) + +/* Store Value into a buffer in Little Endian Format */ +#define STORE_LE_16(buf, val) ( ((buf)[0] = (tHalUint8) (val) ) , \ + ((buf)[1] = (tHalUint8) (val>>8) ) ) + +#define STORE_LE_32(buf, val) ( ((buf)[0] = (tHalUint8) (val) ) , \ + ((buf)[1] = (tHalUint8) (val>>8) ) , \ + ((buf)[2] = (tHalUint8) (val>>16) ) , \ + ((buf)[3] = (tHalUint8) (val>>24) ) ) + +/****************************************************************************** + * 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_byt//es2 number of bytes in 2nd buffer + */ +//void Hal_Write_Serial(const void* data1, const void* data2, tHalInt32 n_bytes1, tHalInt32 n_bytes2); + +/** + * Enable interrupts from HCI controller. + */ +//void Enable_SPI_IRQ(void); + +/** + * Disable interrupts from BLE controller. + */ +//void Disable_SPI_IRQ(void); + + + + +#endif /* __HAL_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hci/inc/hal_types.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,96 @@ +/******************** (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 + +/* 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) bswap_16(d) +#define htobl(d) bswap_32(d) +#define btohs(d) bswap_16(d) +#define btohl(d) bswap_32(d) +#else +#error "Unknown byte order" +#endif + +/** + * Integer type : Machines natural word size + */ +typedef int tHalInt; + +/** + * Unsigned Integer type : Machines natural word size + */ +typedef unsigned int tHalUint; + +/** + * signed 32-bit + */ +typedef int tHalInt32; + +/** + * unsigned 32-bit + */ +typedef unsigned int tHalUint32; + +/** + * signed 16-bit + */ +typedef short tHalInt16; + +/** + * unsigned 16-bit + */ +typedef unsigned short tHalUint16; + +/** + * signed 8-bit + */ +typedef signed char tHalInt8; + +/** + * unsigned 8-bit + */ +typedef unsigned char tHalUint8; + +/** + * Boolean: smallest value. + */ +typedef char tHalBool; + +#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/hci/inc/hci.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,200 @@ +/******************** (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_PACKET_SIZE 255 + + +/*** Data types ***/ + +/* structure used to read received data */ +typedef struct _tHciDataPacket +{ + tListNode currentNode; + uint8_t dataBuff[HCI_PACKET_SIZE]; +}tHciDataPacket; + + +/* 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, -1 otherwise. + */ + +int hci_reset(void); + +int hci_disconnect(uint16_t handle, uint8_t reason); + +int hci_le_set_advertise_enable(tHalUint8 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, tBDAddr direct_bdaddr, uint8_t chan_map, + uint8_t filter); + +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(); + +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(); + +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); + +/** + * 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); + + +extern tListNode hciReadPktPool; +extern tListNode hciReadPktRxQueue; + +#endif /* __HCI_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hci/inc/hci_internal.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,552 @@ +/****************************************************************************** +* +* 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/100) + +#define HCI_MAX_EVENT_SIZE 260 + +#define HCI_MAX_PACKET_SIZE HCI_MAX_EVENT_SIZE + +/* 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 struct __packed _hci_uart_pckt{ + tHalUint8 type; + tHalUint8 data[0]; +} PACKED hci_uart_pckt; +#define HCI_HDR_SIZE 1 + +typedef struct __packed _hci_command_hdr{ + tHalUint16 opcode; /* OCF & OGF */ + tHalUint8 plen; +} PACKED hci_command_hdr; +#define HCI_COMMAND_HDR_SIZE 3 + +typedef struct __packed _hci_event_pckt{ + tHalUint8 evt; + tHalUint8 plen; + tHalUint8 data[0]; +} PACKED hci_event_pckt; +#define HCI_EVENT_HDR_SIZE 2 + +typedef struct __packed _hci_acl_hdr{ + tHalUint16 handle; /* Handle & Flags(PB, BC) */ + tHalUint16 dlen; +} PACKED hci_acl_hdr; +#define HCI_ACL_HDR_SIZE 4 + + +/* Link Control */ +#define OGF_LINK_CTL 0x01 + +#define OCF_DISCONNECT 0x0006 +typedef struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _read_rssi_cp{ + uint16_t handle; +} PACKED read_rssi_cp; +#define READ_RSSI_CP_SIZE 2 +typedef struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _le_read_channel_map_cp{ + uint16_t handle; +} PACKED le_read_channel_map_cp; +#define LE_READ_CHANNEL_MAP_CP_SIZE 2 + +typedef struct __packed _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 struct __packed _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 struct __packed _le_encrypt_cp{ + uint8_t key[16]; + uint8_t plaintext[16]; +} PACKED le_encrypt_cp; +#define LE_ENCRYPT_CP_SIZE 32 + +typedef struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _le_ltk_reply_cp{ + uint16_t handle; + uint8_t key[16]; +} PACKED le_ltk_reply_cp; +#define LE_LTK_REPLY_CP_SIZE 18 + +typedef struct __packed _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 struct __packed _le_ltk_neg_reply_cp{ + uint16_t handle; +} PACKED le_ltk_neg_reply_cp; +#define LE_LTK_NEG_REPLY_CP_SIZE 2 + +typedef struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _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 struct __packed _evt_cmd_complete{ + tHalUint8 ncmd; + tHalUint16 opcode; +} PACKED evt_cmd_complete; +#define EVT_CMD_COMPLETE_SIZE 3 + +#define EVT_CMD_STATUS 0x0F +typedef struct __packed _evt_cmd_status{ + tHalUint8 status; + tHalUint8 ncmd; + tHalUint16 opcode; +} PACKED evt_cmd_status; +#define EVT_CMD_STATUS_SIZE 4 + +#define EVT_HARDWARE_ERROR 0x10 +typedef struct __packed _evt_hardware_error{ + uint8_t code; +} PACKED evt_hardware_error; +#define EVT_HARDWARE_ERROR_SIZE 1 + +#define EVT_NUM_COMP_PKTS 0x13 +typedef struct __packed _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 struct __packed _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_ENCRYPTION_KEY_REFRESH_COMPLETE 0x30 +typedef struct __packed _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 struct __packed _evt_le_meta_event{ + tHalUint8 subevent; + tHalUint8 data[0]; +} PACKED evt_le_meta_event; +#define EVT_LE_META_EVENT_SIZE 1 + +#define EVT_LE_CONN_COMPLETE 0x01 +typedef struct __packed _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 struct __packed _le_advertising_info{ + uint8_t evt_type; + uint8_t bdaddr_type; + tBDAddr bdaddr; + uint8_t length; + uint8_t data[0]; +} PACKED le_advertising_info; +#define LE_ADVERTISING_INFO_SIZE 9 + +#define EVT_LE_CONN_UPDATE_COMPLETE 0x03 +typedef struct __packed _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 struct __packed _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 struct __packed _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 + + +/* Command opcode pack/unpack */ +#define cmd_opcode_pack(ogf, ocf) (tHalUint16)((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; +}; + +int 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, tHalUint16 len); + +/* HCI library functions. */ +void hci_init(void); + +int hci_send_req(struct hci_request *r); + +#endif /* __HCI_INTERNAL_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hci/inc/link_layer.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,107 @@ +/******************** (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> + +/****************************************************************************** + * Types + *****************************************************************************/ + +/** + * advertising policy for filtering (white list related) + */ +typedef tHalUint8 tAdvPolicy; +#define NO_WHITE_LIST_USE (0X00) +#define WHITE_LIST_FOR_ONLY_SCAN (0X01) +#define WHITE_LIST_FOR_ONLY_CONN (0X02) +#define WHITE_LIST_FOR_ALL (0X03) + +/** + * Bluetooth 48 bit address (in little-endian order). + */ +typedef tHalUint8 tBDAddr[6]; + + +/** + * Bluetooth address type + */ +typedef tHalUint8 tAddrType; +#define RANDOM_ADDR (1) +#define PUBLIC_ADDR (0) + +/** + * Advertising type + */ +typedef tHalUint8 tAdvType; +/** + * 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) + + +/* 0X04-0XFF RESERVED */ + + +/** + * 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) + +/** + * Default value of advertising interval for both min/max values. + * This will be used if host does not specify any advertising parameters + * including advIntervalMax and advIntervalMin + * value = 1.28 sec (in units of 625 us) + */ +#define ADV_INTERVAL_DEFAULT (0x0800) + +#define ADV_CH_37 0x01 +#define ADV_CH_38 0x02 +#define ADV_CH_39 0x04 + + + +#endif /* _LINK_LAYER_H */ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hci/inc/role_type.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,9 @@ +#ifndef _ROLE_TYPE_H_ +#define _ROLE_TYPE_H_ + +typedef enum { + CLIENT, + SERVER +} BLE_RoleTypeDef; + +#endif /* _ROLE_TYPE_H_ */ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hci/inc/sm.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,77 @@ +/******************** (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 +*****************************************************************************/ + +/* IO capabilities */ +typedef tHalUint8 tSMIoCapability; +#define IO_CAP_DISPLAY_ONLY (0x00) +#define IO_CAP_DISPLAY_YES_NO (0x01) +#define KEYBOARD_ONLY (0x02) +#define IO_CAP_NO_INPUT_NO_OUTPUT (0x03) +#define IO_CAP_KEYBOARD_DISPLAY (0x04) + +/* authentication requirements */ +typedef tHalUint8 tSMBondingMode; +#define BONDING (0x01) +#define NO_BONDING (0x00) + +typedef tHalUint8 tSMMIMTMode; +#define MITM_PROTECTION_NOT_REQUIRED (0x00) +#define MITM_PROTECTION_REQUIRED (0x01) + +#define OOB_AUTH_DATA_ABSENT (0x00) +#define OOB_AUTH_DATA_PRESENT (0x01) + +#define AUTHORIZATION_NOT_REQUIRED (0x00) +#define AUTHORIZATION_REQUIRED (0x01) + +/* valid authorization responses */ +#define CONNECTION_AUTHORIZED (0x01) +#define CONNECTION_REJECTED (0x02) + +#define USE_FIXED_PIN_FOR_PAIRING (0x0) +#define DONOT_USE_FIXED_PIN_FOR_PAIRING (0x01) +#define PASSKEY_ENTERED (0x02) + +/* link security status */ +#define SM_LINK_AUTHENTICATED (0x01) +#define SM_LINK_AUTHORIZED (0x02) +#define SM_LINK_ENCRYPTED (0x04) + +/* 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) + + +/* error codes to be sent with the pairing complete event */ +#define SM_PAIRING_TIMEOUT (0x01) +#define SM_PAIRING_FAILED (0x02) + + +#endif /* __SM_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hci/src/bluenrg_hci.c Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,1417 @@ +/******************** (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_internal.h" +#include "bluenrg_hci_internal.h" +#include "gatt_service.h" + + +tBleStatus aci_gatt_init() +{ + struct hci_request rq; + tHalUint8 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) < 0) + return -1; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_init(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 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 = GAP_INIT_CP_SIZE; + rq.rparam = &resp; + rq.rlen = GAP_INIT_RP_SIZE; + + if (hci_send_req(&rq) < 0) + return -1; + + if (resp.status) { + return resp.status; + } + + *service_handle = resp.service_handle; + *dev_name_char_handle = resp.dev_name_char_handle; + *appearance_char_handle = resp.appearance_char_handle; + + return 0; +} + +tBleStatus aci_gap_set_non_discoverable(void) +{ + struct hci_request rq; + tHalUint8 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) < 0) + return -1; + + 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, const uint8_t* ServiceUUIDList, + uint16_t SlaveConnIntervMin, uint16_t SlaveConnIntervMax) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PACKET_SIZE]; + uint8_t indx = 0; + + buffer[indx] = AdvType; + indx++; + + Osal_MemCpy(buffer + indx, &AdvIntervMin, 2); + indx += 2; + + 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_DISCOVERABLE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq) < 0) + return -1; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gap_update_adv_data(uint8_t AdvLen, const uint8_t *AdvData) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PACKET_SIZE]; + uint8_t indx = 0; + + 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) < 0) + return -1; + + return status; +} + + +tBleStatus aci_gatt_add_serv(tHalUint8 service_uuid_type, const tHalUint8* service_uuid, tHalUint8 service_type, tHalUint8 max_attr_records, tHalUint16 *serviceHandle) +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[HCI_MAX_PACKET_SIZE]; + uint8_t uuid_len; + uint8_t indx = 0; + + buffer[indx] = service_uuid_type; + indx++; + + if(service_uuid_type == 0x01){ + 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) < 0) + return -1; + + if (resp.status) { + return resp.status; + } + + *serviceHandle = resp.handle; + + return 0; +} + +tBleStatus aci_gatt_add_char(tHalUint16 serviceHandle, + tUuidType charUuidType, + const tHalUint8* charUuid, + tHalUint16 charValueLen, + tHalUint8 charProperties, + tAttrSecurityFlags secPermissions, + tGattServerEvent gattEvtMask, + tHalUint8 encryKeySize, + tHalUint8 isVariable, + tHalUint16* charHandle) + + +{ + struct hci_request rq; + gatt_add_serv_rp resp; + uint8_t buffer[HCI_MAX_PACKET_SIZE]; + uint8_t uuid_len; + uint8_t indx = 0; + + Osal_MemCpy(buffer + indx, &serviceHandle, 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; + + 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) < 0) + return -1; + + if (resp.status) { + return resp.status; + } + + *charHandle = resp.handle; + + return 0; +} + +tBleStatus aci_gatt_add_char_desc(tHalUint16 serviceHandle, + tHalUint16 charHandle, + tUuidType descUuidType, + const tHalUint8* uuid, + tHalUint8 descValueMaxLen, + tHalUint8 descValueLen, + const void* descValue, + tAttrSecurityFlags secPermissions, + tAttrSecurityFlags accPermissions, + tGattServerEvent gattEvtMask, + tHalUint8 encryKeySize, + tHalUint8 isVariable, + tHalUint16* descHandle) + + +{ + struct hci_request rq; + gatt_add_char_desc_rp resp; + uint8_t buffer[HCI_MAX_PACKET_SIZE]; + uint8_t uuid_len; + uint8_t indx = 0; + + Osal_MemCpy(buffer + indx, &serviceHandle, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + buffer[indx] = descUuidType; + indx++; + + if(descUuidType == 0x01){ + 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++; + + 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) < 0) + return -1; + + if (resp.status) { + return resp.status; + } + + *descHandle = resp.handle; + + return 0; +} + + +tBleStatus aci_gatt_update_char_value(tHalUint16 servHandle, + tHalUint16 charHandle, + tHalUint8 charValOffset, + tHalUint8 charValueLen, + const tHalUint8 *charValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PACKET_SIZE]; + uint8_t indx = 0; + + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + 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) < 0) + return -1; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_allow_read(tHalUint16 conn_handle) +{ + struct hci_request rq; + gatt_allow_read_cp cp; + tHalUint8 status; + + cp.conn_handle = 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) < 0) + return -1; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_gatt_set_desc_value(tHalUint16 servHandle, + tHalUint16 charHandle, + tHalUint16 charDescHandle, + tHalUint16 charDescValOffset, + tHalUint8 charDescValueLen, + const tHalUint8 *charDescValue) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PACKET_SIZE]; + uint8_t indx = 0; + + Osal_MemCpy(buffer + indx, &servHandle, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &charHandle, 2); + indx += 2; + + 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) < 0) + return -1; + + if (status) { + return status; + } + + return 0; +} + +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 = 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) < 0) + return -1; + + 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 = conn_handle; + cp.start_handle = start_service_handle; + cp.end_handle = 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) < 0) + return -1; + + 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 = conn_handle; + cp.start_attr_handle = start_attr_handle; + cp.end_attr_handle = 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) < 0) + return -1; + + 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 = conn_handle; + cp.char_val_handle = char_val_handle; + cp.char_end_handle = 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) < 0) + return -1; + + return status; +} + +tBleStatus aci_gatt_write_without_response(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_PACKET_SIZE]; + uint8_t indx = 0; + + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + 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_WITHOUT_RESPONSE; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq) < 0) + return -1; + + 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_PACKET_SIZE]; + uint8_t indx = 0; + + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + 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) < 0) + return -1; + + if (status) { + return status; + } + + return 0; +} + +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 = conn_handle; + cp.attr_handle = 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) < 0) + return -1; + + 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 = conn_handle; + cp.attr_handle = attr_handle; + cp.val_offset = 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) < 0) + return -1; + + 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_PACKET_SIZE]; + uint8_t indx = 0; + + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + 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) < 0) + return -1; + + 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_PACKET_SIZE]; + uint8_t indx = 0; + + Osal_MemCpy(buffer + indx, &conn_handle, 2); + indx += 2; + + 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.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq) < 0) + return -1; + + return status; +} + +tBleStatus aci_hal_write_config_data(tHalUint8 offset, + tHalUint8 len, + const tHalUint8 *val) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PACKET_SIZE]; + uint8_t indx = 0; + + 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) < 0) + return -1; + + 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) < 0) + return -1; + + if (status) { + return status; + } + + return 0; +} + +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 = 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 = GAP_SET_AUTH_REQUIREMENT_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq) < 0) + return -1; + + if (status) { + return status; + } + + return 0; + +} + +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 = scanInterval; + cp.scanWindow = 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 = GAP_START_LIMITED_DISCOVERY_PROC_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq) < 0) + return -1; + + 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 = scanInterval; + cp.scanWindow = 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 = GAP_START_GENERAL_DISCOVERY_PROC_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq) < 0) + return -1; + + return status; +} + + +tBleStatus aci_gap_start_auto_conn_establishment(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, + uint8_t *addr_array) +{ + struct hci_request rq; + uint8_t status; + uint8_t buffer[HCI_MAX_PACKET_SIZE]; + uint8_t indx = 0; + + Osal_MemCpy(buffer + indx, &scanInterval, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &scanWindow, 2); + indx += 2; + + buffer[indx] = own_bdaddr_type; + indx++; + + Osal_MemCpy(buffer + indx, &conn_min_interval, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &conn_max_interval, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &conn_latency, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &supervision_timeout, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, &min_conn_length, 2); + indx += 2; + + 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_ESTABLISHMENT; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq) < 0) + return -1; + + 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 = scanInterval; + cp.scanWindow = 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 = conn_min_interval; + cp.conn_max_interval = conn_max_interval; + cp.conn_latency = conn_latency; + cp.supervision_timeout = supervision_timeout; + cp.min_conn_length = min_conn_length; + cp.max_conn_length = 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 = GAP_CREATE_CONNECTION_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq) < 0) + return -1; + + 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) < 0) + return -1; + + 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 = 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 = GAP_TERMINATE_CP_SIZE; + rq.event = EVT_CMD_STATUS; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq) < 0) + return -1; + + return status; +} + +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_mult) +{ + struct hci_request rq; + l2cap_conn_param_upd_cp cp; + tHalUint8 status; + + cp.handle = conn_handle; + cp.interval_min = interval_min; + cp.interval_max = interval_max; + cp.slave_latency = slave_latency; + cp.timeout_multiplier = timeout_mult; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_L2CAP_CONN_PARAM_UPD_REQ; + rq.event = EVT_CMD_STATUS; + rq.cparam = &cp; + rq.clen = L2CAP_CONN_PARAM_UPD_REQ_CP_SIZE; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq) < 0) + return -1; + + 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) < 0) + return -1; + + if (status) { + return status; + } + + return 0; +} + +tBleStatus aci_updater_start(void) +{ + struct hci_request rq; + tHalUint8 status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_START; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq) < 0) + return -1; + + return status; +} + +tBleStatus aci_updater_reboot() +{ + struct hci_request rq; + tHalUint8 status; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_REBOOT; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq) < 0) + return -1; + + 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) < 0) + return -1; + + *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) < 0) + return -1; + + *buffer_size = resp.buffer_size; + + return resp.status; +} + +tBleStatus aci_erase_blue_flag() +{ + struct hci_request rq; + tHalUint8 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) < 0) + return -1; + + return status; +} + +tBleStatus aci_reset_blue_flag() +{ + struct hci_request rq; + tHalUint8 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) < 0) + return -1; + + return status; +} + +tBleStatus aci_updater_erase_sector(uint32_t address) +{ + struct hci_request rq; + updater_erase_sector_cp cp; + uint8_t status; + + cp.address = 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) < 0) + return -1; + + 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; + uint8_t buffer[HCI_MAX_PACKET_SIZE]; + uint8_t indx = 0; + + if(len > HCI_MAX_PACKET_SIZE) + return -1; + + Osal_MemCpy(buffer + indx, &address, 4); + indx += 4; + + Osal_MemCpy(buffer + indx, &len, 2); + indx += 2; + + Osal_MemCpy(buffer + indx, data, len); + indx += len; + + Osal_MemSet(&rq, 0, sizeof(rq)); + rq.ogf = OGF_VENDOR_CMD; + rq.ocf = OCF_UPDATER_PROG_DATA_BLOCK; + rq.cparam = (void *)buffer; + rq.clen = indx; + rq.rparam = &status; + rq.rlen = 1; + + if (hci_send_req(&rq) < 0) + return -1; + + 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_PACKET_SIZE]; + + if(data_len > HCI_MAX_PACKET_SIZE - 1) + return -1; + + cp.address = address; + cp.data_len = 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) < 0) + return -1; + + 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 = 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) < 0) + return -1; + + *crc = 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) < 0) + return -1; + + *version = resp.version; + + return resp.status; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hci/src/bluenrg_shield_bsp.c Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,328 @@ +/** +****************************************************************************** +* File Name : bluenrg_shield_bsp.c +* Date : 01/10/2014 +* Description : This file provides code for the BlueNRG Shield driver +* based on mbed HAL. +****************************************************************************** +* +* COPYRIGHT(c) 2014 STMicroelectronics +* +* 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 "hci.h" +#include "spi_api.h" +#include "gpio_irq_api.h" +#include "gpio_api.h" +#include "wait_api.h" +#include "pinmap.h" +#include "bluenrg_shield_bsp.h" + +spi_t __spi; +gpio_irq_t irq_exti; +gpio_t gpio_pin_A0, gpio_pin_CS, gpio_pin_MOSI, gpio_pin_MISO, gpio_pin_SCLK, gpio_pin_RESET; +void EXTI_irq_handler(uint32_t id, gpio_irq_event event); + +/** @addtogroup BlueNRG_Shield + * @{ + */ + +/** @defgroup BlueNRG_Shield_Driver + * @brief BlueNRG Shield driver based on mbed HAL + * @{ + */ + + +/* +* mbed EXTI IRQ Handler +* +*/ +void EXTI_irq_handler(uint32_t id, gpio_irq_event event) +{ + tHciDataPacket * hciReadPacket = NULL; + uint8_t data_len; + + //Check id of the IRQ + if(id == (uint32_t)BNRG_SPI_INSTANCE) { + + while (gpio_read(&gpio_pin_A0) == 1) { + 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_PACKET_SIZE); + + if(data_len > 0){ + /* Packet will be inserted to the correct queue */ + HCI_Input(hciReadPacket); + } else { + /* Insert the packet back into the pool */ + list_insert_head(&hciReadPktPool, (tListNode *)hciReadPacket); + } + + } else{ + /* TODO: HCI Read Packet Pool is empty, wait for a free packet */ + } + + } + } +} + +/** +* @brief This function is used to initialize the SPI communication with +* the BlueNRG Shield. All params should come from the User +* @param SPI_MOSI : PA_7 (Nucleo), D11 (Generic Arduino Pin) +* @param SPI_MISO : PA_6, D12 +* @param SPI_SCLK : PB_3, D3 +* @param SPI_CS : PA_1, A1 +* @param EXTI_IRQ : PA_0, A0 +* @param BlueNRG_RESET : PA_8, D7 +* @retval None +*/ +void BNRG_SPI_Init(void) +{ + int ret; + spi_init(&__spi, D11, D12, D3, NC); + //spi_format(&__spi, 8, 0, 0); + //spi_frequency(&__spi, 1000000); + + /*Init IRQ for EXTI Interrupt*/ + //gpio_init(&gpio_pin_A0, A0);//PA_0 in Nucleo + ret = gpio_irq_init(&irq_exti, A0, EXTI_irq_handler,(uint32_t)BNRG_SPI_INSTANCE); + gpio_irq_set(&irq_exti, IRQ_RISE, 1);//Set mode to IRQ_RISE + gpio_init_in(&gpio_pin_A0, A0);//PA_0 in Nucleo//Configure the GPIO Pin as Input pin and PullDefault + //gpio_irq_enable(&irq_exti);//IRQ already enabled in IRQ init call above. + + /* Reset Pin Config */ + gpio_init(&gpio_pin_RESET, D7);//PA_8 in Nucleo + gpio_mode(&gpio_pin_RESET, PullNone); + gpio_dir(&gpio_pin_RESET, PIN_OUTPUT); + gpio_write(&gpio_pin_RESET, 1); + + /* SCLK - PA_5 - Not needed to configure if correct PinName is given to spi_init, in this case PB_3 for L0*/ + /*gpio_init(&gpio_pin_SCLK, PB_3); //PA_5 is not USED????!!!! Since configuring PA_5 does not work! + gpio_mode(&gpio_pin_SCLK, PullUp); + //gpio_dir(&gpio_pin_SCLK, PIN_INPUT); //just 2 options of PIN_INPUT and PIN_OUTPUT does not suffice to configure Pin. + pin_function(PB_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, 0));*/ + + /* NSS/CSN/CS - PA_1*/ + gpio_init(&gpio_pin_CS, A1);//PA_1 in Nucleo + gpio_mode(&gpio_pin_CS, PullNone); + gpio_dir(&gpio_pin_CS, PIN_OUTPUT); + gpio_write(&gpio_pin_CS, 1); + +} + +/** +* @brief Read 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 number of read bytes +*/ +int32_t BlueNRG_SPI_Read_All(uint8_t *buffer, uint8_t buff_size) +{ + uint16_t byte_count; + uint8_t len = 0; + uint8_t i = 0; + uint8_t char_ff = 0xff; + volatile uint8_t read_char, tmpreg; + + uint8_t header_master[5] = {0x0b, 0x00, 0x00, 0x00, 0x00}; + uint8_t header_slave[5]; + + /* CS reset */ + gpio_write(&gpio_pin_CS, 0); + + /* Read the header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_master_write(&__spi, header_master[i]); + header_slave[i] = (uint8_t)(tmpreg); + } + + + if (header_slave[0] == 0x02) { + /* device is ready */ + byte_count = (header_slave[4]<<8)|header_slave[3]; + + if (byte_count > 0) { + /* avoid to read more data that size of the buffer */ + if (byte_count > buff_size){ + byte_count = buff_size; + } + + for (len = 0; len < byte_count; len++){ + read_char = spi_master_write(&__spi, char_ff); + buffer[len] = read_char; + } + } + } + /* Release CS line */ + gpio_write(&gpio_pin_CS, 1); + + return len; +} + +/** +* @brief Write 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) +{ + uint32_t i; + volatile uint8_t read_char; + int32_t result = 0; + volatile uint8_t tmpreg; + + unsigned char header_master[5] = {0x0a, 0x00, 0x00, 0x00, 0x00}; + unsigned char header_slave[5] = {0xaa, 0x00, 0x00, 0x00, 0x00}; + + Disable_SPI_IRQ(); + + /* CS reset */ + gpio_write(&gpio_pin_CS, 0); + + /* Exchange header */ + for (i = 0; i < 5; i++) + { + tmpreg = spi_master_write(&__spi, header_master[i]); + header_slave[i] = tmpreg; + } + + if (header_slave[0] == 0x02) { + /* SPI is ready */ + if (header_slave[1] >= (Nb_bytes1+Nb_bytes2)) { + /* Buffer is big enough */ + for (i = 0; i < Nb_bytes1; i++) { + read_char = spi_master_write(&__spi, *(data1 + i)); + } + for (i = 0; i < Nb_bytes2; i++) { + read_char = spi_master_write(&__spi, *(data2 + i)); + } + } else { + /* Buffer is too small */ + result = -2; + } + } else { + /* SPI is not ready */ + result = -1; + } + + /* Release CS line */ + gpio_write(&gpio_pin_CS, 1); + + Enable_SPI_IRQ(); + + return result; +} + +/** + * 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 + */ +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); + + while(1){ + if(BlueNRG_SPI_Write((uint8_t *)data1,(uint8_t *)data2, n_bytes1, n_bytes2)==0) break; + if(Timer_Expired(&t)){ + break; + } + } +} + +/** + * @brief Disable SPI IRQ + * @param None + * @retval None + */ +void Disable_SPI_IRQ(void) +{ + gpio_irq_disable(&irq_exti); +} + +/** + * @brief Enable SPI IRQ + * @param None + * @retval None + */ +void Enable_SPI_IRQ(void) +{ + gpio_irq_enable(&irq_exti); +} + +/** + * @brief Clear Pending SPI IRQ + * @param None + * @retval None + */ +void Clear_SPI_IRQ(void) +{ + //Not Used +} + +/** + * @brief Clear EXTI (External Interrupt) line for SPI IRQ + * @param None + * @retval None + */ +void Clear_SPI_EXTI_Flag(void) +{ + //Not Used +} + +/** + * @brief Reset the BlueNRG + * @param None + * @retval None + */ +void BlueNRG_RST(void) +{ + gpio_write(&gpio_pin_RESET, 0); + wait_us(5); + gpio_write(&gpio_pin_RESET, 1); + wait_us(5); +} + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hci/src/hci.c Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,1147 @@ +/******************** (C) COPYRIGHT 2013 STMicroelectronics ******************** +* File Name : bluenrg_hci.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 4-Oct-2013 +* Description : Function for managing HCI interface. Implementation of +* standard 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. +*******************************************************************************/ + +/** + ****************************************************************************** + * @file hci.c + * @author AMS/HESA Application Team + * @brief Function for managing HCI interface. + ****************************************************************************** + * @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 "hal_types.h" +#include "osal.h" +#include "ble_status.h" +#include "hal.h" +#include <hci_internal.h> +#include "gp_timer.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) + +static void enqueue_packet(tHciDataPacket * hciReadPacket); + +tListNode hciReadPktPool; +tListNode hciReadPktRxQueue; +/* pool of hci read packets */ +static tHciDataPacket hciReadPacketBuffer[HCI_READ_PACKET_NUM_MAX]; + +static uint8_t *hci_buffer = NULL; +static volatile uint16_t hci_pckt_len; + +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]); + } +} + +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; + + tHalUint16 collected_payload_len = 0; + tHalUint16 payload_len; + + hci_buffer = hciReadPacket->dataBuff; + + while(hci_pckt_len < HCI_PACKET_SIZE){ + + if(state == WAITING_TYPE) + hci_pckt_len = 0; + + 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; + } + } + 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; + } + } + + if(hci_pckt_len >= HCI_MAX_PACKET_SIZE){ + /* Packet too long for buffer. Reset state machine. */ + state = WAITING_TYPE; + } + + } +} + +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); + } +} + +void HCI_Process(void) +{ + tHciDataPacket * hciReadPacket = NULL; + + Disable_SPI_IRQ(); + tHalBool 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); + } + Enable_SPI_IRQ(); +} + +void hci_write(const void* data1, const void* data2, uint32_t n_bytes1, uint32_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); +} + +int 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); + + return 0; +} + +static tHalBool new_packet; + +void new_hci_event(void *pckt, tHalUint16 len) +{ + Disable_SPI_IRQ(); /* Must be re-enabled after packet processing. */ + + new_packet = TRUE; +} + +/* 'to' is timeout in system clock ticks. */ +int hci_send_req(struct hci_request *r) +{ + tHalUint8 *ptr; + tHalUint16 opcode = htobs(cmd_opcode_pack(r->ogf, r->ocf)); + hci_event_pckt *event_pckt; + hci_uart_pckt *hci_hdr; + int try; + int to = DEFAULT_TIMEOUT; + + new_packet = FALSE; + hci_set_packet_complete_callback(new_hci_event); + if (hci_send_cmd(r->ogf, r->ocf, r->clen, r->cparam) < 0) + goto failed; + + 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; + + if (to > 0) { + struct timer t; + + Timer_Set(&t, to); + + while(1){ + if(Timer_Expired(&t)){ + goto failed; + } + if(new_packet){ + break; + } + } + } + + hci_hdr = (void *)hci_buffer; + if(hci_hdr->type != HCI_EVENT_PKT){ + new_packet = FALSE; + Enable_SPI_IRQ(); + 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; + Enable_SPI_IRQ(); + + } + +failed: + hci_set_packet_complete_callback(NULL); + Enable_SPI_IRQ(); + return -1; + +done: + hci_set_packet_complete_callback(NULL); + Enable_SPI_IRQ(); + return 0; +} + +int hci_reset() +{ + struct hci_request rq; + tHalUint8 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) < 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) < 0) + return -1; + + if (status) { + return -1; + } + + return 0; +} + +int hci_le_read_local_version(/* TODO: insert parameters */) +{ + 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) < 0) + return -1; + + if (resp.status) { + return -1; + } + + 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) < 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, 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) < 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) < 0) + return -1; + + if (status) { + return -1; + } + + return 0; +} + +int hci_le_set_advertise_enable(tHalUint8 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) < 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) < 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) < 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) < 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) < 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) < 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) < 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) < 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) < 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) < 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) < 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) < 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) < 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) < 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) < 0){ + return -1; + } + + if (resp.status) { + return -1; + } + + *conn_handle = resp.handle; + *tx_level = resp.handle; + + 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) < 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) < 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) < 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) < 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) < 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) < 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) < 0){ + return -1; + } + + if (resp.status) { + return -1; + } + + *num_pkts = resp.num_pkts; + + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/inc/bluenrg_shield_bsp.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,28 @@ + +#ifndef __BLUENRG_SHIELD_BRP_H_ +#define __BLUENRG_SHIELD_BRP_H_ + +/* Includes ------------------------------------------------------------------*/ +#include <stdint.h> +#include "gp_timer.h" + +// SPI Instance +#define BNRG_SPI_INSTANCE 0x1234 //((uint32_t)(0x40013000)) //Peripheral base Address of SPI1 + +/* Exported functions --------------------------------------------------------*/ +void BNRG_SPI_Init(void); +void BlueNRG_RST(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 Hal_Write_Serial(const void* data1, const void* data2, int32_t n_bytes1, int32_t n_bytes2); +void Enable_SPI_IRQ(void); +void Disable_SPI_IRQ(void); +void Clear_SPI_IRQ(void); +void Clear_SPI_EXTI_Flag(void); + +#endif //_BLUENRG_SHIELD_BRP_H_ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/inc/clock.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,56 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : clock.h +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* 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> +#include <stdint.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(int i); + + +#endif /* __CLOCK_H__ */ + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/inc/compiler.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,31 @@ +/******************** (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. +*******************************************************************************/ + +#ifdef __ICCARM__ +#ifndef PACKED + #define PACKED +#endif +#endif + +#ifdef __GNUC__ +#ifndef __packed + #define __packed __attribute__((__packed__)) +#endif +#ifndef PACKED + #define PACKED __attribute__((packed)) +#endif +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/inc/debug.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,14 @@ +/****************************************************************************** + * 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/platform/inc/gp_timer.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,94 @@ +/******************** (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" + +/** + * 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 +}; + + +/** + * 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); + +#endif /* __GP_TIMER_H__ */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/inc/list.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,52 @@ +/******************** (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_ + +#include <stdbool.h> +#include <stddef.h> + +typedef struct _tListNode { + struct _tListNode * next; + struct _tListNode * prev; +}tListNode, *pListNode; + +void list_init_head (tListNode * listHead); + +bool 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/platform/inc/osal.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,71 @@ +/******************** (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,tHalUint 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, tHalInt value,tHalUint size); + + +#endif /* __OSAL_H__ */ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/src/clock.c Fri Dec 19 18:56:07 2014 +0000 @@ -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(int i) +{ + wait_ms(i); +} +/*---------------------------------------------------------------------------*/ + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/src/gp_timer.c Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,138 @@ +/* + * 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(); +} +/*---------------------------------------------------------------------------*/ + +/** @} */ + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/src/list.c Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,121 @@ +/******************** (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; +} + +bool 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/platform/src/osal.c Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,46 @@ +/******************** (C) COPYRIGHT 2012 STMicroelectronics ******************** +* File Name : osal.c +* Author : AMS - HEA&RF BU +* Version : V1.0.0 +* Date : 19-July-2012 +* Description : Implementation of OS abstraction layer functions used by +* the 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. +*******************************************************************************/ + +/****************************************************************************** + * Includes + *****************************************************************************/ +#include <string.h> +#include <osal.h> + +/** + * Osal_MemCpy + * + */ + +void* Osal_MemCpy(void *dest,const void *src,tHalUint size) +{ + return(memcpy(dest,src,size)); +} + +/** + * Osal_MemSet + * + */ + +void* Osal_MemSet(void *ptr, tHalInt value,tHalUint size) +{ + return(memset(ptr,value,size)); +} + +/****************************************************************************** + * local Functions + *****************************************************************************/ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utils/inc/Payload.h Fri Dec 19 18:56:07 2014 +0000 @@ -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__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utils/inc/Utils.h Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,55 @@ +/* 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 "hal_types.h" +#include "mbed.h" + +// utility functions + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#define NEED_CONSOLE_OUTPUT 1 /* 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] = (tHalUint8) (val) ) , \ + ((buf)[1] = (tHalUint8) (val>>8) ) ) + +#define STORE_LE_32(buf, val) ( ((buf)[0] = (tHalUint8) (val) ) , \ + ((buf)[1] = (tHalUint8) (val>>8) ) , \ + ((buf)[2] = (tHalUint8) (val>>16) ) , \ + ((buf)[3] = (tHalUint8) (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__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utils/src/Payload.cpp Fri Dec 19 18:56:07 2014 +0000 @@ -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; +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/utils/src/Utils.cpp Fri Dec 19 18:56:07 2014 +0000 @@ -0,0 +1,129 @@ +/* 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; +}