/** @brief Function for handling an encoded event.
 *
 * @param[in] p_event   The pointer to the encoded event.
 * @param[in] evt_len   Length of the received event, in bytes.
 */
static void event_handle(const uint8_t * const p_event, const uint16_t evt_len)
{
    uint8_t index = 0;

    // TODO: Use memory pool.
    // Memset of evt_len is not enough as incomming data is not struct padded.
    // Using MAX_EVENT_LEN to solve this.
    memset(m_event_buffer, 0, MAX_EVENT_LEN);

    /** @todo Check if evt_len is greater than sizeof(ble_evt_hdr_t) before decoding header. */
    /** @todo Check if evt_len is big enough for each event. */

    uint8_t event_id = p_event[0];

    //lint -e526 -e628 -e516 -save // Symbol '__INTADDR__()' not defined
                                   // no argument information provided for function '__INTADDR__()'
                                   // Symbol '__INTADDR__()' has arg. type conflict
    switch(event_id)
    {
        // GAP events
        case BLE_GAP_EVT_CONNECTED:
            index += evt_header_decode(p_event, &(mp_ble_evt->header));

            mp_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_event[index]));
            index += sizeof(mp_ble_evt->evt.gap_evt.conn_handle);

            connected_evt_decode(&(p_event[index]), &(mp_ble_evt->evt.gap_evt.params.connected));

            mp_ble_evt->header.evt_len  = (uint16_t)(offsetof(ble_evt_t,
                                                              evt.gap_evt.params.connected));
            mp_ble_evt->header.evt_len += sizeof(ble_gap_evt_connected_t);
            mp_ble_evt->header.evt_len -= sizeof(ble_evt_hdr_t);

            break;

        case BLE_GAP_EVT_DISCONNECTED:
            index += evt_header_decode(p_event, &(mp_ble_evt->header));

            mp_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_event[index]));
            index += sizeof(mp_ble_evt->evt.gap_evt.conn_handle);

            disconnected_evt_decode(&(p_event[index]),
                                    &(mp_ble_evt->evt.gap_evt.params.disconnected));

            mp_ble_evt->header.evt_len  = (uint16_t)(offsetof(ble_evt_t,
                                                              evt.gap_evt.params.disconnected));
            mp_ble_evt->header.evt_len += sizeof(ble_gap_evt_disconnected_t);
            mp_ble_evt->header.evt_len -= sizeof(ble_evt_hdr_t);

            break;

        case BLE_GAP_EVT_TIMEOUT:
            index += evt_header_decode(p_event, &(mp_ble_evt->header));

            mp_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_event[index]));
            index += sizeof(mp_ble_evt->evt.gap_evt.conn_handle);

            gap_timeout_evt_decode(&(p_event[index]), &(mp_ble_evt->evt.gap_evt.params.timeout));

            mp_ble_evt->header.evt_len  = (uint16_t)(offsetof(ble_evt_t,
                                                              evt.gap_evt.params.timeout));
            mp_ble_evt->header.evt_len += sizeof(ble_gap_evt_timeout_t);
            mp_ble_evt->header.evt_len -= sizeof(ble_evt_hdr_t);

            break;

        case BLE_GAP_EVT_CONN_PARAM_UPDATE:
            index += evt_header_decode(p_event, &(mp_ble_evt->header));

            mp_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_event[index]));
            index += sizeof(mp_ble_evt->evt.gap_evt.conn_handle);

            gap_conn_param_update_evt_decode(&(p_event[index]),
                                             &(mp_ble_evt->evt.gap_evt.params.conn_param_update));

            mp_ble_evt->header.evt_len  = (uint16_t)(offsetof(ble_evt_t,
                                                              evt.gap_evt.params.conn_param_update));
            mp_ble_evt->header.evt_len += sizeof(ble_gap_evt_conn_param_update_t);
            mp_ble_evt->header.evt_len -= sizeof(ble_evt_hdr_t);
            break;

        case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
            index += evt_header_decode(p_event, &(mp_ble_evt->header));

            mp_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_event[index]));
            index += sizeof(mp_ble_evt->evt.gap_evt.conn_handle);

            gap_sec_params_request_evt_decode(&(p_event[index]),
                                              &(mp_ble_evt->evt.gap_evt.params.sec_params_request));

            mp_ble_evt->header.evt_len  = (uint16_t)(offsetof(ble_evt_t,
                                                              evt.gap_evt.params.sec_params_request));
            mp_ble_evt->header.evt_len += sizeof(ble_gap_evt_sec_params_request_t);
            mp_ble_evt->header.evt_len -= sizeof(ble_evt_hdr_t);

            break;

        case BLE_GAP_EVT_SEC_INFO_REQUEST:
            index += evt_header_decode(p_event, &(mp_ble_evt->header));

            mp_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_event[index]));
            index += sizeof(mp_ble_evt->evt.gap_evt.conn_handle);

            gap_sec_info_request_evt_decode(&(p_event[index]),
                                            &(mp_ble_evt->evt.gap_evt.params.sec_info_request));

            mp_ble_evt->header.evt_len  = (uint16_t)(offsetof(ble_evt_t,
                                                              evt.gap_evt.params.sec_info_request));
            mp_ble_evt->header.evt_len += sizeof(ble_gap_evt_sec_info_request_t);
            mp_ble_evt->header.evt_len -= sizeof(ble_evt_hdr_t);

            break;

        case BLE_GAP_EVT_CONN_SEC_UPDATE:
            index += evt_header_decode(p_event, &(mp_ble_evt->header));

            mp_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_event[index]));
            index += sizeof(mp_ble_evt->evt.gap_evt.conn_handle);

            gap_conn_sec_update_evt_decode(&(p_event[index]),
                                           &(mp_ble_evt->evt.gap_evt.params.conn_sec_update));

            mp_ble_evt->header.evt_len  = (uint16_t)(offsetof(ble_evt_t,
                                                              evt.gap_evt.params.conn_sec_update));
            mp_ble_evt->header.evt_len += sizeof(ble_gap_evt_conn_sec_update_t);
            mp_ble_evt->header.evt_len -= sizeof(ble_evt_hdr_t);

            break;

        
        case BLE_GAP_EVT_AUTH_STATUS:
            index += evt_header_decode(p_event, &(mp_ble_evt->header));
            
            mp_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_event[index]));
            index += sizeof(mp_ble_evt->evt.gap_evt.conn_handle);
            
            gap_auth_status_evt_decode(&(p_event[index]),
                                       &(mp_ble_evt->evt.gap_evt.params.auth_status));

            mp_ble_evt->header.evt_len  = (uint16_t)(offsetof(ble_evt_t,
                                                              evt.gap_evt.params.auth_status));
            mp_ble_evt->header.evt_len += sizeof(ble_gap_evt_auth_status_t);
            mp_ble_evt->header.evt_len -= sizeof(ble_evt_hdr_t);
            break;

        // GATTS events
        case BLE_GATTS_EVT_WRITE:
            index += evt_header_decode(p_event, &(mp_ble_evt->header));

            mp_ble_evt->evt.gatts_evt.conn_handle = uint16_decode(&(p_event[index]));
            index += sizeof(mp_ble_evt->evt.gatts_evt.conn_handle);

            gatts_write_evt_decode(&(p_event[index]), &(mp_ble_evt->evt.gatts_evt.params.write));

            mp_ble_evt->header.evt_len  = (uint16_t)(offsetof(ble_evt_t,
                                                              evt.gatts_evt.params.write.data));

            // Additional data, One byte is already counted in the struct itself.
            mp_ble_evt->header.evt_len += mp_ble_evt->evt.gatts_evt.params.write.len;
            mp_ble_evt->header.evt_len -= sizeof(ble_evt_hdr_t);
            break;

        case BLE_GATTS_EVT_SYS_ATTR_MISSING:
            index += evt_header_decode(p_event, &(mp_ble_evt->header));

            mp_ble_evt->evt.gatts_evt.conn_handle = uint16_decode(&(p_event[index]));
            index += sizeof(mp_ble_evt->evt.gatts_evt.conn_handle);

            mp_ble_evt->evt.gatts_evt.params.sys_attr_missing.hint = p_event[index++];

            mp_ble_evt->header.evt_len  = (uint16_t)(offsetof(ble_evt_t,
                                                              evt.gatts_evt.params.sys_attr_missing));
            mp_ble_evt->header.evt_len += sizeof(ble_gatts_evt_sys_attr_missing_t);
            mp_ble_evt->header.evt_len -= sizeof(ble_evt_hdr_t);

            break;

        default:
            // Unhandled event received.
            return;
    }

    //lint -restore

    NVIC_SetPendingIRQ(SWI2_IRQn);
}
void ble_rpc_gap_evt_packet_decode(ble_evt_t *           p_ble_evt,
                                   uint8_t const * const p_packet)
{
    uint32_t index = 0;

    index += evt_header_id_decode(&p_packet[index], &(p_ble_evt->header));

    switch (p_ble_evt->header.evt_id)
    {
        // GAP events
        case BLE_GAP_EVT_CONNECTED:
            p_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_packet[index]));
            index                             += sizeof(p_ble_evt->evt.gap_evt.conn_handle);

            gap_connected_evt_decode(&(p_packet[index]),
                                     &(p_ble_evt->evt.gap_evt.params.connected));
            break;

        case BLE_GAP_EVT_DISCONNECTED:
            p_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_packet[index]));
            index                             += sizeof(p_ble_evt->evt.gap_evt.conn_handle);

            gap_disconnected_evt_decode(&(p_packet[index]),
                                        &(p_ble_evt->evt.gap_evt.params.disconnected));
            break;

        case BLE_GAP_EVT_TIMEOUT:
            p_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_packet[index]));
            index                             += sizeof(p_ble_evt->evt.gap_evt.conn_handle);

            gap_timeout_evt_decode(&(p_packet[index]), &(p_ble_evt->evt.gap_evt.params.timeout));
            break;

        case BLE_GAP_EVT_CONN_PARAM_UPDATE:
            p_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_packet[index]));
            index                             += sizeof(p_ble_evt->evt.gap_evt.conn_handle);

            gap_conn_param_update_evt_decode(&(p_packet[index]),
                                             &(p_ble_evt->evt.gap_evt.params.conn_param_update));
            break;

        case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
            p_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_packet[index]));
            index                             += sizeof(p_ble_evt->evt.gap_evt.conn_handle);

            gap_sec_params_request_evt_decode(&(p_packet[index]),
                                              &(p_ble_evt->evt.gap_evt.params.sec_params_request));
            break;

        case BLE_GAP_EVT_AUTH_STATUS:
            p_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_packet[index]));
            index                             += sizeof(p_ble_evt->evt.gap_evt.conn_handle);

            gap_auth_status_evt_decode(&(p_packet[index]),
                                       &(p_ble_evt->evt.gap_evt.params.auth_status));
            break;

        case BLE_GAP_EVT_SEC_INFO_REQUEST:
            p_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_packet[index]));
            index                             += sizeof(p_ble_evt->evt.gap_evt.conn_handle);

            gap_sec_info_request_evt_decode(&(p_packet[index]),
                                            &(p_ble_evt->evt.gap_evt.params.sec_info_request));
            break;

        case BLE_GAP_EVT_CONN_SEC_UPDATE:
            p_ble_evt->evt.gap_evt.conn_handle = uint16_decode(&(p_packet[index]));
            index                             += sizeof(p_ble_evt->evt.gap_evt.conn_handle);

            gap_conn_sec_update_evt_decode(&(p_packet[index]),
                                           &(p_ble_evt->evt.gap_evt.params.conn_sec_update));
            break;

        default:
            // No implementation needed.
            break;
    }
}