/* 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.*/

/* @file
*
* @defgroup ble_sdk_srv_ansc Apple Notification Client Service
* @{
* @ingroup ble_sdk_srv
* @brief Apple Notification central module.
*
* @details This module implements the Apple  Notification  central according to the
* Apple Notification central Profile.
*
* @note The application must propagate BLE stack events to the Apple Notification center module
* by calling ble_ancs_on_ble_evt() from the from the @ref ble_stack_handler callback.
*/
#ifndef BLE_ANCS_H__
#define BLE_ANCS_H__

#include "ble.h"
#include "ble_gatts.h"
#include "ble_types.h"
#include "ble_bondmngr.h"

#define ANCS_NB_OF_CHARACTERISTICS                   3                                     /**< Number of characteristics as defined by Apple Notification Service specification. */
#define ANCS_NB_OF_SERVICES                          1                                     /**< Number of services supported in one master. */
#define INVALID_SERVICE_HANDLE_BASE                 0xF0                                  /**< Base for indicating invalid service handle. */
#define INVALID_SERVICE_HANDLE                      (INVALID_SERVICE_HANDLE_BASE + 0x0F)  /**< Indication that the current service handle is invalid. */
#define INVALID_SERVICE_HANDLE_DISC                 (INVALID_SERVICE_HANDLE_BASE + 0x0E)  /**< Indication that the current service handle is invalid but the service has been discovered. */
#define BLE_ANCS_INVALID_HANDLE                      0xFF                                  /**< Indication that the current service handle is invalid. */

// Forward declaration of the ble_ancs_t type.
typedef struct ble_ancs_s ble_ancs_t;

/* Apple types as defined in the apple category id at Notification Source; UUID: 0x120D. */
typedef enum
{
    ANS_TYPE_OTHER                           = 0,                                  /*< CategoryIDOther.*/
    ANS_TYPE_INCOMINGCALL                    = 1,                                  /*< CategoryIDIncomingCall.*/
    ANS_TYPE_MISSEDCALL                      = 2,                                  /*< CategoryIDMissedCall.*/
    ANS_TYPE_VOICEMAIL                       = 3,                                  /*< CategoryIDVoicemail.*/
    ANS_TYPE_SOCIAL                          = 4,                                  /*< CategoryIDSocial.*/
    ANS_TYPE_SCHEDULE                        = 5,                                  /*< CategoryIDSchedule.*/
    ANS_TYPE_EMAIL                           = 6,                                  /*< CategoryIDEmail.*/
    ANS_TYPE_NEWS                            = 7,                                  /*< CategoryIDNews.*/
    ANS_TYPE_HEALTHANDFITNESS                = 8,                                  /*< CategoryIDHealthAndFitness.*/
    ANS_TYPE_BUSINESSANDFINANCE              = 9,                                  /*< CategoryIDBusinessAndFinance.*/
    ANS_TYPE_LOCATION                        = 10,                                 /*< CategoryIDLocation.*/
    ANS_TYPE_ENTERTAINMENT                   = 11,                                 /*< CategoryIDEntertainment.*/
    ANS_TYPE_ALL_ALERTS                      = 0xFF                                /*< Reserved CategoryID values. */
} ble_ancs_category_id_t;

/* Apple types as defined in the apple EventID at Notification Source; UUID: 0x120D. */
typedef enum
{
    EVENT_TYPE_ADDED    = 0, //when the new event add
    EVENT_TYPE_MODIFIED = 1, //when the the event modified
    EVENT_TYPE_REMOVED  = 2, //when the event remove,by user peer device
    EVENT_TYPE_Reserved = 3 //other event status,should not have
} ble_ancs_event_id_t;

/* MACRO EventFlags at Notification Source; UUID: 0x120D. */
#define EVENTFLAGSILENT 1<<0
#define EVENTFLAGIMPORTANT 1<<1
#define EVENTFLAGSRESERVED (1 << 2)

#define BLE_APP_NOTIFI_SOURCE   0x120D
#define BLE_APP_CONTROL_POINT   0xD8F3
#define BLE_APP_DATA_SOURCE     0xC6E9
/* Apple notification control point commands to retrieve more information abous ios notification;
 * UUID: 0xD8F3.CommandID Values
 */
typedef enum
{
    ANCS_GET_NOT_ATT = 0, //to retrieven the notification information with NotificationAttributeID
    ANCS_GET_APP_ATT = 1, //to retrieven the application information with application AttributeID
    ANCS_RESERVED    = 2, //reserved furture
} ble_ancs_command_id_t;

/* Apple notification control point commands to retrieve more information abous ios notification;
 * UUID: 0xD8F3. NotificationAttributeID Values
 */
typedef enum
{
    ANCS_NOT_ATT_APPID      = 0,
    ANCS_NOT_ATT_TITLE      = 1, //needs to be followed by a 2-bytes max length parameter
    ANCS_NOT_ATT_SUBTITLE   = 2, //needs to be followed by a 2-bytes max length parameter
    ANCS_NOT_ATT_MESSAGE    = 3, //needs to be followed by a 2-bytes max length parameter
    ANCS_NOT_ATT_MESSAGESIZE = 4,
    ANCS_NOT_ATT_DATE       = 5,
    ANCS_RESERVEDCOMM       = 6 //Reserved furture
} ble_ancs_notifatt_id_t;

/**@brief Apple Notification Event types that are passed from client to application on an event. */
typedef enum
{
    BLE_ANCS_C_EVT_DISCOVER_COMPLETE,                                                      /**< A successful connection has been established and the characteristics of the server has been fetched. */
    BLE_ANCS_C_EVT_DISCOVER_FAILED,                                                        /**< It was not possible to discover service or characteristics of the connected peer. */
    BLE_ANCS_C_EVT_RECONNECT,                                                              /**< A re-connection to a known and previously discovered master has occurred. */
    BLE_ANCS_C_EVT_DISCONN_COMPLETE,                                                       /**< The connection has been taken down. */
    BLE_ANCS_C_EVT_NOTIFICATION,                                                           /**< A valid Alert Notification has been received from the server.*/
    BLE_ANCS_C_EVT_READ_RESP,                                                              /**< A read response has been received from the server.*/
    BLE_ANCS_C_EVT_WRITE_RESP                                                              /**< A write response has been received from the server.*/
} ble_ancs_evt_type_t;

/**@brief Apple Notification Control Point structure. */
typedef struct
{
    ble_ancs_command_id_t
    command;                                          /*< The command to be written to the control point, see @ref ble_ans_command_id_t. */
    uint32_t NotificationUID;
    /*<  The 32-bit numerical value that is the UID of the iOS notification the following attributes correspond to.*/
    uint8_t AttributeList[10];  //A list of AttributeIDs/16-bit Length/Attribute tuples. An attribute is always a string whose length in bytes is provided in the tuple, but which is not NULL-terminated. If a requested attribute is empty or missing for the iOS notification, its length is set to 0.
} ble_ancs_control_point_t;

/**@brief Apple Notification Setting structure containing the supported alerts in the service.
  *
  *@details
  * The structure contains bit fields describing which alerts that are supported:
  * 0 = Unsupported
  * 1 = Supported
  */
typedef struct
{
uint8_t                             ancs_other_support           :
    1;           /*< Support for General text alert or non-text alert.*/
uint8_t                             ancs_incomingcall_support                  :
    1;           /*< Support for Alert when email messages arrives.*/
uint8_t                             ancs_missedcall_support                   :
    1;           /*< Support for News feeds such as RSS, Atom.*/
    uint8_t                             ancs_voicemail_support      : 1;           /*< Support for Incoming call.*/
    uint8_t                             ancs_social_support            : 1;           /*< Support for Missed call.*/
uint8_t                             ancs_schedule_support                :
    1;           /*< Support for SMS/MMS message arrives.*/
    uint8_t                             ancs_email_support             : 1;           /*< Support for Voice mail.*/
uint8_t                             ancs_news_support               :
    1;           /*< Support for Alert occurred on calendar, planner.*/
uint8_t                             ancs_healthandfitness_support :
    1;           /*< Support for Alert that should be handled as high priority.*/
uint8_t                             ancs_businessandfinance_support        :
    1;           /*< Support for Alert for incoming instant messages.*/
uint8_t                             ancs_location_support        :
    1;           /*< Support for Alert for incoming instant messages.*/
uint8_t                             ancs_entertainment_support        :
    1;           /*< Support for Alert for incoming instant messages.*/
    uint8_t                             reserved                           : 6;           /*< Reserved for future use. */
} ble_ancs_settings_t;

/**@brief Apple Notification structure
 * eventid,categoryid,categorycount,notificationuid
 */
typedef struct
{
    uint8_t u8EventID ; //ble_ancs_event_id_t enum
    uint8_t u8CategoryID; //ble_ancs_category_id_t
    uint8_t u8CategoryCount;
    uint8_t u8NotiUID[4];
} ble_ancs_notification_t;

/**@brief Apple Notification Event structure
u8 *
 * @details The structure contains the event that should be handled, as well as
 *          additional information.
 */
typedef struct
{
    ble_ancs_evt_type_t                evt_type;                                         /**< Type of event. */
    ble_uuid_t
    uuid;                                             /**< UUID of the event in case of an alert or notification. */
    union
    {
        ble_ancs_settings_t
        settings;                                         /**< Setting returned from server on read request. */
        ble_ancs_notification_t
        alert;                                            /**< Alert Notification data sent by the server. */
        uint32_t
        error_code;                                       /**< Additional status/error code if the event was caused by a stack error or gatt status, e.g. during service discovery. */
    } data;
} ble_ancs_evt_t;

/**@brief Apple Notification event handler type. */
typedef void (*ble_ancs_evt_handler_t) (ble_ancs_evt_t * p_evt);

/**@brief Apple Notification structure. This contains various status information for the client. */
typedef struct ble_ancs_s
{
    uint8_t                  						uuid_type;               /**< UUID type for Apple ANCS Service Base UUID. */
    ble_ancs_evt_handler_t
    evt_handler;                                      /**< Event handler to be called for handling events in the Apple Notification Center Application. */
    ble_srv_error_handler_t
    error_handler;                                    /**< Function to be called in case of an error. */
    uint16_t
    conn_handle;                                      /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */
    int8_t
    master_handle;                                    /**< Handle for the currently connected master if we have a bond in the bond manager. */
    uint8_t
    service_handle;                                   /**< Handle to the service in the database to use for this instance. for the assigned the sd_ble_uuid_vs_add  */
    uint32_t
    message_buffer_size;                              /**< Size of message buffer to hold the additional text messages received on notifications. */
    uint8_t *
    p_message_buffer;                                 /**< Pointer to the buffer to be used for additional text message handling. */
} ble_ancs_t;

/**@brief Apple Notification init structure. This contains all options and data needed for
 *        initialization of the client.*/
typedef struct
{
    ble_ancs_evt_handler_t
    evt_handler;                                      /**< Event handler to be called for handling events in the Battery Service. */
    ble_srv_error_handler_t
    error_handler;                                    /**< Function to be called in case of an error. */
    uint32_t
    message_buffer_size;                              /**< Size of buffer to handle messages. */
    uint8_t *
    p_message_buffer;                                 /**< Pointer to buffer for passing messages. */
    uint8_t
    flash_page_num;                                   /**< Flash page number to use for storing data. */
} ble_ancs_init_t;


/**@brief Function for handling the Application's BLE Stack events.
 *
 * @details Handles all events from the BLE stack of interest to the Apple Notification Client.
 *
 * @param[in]   p_ancs     Apple Notification Client structure.
 * @param[in]   p_ble_evt  Event received from the BLE stack.
 */
void ble_ancs_on_ble_evt(ble_ancs_t * p_ans, const ble_evt_t * p_ble_evt);


/**@brief Function for handling the Apple Notification Client - Bond Manager stack event.
 *
 * @details Handles all events from the Bond Manager of interest to the Apple Notification Client.
 *          The Apple Notification Client will use the events of re-connection to existing master
 *          and creation of new bonds for handling of service discovery and writing of the Alert
 *          Notification Control Point for re-send of New Apple and Unread Alert notifications.
 *
 * @param[in]   p_ans            Apple Notification Client structure.
 * @param[in]   p_bond_mgmr_evt  Event received from the Bond Manager.
 */
void ble_ancs_on_bondmgmr_evt(ble_ancs_t * p_ans, const ble_bondmngr_evt_t * p_bond_mgmr_evt);


/**@brief Function for initializing the Apple Notification Client.
 *
 * @param[out]  p_ans       Apple Notification Client structure. This structure will have to be
 *                          supplied by the application. It will be initialized by this function,
 *                          and will later be used to identify this particular client instance.
 * @param[in]   p_ans_init  Information needed to initialize the client.
 *
 * @return      NRF_SUCCESS on successful initialization of client, otherwise an error code.
 */
uint32_t ble_ancs_init(ble_ancs_t * p_ans, const ble_ancs_init_t * p_ans_init);


/**@brief Function for writing the to CCCD to enable new apple notifications from the Apple Notification Service.
 *
 * @param[in]  p_ans       Apple Notification structure. This structure will have to be supplied by
 *                         the application. It identifies the particular client instance to use.
 *
 * @return     NRF_SUCCESS on successful writing of the CCCD, otherwise an error code.
 */
uint32_t ble_ancs_enable_notif_new_alert(const ble_ancs_t * p_ans);

/**@brief Function for writing to the CCCD to disable new alert notifications from the Apple Notification Service.
 *
 * @param[in]  p_ans       Apple Notification structure. This structure will have to be supplied by
 *                         the application. It identifies the particular client instance to use.
 *
 * @return     NRF_SUCCESS on successful writing of the CCCD, otherwise an error code.
 */
uint32_t ble_ancs_disable_notif_new_alert(const ble_ancs_t * p_ans);

/**@brief Function for writing to the Apple Notification Control Point to specify apple notification behavior in the
 * Apple Notification Service on the Master.
 *
 * @param[in]  p_ans           Apple Notification structure. This structure will have to be
 *                             supplied by the application. It identifies the particular client
 *                             instance to use.
 * @param[in]  p_control_point Apple Notification Control Point structure. This structure
 *                             specifies the values to write to the Alert Notification Control
 *                             Point, UUID 0xD8F3.
 *
 * @return     NRF_SUCCESS     on successful writing of the Control Point, otherwise an error code.
 */
uint32_t ble_ancs_control_point_write(const ble_ancs_t * p_ans,
                                      const ble_ancs_control_point_t * p_control_point);


/**@brief Function for reading the Supported New Apple Data source(0xC6E9) characteristic value of the service.
 *        The value describes the apple supported in the master.
 *
 * @param[in]  p_ans       Apple Notification structure. This structure will have to be supplied by
 *                         the application. It identifies the particular client instance to use.
 *
 * @return     NRF_SUCCESS on successful transmission of the read request, otherwise an error code.
 */
uint32_t ble_ancs_new_alert_read(const ble_ancs_t * p_ans);

/**@brief Function for requesting the peer to notify the New Apple characteristics immediately.
 *
 * @param[in]  p_ans       Apple Notification structure. This structure will have to be supplied by
 *                         the application. It identifies the particular client instance to use.
 * @param[in]  category    The category ID for which the peer should notify the client.
 *
 * @return     NRF_SUCCESS on successful transmission of the read request, otherwise an error code.
 */
uint32_t ble_ancs_new_alert_notify(const ble_ancs_t * p_ans, ble_ancs_category_id_t category);

/**@brief  Function for loading previous discovered service and characteristic handles for bonded masters from
 *          flash into RAM.
 *
 * @details Read the database of all discovered service and characteristic handles from flash.
 *          If the flash does not contain any valid data, the array of discovered service handles in
 *          RAM will be empty.
 *
 * @param[in] p_ans  Apple Notification structure. This structure will have to be supplied by the
 *                   application. It identifies the particular client instance to use.
 *
 * @note    Currently the Apple Notification Client uses only one page in flash.
 *
 * @return  NRF_SUCCESS if all operations went successfully, an error_code otherwise.
 */
uint32_t ble_ancs_service_load(const ble_ancs_t * p_ans);


/**@brief Function for storing discovered service and characteristic handles for bonded masters into flash memory.
 *
 * @details This function will erase the flash page (if the data to store
 *          are diferent than the one already stored) and then write into flash. Those
 *          operations could prevent the radio to run.
 *
 * @note    Do not call this function while in a connection or when advertising. If you do, the
 *          behavior is undefined.
 *
 * @return  NRF_SUCCESS if all operations went successfully, an error_code otherwise.
 */
uint32_t ble_ancs_service_store(void);


/**@brief Function for deleting the Apple Notification Client database from flash.
 *
 * @details After calling this function you should call ble_ancs_init(...) to re-initialize
 *          the RAM database.
 *
 * @return  NRF_SUCCESS if all operations went successfully.
 */
uint32_t ble_ancs_service_delete(void);


uint32_t ble_ancs_enable_notif_data(const ble_ancs_t * p_ans);
uint32_t ble_ancs_disable_notif_data(const ble_ancs_t * p_ans);
uint32_t ble_ancs_noti_data_read(const ble_ancs_t * p_ans);

#endif // BLE_ANCS_H__
