/*
 *
 *    Copyright (c) 2020 Project CHIP Authors
 *    Copyright (c) 2020 Texas Instruments Incorporated
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *        @file  chipOBLeProfile.c
 *        This file contains the CHIPOBLE profile sample GATT service profile
 *        for use with the BLE Manager.
 */
/*********************************************************************
 * INCLUDES
 */
#include <string.h>

#include <icall.h>
#include <util.h>

#include "icall_ble_api.h"
#include "ti_ble_config.h"

#include "chipOBleProfile.h"

/*********************************************************************
 * GLOBAL VARIABLES
 */
// CHIPoBLE GATT Profile Service UUID
const uint8 chipOBleServUUID[ATT_BT_UUID_SIZE] = {
    // 0xF6, 0xFF
    LO_UINT16(CHIPOBLE_SERV_UUID), HI_UINT16(CHIPOBLE_SERV_UUID)
};

// CHIPoBLE Tx characteristic UUID
const uint8 chipOBleProfileTxCharUUID[ATT_UUID_SIZE] = {
    // 0x12, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18
    CHIPOBLEPROFILE_CHAR_UUID_BASE128(CHIPOBLEPROFILE_TX_CHAR_UUID)
};

// CHIPoBLE Rx characteristic UUID
const uint8 chipOBleProfileRxCharUUID[ATT_UUID_SIZE] = {
    // 0x11, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18
    CHIPOBLEPROFILE_CHAR_UUID_BASE128(CHIPOBLEPROFILE_RX_CHAR_UUID)
};

/*********************************************************************
 * Profile Attributes - variables
 */

// CHIPoBLE GATT Profile Service attribute
static const gattAttrType_t chipoBleProfile = { ATT_BT_UUID_SIZE, chipOBleServUUID };

// CHIPoBLE Tx Characteristic Properties
static uint8_t chipOBleProfileTxCharProps = GATT_PROP_READ | GATT_PROP_INDICATE;

// CHIPoBLE Tx Characteristic Value
static uint8_t chipOBleProfileTxCharVal[CHIPOBLEPROFILE_CHAR_LEN] = { 0x00 };

// CHIPoBLE Tx Characteristic User Description
static uint8_t chipOBleProfileTxdDataUserDesp[CHIPOBLEPROFILE_MAX_DESCRIPTION_LEN] = "ChipOBLE Tx Char";

static gattCharCfg_t * chipOBleProfileTxStateDataConfig;

// CHIPoBLE Rx Characteristic Properties
static uint8_t chipOBleProfileRxCharProps = GATT_PROP_WRITE;

// CHIPoBLE Rx Characteristic Value
static uint8_t chipOBleProfileRxCharVal[CHIPOBLEPROFILE_CHAR_LEN] = { 0x00 };

// CHIPoBLE Rx Characteristic User Description
static uint8_t chipOBleProfileRxdDataUserDesp[CHIPOBLEPROFILE_MAX_DESCRIPTION_LEN] = "ChipOBLE Rx Char";

/*********************************************************************
 * LOCAL VARIABLES
 */

static chipOBleProfileCBs_t * chipOBleProfile_AppCBs = NULL;

/*********************************************************************
 * Profile Attributes - Table
 */

static gattAttribute_t chipoBleProfileAttrTbl[] = {
    // CHIPoBLE Service
    {
        { ATT_BT_UUID_SIZE, primaryServiceUUID }, /* type */
        GATT_PERMIT_READ,                         /* permissions */
        0,                                        /* handle */
        (uint8 *) &chipoBleProfile                /* pValue */
    },
    // CHIPoBLE Tx Characteristic Declaration
    { { ATT_BT_UUID_SIZE, characterUUID }, GATT_PERMIT_READ, 0, &chipOBleProfileTxCharProps },
    // CHIPoBLE Tx Characteristic Value
    { { ATT_UUID_SIZE, chipOBleProfileTxCharUUID }, GATT_PERMIT_READ, 0, chipOBleProfileTxCharVal },

    // CHIPoBLE Tx Characteristic configuration
    { { ATT_BT_UUID_SIZE, clientCharCfgUUID },
      GATT_PERMIT_READ | GATT_PERMIT_WRITE,
      0,
      (uint8 *) &chipOBleProfileTxStateDataConfig },

    // CHIPoBLE Tx Characteristic User Description
    { { ATT_BT_UUID_SIZE, charUserDescUUID }, GATT_PERMIT_READ, 0, chipOBleProfileTxdDataUserDesp },

    // CHIPoBLE Rx Characteristic Declaration
    { { ATT_BT_UUID_SIZE, characterUUID }, GATT_PERMIT_READ, 0, &chipOBleProfileRxCharProps },
    // CHIPoBLE Rx Characteristic Value
    { { ATT_UUID_SIZE, chipOBleProfileRxCharUUID }, GATT_PERMIT_WRITE, 0, chipOBleProfileRxCharVal },

    // CHIPoBLE Rx Characteristic User Description
    { { ATT_BT_UUID_SIZE, charUserDescUUID }, GATT_PERMIT_READ, 0, chipOBleProfileRxdDataUserDesp },
};

/*********************************************************************
 * LOCAL FUNCTIONS
 */
static bStatus_t CHIPoBLEProfile_ReadAttrCB(uint16_t connHandle, gattAttribute_t * pAttr, uint8_t * pValue, uint16_t * pLen,
                                            uint16_t offset, uint16_t maxLen, uint8_t method);
static bStatus_t CHIPoBLEProfile_WriteAttrCB(uint16_t connHandle, gattAttribute_t * pAttr, uint8_t * pValue, uint16_t len,
                                             uint16_t offset, uint8_t method);

/*********************************************************************
 * PROFILE CALLBACKS
 */

// CHIPoBLE Service Callbacks
// Note: When an operation on a characteristic requires authorization and
// pfnAuthorizeAttrCB is not defined for that characteristic's service, the
// Stack will report a status of ATT_ERR_UNLIKELY to the client.  When an
// operation on a characteristic requires authorization the Stack will call
// pfnAuthorizeAttrCB to check a client's authorization prior to calling
// pfnReadAttrCB or pfnWriteAttrCB, so no checks for authorization need to be
// made within these functions.
const gattServiceCBs_t chipOBleProfileCBs = {
    CHIPoBLEProfile_ReadAttrCB,  // Read callback function pointer
    CHIPoBLEProfile_WriteAttrCB, // Write callback function pointer
    NULL                         // Authorization callback function pointer
};

/*********************************************************************
 * PUBLIC FUNCTIONS
 */

/*********************************************************************
 * @fn      CHIPoBLEProfile_AddService
 *
 * @brief   Initializes the Simple Profile service by registering
 *          GATT attributes with the GATT server.
 *
 * @param   services - services to add. This is a bit map and can
 *                     contain more than one service.
 *
 * @return  Success or Failure
 */
bStatus_t CHIPoBLEProfile_AddService(uint32 services)
{
    uint8 status;

    // Allocate Client Characteristic Configuration tables
    chipOBleProfileTxStateDataConfig = (gattCharCfg_t *) ICall_malloc((uint_least16_t)(sizeof(gattCharCfg_t) * MAX_NUM_BLE_CONNS));
    if (chipOBleProfileTxStateDataConfig == NULL)
    {
        return bleMemAllocError;
    }

    // Initialize Client Characteristic Configuration attributes
    GATTServApp_InitCharCfg(LL_CONNHANDLE_INVALID, chipOBleProfileTxStateDataConfig);

    if (services & CHIPOBLEPROFILE_SERVICE)
    {
        // Register GATT attribute list and CBs with GATT Server App
        status = GATTServApp_RegisterService(chipoBleProfileAttrTbl, GATT_NUM_ATTRS(chipoBleProfileAttrTbl),
                                             GATT_MAX_ENCRYPT_KEY_SIZE, &chipOBleProfileCBs);
    }
    else
    {
        status = SUCCESS;
    }

    return status;
}

/*********************************************************************
 * @fn      CHIPoBLEProfile_RegisterAppCBs
 *
 * @brief   Registers the application callback function. Only call
 *          this function once.
 *
 * @param   callbacks - pointer to application callbacks.
 *
 * @return  SUCCESS or bleAlreadyInRequestedMode
 */
bStatus_t CHIPoBLEProfile_RegisterAppCBs(chipOBleProfileCBs_t * appCallbacks)
{
    if (appCallbacks)
    {
        chipOBleProfile_AppCBs = appCallbacks;

        return SUCCESS;
    }
    else
    {
        return bleAlreadyInRequestedMode;
    }
}

/*********************************************************************
 * @fn      CHIPoBLEProfile_SetParameter
 *
 * @brief   Set a CHIPoBLE Characteristic value
 *
 * @param   param - Profile parameter ID
 * @param   len - length of data to write
 * @param   value - pointer to data to write.  This is dependent on
 *          the parameter ID and WILL be cast to the appropriate
 *          data type (example: data type of uint16 will be cast to
 *          uint16 pointer).
 *
 * @return  bStatus_t
 */
extern uint8 gattAppTaskID;
bStatus_t CHIPoBLEProfile_SetParameter(uint8 param, uint8 len, void * value, uint8_t taskId)
{
    bStatus_t ret = SUCCESS;
    switch (param)
    {
    case CHIPOBLEPROFILE_TX_CHAR:

        VOID memcpy(chipOBleProfileTxCharVal, value, len);

        // See if Indications has been enabled
        ret = GATTServApp_ProcessCharCfg(chipOBleProfileTxStateDataConfig, chipOBleProfileTxCharVal, FALSE, chipoBleProfileAttrTbl,
                                         GATT_NUM_ATTRS(chipoBleProfileAttrTbl), taskId, CHIPoBLEProfile_ReadAttrCB);
        break;
    default:
        ret = INVALIDPARAMETER;
        break;
    }

    return ret;
}

/*********************************************************************
 * @fn      CHIPoBLEProfile_GetParameter
 *
 * @brief   Get a CHIPoBLE Characteristic value
 *
 * @param   param - Profile parameter ID
 * @param   value - pointer to data to put.  This is dependent on
 *          the parameter ID and WILL be cast to the appropriate
 *          data type (example: data type of uint16 will be cast to
 *          uint16 pointer).
 *
 * @return  bStatus_t
 */
bStatus_t CHIPoBLEProfile_GetParameter(uint8 param, void * value, uint16_t len)
{
    bStatus_t ret = SUCCESS;
    switch (param)
    {
    case CHIPOBLEPROFILE_RX_CHAR:
        if (len != 0)
        {
            VOID memcpy(value, chipOBleProfileRxCharVal, len);
        }
        else
        {
            VOID memcpy(value, chipOBleProfileRxCharVal, CHIPOBLEPROFILE_CHAR_LEN);
        }
        break;
    case CHIPOBLEPROFILE_CCCWrite:
        *((uint8 *) value) = chipOBleProfileTxStateDataConfig->value;
        break;
    default:
        ret = INVALIDPARAMETER;
        break;
    }

    return ret;
}

/*********************************************************************
 * @fn          CHIPoBLEProfile_ReadAttrCB
 *
 * @brief       Read an attribute.
 *
 * @param       connHandle - connection message was received on
 * @param       pAttr - pointer to attribute
 * @param       pValue - pointer to data to be read
 * @param       pLen - length of data to be read
 * @param       offset - offset of the first octet to be read
 * @param       maxLen - maximum length of data to be read
 * @param       method - type of read message
 *
 * @return      SUCCESS, blePending or Failure
 */
static bStatus_t CHIPoBLEProfile_ReadAttrCB(uint16_t connHandle, gattAttribute_t * pAttr, uint8_t * pValue, uint16_t * pLen,
                                            uint16_t offset, uint16_t maxLen, uint8_t method)
{
    bStatus_t status = SUCCESS;
    uint8 len        = maxLen;

    if (offset + maxLen > CHIPOBLEPROFILE_CHAR_LEN)
        len = CHIPOBLEPROFILE_CHAR_LEN - offset;

    *pLen = len;
    VOID osal_memcpy(pValue, (pAttr->pValue) + offset, len);

    return status;
}

/*********************************************************************
 * @fn      CHIPoBLEProfile_WriteAttrCB
 *
 * @brief   Validate attribute data prior to a write operation
 *
 * @param   connHandle - connection message was received on
 * @param   pAttr - pointer to attribute
 * @param   pValue - pointer to data to be written
 * @param   len - length of data
 * @param   offset - offset of the first octet to be written
 * @param   method - type of write message
 *
 * @return  SUCCESS, blePending or Failure
 */
static bStatus_t CHIPoBLEProfile_WriteAttrCB(uint16_t connHandle, gattAttribute_t * pAttr, uint8_t * pValue, uint16_t len,
                                             uint16_t offset, uint8_t method)
{
    bStatus_t status = SUCCESS;
    uint8 notifyApp  = 0xFF;

    if (pAttr->type.len == ATT_UUID_SIZE)
    {
        if (!memcmp(pAttr->type.uuid, chipOBleProfileRxCharUUID, pAttr->type.len))
        {
            VOID osal_memcpy((pAttr->pValue) + offset, pValue, len);

            // Send notification to BLE Event handler
            notifyApp = CHIPOBLEPROFILE_RX_CHAR;
        }
        else
        {
            status = ATT_ERR_ATTR_NOT_FOUND;
        }
    }

    else if ((pAttr->type.len == ATT_BT_UUID_SIZE) &&
             (BUILD_UINT16(pAttr->type.uuid[0], pAttr->type.uuid[1]) == GATT_CLIENT_CHAR_CFG_UUID))
    {

        notifyApp = CHIPOBLEPROFILE_CCCWrite;

        status = GATTServApp_ProcessCCCWriteReq(connHandle, pAttr, pValue, len, offset, GATT_CLIENT_CFG_INDICATE);
    }
    else
    {
        // unsupported length
        status = ATT_ERR_INVALID_HANDLE;
    }

    // If a characteristic value changed then callback function to notify application of change
    if ((notifyApp != 0xFF) && chipOBleProfile_AppCBs && chipOBleProfile_AppCBs->pfnchipOBleProfileChange)
    {
        chipOBleProfile_AppCBs->pfnchipOBleProfileChange(notifyApp, len, connHandle);
    }

    return status;
}
