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);
}
Ejemplo n.º 2
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);
    }

}
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);
    }

}
Ejemplo n.º 4
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);
    }

}
Ejemplo n.º 5
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);
}
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);

}
Ejemplo n.º 7
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);

}
Ejemplo n.º 8
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);

}
Ejemplo n.º 9
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;
        }
    }
}