Stopping Websocket Update when Ethernet disconnects

Discussion to talk about software related topics only.
Post Reply
Jcz
Posts: 7
Joined: Wed Mar 03, 2021 7:04 am

Stopping Websocket Update when Ethernet disconnects

Post by Jcz »

So I'm unfortunately still stuck on this problem but I think I've narrowed it down. Here's the code for my websocket update task and the function that handles starting and stopping DHCP:

Code: Select all

void ToggleDHCP(bool enable)
{
	int interface = GetFirstInterface();
	InterfaceBlock *dhcpIntf = GetInterFaceBlock(interface);
	DhcpObject *dhcpObj = dhcpIntf->dhcpClient;

	if(dhcpObj == NULL)
	{
		iprintf("Create a dhcp object since one doesn't exist\n");
		dhcpObj = new DhcpObject(interface);
	}

	if(enable)
	{
		iprintf("enabling DHCP\n");
		dhcpObj->StartDHCP();
		AssignedDHCP = true;
		iprintf("dhcpstate: %d\n", dhcpObj->GetDHCPState());
	}
	else
	{
		iprintf("disabling DHCP\n");
		dhcpObj->StopDHCP();
		AssignedDHCP = false;
		iprintf("dhcpstate: %d\n", dhcpObj->GetDHCPState());
	}

	if ( OSSemPend( &( dhcpObj->NotifySem ), 10 * TICKS_PER_SECOND ) == OS_TIMEOUT ) //Wait 10 seconds
	{
	  iprintf("\r\n\r\n*** WARNING ***\r\n");
	  iprintf("IP Address was set to 0.0.0.0, and a DHCP server could not be found.\r\n");
	  iprintf("Device does not have a valid IP address.\r\n\r\n");
	}
	else
	{
		ShowDhcpSettings(interface);
	}
}

void WSTask(void *pd)
{
	InterfaceBlock *dhcpIntf = GetInterFaceBlock(GetFirstInterface());
	DhcpObject *dhcpObj = dhcpIntf->dhcpClient;
	while(1)
	{
		OSTimeDly(6);
	// Send data up to the web interface via the websockets
		for(int i = 0; i < WS_MAX_SOCKS; i++)
		{
			if(EtherLink())
			{
				if(!AssignedDHCP)
				{
	//				iprintf("Ethernet connected and no DHCP assigned\n");
					iprintf("Start DHCP\n");
					ToggleDHCP(true);
				}
				else if(AssignedDHCP)
				{
					if(ws_fd[i] > 0)  // We only need to update the websocket if the website is loaded
					{
	//						iprintf("Update the Websocket\n");
						/* This is the websocket update function */
						if(dhcpObj->GetDHCPState() == SDHCP_CMPL && dhcpObj->GetDHCPState() != SDHCP_NOTSTARTED)
						{
							// check ethernet connection again
							if(EtherLink()) SendConfigReport(ws_fd[i]);
							iprintf("SendConfigReport\n");
						}
					}
				}
			}
			else
			{
				if(AssignedDHCP)
				{
					iprintf("Ethernet disconnected and DHCP is assigned\n");
					iprintf("stop dhcp\n");
					ToggleDHCP(false);
				}
			}
		}
	}
}
The issue I'm having is that I'm getting a Debug Interrupt(12) trap about 5 minutes after when the websocket was loaded and then the ethernet cable unplugged. I don't get this trap when I comment out the SendConfigReport() function, which is pretty much exactly what's in the websocket example. So I assume the buffer being over ran (if that is in fact what the trap is pointing towards) is located there. However I've monitored the buffers in that function and didn't notice anything out of the ordinary until SendConfigReport() stops being called since EtherLink() went false and/or DHCP was unassigned.
If I reconnect the ethernet before the trap happens DHCP reconnects and everything continues operating correctly.
User avatar
pbreed
Posts: 1080
Joined: Thu Apr 24, 2008 3:58 pm

Re: Stopping Websocket Update when Ethernet disconnects

Post by pbreed »

Module type and NNDK revision ie 2.9.x or 3.x.x.
would be helpful...
given that we can provide some hints on tracking this down...
Jcz
Posts: 7
Joined: Wed Mar 03, 2021 7:04 am

Re: Stopping Websocket Update when Ethernet disconnects

Post by Jcz »

I'm using a MOD54415 and we're on NNDK ver 2.7.1
I've since narrowed it down to the writeall() function sending the data as what is crashing the system, using NB::Websocket::ws_write also yields the same result.
I've tried re-working how data is sent to the web client, so now the webclient requests data to be sent to it then the firmware sends the data. I've also tried sending just a string in case for some reason the JSON object builder functions that I was using to send the data were causing an issue. I'm also monitoring GetFreeCount() and we don't appear to be running out of buffers when the system traps.

This is now what I'm doing when sending data to the client

Code: Select all

char string[] = "test";
iprintf("send this through the websocket: %s\n", string);
int dataLen = strlen(string);
iprintf("dataLen = %d\n", dataLen);

int check = NB::WebSocket::ws_write(ws_fd, string, dataLen);
iprintf("check: %d\n", check);
And this is what calls that code

Code: Select all

if (FD_ISSET(ws_fd[i], &read_fds))
{
	iprintf("Read FDs\n");
	NB::WebSocket::ws_read(ws_fd[i], IncomingBuffer, INCOMING_BUF_SIZE);
	printf("Incoming buffer: %s\n", IncomingBuffer);

	if(!strcmp(IncomingBuffer, "WS data request"))
	{
		iprintf("update ws\n");
		SendConfigReport(ws_fd[i]); // Send data to the web client
	}
}
Last edited by Jcz on Fri Nov 19, 2021 9:56 am, edited 1 time in total.
Jcz
Posts: 7
Joined: Wed Mar 03, 2021 7:04 am

Re: Stopping Websocket Update when Ethernet disconnects

Post by Jcz »

I ended up removing the code that access the InterfaceBlock to turn DHCP on/off and went back to my GetDHCPAddress() call. This resulted in the system not crashing. But once I went back to compiling the data as a JSON object instead of my test string the crash happened again.
Maybe I'll just be reworking how I compile the data.

I started compiling the data to be sent over with sprintf, just adding four floats to the string each of which has the precision set to 4 decimal points and wouldn't be larger than 5000, But with this I get the trap again. Tested with hardcoding longer strings, this causes the same trap to happen. strlen reports a size of 24 and 82 for my sprintf string and the hardcoded string respectively. I never saw a crash when just sending "test" being a length of 4.
Post Reply