From 87aadafa4d8ee0ea87824b144ce6854d8c59c648 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Mon, 8 May 2023 00:03:07 -0500 Subject: [PATCH] Add timeout to Philips Wiz packet receive so that it doesn't hang on rescan --- .../PhilipsWizController.cpp | 85 +++++++++++-------- net_port/net_port.cpp | 19 +++++ net_port/net_port.h | 1 + 3 files changed, 68 insertions(+), 37 deletions(-) diff --git a/Controllers/PhilipsWizController/PhilipsWizController.cpp b/Controllers/PhilipsWizController/PhilipsWizController.cpp index caad811a..59871d54 100644 --- a/Controllers/PhilipsWizController/PhilipsWizController.cpp +++ b/Controllers/PhilipsWizController/PhilipsWizController.cpp @@ -152,49 +152,52 @@ void PhilipsWizController::ReceiveThreadFunction() while(ReceiveThreadRun.load()) { /*-----------------------------------------------------------------*\ - | Receive up to 1024 bytes from the device | + | Receive up to 1024 bytes from the device with a 1s timeout | \*-----------------------------------------------------------------*/ - int size = port.udp_listen(recv_buf, 1024); + int size = port.udp_listen_timeout(recv_buf, 1024, 1, 0); - /*-----------------------------------------------------------------*\ - | Responses are not null-terminated, so add termination | - \*-----------------------------------------------------------------*/ - recv_buf[size] = '\0'; - - /*-----------------------------------------------------------------*\ - | Convert null-terminated response to JSON | - \*-----------------------------------------------------------------*/ - json response = json::parse(recv_buf); - - /*-----------------------------------------------------------------*\ - | Check if the response contains the method name | - \*-----------------------------------------------------------------*/ - if(response.contains("method")) + if(size > 0) { - /*-------------------------------------------------------------*\ - | Handle responses for getSystemConfig method | - | This method's response should contain a result object | - | containing fwVersion, moduleName, and mac, among others. | - \*-------------------------------------------------------------*/ - if(response["method"] == "getSystemConfig") + /*-----------------------------------------------------------------*\ + | Responses are not null-terminated, so add termination | + \*-----------------------------------------------------------------*/ + recv_buf[size] = '\0'; + + /*-----------------------------------------------------------------*\ + | Convert null-terminated response to JSON | + \*-----------------------------------------------------------------*/ + json response = json::parse(recv_buf); + + /*-----------------------------------------------------------------*\ + | Check if the response contains the method name | + \*-----------------------------------------------------------------*/ + if(response.contains("method")) { - if(response.contains("result")) + /*-------------------------------------------------------------*\ + | Handle responses for getSystemConfig method | + | This method's response should contain a result object | + | containing fwVersion, moduleName, and mac, among others. | + \*-------------------------------------------------------------*/ + if(response["method"] == "getSystemConfig") { - json result = response["result"]; - - if(result.contains("fwVersion")) + if(response.contains("result")) { - firmware_version = result["fwVersion"]; - } + json result = response["result"]; - if(result.contains("moduleName")) - { - module_name = result["moduleName"]; - } + if(result.contains("fwVersion")) + { + firmware_version = result["fwVersion"]; + } - if(result.contains("mac")) - { - module_mac = result["mac"]; + if(result.contains("moduleName")) + { + module_name = result["moduleName"]; + } + + if(result.contains("mac")) + { + module_mac = result["mac"]; + } } } } @@ -219,7 +222,15 @@ void PhilipsWizController::RequestSystemConfig() port.udp_write((char *)command_str.c_str(), command_str.length() + 1); /*-----------------------------------------------------------------*\ - | Sleep for 100ms to give it time to receive and process response | + | Wait up to 1s to give it time to receive and process response | \*-----------------------------------------------------------------*/ - std::this_thread::sleep_for(100ms); + for(unsigned int wait_count = 0; wait_count < 100; wait_count++) + { + if(firmware_version != "") + { + return; + } + + std::this_thread::sleep_for(10ms); + } } diff --git a/net_port/net_port.cpp b/net_port/net_port.cpp index 6a2912a5..8d0913a0 100644 --- a/net_port/net_port.cpp +++ b/net_port/net_port.cpp @@ -94,6 +94,25 @@ int net_port::udp_listen(char * recv_data, int length) return(recvfrom(sock, recv_data, length, 0, NULL, NULL)); } +int net_port::udp_listen_timeout(char * recv_data, int length, int sec, int usec) +{ + fd_set fds; + struct timeval tv; + + FD_ZERO(&fds); + FD_SET(sock, &fds); + + tv.tv_sec = sec; + tv.tv_usec = usec; + + if(select(sock, &fds, NULL, NULL, &tv) <= 0) + { + return(0); + } + + return(recvfrom(sock, recv_data, length, 0, NULL, NULL)); +} + int net_port::udp_write(char * buffer, int length) { return(sendto(sock, buffer, length, 0, (sockaddr *)&addrDest, sizeof(addrDest))); diff --git a/net_port/net_port.h b/net_port/net_port.h index 2ffc0dff..d97f1a8b 100644 --- a/net_port/net_port.h +++ b/net_port/net_port.h @@ -65,6 +65,7 @@ public: SOCKET * tcp_server_listen(); int udp_listen(char * recv_data, int length); + int udp_listen_timeout(char * recv_data, int length, int sec, int usec); int tcp_listen(char * recv_data, int length); //Function to write data to the serial port