/******************************************************************************* * Function Name: ResetGattDb ******************************************************************************** * * Summary: * Resets all relevant characteristics in the GATT DB * * Parameters: * None * * Return: * None * *******************************************************************************/ void ResetGattDb(void) { /*Default URI Data */ memcpy(CurrentURL, DefaultURL, MAX_URL_LENGTH); WriteAttributeValue(CYBLE_EDDYSTONE_CONFIGURATION_URI_DATA_CHAR_HANDLE, sizeof(DefaultURL), (uint8 *)DefaultURL, CYBLE_GATT_DB_LOCALLY_INITIATED); URLLength = DEFAULT_URL_LENGTH; cyBle_attValuesLen[16].actualLength = URLLength; /*Default URI Flags */ WriteAttributeValue(CYBLE_EDDYSTONE_CONFIGURATION_URI_FLAGS_CHAR_HANDLE, sizeof(DefaultURLFlags), &DefaultURLFlags, CYBLE_GATT_DB_LOCALLY_INITIATED); /*Default TX power mode */ currentTxmode = TX_POWER_MODE_LOW; WriteAttributeValue(CYBLE_EDDYSTONE_CONFIGURATION_TX_POWER_MODE_CHAR_HANDLE, sizeof(currentTxmode), ¤tTxmode, CYBLE_GATT_DB_LOCALLY_INITIATED); /*Default Beacon period */ CurrentAdvPeriod = DEFAULT_BEACON_PERIOD; WriteAttributeValue(CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE, sizeof(CurrentAdvPeriod), (uint8 *)&CurrentAdvPeriod, CYBLE_GATT_DB_LOCALLY_INITIATED); /*Default LOCK key */ WriteAttributeValue(CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE, sizeof(LOCK), (uint8 *)LOCK, CYBLE_GATT_DB_LOCALLY_INITIATED); }
void WriterImplBase::_WritePackageAttributes( const PackageAttributeList& packageAttributes) { DoublyLinkedList<PackageAttribute>::ConstIterator it = packageAttributes.GetIterator(); while (PackageAttribute* attribute = it.Next()) { uint8 encoding = attribute->ApplicableEncoding(); // write tag WriteUnsignedLEB128(compose_attribute_tag( attribute->id, attribute->type, encoding, !attribute->children.IsEmpty())); // write value WriteAttributeValue(*attribute, encoding); if (!attribute->children.IsEmpty()) _WritePackageAttributes(attribute->children); } WriteUnsignedLEB128(0); }
/******************************************************************************* * 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); } }