//This function configures the Generic access Profile //GAP is a service that must be implemented on all BLE devices //These are some basic values that other devices can request //Some of these values might be writable over the air //The current characteristics are // Device name // Appearance // Peripheral Preferred Connection Parameters void GAPController::bleConfigureGAP(){ u32 err = 0; //Set up an open link write permission //There are multiple security modes defined in the BLE spec //Use these macros: http://developer.nordicsemi.com/nRF51_SDK/doc/7.1.0/s110/html/a00813.html ble_gap_conn_sec_mode_t secPermissionOpen; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&secPermissionOpen); //Set the GAP device name err = sd_ble_gap_device_name_set(&secPermissionOpen, (u8*)DEVICE_NAME, strlen(DEVICE_NAME)); APP_ERROR_CHECK(err); //Set the appearance of the device as defined in http://developer.nordicsemi.com/nRF51_SDK/doc/7.1.0/s110/html/a00837.html err = sd_ble_gap_appearance_set(BLE_APPEARANCE_GENERIC_COMPUTER); APP_ERROR_CHECK(err); //Set gap peripheral preferred connection parameters (not used by the mesh implementation) ble_gap_conn_params_t gapConnectionParams; memset(&gapConnectionParams, 0, sizeof(gapConnectionParams)); gapConnectionParams.min_conn_interval = Config->meshMinConnectionInterval; gapConnectionParams.max_conn_interval = Config->meshMaxConnectionInterval; gapConnectionParams.slave_latency = Config->meshPeripheralSlaveLatency; gapConnectionParams.conn_sup_timeout = Config->meshConnectionSupervisionTimeout; err = sd_ble_gap_ppcp_set(&gapConnectionParams); APP_ERROR_CHECK(err); }
/**@brief Function for the GAP initialization. * * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the * device including the device name, appearance, and the preferred connection parameters. */ static void gap_params_init(void) { uint32_t err_code; ble_gap_conn_params_t gap_conn_params; ble_gap_conn_sec_mode_t sec_mode; ble_gap_addr_t device_mac; #ifdef RANDOM_MAC device_mac.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE; err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_AUTO, &device_mac); #else uint8_t mac_addr[] = {0x00,0x19,0x25,0x39,0x54,0x95}; device_mac.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC; memcpy(device_mac.addr, mac_addr,6); err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &device_mac); APP_ERROR_CHECK(err_code); #endif BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)DEVICE_NAME, strlen(DEVICE_NAME)); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_GENERIC_TAG); APP_ERROR_CHECK(err_code); memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_tx_power_set(4); APP_ERROR_CHECK(err_code); }
// gap name/appearance/connection parameters static void gap_params_init (void) { uint32_t err_code; ble_gap_conn_sec_mode_t sec_mode; ble_gap_conn_params_t gap_conn_params; // Full strength signal sd_ble_gap_tx_power_set(4); // Let anyone connect and set the name given the platform BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)"BEES", strlen("BEES")); //(const uint8_t *)DEVICE_NAME, strlen(DEVICE_NAME)); APP_ERROR_CHECK(err_code); // Not sure what this is useful for, but why not set it err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_GENERIC_COMPUTER); APP_ERROR_CHECK(err_code); // Specify parameters for a connection memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code); }
//////////////////////////////////////////////////////////////////////////////// // // GAP Initialization static void gap_params_init(void) { // Create the scan response name memset(_scanResponse, 0, sizeof(_scanResponse)); memcpy(_scanResponse, SCAN_RESPONSE_BASE, strlen(SCAN_RESPONSE_BASE)); memcpy(_scanResponse + strlen(SCAN_RESPONSE_BASE), STR(BUILD_NUM), 4); uint32_t err_code; ble_gap_conn_params_t gap_conn_params; ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)_scanResponse, strlen(_scanResponse)); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_UNKNOWN); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_tx_power_set(4); APP_ERROR_CHECK(err_code); memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code); }
/**@brief Function for the GAP initialization. * * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the * device including the device name, appearance, and the preferred connection parameters. */ static void gap_params_init(void) { uint32_t err_code; ble_gap_conn_params_t gap_conn_params; ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)DEVICE_NAME, strlen(DEVICE_NAME)); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_GENERIC_KEYRING); APP_ERROR_CHECK(err_code); memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_tx_power_set(TX_POWER_LEVEL); APP_ERROR_CHECK(err_code); }
*/ static void gap_params_init(void) { uint32_t err_code; char deviceaddr_name[16]; ble_gap_conn_params_t gap_conn_params; ble_gap_conn_sec_mode_t sec_mode; snprintf(&deviceaddr_name,14,"%s-%.4X%.2X\0", DEVICE_NAME, NRF_FICR->DEVICEADDR[0], NRF_FICR->DEVICEADDR[1]); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)deviceaddr_name, strlen(deviceaddr_name)); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_CYCLING_CADENCE_SENSOR); APP_ERROR_CHECK(err_code); memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code);
/**@brief Function for the GAP initialization. * * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the * device including the device name, appearance, and the preferred connection parameters. */ static void gap_params_init(void) { uint32_t err_code; ble_gap_conn_params_t gap_conn_params; ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)DEVICE_NAME, strlen(DEVICE_NAME)); APP_ERROR_CHECK(err_code); /* YOUR_JOB: Use an appearance value matching the application's use case. err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_); APP_ERROR_CHECK(err_code); */ memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code); // Set appearence sd_ble_gap_appearance_set(0); APP_ERROR_CHECK(err_code);// Check for errors }
ble_error_t nRF5xGap::setAppearance(GapAdvertisingData::Appearance appearance) { if (sd_ble_gap_appearance_set(appearance) == NRF_SUCCESS) { return BLE_ERROR_NONE; } else { return BLE_ERROR_PARAM_OUT_OF_RANGE; } }
static void bluetooth_init(void) { uint32_t err_code; ble_gap_conn_params_t gppcp; ble_advdata_t advdata; ble_gap_conn_sec_mode_t sec_mode; uint8_t flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE; // Initialise SoftDevice, and enable BLE event interrupt. BLE_STACK_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, BLE_L2CAP_MTU_DEF, ble_evt_dispatch, false); // Set GAP parameters BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, DEVICE_NAME, strlen(DEVICE_NAME)); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_GENERIC_TAG); APP_ERROR_CHECK(err_code); memset(&gppcp, 0, sizeof(gppcp)); gppcp.min_conn_interval = MIN_CONN_INTERVAL; gppcp.max_conn_interval = MAX_CONN_INTERVAL; gppcp.slave_latency = SLAVE_LATENCY; gppcp.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gppcp); APP_ERROR_CHECK(err_code); // Build and set advertising data. memset(&advdata, 0, sizeof(advdata)); advdata.name_type = BLE_ADVDATA_FULL_NAME; advdata.include_appearance = true; advdata.flags.size = sizeof(flags); advdata.flags.p_data = &flags; err_code = ble_advdata_set(&advdata, NULL); APP_ERROR_CHECK(err_code); // Initialise advertising parameters (used when starting advertising). memset(&m_adv_params, 0, sizeof(m_adv_params)); m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; m_adv_params.p_peer_addr = NULL; // Undirected advertisement. m_adv_params.fp = BLE_GAP_ADV_FP_ANY; m_adv_params.interval = APP_ADV_INTERVAL; m_adv_params.timeout = APP_ADV_TIMEOUT_IN_SECONDS; // Start advertising when entering main loop. m_start_adv_flag = true; }
/**@brief Function for decoding a command packet with RPC_SD_BLE_GAP_APPEARANCE_SET opcode. * * This function will decode the command, call the BLE Stack API, and also send command response * to the peer through the the transport layer. * * @param[in] p_command The encoded structure that needs to be decoded and passed on * to the BLE Stack API. * @param[in] command_len The length of the encoded command read from transport layer. * * @retval NRF_SUCCESS If the decoding of the command was successful, the SoftDevice * API was called, and the command response was sent to peer, * otherwise an error code. * @retval NRF_ERROR_INVALID_LENGTH If the content length of the packet is not conforming to the * codec specification. */ static uint32_t gap_appearance_set_handle(uint8_t * p_command, uint32_t command_len) { uint16_t appearance = uint16_decode(&(p_command[0])); RPC_DECODER_LENGTH_CHECK(command_len, sizeof(appearance), SD_BLE_GAP_APPEARANCE_SET); uint32_t err_code = sd_ble_gap_appearance_set(appearance); return ble_rpc_cmd_resp_send(SD_BLE_GAP_APPEARANCE_SET, err_code); }
/**@brief Function for the GAP initialization. * * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the * device including the device name, appearance, and the preferred connection parameters. */ static void gap_params_init(void) { uint32_t err_code; ble_gap_conn_params_t gap_conn_params; ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)DEVICE_NAME, strlen(DEVICE_NAME)); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_UNKNOWN); APP_ERROR_CHECK(err_code); memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_tx_power_set(INITIAL_TX_POWER_LEVEL); APP_ERROR_CHECK(err_code); ble_opt_t ble_opt; uint8_t passkey[6] = { 0 }; // Fetch pin from UICR uint8_t val = (*((uint32_t *)UICR_PIN_ADDRESS)) & 0x000000FF; passkey[0] = (val == 0xFF) ? 0x31 : val; val = ((*((uint32_t *)UICR_PIN_ADDRESS)) & 0x0000FF00) >> 8; passkey[1] = (val == 0xFF) ? 0x32 : val; val = ((*((uint32_t *)UICR_PIN_ADDRESS)) & 0x00FF0000) >> 16; passkey[2] = (val == 0xFF) ? 0x33 : val; val = ((*((uint32_t *)UICR_PIN_ADDRESS)) & 0xFF000000) >> 24; passkey[3] = (val == 0xFF) ? 0x34 : val; val = (*((uint32_t *)(UICR_PIN_ADDRESS+4))) & 0x000000FF; passkey[4] = (val == 0xFF) ? 0x35 : val; val = ((*((uint32_t *)(UICR_PIN_ADDRESS+4))) & 0x0000FF00) >> 8; passkey[5] = (val == 0xFF) ? 0x36 : val; ble_opt.gap_opt.passkey.p_passkey = passkey; err_code = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &ble_opt); APP_ERROR_CHECK(err_code); }
error_t btle_gap_init(void) { ble_gap_conn_params_t gap_conn_params = {0}; gap_conn_params.min_conn_interval = msec_to_1_25msec( CFG_GAP_CONNECTION_MIN_INTERVAL_MS); // in 1.25ms units gap_conn_params.max_conn_interval = msec_to_1_25msec( CFG_GAP_CONNECTION_MAX_INTERVAL_MS); // in 1.25ms unit gap_conn_params.slave_latency = CFG_GAP_CONNECTION_SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CFG_GAP_CONNECTION_SUPERVISION_TIMEOUT_MS / 10; // in 10ms unit ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); // no security is needed // ASSERT_STATUS( sd_ble_gap_device_name_set(&sec_mode, //_modify // (const uint8_t *) // CFG_GAP_LOCAL_NAME, // strlen(CFG_GAP_LOCAL_NAME))); // ASSERT_STATUS( sd_ble_gap_appearance_set(CFG_GAP_APPEARANCE)); // ASSERT_STATUS( sd_ble_gap_ppcp_set(&gap_conn_params)); // ASSERT_STATUS( sd_ble_gap_tx_power_set(CFG_BLE_TX_POWER_LEVEL)); nrf_err_check( sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *) CFG_GAP_LOCAL_NAME, strlen(CFG_GAP_LOCAL_NAME)) ); nrf_err_check( sd_ble_gap_appearance_set(CFG_GAP_APPEARANCE) ); nrf_err_check( sd_ble_gap_ppcp_set(&gap_conn_params) ); nrf_err_check( sd_ble_gap_tx_power_set(CFG_BLE_TX_POWER_LEVEL) ); /* Connection Parameters */ enum { FIRST_UPDATE_DELAY = APP_TIMER_TICKS(5000, CFG_TIMER_PRESCALER), NEXT_UPDATE_DELAY = APP_TIMER_TICKS(5000, CFG_TIMER_PRESCALER), MAX_UPDATE_COUNT = 3 }; ble_conn_params_init_t cp_init = {0}; cp_init.p_conn_params = NULL; cp_init.first_conn_params_update_delay = FIRST_UPDATE_DELAY; cp_init.next_conn_params_update_delay = NEXT_UPDATE_DELAY; cp_init.max_conn_params_update_count = MAX_UPDATE_COUNT; cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID; cp_init.disconnect_on_fail = true; cp_init.evt_handler = NULL; cp_init.error_handler = error_callback; //ASSERT_STATUS ( ble_conn_params_init(&cp_init)); //_modify nrf_err_check( ble_conn_params_init(&cp_init) ); return ERROR_NONE; }
static void gap_params_init(void) { uint32_t err_code; ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); //no security needed //set BLE name err_code = sd_ble_gap_device_name_set(&sec_mode,(const uint8_t *)DEVICE_NAME,strlen(DEVICE_NAME)); BLE_ERROR_CHECK(err_code); //set BLE appearance err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_GENERIC_TAG); BLE_ERROR_CHECK(err_code); }
/**@brief Function for the GAP initialization. * * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the * device including the device name, appearance, and the preferred connection parameters. */ static void gap_params_init(void) { uint32_t err_code; ble_gap_conn_params_t gap_conn_params; ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)DEVICE_NAME, strlen(DEVICE_NAME)); if (err_code == NRF_SUCCESS) debug_printf("Device name set!\r\n"); else { debug_printf("Ooops.. Something went wrong with setting the name..\r\n"); APP_ERROR_CHECK(err_code); } err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_UNKNOWN); if (err_code == NRF_SUCCESS) debug_printf("Appearance set!\r\n"); else { debug_printf("Ooops.. Something is wrong with setting the appearrance..\r\n"); APP_ERROR_CHECK(err_code); } memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); if (err_code == NRF_SUCCESS) debug_printf("Connection parameters set!\r\n"); else { debug_printf("Ooops.. Something is wrong with setting connection parameters..\r\n"); APP_ERROR_CHECK(err_code); } sd_ble_gap_tx_power_set(4); }
ble_error_t nRF5xGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse) { /* 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; } /* Check the scan response payload limits */ //if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED)) //{ // /* Check if we're within the upper limit */ // 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; // } //} /* Send advertising data! */ ASSERT_TRUE(ERROR_NONE == sd_ble_gap_adv_data_set(advData.getPayload(), advData.getPayloadLen(), scanResponse.getPayload(), scanResponse.getPayloadLen()), BLE_ERROR_PARAM_OUT_OF_RANGE); /* Make sure the GAP Service appearance value is aligned with the *appearance from GapAdvertisingData */ ASSERT_TRUE(ERROR_NONE == sd_ble_gap_appearance_set(advData.getAppearance()), BLE_ERROR_PARAM_OUT_OF_RANGE); /* ToDo: Perform some checks on the payload, for example the Scan Response can't */ /* contains a flags AD type, etc. */ return BLE_ERROR_NONE; }
static void gap_params_init(void) { uint32_t err_code; ble_gap_conn_params_t gap_conn_params; err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_UNKNOWN); APP_ERROR_CHECK(err_code); memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code); }
/**@brief Function for the GAP initialization. * * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the * device including the device name, appearance, and the preferred connection parameters. */ static void gap_params_init(void) { uint32_t err_code; // Declearing parameter structs. Try to go to the struct definitions to get // more information about what parameters they contain ble_gap_conn_params_t gap_conn_params; // Struct to store GAP connection parameters like max min connection interval etc ble_gap_conn_sec_mode_t sec_mode; // Struct to store security parameters // A simple macro that sets the Security Mode and Level bits in sec_mode // to require no protection (open link) BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); // Store the device name and security mode in the SoftDevice. Our name is defined to "HelloWorld" in the beginning of this file err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)DEVICE_NAME, strlen(DEVICE_NAME)); APP_ERROR_CHECK(err_code);// Check for errors // Always initialize all fields in structs to zero or you might get unexpected behaviour memset(&gap_conn_params, 0, sizeof(gap_conn_params)); // Populate the GAP connection parameter struct gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; // Set GAP Peripheral Preferred Connection Parameters // The device use these prefered values when negotiating connection terms with another device err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code);// Check for errors // Set appearence //sd_ble_gap_appearance_set(BLE_APPEARANCE_HID_MOUSE); sd_ble_gap_appearance_set(0); APP_ERROR_CHECK(err_code);// Check for errors }
/**@brief GAP initialization. * * @details This function shall be used to setup all the necessary GAP (Generic Access Profile) * parameters of the device. It also sets the permissions and appearance. */ static void gap_params_init(void) { uint32_t err_code; ble_gap_conn_params_t gap_conn_params; ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, DEVICE_NAME, strlen(DEVICE_NAME)); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR); APP_ERROR_CHECK(err_code); memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code); }
uint32_t conn_mw_ble_gap_appearance_set(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len) { SER_ASSERT_NOT_NULL(p_rx_buf); SER_ASSERT_NOT_NULL(p_tx_buf); SER_ASSERT_NOT_NULL(p_tx_buf_len); uint16_t appearance; uint32_t err_code = NRF_SUCCESS; uint32_t sd_err_code; err_code = ble_gap_appearance_set_req_dec(p_rx_buf, rx_buf_len, &appearance); SER_ASSERT(err_code == NRF_SUCCESS, err_code); sd_err_code = sd_ble_gap_appearance_set(appearance); err_code = ble_gap_appearance_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); SER_ASSERT(err_code == NRF_SUCCESS, err_code); return err_code; }
/**@brief Function for initializing the Advertising functionality. * * @details Encodes the required advertising data and passes it to the stack. * Also builds a structure to be passed to the stack when starting advertising. */ static void advertising_init(void) { uint32_t err_code; ble_advdata_t advdata; ble_gap_conn_sec_mode_t sec_mode; uint8_t flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE; // Set GAP parameters BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)DEVICE_NAME, strlen(DEVICE_NAME)); APP_ERROR_CHECK(err_code); err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_GENERIC_WATCH); APP_ERROR_CHECK(err_code); // Build and set advertising data memset(&advdata, 0, sizeof (advdata)); advdata.name_type = BLE_ADVDATA_FULL_NAME; advdata.include_appearance = false; advdata.flags = flags; err_code = ble_advdata_set(&advdata, NULL); APP_ERROR_CHECK(err_code); // Initialize advertising parameters (used when starting advertising) memset(&m_adv_params, 0, sizeof (m_adv_params)); m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; m_adv_params.p_peer_addr = NULL; // Undirected advertisement m_adv_params.fp = BLE_GAP_ADV_FP_ANY; m_adv_params.interval = APP_ADV_INTERVAL; m_adv_params.timeout = APP_ADV_TIMEOUT_IN_SECONDS; }
/**@brief GAP initialization. * * @details This function shall be used to setup all the necessary GAP (Generic Access Profile) * parameters of the device. It also sets the permissions and appearance. */ void bleApp_gapParamsInit() { uint32_t err_code; ble_gap_conn_params_t gap_conn_params; ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (uint8_t *)deviceName, strlen(deviceName)); APP_ERROR_CHECK(err_code); /* YOUR_JOB: Use an appearance value matching the application's use case.*/ err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_UNKNOWN); APP_ERROR_CHECK(err_code); memset(&gap_conn_params, 0, sizeof(gap_conn_params)); gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; gap_conn_params.slave_latency = SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code); }
/** * @brief BLEスタック初期化 * * @detail BLE関連の初期化を行う。 * -# SoftDeviceハンドラ初期化 * -# システムイベントハンドラ初期化 * -# BLEスタック有効化 * -# BLEイベントハンドラ設定 * -# デバイス名設定 * -# Appearance設定(GAP_USE_APPEARANCE定義時) * -# PPCP設定 * -# Service初期化 * -# Advertising初期化 * -# Connection初期化 */ static void ble_stack_init(void) { uint32_t err_code; /* BLEスタックの有効化 */ { ble_enable_params_t ble_enable_params; memset(&ble_enable_params, 0, sizeof(ble_enable_params)); ble_enable_params.gatts_enable_params.service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT; err_code = sd_ble_enable(&ble_enable_params); APP_ERROR_CHECK(err_code); } /* デバイス名設定 */ { //デバイス名へのWrite Permission(no protection, open link) ble_gap_conn_sec_mode_t sec_mode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)GAP_DEVICE_NAME, strlen(GAP_DEVICE_NAME)); APP_ERROR_CHECK(err_code); } #ifdef GAP_USE_APPEARANCE /* Appearance設定 */ err_code = sd_ble_gap_appearance_set(GAP_USE_APPEARANCE); APP_ERROR_CHECK(err_code); #endif //GAP_USE_APPEARANCE /* * Peripheral Preferred Connection Parameters(PPCP) * ここで設定しておくと、Connection Parameter Update Reqを送信せずに済むらしい。 */ { ble_gap_conn_params_t gap_conn_params = {0}; gap_conn_params.min_conn_interval = MSEC_TO_UNITS(CONN_MIN_INTERVAL, UNIT_1_25_MS); gap_conn_params.max_conn_interval = MSEC_TO_UNITS(CONN_MAX_INTERVAL, UNIT_1_25_MS); gap_conn_params.slave_latency = CONN_SLAVE_LATENCY; gap_conn_params.conn_sup_timeout = MSEC_TO_UNITS(CONN_SUP_TIMEOUT, UNIT_10_MS); err_code = sd_ble_gap_ppcp_set(&gap_conn_params); APP_ERROR_CHECK(err_code); } /* * Service初期化 */ { ble_ios_init_t ios_init; ios_init.evt_handler_in = svc_ios_handler_in; //ios_init.evt_handler_out = svc_ios_handler_out; ios_init.len_in = 64; ios_init.len_out = 32; ble_ios_init(&m_ios, &ios_init); } /* * Advertising初期化 */ { ble_uuid_t adv_uuids[] = { { IOS_UUID_SERVICE, m_ios.uuid_type } }; ble_advdata_t advdata; ble_advdata_t scanrsp; memset(&advdata, 0, sizeof(advdata)); memset(&scanrsp, 0, sizeof(scanrsp)); /* * ble_advdata_name_type_t (ble_advdata.h) * * BLE_ADVDATA_NO_NAME : デバイス名無し * BLE_ADVDATA_SHORT_NAME : デバイス名あり «Shortened Local Name» * BLE_ADVDATA_FULL_NAME : デバイス名あり «Complete Local Name» * * https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile * https://developer.nordicsemi.com/nRF51_SDK/nRF51_SDK_v7.x.x/doc/7.2.0/s110/html/a01015.html#ga03c5ccf232779001be9786021b1a563b */ advdata.name_type = BLE_ADVDATA_FULL_NAME; /* * Appearanceが含まれるかどうか */ #ifdef GAP_USE_APPEARANCE advdata.include_appearance = true; #else //GAP_USE_APPEARANCE advdata.include_appearance = false; #endif //GAP_USE_APPEARANCE /* * Advertisingフラグの設定 * CSS_v4 : Part A 1.3 FLAGS * https://developer.nordicsemi.com/nRF51_SDK/nRF51_SDK_v7.x.x/doc/7.2.0/s110/html/a00802.html * * BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE = BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED * BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE : LE Limited Discoverable Mode * BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED : BR/EDR not supported */ advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE; //探索時間に制限あり /* SCAN_RSPデータ設定 */ scanrsp.uuids_complete.uuid_cnt = ARRAY_SIZE(adv_uuids); scanrsp.uuids_complete.p_uuids = adv_uuids; err_code = ble_advdata_set(&advdata, &scanrsp); APP_ERROR_CHECK(err_code); } /* * Connection初期化 */ { ble_conn_params_init_t cp_init = {0}; /* APP_TIMER_PRESCALER = 0 */ cp_init.p_conn_params = NULL; cp_init.first_conn_params_update_delay = APP_TIMER_TICKS(CONN_FIRST_PARAMS_UPDATE_DELAY, 0); cp_init.next_conn_params_update_delay = APP_TIMER_TICKS(CONN_NEXT_PARAMS_UPDATE_DELAY, 0); cp_init.max_conn_params_update_count = CONN_MAX_PARAMS_UPDATE_COUNT; cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID; cp_init.disconnect_on_fail = false; cp_init.evt_handler = conn_params_evt_handler; cp_init.error_handler = conn_params_error_handler; err_code = ble_conn_params_init(&cp_init); APP_ERROR_CHECK(err_code); } #ifdef BLE_DFU_APP_SUPPORT /** @snippet [DFU BLE Service initialization] */ { ble_dfu_init_t dfus_init; // Initialize the Device Firmware Update Service. memset(&dfus_init, 0, sizeof(dfus_init)); dfus_init.evt_handler = dfu_app_on_dfu_evt; dfus_init.error_handler = NULL; //service_error_handler - Not used as only the switch from app to DFU mode is required and not full dfu service. dfus_init.evt_handler = dfu_app_on_dfu_evt; dfus_init.revision = DFU_REVISION; err_code = ble_dfu_init(&m_dfus, &dfus_init); APP_ERROR_CHECK(err_code); dfu_app_reset_prepare_set(dfu_reset_prepare); } /** @snippet [DFU BLE Service initialization] */ #endif // BLE_DFU_APP_SUPPORT }
void nRF51822::begin(unsigned char advertisementDataType, unsigned char advertisementDataLength, const unsigned char* advertisementData, unsigned char scanDataType, unsigned char scanDataLength, const unsigned char* scanData, BLELocalAttribute** localAttributes, unsigned char numLocalAttributes, BLERemoteAttribute** remoteAttributes, unsigned char numRemoteAttributes) { #ifdef __RFduino__ sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_SYNTH_250_PPM, NULL); #else sd_softdevice_enable(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, NULL); // sd_nvic_EnableIRQ(SWI2_IRQn); #endif #ifdef NRF51_S130 ble_enable_params_t enableParams = { .gatts_enable_params = { .service_changed = true } }; sd_ble_enable(&enableParams); #endif #ifdef NRF_51822_DEBUG ble_version_t version; sd_ble_version_get(&version); Serial.print(F("version = ")); Serial.print(version.version_number); Serial.print(F(" ")); Serial.print(version.company_id); Serial.print(F(" ")); Serial.print(version.subversion_number); Serial.println(); #endif ble_gap_conn_params_t gap_conn_params; gap_conn_params.min_conn_interval = 40; // in 1.25ms units gap_conn_params.max_conn_interval = 80; // in 1.25ms unit gap_conn_params.slave_latency = 0; gap_conn_params.conn_sup_timeout = 4000 / 10; // in 10ms unit sd_ble_gap_ppcp_set(&gap_conn_params); sd_ble_gap_tx_power_set(0); unsigned char srData[31]; unsigned char srDataLen = 0; this->_advDataLen = 0; // flags this->_advData[this->_advDataLen + 0] = 2; this->_advData[this->_advDataLen + 1] = 0x01; this->_advData[this->_advDataLen + 2] = 0x06; this->_advDataLen += 3; if (advertisementDataType && advertisementDataLength && advertisementData) { this->_advData[this->_advDataLen + 0] = advertisementDataLength + 1; this->_advData[this->_advDataLen + 1] = advertisementDataType; this->_advDataLen += 2; memcpy(&this->_advData[this->_advDataLen], advertisementData, advertisementDataLength); this->_advDataLen += advertisementDataLength; } if (scanDataType && scanDataLength && scanData) { srData[0] = scanDataLength + 1; srData[1] = scanDataType; memcpy(&srData[2], scanData, scanDataLength); srDataLen = 2 + scanDataLength; } sd_ble_gap_adv_data_set(this->_advData, this->_advDataLen, srData, srDataLen); sd_ble_gap_appearance_set(0); for (int i = 0; i < numLocalAttributes; i++) { BLELocalAttribute *localAttribute = localAttributes[i]; if (localAttribute->type() == BLETypeCharacteristic) { this->_numLocalCharacteristics++; } } this->_numLocalCharacteristics -= 3; // 0x2a00, 0x2a01, 0x2a05 this->_localCharacteristicInfo = (struct localCharacteristicInfo*)malloc(sizeof(struct localCharacteristicInfo) * this->_numLocalCharacteristics); unsigned char localCharacteristicIndex = 0; uint16_t handle = 0; BLEService *lastService = NULL; for (int i = 0; i < numLocalAttributes; i++) { BLELocalAttribute *localAttribute = localAttributes[i]; BLEUuid uuid = BLEUuid(localAttribute->uuid()); const unsigned char* uuidData = uuid.data(); unsigned char value[255]; ble_uuid_t nordicUUID; if (uuid.length() == 2) { nordicUUID.uuid = (uuidData[1] << 8) | uuidData[0]; nordicUUID.type = BLE_UUID_TYPE_BLE; } else { unsigned char uuidDataTemp[16]; memcpy(&uuidDataTemp, uuidData, sizeof(uuidDataTemp)); nordicUUID.uuid = (uuidData[13] << 8) | uuidData[12]; uuidDataTemp[13] = 0; uuidDataTemp[12] = 0; sd_ble_uuid_vs_add((ble_uuid128_t*)&uuidDataTemp, &nordicUUID.type); } if (localAttribute->type() == BLETypeService) { BLEService *service = (BLEService *)localAttribute; if (strcmp(service->uuid(), "1800") == 0 || strcmp(service->uuid(), "1801") == 0) { continue; // skip } sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &nordicUUID, &handle); lastService = service; } else if (localAttribute->type() == BLETypeCharacteristic) { BLECharacteristic *characteristic = (BLECharacteristic *)localAttribute; if (strcmp(characteristic->uuid(), "2a00") == 0) { ble_gap_conn_sec_mode_t secMode; BLE_GAP_CONN_SEC_MODE_SET_OPEN(&secMode); // no security is needed sd_ble_gap_device_name_set(&secMode, characteristic->value(), characteristic->valueLength()); } else if (strcmp(characteristic->uuid(), "2a01") == 0) { const uint16_t *appearance = (const uint16_t*)characteristic->value(); sd_ble_gap_appearance_set(*appearance); } else if (strcmp(characteristic->uuid(), "2a05") == 0) { // do nothing } else { uint8_t properties = characteristic->properties() & 0xfe; uint16_t valueLength = characteristic->valueLength(); this->_localCharacteristicInfo[localCharacteristicIndex].characteristic = characteristic; this->_localCharacteristicInfo[localCharacteristicIndex].notifySubscribed = false; this->_localCharacteristicInfo[localCharacteristicIndex].indicateSubscribed = false; this->_localCharacteristicInfo[localCharacteristicIndex].service = lastService; ble_gatts_char_md_t characteristicMetaData; ble_gatts_attr_md_t clientCharacteristicConfigurationMetaData; ble_gatts_attr_t characteristicValueAttribute; ble_gatts_attr_md_t characteristicValueAttributeMetaData; memset(&characteristicMetaData, 0, sizeof(characteristicMetaData)); memcpy(&characteristicMetaData.char_props, &properties, 1); characteristicMetaData.p_char_user_desc = NULL; characteristicMetaData.p_char_pf = NULL; characteristicMetaData.p_user_desc_md = NULL; characteristicMetaData.p_cccd_md = NULL; characteristicMetaData.p_sccd_md = NULL; if (properties & (BLENotify | BLEIndicate)) { memset(&clientCharacteristicConfigurationMetaData, 0, sizeof(clientCharacteristicConfigurationMetaData)); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&clientCharacteristicConfigurationMetaData.read_perm); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&clientCharacteristicConfigurationMetaData.write_perm); clientCharacteristicConfigurationMetaData.vloc = BLE_GATTS_VLOC_STACK; characteristicMetaData.p_cccd_md = &clientCharacteristicConfigurationMetaData; } memset(&characteristicValueAttributeMetaData, 0, sizeof(characteristicValueAttributeMetaData)); if (properties & (BLERead | BLENotify | BLEIndicate)) { if (this->_bondStore) { BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&characteristicValueAttributeMetaData.read_perm); } else { BLE_GAP_CONN_SEC_MODE_SET_OPEN(&characteristicValueAttributeMetaData.read_perm); } } if (properties & (BLEWriteWithoutResponse | BLEWrite)) { if (this->_bondStore) { BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&characteristicValueAttributeMetaData.write_perm); } else { BLE_GAP_CONN_SEC_MODE_SET_OPEN(&characteristicValueAttributeMetaData.write_perm); } } characteristicValueAttributeMetaData.vloc = BLE_GATTS_VLOC_STACK; characteristicValueAttributeMetaData.rd_auth = 0; characteristicValueAttributeMetaData.wr_auth = 0; characteristicValueAttributeMetaData.vlen = !characteristic->fixedLength(); for (int j = (i + 1); j < numLocalAttributes; j++) { localAttribute = localAttributes[j]; if (localAttribute->type() != BLETypeDescriptor) { break; } BLEDescriptor *descriptor = (BLEDescriptor *)localAttribute; if (strcmp(descriptor->uuid(), "2901") == 0) { characteristicMetaData.p_char_user_desc = (uint8_t*)descriptor->value(); characteristicMetaData.char_user_desc_max_size = descriptor->valueLength(); characteristicMetaData.char_user_desc_size = descriptor->valueLength(); } else if (strcmp(descriptor->uuid(), "2904") == 0) { characteristicMetaData.p_char_pf = (ble_gatts_char_pf_t *)descriptor->value(); } } memset(&characteristicValueAttribute, 0, sizeof(characteristicValueAttribute)); characteristicValueAttribute.p_uuid = &nordicUUID; characteristicValueAttribute.p_attr_md = &characteristicValueAttributeMetaData; characteristicValueAttribute.init_len = valueLength; characteristicValueAttribute.init_offs = 0; characteristicValueAttribute.max_len = characteristic->valueSize(); characteristicValueAttribute.p_value = NULL; sd_ble_gatts_characteristic_add(BLE_GATT_HANDLE_INVALID, &characteristicMetaData, &characteristicValueAttribute, &this->_localCharacteristicInfo[localCharacteristicIndex].handles); if (valueLength) { for (int j = 0; j < valueLength; j++) { value[j] = (*characteristic)[j]; } sd_ble_gatts_value_set(this->_localCharacteristicInfo[localCharacteristicIndex].handles.value_handle, 0, &valueLength, value); } localCharacteristicIndex++; } } else if (localAttribute->type() == BLETypeDescriptor) { BLEDescriptor *descriptor = (BLEDescriptor *)localAttribute; if (strcmp(descriptor->uuid(), "2901") == 0 || strcmp(descriptor->uuid(), "2902") == 0 || strcmp(descriptor->uuid(), "2903") == 0 || strcmp(descriptor->uuid(), "2904") == 0) { continue; // skip } uint16_t valueLength = descriptor->valueLength(); ble_gatts_attr_t descriptorAttribute; ble_gatts_attr_md_t descriptorMetaData; memset(&descriptorAttribute, 0, sizeof(descriptorAttribute)); memset(&descriptorMetaData, 0, sizeof(descriptorMetaData)); descriptorMetaData.vloc = BLE_GATTS_VLOC_STACK; descriptorMetaData.vlen = (valueLength == descriptor->valueLength()) ? 0 : 1; if (this->_bondStore) { BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&descriptorMetaData.read_perm); } else { BLE_GAP_CONN_SEC_MODE_SET_OPEN(&descriptorMetaData.read_perm); } descriptorAttribute.p_uuid = &nordicUUID; descriptorAttribute.p_attr_md = &descriptorMetaData; descriptorAttribute.init_len = valueLength; descriptorAttribute.max_len = descriptor->valueLength(); descriptorAttribute.p_value = NULL; sd_ble_gatts_descriptor_add(BLE_GATT_HANDLE_INVALID, &descriptorAttribute, &handle); if (valueLength) { for (int j = 0; j < valueLength; j++) { value[j] = (*descriptor)[j]; } sd_ble_gatts_value_set(handle, 0, &valueLength, value); } } } if ( numRemoteAttributes > 0) { numRemoteAttributes -= 2; // 0x1801, 0x2a05 } for (int i = 0; i < numRemoteAttributes; i++) { BLERemoteAttribute *remoteAttribute = remoteAttributes[i]; if (remoteAttribute->type() == BLETypeService) { this->_numRemoteServices++; } else if (remoteAttribute->type() == BLETypeCharacteristic) { this->_numRemoteCharacteristics++; } } this->_remoteServiceInfo = (struct remoteServiceInfo*)malloc(sizeof(struct remoteServiceInfo) * this->_numRemoteServices); this->_remoteCharacteristicInfo = (struct remoteCharacteristicInfo*)malloc(sizeof(struct remoteCharacteristicInfo) * this->_numRemoteCharacteristics); BLERemoteService *lastRemoteService = NULL; unsigned char remoteServiceIndex = 0; unsigned char remoteCharacteristicIndex = 0; for (int i = 0; i < numRemoteAttributes; i++) { BLERemoteAttribute *remoteAttribute = remoteAttributes[i]; BLEUuid uuid = BLEUuid(remoteAttribute->uuid()); const unsigned char* uuidData = uuid.data(); ble_uuid_t nordicUUID; if (uuid.length() == 2) { nordicUUID.uuid = (uuidData[1] << 8) | uuidData[0]; nordicUUID.type = BLE_UUID_TYPE_BLE; } else { unsigned char uuidDataTemp[16]; memcpy(&uuidDataTemp, uuidData, sizeof(uuidDataTemp)); nordicUUID.uuid = (uuidData[13] << 8) | uuidData[12]; uuidDataTemp[13] = 0; uuidDataTemp[12] = 0; sd_ble_uuid_vs_add((ble_uuid128_t*)&uuidDataTemp, &nordicUUID.type); } if (remoteAttribute->type() == BLETypeService) { this->_remoteServiceInfo[remoteServiceIndex].service = lastRemoteService = (BLERemoteService *)remoteAttribute; this->_remoteServiceInfo[remoteServiceIndex].uuid = nordicUUID; memset(&this->_remoteServiceInfo[remoteServiceIndex].handlesRange, 0, sizeof(this->_remoteServiceInfo[remoteServiceIndex].handlesRange)); remoteServiceIndex++; } else if (remoteAttribute->type() == BLETypeCharacteristic) { this->_remoteCharacteristicInfo[remoteCharacteristicIndex].characteristic = (BLERemoteCharacteristic *)remoteAttribute; this->_remoteCharacteristicInfo[remoteCharacteristicIndex].service = lastRemoteService; this->_remoteCharacteristicInfo[remoteCharacteristicIndex].uuid = nordicUUID; memset(&this->_remoteCharacteristicInfo[remoteCharacteristicIndex].properties, 0, sizeof(this->_remoteCharacteristicInfo[remoteCharacteristicIndex].properties)); this->_remoteCharacteristicInfo[remoteCharacteristicIndex].valueHandle = 0; remoteCharacteristicIndex++; } } if (this->_bondStore && this->_bondStore->hasData()) { #ifdef NRF_51822_DEBUG Serial.println(F("Restoring bond data")); #endif #ifdef NRF51_S130 this->_bondStore->getData(this->_bondData, 0, sizeof(this->_bondData)); #else this->_bondStore->getData(this->_authStatusBuffer, 0, sizeof(this->_authStatusBuffer)); #endif } this->startAdvertising(); #ifdef __RFduino__ RFduinoBLE_enabled = 1; #endif }