Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of X_NUCLEO_IDB0XA1 by
Diff: BlueNRGGap.cpp
- Revision:
- 58:027c65a54097
- Parent:
- 57:986ba1f56630
- Child:
- 59:68e45913b2c4
--- a/BlueNRGGap.cpp Wed Oct 01 11:47:54 2014 +0000 +++ b/BlueNRGGap.cpp Tue Oct 07 10:13:02 2014 +0000 @@ -1,18 +1,18 @@ /* 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. - */ +* 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" @@ -84,116 +84,105 @@ 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())); - - #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\r"); - return BLE_ERROR_PARAM_OUT_OF_RANGE; // no other suitable error code is available - DEBUG("error occurred while adding adv data for Adv type 0x%x, errCode = 0x%x\n", *loadPtr.getUnitAtIndex(index).getAdTypePtr(), err); - //return BLE_ERROR_PARAM_OUT_OF_RANGE; // no other suitable error code is available - } - #endif - //UnitPayload unitLoad = load.getPayLoadAtIndex(index); + 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 */ + 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; - } + 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 */ + 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) */ + 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) */ + 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 */ + 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 */ + case GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS: /**< Complete list of 128-bit Service IDs */ break; - case GapAdvertisingData::SHORTENED_LOCAL_NAME: /**< Shortened Local Name */ + 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(); - //for(int i=0; i<local_name_length; i++) DEBUG("\n%c", local_name[i]); - /*aci_gatt_update_char_value(g_gap_service_handle, + 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(); + //for(int i=0; i<local_name_length; i++) DEBUG("\n%c", local_name[i]); + /*aci_gatt_update_char_value(g_gap_service_handle, g_device_name_char_handle, 0, local_name_length, (tHalUint8 *)local_name);*/ - //COMPLETE_LOCAL_NAME is only advertising device name. Gatt Device Name is not the same.(Must be set right after GAP/GATT init?) + //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; + + 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 */ + 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::SLAVE_CONNECTION_INTERVAL_RANGE: /**< Slave :Connection Interval Range */ + case GapAdvertisingData::DEVICE_ID: /**< Device ID */ + break; + case GapAdvertisingData::SLAVE_CONNECTION_INTERVAL_RANGE: /**< Slave :Connection Interval Range */ break; - case GapAdvertisingData::SERVICE_DATA: /**< Service Data */ + case GapAdvertisingData::SERVICE_DATA: /**< Service Data */ break; - case GapAdvertisingData::APPEARANCE: - /* + 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); + 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::MANUFACTURER_SPECIFIC_DATA: /**< Manufacturer Specific Data */ + 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; + return BLE_ERROR_NONE; } /**************************************************************************/ @@ -227,12 +216,12 @@ 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)) { + (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)) { + (params.getInterval() > GAP_ADV_PARAMS_INTERVAL_MAX)) { return BLE_ERROR_PARAM_OUT_OF_RANGE; } } @@ -246,59 +235,59 @@ /* Check timeout for other advertising types */ if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && - (params.getTimeout() > GAP_ADV_PARAMS_TIMEOUT_MAX)) { + (params.getTimeout() > GAP_ADV_PARAMS_TIMEOUT_MAX)) { return BLE_ERROR_PARAM_OUT_OF_RANGE; } - tBleStatus ret; - - //const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; - //const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,device_name[27],device_name[28],device_name[29],device_name[30], device_name[31], - // device_name[32], device_name[33], device_name[34], device_name[35], device_name[36]}; - + tBleStatus ret; + + //const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,'B','l','u','e','N','R','G'}; + //const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,device_name[27],device_name[28],device_name[29],device_name[30], device_name[31], + // device_name[32], device_name[33], device_name[34], device_name[35], device_name[36]}; + + - - //const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,device_name[27],device_name[28]}; - 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, + //const char local_name[] = {AD_TYPE_COMPLETE_LOCAL_NAME,device_name[27],device_name[28]}; + 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*/ + /*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 <hdd> It seems there is some problem with RANDOM_ADDRESS. <problem_desc> When RANDOM_ADDRESS is selected device name is not being handled properly, i.e. wrong device name is seen by android app </problem_desc> - 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; - + 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; } @@ -323,17 +312,17 @@ 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; + //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; @@ -363,14 +352,14 @@ 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; + 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; @@ -417,18 +406,18 @@ 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); + btle_init(isSetAddress); //if (ret==BLE_STATUS_SUCCESS) return BLE_ERROR_NONE; @@ -559,16 +548,16 @@ //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); - + 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; } @@ -600,7 +589,7 @@ int ret; if(DeviceName==NULL) - return BLE_ERROR_PARAM_OUT_OF_RANGE; + return BLE_ERROR_PARAM_OUT_OF_RANGE; strcpy((char*)deviceName, (const char*)DeviceName); //DEBUG("GetDeviceName=%s\n\r", deviceName);