PING problem with WIP plug-in (Q2686)

Hi,

I have a Q2686H working on Open At OS v4.21.01; firmware version 663.

I have implemented a timer that sends a PING packet via GPRS each 2 minutes (with WIP plug in v3.00.09).
It works fine 5 or 6 iterations, but after it, starts to fail. Returns WIP_CEV_ERROR, but without any error describing what happened(ev->content.error.errnum is 0).
Does anybody have problems with PING? Is it working fine (stable) with WIP?

Thank you in advance.

Alejandro

Have you set up wip traces? (cf. WIP_NET_OPT_DEBUG_PORT in wip_netInitOpts(), or simply look at samples’ default settings in appli.c)? What do these traces say?

Hi fft,

Thanks for your reply.

I hadn’t set up WIP traces. I did it, and the result is: ERRLOG ch_ping.c:191: Can’t allocate buffer for PING send

Now, my question is: Can I resolve it with PING options or with wip_netInitOpts()? I don’t change default buffer value, and I am sending 4 pings each time:
ping_channel = wip_pingCreateOpts (gServerConf.server_ip, gprsPingHandler, NULL, WIP_COPT_REPEAT, 4, WIP_COPT_END);

Alejandro.

it seems to mean that ping can’t allocate an internal buffer to emit the ping packet. Presumably, all of them are full.

  • have you set the buffer dimensions to unusually tiny sizes in the netInitOpts()?
  • are there some other, network-hungry activities going on in your application?
  • are the ping packets detected on the pinged machine?
  • do you receive ping response events on the event handler?
  • do you see any other wip trace that sounds like an error?

Hello,

I stumpled into the same problem the other day…

It turned out that I had the WIP_NET_OPT_BUF_MAX set to 8 and when I tried to PING to an IP that did not reply (timeout), I got the same error as you got. Directly after 7 pings were sent out and when the application tried with the 8th the application crashed.
(ERRLOG ch_ping.c:191: Can’t allocate buffer for PING send)

When successful replys come back from PING, its not any buffer limitations.

It looks like the unit does not release previously used buffers.
Maybe it takes some time but how long time I do not know.
Maybe someone else know?

/R

It seems like there’s somethings very wrong on how the WIP plugin is handling the timeout replyes when doing a ICMP request.

It looks like they are stacked internally and the resources (memory etc.) are not given back to the system.

Even if I put 128 as BUF size, I still get the problem when all PINGs are timedout.

If PINGs are replyed within the time limit, then everything seems to be OK.

Anyone with a clue or have seen something similar?

/H

There seems to be a resource leak on expired ping responses indeed, it’s under investigation internally.

OK, thats always good to know… that someone is investigating it. Hopefully there’ll be a fixed version soon… :confused:

next question… whats the workaround?

reboot system after a critical amount of no_reply PINGs?

I’d guess:

  • Set a ridiculously long timeout, and handle timeouts by yourself
  • Set WIP_COPT_REPEAT and the amount of sent data to 1
  • If it’s not enough, use an UDP packet and a dumb echo server on the poked machine, to check its liveliness without using ping.

On unix and windows, netcat will let you write a dumb UDP server which will send an echo back to any UDP port that sends something to it. On an embedded POSIX device, you’ll need a loop with a recvfrom() and a sendto().

Thanks for the tip but thats not going to do it for my application.

How do you mean that a ridiculous long timeout could help… I still need to send multiple ICMP requests in ~every 10 sec or so.
And by extending the timeout there’s no way to handle it better when the next request must be sent out… the allocated resources are still locked and I can hardly free them by force… or can I?

Unfortunately, I need to be a bit more generic than what you suggested. So I guess I’ll just have to wait… or implement a workaround that reboot the unit after a critical number of “no replies”…

thanks anyway…

It will only save you against nodes that takes very long to answer, not against those which don’t answer at all I’m afraid.

Anyone knows if this resourse allocation leak discussed above still is unsolved?

/H

Hi all,

i’m receiving these result when i tried to ping some website.
could somebody explain me about these result? because i think there is something weird with the time. because the time is 0ms which is impossible.

[WIPEV] WIP_CEV_PING @ PING 0x180c69b8 (seq=0, time=0ms, timeout=true)

this is inside the PingHandler
[WIPEV] WIP_CEV_PING @ PING 0x180c69b8 (seq=1, time=0ms, timeout=true)

this is inside the PingHandler
[WIPEV] WIP_CEV_PING @ PING 0x180c69b8 (seq=2, time=1000ms, timeout=false)

this is inside the PingHandler
[WIPEV] WIP_CEV_PING @ PING 0x180c69b8 (seq=3, time=1000ms, timeout=false)

this is inside the PingHandler
[WIPEV] WIP_CEV_PEER_CLOSE @ PING 0x180c69b8

i compare it with the ping in MsDOS. the ping result will about 128ms average for each probe sent.
could someone give me clue here… thank you very much…

regards,
Edy2

哈哈

Hi,
I using newest firmware and WIP plugin and problem continuously existing. I use wip_pingCreateOpts function and when ping response not return, probably channel resources doesn’t free correctly. Next using wip_CreateOpts function result in reeboot system. Sometimes I receive TRACE: ARM memory error. When ping response is correct, application working OK.

Anybody can help ?

I encountered a similar problem when using wip-soft.
i could use the command wipping to ping a website, but after issuing about 15 single pings, it returns error.

Maybe We must notice Wavecoms support about this problem.
This problem go on very long. This is a bit irritating.

i think ping channel must be closed properly before creating the new one or just after getting a response. when you close the channel with wip_close(ev->channel); then the buffers allocated for that channel may be freed. The issue is when to close the channel. If you wait for a response to close the current channel but not getting any response, then you may miss closing the channel. So i think it is better to create ping channels with a timer and check the ping timeout on your own. Whenever timeout occurs or a response received, then you should close the channel to release the internal buffers.

I tried the zafer’s idea (previous post) and I’m havin the following problem. When module tries to send the second ping, the module restarts. (It sends the first one, recieves timeout, initiates wip_close() (with r=0), creates a new ping channel (with the same id as the old one) and restarts).
I’m creating pings every minute.

My code…

char pingok;
wip_channel_t ping;

void appli_entry_point()
{
	adl_tmrSubscribe ( TRUE, 600, ADL_TMR_TYPE_100MS, TimerHandlerPing );
}

void TimerHandlerPing ( u8 ID, void * Context )
{
	pingok=0;
	ping=wip_pingCreateOpts (PEER_STRADDR, PingHandler, NULL, WIP_COPT_RCV_TIMEOUT, 100000, WIP_COPT_NWRITE, 32, WIP_COPT_END);
	adl_tmrSubscribe ( FALSE, 100, ADL_TMR_TYPE_100MS, TimerHandlerPingTimeout );
}

wip_eventHandler_f PingHandler (wip_event_t *ev, void *ctx)
{
	switch(ev->kind)
	{
		case WIP_CEV_PING:
			wip_debug("[PING] Server available.\n");
			pingok=1;
			wip_close(ping);
			break;
		case WIP_CEV_ERROR:
			wip_debug("[PING] Error\n");
			break;
	}
}
void TimerHandlerPingTimeout ( u8 ID, void * Context )
{
	if(!pingok)
	{
		int r;
		wip_debug("[PING] Timeout(10s)!\n");
		r=wip_close(ping);
		wip_debug("[PING] Ping shutdown, r=%i.\n",r);
	}
}

Thank you for your help.

Hi Roko,
i think the problem is trying to close ping handle. You should close the ping channel not the handle itself. I mean you should apply wip_close(ev->event); like this.
here is the code i use. It may work for you.

wip_channel_t pingChannel;
bool pingTimeOutFlag=FALSE;
wip_event_t * pingEvent=(wip_event_t *)NULL;
adl_tmr_t * tmrHandlerPing = (adl_tmr_t *)NULL;

void tmrStartPingWithTime(int Seconds);

void ClosePingChannel()
{
	if(pingEvent!=(wip_event_t *)NULL)
	{
		wip_close(pingEvent->channel);
		pingEvent=(wip_event_t *)NULL;
	}
}


static void CheckPingTimeOut(u8 tmrID)
{
    if(pingTimeOutFlag==TRUE)
	{
		WriteLog2("ping","0","PING PingTimeOut ",TRUE);
		ClosePingChannel();
	}
}

void EventHandler_PingChannel(wip_event_t *ev, void *ctx)
{
	pingTimeOutFlag=FALSE;
	pingEvent=ev;
	switch (ev->kind)
	{

		case WIP_CEV_OPEN:
			WriteLog2("ping","0","PING WIP_CEV_OPEN",TRUE);
			// timeout kontrolu yap 4 saniye sonra
			pingTimeOutFlag=TRUE;
			adl_tmrSubscribe(FALSE, 40, ADL_TMR_TYPE_100MS, CheckPingTimeOut);	
			break;

		case WIP_CEV_PING:
			if(ev->content.ping.timeout==TRUE)
			{
				WriteLog2("ping","0","PING TIMEOUT ",TRUE);
				pingTimeOutFlag=TRUE;
			}
			else
				WriteLog2("ping","0","PING OK",TRUE);
			break;

		case WIP_CEV_ERROR:
			WriteLog2("ping","0","PING ERROR",TRUE);
			ClosePingChannel();
			break;		

		case WIP_CEV_DONE:
			WriteLog2("ping","0","PING WIP_CEV_DONE",TRUE);
			break;		

		case WIP_CEV_PEER_CLOSE:
			WriteLog2("ping","0","PING WIP_CEV_PEER_CLOSE",TRUE);
			ClosePingChannel();
			break;

		default:
			WriteLog2("ping","0","PING DEFAULT",TRUE);
			break;
	}
}

void StartPing()
{
	if(GetGPRSok()==FALSE)
		return;

    pingChannel = wip_pingCreateOpts("www.google.com", EventHandler_PingChannel, NULL, WIP_COPT_REPEAT, 1 , WIP_COPT_END);
    
	if (pingChannel == (wip_channel_t)NULL)
	{
		WriteLog2("ping","0","PING CHANNEL FAILED",TRUE);
		return;
	}
}