static uint16 GetSupported128BitUUIDServiceList(uint8 *p_service_uuid_ad_128) { uint16 i = 0; /* Add 16-bit UUID for Standard HID service */ p_service_uuid_ad_128[i++] = AD_TYPE_SERVICE_UUID_128BIT_LIST; p_service_uuid_ad_128[i++] = LE8_L(HID_SERV_UUID_7); p_service_uuid_ad_128[i++] = LE8_H(HID_SERV_UUID_7); p_service_uuid_ad_128[i++] = LE8_L(HID_SERV_UUID_6); p_service_uuid_ad_128[i++] = LE8_H(HID_SERV_UUID_6); p_service_uuid_ad_128[i++] = LE8_L(HID_SERV_UUID_5); p_service_uuid_ad_128[i++] = LE8_H(HID_SERV_UUID_5); p_service_uuid_ad_128[i++] = LE8_L(HID_SERV_UUID_4); p_service_uuid_ad_128[i++] = LE8_H(HID_SERV_UUID_4); p_service_uuid_ad_128[i++] = LE8_L(HID_SERV_UUID_3); p_service_uuid_ad_128[i++] = LE8_H(HID_SERV_UUID_3); p_service_uuid_ad_128[i++] = LE8_L(HID_SERV_UUID_2); p_service_uuid_ad_128[i++] = LE8_H(HID_SERV_UUID_2); p_service_uuid_ad_128[i++] = LE8_L(HID_SERV_UUID_1); p_service_uuid_ad_128[i++] = LE8_H(HID_SERV_UUID_1); p_service_uuid_ad_128[i++] = LE8_L(HID_SERV_UUID_0); p_service_uuid_ad_128[i++] = LE8_H(HID_SERV_UUID_0); return (i); }
static uint16 GetSupported16BitUUIDServiceList(uint8 *p_service_uuid_ad) { uint8 i = 0; /* Add 16-bit UUID for Standard HID service */ p_service_uuid_ad[i++] = AD_TYPE_SERVICE_UUID_16BIT_LIST; p_service_uuid_ad[i++] = LE8_L(HID_SERVICE_UUID); p_service_uuid_ad[i++] = LE8_H(HID_SERVICE_UUID); return ((uint16)i); }
/*----------------------------------------------------------------------------* * NAME * GetSupported16BitUUIDServiceList * * DESCRIPTION * This function prepares the list of supported 16-bit service UUIDs to be * added to Advertisement data. It also adds the relevant AD Type to the * starting of AD array. * * RETURNS * Return the size AD Service UUID data. * *---------------------------------------------------------------------------*/ extern uint16 GetSupported16BitUUIDServiceList(uint8 *p_service_uuid_ad) { uint8 i = 0; /* Add 16-bit UUID for supported main service */ p_service_uuid_ad[i++] = AD_TYPE_SERVICE_UUID_16BIT_LIST; p_service_uuid_ad[i++] = LE8_L(MESH_CONTROL_SERVICE_UUID); p_service_uuid_ad[i++] = LE8_H(MESH_CONTROL_SERVICE_UUID); return ((uint16)i); }
static void gattSetAdvertParams(bool fast_connection, gap_mode_connect connect_mode) { uint8 advert_data[MAX_ADV_DATA_LEN]; uint16 length; uint32 adv_interval_min = RP_ADVERTISING_INTERVAL_MIN; uint32 adv_interval_max = RP_ADVERTISING_INTERVAL_MAX; int8 tx_power_level; /* Unsigned value */ gap_mode_discover discover_mode = gap_mode_discover_limited; TYPED_BD_ADDR_T temp_addr; /* A variable to keep track of the data added to AdvData. The limit is * MAX_ADV_DATA_LEN. GAP layer will add AD Flags to AdvData which is 3 * bytes. Refer BT Spec 4.0, Vol 3, Part C, Sec 11.1.3. */ uint16 length_added_to_adv = 3; uint16 length_added_to_scan = 0; /* Tx power level value prefixed with 'Tx Power' AD Type */ uint8 device_tx_power[TX_POWER_VALUE_LENGTH] = { AD_TYPE_TX_POWER}; uint8 device_appearance[ATTR_LEN_DEVICE_APPEARANCE + 1] = { AD_TYPE_APPEARANCE, LE8_L(APPEARANCE_GENERAL_HID_VALUE), LE8_H(APPEARANCE_GENERAL_HID_VALUE) }; /* If privacy is enabled, reconnection address will be used as Initiator's * address for directed advertisements. Otherwise, the bonded host address * shall be used as Initiator's address. */ #ifdef __GAP_PRIVACY_SUPPORT__ temp_addr.type = ls_addr_type_random; MemCopy(&temp_addr.addr, GapGetReconnectionAddress(), sizeof(BD_ADDR_T)); #else /* __GAP_PRIVACY_SUPPORT__ */ temp_addr.type = ls_addr_type_public; MemCopy(&temp_addr.addr, &g_btcar_data.bonded_bd_addr.addr, sizeof(BD_ADDR_T)); #endif /* ! __GAP_PRIVACY_SUPPORT__ */ if(fast_connection) { adv_interval_min = FC_ADVERTISING_INTERVAL_MIN; adv_interval_max = FC_ADVERTISING_INTERVAL_MAX; } if(g_btcar_data.bonded) { /* As the device is bonded, we don't want it to be discoverable any * more */ discover_mode = gap_mode_discover_no; } if((GapSetMode(gap_role_peripheral, discover_mode, connect_mode, gap_mode_bond_yes, gap_mode_security_unauthenticate) != ls_err_none) || (connect_mode == gap_mode_connect_directed && GapSetAdvAddress(&temp_addr) != ls_err_none) || /* Advertisement interval will be ignored for directed advertisement */ (GapSetAdvInterval(adv_interval_min, adv_interval_max) != ls_err_none)) { ReportPanic(app_panic_set_advert_params); return; } /* Reset existing advertising data as application is again going to add * data for undirected advertisements. */ if(LsStoreAdvScanData(0, NULL, ad_src_advertise) != ls_err_none) { ReportPanic(app_panic_set_advert_data); return; } /* Reset existing scan response data as application is again going to add * data for undirected advertisements. */ if(LsStoreAdvScanData(0, NULL, ad_src_scan_rsp) != ls_err_none) { ReportPanic(app_panic_set_scan_rsp_data); return; } /* Add to advData only if undirected advertisements are to be done. */ if(connect_mode == gap_mode_connect_undirected) { /* Set up the advertising data. The GAP layer will automatically add the * AD Flags field so all we need to do here is add 16-bit supported * services UUID and Complete Local Name type. Applications are free to * add any other AD types based upon the profile requirements and * subject to the maximum AD size of 31 octets. */ /* Add 16-bit UUID list of the services supported by the device */ length = GetSupported16BitUUIDServiceList(advert_data); /* Before adding data to the ADV_IND, increment 'lengthAddedToAdv' to * keep track of the total number of bytes added to ADV_IND. At the end * while adding the device name to the ADV_IND, this can be used to * verify whether the complete name can fit into the AdvData adhering to * the limit of 31 octets. In addition to the above populated fields, a * 'length' field will also be added to AdvData by GAP layer. Refer * BT 4.0 spec, Vol 3, Part C, Figure 11.1. */ length_added_to_adv += (length + 1); if (LsStoreAdvScanData(length, advert_data, ad_src_advertise) != ls_err_none) { ReportPanic(app_panic_set_advert_data); return; } length_added_to_adv += (sizeof(device_appearance) + 1); /* Add device appearance as advertisement data */ if (LsStoreAdvScanData(sizeof(device_appearance), device_appearance, ad_src_advertise) != ls_err_none) { ReportPanic(app_panic_set_advert_data); return; } /* If 128-bit proprietary service UUID is added to the advData, there * will be no space left for any more data. So don't add the * TxPowerLevel to the advData. */ /* Read tx power of the chip */ if(LsReadTransmitPowerLevel(&tx_power_level) != ls_err_none) { /* Readin tx power failed */ ReportPanic(app_panic_read_tx_pwr_level); } /* Add the read tx power level to g_device_tx_power * Tx power level value is of 1 byte */ device_tx_power[TX_POWER_VALUE_LENGTH - 1] = (uint8 )tx_power_level; length_added_to_scan += TX_POWER_VALUE_LENGTH + 1; /* Add tx power value of device to the scan response data */ if (LsStoreAdvScanData(TX_POWER_VALUE_LENGTH, device_tx_power, ad_src_scan_rsp) != ls_err_none) { ReportPanic(app_panic_set_scan_rsp_data); return; } addDeviceNameToAdvData(length_added_to_adv, length_added_to_scan); } }
/*----------------------------------------------------------------------------* * NAME * gattSetAdvertParams * * DESCRIPTION * This function is used to set advertisement parameters * * RETURNS * Nothing. * *---------------------------------------------------------------------------*/ static void gattSetAdvertParams(bool fast_connection) { uint8 advert_data[MAX_ADV_DATA_LEN]; uint16 length; int8 tx_power_level = 0xff; /* Signed value */ /* Tx power level value prefixed with 'Tx Power' AD Type */ uint8 device_tx_power[TX_POWER_VALUE_LENGTH] = { AD_TYPE_TX_POWER }; uint8 device_appearance[ATTR_LEN_DEVICE_APPEARANCE + 1] = { AD_TYPE_APPEARANCE, LE8_L(APPEARANCE_UNKNOWN_VALUE), LE8_H(APPEARANCE_UNKNOWN_VALUE) }; /* A variable to keep track of the data added to AdvData. The limit is * MAX_ADV_DATA_LEN. GAP layer will add AD Flags to AdvData which * is 3 bytes. Refer BT Spec 4.0, Vol 3, Part C, Sec 11.1.3. */ uint16 length_added_to_adv = 3; /* Add UUID list of the services supported by the device */ length = GetSupported16BitUUIDServiceList(advert_data); /* One added for Length field, which will be added to Adv Data by GAP * layer */ length_added_to_adv += (length + 1); if (CsrMeshStoreUserAdvData(length, advert_data, ad_src_advertise) != TRUE) { ReportPanic(app_panic_set_advert_data); } /* One added for Length field, which will be added to Adv Data by GAP * layer */ length_added_to_adv += (sizeof(device_appearance) + 1); /* Add device appearance to the advertisements */ if (CsrMeshStoreUserAdvData(ATTR_LEN_DEVICE_APPEARANCE + 1, device_appearance, ad_src_advertise) != TRUE) { ReportPanic(app_panic_set_advert_data); } /* Read tx power of the chip */ if(LsReadTransmitPowerLevel(&tx_power_level) != ls_err_none) { /* Reading tx power failed */ ReportPanic(app_panic_read_tx_pwr_level); } /* Add the read tx power level to device_tx_power * Tx power level value is of 1 byte */ device_tx_power[TX_POWER_VALUE_LENGTH - 1] = (uint8 )tx_power_level; /* One added for Length field, which will be added to Adv Data by GAP * layer */ length_added_to_adv += (TX_POWER_VALUE_LENGTH + 1); /* Add tx power value of device to the advertising data */ if (CsrMeshStoreUserAdvData(TX_POWER_VALUE_LENGTH, device_tx_power, ad_src_advertise) != TRUE) { ReportPanic(app_panic_set_advert_data); } addDeviceNameToAdvData(length_added_to_adv, 0); }
static void gattSetAdvertParams(bool fast_connection) { uint8 advert_data[MAX_ADV_DATA_LEN]; uint16 length; uint32 adv_interval_min = RP_ADVERTISING_INTERVAL_MIN; uint32 adv_interval_max = RP_ADVERTISING_INTERVAL_MAX; int8 tx_power_level = 0xff; /* Signed value */ /* Tx power level value prefixed with 'Tx Power' AD Type */ uint8 device_tx_power[TX_POWER_VALUE_LENGTH] = { AD_TYPE_TX_POWER }; uint8 device_appearance[ATTR_LEN_DEVICE_APPEARANCE + 1] = { AD_TYPE_APPEARANCE, LE8_L(APPEARANCE_HR_SENSOR_VALUE), LE8_H(APPEARANCE_HR_SENSOR_VALUE) }; /* A variable to keep track of the data added to AdvData. The limit is * MAX_ADV_DATA_LEN. GAP layer will add AD Flags to AdvData which * is 3 bytes. Refer BT Spec 4.0, Vol 3, Part C, Sec 11.1.3. */ uint16 length_added_to_adv = 3; if(fast_connection) { adv_interval_min = FC_ADVERTISING_INTERVAL_MIN; adv_interval_max = FC_ADVERTISING_INTERVAL_MAX; } /* In a Public Environment like Gym, there is a requirement for HR Sensor * to communicate with fitness machines even without having a bond. So, * for HR Sensor application we will not enforce bonding by calling SM * Slave Security Request. Though, we will set HR Sensor's security * capabilities to 'gap_mode_bond_yes' so that we accept bonding if the * collector (like Watch or Cell Phone) would like to bond. */ if((GapSetMode(gap_role_peripheral, gap_mode_discover_general, gap_mode_connect_undirected, gap_mode_bond_yes, gap_mode_security_unauthenticate) != ls_err_none) || (GapSetAdvInterval(adv_interval_min, adv_interval_max) != ls_err_none)) { ReportPanic(app_panic_set_advert_params); } /* Add bonded device to white list.*/ if((g_hr_data.enable_white_list == TRUE)) { /* Initial case when advertisements are started for Bonded host for * 10 seconds. White list is configured with the Bonded host address */ if(LsAddWhiteListDevice(&g_hr_data.bonded_bd_addr)!= ls_err_none) { ReportPanic(app_panic_add_whitelist); } } /* Reset existing advertising data */ if(LsStoreAdvScanData(0, NULL, ad_src_advertise) != ls_err_none) { ReportPanic(app_panic_set_advert_data); } /* Reset existing scan response data */ if(LsStoreAdvScanData(0, NULL, ad_src_scan_rsp) != ls_err_none) { ReportPanic(app_panic_set_scan_rsp_data); } /* Setup ADVERTISEMENT DATA */ /* Add UUID list of the services supported by the device */ length = GetSupported16BitUUIDServiceList(advert_data); /* One added for Length field, which will be added to Adv Data by GAP * layer */ length_added_to_adv += (length + 1); if (LsStoreAdvScanData(length, advert_data, ad_src_advertise) != ls_err_none) { ReportPanic(app_panic_set_advert_data); } /* One added for Length field, which will be added to Adv Data by GAP * layer */ length_added_to_adv += (sizeof(device_appearance) + 1); /* Add device appearance to the advertisements */ if (LsStoreAdvScanData(ATTR_LEN_DEVICE_APPEARANCE + 1, device_appearance, ad_src_advertise) != ls_err_none) { ReportPanic(app_panic_set_advert_data); } /* Read tx power of the chip */ if(LsReadTransmitPowerLevel(&tx_power_level) != ls_err_none) { /* Reading tx power failed */ ReportPanic(app_panic_read_tx_pwr_level); } /* Add the read tx power level to device_tx_power * Tx power level value is of 1 byte */ device_tx_power[TX_POWER_VALUE_LENGTH - 1] = (uint8 )tx_power_level; /* One added for Length field, which will be added to Adv Data by GAP * layer */ length_added_to_adv += (TX_POWER_VALUE_LENGTH + 1); /* Add tx power value of device to the advertising data */ if (LsStoreAdvScanData(TX_POWER_VALUE_LENGTH, device_tx_power, ad_src_advertise) != ls_err_none) { ReportPanic(app_panic_set_advert_data); } addDeviceNameToAdvData(length_added_to_adv, 0); }