in HAP/HAPIPAccessoryServer.c [1489:1734]
static void handle_characteristic_read_request(
HAPIPSessionDescriptor* session,
const HAPCharacteristic* chr_,
const HAPService* svc,
const HAPAccessory* acc,
HAPIPReadContextRef* ctx,
HAPIPByteBuffer* data_buffer) {
HAPPrecondition(session);
HAPPrecondition(session->server);
HAPPrecondition(session->securitySession.type == kHAPIPSecuritySessionType_HAP);
HAPPrecondition(session->securitySession.isOpen);
HAPPrecondition(session->securitySession.isSecured || kHAPIPAccessoryServer_SessionSecurityDisabled);
HAPPrecondition(!HAPSessionIsTransient(&session->securitySession._.hap));
HAPError err;
size_t n, sval_length;
bool bool_val;
int32_t int_val;
uint8_t uint8_val;
uint16_t uint16_val;
uint32_t uint32_val;
uint64_t uint64_val;
float float_val;
HAPTLVWriterRef tlv8_writer;
HAPAssert(chr_);
const HAPBaseCharacteristic* chr = chr_;
HAPAssert(svc);
HAPAssert(acc);
HAPAssert(ctx);
HAPAssert(data_buffer);
HAPAssert(data_buffer->data);
HAPAssert(data_buffer->position <= data_buffer->limit);
HAPAssert(data_buffer->limit <= data_buffer->capacity);
HAPIPReadContext* readContext = (HAPIPReadContext*) ctx;
readContext->status = kHAPIPAccessoryServerStatusCode_Success;
switch (chr->format) {
case kHAPCharacteristicFormat_Data: {
err = HAPDataCharacteristicHandleRead(
HAPNonnull(session->server),
&(const HAPDataCharacteristicReadRequest) { .transportType = kHAPTransportType_IP,
.session = &session->securitySession._.hap,
.characteristic = (const HAPDataCharacteristic*) chr,
.service = svc,
.accessory = acc },
&data_buffer->data[data_buffer->position],
data_buffer->limit - data_buffer->position,
&sval_length,
HAPAccessoryServerGetClientContext(HAPNonnull(session->server)));
readContext->status = ConvertCharacteristicReadErrorToStatusCode(err);
if (readContext->status == kHAPIPAccessoryServerStatusCode_Success) {
if (sval_length <= data_buffer->limit - data_buffer->position) {
util_base64_encode(
&data_buffer->data[data_buffer->position],
sval_length,
&data_buffer->data[data_buffer->position],
data_buffer->limit - data_buffer->position,
&sval_length);
if (sval_length < data_buffer->limit - data_buffer->position) {
data_buffer->data[data_buffer->position + sval_length] = 0;
readContext->value.stringValue.bytes = &data_buffer->data[data_buffer->position];
readContext->value.stringValue.numBytes = sval_length;
data_buffer->position += sval_length + 1;
HAPAssert(data_buffer->position <= data_buffer->limit);
HAPAssert(data_buffer->limit <= data_buffer->capacity);
} else {
readContext->status = kHAPIPAccessoryServerStatusCode_OutOfResources;
}
} else {
readContext->status = kHAPIPAccessoryServerStatusCode_OutOfResources;
}
}
} break;
case kHAPCharacteristicFormat_Bool: {
err = HAPBoolCharacteristicHandleRead(
HAPNonnull(session->server),
&(const HAPBoolCharacteristicReadRequest) { .transportType = kHAPTransportType_IP,
.session = &session->securitySession._.hap,
.characteristic = (const HAPBoolCharacteristic*) chr,
.service = svc,
.accessory = acc },
&bool_val,
HAPAccessoryServerGetClientContext(HAPNonnull(session->server)));
readContext->status = ConvertCharacteristicReadErrorToStatusCode(err);
if (readContext->status == kHAPIPAccessoryServerStatusCode_Success) {
readContext->value.unsignedIntValue = bool_val ? 1 : 0;
}
} break;
case kHAPCharacteristicFormat_UInt8: {
err = HAPUInt8CharacteristicHandleRead(
HAPNonnull(session->server),
&(const HAPUInt8CharacteristicReadRequest) { .transportType = kHAPTransportType_IP,
.session = &session->securitySession._.hap,
.characteristic = (const HAPUInt8Characteristic*) chr,
.service = svc,
.accessory = acc },
&uint8_val,
HAPAccessoryServerGetClientContext(HAPNonnull(session->server)));
readContext->status = ConvertCharacteristicReadErrorToStatusCode(err);
if (readContext->status == kHAPIPAccessoryServerStatusCode_Success) {
readContext->value.unsignedIntValue = uint8_val;
}
} break;
case kHAPCharacteristicFormat_UInt16: {
err = HAPUInt16CharacteristicHandleRead(
HAPNonnull(session->server),
&(const HAPUInt16CharacteristicReadRequest) { .transportType = kHAPTransportType_IP,
.session = &session->securitySession._.hap,
.characteristic =
(const HAPUInt16Characteristic*) chr,
.service = svc,
.accessory = acc },
&uint16_val,
HAPAccessoryServerGetClientContext(HAPNonnull(session->server)));
readContext->status = ConvertCharacteristicReadErrorToStatusCode(err);
if (readContext->status == kHAPIPAccessoryServerStatusCode_Success) {
readContext->value.unsignedIntValue = uint16_val;
}
} break;
case kHAPCharacteristicFormat_UInt32: {
err = HAPUInt32CharacteristicHandleRead(
HAPNonnull(session->server),
&(const HAPUInt32CharacteristicReadRequest) { .transportType = kHAPTransportType_IP,
.session = &session->securitySession._.hap,
.characteristic =
(const HAPUInt32Characteristic*) chr,
.service = svc,
.accessory = acc },
&uint32_val,
HAPAccessoryServerGetClientContext(HAPNonnull(session->server)));
readContext->status = ConvertCharacteristicReadErrorToStatusCode(err);
if (readContext->status == kHAPIPAccessoryServerStatusCode_Success) {
readContext->value.unsignedIntValue = uint32_val;
}
} break;
case kHAPCharacteristicFormat_UInt64: {
err = HAPUInt64CharacteristicHandleRead(
HAPNonnull(session->server),
&(const HAPUInt64CharacteristicReadRequest) { .transportType = kHAPTransportType_IP,
.session = &session->securitySession._.hap,
.characteristic =
(const HAPUInt64Characteristic*) chr,
.service = svc,
.accessory = acc },
&uint64_val,
HAPAccessoryServerGetClientContext(HAPNonnull(session->server)));
readContext->status = ConvertCharacteristicReadErrorToStatusCode(err);
if (readContext->status == kHAPIPAccessoryServerStatusCode_Success) {
readContext->value.unsignedIntValue = uint64_val;
}
} break;
case kHAPCharacteristicFormat_Int: {
err = HAPIntCharacteristicHandleRead(
HAPNonnull(session->server),
&(const HAPIntCharacteristicReadRequest) { .transportType = kHAPTransportType_IP,
.session = &session->securitySession._.hap,
.characteristic = (const HAPIntCharacteristic*) chr,
.service = svc,
.accessory = acc },
&int_val,
HAPAccessoryServerGetClientContext(HAPNonnull(session->server)));
readContext->status = ConvertCharacteristicReadErrorToStatusCode(err);
if (readContext->status == kHAPIPAccessoryServerStatusCode_Success) {
readContext->value.intValue = int_val;
}
} break;
case kHAPCharacteristicFormat_Float: {
err = HAPFloatCharacteristicHandleRead(
HAPNonnull(session->server),
&(const HAPFloatCharacteristicReadRequest) { .transportType = kHAPTransportType_IP,
.session = &session->securitySession._.hap,
.characteristic = (const HAPFloatCharacteristic*) chr,
.service = svc,
.accessory = acc },
&float_val,
HAPAccessoryServerGetClientContext(HAPNonnull(session->server)));
readContext->status = ConvertCharacteristicReadErrorToStatusCode(err);
if (readContext->status == kHAPIPAccessoryServerStatusCode_Success) {
readContext->value.floatValue = float_val;
}
} break;
case kHAPCharacteristicFormat_String: {
err = HAPStringCharacteristicHandleRead(
HAPNonnull(session->server),
&(const HAPStringCharacteristicReadRequest) { .transportType = kHAPTransportType_IP,
.session = &session->securitySession._.hap,
.characteristic =
(const HAPStringCharacteristic*) chr,
.service = svc,
.accessory = acc },
&data_buffer->data[data_buffer->position],
data_buffer->limit - data_buffer->position,
HAPAccessoryServerGetClientContext(HAPNonnull(session->server)));
readContext->status = ConvertCharacteristicReadErrorToStatusCode(err);
if (readContext->status == kHAPIPAccessoryServerStatusCode_Success) {
sval_length = HAPStringGetNumBytes(&data_buffer->data[data_buffer->position]);
if (sval_length < data_buffer->limit - data_buffer->position) {
data_buffer->data[data_buffer->position + sval_length] = 0;
readContext->value.stringValue.bytes = &data_buffer->data[data_buffer->position];
readContext->value.stringValue.numBytes = sval_length;
data_buffer->position += sval_length + 1;
HAPAssert(data_buffer->position <= data_buffer->limit);
HAPAssert(data_buffer->limit <= data_buffer->capacity);
} else {
readContext->status = kHAPIPAccessoryServerStatusCode_OutOfResources;
}
}
} break;
case kHAPCharacteristicFormat_TLV8: {
n = data_buffer->limit - data_buffer->position;
HAPTLVWriterCreate(&tlv8_writer, &data_buffer->data[data_buffer->position], n);
err = HAPTLV8CharacteristicHandleRead(
HAPNonnull(session->server),
&(const HAPTLV8CharacteristicReadRequest) { .transportType = kHAPTransportType_IP,
.session = &session->securitySession._.hap,
.characteristic = (const HAPTLV8Characteristic*) chr,
.service = svc,
.accessory = acc },
&tlv8_writer,
HAPAccessoryServerGetClientContext(HAPNonnull(session->server)));
readContext->status = ConvertCharacteristicReadErrorToStatusCode(err);
if (readContext->status == kHAPIPAccessoryServerStatusCode_Success) {
if (((HAPTLVWriter*) &tlv8_writer)->numBytes <= data_buffer->limit - data_buffer->position) {
util_base64_encode(
&data_buffer->data[data_buffer->position],
((HAPTLVWriter*) &tlv8_writer)->numBytes,
&data_buffer->data[data_buffer->position],
data_buffer->limit - data_buffer->position,
&sval_length);
if (sval_length < data_buffer->limit - data_buffer->position) {
data_buffer->data[data_buffer->position + sval_length] = 0;
readContext->value.stringValue.bytes = &data_buffer->data[data_buffer->position];
readContext->value.stringValue.numBytes = sval_length;
data_buffer->position += sval_length + 1;
HAPAssert(data_buffer->position <= data_buffer->limit);
HAPAssert(data_buffer->limit <= data_buffer->capacity);
} else {
readContext->status = kHAPIPAccessoryServerStatusCode_OutOfResources;
}
} else {
readContext->status = kHAPIPAccessoryServerStatusCode_OutOfResources;
}
}
} break;
}
}