
#include <stdint.h>
#include <string.h>

#include "ble_tpls.h"
#include "nrf_gpio.h"
#include "app_error.h"
#include "SEGGER_RTT.h"
#include "ble_srv_common.h"

/**@brief Function for handling the Connect event.
 *
 * @param[in]   p_our_service	LED Button Service structure.
 * @param[in]   p_ble_evt		Event received from the BLE stack.
 */
static void on_connect( ble_tpls_t * p_tpls, ble_evt_t const * p_ble_evt )
{
    p_tpls->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
}
//
 
/**@brief Function for handling the Disconnect event.
 *
 * @param[in]   p_our_service	LED Button Service structure.
 * @param[in]   p_ble_evt		Event received from the BLE stack.
 */
static void on_disconnect( ble_tpls_t * p_tpls, ble_evt_t const * p_ble_evt )
{
    UNUSED_PARAMETER(p_ble_evt);
    p_tpls->conn_handle = BLE_CONN_HANDLE_INVALID;
}
//
 
/**@brief Function for handling the Write event.
 *
 * @param[in]   p_midi_service   LED Button Service structure.
 * @param[in]   p_ble_evt        Event received from the BLE stack.
 */
static void on_write( ble_tpls_t * p_tpls, ble_evt_t const * p_ble_evt )
{
    ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
    
    if ( ( p_evt_write->handle == p_tpls->char_handles.value_handle ) &&
         ( p_evt_write->len == 1 ) &&
         ( p_tpls->tx_power_level_handler != NULL ) )
    {
        p_tpls->tx_power_level_handler( p_tpls, p_evt_write->data[ 0 ] );
    }
}
//
 
//void ble_tpls_on_ble_evt( ble_tpls_t * p_tpls, ble_evt_t const * p_ble_evt)
void ble_tpls_on_ble_evt(  ble_evt_t const * p_ble_evt, void * p_context )
{
	ble_tpls_t * p_tpls = ( ble_tpls_t * )p_context;
	
	switch( p_ble_evt->header.evt_id )
	{
        case BLE_GAP_EVT_CONNECTED:
            on_connect( p_tpls, p_ble_evt);
            break;
            
        case BLE_GAP_EVT_DISCONNECTED:
            on_disconnect( p_tpls, p_ble_evt);
            break;
            
        case BLE_GATTS_EVT_WRITE:
            on_write( p_tpls, p_ble_evt);
            break;
            
        default:
            // No implementation needed.
            break;
	}
}
//

/**@brief Function for adding our new characterstic to "Our service" that we initiated in the previous tutorial. 
 *
 * @param[in]   p_our_service        Our Service structure.
 *
 */
static uint32_t char_add( ble_tpls_t * p_tpls, ble_tpls_init_t const * p_tpls_init )
{
    // OUR_JOB: Step 2.A, Add a custom characteristic UUID
    uint32_t 		err_code;
	ble_uuid_t		char_uuid;
	ble_uuid128_t	base_uuid = BLE_UUID_TPC_BASE_UUID;
	
	char_uuid.uuid  = BLE_UUID_TPC_CHARACTERISTC_UUID;
	
	err_code = sd_ble_uuid_vs_add( &base_uuid, &char_uuid.type );
	APP_ERROR_CHECK( err_code );
	
    ble_gatts_char_md_t char_md;
    memset(&char_md, 0, sizeof(char_md));
	
	char_md.char_props.read = 1;
	char_md.char_props.write = 1;

    ble_gatts_attr_md_t attr_md;
    memset(&attr_md, 0, sizeof(attr_md));  
	attr_md.vloc = BLE_GATTS_VLOC_STACK;
    
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
	BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
    
    ble_gatts_attr_t    attr_char_value;
    memset(&attr_char_value, 0, sizeof(attr_char_value));
	
	attr_char_value.p_uuid 		= &char_uuid;
	attr_char_value.p_attr_md 	= &attr_md;
    
	attr_char_value.max_len 	= 1;
	attr_char_value.init_len 	= 1;
	
	uint8_t value	 			= p_tpls_init->tx_power_level;
	attr_char_value.p_value 	= &value;

    // OUR_JOB: Step 2.E, Add our new characteristic to the service
	err_code = sd_ble_gatts_characteristic_add( p_tpls->service_handle, &char_md, &attr_char_value, &p_tpls->char_handles );
	APP_ERROR_CHECK( err_code );
	
    return NRF_SUCCESS;
}
//

/**@brief Function for initiating our new service.
 *
 * @param[in]   p_tpls        Tx Power Level Service structure.
 *
 */
uint32_t ble_tpls_init( ble_tpls_t * p_tpls, ble_tpls_init_t const * p_tpls_init )
{
    uint32_t			err_code;
    ble_uuid_t			service_uuid;
    ble_uuid128_t		base_uuid = BLE_UUID_TPC_BASE_UUID;
	
    err_code = sd_ble_uuid_vs_add(&base_uuid, &p_tpls->uuid_type);
    APP_ERROR_CHECK(err_code);    
    
    service_uuid.uuid = BLE_UUID_TPC_SERVICE_UUID;
	service_uuid.type = p_tpls->uuid_type;
	
	p_tpls->conn_handle = BLE_CONN_HANDLE_INVALID;
	
    err_code = sd_ble_gatts_service_add( BLE_GATTS_SRVC_TYPE_PRIMARY,
                                        &service_uuid,
                                        &p_tpls->service_handle );
    
    APP_ERROR_CHECK(err_code);
     
    return char_add( p_tpls, p_tpls_init );
}
//

