Exemplo n.º 1
0
static void handleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{

    /* Check all the services that support attribute 'Write' operation handled
     * by application
     */
    if(GapCheckHandleRange(p_ind->handle))
    {
        GapHandleAccessWrite(p_ind);
    }
    else if(HidCheckHandleRange(p_ind->handle))
    {
        HidHandleAccessWrite(p_ind);
    }

    else if(BatteryCheckHandleRange(p_ind->handle))
    {
        BatteryHandleAccessWrite(p_ind);
    }
    else if(ScanParamCheckHandleRange(p_ind->handle))
    {
        ScanParamHandleAccessWrite(p_ind);
    }
    else
    {
        GattAccessRsp(p_ind->cid, p_ind->handle, 
                      gatt_status_write_not_permitted,
                      0, NULL);
    }

}
extern void ScanParamHandleAccessRead(GATT_ACCESS_IND_T *p_ind)
{
    uint16 length = 0;
    uint8  val[2], *p_value = NULL;
    sys_status rc = sys_status_success;

    switch(p_ind->handle)
    {

        case HANDLE_SCAN_REFRESH_C_CFG:
        {
            p_value = val;
            length = 2; /* Two Octets */

            BufWriteUint16(&p_value, scan_param_data.refresh_client_config);

            /* BufWriteUint16 will have incremented p_value. Revert it back
             * to point to val.
             */
            p_value -= length;
        }
        break;

        default:
        {
            rc = gatt_status_read_not_permitted;
        }
        break;

    }

    GattAccessRsp(p_ind->cid, p_ind->handle, rc,
                  length, p_value);

}
extern void ImmAlertHandleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{
    sys_status rc = sys_status_success;

    switch(p_ind->handle)
    {

        case HANDLE_IMM_ALERT_LEVEL:
        {

            uint8 level = BufReadUint8(&p_ind->value);

            /* Ignore reserved values for Alert Level */
            if((level < alert_level_reserved) &&
               (g_imm_alert_data.p_alert_handler_fn != NULL))
            {
                /* Call registered function handler to raise alarm as per 
                 * the configured alert level 
                 */
                (*(g_imm_alert_data.p_alert_handler_fn))((alert_level)level);
            } /* Else Ignore the alert */

        }
        break;

        default:
            rc = gatt_status_write_not_permitted;
        break;

    }

    GattAccessRsp(p_ind->cid, p_ind->handle, rc, 0, NULL);

}
Exemplo n.º 4
0
extern void BatteryHandleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{
    uint8 *p_value = p_ind->value;
    uint16 client_config;
    sys_status rc = sys_status_success;

    switch(p_ind->handle)
    {
        case HANDLE_BATT_LEVEL_C_CFG:
        {
            client_config = BufReadUint16(&p_value);


            /* Client Configuration is bit field value so ideally bitwise 
             * comparison should be used but since the application supports only 
             * notifications, direct comparison is being used.
             */
            if((client_config == gatt_client_config_notification) ||
               (client_config == gatt_client_config_none))
            {
                g_batt_data.level_client_config = client_config;

                /* Write battery level client configuration to NVM if the 
                 * device is bonded.
                 */
                 Nvm_Write(&client_config,
                          sizeof(client_config),
                          g_batt_data.nvm_offset + 
                          BATTERY_NVM_LEVEL_CLIENT_CONFIG_OFFSET);
            }
            else
            {
                /* INDICATION or RESERVED */

                /* Return error as only notifications are supported */
                rc = gatt_status_desc_improper_config;
            }
        }
        break;

        default:
            rc = gatt_status_write_not_permitted;
        break;
    }

    /* Send ACCESS RESPONSE */
    GattAccessRsp(p_ind->cid, p_ind->handle, rc, 0, NULL);

    /* Send an update as soon as notifications are configured */
    if(g_batt_data.level_client_config & gatt_client_config_notification)
    {
        /* Reset current battery level to an invalid value so that it 
         * triggers notifications on reading the current battery level 
         */
        g_batt_data.level = 0xFF; /* 0 to 100: Valid value range */

        BatteryUpdateLevel(p_ind->cid);
    }

}
Exemplo n.º 5
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      HandleAccessWrite
 *
 *  DESCRIPTION
 *      This function handles write operations on attributes (as received in 
 *      GATT_ACCESS_IND message) maintained by the application and responds
 *      with the GATT_ACCESS_RSP message.
 *
 *  PARAMETERS
 *      p_ind [in]              Data received in GATT_ACCESS_IND message.
 *
 *  RETURNS
 *      Nothing
 *----------------------------------------------------------------------------*/
extern void HandleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{
    /* For the received attribute handle, check all the services that support 
     * attribute 'Write' operation handled by application.
     */
    /* More services may be added here to support their write operations */
    if(GapCheckHandleRange(p_ind->handle))
    {
        /* Attribute handle belongs to GAP service */
        GapHandleAccessWrite(p_ind);
    }
    else if(BatteryCheckHandleRange(p_ind->handle))
    {
        /* Attribute handle belongs to BATTERY service */
        BatteryHandleAccessWrite(p_ind);
    }
    else if(EsurlBeaconCheckHandleRange(p_ind->handle))
    {
        /* Attribute handle belongs to Beacon service */
        EsurlBeaconHandleAccessWrite(p_ind);
    }    
    else
    {
        /* Application doesn't support 'Write' operation on received  attribute
         * handle, so return 'gatt_status_write_not_permitted' status
         */
        GattAccessRsp(p_ind->cid, p_ind->handle, 
                      gatt_status_write_not_permitted,
                      0, NULL);
    }

}
extern void BatteryHandleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{
    uint8 *p_value = p_ind->value;
    uint16 client_config;
    sys_status rc = sys_status_success;

    switch(p_ind->handle)
    {
        case HANDLE_BATT_LEVEL_C_CFG:
        {
            client_config = BufReadUint16(&p_value);

            if((client_config == gatt_client_config_notification) ||
               (client_config == gatt_client_config_none))
            {
                g_batt_data.level_client_config = client_config;

                /* Write batery level client configuration to NVM if the 
                 * device is bonded.
                 */
                if(AppIsDeviceBonded())
                {
                     Nvm_Write((uint16 *)&client_config,
                              sizeof(client_config),
                              g_batt_data.nvm_offset + 
                              BATTERY_NVM_LEVEL_CLIENT_CONFIG_OFFSET);
                }
            }
            else
            {
                /* INDICATION or RESERVED */

                /* Return error as only notifications are supported */
                rc = gatt_status_app_mask;
            }
        }
        break;

        default:
        {
            rc = gatt_status_write_not_permitted;
        }
        break;
    }

    /* Send ACCESS RESPONSE */
    GattAccessRsp(p_ind->cid, p_ind->handle, rc, 0, NULL);

    /* Send an update as soon as notifications are configured */
    if(g_batt_data.level_client_config == gatt_client_config_notification)
    {
        /* Reset current battery level to an invalid value so that it
         * triggers notifications on reading the current battery level
         */
        g_batt_data.level = 0xFF; /* 0 to 100: Valid value range */
        BatteryUpdateLevel(p_ind->cid);
    }

}
extern void ScanParamHandleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{
    uint8  *p_value =  p_ind->value;
    sys_status rc = sys_status_success;

    switch(p_ind->handle)
    {

        case HANDLE_SCAN_INTERVAL_WINDOW:
        {
            scan_param_data.interval = BufReadUint16(&p_value);
            scan_param_data.window = BufReadUint16(&p_value);
        }
        break;

        case HANDLE_SCAN_REFRESH_C_CFG:
        {
            uint16 client_config = BufReadUint16(&p_value);


            /* Client Configuration is bit field value so ideally bitwise 
             * comparison should be used but since the application supports only 
             * notifications, direct comparison is being used.
             */
            if((client_config == gatt_client_config_notification) ||
               (client_config == gatt_client_config_none))
            {
                scan_param_data.refresh_client_config = client_config;

                /* Write Scan refresh Client configuration to NVM if the 
                 * device is bonded.
                 */
                 Nvm_Write(&client_config,
                          sizeof(gatt_client_config),
                          scan_param_data.nvm_offset+ 
                          SCAN_PARAM_NVM_REFRESH_CLIENT_CONFIG_OFFSET);
            }
            else
            {
                /* INDICATION or RESERVED */

                /* Return Error as only Notifications are supported */
                rc = gatt_status_desc_improper_config;
            }
        }
        break;        


        default:
        {
            rc = gatt_status_write_not_permitted;
        }
        break;

    }

    GattAccessRsp(p_ind->cid, p_ind->handle, rc, 0, NULL);
}
Exemplo n.º 8
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      HandleAccessWrite
 *
 *  DESCRIPTION
 *      This function handles write operations on Battery Service attributes
 *      maintained by the application and responds with the GATT_ACCESS_RSP
 *      message.
 *
 *  PARAMETERS
 *      p_ind [in]              Data received in GATT_ACCESS_IND message.
 *
 *  RETURNS
 *      Nothing
 *----------------------------------------------------------------------------*/
extern void BatteryHandleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{
    uint8 *p_value = p_ind->value;      /* New attribute value */
    uint16 client_config;               /* Client configuration descriptor */
    sys_status rc = sys_status_success; /* Function status */

    switch(p_ind->handle)
    {
        case HANDLE_BATT_LEVEL_C_CFG:
        {
            /* Write the client configuration descriptor for the battery level
             * characteristic.
             */
            client_config = BufReadUint16(&p_value);

            /* Only notifications are allowed for this client configuration 
             * descriptor.
             */
            if((client_config == gatt_client_config_notification) ||
               (client_config == gatt_client_config_none))
            {
                g_batt_data.level_client_config = client_config;
            }
            else
            {
                /* INDICATION or RESERVED */

                /* Return error as only notifications are supported */
                rc = gatt_status_app_mask;
            }

        }
        break;


        default:
            rc = gatt_status_write_not_permitted;
        break;

    }

    /* Send ACCESS RESPONSE */
    GattAccessRsp(p_ind->cid, p_ind->handle, rc, 0, NULL);

    /* Send an update as soon as notifications are configured */
    if(g_batt_data.level_client_config == gatt_client_config_notification)
    {
        /* Reset current battery level to an invalid value so that it 
         * triggers notifications on reading the current battery level 
         */
        g_batt_data.level = 0xFF; /* 0 to 100: Valid value range */

        /* Update the battery level and send notification. */
        BatteryUpdateLevel(p_ind->cid);
    }

}
Exemplo n.º 9
0
static void handleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{

    /* Check all the services that support attribute 'Write' operation handled
     * by application
     */
    if(GapCheckHandleRange(p_ind->handle))
    {
        GapHandleAccessWrite(p_ind);
    }
#ifdef ENABLE_OTA
    else if(GattCheckHandleRange(p_ind->handle))
    {
        /* Attribute handle belongs to Gatt service */
        GattHandleAccessWrite(p_ind);
    }
    else if(OtaCheckHandleRange(p_ind->handle))
    {
        /* Attribute handle belongs to OTA service */
        OtaHandleAccessWrite(p_ind);
    }
#endif /* ENABLE_OTA */
    else if(HidCheckHandleRange(p_ind->handle))
    {
        HidHandleAccessWrite(p_ind);
    }

#ifdef __PROPRIETARY_HID_SUPPORT__

    else if(HidBootCheckHandleRange(p_ind->handle))
    {
        HidBootHandleAccessWrite(p_ind);
    }

#endif /* __PROPRIETARY_HID_SUPPORT__ */

    else if(BatteryCheckHandleRange(p_ind->handle))
    {
        BatteryHandleAccessWrite(p_ind);
    }
    else if(ScanParamCheckHandleRange(p_ind->handle))
    {
        ScanParamHandleAccessWrite(p_ind);
    }
    else if(BondMgmtCheckHandleRange(p_ind->handle))
    {
        BondMgmtHandleAccessWrite(p_ind);
    }
    else
    {
        GattAccessRsp(p_ind->cid, p_ind->handle,
                      gatt_status_write_not_permitted,
                      0, NULL);
    }

}
Exemplo n.º 10
0
extern void DeviceInfoHandleAccessRead(GATT_ACCESS_IND_T *p_ind)
{
    uint16 length = 0;
    uint8  *p_value = NULL;
    sys_status rc = gatt_status_irq_proceed;

    /* Let the firmware handle reads on this service.
     * Send response indication 
     */
    GattAccessRsp(p_ind->cid, p_ind->handle, rc,
                  length, p_value);
}
Exemplo n.º 11
0
extern void HandleAccessRead(GATT_ACCESS_IND_T *p_ind)
{

    /* For the received attribute handle, check all the services that support
     * attribute 'Read' operation handled by application.
     */

    if(GapCheckHandleRange(p_ind->handle))
    {
        /* Attribute handle belongs to GAP service */
        GapHandleAccessRead(p_ind);
    }
#ifdef ENABLE_OTA
    else if(GattCheckHandleRange(p_ind->handle))
    {
        /* Attribute handle belongs to Gatt service */
        GattHandleAccessRead(p_ind);
    }
    else if(OtaCheckHandleRange(p_ind->handle))
    {
        /* Attribute handle belongs to OTA service */
        OtaHandleAccessRead(p_ind);
    }
#endif /* ENABLE_OTA */
    else if(HeartRateCheckHandleRange(p_ind->handle))
    {
        /* Attribute handle belongs to Heart Rate service */
        HeartRateHandleAccessRead(p_ind);
    }
    else if(BatteryCheckHandleRange(p_ind->handle))
    {
        /* Attribute handle belongs to Battery service */
        BatteryHandleAccessRead(p_ind);
    }
    else if(DeviceInfoCheckHandleRange(p_ind->handle))
    {
        /* Attribute handle belongs to Device Information Service. */
        DeviceInfoHandleAccessRead(p_ind);
    }
    else
    {
        /* Application doesn't support 'Read' operation on received
         * attribute handle, hence return 'gatt_status_read_not_permitted'
         * status
         */
        GattAccessRsp(p_ind->cid, p_ind->handle,
                      gatt_status_read_not_permitted,
                      0, NULL);
    }

}
Exemplo n.º 12
0
extern void GapHandleAccessRead(GATT_ACCESS_IND_T *p_ind)
{
    uint16 length = 0;
    uint8  *p_value = NULL;
    sys_status rc = sys_status_success;

    switch(p_ind->handle)
    {

        case HANDLE_DEVICE_NAME:
        {
            /* Validate offset against length, it should be less than 
             * device name length
             */
            if(p_ind -> offset < g_gap_data.length)
            {
                length = g_gap_data.length - p_ind -> offset;
                p_value = (g_gap_data.p_dev_name + p_ind -> offset);
            }
            else
            {
                rc = gatt_status_invalid_offset;
            }
        }
        break;

#ifdef __GAP_PRIVACY_SUPPORT__

        case HANDLE_PERIPHERAL_PRIVACY_FLAG:
        {
            length = 1;
            p_value = (uint8 *)&g_gap_data.peripheral_privacy_flag;
            
        }
        break;

#endif /* __GAP_PRIVACY_SUPPORT__ */

        default:
            /* Let firmware handle the request  */
            rc = gatt_status_irq_proceed;
        break;

    }

    GattAccessRsp(p_ind->cid, p_ind->handle, rc,
                  length, p_value);

}
Exemplo n.º 13
0
extern void GapHandleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{
    sys_status rc = sys_status_success;

    switch(p_ind->handle)
    {

        case HANDLE_DEVICE_NAME:
            /* Update device name */
            updateDeviceName(p_ind->size_value, p_ind->value);
        break;

#ifdef __GAP_PRIVACY_SUPPORT__

        case HANDLE_PERIPHERAL_PRIVACY_FLAG:
            GapSetPeripheralPrivacyFlag(BufReadUint8(&p_ind->value));
        break;

        case HANDLE_RECONNECTION_ADDRESS:
            /* There is no specific application error code when the remote
             * device writes to the reconnection address when peripheral
             * privacy flag is disabled. So, send a success write response
             * but don't update the reconnection address.
             */
            if(g_gap_data.peripheral_privacy_flag)
            {
                /* Store the re-connection address only if it is valid. */
                if(GapIsReconnectionAddressValid())
                {
                    GapSetReconnectionAddress(p_ind->value);
                }
            }
        break;
            
#endif /* __GAP_PRIVACY_SUPPORT__ */

        default:
        {
            /* No more IRQ characteristics */
            rc = gatt_status_write_not_permitted;
        }
        break;

    }

    GattAccessRsp(p_ind->cid, p_ind->handle, rc, 0, NULL);

}
Exemplo n.º 14
0
extern void BatteryHandleAccessRead(GATT_ACCESS_IND_T *p_ind)
{
    uint16 length = 0;
    uint8 value[2];
    uint8 *p_val = NULL;
    sys_status rc = sys_status_success;

    switch(p_ind->handle)
    {
        /* Battery level is being read */
        case HANDLE_BATT_LEVEL:
        {
            /* Reading battery level */
            length = 1; /* One Octet */

            g_batt_data.level = readBatteryLevel();

            value[0] = g_batt_data.level;
        }
        break;

        /* Client Characteristic Configuration for the Battery Level 
         * Characteristic is being read 
         */
        case HANDLE_BATT_LEVEL_C_CFG:
        {
            length = 2; /* Two Octets */
            p_val = value;

            BufWriteUint16((uint8 **)&p_val, g_batt_data.level_client_config);
        }
        break;

        default:
            /* No more IRQ characteristics */
            rc = gatt_status_read_not_permitted;
        break;

    }

    /* Send Access response */
    GattAccessRsp(p_ind->cid, p_ind->handle, rc,
                  length, value);

}
Exemplo n.º 15
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      BatteryHandleAccessRead
 *
 *  DESCRIPTION
 *      This function handles read operations on Battery Service attributes
 *      maintained by the application and responds with the GATT_ACCESS_RSP
 *      message.
 *
 *  PARAMETERS
 *      p_ind [in]              Data received in GATT_ACCESS_IND message.
 *
 *  RETURNS
 *      Nothing
 *----------------------------------------------------------------------------*/
extern void BatteryHandleAccessRead(GATT_ACCESS_IND_T *p_ind)
{
    uint16 length = 0;                  /* Length of attribute data, octets */
    uint8  value[2];                    /* Attribute value */
    uint8 *p_val = NULL;                /* Pointer to attribute value */
    sys_status rc = sys_status_success; /* Function status */

    switch(p_ind->handle)
    {

        case HANDLE_BATT_LEVEL:
        {
            /* Read the battery level */
            length = 1; /* One Octet */

            g_batt_data.level = readBatteryLevel();

            value[0] = g_batt_data.level;
        }
        break;

        case HANDLE_BATT_LEVEL_C_CFG:
        {
            /* Read the client configuration descriptor for the battery level
             * characteristic.
             */
            length = 2; /* Two Octets */
            p_val = value;

            BufWriteUint16((uint8 **)&p_val, g_batt_data.level_client_config);
        }
        break;

        default:
            /* No more IRQ characteristics */
            rc = gatt_status_read_not_permitted;
        break;

    }

    /* Send ACCESS RESPONSE */
    GattAccessRsp(p_ind->cid, p_ind->handle, rc, length, value);

}
Exemplo n.º 16
0
/*-----------------------------------------------------------------------------*
 *  NAME
 *      OtaHandleAccessRead
 *
 *  DESCRIPTION
 *      Handle read-access requests from the Host where the characteristic
 *      handle falls within the range of the OTAU Application Service.
 *
 *  PARAMETERS
 *      p_ind [in]              Read request data
 *
 *  RETURNS
 *      Nothing
 *----------------------------------------------------------------------------*/
void OtaHandleAccessRead(GATT_ACCESS_IND_T *p_ind)
{
    sys_status  rc = sys_status_success;
                                    /* Function status */
    uint8       data_length = 0;    /* Length of data to return in octets */
    uint8      *p_value = NULL;     /* Pointer to return data */
    
    csr_application_id current_app; /* Index of the current application */
    
    switch (p_ind->handle)
    {
        case HANDLE_CSR_OTA_CURRENT_APP:
            /* Read the index of the current application */
            current_app = OtaReadCurrentApp();
            
            p_value = (uint8 *)&current_app;
            data_length = 1;
            break;
            
        case HANDLE_CSR_OTA_DATA_TRANSFER:
            /* Read the value of the Data Transfer characteristic */
            p_value = (uint8 *)data_transfer_memory;
            data_length = data_transfer_data_length;
            break;
            
        case HANDLE_CSR_OTA_DATA_TRANSFER_CLIENT_CONFIG:
            /* Read the value of the Data Transfer Client Characteristic
             * Configuration Descriptor
             */
            p_value = (uint8 *)data_transfer_configuration;
            data_length = 2;
            break;
            
        default:
            /* Reading is not supported on this handle */
            rc = gatt_status_read_not_permitted;
            break;
    }
    
    GattAccessRsp(p_ind->cid, p_ind->handle, rc, data_length, p_value);
}
Exemplo n.º 17
0
extern void GattHandleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{
    uint16  client_config;
    uint8  *p_value = p_ind->value;
    sys_status rc = gatt_status_write_not_permitted;

    if(p_ind->handle == HANDLE_SERVICE_CHANGED_CLIENT_CONFIG)
    {
        uint8 dev_index;    
        dev_index = AppGetConnectedDeviceIndex();        

        client_config = BufReadUint16(&p_value);

        /* Client configuration is a bit field value, so ideally bit wise
         * comparison should be used but since the application supports only
         * indications or nothing, direct comparison should be used.
         */
        if((client_config == gatt_client_config_indication) ||
           (client_config == gatt_client_config_none))
        {
            g_gatt_data.serv_changed_config[dev_index] = client_config;
            rc = sys_status_success;
            
            if(AppIsDeviceBonded(dev_index))
            {               
                /* Write to NVM the Service Changed Client Configuration value */
                Nvm_Write((uint16*)&(g_gatt_data.serv_changed_config[dev_index]),
                          sizeof(g_gatt_data.serv_changed_config[dev_index]),
                          (g_gatt_data.nvm_offset +
                           SERV_CHANGED_CLIENT_CONFIG_OFFSET(dev_index)));
            }
        }
        else
        {
            rc = gatt_status_desc_improper_config;
        }
    }
    /* Send Access Response */
    GattAccessRsp(p_ind->cid, p_ind->handle, rc, 0, NULL);
}
Exemplo n.º 18
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      HandleAccessWrite
 *
 *  DESCRIPTION
 *      This function handles Write operation on attributes (as received in 
 *      GATT_ACCESS_IND message) maintained by the application.
 *
 *  RETURNS
 *      Nothing
 *
 *---------------------------------------------------------------------------*/
extern void HandleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{

    /* For the received attribute handle, check all the services that support 
     * attribute 'Write' operation handled by application.
     */

    if(GapCheckHandleRange(p_ind->handle))
    {
        /* Attribute handle belongs to GAP service */
        GapHandleAccessWrite(p_ind);
    }
    else if(MeshControlCheckHandleRange(p_ind->handle))
    {
        /* Attribute handle belongs to Mesh Control service */
        MeshControlHandleAccessWrite(p_ind);
    }
#ifdef ENABLE_GATT_OTA_SERVICE 
    else if(GattCheckHandleRange(p_ind->handle))
    {
        /* Attribute handle belongs to Gatt service */
        GattHandleAccessWrite(p_ind);
    }
    else if(OtaCheckHandleRange(p_ind->handle))
    {
        OtaHandleAccessWrite(p_ind);
    }
#endif /* ENABLE_GATT_OTA_SERVICE */
    else
    {
        /* Application doesn't support 'Write' operation on received 
         * attribute handle, hence return 'gatt_status_write_not_permitted'
         * status
         */
        GattAccessRsp(p_ind->cid, p_ind->handle, 
                      gatt_status_write_not_permitted,
                      0, NULL);
    }

}
Exemplo n.º 19
0
extern void GapHandleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{
    sys_status rc = sys_status_success;

    switch(p_ind->handle)
    {

        case HANDLE_DEVICE_NAME:
            /* Update device name */
            updateDeviceName(p_ind->size_value, p_ind->value);
        break;

        default:
            /* No more IRQ characteristics */
            rc = gatt_status_write_not_permitted;
        break;

    }

    GattAccessRsp(p_ind->cid, p_ind->handle, rc, 0, NULL);

}
Exemplo n.º 20
0
extern void GattHandleAccessRead(GATT_ACCESS_IND_T *p_ind)
{
    uint16  data_length = 0;
    uint8   value[2];
    uint8   *p_value = NULL;
    sys_status rc = gatt_status_read_not_permitted;
    uint8 dev_index = AppGetConnectedDeviceIndex();
    
    if(p_ind->handle == HANDLE_SERVICE_CHANGED_CLIENT_CONFIG)
    {
        /* Service changed client characteristic configuration descriptor read
         * has been requested
         */
        data_length = 2;
        p_value = value;
        BufWriteUint16((uint8 **)&p_value,
                       g_gatt_data.serv_changed_config[dev_index]);
        rc = sys_status_success;
    }

    /* Send Access Response */
    GattAccessRsp(p_ind->cid, p_ind->handle, rc, data_length, p_value);
}
Exemplo n.º 21
0
extern void GapHandleAccessRead(GATT_ACCESS_IND_T *p_ind)
{
    uint16 length = 0;
    uint8  *p_value = NULL;
    sys_status rc = sys_status_success;

    switch(p_ind->handle)
    {

        case HANDLE_DEVICE_NAME:
        {
            /* Validate offset against length, it should be less than 
             * device name length
             */
            if(p_ind -> offset < g_gap_data.length)
            {
                length = g_gap_data.length - p_ind -> offset;
                p_value = (g_gap_data.p_dev_name + p_ind -> offset);
            }
            else
            {
                rc = gatt_status_invalid_offset;
            }
        }
        break;

        default:
            /* No more IRQ characteristics */
            rc = gatt_status_irq_proceed;
        break;

    }

    GattAccessRsp(p_ind->cid, p_ind->handle, rc,
                  length, p_value);

}
Exemplo n.º 22
0
/*----------------------------------------------------------------------------*
 *  NAME
 *      GapHandleAccessRead
 *
 *  DESCRIPTION
 *      This function handles read operations on GAP Service attributes
 *      maintained by the application and responds with the GATT_ACCESS_RSP
 *      message.
 *
 *  PARAMETERS
 *      p_ind [in]              Data received in GATT_ACCESS_IND message.
 *
 *  RETURNS
 *      Nothing
 *----------------------------------------------------------------------------*/
extern void GapHandleAccessRead(GATT_ACCESS_IND_T *p_ind)
{
    uint16 length = 0;                  /* Length of attribute data, octets */
    uint8 *p_value = NULL;              /* Pointer to attribute value */
    sys_status rc = sys_status_success; /* Function status */

    switch(p_ind->handle)
    {

        case HANDLE_DEVICE_NAME:
        {
            /* Validate offset against length, it should be less than the
             * device name length
             */
            if(p_ind->offset < g_gap_data.length)
            {
                length = g_gap_data.length - p_ind->offset;
                p_value = g_gap_data.p_dev_name + p_ind->offset;
            }
            else
            {
                rc = gatt_status_invalid_offset;
            }
        }
        break;

        default:
            /* No more IRQ characteristics */
            rc = gatt_status_read_not_permitted;
        break;

    }

    /* Send the GATT response. */
    GattAccessRsp(p_ind->cid, p_ind->handle, rc, length, p_value);

}
extern void HeartRateHandleAccessRead(GATT_ACCESS_IND_T *p_ind)
{
    /* Initialise to 2 octets for Client Configuration */
    uint16 length = 2;
    uint8  value[2];
    uint8  *p_val = NULL;
    sys_status rc = sys_status_success;

    switch(p_ind->handle)
    {
        /* Client configuration of the Heart Rate Measurement Characteristic is 
         * being read.
         */
        case HANDLE_HEART_RATE_MEASUREMENT_C_CFG:
        {
            p_val = value;

            /* copy the client configuration value in response buffer */
            BufWriteUint16(&p_val, g_hr_serv_data.hr_meas_client_config);
        }
        break;

        default:
        {   
            /* Let the firmware handle.the request
             */
            rc = gatt_status_irq_proceed;
        }
        break;

    }

    /* Send GATT Response for the received request */
    GattAccessRsp(p_ind->cid, p_ind->handle, rc,
                          length, value);

}
extern void HeartRateHandleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{
    uint8 *p_value = p_ind->value;
    gatt_client_config client_config;
    sys_status rc = sys_status_success;

    switch(p_ind->handle)
    {
        /* Heart Rate measurement characteristic client configuration is being 
         * written 
         */
        case HANDLE_HEART_RATE_MEASUREMENT_C_CFG:
        {
            client_config = BufReadUint16(&p_value);


            /* Client Configuration is bit field value so ideally bitwise 
             * comparison should be used but since the application supports only 
             * notifications, direct comparison is being used.
             */
            if((client_config == gatt_client_config_notification) ||
               (client_config == gatt_client_config_none))
            {
                /* Store the new client configuration */
                g_hr_serv_data.hr_meas_client_config = client_config;

                /* Write Heart Rate Measurement Client configuration to NVM if 
                 * the device is bonded.
                 */
                if(AppIsDeviceBonded())
                {
                     Nvm_Write((uint16*)&client_config,
                              sizeof(client_config),
                              g_hr_serv_data.nvm_offset + 
                              HR_NVM_HR_MEAS_CLIENT_CONFIG_OFFSET);
                }

                /* Start sending the HR measurement notifications if they are 
                 * not being sent currently. 
                 */
                StartSendingHRMeasurements();
            }
            else
            {
                /* INDICATION or RESERVED */

                /* Return Error as only Notifications are supported */
                rc = gatt_status_desc_improper_config;
            }

            break;
        }

        /* Heart Rate Control point is being written */
        case HANDLE_HEART_RATE_CONTROL_POINT:
        {
            /* Extract the written value */
            uint8 cntl_point_val = BufReadUint8(&p_value);

            /* Check if the HR client has reset the expended energy. */
            if(cntl_point_val == hr_control_point_reset_energy)
            {
                /* Yes, it has. Make a note of it. */
                g_hr_serv_data.energy_expended = 0;
                g_hr_serv_data.reset_energy_expended_received = TRUE;
            }
            else /* Reserved Value */
            {
                rc  = gatt_status_desc_improper_config;
            }

            break;
        }

        default:
        {
            /* Write is not permitted on any other characteristic/attribute */
            rc = gatt_status_write_not_permitted;
            break;
        }
    }

    /* Send ACCESS RESPONSE */
    GattAccessRsp(p_ind->cid, p_ind->handle, rc, 0, NULL);

}
Exemplo n.º 25
0
/*-----------------------------------------------------------------------------*
 *  NAME
 *      OtaHandleAccessWrite
 *
 *  DESCRIPTION
 *      Handle write-access requests from the Host where the characteristic
 *      handle falls within the range of the OTAU Application Service.
 *
 *  PARAMETERS
 *      p_ind [in]              Write request data
 *
 *  RETURNS
 *      Nothing
 *----------------------------------------------------------------------------*/
void OtaHandleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{
    sys_status  rc = gatt_status_write_not_permitted;
                                    /* Function status */
        
    switch (p_ind->handle)
    {
        case HANDLE_CSR_OTA_CURRENT_APP:
        {
            /* Set the index of the current application */
            const uint8 app_id = p_ind->value[0];
                                            /* New application index */
#if defined(USE_STATIC_RANDOM_ADDRESS) || defined(USE_RESOLVABLE_RANDOM_ADDRESS)
            BD_ADDR_T   bd_addr;            /* Bluetooth Device address */

            GapGetRandomAddress(&bd_addr);
#endif /* USE_STATIC_RANDOM_ADDRESS || USE_RESOLVABLE_RANDOM_ADDRESS */
            
            rc = OtaWriteCurrentApp(app_id,
                                    IS_BONDED,
                                    &(CONN_HOST_ADDR),
                                    LINK_DIVERSIFIER,
#if defined(USE_STATIC_RANDOM_ADDRESS) || defined(USE_RESOLVABLE_RANDOM_ADDRESS)
                                    &bd_addr,
#else
                                    NULL,
#endif
                                    CONNECTION_IRK,
                                    GattServiceChangedIndActive());
            if (rc != sys_status_success)
            {
                /* Sanitise the result. If OtaWriteCurrentApp fails it will be
                 * because one or more of the supplied parameters was invalid.
                 */
                rc = gatt_status_invalid_param_value;
            }
        }
            break;
            
        case HANDLE_CSR_OTA_READ_CS_BLOCK:
            /* Set the offset and length of a block of CS to read */
            
            /* Validate input (expecting uint16[2]) */
            if (p_ind->size_value == WORDS_TO_BYTES(sizeof(uint16[2])))
            {
                const uint16 offset = BufReadUint16(&p_ind->value);
                
                data_transfer_data_length = (uint8)BufReadUint16(&p_ind->value);
            
                rc = readCsBlock(offset,
                                 data_transfer_data_length,
                                 data_transfer_memory);
            }
            else
            {
                rc = gatt_status_invalid_length;
            }
            break;
            
        case HANDLE_CSR_OTA_DATA_TRANSFER_CLIENT_CONFIG:
        {
            /* Modify the Data Transfer Client Characteristic Configuration
             * Descriptor
             */
            const uint16 client_config = BufReadUint16(&p_ind->value);
                                            /* Requested descriptor value */

            if((client_config == gatt_client_config_notification) ||
               (client_config == gatt_client_config_none))
            {
                data_transfer_configuration[0] = client_config;
                rc = sys_status_success;
            }
            else
            {
                /* INDICATION or RESERVED */

                /* Return error as only notifications are supported */
                rc = gatt_status_desc_improper_config;
            }
        }
            break;
            
        default:
            /* Writing to this characteristic is not permitted */
            break;
    }
 
    GattAccessRsp(p_ind->cid, p_ind->handle, rc, 0, NULL);
    
    /* Perform any follow-up actions */
    if (rc == sys_status_success)
    {
        switch (p_ind->handle)
        {
            case HANDLE_CSR_OTA_READ_CS_BLOCK:
                /* If this write action was to trigger a CS key read and
                 * notifications have been enabled send the result now.
                 */
                if (data_transfer_configuration[0] ==
                                                gatt_client_config_notification)
                {
                    GattCharValueNotification(CONNECTION_CID, 
                                              HANDLE_CSR_OTA_DATA_TRANSFER, 
                                              data_transfer_data_length,
                                              data_transfer_memory);
                }
                break;

            case HANDLE_CSR_OTA_CURRENT_APP:
                /* If a new application index has been requested disconnect from
                 * the Host and reset the device to run the new application.
                 */
                
                /* Record that the GATT database may be different after the
                 * device has reset.
                 */
                GattOnOtaSwitch();
                
                /* When the disconnect confirmation comes in, call OtaReset() */
                g_ota_reset_required = TRUE;

                /* Disconnect from the Host */
                GattDisconnectReq(CONNECTION_CID);
                break;

            default:
                /* No follow up action necessary */
                break;
        }
    }
}
Exemplo n.º 26
0
extern void HidHandleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{
    uint16 client_config, input_rpt_hndl;
    uint8 *p_value = p_ind->value;
    sys_status rc = sys_status_success;
    bool update_input_report_config = FALSE;

    switch(p_ind->handle)
    {
        case HANDLE_HID_INPUT_RPT_CLIENT_CONFIG:
        case HANDLE_HID_BOOT_INPUT_RPT_CLIENT_CONFIG:
        {
            /* Copy the value being written by the remote device to a local
             * variable
             */
            client_config = BufReadUint16(&p_value);


            /* Client Configuration is bit field value so ideally bitwise 
             * comparison should be used but since the application supports only 
             * notifications, direct comparison is being used.
             */
            if((client_config == gatt_client_config_notification) ||
               (client_config == gatt_client_config_none))
            {
                /* CCCD of input report and boot input report have different
                 * offsets at which their values are written into NVM
                 */
                uint16 offset;

                if(p_ind->handle == HANDLE_HID_INPUT_RPT_CLIENT_CONFIG)
                {
                    hid_data.input_client_config = client_config;

                    /* If Report mode set, update Input Report Configuration 
                     * for Report mode
                     */
                    if(hid_data.report_mode)
                    {
                        update_input_report_config = TRUE;
                        input_rpt_hndl = HANDLE_HID_INPUT_REPORT;
                    }

                    offset =  hid_data.nvm_offset+ 
                              HID_NVM_INPUT_RPT_CLIENT_CONFIG_OFFSET;

                }
                else /* Input Boot Report Client Configuration */
                {
                    hid_data.input_boot_client_config = client_config;

                    /* If Report mode not set, update Input Report Configuration 
                     * for Boot mode
                     */
                    if(!hid_data.report_mode)
                    {
                        update_input_report_config = TRUE;
                        input_rpt_hndl = HANDLE_HID_BOOT_INPUT_REPORT;
                    }

                    offset =  hid_data.nvm_offset+ 
                              HID_NVM_INPUT_BOOT_RPT_CLIENT_CONFIG_OFFSET;

                }

                /* Write HID Input Report Client configuration or HID Input Boot 
                 * Report Client configuration to NVM if the devices are bonded.
                 */
                 Nvm_Write(&client_config,
                          sizeof(gatt_client_config),
                          offset);

                /* Device shall only trigger Input reports (boot / main) if 
                 * notifications are enabled for characteristic corresponding
                 * to the current protocol mode.
                 */
                if(update_input_report_config)
                {
                    updateInputReportConfiguration(client_config, 
                                                   input_rpt_hndl);
                }
            }
            else
            {
                /* INDICATION or RESERVED */

                /* Return Error as only Notifications are supported for 
                 * mouse application
                 */

                rc = gatt_status_desc_improper_config;
            }
        }
        break;

        case HANDLE_HID_CONTROL_POINT:
        {
            /* Copy the value being written by the remote device to a local
             * variable.
             */
            uint8 control_op = BufReadUint8(&p_value);

            handleControlPointUpdate(control_op);
        }
        break;

        case HANDLE_HID_PROTOCOL_MODE:
        {
            /* Copy the value being written by the remote device to a local
             * variable.
             */
            uint8 mode = BufReadUint8(&p_value);
            /* Update the protocol mode only if the value being written is not
             * the same as the already existing protocol mode.
             */
            hid_protocol_mode old_mode = hid_data.report_mode;

            if(((mode == hid_boot_mode) ||
                (mode == hid_report_mode)) &&
                (mode != old_mode)) /* Change of Protocol Mode */
            {
                if(mode == hid_boot_mode)
                {
                    client_config = hid_data.input_boot_client_config;
                    input_rpt_hndl = HANDLE_HID_BOOT_INPUT_REPORT;
                }
                else
                {
                    client_config = hid_data.input_client_config;
                    input_rpt_hndl = HANDLE_HID_INPUT_REPORT;
                }

                hid_data.report_mode = mode;

                /* After the protocol mode is updated, update the service
                 * notification status from the notifications
                 * on CCCD of the respective mode handles.
                 */
                updateInputReportConfiguration(client_config,
                                               input_rpt_hndl);

            } /* Else Ignore the value */
        }
        break;

        case HANDLE_HID_FEATURE_REPORT:
        {
            /* Copy the value being written by the remote device to a local
             * variable.
             */
            sensor_resolution resolution = BufReadUint8(&p_value);

            /* Update the mouse resolution. This is an example feature report.
             * Customers can define vendor specific feature reports and
             * implement their handling as per the requirements
             */
            if(!SetSensorResolution(resolution))
            {
                rc = gatt_status_att_val_oor;
            }
        }
        break;
        
        default:
        {
            /* No more IRQ characteristics in HID service */
            rc = gatt_status_write_not_permitted;
        }
        break;
    }

    /* Send ACCESS RESPONSE */
    GattAccessRsp(p_ind->cid, p_ind->handle, rc, 0, NULL);

}
Exemplo n.º 27
0
extern void HidHandleAccessRead(GATT_ACCESS_IND_T *p_ind)
{
    uint16 length = 0;
    uint8  *p_value = NULL;
    uint8  val[2];
    sys_status rc = sys_status_success;


    switch(p_ind->handle)
    {

        case HANDLE_HID_INPUT_RPT_CLIENT_CONFIG:
        {
            p_value = val;

            BufWriteUint16(&p_value, hid_data.input_client_config);
            /* CCCD value of a characteristic is 2 bytes in length. */
            length = 2;

            /* BufWriteUint16 will have incremented p_value. Revert it back
             * to point to val.
             */
            p_value -= length;
        }
        break;

        case HANDLE_HID_BOOT_INPUT_RPT_CLIENT_CONFIG:
        {
            p_value = val;

            BufWriteUint16(&p_value, hid_data.input_boot_client_config);
            /* CCCD value of a characteristic is 2 bytes in length. */
            length = 2;

            /* BufWriteUint16 will have incremented p_value. Revert it back
             * to point to val.
             */
            p_value -= length;
        }
        break;

        case HANDLE_HID_INPUT_REPORT:
        {
            /* The input report array is maintained by mouse_hw.c. Get a
             * reference to it.
             */
            p_value = GetMouseReport(HID_INPUT_REPORT_ID);
            length = ATTR_LEN_HID_INPUT_REPORT;
        }
        break;

        case HANDLE_HID_BOOT_INPUT_REPORT:
        {
            /* The input report array is maintained by mouse_hw.c. Get a
             * reference to it.
             */
            p_value = GetMouseReport(HID_INPUT_REPORT_ID);
            length = ATTR_LEN_HID_BOOT_INPUT_REPORT;
        }
        break;

        case HANDLE_HID_PROTOCOL_MODE:
        {
            p_value = val;

            /* Get the current protocol mode. */
            p_value[0] = hid_data.report_mode;
            length = ATTR_LEN_HID_PROTOCOL_MODE;
        }
        break;

        case HANDLE_HID_FEATURE_REPORT:
        {
            p_value = val;

            val[0] = GetSensorResolution();
            
            /* Feature report value is 1 byte in length */
            length = ATTR_LEN_HID_FEATURE_REPORT;
        }
        break;

        default:
        {
            /* Let firmware handle the request */
            rc = gatt_status_irq_proceed;
        }
        break;
    }

    GattAccessRsp(p_ind->cid, p_ind->handle, rc,
                  length, p_value);

}
Exemplo n.º 28
0
extern void HeartRateHandleAccessWrite(GATT_ACCESS_IND_T *p_ind)
{
    uint8 *p_value = p_ind->value;
    gatt_client_config client_config;
    sys_status rc = sys_status_success;

    switch(p_ind->handle)
    {
        /* Heart Rate measurement characteristic client configuration is being 
         * written 
         */
        case HANDLE_EEG_MEASUREMENT_C_CFG:
        {
            client_config = BufReadUint16(&p_value);


            /* Client Configuration is bit field value so ideally bitwise 
             * comparison should be used but since the application supports only 
             * notifications, direct comparison is being used.
             */
            if((client_config == gatt_client_config_notification) ||
               (client_config == gatt_client_config_none))
            {                            
                /* Store the new client configuration */
                g_eeg_serv_data.hr_meas_client_config = client_config;

                /* Write Heart Rate Measurement Client configuration to NVM if 
                 * the device is bonded.
                 */
                if(AppIsDeviceBonded())
                {
                     Nvm_Write((uint16*)&client_config,
                              sizeof(client_config),
                              g_eeg_serv_data.nvm_offset + 
                              HR_NVM_HR_MEAS_CLIENT_CONFIG_OFFSET);
                }

                /* Start sending the HR measurement notifications if they are 
                 * not being sent currently. 
                 */
                StartSendingHRMeasurements();
            }
            else
            {
                /* INDICATION or RESERVED */

                /* Return Error as only Notifications are supported */
                rc = gatt_status_desc_improper_config;
            }

            break;
        }

        /* EEG channels Control point is being written */
        case HANDLE_EEG_CHANNELS:
        {
            /* Extract the written value */
            g_eeg_serv_data.channel_map = BufReadUint16(&p_value);
            DebugWriteString("\n\rChannel map updated");
            break;
        }
		
		case HANDLE_EEG_ACQUISITION_RATE:
		{
            g_eeg_serv_data.acquisition_rate = BufReadUint16(&p_value);
            TimerDelete(g_eeg_serv_data.acq_tmr);
            g_eeg_serv_data.acq_tmr = TimerCreate((uint32) (1000000/g_eeg_serv_data.acquisition_rate),
                                 TRUE, 
                                 acquireData); 
			DebugWriteString("\n\rAcq Rate changed");
            break;
		}
		
        default:
        {
            /* Write is not permitted on any other characteristic/attribute */
            rc = gatt_status_write_not_permitted;
            break;
        }
    }

    /* Send ACCESS RESPONSE */
    GattAccessRsp(p_ind->cid, p_ind->handle, rc, 0, NULL);

}