/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved.
 *
 * The information contained herein is property of Nordic Semiconductor ASA.
 * Terms and conditions of usage are described in detail in NORDIC
 * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
 *
 * Licensees are granted free, non-transferable use of the information. NO
 * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
 * the file.
 *
 * $LastChangedRevision$
 */
/** @file Project-specific parameters and helper functions.
 *
 */
#ifndef __PROJECT_PARAMS_H__
#define __PROJECT_PARAMS_H__

#include <string.h>

#include "ble_types.h"
#include "m_coms.h"
#include "nrf51.h"

#define MERGE_DESCRIPTORS

/** Audio module */
#define INPUT_REPORT_COUNT     1 
#define INPUT_REP_AUDIO_LEN   20
#define INPUT_REP_AUDIO_ID     2
#define OUTPUT_REPORT_COUNT    1 
#define OUTPUT_REP_AUDIO_LEN   1
#define OUTPUT_REP_AUDIO_ID    1

/** Smart Remote */
#define OUTPUT_REPORT_KEYBOARD_MAX_LEN    1    /**< Maximum length of Output Report. */
#define OUTPUT_REPORT_BIT_MASK_CAPS_LOCK  0x02 /**< CAPS LOCK bit in Output Report (based on 'LED Page (0x08)' of the Universal Serial Bus HID Usage Tables). */
#define INPUT_REPORT_KEYS_MAX_LEN         8
                                          
#define INPUT_REP_BUTTONS_LEN             3    /**< Length of Mouse Input Report containing button data.               */
#define INPUT_REP_MOVEMENT_LEN            3    /**< Length of Mouse Input Report containing movement data.             */
#define INPUT_REP_MPLAYER_LEN             1    /**< Length of Mouse Input Report containing media player data.         */

#ifdef MERGE_DESCRIPTORS
    #define INPUT_REP_KEYBOARD_ID         3    /**< Id of reference to Keyboard Input Report. */
    #define OUTPUT_REP_KEYBOARD_ID        3    /**< Id of reference to Keyboard Output Report. */
    #define INPUT_REP_BUTTONS_ID          4    /**< Id of reference to Mouse Input Report containing button data.      */
    #define INPUT_REP_MOVEMENT_ID         5    /**< Id of reference to Mouse Input Report containing movement data.    */
    #define INPUT_REP_MPLAYER_ID          6    /**< Id of reference to Mouse Input Report containing media player data.*/    
#else                                     
    #define INPUT_REP_KEYBOARD_ID         1    /**< Id of reference to Keyboard Input Report. */
    #define OUTPUT_REP_KEYBOARD_ID        1    /**< Id of reference to Keyboard Output Report. */
    #define INPUT_REP_BUTTONS_ID          2    /**< Id of reference to Mouse Input Report containing button data.      */
    #define INPUT_REP_MOVEMENT_ID         3    /**< Id of reference to Mouse Input Report containing movement data.    */
    #define INPUT_REP_MPLAYER_ID          4    /**< Id of reference to Mouse Input Report containing media player data.*/    
    
    static const uint8_t s_audio_hid_desc[] =
    {
        0x06, 0x00, 0xFF,               // Usage Page (Vendor defined page 1)
        0x09, 0x00,                     // Usage (Vendor Usage 1)
        0xA1, 0x01,                     // Collection (Application)
        0x85, INPUT_REP_AUDIO_ID,       //     Report Id (2)
        0x15, 0x00,                     //     Logical minimum (0)
        0x25, 0xFF,                     //     Logical maximum (255)
        0x75, 0x08,                     //     Report size (8 bit)
        0x95, 0x14,                     //     Report count (20)
        0x09, 0x00,                     //     Usage (Vendor Usage 1)
        0x81, 0x02,                     //     Input (Data,Var,Abs)
        0x85, OUTPUT_REP_AUDIO_ID,      //     Report Id (1)
        0x95, 0x01,                     //     Report Count (1)
        0x75, 0x08,                     //     Report Size (8)
        0x09, 0x00,                     //     Usage (Vendor Usage 1)
        0x91, 0x02,                     //     Output (Data,Var,Abs)
        0xC0                            // End Collection
    };    
#endif


static const uint8_t s_sm_hid_desc[] =
{
    #ifdef MERGE_DESCRIPTORS
    // Input Report ID 5 and output report ID 2: Audio input and output report
    0x06, 0x00, 0xFF,               // Usage Page (Vendor defined page 1)
    0x09, 0x00,                     // Usage (Vendor Usage 1)
    0xA1, 0x01,                     // Collection (Application)
    0x85, INPUT_REP_AUDIO_ID,       //     Report Id (2)
    0x15, 0x00,                     //     Logical minimum (0)
    0x25, 0xFF,                     //     Logical maximum (255)
    0x75, 0x08,                     //     Report size (8 bit)
    0x95, 0x14,                     //     Report count (20)
    0x09, 0x00,                     //     Usage (Vendor Usage 1)
    0x81, 0x02,                     //     Input (Data,Var,Abs)
    0x85, OUTPUT_REP_AUDIO_ID,      //     Report Id (1)
    0x95, 0x01,                     //     Report Count (1)
    0x75, 0x08,                     //     Report Size (8)
    0x09, 0x00,                     //     Usage (Vendor Usage 1)
    0x91, 0x02,                     //     Output (Data,Var,Abs)
    0xC0,                            // End Collection    
    #endif    
    
    0x05, 0x01,                 // Usage Page (Generic Desktop)
    0x09, 0x06,                 // Usage (Keyboard)
    0xA1, 0x01,                 // Collection (Application)
    
    // Report ID 1: Keyboard keys
    0x85, INPUT_REP_KEYBOARD_ID,//     Report Id 3 
    0x05, 0x07,                 //     Usage Page (Key Codes)
    0x19, 0xe0,                 //     Usage Minimum (224)
    0x29, 0xe7,                 //     Usage Maximum (231)
    0x15, 0x00,                 //     Logical Minimum (0)
    0x25, 0x01,                 //     Logical Maximum (1)
    0x75, 0x01,                 //     Report Size (1)
    0x95, 0x08,                 //     Report Count (8)
    0x81, 0x02,                 //     Input (Data, Variable, Absolute)

    0x95, 0x01,                 //     Report Count (1)
    0x75, 0x08,                 //     Report Size (8)
    0x81, 0x01,                 //     Input (Constant) reserved byte(1)

    0x95, 0x05,                 //     Report Count (5)
    0x75, 0x01,                 //     Report Size (1)
    0x05, 0x08,                 //     Usage Page (Page# for LEDs)
    0x19, 0x01,                 //     Usage Minimum (1)
    0x29, 0x05,                 //     Usage Maximum (5)
    0x91, 0x02,                 //     Output (Data, Variable, Absolute), Led report
    0x95, 0x01,                 //     Report Count (1)
    0x75, 0x03,                 //     Report Size (3)
    0x91, 0x01,                 //     Output (Data, Variable, Absolute), Led report padding

    0x95, 0x06,                 //     Report Count (6)
    0x75, 0x08,                 //     Report Size (8)
    0x15, 0x00,                 //     Logical Minimum (0)
    0x25, 0x65,                 //     Logical Maximum (101)
    0x05, 0x07,                 //     Usage Page (Key codes)
    0x19, 0x00,                 //     Usage Minimum (0)
    0x29, 0x65,                 //     Usage Maximum (101)
    0x81, 0x00,                 //     Input (Data, Array) Key array(6 bytes)

    0x09, 0x05,                 //     Usage (Vendor Defined)
    0x15, 0x00,                 //     Logical Minimum (0)
    0x26, 0xFF, 0x00,           //     Logical Maximum (255)
    0x75, 0x08,                 //     Report Count (2)
    0x95, 0x02,                 //     Report Size (8 bit)
    0xB1, 0x02,                 //     Feature (Data, Variable, Absolute)

    0xC0,                       // End Collection (Application)
    
    0x05, 0x01,                     // Usage Page (Generic Desktop)
    0x09, 0x02,                     // Usage (Mouse)

    0xA1, 0x01,                     // Collection (Application)

    // Report ID 2: Mouse buttons + scroll/pan
    0x85, INPUT_REP_BUTTONS_ID, //     Report Id 4 
    0x09, 0x01,                     //     Usage (Pointer)
    0xA1, 0x00,                     //     Collection (Physical)
    0x95, 0x05,                     //         Report Count (3)
    0x75, 0x01,                     //         Report Size (1)
    0x05, 0x09,                     //         Usage Page (Buttons)
    0x19, 0x01,                     //             Usage Minimum (01)
    0x29, 0x05,                     //             Usage Maximum (05)
    0x15, 0x00,                     //             Logical Minimum (0)
    0x25, 0x01,                     //             Logical Maximum (1)
    0x81, 0x02,                     //             Input (Data, Variable, Absolute)
    0x95, 0x01,                     //             Report Count (1)
    0x75, 0x03,                     //             Report Size (3)
    0x81, 0x01,                     //             Input (Constant) for padding
    0x75, 0x08,                     //             Report Size (8)
    0x95, 0x01,                     //             Report Count (1)
    0x05, 0x01,                     //         Usage Page (Generic Desktop)
    0x09, 0x38,                     //             Usage (Wheel)
    0x15, 0x81,                     //             Logical Minimum (-127)
    0x25, 0x7F,                     //             Logical Maximum (127)
    0x81, 0x06,                     //             Input (Data, Variable, Relative) 
    0x05, 0x0C,                     //         Usage Page (Consumer)
    0x0A, 0x38, 0x02,               //             Usage (AC Pan) 
    0x95, 0x01,                     //             Report Count (1)
    0x81, 0x06,                     //             Input (Data,Value,Relative,Bit Field)
    0xC0,                           //     End Collection (Physical)

    // Report ID 3: Mouse motion
    0x85, INPUT_REP_MOVEMENT_ID,//     Report Id 5 
    0x09, 0x01,                     //     Usage (Pointer)
    0xA1, 0x00,                     //     Collection (Physical)
    0x75, 0x0C,                     //         Report Size (12)
    0x95, 0x02,                     //         Report Count (2)
    0x05, 0x01,                     //         Usage Page (Generic Desktop)
    0x09, 0x30,                     //             Usage (X)                                                  
    0x09, 0x31,                     //             Usage (Y)
    0x16, 0x01, 0xF8,               //             Logical maximum (2047) 
    0x26, 0xFF, 0x07,               //             Logical minimum (-2047) 
    0x81, 0x06,                     //             Input (Data, Variable, Relative) 
    0xC0,                           //     End Collection (Physical) 
    0xC0,                           // End Collection (Application)

    // Report ID 4: Advanced buttons
    0x05, 0x0C,                     // Usage Page (Consumer)
    0x09, 0x01,                     // Usage (Consumer Control) 
    0xA1, 0x01,                     // Collection (Application)
    0x85, INPUT_REP_MPLAYER_ID, //     Report Id (6) 
    0x15, 0x00,                     //     Logical minimum (0)
    0x25, 0x01,                     //     Logical maximum (1) 
    0x75, 0x01,                     //     Report Size (1)
    0x95, 0x01,                     //     Report Count (1)

    0x09, 0xCD,                     //     Usage (Play/Pause) 
    0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field)
    0x0A, 0x83, 0x01,               //     Usage (AL Consumer Control Configuration) 
    0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field)
    0x09, 0xB5,                     //     Usage (Scan Next Track)
    0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field)   
    0x09, 0xB6,                     //     Usage (Scan Previous Track)
    0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field) 

    0x09, 0xEA,                     //     Usage (Volume Down)
    0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field) 
    0x09, 0xE9,                     //     Usage (Volume Up) 
    0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field) 
    0x0A, 0x25, 0x02,               //     Usage (AC Forward) 
    0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field) 
    0x0A, 0x24, 0x02,               //     Usage (AC Back) 
    0x81, 0x06,                     //     Input (Data,Value,Relative,Bit Field) 
    0xC0,                            // End Collection
};

/**@brief Convenience function to fill parameter struct.
 *
 * @param[in] ble_params
 */
static __inline void M_COMS_BLE_PARAMS_FILL(m_coms_ble_params_t * ble_params)
{
    memset(ble_params, 0, sizeof(m_coms_ble_params_t));
    
    // Device information
    ble_params->device_info.device_name       = "Smart Remote 2";   
    ble_params->device_info.manufacturer_name = "NordicSemi";  
    ble_params->device_info.fw_revision       = "2.0.0";                
    ble_params->device_info.hw_revision       = 0;          // Don't have a specific hardware revision yet
    ble_params->device_info.serial_number     = 0;          // Could use NRF_FICR->DEVICEID
    ble_params->device_info.pnp_product_id        = 0xEEEE; // PNP ID product ID
    ble_params->device_info.pnp_product_version   = 0x0001; // PNP ID product version
    ble_params->device_info.pnp_vendor_id         = 0x1915; // PNP ID vendor ID
    ble_params->device_info.pnp_vendor_id_src     = 0x02;   // @ref BLE_DIS_VENDOR_ID_SRC_BLUETOOTH_SIG or @ref BLE_DIS_VENDOR_ID_SRC_USB_IMPL_FORUM
    
    
    // Bond behavior parameters:
    ble_params->bond_params.directed_adv       = true; // Use directed advertising vs bonded central devices.
    ble_params->bond_params.change_address     = true; // Change device address for each new bond. 
                                                       // This prevents previously connected masters from attempting reconnect.
    ble_params->bond_params.bond_reconnect_all = true; // When pairing button is pressed: 
                                                       // Attempt reconnection to other bonded masters before advertising as bondable.
    ble_params->bond_params.reconnect_all      = false;// Do not normally try to reconnect to every master, only the latest used one.
    
    // Preferred connection parameters
    ble_params->conn_params.min_conn_interval = MSEC_TO_UNITS(7.5, UNIT_1_25_MS);  // Minimum connection interval. In units of 1.25 ms. 
    ble_params->conn_params.max_conn_interval = MSEC_TO_UNITS(7.5, UNIT_1_25_MS);  // Maximum connection interval. In units of 1.25 ms.
    ble_params->conn_params.slave_latency     = 99; // Number of connection events the Peripheral can skip. 
                                                     // Note that this introduces delay in Central -> Peripheral communication
    ble_params->conn_params.conn_sup_timeout  = 600; // Connection timeout in units of 100 ms. If link members i.e. loses power it takes this long
                                                     // before the connection is considered dead.
    // Security parameters
    ble_params->sec_params.io_capabilities = BLE_GAP_IO_CAPS_NONE; // See @ref BLE_GAP_IO_CAPS for valid numbers.
    ble_params->sec_params.oob_data_availible = false;
    
    // Misc parameters
    ble_params->appearance       = BLE_APPEARANCE_GENERIC_HID;
    ble_params->base_hid_version = 0x0101; // Version number of base USB HID Specification implemented by this device
    ble_params->hid_country_code = 0;      // Country code can be used to specify which country the hardware is localized for. Most hardware is not localized (value 0).
    ble_params->max_tx_buf_cnt   = 2;      // Only allow 2 packets to be in SoftDevice TX buffer at a time to reduce max interrupt latency
    // HID Service flags: 
    // Remote wakeup indicates that this device considers itself capable of wakeing up the Central device
    // Normally connectable flag indicates that this device is normally advertising (and can be connected to) when not already connected.
    ble_params->hids_flags       =  HID_INFO_FLAG_REMOTE_WAKE_MSK | HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK;    
    
    
    //
    // Parameters not initialized: THESE MUST BE INITIALIZED IN APPLICATION
    //
    ble_params->boot_mode_callback = 0; // Callback function used to translate HID reports into boot format when needed
}

/**@brief Convenience function to fill parameter struct.
 *
 * @param[in] ble_params Parameters to 
 */
static __inline void M_COMS_GZLL_PARAMS_FILL(m_coms_gzll_params_t * gzll_params)
{
    memset(gzll_params, 0, sizeof(m_coms_gzll_params_t));
    
    // Device information
    gzll_params->encrypt=false;  /** Make encrypted pipe available */
    gzll_params->tx_attempts = 400;
    gzll_params->timeslot_period = 504; //Should be the the LU1 dongle RX_PERIOD / 2
    gzll_params->sync_lifetime=1000;

    
}

#endif /* __PROJECT_PARAMS_H__ */
