in HAP/HAPIPAccessoryProtocol.c [284:542]
size_t HAPIPAccessoryProtocolGetNumCharacteristicReadResponseBytes(
HAPAccessoryServerRef* server,
HAPIPReadContextRef* readContexts,
size_t numReadContexts,
HAPIPReadRequestParameters* parameters) {
HAPPrecondition(server);
HAPPrecondition(readContexts);
HAPPrecondition(parameters);
size_t r, i, n;
int success;
r = 22;
i = 0;
HAPAssert(i <= numReadContexts);
while ((i < numReadContexts) && (((HAPIPReadContext*) &readContexts[i])->status == 0)) {
i++;
}
HAPIPReadContext* readContext = (HAPIPReadContext*) &readContexts[i];
HAPAssert((i == numReadContexts) || ((i < numReadContexts) && (readContext->status != 0)));
success = i == numReadContexts;
for (i = 0; i < numReadContexts; i++) {
readContext = (HAPIPReadContext*) &readContexts[i];
const HAPBaseCharacteristic* chr_ = GetCharacteristic(server, readContext->aid, readContext->iid);
HAPAssert(chr_ || (readContext->status != 0));
r += (i == 0 ? 15 : 16) + HAPUInt64GetNumDescriptionBytes(readContext->aid) +
HAPUInt64GetNumDescriptionBytes(readContext->iid);
if (parameters->type && chr_) {
r += 10 + HAPUUIDGetNumDescriptionBytes(chr_->characteristicType);
}
if (parameters->meta && chr_) {
switch (chr_->format) {
case kHAPCharacteristicFormat_Bool: {
r += 16;
} break;
case kHAPCharacteristicFormat_UInt8: {
r += 17;
} break;
case kHAPCharacteristicFormat_UInt16: {
r += 18;
} break;
case kHAPCharacteristicFormat_UInt32: {
r += 18;
} break;
case kHAPCharacteristicFormat_UInt64: {
r += 18;
} break;
case kHAPCharacteristicFormat_Int: {
r += 15;
} break;
case kHAPCharacteristicFormat_Float: {
r += 17;
} break;
case kHAPCharacteristicFormat_String: {
r += 18;
} break;
case kHAPCharacteristicFormat_TLV8: {
r += 16;
} break;
case kHAPCharacteristicFormat_Data: {
r += 16;
} break;
}
}
if (readContext->status == 0) {
HAPAssert(chr_);
r += success ? 9 : 20;
if (HAPUUIDAreEqual(chr_->characteristicType, &kHAPCharacteristicType_ProgrammableSwitchEvent)) {
r += 4;
} else {
switch (chr_->format) {
case kHAPCharacteristicFormat_Bool: {
r += 1;
} break;
case kHAPCharacteristicFormat_UInt8:
case kHAPCharacteristicFormat_UInt16:
case kHAPCharacteristicFormat_UInt32:
case kHAPCharacteristicFormat_UInt64: {
r += HAPUInt64GetNumDescriptionBytes(readContext->value.unsignedIntValue);
} break;
case kHAPCharacteristicFormat_Int: {
r += HAPInt32GetNumDescriptionBytes(readContext->value.intValue);
} break;
case kHAPCharacteristicFormat_Float: {
r += HAPJSONUtilsGetFloatNumDescriptionBytes(readContext->value.floatValue);
} break;
case kHAPCharacteristicFormat_String:
case kHAPCharacteristicFormat_TLV8:
case kHAPCharacteristicFormat_Data: {
r += 2 + HAPJSONUtilsGetNumEscapedStringDataBytes(
HAPNonnull(readContext->value.stringValue.bytes),
readContext->value.stringValue.numBytes);
} break;
}
}
} else {
r += 10 + HAPInt32GetNumDescriptionBytes(readContext->status);
}
if (parameters->perms && chr_) {
n = HAPCharacteristicGetNumEnabledProperties(chr_);
r += 11 + (unsigned int) (n == 0 ? 0 : n * 4 + n - 1);
}
if (parameters->ev && chr_) {
r += 6 + (readContext->ev ? 4 : 5);
}
if (parameters->meta && chr_) {
HAPCharacteristicUnits unit = kHAPCharacteristicUnits_None;
switch (chr_->format) {
case kHAPCharacteristicFormat_Bool: {
} break;
case kHAPCharacteristicFormat_UInt8: {
unit = ((const HAPUInt8Characteristic*) chr_)->units;
} break;
case kHAPCharacteristicFormat_UInt16: {
unit = ((const HAPUInt16Characteristic*) chr_)->units;
} break;
case kHAPCharacteristicFormat_UInt32: {
unit = ((const HAPUInt32Characteristic*) chr_)->units;
} break;
case kHAPCharacteristicFormat_UInt64: {
unit = ((const HAPUInt64Characteristic*) chr_)->units;
} break;
case kHAPCharacteristicFormat_Int: {
unit = ((const HAPIntCharacteristic*) chr_)->units;
} break;
case kHAPCharacteristicFormat_Float: {
unit = ((const HAPFloatCharacteristic*) chr_)->units;
} break;
case kHAPCharacteristicFormat_String:
case kHAPCharacteristicFormat_TLV8:
case kHAPCharacteristicFormat_Data: {
} break;
}
switch (unit) {
case kHAPCharacteristicUnits_None: {
r += 0;
} break;
case kHAPCharacteristicUnits_Celsius: {
r += 17;
} break;
case kHAPCharacteristicUnits_ArcDegrees: {
r += 20;
} break;
case kHAPCharacteristicUnits_Percentage: {
r += 20;
} break;
case kHAPCharacteristicUnits_Lux: {
r += 13;
} break;
case kHAPCharacteristicUnits_Seconds: {
r += 17;
} break;
}
switch (chr_->format) {
case kHAPCharacteristicFormat_Bool: {
} break;
case kHAPCharacteristicFormat_UInt8: {
const HAPUInt8Characteristic* chr = (const HAPUInt8Characteristic*) chr_;
uint8_t minimumValue = chr->constraints.minimumValue;
uint8_t maximumValue = chr->constraints.maximumValue;
uint8_t stepValue = chr->constraints.stepValue;
HAPAssert(minimumValue <= maximumValue);
if (minimumValue || maximumValue != UINT8_MAX) {
r += 35 + HAPUInt64GetNumDescriptionBytes(minimumValue) +
HAPUInt64GetNumDescriptionBytes(maximumValue) + HAPUInt64GetNumDescriptionBytes(stepValue);
}
} break;
case kHAPCharacteristicFormat_UInt16: {
const HAPUInt16Characteristic* chr = (const HAPUInt16Characteristic*) chr_;
uint16_t minimumValue = chr->constraints.minimumValue;
uint16_t maximumValue = chr->constraints.maximumValue;
uint16_t stepValue = chr->constraints.stepValue;
HAPAssert(minimumValue <= maximumValue);
if (minimumValue || maximumValue != UINT16_MAX) {
r += 35 + HAPUInt64GetNumDescriptionBytes(minimumValue) +
HAPUInt64GetNumDescriptionBytes(maximumValue) + HAPUInt64GetNumDescriptionBytes(stepValue);
}
} break;
case kHAPCharacteristicFormat_UInt32: {
const HAPUInt32Characteristic* chr = (const HAPUInt32Characteristic*) chr_;
uint32_t minimumValue = chr->constraints.minimumValue;
uint32_t maximumValue = chr->constraints.maximumValue;
uint32_t stepValue = chr->constraints.stepValue;
HAPAssert(minimumValue <= maximumValue);
if (minimumValue || maximumValue != UINT32_MAX) {
r += 35 + HAPUInt64GetNumDescriptionBytes(minimumValue) +
HAPUInt64GetNumDescriptionBytes(maximumValue) + HAPUInt64GetNumDescriptionBytes(stepValue);
}
} break;
case kHAPCharacteristicFormat_UInt64: {
const HAPUInt64Characteristic* chr = (const HAPUInt64Characteristic*) chr_;
uint64_t minimumValue = chr->constraints.minimumValue;
uint64_t maximumValue = chr->constraints.maximumValue;
uint64_t stepValue = chr->constraints.stepValue;
HAPAssert(minimumValue <= maximumValue);
if (minimumValue || maximumValue != UINT64_MAX) {
r += 35 + HAPUInt64GetNumDescriptionBytes(minimumValue) +
HAPUInt64GetNumDescriptionBytes(maximumValue) + HAPUInt64GetNumDescriptionBytes(stepValue);
}
} break;
case kHAPCharacteristicFormat_Int: {
const HAPIntCharacteristic* chr = (const HAPIntCharacteristic*) chr_;
int32_t minimumValue = chr->constraints.minimumValue;
int32_t maximumValue = chr->constraints.maximumValue;
int32_t stepValue = chr->constraints.stepValue;
HAPAssert(minimumValue <= maximumValue);
HAPAssert(stepValue >= 0);
if (minimumValue != INT32_MIN || maximumValue != INT32_MAX) {
r += 35 + HAPInt32GetNumDescriptionBytes(minimumValue) +
HAPInt32GetNumDescriptionBytes(maximumValue) + HAPInt32GetNumDescriptionBytes(stepValue);
}
} break;
case kHAPCharacteristicFormat_Float: {
const HAPFloatCharacteristic* chr = (const HAPFloatCharacteristic*) chr_;
float minimumValue = chr->constraints.minimumValue;
float maximumValue = chr->constraints.maximumValue;
float stepValue = chr->constraints.stepValue;
HAPAssert(HAPFloatIsFinite(minimumValue) || HAPFloatIsInfinite(minimumValue));
HAPAssert(HAPFloatIsFinite(maximumValue) || HAPFloatIsInfinite(maximumValue));
HAPAssert(minimumValue <= maximumValue);
HAPAssert(stepValue >= 0);
if (!(HAPFloatIsInfinite(minimumValue) && minimumValue < 0) ||
!(HAPFloatIsInfinite(maximumValue) && maximumValue > 0)) {
r += 35 + HAPJSONUtilsGetFloatNumDescriptionBytes(minimumValue) +
HAPJSONUtilsGetFloatNumDescriptionBytes(maximumValue) +
HAPJSONUtilsGetFloatNumDescriptionBytes(stepValue);
}
} break;
case kHAPCharacteristicFormat_String: {
const HAPStringCharacteristic* chr = (const HAPStringCharacteristic*) chr_;
uint16_t maxLength = chr->constraints.maxLength;
if (maxLength != 64) {
r += 10 + HAPUInt64GetNumDescriptionBytes(maxLength);
}
} break;
case kHAPCharacteristicFormat_TLV8: {
} break;
case kHAPCharacteristicFormat_Data: {
const HAPDataCharacteristic* chr = (const HAPDataCharacteristic*) chr_;
uint32_t maxLength = chr->constraints.maxLength;
if (maxLength != 2097152) {
r += 14 + HAPUInt64GetNumDescriptionBytes(maxLength);
}
} break;
}
}
}
HAPAssert(i == numReadContexts);
return r;
}