/**@brief Function for adding a characteristic for the Continuous Glucose Meter Measurement. * * @param[in] p_cgms Service instance. * * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. */ ret_code_t cgms_meas_char_add(nrf_ble_cgms_t * p_cgms) { uint8_t num_recs; uint8_t encoded_cgms_meas[NRF_BLE_CGMS_MEAS_LEN_MAX]; ble_add_char_params_t add_char_params; ble_cgms_rec_t initial_cgms_rec_value; memset(&add_char_params, 0, sizeof(add_char_params)); memset(&initial_cgms_rec_value, 0, sizeof(ble_cgms_rec_t)); num_recs = cgms_db_num_records_get(); if (num_recs > 0) { uint32_t err_code = cgms_db_record_get(num_recs - 1, &initial_cgms_rec_value); if (err_code != NRF_SUCCESS) { return err_code; } } add_char_params.uuid = BLE_UUID_CGM_MEASUREMENT; add_char_params.max_len = NRF_BLE_CGMS_MEAS_LEN_MAX; add_char_params.init_len = cgms_meas_encode(p_cgms, &initial_cgms_rec_value.meas, encoded_cgms_meas); add_char_params.p_init_value = encoded_cgms_meas; add_char_params.is_var_len = true; add_char_params.char_props.notify = true; add_char_params.cccd_write_access = SEC_JUST_WORKS; return characteristic_add(p_cgms->service_handle, &add_char_params, &p_cgms->char_handles.measurment); }
/**@brief Function for adding the Bond Management Feature characteristic. * * @param[in] p_bms Bond Management Service structure. * @param[in] p_bms_init Information needed to initialize the service. * * @return NRF_SUCCESS on success, otherwise an error code returned by @ref characteristic_add. */ static ret_code_t feature_char_add(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t const * p_bms_init) { uint8_t encoded_feature[NRF_BLE_BMS_FEATURE_LEN]; uint8_t init_value_len; ble_add_char_params_t add_char_params; nrf_ble_bms_features_t * p_feature = &p_bms->feature; if ((p_feature->delete_all_auth) || (p_feature->delete_all_but_requesting_auth) || (p_feature->delete_requesting_auth)) { VERIFY_PARAM_NOT_NULL(p_bms_init->evt_handler); } if ((p_feature->delete_requesting_auth) || (p_feature->delete_requesting)) { VERIFY_PARAM_NOT_NULL(p_bms_init->bond_callbacks.delete_requesting); } if ((p_feature->delete_all) || (p_feature->delete_all_auth)) { VERIFY_PARAM_NOT_NULL(p_bms_init->bond_callbacks.delete_all); } if ((p_feature->delete_all_but_requesting) || (p_feature->delete_all_but_requesting_auth)) { VERIFY_PARAM_NOT_NULL(p_bms_init->bond_callbacks.delete_all_except_requesting); } init_value_len = feature_encode(&p_bms->feature, encoded_feature); memset(&add_char_params, 0, sizeof(add_char_params)); add_char_params.uuid = BLE_UUID_BMS_FEATURE; add_char_params.char_props.read = true; add_char_params.max_len = init_value_len; add_char_params.p_init_value = encoded_feature; add_char_params.init_len = init_value_len; add_char_params.read_access = p_bms_init->bms_feature_sec_req; add_char_params.write_access = SEC_NO_ACCESS; return characteristic_add(p_bms->service_handle, &add_char_params, &p_bms->feature_handles); }
uint32_t ble_sc_ctrlpt_init(ble_sc_ctrlpt_t * p_sc_ctrlpt, const ble_cs_ctrlpt_init_t * p_sc_ctrlpt_init) { if (p_sc_ctrlpt == NULL || p_sc_ctrlpt_init == NULL) { return NRF_ERROR_NULL; } ble_add_char_params_t add_char_params; p_sc_ctrlpt->conn_handle = BLE_CONN_HANDLE_INVALID; p_sc_ctrlpt->procedure_status = BLE_SCPT_NO_PROC_IN_PROGRESS; p_sc_ctrlpt->size_list_supported_locations = p_sc_ctrlpt_init->size_list_supported_locations; if ((p_sc_ctrlpt_init->size_list_supported_locations != 0) && (p_sc_ctrlpt_init->list_supported_locations != NULL)) { memcpy(p_sc_ctrlpt->list_supported_locations, p_sc_ctrlpt_init->list_supported_locations, p_sc_ctrlpt->size_list_supported_locations * sizeof(ble_sensor_location_t)); } p_sc_ctrlpt->service_handle = p_sc_ctrlpt_init->service_handle; p_sc_ctrlpt->evt_handler = p_sc_ctrlpt_init->evt_handler; p_sc_ctrlpt->supported_functions = p_sc_ctrlpt_init->supported_functions; p_sc_ctrlpt->sensor_location_handle = p_sc_ctrlpt_init->sensor_location_handle; p_sc_ctrlpt->error_handler = p_sc_ctrlpt_init->error_handler; // Add speed and cadence control point characteristic memset(&add_char_params, 0, sizeof(add_char_params)); add_char_params.uuid = BLE_UUID_SC_CTRLPT_CHAR; add_char_params.max_len = BLE_SC_CTRLPT_MAX_LEN; add_char_params.is_var_len = true; add_char_params.char_props.indicate = 1; add_char_params.char_props.write = 1; add_char_params.cccd_write_access = p_sc_ctrlpt_init->sc_ctrlpt_cccd_wr_sec; add_char_params.write_access = p_sc_ctrlpt_init->sc_ctrlpt_wr_sec; add_char_params.is_defered_write = true; return characteristic_add(p_sc_ctrlpt->service_handle, &add_char_params, &p_sc_ctrlpt->sc_ctrlpt_handles); }
/**@brief Function for adding the Bond Management Control Point characteristic. * * @param[in] p_bms Bond Management Service structure. * @param[in] p_bms_init Information needed to initialize the service. * * @return NRF_SUCCESS on success, otherwise an error code returned by @ref characteristic_add. */ static ret_code_t ctrlpt_char_add(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t const * p_bms_init) { ble_add_char_params_t add_char_params; memset(&add_char_params, 0, sizeof(add_char_params)); add_char_params.uuid = BLE_UUID_BMS_CTRLPT; add_char_params.char_props.write = 1; add_char_params.is_defered_write = true; add_char_params.is_var_len = true; add_char_params.max_len = NRF_BLE_BMS_CTRLPT_MAX_LEN; add_char_params.read_access = SEC_NO_ACCESS; add_char_params.write_access = p_bms_init->bms_ctrlpt_sec_req; if (p_bms_init->p_qwr != NULL) { add_char_params.char_ext_props.reliable_wr = 1; } return characteristic_add(p_bms->service_handle, &add_char_params, &p_bms->ctrlpt_handles); }
/**@brief Function for adding a characteristic for the Record Access Control Point. * * @param[in] p_cgms Service instance. * * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. */ ret_code_t cgms_racp_char_add(nrf_ble_cgms_t * p_cgms) { ble_add_char_params_t add_char_params; memset(&add_char_params, 0, sizeof(add_char_params)); add_char_params.uuid = BLE_UUID_RECORD_ACCESS_CONTROL_POINT_CHAR; add_char_params.max_len = BLE_L2CAP_MTU_DEF; add_char_params.init_len = 0; add_char_params.p_init_value = 0; add_char_params.is_var_len = true; add_char_params.write_access = SEC_JUST_WORKS; add_char_params.char_props.write = true; add_char_params.char_props.indicate = true; add_char_params.cccd_write_access = SEC_JUST_WORKS; add_char_params.is_defered_write = 1; return characteristic_add(p_cgms->service_handle, &add_char_params, &p_cgms->char_handles.racp); }
/**@brief Function for adding a status characteristic for the CGMS. * * @param[in] p_cgms Service instance. * * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. */ static uint32_t status_char_add(nrf_ble_cgms_t * p_cgms) { uint8_t init_value_len; uint8_t encoded_initial_status[NRF_BLE_CGMS_STATUS_LEN]; ble_add_char_params_t add_char_params; memset(&add_char_params, 0, sizeof(add_char_params)); init_value_len = encode_status(encoded_initial_status, p_cgms); add_char_params.uuid = BLE_UUID_CGM_STATUS; add_char_params.max_len = init_value_len; add_char_params.init_len = init_value_len; add_char_params.p_init_value = encoded_initial_status; add_char_params.read_access = SEC_JUST_WORKS; add_char_params.write_access = SEC_NO_ACCESS; return characteristic_add(p_cgms->service_handle, &add_char_params, &p_cgms->char_handles.status); }
/**@brief Function for adding a characteristic for the Session Start Time. * * @param[in] p_cgms Service instance. * * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. */ ret_code_t cgms_sst_char_add(nrf_ble_cgms_t * p_cgms) { ble_add_char_params_t add_char_params; uint8_t init_value[NRF_BLE_CGMS_SST_LEN] = {0}; memset(&add_char_params, 0, sizeof(add_char_params)); add_char_params.uuid = BLE_UUID_CGM_SESSION_START_TIME; add_char_params.max_len = NRF_BLE_CGMS_SST_LEN; add_char_params.init_len = NRF_BLE_CGMS_SST_LEN; add_char_params.p_init_value = init_value; add_char_params.read_access = SEC_JUST_WORKS; add_char_params.write_access = SEC_JUST_WORKS; add_char_params.is_defered_write = 1; add_char_params.char_props.write = true; return characteristic_add(p_cgms->service_handle, &add_char_params, &p_cgms->char_handles.sst); }
/**@brief Function for adding a characteristic for the Session Run Time. * * @param[in] p_cgms Service instance. * * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. */ static uint32_t srt_char_add(nrf_ble_cgms_t * p_cgms) { uint8_t len = 0; uint8_t encoded_initial_srt[NRF_BLE_CGMS_SRT_LEN]; ble_add_char_params_t add_char_params; memset(&add_char_params, 0, sizeof(add_char_params)); len += uint16_encode(p_cgms->session_run_time, &(encoded_initial_srt[len])); add_char_params.uuid = BLE_UUID_CGM_SESSION_RUN_TIME; add_char_params.max_len = NRF_BLE_CGMS_SRT_LEN; add_char_params.init_len = len; add_char_params.p_init_value = encoded_initial_srt; add_char_params.read_access = SEC_JUST_WORKS; add_char_params.write_access = SEC_NO_ACCESS; return characteristic_add(p_cgms->service_handle, &add_char_params, &p_cgms->char_handles.srt); }
/**@brief Function for adding a characteristic for the glucose feature. * * @param[in] p_cgms Service instance. * * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. */ static uint32_t glucose_feature_char_add(nrf_ble_cgms_t * p_cgms) { uint8_t init_value_len; uint8_t encoded_initial_feature[NRF_BLE_CGMS_FEATURE_LEN]; ble_add_char_params_t add_char_params; memset(&add_char_params, 0, sizeof(add_char_params)); init_value_len = encode_feature_location_type(encoded_initial_feature, &(p_cgms->feature)); add_char_params.uuid = BLE_UUID_CGM_FEATURE; add_char_params.max_len = init_value_len; add_char_params.init_len = init_value_len; add_char_params.p_init_value = encoded_initial_feature; add_char_params.read_access = SEC_JUST_WORKS; add_char_params.write_access = SEC_NO_ACCESS; return characteristic_add(p_cgms->service_handle, &add_char_params, &p_cgms->char_handles.feature); }
static void addService(uint8_t uuid_type) { ret_code_t err_code; ble_add_char_params_t params; // サービスを登録 ble_uuid_t uuid; uuid.uuid = METADATA_SERVICE_UUID; uuid.type = uuid_type; err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &uuid, &context.service_handle); APP_ERROR_CHECK(err_code); // params初期設定 memset(¶ms, 0 , sizeof(params)); // UUID params.uuid_type = uuid_type; // 値はスタック側 params.is_value_user = false; // ターゲットログ params.uuid = TARGET_LOG_ID_CHAR_UUID; params.max_len = 1; params.char_props.read = true; params.char_props.write = true; params.char_props.notify = false; params.is_defered_read = false; params.is_defered_write = false; params.read_access = SEC_OPEN; params.write_access = SEC_OPEN; params.cccd_write_access = SEC_NO_ACCESS; err_code = characteristic_add(context.service_handle, ¶ms, &context.target_log_id_char_handle); APP_ERROR_CHECK(err_code); // メタ属性:時間 params.uuid = TARGET_DATETIME_CHAR_UUID; params.max_len = 7; // ble_date_timeのシリアライズされたバイナリサイズ params.char_props.read = true; params.char_props.write = false; params.char_props.notify = false; params.is_defered_read = true; params.is_defered_write = false; params.is_var_len = false; params.read_access = SEC_OPEN; params.write_access = SEC_NO_ACCESS; params.cccd_write_access = SEC_NO_ACCESS; err_code = characteristic_add(context.service_handle, ¶ms, &context.target_datetime_char_handle); APP_ERROR_CHECK(err_code); // メタ属性:概要 params.uuid = TARGET_ABSTRACT_CHAR_UUID; params.max_len = GATT_MAX_DATA_LENGTH; params.is_var_len = true; params.char_props.read = true; params.char_props.write = false; params.char_props.notify = false; params.is_defered_read = true; params.is_defered_write = false; params.is_var_len = false; params.read_access = SEC_OPEN; params.write_access = SEC_NO_ACCESS; params.cccd_write_access = SEC_NO_ACCESS; err_code = characteristic_add(context.service_handle, ¶ms, &context.target_abstract_char_handle); APP_ERROR_CHECK(err_code); }
/**@brief Function for initializing the DFU (Nordic). */ uint32_t ble_dfu__nordic__init(ble_dfu__nordic__t * p_dfu__nordic_, const ble_dfu__nordic__init_t * p_dfu__nordic__init) { uint32_t err_code; ble_uuid_t ble_uuid; // Initialize service structure p_dfu__nordic_->evt_handler = p_dfu__nordic__init->evt_handler; p_dfu__nordic_->conn_handle = BLE_CONN_HANDLE_INVALID; // Add a custom base UUID. ble_uuid128_t bds_base_uuid = ble_agsensor_get_uuid(true); uint8_t uuid_type; err_code = sd_ble_uuid_vs_add(&bds_base_uuid, &uuid_type); if (err_code != NRF_SUCCESS) { return err_code; } ble_uuid.type = uuid_type; ble_uuid.uuid = 0xBE4A; // Add service err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_dfu__nordic_->service_handle); if (err_code != NRF_SUCCESS) { return err_code; } // Add DFU Packet characteristic //dfu_packet_initial_value = p_dfu__nordic__init->ble_dfu__nordic__dfu_packet_initial_value; // dhaval test ble_dfu__nordic__dfu_packet_t dfu_packet_initial_value = p_dfu__nordic__init->ble_dfu__nordic__dfu_packet_initial_value; uint8_t dfu_packet_encoded_value[MAX_DFU_PACKET_LEN]; ble_add_char_params_t add_dfu_packet_params; memset(&add_dfu_packet_params, 0, sizeof(add_dfu_packet_params)); add_dfu_packet_params.uuid = 0xD4C0; add_dfu_packet_params.uuid_type = ble_uuid.type; add_dfu_packet_params.max_len = MAX_DFU_PACKET_LEN; add_dfu_packet_params.init_len = dfu_packet_encode(&dfu_packet_initial_value, dfu_packet_encoded_value); add_dfu_packet_params.p_init_value = dfu_packet_encoded_value; add_dfu_packet_params.char_props.write = 1; add_dfu_packet_params.write_access = SEC_OPEN; // 1 for variable length and 0 for fixed length. add_dfu_packet_params.is_var_len = 1; err_code = characteristic_add(p_dfu__nordic_->service_handle, &add_dfu_packet_params, &(p_dfu__nordic_->dfu_packet_handles)); if (err_code != NRF_SUCCESS) { return err_code; } // Add DFU Control Point characteristic //dfu_control_point_initial_value = p_dfu__nordic__init->ble_dfu__nordic__dfu_control_point_initial_value; //Dhaval test ble_dfu__nordic__dfu_control_point_t dfu_control_point_initial_value = p_dfu__nordic__init->ble_dfu__nordic__dfu_control_point_initial_value; uint8_t dfu_control_point_encoded_value[MAX_DFU_CONTROL_POINT_LEN]; ble_add_char_params_t add_dfu_control_point_params; memset(&add_dfu_control_point_params, 0, sizeof(add_dfu_control_point_params)); add_dfu_control_point_params.uuid = 0x1FE8; add_dfu_control_point_params.uuid_type = ble_uuid.type; add_dfu_control_point_params.max_len = MAX_DFU_CONTROL_POINT_LEN; add_dfu_control_point_params.init_len = dfu_control_point_encode(&dfu_control_point_initial_value, dfu_control_point_encoded_value); add_dfu_control_point_params.p_init_value = dfu_control_point_encoded_value; add_dfu_control_point_params.char_props.notify = 1; add_dfu_control_point_params.char_props.write = 1; add_dfu_control_point_params.write_access = SEC_OPEN; add_dfu_control_point_params.cccd_write_access = SEC_OPEN; // 1 for variable length and 0 for fixed length. add_dfu_control_point_params.is_var_len = 1; err_code = characteristic_add(p_dfu__nordic_->service_handle, &add_dfu_control_point_params, &(p_dfu__nordic_->dfu_control_point_handles)); if (err_code != NRF_SUCCESS) { return err_code; } return NRF_SUCCESS; }
/**@brief Function for initializing the AgSensor. */ uint32_t ble_agsensor_init(ble_agsensor_t * p_agsensor, const ble_agsensor_init_t * p_agsensor_init) { uint32_t err_code; ble_uuid_t ble_uuid; // Initialize service structure p_agsensor->evt_handler = p_agsensor_init->evt_handler; p_agsensor->conn_handle = BLE_CONN_HANDLE_INVALID; // Add a custom base UUID. ble_uuid128_t bds_base_uuid = {0x8D, 0x69, 0xDE, 0x3D, 0x57, 0x37, 0x4F, 0xBD, 0x54, 0x41, 0xE8, 0x73, 0x00, 0x00, 0xFE, 0x94}; uint8_t uuid_type; err_code = sd_ble_uuid_vs_add(&bds_base_uuid, &uuid_type); if (err_code != NRF_SUCCESS) { return err_code; } ble_uuid.type = uuid_type; ble_uuid.uuid = 0x9B64; // Add service err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_agsensor->service_handle); if (err_code != NRF_SUCCESS) { return err_code; } // Add configuration characteristic ble_agsensor_configuration_t configuration_initial_value = p_agsensor_init->ble_agsensor_configuration_initial_value; // Initialize value struct. memset(&configuration_initial_value, 0, sizeof(configuration_initial_value)); // Dhaval test configuration_initial_value = p_agsensor_init->ble_agsensor_configuration_initial_value; configuration_initial_value.ble_agsensor_code = 0x0001; configuration_initial_value.data.ble_agsensor_date_time_Sec = getTimeInSec(); // configuration_initial_value.ble_agsensor_data = "test"; uint8_t configuration_encoded_value[MAX_CONFIGURATION_LEN]; ble_add_char_params_t add_configuration_params; memset(&add_configuration_params, 0, sizeof(add_configuration_params)); add_configuration_params.uuid = 0x866D; add_configuration_params.uuid_type = ble_uuid.type; add_configuration_params.max_len = MAX_CONFIGURATION_LEN; add_configuration_params.init_len = configuration_encode(&configuration_initial_value, configuration_encoded_value); add_configuration_params.p_init_value = configuration_encoded_value; //// add_configuration_params.char_props.indicate = 1; // add_configuration_params.char_props.write = 1; //// add_configuration_params.read_access = SEC_OPEN; // add_configuration_params.write_access = SEC_OPEN; //// add_configuration_params.cccd_write_access = SEC_OPEN; // // 1 for variable length and 0 for fixed length. // add_configuration_params.is_var_len = 1; // // add_configuration_params.char_props.read = 1; // add_configuration_params.read_access = SEC_OPEN; add_configuration_params.char_props.notify = 1; add_configuration_params.char_props.indicate = 1; add_configuration_params.char_props.read = 1; add_configuration_params.read_access = SEC_OPEN; add_configuration_params.char_props.write = 1; add_configuration_params.write_access = SEC_OPEN; add_configuration_params.cccd_write_access = SEC_OPEN; // 1 for variable length and 0 for fixed length. add_configuration_params.is_var_len = 1; err_code = characteristic_add(p_agsensor->service_handle, &add_configuration_params, &(p_agsensor->configuration_handles)); if (err_code != NRF_SUCCESS) { return err_code; } // Add data characteristic //data_initial_value = p_agsensor_init->ble_agsensor_data_initial_value; ble_agsensor_data_t data_initial_value = p_agsensor_init->ble_agsensor_data_initial_value; uint8_t data_encoded_value[MAX_DATA_LEN]; ble_add_char_params_t add_data_params; memset(&add_data_params, 0, sizeof(add_data_params)); add_data_params.uuid = 0x20D7; add_data_params.uuid_type = ble_uuid.type; add_data_params.max_len = MAX_DATA_LEN; add_data_params.init_len = data_encode(&data_initial_value, data_encoded_value); add_data_params.p_init_value = data_encoded_value; add_data_params.char_props.indicate = 1; add_data_params.char_props.write = 1; add_data_params.write_access = SEC_OPEN; add_data_params.cccd_write_access = SEC_OPEN; // 1 for variable length and 0 for fixed length. add_data_params.is_var_len = 1; err_code = characteristic_add(p_agsensor->service_handle, &add_data_params, &(p_agsensor->data_handles)); if (err_code != NRF_SUCCESS) { return err_code; } return NRF_SUCCESS; }
/**@brief Function for initializing the Display Service. */ uint32_t ble_display_service_init(ble_display_service_t * p_display_service, const ble_display_service_init_t * p_display_service_init) { uint32_t err_code; ble_uuid_t ble_uuid; // Initialize service structure p_display_service->evt_handler = p_display_service_init->evt_handler; p_display_service->conn_handle = BLE_CONN_HANDLE_INVALID; // Add a custom base UUID. ble_uuid128_t bds_base_uuid = { { 0x22, 0x13, 0xDC, 0x64, 0xC5, 0x14, 0x2B, 0x90, 0x0C, 0x43, 0xCF, 0x10, 0x00, 0x00, 0x00, 0x0D } }; uint8_t uuid_type; err_code = sd_ble_uuid_vs_add(&bds_base_uuid, &uuid_type); if (err_code != NRF_SUCCESS) { return err_code; } ble_uuid.type = uuid_type; ble_uuid.uuid = 0x14CE; // Add service err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_display_service->service_handle); if (err_code != NRF_SUCCESS) { return err_code; } // Add Record Number characteristic ble_display_service_record_number_t record_number_initial_value = p_display_service_init->ble_display_service_record_number_initial_value; uint8_t record_number_encoded_value[MAX_RECORD_NUMBER_LEN]; ble_add_char_params_t add_record_number_params; memset(&add_record_number_params, 0, sizeof(add_record_number_params)); add_record_number_params.uuid = 0xAF2A; add_record_number_params.uuid_type = ble_uuid.type; add_record_number_params.max_len = MAX_RECORD_NUMBER_LEN; add_record_number_params.init_len = record_number_encode(&record_number_initial_value, record_number_encoded_value); add_record_number_params.p_init_value = record_number_encoded_value; add_record_number_params.char_props.write = 1; add_record_number_params.char_props.write_wo_resp = 1; add_record_number_params.write_access = SEC_OPEN; // 1 for variable length and 0 for fixed length. add_record_number_params.is_var_len = 1; err_code = characteristic_add(p_display_service->service_handle, &add_record_number_params, &(p_display_service->record_number_handles)); if (err_code != NRF_SUCCESS) { return err_code; } // Add Record characteristic ble_display_service_record_t record_initial_value = p_display_service_init->ble_display_service_record_initial_value; uint8_t record_encoded_value[MAX_RECORD_LEN]; ble_add_char_params_t add_record_params; memset(&add_record_params, 0, sizeof(add_record_params)); add_record_params.uuid = 0x411C; add_record_params.uuid_type = ble_uuid.type; add_record_params.max_len = MAX_RECORD_LEN; add_record_params.init_len = record_encode(&record_initial_value, record_encoded_value); add_record_params.p_init_value = record_encoded_value; add_record_params.char_props.notify = 1; add_record_params.char_props.read = 1; add_record_params.read_access = SEC_OPEN; add_record_params.cccd_write_access = SEC_OPEN; // 1 for variable length and 0 for fixed length. add_record_params.is_var_len = 1; err_code = characteristic_add(p_display_service->service_handle, &add_record_params, &(p_display_service->record_handles)); if (err_code != NRF_SUCCESS) { return err_code; } return NRF_SUCCESS; }