Add timeout to Philips Wiz packet receive so that it doesn't hang on rescan

This commit is contained in:
Adam Honse 2023-05-08 00:03:07 -05:00
parent 5a0d0d65aa
commit 87aadafa4d
3 changed files with 68 additions and 37 deletions

View file

@ -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);
}
}

View file

@ -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)));

View file

@ -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