HW layer for the Nucleo board, it only work with old BLE_API
Dependents: Hello_BLE F446RE-BLE
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);