コード例 #1
0
ファイル: scps.c プロジェクト: dmaone/CommonSense
/*******************************************************************************
* Function Name: ScpsCallBack()
********************************************************************************
*
* Summary:
*   This is an event callback function to receive service specific events from 
*   SCPS Service.
*
* Parameters:
*  event - the event code
*  *eventParam - the event parameters
*
* Return:
*  None.
*
********************************************************************************/
void ScpsCallBack (uint32 event, void *eventParam)
{
    DBG_PRINTF("SCPS event: %lx, ", event);
    switch(event)
    {
        case CYBLE_EVT_SCPSS_NOTIFICATION_ENABLED:
            DBG_PRINTF("CYBLE_EVT_SCPSS_NOTIFICATION_ENABLED \r\n");
            requestScanRefresh = ENABLED;
            break;
        case CYBLE_EVT_SCPSS_NOTIFICATION_DISABLED:
            DBG_PRINTF("CYBLE_EVT_SCPSS_NOTIFICATION_DISABLED \r\n");
            requestScanRefresh = DISABLED;
            break;
        case CYBLE_EVT_SCPSS_SCAN_INT_WIN_CHAR_WRITE:
            scanInterval = CyBle_Get16ByPtr(((CYBLE_SCPS_CHAR_VALUE_T *)eventParam)->value->val);
            scanWindow = CyBle_Get16ByPtr(((CYBLE_SCPS_CHAR_VALUE_T *)eventParam)->value->val + sizeof(scanInterval));
            DBG_PRINTF("CYBLE_EVT_SCPSS_SCAN_INT_WIN_CHAR_WRITE scanInterval: %x, scanWindow: %x \r\n", scanInterval, scanWindow);
            break;
        case CYBLE_EVT_SCPSC_NOTIFICATION:
            break;
        case CYBLE_EVT_SCPSC_READ_DESCR_RESPONSE:
            break;
        case CYBLE_EVT_SCPSC_WRITE_DESCR_RESPONSE:
            break;
        default:
            DBG_PRINTF("Not supported event\r\n");
			break;
    }
}
コード例 #2
0
ファイル: hrss.c プロジェクト: Ahamedjee/PSoC-4-BLE
/*******************************************************************************
* Function Name: HrssGetHrmDescriptor
********************************************************************************
*
* Summary:
*   Gets the Heart Rate Measurement characteristic
*   Configuration Descriptor value
*
* Parameters:
*   None.
*
* Return:
*   uint16 value of the Heart Rate Measurement characteristic
*   configuration Descriptor.
*
*******************************************************************************/
uint16 HrssGetHrmDescriptor(void)
{
    uint8 val[CYBLE_CCCD_LEN];
    uint16 retVal;

    if(CYBLE_ERROR_OK == CyBle_HrssGetCharacteristicDescriptor(CYBLE_HRS_HRM,
        CYBLE_HRS_HRM_CCCD, CYBLE_CCCD_LEN, val))
    {
        /* Using the length as a temporary variable with suitable type to return */
        retVal = CyBle_Get16ByPtr(val);
    }
    else
    {
        retVal = 0u;
    }

    return (retVal);
}
コード例 #3
0
ファイル: ANCS.c プロジェクト: Ahamedjee/PSoC-4-BLE
/*******************************************************************************
* Function Name: Ancs_EventHandler()
********************************************************************************
* Summary:
* Event handler for the Apple Notification Center Service.
*
* Parameters:
* uint32 eventCode: The event to be processed
* void * eventParam: Pointer to hold the additional information associated 
*                    with an event
*
* Return:
* None
*
* Theory:
* This function is responsible for the discovery of the ANCS service, its 
* characteristics, and the characteristic descriptors. 
* Three characteristics are identified - 
*   1. Notification source
*   2. Control Point
*   3. Data source
* All other characteristics (if present) are ignored. 
* The CCCD of Notification Source and Data Source characteristics are identified.
* All other descriptors (if present) are ignored.
*
* Once the discovery procedure is complete, this function writes to the CCCDs 
* of the Notification Source and Data Source characteristics to enable GATT
* notifications on those characteristics.
* It also subscribes to the Service Changed indication on the GATT service for
* any future service change.
*
*******************************************************************************/
void Ancs_EventHandler(uint32 eventCode, void * eventParam)
{
    uint16 counter;
    uint16 dataLength;
    uint16 attributeLength;
    
    SERVICE_DATA_STRUCT * serviceData;
    CHAR_DATA_STRUCT characteristicData;
    DESC_DATA_STRUCT * descriptorData;
    
    CYBLE_GATTC_READ_BY_GRP_RSP_PARAM_T * readByGroupResponse;
    CYBLE_GATTC_READ_BY_TYPE_RSP_PARAM_T * readByTypeResponse;
    CYBLE_GATTC_FIND_INFO_RSP_PARAM_T * findInfoResponse;
    CYBLE_GATTC_ERR_RSP_PARAM_T * errorResponse;
    
    switch(eventCode)
    {
        /* Case to discover services */
        case CYBLE_EVT_GATTC_READ_BY_GROUP_TYPE_RSP:
            /* Typecast the event paramter for Read by Group Response data */ 
            readByGroupResponse = (CYBLE_GATTC_READ_BY_GRP_RSP_PARAM_T *)eventParam;
            dataLength = readByGroupResponse->attrData.length;
            attributeLength = readByGroupResponse->attrData.attrLen;
            
            /* Search for ANCS service within Services with 128-bit UUID only */
            if((dataLength == CYBLE_DISC_SRVC_INFO_128_LEN) && (ancsDiscoveryStatus == ANCS_DISC_NONE_DISCOVERED))
            {
                for(counter = 0; counter < attributeLength; counter += dataLength)
                {
                    /* Read by Group response data consists of rows of 
                     * {Service Handle range, Service UUID}.
                     * So typecast the relevant data into that structure.
                     */
                    serviceData = (SERVICE_DATA_STRUCT *)(readByGroupResponse->attrData.attrValue + counter);
                    
                    /* Check whether the Service UUID matches that of ANCS */
                    if(memcmp(serviceData->uuid.value, ancsServiceUuid, CYBLE_GATT_128_BIT_UUID_SIZE) == 0)
                    {
                        /* Match! ANCS Service found. */
                        ancsServiceRange.startHandle = serviceData->range.startHandle;
                        ancsServiceRange.endHandle = serviceData->range.endHandle;
                        ancsDiscoveryStatus = ANCS_DISC_SERVICE_DISCOVERED;
                        break;
                    }
                }
            }
            break;

            
        /* Case to discover characteristics */
        case CYBLE_EVT_GATTC_READ_BY_TYPE_RSP:
            if(ANCS_DISC_SERVICE_DISCOVERED == ancsDiscoveryStatus)
            {
                /* Typecast the event paramter for Read by Type Response data */ 
                readByTypeResponse = (CYBLE_GATTC_READ_BY_TYPE_RSP_PARAM_T *)eventParam;
                dataLength = readByTypeResponse->attrData.length;
                attributeLength = readByTypeResponse->attrData.attrLen;
                
                /* Search for ANCS characteristics (128-bit UUID) in the data */
                if(dataLength == CYBLE_DISC_CHAR_INFO_128_LEN)
                {
                    for(counter = 0; counter < attributeLength; counter += dataLength)
                    {
                        /* Cache the characteristic UUID in a buffer */
                        characteristicData.valueHandle = CyBle_Get16ByPtr(readByTypeResponse->attrData.attrValue + counter + 3);
                        memcpy(characteristicData.uuid.value, (uint8 *)(readByTypeResponse->attrData.attrValue + counter + 5), CYBLE_GATT_128_BIT_UUID_SIZE);
                        
                        /* Compare the UUID with known UUIDs for ANCS */
                        if(memcmp(characteristicData.uuid.value, ancsNotifSourceCharUuid, CYBLE_GATT_128_BIT_UUID_SIZE) == 0)
                        {
                            /* Match! ANCS Notification Source characteristic */
                            ancsNotifSourceCharHandle = characteristicData.valueHandle;
                        }
                        else if(memcmp(characteristicData.uuid.value, ancsControlPointCharUuid, CYBLE_GATT_128_BIT_UUID_SIZE) == 0)
                        {
                            /* Match! ANCS Control Point characteristic */
                            ancsControlPointCharHandle = characteristicData.valueHandle;
                        }
                        else if(memcmp(characteristicData.uuid.value, ancsDataSourceCharUuid, CYBLE_GATT_128_BIT_UUID_SIZE) == 0)
                        {
                            /* Match! ANCS Data Source characteristic */
                            ancsDataSourceCharHandle = characteristicData.valueHandle;
                        }
                        else
                        {
                            /* Unknown characteristic */
                        }
                    }
                }
            }
            break;

            
        /* Case to discover characteristic descriptors */
        case CYBLE_EVT_GATTC_FIND_INFO_RSP:
            if(ANCS_DISC_CHAR_DISCOVERED == ancsDiscoveryStatus)
            {
                /* Typecast the event paramter for Find Info Response data */ 
                findInfoResponse = (CYBLE_GATTC_FIND_INFO_RSP_PARAM_T *)eventParam;
                dataLength = CYBLE_DB_ATTR_HANDLE_LEN + CYBLE_GATT_16_BIT_UUID_SIZE;
                attributeLength = findInfoResponse->handleValueList.byteCount;
                
                /* Search within the descriptors with 16-bit UUID */
                if(findInfoResponse->uuidFormat == CYBLE_GATT_16_BIT_UUID_FORMAT)
                {
                    for(counter = 0; counter < attributeLength; counter += dataLength)
                    {
                        /* Find Info Response data consists of rows of 
                         * {Handle, UUID} of descriptors. So typecast the 
                         * relevant data into that structure.
                         */
                        descriptorData = (DESC_DATA_STRUCT *)(findInfoResponse->handleValueList.list + counter);
                        
                        /* Search for CCCD descriptors in the data */
                        if(descriptorData->uuid == CCCD_UUID_16BIT)
                        {
                            /* Found the CCCD descriptor; now check which 
                             * characteristic it belongs to.
                             */
                            if((descriptorData->descHandle < ancsNotifSourceCharHandle) && 
                               (descriptorData->descHandle < ancsDataSourceCharHandle))
                            {
                                /* Unknown CCCD; ignore */
                            }
                            else if((descriptorData->descHandle > ancsNotifSourceCharHandle) && 
                                    (descriptorData->descHandle < ancsDataSourceCharHandle))
                            {
                                /* This belongs to the Notification source 
                                 * characteristic.
                                 */
                                ancsNotifSourceCccdHandle = descriptorData->descHandle;
                            }
                            else if((descriptorData->descHandle < ancsNotifSourceCharHandle) && 
                                    (descriptorData->descHandle > ancsDataSourceCharHandle))
                            {
                                /* This belongs to the Data source 
                                 * characteristic.
                                 */
                                ancsDataSourceCccdHandle = descriptorData->descHandle;
                            }
                            else if((descriptorData->descHandle > ancsNotifSourceCharHandle) && 
                                    (descriptorData->descHandle > ancsDataSourceCharHandle))
                            {
                                /* Check if the CCCD is within range of the 
                                 * ANCS service. 
                                 */
                                if(descriptorData->descHandle <= ancsServiceRange.endHandle)
                                {
                                    /* Need to know whether Notification source 
                                     * char handle is more or Data source char. 
                                     */
                                    if(ancsNotifSourceCharHandle < ancsDataSourceCharHandle)
                                    {
                                        /* Data source CCCD */
                                        ancsDataSourceCccdHandle = descriptorData->descHandle;
                                    }
                                    else if(ancsNotifSourceCharHandle > ancsDataSourceCharHandle)
                                    {
                                        /* Notification source CCCD */
                                        ancsNotifSourceCccdHandle = descriptorData->descHandle;
                                    }
                                }
                                else
                                {
                                    /* Unknown CCCD; ignore */
                                }
                            }
                            else
                            {
                                /* Invalid data; ignore */
                            }
                        }
                        
                        if(descriptorData->descHandle == descriptorHandleRange.endHandle)
                        {
                            /* Descriptor discovery is complete */
                            ancsDiscoveryStatus = ANCS_DISC_DESC_DISCOVERED;
                            
                            /* Service discovery procedure complete; subscribe to the GATT
                             * Service changed indication by writing 0x02 to its CCCD.
                             */
                            if((serviceChangedCccdWriteStatus == SERVICE_CHANGED_CCCD_WRITE_REQ_NOT_SENT) && 
                              (cyBle_gattc.serviceChanged.valueHandle != CYBLE_GATT_INVALID_ATTR_HANDLE_VALUE))
                            {
                                serviceChangedCccdPacket.value = cccdIndFlagSetStruct;
                                serviceChangedCccdPacket.attrHandle = cyBle_gattc.cccdHandle;
                                CyBle_GattcWriteCharacteristicDescriptors(cyBle_connHandle, &serviceChangedCccdPacket);
                            }
                            serviceChangedCccdWriteStatus = SERVICE_CHANGED_CCCD_WRITE_REQ_SENT;
                            
                            break;
                        }
                    }
                }
            }
            break;

            
        case CYBLE_EVT_GATTC_WRITE_RSP:
            /* Service changed CCCD set to 0x02 to enable indications */
            if(serviceChangedCccdWriteStatus == SERVICE_CHANGED_CCCD_WRITE_REQ_SENT)
            {
                serviceChangedCccdWriteStatus = SERVICE_CHANGED_CCCD_WRITE_RESP_RECEIVED;
                
                /* Enable Notification source characteristic notifications */
                if(ancsDiscoveryStatus == ANCS_DISC_DESC_DISCOVERED)
                {
                    ancsNotificationSourceCccdPacket.value = cccdNotifFlagSetStruct;
                    ancsNotificationSourceCccdPacket.attrHandle = ancsNotifSourceCccdHandle;
                    CyBle_GattcWriteCharacteristicDescriptors(cyBle_connHandle, &ancsNotificationSourceCccdPacket);
                    ancsDiscoveryStatus = ANCS_DISC_NOTIF_SOURCE_CCCD_SET;
                }
            }
            /* ANCS Notification source characteristic CCCD set to 0x01
             * to enable notifications 
             */
            else if((ancsDiscoveryStatus == ANCS_DISC_NOTIF_SOURCE_CCCD_SET) &&
                    (ancsDataSourceCccdHandle != 0))
            {
                ancsDataSourceCccdPacket.value = cccdNotifFlagSetStruct;
                ancsDataSourceCccdPacket.attrHandle = ancsDataSourceCccdHandle;
                CyBle_GattcWriteCharacteristicDescriptors(cyBle_connHandle, &ancsDataSourceCccdPacket);
                ancsDiscoveryStatus = ANCS_DISC_DATA_SOURCE_CCCD_SET;
            }
            /* ANCS Data source characteristic CCCD set to 0x01 to enable
             * notifications.
             */
            else if(ancsDiscoveryStatus == ANCS_DISC_DATA_SOURCE_CCCD_SET)
            {
                ancsDiscoveryStatus = ANCS_DISC_WRITE_COMPLETE;
            }
            break;

            
        case CYBLE_EVT_GATTC_ERROR_RSP:
            errorResponse = (CYBLE_GATTC_ERR_RSP_PARAM_T *)eventParam;
            
            /* Check if the ANCS characteristic discovery is complete.
             * Initiate descriptor discovery if it is done.
             */
            if(ancsDiscoveryStatus == ANCS_DISC_SERVICE_DISCOVERED)
            {
                if((errorResponse->opCode == CYBLE_GATT_READ_BY_TYPE_REQ) && 
                   (errorResponse->errorCode == CYBLE_GATT_ERR_ATTRIBUTE_NOT_FOUND) &&
                   (errorResponse->attrHandle == ancsServiceRange.endHandle) &&
                   (cyBle_clientState != CYBLE_CLIENT_STATE_CHAR_DISCOVERING))
                {
                    ancsDiscoveryStatus = ANCS_DISC_CHAR_DISCOVERED;
                    descriptorHandleRange.startHandle = (ancsNotifSourceCharHandle < ancsDataSourceCharHandle) ? 
                                                        (ancsNotifSourceCharHandle + 1) : 
                                                        (ancsDataSourceCharHandle + 1);
                    descriptorHandleRange.endHandle = ancsServiceRange.endHandle;
                    CyBle_GattcDiscoverAllCharacteristicDescriptors(cyBle_connHandle, &descriptorHandleRange);
                }
            }
            break;
            
            
        default:
            break;
    }
}
コード例 #4
0
ファイル: Eddystone.c プロジェクト: seung1107/wimds_ble_gps
/*******************************************************************************
* Function Name: ProcessWriteReq
********************************************************************************
*
* Summary:
*  Process all GATT level write requests and responds with appropriate status
*
* Parameters:
*  CYBLE_GATTS_WRITE_CMD_REQ_PARAM_T:  GATT write command request prameter
*
* Return:
*  None
*
*******************************************************************************/
void ProcessWriteReq(CYBLE_GATTS_WRITE_CMD_REQ_PARAM_T writeCmdReq)
{
    bool value_val;
    uint8 status = LOCKED, key_buf[LOCK_CODE_LENGTH];
    uint16 beaconPeriod = 0;
    CYBLE_GATT_HANDLE_VALUE_PAIR_T valuePairT;
    /* Reset error send flag */
    errorSent = false;
    /* Retrieve the LOCK status from the GATT DB */
    valuePairT.attrHandle =
                        CYBLE_EDDYSTONE_CONFIGURATION_LOCK_STATE_CHAR_HANDLE;
    valuePairT.value.val = (uint8 *)&value_val;
    valuePairT.value.len = sizeof(bool);

    CyBle_GattsReadAttributeValue( &valuePairT, &cyBle_connHandle,
                                    CYBLE_GATT_DB_LOCALLY_INITIATED );

    /* Check the LOCK status */
    if(valuePairT.value.val[0] == UNLOCKED)
    {
        /*URL Data*/
        if(writeCmdReq.handleValPair.attrHandle ==
                            CYBLE_EDDYSTONE_CONFIGURATION_URI_DATA_CHAR_HANDLE)
        {
            /* First byte should be scheme prefix and length should be less than
            *  or equal to MAX_URL_LENGTH */
            if( (writeCmdReq.handleValPair.value.len <= MAX_URL_LENGTH) &&
                (writeCmdReq.handleValPair.value.val[0] < URL_PREFIX_MAX)   )
            {
                uint8 TempURL[MAX_URL_LENGTH];
                memset(TempURL, 0, MAX_URL_LENGTH);
                memcpy(
                            TempURL,
                            writeCmdReq.handleValPair.value.val,
                            writeCmdReq.handleValPair.value.len
                       );
                if( CYBLE_GATT_ERR_NONE == WriteAttributeValue   (
                            CYBLE_EDDYSTONE_CONFIGURATION_URI_DATA_CHAR_HANDLE,
                            writeCmdReq.handleValPair.value.len,
                            writeCmdReq.handleValPair.value.val,
                            CYBLE_GATT_DB_PEER_INITIATED        ) )
                {
                    /* Update the length as per the new URL data */
                    URLLength = writeCmdReq.handleValPair.value.len;
                    cyBle_attValuesLen[16].actualLength = URLLength;
                    /* Update the URL data */
                    memcpy(CurrentURL, TempURL, MAX_URL_LENGTH);
                }
            }
            else if (writeCmdReq.handleValPair.value.len > MAX_URL_LENGTH)
            {
                 /* Invalid length. Send error response */
               SendErrorResponse        (
                            CYBLE_EDDYSTONE_CONFIGURATION_URI_DATA_CHAR_HANDLE,
                            CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN
                                        );
            }
        }
        /* Lock Characteristic */
        else if(writeCmdReq.handleValPair.attrHandle ==
                                CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE)
        {

            if(writeCmdReq.handleValPair.value.len == LOCK_CODE_LENGTH)
            {
                WriteAttributeValue (
                                CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE,
                                writeCmdReq.handleValPair.value.len,
                                writeCmdReq.handleValPair.value.val,
                                CYBLE_GATT_DB_PEER_INITIATED
                                    );

                /* Update the LOCK characteristic */
                status = LOCKED;
                WriteAttributeValue (
                        CYBLE_EDDYSTONE_CONFIGURATION_LOCK_STATE_CHAR_HANDLE,
                        sizeof(bool), &status,
                        CYBLE_GATT_DB_LOCALLY_INITIATED
                                    );
            }
            else
            {
                /* Invalid length. Send error response */
               SendErrorResponse(CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE,
                                    CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN);
            }
        }
        /* Advertised Tx power level */
        else if(writeCmdReq.handleValPair.attrHandle ==
           CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE)
        {

            if (writeCmdReq.handleValPair.value.len == MAX_NUM_PWR_LVL)
            {
                WriteAttributeValue (
                    CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE,
                    writeCmdReq.handleValPair.value.len,
                    writeCmdReq.handleValPair.value.val,
                    CYBLE_GATT_DB_PEER_INITIATED
                                    );

                if (writeCmdReq.handleValPair.value.len == MAX_NUM_PWR_LVL)
                {
                    /* Update Tx Power levels */
                    memcpy  (
                                currentTxPowerLevels,
                                writeCmdReq.handleValPair.value.val,
                                MAX_NUM_PWR_LVL
                            );
                }
                else
                {
                    SendErrorResponse   (
                        CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE,
                        CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN
                                        );
                }
            }
            else
            {
                /* Invalid length. Send error response */
               SendErrorResponse    (
                    CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE,
                    CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN
                                    );
            }
        }
        /* Tx Power Mode */
        else if(writeCmdReq.handleValPair.attrHandle ==
                        CYBLE_EDDYSTONE_CONFIGURATION_TX_POWER_MODE_CHAR_HANDLE)
        {

            if(writeCmdReq.handleValPair.value.val[0] <= 0x03)
            {
                WriteAttributeValue (
                        CYBLE_EDDYSTONE_CONFIGURATION_TX_POWER_MODE_CHAR_HANDLE,
                        writeCmdReq.handleValPair.value.len,
                        writeCmdReq.handleValPair.value.val,
                        CYBLE_GATT_DB_PEER_INITIATED
                                    );
                currentTxmode = writeCmdReq.handleValPair.value.val[0];

                UpdateTxPower(currentTxmode);
            }
            else /* Invalid value. Write not permitted. */
            {
                SendErrorResponse   (
                        CYBLE_EDDYSTONE_CONFIGURATION_TX_POWER_MODE_CHAR_HANDLE,
                        CYBLE_GATT_ERR_WRITE_NOT_PERMITTED
                                    );
            }
        }
        /* Beacon Period */
        else if(writeCmdReq.handleValPair.attrHandle ==
                        CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE)
        {

            beaconPeriod =
                        CyBle_Get16ByPtr(writeCmdReq.handleValPair.value.val);

            /* Disable URL FRAMES */
            if(beaconPeriod == 0)
            {
                eddystoneImplenmentation = EDDYSTONE_UID;
                WriteAttributeValue (
                        CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE,
                        writeCmdReq.handleValPair.value.len,
                        writeCmdReq.handleValPair.value.val,
                        CYBLE_GATT_DB_PEER_INITIATED
                                    );
            }
            /* Values in valid range */
            else if((beaconPeriod >= MIN_BEACON_PERIOD) &&
                    (beaconPeriod <= MAX_BEACON_PERIOD))
            {
                WriteAttributeValue (
                        CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE,
                        writeCmdReq.handleValPair.value.len,
                        writeCmdReq.handleValPair.value.val,
                        CYBLE_GATT_DB_PEER_INITIATED
                                    );
                CurrentAdvPeriod = beaconPeriod / 0.625;
                eddystoneImplenmentation = EDDYSTONE_URL;
            }
            else
            {
                uint16 temp = MIN_BEACON_PERIOD;
                /* Values not supportes. Write default values */
                WriteAttributeValue(
                        CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE,
                        sizeof(temp),
                        (uint8 *)&temp,
                        CYBLE_GATT_DB_PEER_INITIATED);
                CurrentAdvPeriod = CYBLE_GAP_ADV_ADVERT_INTERVAL_NONCON_MIN;
                eddystoneImplenmentation = EDDYSTONE_URL;
            }
        }
        /* Reset the Configurations to default */
        else if((writeCmdReq.handleValPair.attrHandle ==
                CYBLE_EDDYSTONE_CONFIGURATION_RESET_CHAR_HANDLE) &&
                (writeCmdReq.handleValPair.value.val[0] != 0))

        {
            ResetGattDb();
        }
    }
    else if(valuePairT.value.val[0] == LOCKED)
    {

        if(writeCmdReq.handleValPair.attrHandle ==
                                CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE)
        {
            /* Accesing the lock in LOCKED state */
            SendErrorResponse(writeCmdReq.handleValPair.attrHandle,
                                    CYBLE_GATT_ERR_INSUFFICIENT_AUTHORIZATION);
        }
    }

    if(writeCmdReq.handleValPair.attrHandle ==
                        CYBLE_EDDYSTONE_CONFIGURATION_UNLOCK_CHAR_HANDLE)
    {
        if(writeCmdReq.handleValPair.value.len == LOCK_CODE_LENGTH)
        {
            if(valuePairT.value.val[0] == LOCKED)
            {
                int compareResult;
                valuePairT.attrHandle =
                                CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE;
                valuePairT.value.val = key_buf;
                valuePairT.value.len = sizeof(LOCK);
                CyBle_GattsReadAttributeValue(&valuePairT, &cyBle_connHandle,
                                            CYBLE_GATT_DB_LOCALLY_INITIATED);

                compareResult = memcmp  (
                                            valuePairT.value.val,
                                            writeCmdReq.handleValPair.value.val,
                                            LOCK_CODE_LENGTH
                                        );

                if(compareResult == 0)
                {
                    status = UNLOCKED;
                    /* Update the LOCK STATE */
                    WriteAttributeValue (
                        CYBLE_EDDYSTONE_CONFIGURATION_LOCK_STATE_CHAR_HANDLE,
                        sizeof(bool), &status,
                        CYBLE_GATT_DB_LOCALLY_INITIATED
                                        );

                    /* Reset the LOCK */
                    WriteAttributeValue (
                                CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE,
                                sizeof(LOCK), (uint8 *)LOCK,
                                CYBLE_GATT_DB_LOCALLY_INITIATED
                                        );
                }
                else /* LOCK not matched */
                {
                    SendErrorResponse(writeCmdReq.handleValPair.attrHandle,
                                    CYBLE_GATT_ERR_INSUFFICIENT_AUTHORIZATION);
                }
            }
        }
        else /* Invalid length */
        {
            SendErrorResponse(writeCmdReq.handleValPair.attrHandle,
                                        CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN);
        }
    }

    if (errorSent == false)
    {
        CyBle_GattsWriteRsp(cyBle_connHandle);
    }
}
コード例 #5
0
ファイル: BLE_hts.c プロジェクト: Shogun5/BLE
/******************************************************************************
##Function Name: CyBle_HtssWriteEventHandler
*******************************************************************************

Summary:
 Handles Write Request Event for HTS service.

Parameters:
 void *eventParam: The pointer to the data structure specified by the event.

Return:
 Return value is of type CYBLE_GATT_ERR_CODE_T.
  * CYBLE_GATT_ERR_NONE - Write is successful

******************************************************************************/
CYBLE_GATT_ERR_CODE_T CyBle_HtssWriteEventHandler(CYBLE_GATTS_WRITE_REQ_PARAM_T *eventParam)
{
    CYBLE_HTS_CHAR_INDEX_T locCharIndex;
    CYBLE_HTS_CHAR_VALUE_T locCharValue;
    CYBLE_GATT_ERR_CODE_T gattErr = CYBLE_GATT_ERR_NONE;
    uint8 locReqHandle = 0u;

    if(NULL != CyBle_HtsApplCallback)
    {
        for(locCharIndex = CYBLE_HTS_TEMP_MEASURE; (locCharIndex < CYBLE_HTS_CHAR_COUNT) && (locReqHandle == 0u); 
            locCharIndex++)
        {
            
            if((eventParam->handleValPair.attrHandle == cyBle_htss.charInfo[locCharIndex].descrHandle[CYBLE_HTS_CCCD]) ||
               (eventParam->handleValPair.attrHandle == cyBle_htss.charInfo[locCharIndex].charHandle))
            {
                locCharValue.connHandle = eventParam->connHandle;
                locCharValue.charIndex = locCharIndex;
                locCharValue.value = &eventParam->handleValPair.value;
                /* Characteristic value write request */
                if(eventParam->handleValPair.attrHandle == cyBle_htss.charInfo[locCharIndex].charHandle)
                {
                    /* Validate Measure Interval value */
                    if(locCharIndex == CYBLE_HTS_MEASURE_INTERVAL)
                    {
                        uint8 locAttrValue[CYBLE_HTS_VRD_LEN];
                        uint16 requestValue;
                        
                        requestValue = CyBle_Get16ByPtr(eventParam->handleValPair.value.val);
                        
                        if(requestValue != 0u) /* 0 is valid interval value for no periodic measurement */
                        {
                            /* Check Valid range for Measure Interval characteristic value */
                            if(CYBLE_ERROR_OK == CyBle_HtssGetCharacteristicDescriptor(locCharIndex, CYBLE_HTS_VRD, 
                                                    CYBLE_HTS_VRD_LEN, locAttrValue))
                            {
                                uint16 lowerValue;
                                uint16 upperValue;
                                
                                lowerValue = CyBle_Get16ByPtr(locAttrValue);
                                upperValue = CyBle_Get16ByPtr(locAttrValue + sizeof(lowerValue));
                                requestValue = CyBle_Get16ByPtr(eventParam->handleValPair.value.val);
                                if((requestValue != 0u) && ((requestValue < lowerValue) || (requestValue > upperValue)))
                                {
                                    gattErr = CYBLE_GATT_ERR_HTS_OUT_OF_RANGE;
                                }
                            }
                        }
                    }
                    if(CYBLE_GATT_ERR_NONE == gattErr)
                    {   /* Store value to database */
                        gattErr = CyBle_GattsWriteAttributeValue(&eventParam->handleValPair, 0u, 
                                    &eventParam->connHandle, CYBLE_GATT_DB_PEER_INITIATED);
                        if(CYBLE_GATT_ERR_NONE == gattErr)
                        {
                            CyBle_HtsApplCallback((uint32)CYBLE_EVT_HTSS_CHAR_WRITE, &locCharValue);
                        }
                    }    
                }
                else /* Client Characteristic Configuration descriptor write request */
                {
                    /* Store value to database */
                    gattErr = CyBle_GattsWriteAttributeValue(&eventParam->handleValPair, 0u, 
                                    &eventParam->connHandle, CYBLE_GATT_DB_PEER_INITIATED);
                    if(CYBLE_GATT_ERR_NONE == gattErr)
                    {
                        /* Check characteristic properties for Notification */
                        if(CYBLE_IS_NOTIFICATION_SUPPORTED(cyBle_htss.charInfo[locCharIndex].charHandle))
                        {
                            if(CYBLE_IS_NOTIFICATION_ENABLED_IN_PTR(eventParam->handleValPair.value.val))
                            {
                                CyBle_HtsApplCallback((uint32)CYBLE_EVT_HTSS_NOTIFICATION_ENABLED, &locCharValue);
                            }
                            else
                            {
                                CyBle_HtsApplCallback((uint32)CYBLE_EVT_HTSS_NOTIFICATION_DISABLED, &locCharValue);
                            }
                        }
                        /* Check characteristic properties for Indication */
                        if(CYBLE_IS_INDICATION_SUPPORTED(cyBle_htss.charInfo[locCharIndex].charHandle))
                        {
                            if(CYBLE_IS_INDICATION_ENABLED_IN_PTR(eventParam->handleValPair.value.val))
                            {
                                CyBle_HtsApplCallback((uint32)CYBLE_EVT_HTSS_INDICATION_ENABLED, &locCharValue);
                            }
                            else
                            {
                                CyBle_HtsApplCallback((uint32)CYBLE_EVT_HTSS_INDICATION_DISABLED, &locCharValue);
                            }
                        }
                    #if((CYBLE_GAP_ROLE_PERIPHERAL || CYBLE_GAP_ROLE_CENTRAL) && \
                        (CYBLE_BONDING_REQUIREMENT == CYBLE_BONDING_YES))
                        /* Set flag to store bonding data to flash */
                        cyBle_pendingFlashWrite |= CYBLE_PENDING_CCCD_FLASH_WRITE_BIT;
                    #endif /* (CYBLE_BONDING_REQUIREMENT == CYBLE_BONDING_YES) */
                        
                    }
                }
                cyBle_eventHandlerFlag &= (uint8)~CYBLE_CALLBACK;
                locReqHandle = 1u;
            }
        }
    }
    return (gattErr);
}