#include "ble_cus.h"

/**@brief Function for adding the Custom Value characteristic.
 * @param[in]   p_cus        Custom Service structure.
 * @param[in]   p_cus_init   Information needed to initialize the service.
 * @return      NRF_SUCCESS on success, otherwise an error code. */
uint32_t custom_char_add_1(ble_cus_t * p_cus, const ble_cus_init_t * p_cus_init)
{
    uint32_t            err_code;
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_md_t cccd_md;
    ble_gatts_attr_t    attr_char_value;
    ble_uuid_t          ble_uuid;
    ble_gatts_attr_md_t attr_md;

    // Add Custom Value characteristic
    memset(&cccd_md, 0, sizeof(cccd_md));

    //  Read  operation on cccd should be possible without authentication.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);

    cccd_md.write_perm = p_cus_init->custom_value_char_attr_md.cccd_write_perm;
    cccd_md.vloc       = BLE_GATTS_VLOC_STACK;

    memset(&char_md, 0, sizeof(char_md));

    char_md.char_props.read   = 1;
    char_md.char_props.write  = 1;
	char_md.char_props.write_wo_resp = 1; /*oct*/
    char_md.char_props.notify = 1;
    char_md.p_char_user_desc  = NULL;
    char_md.p_char_pf         = NULL;
    char_md.p_user_desc_md    = NULL;
    char_md.p_cccd_md         = &cccd_md;
    char_md.p_sccd_md         = NULL;

    ble_uuid.type = p_cus->uuid_type;
    ble_uuid.uuid = CUSTOM_VALUE_CHAR_1_UUID;

    memset(&attr_md, 0, sizeof(attr_md));

    attr_md.read_perm  = p_cus_init->custom_value_char_attr_md.read_perm;
    attr_md.write_perm = p_cus_init->custom_value_char_attr_md.write_perm;
    attr_md.vloc       = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth    = 0;
    attr_md.wr_auth    = 0;
    attr_md.vlen       = 0;

    memset(&attr_char_value, 0, sizeof(attr_char_value));

    attr_char_value.p_uuid    = &ble_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_len  = RAW_DATA_LENGTH*sizeof(uint8_t);
    attr_char_value.init_offs = 0;
    attr_char_value.max_len   = RAW_DATA_LENGTH*sizeof(uint8_t);

    err_code = sd_ble_gatts_characteristic_add(p_cus->service_handle, &char_md, &attr_char_value, &p_cus->custom_char_handle_1);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }

    return NRF_SUCCESS;
}

/* New Characteristic */
uint32_t custom_char_add_2(ble_cus_t * p_cus, const ble_cus_init_t * p_cus_init)
{
    uint32_t            err_code;
    ble_gatts_char_md_t char_md;
    ble_gatts_attr_md_t cccd_md;
    ble_gatts_attr_t    attr_char_value;
    ble_uuid_t          ble_uuid;
    ble_gatts_attr_md_t attr_md;

    // Add Custom Value characteristic
    memset(&cccd_md, 0, sizeof(cccd_md));

    //  Read  operation on cccd should be possible without authentication.
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);

    cccd_md.write_perm = p_cus_init->custom_value_char_attr_md.cccd_write_perm;
    cccd_md.vloc       = BLE_GATTS_VLOC_STACK;

    memset(&char_md, 0, sizeof(char_md));

    char_md.char_props.read   = 1;
    char_md.char_props.write  = 1;
	char_md.char_props.write_wo_resp = 1; /*oct*/
    char_md.char_props.notify = 1;
    char_md.p_char_user_desc  = NULL;
    char_md.p_char_pf         = NULL;
    char_md.p_user_desc_md    = NULL;
    char_md.p_cccd_md         = &cccd_md;
    char_md.p_sccd_md         = NULL;

    ble_uuid.type = p_cus->uuid_type;
    ble_uuid.uuid = CUSTOM_VALUE_CHAR_2_UUID;

    memset(&attr_md, 0, sizeof(attr_md));

    attr_md.read_perm  = p_cus_init->custom_value_char_attr_md.read_perm;
    attr_md.write_perm = p_cus_init->custom_value_char_attr_md.write_perm;
    attr_md.vloc       = BLE_GATTS_VLOC_STACK;
    attr_md.rd_auth    = 0;
    attr_md.wr_auth    = 0;
    attr_md.vlen       = 0;

    memset(&attr_char_value, 0, sizeof(attr_char_value));

    attr_char_value.p_uuid    = &ble_uuid;
    attr_char_value.p_attr_md = &attr_md;
    attr_char_value.init_len  = RAW_DATA_LENGTH*sizeof(uint8_t);
    attr_char_value.init_offs = 0;
    attr_char_value.max_len   = RAW_DATA_LENGTH*sizeof(uint8_t);

    err_code = sd_ble_gatts_characteristic_add(p_cus->service_handle, &char_md, &attr_char_value, &p_cus->custom_char_handle_2);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
	
    return NRF_SUCCESS;
}

uint32_t ble_cus_init(ble_cus_t * p_cus, const ble_cus_init_t * p_cus_init)
{
    if (p_cus == NULL || p_cus_init == NULL)
    {
        return NRF_ERROR_NULL;
    }
    uint32_t   err_code;
    ble_uuid_t ble_uuid;
    // Initialize service structure
    p_cus->evt_handler               = p_cus_init->evt_handler;
    p_cus->conn_handle               = BLE_CONN_HANDLE_INVALID;
	//	p_cus->characteristic1_value_write_handler = p_cus_init->characteristic1_value_write_handler;
    // Add Custom Service UUID
    ble_uuid128_t base_uuid = {CUSTOM_SERVICE_UUID_BASE};
    err_code =  sd_ble_uuid_vs_add(&base_uuid, &p_cus->uuid_type);
    VERIFY_SUCCESS(err_code);
    ble_uuid.type = p_cus->uuid_type;
    ble_uuid.uuid = CUSTOM_SERVICE_UUID;
    // Add the Custom Service
    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_cus->service_handle);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    // Add Custom Value characteristic
	err_code = custom_char_add_1(p_cus, p_cus_init);
	if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
	
	/* New Characteristic */
	err_code = custom_char_add_2(p_cus, p_cus_init);
	if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
	
    return NRF_SUCCESS;
}

uint32_t ble_cus_custom_char_update_1(ble_cus_t * p_cus, uint8_t * custom_value)	/*NEW CHANGE*/
{
//    NRF_LOG_INFO("Data Sent to Host. \r\n");
    if (p_cus == NULL)
    {
        return NRF_ERROR_NULL;
    }
    uint32_t err_code = NRF_SUCCESS;
    ble_gatts_value_t gatts_value;
    // Initialize value struct.
    memset(&gatts_value, 0, sizeof(gatts_value));
    gatts_value.len     = RAW_DATA_LENGTH*sizeof(uint8_t);	/*NEW CHANGE*/
    gatts_value.offset  = 0;
    gatts_value.p_value = (uint8_t *)custom_value;
    // Update database.
    err_code = sd_ble_gatts_value_set(p_cus->conn_handle, p_cus->custom_char_handle_1.value_handle, &gatts_value);
	//NRF_LOG_INFO("sd_ble_gatts_value_set: %x. \r\n", err_code);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    // Send value if connected and notifying.
    if ((p_cus->conn_handle != BLE_CONN_HANDLE_INVALID))
    {
        ble_gatts_hvx_params_t hvx_params;
        memset(&hvx_params, 0, sizeof(hvx_params));
        hvx_params.handle = p_cus->custom_char_handle_1.value_handle;
        hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
        hvx_params.offset = gatts_value.offset;
        hvx_params.p_len  = &gatts_value.len;
        hvx_params.p_data = gatts_value.p_value;
        err_code = sd_ble_gatts_hvx(p_cus->conn_handle, &hvx_params);
        //NRF_LOG_INFO("sd_ble_gatts_hvx result: %x. \r\n", err_code);
    }
    else
    {
        err_code = NRF_ERROR_INVALID_STATE;
        //NRF_LOG_INFO("sd_ble_gatts_hvx result: NRF_ERROR_INVALID_STATE. \r\n");
    }
	//NRF_LOG_INFO("outside: %x. \r\n", err_code);
    return err_code;
}

uint32_t ble_cus_custom_char_update_2(ble_cus_t * p_cus, uint8_t * custom_value)	/*NEW CHANGE*/
{
//    NRF_LOG_INFO("Data Sent to Host. \r\n");
    if (p_cus == NULL)
    {
		//NRF_LOG_INFO("in if (p_cus == NULL)");
        return NRF_ERROR_NULL;
    }
    uint32_t err_code = NRF_SUCCESS;
    ble_gatts_value_t gatts_value;
    // Initialize value struct.
    memset(&gatts_value, 0, sizeof(gatts_value));
    gatts_value.len     = RAW_DATA_LENGTH*sizeof(uint8_t);	/*NEW CHANGE*/
    gatts_value.offset  = 0;
    gatts_value.p_value = (uint8_t *)custom_value;
    // Update database.
	/* New Characteristic */
	// Update database.
    err_code = sd_ble_gatts_value_set(p_cus->conn_handle, p_cus->custom_char_handle_2.value_handle, &gatts_value);
	//NRF_LOG_INFO("sd_ble_gatts_value_set: %x. \r\n", err_code);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
	
    // Send value if connected and notifying.
    if ((p_cus->conn_handle != BLE_CONN_HANDLE_INVALID))
    {
        ble_gatts_hvx_params_t hvx_params;
        memset(&hvx_params, 0, sizeof(hvx_params));
 		hvx_params.handle = p_cus->custom_char_handle_2.value_handle;	/* New Characteristic */
        hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
        hvx_params.offset = gatts_value.offset;
        hvx_params.p_len  = &gatts_value.len;
        hvx_params.p_data = gatts_value.p_value;
        err_code = sd_ble_gatts_hvx(p_cus->conn_handle, &hvx_params);
        //NRF_LOG_INFO("sd_ble_gatts_hvx result: %x. \r\n", err_code);
    }
    else
    {
        err_code = NRF_ERROR_INVALID_STATE;
        //NRF_LOG_INFO("sd_ble_gatts_hvx result: NRF_ERROR_INVALID_STATE. \r\n");
    }
	//NRF_LOG_INFO("outside: %x. \r\n", err_code);
    return err_code;
}

/**@brief Function for handling the Connect event.
 * @param[in]   p_cus       Custom Service structure.
 * @param[in]   p_ble_evt   Event received from the BLE stack. */
void cus_on_connect(ble_cus_t * p_cus, ble_evt_t const * p_ble_evt)
{
	NRF_LOG_INFO("Cus on_connect");
    p_cus->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    ble_cus_evt_t evt;
    evt.evt_type = BLE_CUS_EVT_CONNECTED;
    p_cus->evt_handler(p_cus, &evt);
}

/**@brief Function for handling the Disconnect event.
 * @param[in]   p_cus       Custom Service structure.
 * @param[in]   p_ble_evt   Event received from the BLE stack. */
void cus_on_disconnect(ble_cus_t * p_cus, ble_evt_t const * p_ble_evt)
{
	NRF_LOG_INFO("Cus on_disconnect");
    UNUSED_PARAMETER(p_ble_evt);
    p_cus->conn_handle = BLE_CONN_HANDLE_INVALID;
    ble_cus_evt_t evt;
    evt.evt_type = BLE_CUS_EVT_DISCONNECTED;
    p_cus->evt_handler(p_cus, &evt);
}

/**@brief Function for handling the Write event.
 * @param[in]   p_cus       Custom Service structure.
 * @param[in]   p_ble_evt   Event received from the BLE stack. */
static void cus_on_write(ble_cus_t * p_cus, ble_evt_t const * p_ble_evt)
{
	//NRF_LOG_INFO("***************************************************************************");
	uint8_t i;
    ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    // Custom Value Characteristic Written to.
    if (p_evt_write->handle == p_cus->custom_char_handle_1.value_handle)
    {		        
		NRF_LOG_INFO("Char-1 Data Length:::::::::::::: %d", p_evt_write->len);		
        
		// Check for latency & packet drop tests for BLE only
		if ( p_evt_write->len <= MAX_LEN)
        {
            
            for(i = 0; i < p_evt_write->len; i++)
            {
                receive_buffer[i] = p_evt_write->data[i];	
				NRF_LOG_INFO("Char-1 Data :::::::::::::: %d", p_evt_write->data[i]);				
            }
            handle_message();
        }else
        {
            NRF_LOG_INFO("Error in cus_on_write(), message exceeds MAX_LEN");	
        }   
    }
	
	// Custom Value Characteristic Written to.
    if (p_evt_write->handle == p_cus->custom_char_handle_2.value_handle)	/* New Characteristic */
    {		        
		NRF_LOG_INFO("Char-2 Data Length:::::::::::::: %d", p_evt_write->len);		
        
		// Check for latency & packet drop tests for BLE only
		if ( p_evt_write->len <= MAX_LEN)
        {
            
            for(i = 0; i < p_evt_write->len; i++)
            {
                receive_buffer[i] = p_evt_write->data[i];	
				NRF_LOG_INFO("Char-2 Data :::::::::::::: %d", p_evt_write->data[i]);				
            }
            handle_message();
        }
		else
        {
            NRF_LOG_INFO("Error in cus_on_write(), message exceeds MAX_LEN");	
        }   
    }
	
    // Check if the Custom value CCCD is written to and that the value is the appropriate length, i.e 2 bytes.
    if ((p_evt_write->handle == p_cus->custom_char_handle_1.cccd_handle) && (p_evt_write->len == 2))
    {
        // CCCD written, call application event handler
        if (p_cus->evt_handler != NULL)
        {
            ble_cus_evt_t evt;
            if (ble_srv_is_notification_enabled(p_evt_write->data))
            {
				NRF_LOG_INFO("BLE_CUS_EVT_NOTIFICATION_ENABLED\r\n");
                evt.evt_type = BLE_CUS_EVT_NOTIFICATION_ENABLED;
            }
            else
            {
				NRF_LOG_INFO("BLE_CUS_EVT_NOTIFICATION_DISABLED\r\n");
                evt.evt_type = BLE_CUS_EVT_NOTIFICATION_DISABLED;
            }
            // Call the application event handler.
            p_cus->evt_handler(p_cus, &evt);
        }
    }
	
	/* New Characteristic */
	// Check if the Custom value CCCD is written to and that the value is the appropriate length, i.e 2 bytes.
    if ((p_evt_write->handle == p_cus->custom_char_handle_2.cccd_handle) && (p_evt_write->len == 2))
    {
        // CCCD written, call application event handler
        if (p_cus->evt_handler != NULL)
        {
            ble_cus_evt_t evt;
            if (ble_srv_is_notification_enabled(p_evt_write->data))
            {
				NRF_LOG_INFO("BLE_CUS_EVT_NOTIFICATION_ENABLED\r\n");
                evt.evt_type = BLE_CUS_EVT_NOTIFICATION_ENABLED;
            }
            else
            {
				NRF_LOG_INFO("BLE_CUS_EVT_NOTIFICATION_DISABLED\r\n");
                evt.evt_type = BLE_CUS_EVT_NOTIFICATION_DISABLED;
            }
            // Call the application event handler.
            p_cus->evt_handler(p_cus, &evt);
        }
    }
}

void ble_cus_on_ble_evt( ble_evt_t const * p_ble_evt, void * p_context)
{
    ble_cus_t * p_cus = (ble_cus_t *) p_context;
    //NRF_LOG_INFO("BLE event received. Event type = %d\r\n", p_ble_evt->header.evt_id);
    if (p_cus == NULL || p_ble_evt == NULL)
    {
        return;
    }
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:				
			NRF_LOG_INFO("Cus Connected");						
			//NRF_LOG_INFO("BLE_GAP_EVT_CONNECTED= %d\r\n", p_ble_evt->header.evt_id);
            cus_on_connect(p_cus, p_ble_evt);
        break;
        case BLE_GAP_EVT_DISCONNECTED:
			NRF_LOG_INFO("Cus Disconnected");
			//NRF_LOG_INFO("BLE_GAP_EVT_DISCONNECTED= %d\r\n", p_ble_evt->header.evt_id);
            cus_on_disconnect(p_cus, p_ble_evt);
        break;

		case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_PHY_UPDATE_REQUEST");
        break;
		case BLE_GAP_EVT_RSSI_CHANGED:	/*Testing*/	/*rssi*/
            NRF_LOG_INFO("CUSTOM GATT -- Changed RSSI: %d dBm", p_ble_evt->evt.gap_evt.params.rssi_changed.rssi);
        break;        
		case BLE_GAP_EVT_CONN_PARAM_UPDATE:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_CONN_PARAM_UPDATE");
		break;
		case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_SEC_PARAMS_REQUEST");
		break;
		case BLE_GAP_EVT_SEC_INFO_REQUEST:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_SEC_INFO_REQUEST");
		break;
		case BLE_GAP_EVT_PASSKEY_DISPLAY:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_PASSKEY_DISPLAY");
		break;
		case BLE_GAP_EVT_KEY_PRESSED:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_KEY_PRESSED");
		break;
		case BLE_GAP_EVT_AUTH_KEY_REQUEST:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_AUTH_KEY_REQUEST");
		break;
		case BLE_GAP_EVT_LESC_DHKEY_REQUEST:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_LESC_DHKEY_REQUEST");
		break;
		case BLE_GAP_EVT_AUTH_STATUS:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_AUTH_STATUS");
		break;
		case BLE_GAP_EVT_CONN_SEC_UPDATE:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_CONN_SEC_UPDATE");
		break;
		case BLE_GAP_EVT_SEC_REQUEST:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_SEC_REQUEST");
		break;
		case BLE_GAP_EVT_SCAN_REQ_REPORT:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_SCAN_REQ_REPORT");
		break;
		case BLE_GAP_EVT_PHY_UPDATE:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_PHY_UPDATE");
		break;
		case BLE_GAP_EVT_TIMEOUT:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_TIMEOUT");
		break;
		case BLE_GAP_EVT_ADV_REPORT :
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_ADV_REPORT");
		break;
		case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST");
		break;
		case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST");
		break;
		case BLE_GAP_EVT_DATA_LENGTH_UPDATE:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_DATA_LENGTH_UPDATE");
		break;
		case BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT");
		break;
		case BLE_GAP_EVT_ADV_SET_TERMINATED:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GAP_EVT_ADV_SET_TERMINATED");
		break;
		
		case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, client_rx_mtu: %d", p_ble_evt->evt.gatts_evt.params.exchange_mtu_request.client_rx_mtu);
		break;
        case BLE_GATTS_EVT_WRITE:
			NRF_LOG_INFO("CUSTOM GATT -- Cus Writing");
			//NRF_LOG_INFO("BLE_GATTS_EVT_WRITE= %d\r\n", p_ble_evt->header.evt_id);
            cus_on_write(p_cus, p_ble_evt);
        break;		
		case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
			NRF_LOG_INFO("BCUSTOM GATT -- LE_GATTS_EVT_RW_AUTHORIZE_REQUEST");
		break;
		case BLE_GATTS_EVT_SYS_ATTR_MISSING:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTS_EVT_SYS_ATTR_MISSING");
		break;
		case BLE_GATTS_EVT_HVC:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTS_EVT_HVC");
		break;
		case BLE_GATTS_EVT_SC_CONFIRM:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTS_EVT_SC_CONFIRM");
		break;
		case BLE_GATTS_EVT_TIMEOUT:
            // Disconnect on GATT Server timeout event.
            NRF_LOG_DEBUG("CUSTOM GATT -- GATT Server Timeout. -BLE_GATTS_EVT_TIMEOUT");
            //err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            //APP_ERROR_CHECK(err_code);
        break;
		case BLE_GATTS_EVT_HVN_TX_COMPLETE:
           //NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTS_EVT_HVN_TX_COMPLETE");
           check_for_buffer_sending();  /* For qspi - Reading a buffer */
           sensor_report_sending = false;      
        break;
				
		case BLE_GATTC_EVT_TIMEOUT:
            // Disconnect on GATT Client timeout event.
            NRF_LOG_DEBUG("CUSTOM GATT -- GATT Client Timeout.-BLE_GATTC_EVT_TIMEOUT");
            //err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            //APP_ERROR_CHECK(err_code);
        break;
        case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP");
        break;
		case BLE_GATTC_EVT_REL_DISC_RSP:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTC_EVT_REL_DISC_RSP");
        break;
		case BLE_GATTC_EVT_CHAR_DISC_RSP:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTC_EVT_CHAR_DISC_RSP");
        break;
		case BLE_GATTC_EVT_DESC_DISC_RSP:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTC_EVT_DESC_DISC_RSP");
        break;
		case BLE_GATTC_EVT_ATTR_INFO_DISC_RSP:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTC_EVT_ATTR_INFO_DISC_RSP");
        break;
		case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP");
        break;
		case BLE_GATTC_EVT_READ_RSP:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTC_EVT_READ_RSP");
        break;
		case BLE_GATTC_EVT_CHAR_VALS_READ_RSP:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTC_EVT_CHAR_VALS_READ_RSP");
        break;
		case BLE_GATTC_EVT_WRITE_RSP:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTC_EVT_WRITE_RSP");
        break;
		case BLE_GATTC_EVT_HVX:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTC_EVT_HVX");
        break;
		case BLE_GATTC_EVT_EXCHANGE_MTU_RSP:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTC_EVT_EXCHANGE_MTU_RSP");
        break;
		case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE:
			NRF_LOG_INFO("CUSTOM GATT -- BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE");
        break;
        default:
        break;
    }
}
