Skip to content

Commit

Permalink
bugfix test version
Browse files Browse the repository at this point in the history
For "Decryption error/Connection lost on ESP32 with multiple Apple devices running Home"
, espressif/esp-homekit-sdk#14
  • Loading branch information
Mixiaoxiao committed Dec 23, 2020
1 parent 41804ca commit 2557861
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 6 deletions.
46 changes: 46 additions & 0 deletions src/esp_hap_ip_services.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,55 @@ static int hap_http_pair_verify_handler(httpd_req_t *req)
sizeof(timeout)) < 0) {
ESP_MFI_DEBUG(ESP_MFI_DEBUG_ERR, "setsockopt on pair verified socket failed for SO_SNDTIMEO");
}


// ----
const int s = fd;
const int yes = 1; /* enable sending keepalive probes for socket */
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes));

const int idle = 15; /* 180 sec idle before start sending probes */
setsockopt(s, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle));

const int interval = 5; /* 30 sec between probes */
setsockopt(s, IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(interval));

const int maxpkt = 3; /* Drop connection after 4 probes without response */
setsockopt(s, IPPROTO_TCP, TCP_KEEPCNT, &maxpkt, sizeof(maxpkt));
// ----

hap_platform_httpd_set_sess_ctx(req, ctx, hap_free_session, true);
httpd_sess_set_send_override(hap_priv.server, fd, hap_httpd_send);
httpd_sess_set_recv_override(hap_priv.server, fd, hap_httpd_recv);


hap_secure_session_t* session = (hap_secure_session_t *)ctx;
int socket = session->conn_identifier;

//struct sockaddr_storage addr;
struct sockaddr_in6 addr;
socklen_t len = sizeof addr;
getpeername(fd, (struct sockaddr*)&addr, &len);
/*
struct sockaddr_in *sockaddr = (struct sockaddr_in *)&addr;
in_addr_t a = sockaddr->sin_addr.s_addr;
union {
uint8_t ui8[4];
uint32_t ui32;
}ip;
ip.ui32 = (uint32_t)a;
*/
//uint16_t port = ntohs(sockaddr->sin6_port);
uint16_t port = addr.sin6_port;
printf("---- STATE_VERIFIED ----\n");
//printf("ip32: %u\n", a);
//printf("fd: %d, %u.%u.%u.%u:%u \n", socket,
//ip.ui8[0], ip.ui8[1], ip.ui8[2], ip.ui8[3], port);
//https://github.com/espressif/esp-idf/issues/4863
printf("fd: %d, remote: %s:%u\n", fd, inet_ntoa(addr.sin6_addr.un.u32_addr[3]), port);
printf("ctrl: %s\n", session->ctrl->info.id);

printf("------------------------\n");
}
}
return ret1;
Expand Down
44 changes: 41 additions & 3 deletions src/esp_hap_network_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,35 @@ int hap_encrypt_data(hap_encrypt_frame_t *frame, hap_secure_session_t *session,
return 2 + buflen + 16; /* Total length of the encrypted data */
}

#include <esp_hap_main.h>
void hap_close_ctrl_sessions_fix(hap_secure_session_t *session)
{
if (!session)
return;
int i;
printf("---- hap_close_ctrl_sessions_fix begin -----\n");
for (i = 0; i < HAP_MAX_SESSIONS; i++) {
if (!hap_priv.sessions[i])
continue;
if (hap_priv.sessions[i] == session) {
hap_report_event(HAP_EVENT_CTRL_DISCONNECTED, (session->ctrl->info.id),
sizeof((session->ctrl->info.id)));
/* TODO: Use some generic function and not a direct HTTPD function
*/
printf("---- trigger_close fd: %d\n", hap_priv.sessions[i]->conn_identifier);
httpd_sess_trigger_close(hap_priv.server, hap_priv.sessions[i]->conn_identifier);
}
}
printf("---- hap_close_ctrl_sessions_fix end ----\n");
}

int hap_decrypt_error(hap_secure_session_t *session)
{
ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "Decryption error/Connection lost. Marking session as invalid");
if (session) {
session->state = STATE_INVALID;
hap_close_ctrl_sessions(session->ctrl);
//hap_close_ctrl_sessions(session->ctrl);
hap_close_ctrl_sessions_fix(session);
}
return HAP_FAIL;
}
Expand All @@ -115,17 +138,31 @@ int hap_decrypt_data(hap_decrypt_frame_t *frame, hap_secure_session_t *session,
frame->session = session;
}
if ((frame->pkt_size - frame->bytes_read) == 0) {
if (read_fn(frame->data, 2, context) < 2)
int len = read_fn(frame->data, 2, context);
if (len == 0) { //nothing received, but we should NOT consider this is a 'decrypt_error'
return 0;
}
if (len < 2) {
//len is -1 or 1
//len = -1: socket disconnected
//len = 1: try receiving 2 bytes timeout (SO_RCVTIMEO is set in esp_hap_ip_services.c)
printf("---- error 1 ----, len: %d\n", len);
//Decryption error/Connection lost on ESP32 with multiple Apple devices running Home
//https://github.com/espressif/esp-homekit-sdk/issues/14
//---- error 1 ----, len: 0
return hap_decrypt_error(session);
}

frame->pkt_size = get_u16_le(frame->data);
frame->bytes_read = 0;
uint16_t bytes_to_read = frame->pkt_size + AUTH_TAG_LEN; /* +AUTH_TAG_LEN as the receivedd packet will also have the auth Tag */
while (bytes_to_read) {
int num_bytes = read_fn(&frame->data[frame->bytes_read],
bytes_to_read, context);
if (num_bytes <= 0)
if (num_bytes <= 0) {
printf("---- error 2 ----\n");
return hap_decrypt_error(session);
}
bytes_to_read -= num_bytes;
frame->bytes_read += num_bytes;
}
Expand All @@ -140,6 +177,7 @@ int hap_decrypt_data(hap_decrypt_frame_t *frame, hap_secure_session_t *session,
&frame->data[frame->bytes_read], aad, 2, newnonce, session->decrypt_key);
if (ret != 0) {
ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "AEAD decryption failure");
printf("---- error 3 ----\n");
return hap_decrypt_error(session);
}
frame->bytes_read = 0;
Expand Down
11 changes: 9 additions & 2 deletions src/esp_hap_pair_verify.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ void hap_close_ctrl_sessions(hap_ctrl_data_t *ctrl)
if (!ctrl)
return;
int i;
printf("---- hap_close_ctrl_sessions begin -----\n");
for (i = 0; i < HAP_MAX_SESSIONS; i++) {
if (!hap_priv.sessions[i])
continue;
Expand All @@ -74,9 +75,12 @@ void hap_close_ctrl_sessions(hap_ctrl_data_t *ctrl)
sizeof((ctrl->info.id)));
/* TODO: Use some generic function and not a direct HTTPD function
*/
printf("---- trigger_close fd: %d\n", hap_priv.sessions[i]->conn_identifier);
httpd_sess_trigger_close(hap_priv.server, hap_priv.sessions[i]->conn_identifier);
break;
}
}
printf("----hap_close_ctrl_sessions end ----\n");
}

int hap_get_ctrl_session_index(hap_secure_session_t *session)
Expand Down Expand Up @@ -116,7 +120,8 @@ static void hap_add_secure_session(hap_secure_session_t *session)
* state.
*/
hap_priv.disconnected_event_sent = false;
ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "HomeKit Session active");
//ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "HomeKit Session active");
ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "HomeKit Session active, fd: %d", session->conn_identifier);
break;
}
}
Expand All @@ -130,9 +135,11 @@ void hap_free_session(void *session)
for (i = 0; i < HAP_MAX_SESSIONS; i++) {
if (hap_priv.sessions[i] == session) {
/* Disable all characteristic notifications on this session */
int fd = (hap_priv.sessions[i])->conn_identifier;
hap_disable_all_char_notif(i);
hap_priv.sessions[i] = NULL;
ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "HomeKit Session terminated");
//ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "HomeKit Session terminated");
ESP_MFI_DEBUG(ESP_MFI_DEBUG_INFO, "HomeKit Session terminated, fd: %d", fd);
break;
}
}
Expand Down
11 changes: 10 additions & 1 deletion src/esp_mfi_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ uint32_t esp_mfi_get_debug_level(uint32_t level, uint32_t *color);
__color_LINE, ##__VA_ARGS__); \
} \
}
*/
#define ESP_MFI_DEBUG(l, fmt, ...) \
{ \
uint32_t __color_LINE; \
Expand All @@ -122,6 +122,15 @@ uint32_t esp_mfi_get_debug_level(uint32_t level, uint32_t *color);
if (l > esp_mfi_get_debug_level(l, &__color_LINE)) { \
printf("[%7lu] " fmt "\n", ((unsigned long) (esp_timer_get_time() / 1000ULL)), ##__VA_ARGS__); \
} \
}*/

#define ESP_MFI_DEBUG(l, fmt, ...) \
{ \
printf("[%7lu] " fmt "\n", ((unsigned long) (esp_timer_get_time() / 1000ULL)), ##__VA_ARGS__); \
}
#define ESP_MFI_DEBUG_INTR(l, fmt, ...) \
{ \
printf("[%7lu] " fmt "\n", ((unsigned long) (esp_timer_get_time() / 1000ULL)), ##__VA_ARGS__); \
}
#else /* ESP_MFI_DEBUG_ENABLE */
#define ESP_MFI_DEBUG(l, fmt, ...)
Expand Down

0 comments on commit 2557861

Please sign in to comment.