diff --git a/include/homekit/characteristics.h b/include/homekit/characteristics.h index 93d8ca4..d5cfd23 100644 --- a/include/homekit/characteristics.h +++ b/include/homekit/characteristics.h @@ -815,7 +815,7 @@ .unit = homekit_unit_celsius, \ .permissions = homekit_permissions_paired_read \ | homekit_permissions_notify, \ - .min_value = (float[]) {0}, \ + .min_value = (float[]) {-50}, \ .max_value = (float[]) {100}, \ .min_step = (float[]) {0.1}, \ .value = HOMEKIT_FLOAT_(_value), \ diff --git a/src/homekit_mdns_debug.c b/src/homekit_mdns_debug.c index dd1fee5..a8870ab 100644 --- a/src/homekit_mdns_debug.c +++ b/src/homekit_mdns_debug.c @@ -108,7 +108,7 @@ uint8_t *mdns_print_answer(uint8_t *data, uint8_t *payload) { uint16_t answer_type = mdns_read_u16(data + 0); uint16_t answer_class = mdns_read_u16(data + 2); - uint32_t answer_ttl = mdns_read_u32(data + 4); +// uint32_t answer_ttl = mdns_read_u32(data + 4); uint16_t answer_len = mdns_read_u16(data + 8); data += 10; diff --git a/src/server.c b/src/server.c index cf149e6..2404b28 100644 --- a/src/server.c +++ b/src/server.c @@ -83,6 +83,14 @@ typedef enum { } characteristic_format_t; +typedef enum { + ENCRYPTION_STATE_FALSE = 0, + ENCRYPTION_STATE_VERIFIED, + ENCRYPTION_STATE_GOT_ACCESSORIES, + ENCRYPTION_STATE_IN_USE, + } ENCRYPTION_STATE; + + typedef struct { Srp *srp; byte *public_key; @@ -201,7 +209,7 @@ struct _client_context_t { bool disconnect; - bool encrypted; + int encrypted; byte read_key[32]; byte write_key[32]; int count_reads; @@ -471,7 +479,7 @@ client_context_t *client_context_new() { c->id = 0; c->pairing_id = -1; - c->encrypted = false; + c->encrypted = ENCRYPTION_STATE_FALSE; c->count_reads = 0; c->count_writes = 0; @@ -1101,6 +1109,20 @@ void send_tlv_error_response(client_context_t *context, int state, TLVError erro } +void send_tlv_delay_response(client_context_t *context, int state, int delay) { + tlv_values_t *response = tlv_new(); + if (!response) { + // TODO: panic? + return; + } + tlv_add_integer_value(response, TLVType_State, 1, state); + tlv_add_integer_value(response, TLVType_Error, 1, TLVError_Backoff); + tlv_add_integer_value(response, TLVType_RetryDelay, 1, delay); + + send_tlv_response(context, response); +} + + void send_tlv_response(client_context_t *context, tlv_values_t *values) { CLIENT_DEBUG(context, "Sending TLV response"); TLV_DEBUG(values); @@ -1249,6 +1271,8 @@ void homekit_server_on_identify(client_context_t *context) { CLIENT_INFO(context, "Identify"); DEBUG_HEAP(); + context->encrypted = ENCRYPTION_STATE_IN_USE; + if (context->server->paired) { // Already paired send_json_error_response(context, 400, HAPStatus_InsufficientPrivileges); @@ -1969,6 +1993,19 @@ void homekit_server_on_pair_verify(client_context_t *context, const byte *data, case 1: { CLIENT_INFO(context, "Pair Verify Step 1/2"); + int committed=0; + client_context_t *c = server->clients; + while (c) { + if (c->encrypteddisconnect) committed++; + c = c->next; + } + if (xPortGetFreeHeapSize()disconnect = true; + break; + } + CLIENT_DEBUG(context, "Importing device Curve25519 public key"); tlv_t *tlv_device_public_key = tlv_get_value(message, TLVType_PublicKey); if (!tlv_device_public_key) { @@ -2503,7 +2540,7 @@ void homekit_server_on_pair_verify(client_context_t *context, const byte *data, context->pairing_id = pairing_id; context->permissions = permissions; - context->encrypted = true; + context->encrypted = ENCRYPTION_STATE_VERIFIED; HOMEKIT_NOTIFY_EVENT(context->server, HOMEKIT_EVENT_CLIENT_VERIFIED); @@ -2615,12 +2652,16 @@ void homekit_server_on_get_accessories(client_context_t *context) { json_flush(json); client_send_chunk(NULL, 0, context); + + context->encrypted = ENCRYPTION_STATE_GOT_ACCESSORIES; } void homekit_server_on_get_characteristics(client_context_t *context) { CLIENT_INFO(context, "Get Characteristics"); DEBUG_HEAP(); + context->encrypted = ENCRYPTION_STATE_IN_USE; + if (context->server->endpoint_params.ids[0].aid == 0) { CLIENT_ERROR(context, "Invalid get characteristics request: missing ID parameter"); send_json_error_response(context, 400, HAPStatus_InvalidValue); @@ -2719,6 +2760,8 @@ void homekit_server_on_update_characteristics(client_context_t *context, const b CLIENT_INFO(context, "Update Characteristics"); DEBUG_HEAP(); + context->encrypted = ENCRYPTION_STATE_IN_USE; + cJSON *json = cJSON_Parse((char *)data); if (!json) { @@ -3159,6 +3202,8 @@ void homekit_server_on_pairings(client_context_t *context, const byte *data, siz DEBUG("HomeKit Pairings"); DEBUG_HEAP(); + context->encrypted = ENCRYPTION_STATE_IN_USE; + tlv_values_t *message = tlv_new(); if (!message) { CLIENT_ERROR(context, "Failed to allocate memory for TLV payload"); @@ -3426,6 +3471,8 @@ void homekit_server_on_resource(client_context_t *context) { CLIENT_INFO(context, "Resource"); DEBUG_HEAP(); + context->encrypted = ENCRYPTION_STATE_IN_USE; + if (!context->server->config->on_resource) { send_404_response(context); return; @@ -3759,6 +3806,21 @@ void homekit_server_close_client(homekit_server_t *server, client_context_t *con } +void homekit_server_close_duplicate_clients(homekit_server_t *server, struct sockaddr_in addr) { + struct sockaddr_in old_addr; + socklen_t addr_len = sizeof(addr); + client_context_t *context = server->clients; + + while (context) { + if ( getpeername(context->socket, (struct sockaddr *)&old_addr, &addr_len) == 0 && + (old_addr.sin_addr.s_addr == addr.sin_addr.s_addr) && + (old_addr.sin_port != addr.sin_port) ) + context->disconnect = true; + context = context->next; + } + } + + client_context_t *homekit_server_accept_client(homekit_server_t *server) { int s = accept(server->listen_fd, (struct sockaddr *)NULL, (socklen_t *)NULL); if (s < 0) { @@ -3831,6 +3893,8 @@ client_context_t *homekit_server_accept_client(homekit_server_t *server) { } else { strcpy(address_buffer, "?.?.?.?"); } + + homekit_server_close_duplicate_clients(server, addr); //remove old connections with same ip but different port CLIENT_INFO(context, "Got new client connection from %s", address_buffer);