WIP HTTP POST problems


#1

hi
I’m trying to make a system to send data to our website. It mostly works but isn’t very reliable. The system is running on a Fastrax Supreme 10 modem at the moment, running inside the modem.

It has a few tasks doing various tasks -

  • the main task initialises the WIP stack
  • one task manages the comunications on UART2
  • one task processes the messages on UART2 (ie manages the comms protocol)
  • one task looks after sending data over the GPRS link

It all goes well for a while - I can make somewhere between 5 & 50 HTTP POST requests before it stops working. So far I can’t work out how to recover.

For each request I do the following (simplified)

  • create a HTTP Session Channel
  • create a HTTP Data channel
  • Wait for WIP_CEV_OPEN event (which I ignore)
  • Wait for WIP_CEV_WRITE event
  • send the POST data
  • if I get any WIP_CEV_READ events I read all the data
  • Wait for WIP_CEV_PEER_CLOSE event
  • Close the session channel
  • close the data channel
  • wait for the next message to arrive

When it fails I never get the WIP_CEV_OPEN or WIP_CEV_WRITE events. My code times out after 20 seconds but I’m not sure how to recover.

I’m using M2M Studio 1.02, my modem has firmwar R74_00gg.FSU0004 and my application OS is 6.30.


#2

My suggestion is to use a timer to make sure the WIP_CEV_PEER_CLOSE event is received, and if it is not received after 10seconds or so manually close it. If the connection to the server is never closed you would not be able to re-open it.

While connected to the server if any events are not received your process will fail, so to make the system robust use timers to make sure that events are received. If they aren’t, close the connection and re-open and retry.

Hope it helps


#3

Hello Peter,

Please, would you mind sending me a piece of code showing how you are sending data via HTTP POST to the server? I’m trying to use wip_write but it’s adding 2 additional bytes in the payload as the buffer size on the payload. See bellow and note the 5f (95 decimal) at the beginning the the content.

POST /HelloWMP/HelloServlet HTTP/1.1
Host: myserver.com.br:8088
Transfer-Encoding: chunked
User-Agent: WIPHTTP/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 95

5f
p1=This is a big message that I want to send using the wip_write command via POST http method!

Regards

Rafael


#4

It is working perfectly correctly & normally - that’s what “chunked” encoding means! 8)


#5

Hi,
I need to send data to web server using HTTP Post method. I tried the code given in these forums. I was able to send data through HTTP post method only once. For second time I am getting HTTP 400 Error Response. I have to restart my Wavecom Modem in-order to send data again. Please suggest me any solution regarding this issue. In this post its said to close channels manully, but while doing so it says I am trying to close channel which is null. My code is as follows:

#include	"wip.h"

#define RECBUFF 	400


/////////External Function Declarations
extern void InboundData(char *Data);
/////////Local Function Declarations
s32 http_Client(void);
void KillHTTP(void);

////////External Variable Declarations
extern char *Data_PCKT;
////////Local Variable Declarations
static u8 rcv_buffer [RECBUFF];
const ascii * HTTP_STR_URL = "http://lightmatrix.net/TEST/DEFAULT.ASPX";
int BytesWritten, code;
s32 status;
ascii info[50];
ascii *tmpbuf;
static int offset = 0;



typedef struct
{
	wip_channel_t CnxChannel; // session channel
	wip_channel_t DataChannel; // data channel
	u32 dataLength; // response data length

}http_ClientTestCtx_t;

http_ClientTestCtx_t http_ClientTestCtx;






void KillHTTP(void)
{
	int i = 0;
	wip_debug("\r\nKilling HTTP Handler...\r\n");
	if (http_ClientTestCtx.CnxChannel != NULL)
		http_ClientTestCtx.CnxChannel  = NULL;
	if (http_ClientTestCtx.DataChannel != NULL)
		http_ClientTestCtx.DataChannel = NULL;

	for(i=0;i<RECBUFF;i++)
	{
		rcv_buffer[i] = 0;
	}
	for(i=0;i<50;i++)
	{
		info[i] = 0;
	}
	wip_debug("\r\nHTTP Handler killed...\r\n");
}



static void http_ClientTestDataHandler( wip_event_t *ev, void *ctx)
{


	//s16 m,n,p,w;
	int tmp = 0;
		http_ClientTestCtx_t *pHttpClientCtx = (http_ClientTestCtx_t *) &http_ClientTestCtx;
	switch(ev->kind)
	{
		case WIP_CEV_OPEN:						wip_debug("\r\nhttp_ClientTestDataHandler: Start\r\n");

												break;

		case WIP_CEV_READ:						wip_debug("\r\nhttp_ClientTestDataHandler: WIP_CEV_READ\r\n");
												wip_getOpts(http_ClientTestCtx.DataChannel, WIP_COPT_HTTP_STATUS_CODE, &code, WIP_COPT_END);
												wm_sprintf( info, "\r\nHTTP Status code: %d\r\n", code);
												wip_debug(info);
												if (code == 200)
												{
													int nread,i;
													nread = wip_read( ev->channel, rcv_buffer,RECBUFF);
													 if( nread < 0)
													 {
														  wip_debug( "\n[client]Unable to read. Error %i\n", nread);
														  return;
													 }
													 // wip_debug( "\n[client]Data received is %s\n", rcv_buffer);
													 nread = -1;
													 tmp = 0;
												 	 for(i=0;i<RECBUFF;i++)
													 {
														 if(rcv_buffer[i] == '~')
														 {
															 tmp = 1;
														 }
														 if(tmp==1)
														 {
															 rcv_buffer[i] = '\0';
														 }

													 }
												 	InboundData(rcv_buffer);


												 	do
												 	{

												 		wip_debug( "\n[client]Trying to close Data Channel.\n");
												 		wip_close( http_ClientTestCtx.DataChannel);
												 		adl_ctxSleep(100);

												 	}while(wip_getState(http_ClientTestCtx.DataChannel) == WIP_CSTATE_READY);
												 	do
												 	{
												 		wip_debug( "\n[client]Trying to close CX Channel.\n");
												 		wip_close( http_ClientTestCtx.CnxChannel);
												 		adl_ctxSleep(100);
												 	}while(wip_getState(http_ClientTestCtx.CnxChannel) == WIP_CSTATE_READY);
												 	adl_ctxSleep(2000);
												 	Business_Logic();


												}
												if (code == 400)
												{
													wip_debug( "\nChannel Unstable...\n");
													wip_debug( "\n[client]Trying to close CX Channel.\n");
													wip_close( http_ClientTestCtx.CnxChannel);
													if(wip_getState(http_ClientTestCtx.CnxChannel) == WIP_CSTATE_READY)
														wip_debug( "\n[client]Successfully to close CX Channel.\n");
													else
														wip_debug( "\n[client]Failed to close CX Channel.\n");

												}
												code = 0;
											//	wip_close( http_ClientTestCtx.DataChannel);
											//	wip_close( http_ClientTestCtx.CnxChannel);
												break;

		case WIP_CEV_WRITE:
												tmpbuf = 0;
												tmpbuf = adl_memGet(strlen(Data_PCKT)+3);
												wm_sprintf(tmpbuf,"Q=%s",Data_PCKT);
												wip_debug("\nSize of TMPBUF is %d. TMPBUF has : %s\n",strlen(tmpbuf),tmpbuf);

												wip_debug("\r\nhttp_ClientTestDataHandler: WIP_CEV_WRITE\r\n");
												BytesWritten = wip_write( http_ClientTestCtx.DataChannel, tmpbuf, (strlen(tmpbuf)+1)-offset);
												if(BytesWritten < 0)
												{/* error */
													wip_debug( "HTTP write error %i\n", BytesWritten);
													wip_debug( "\r\nwip_write error\r\n" );
													return;
												}
												offset += BytesWritten; /* Update the number of bytes sent. */
												if( offset == strlen(tmpbuf)+1)
												{ /* All of [buffer] has been sent */

													wm_sprintf( info, "\r\nhttp_ClientTestDataHandler: %d bytes written\r\n", offset);

													wip_debug(info);
												}
										//		wip_shutdown( http_ClientTestCtx.DataChannel,FALSE,TRUE);
												adl_memRelease (tmpbuf);
												tmpbuf = NULL;

												wip_debug( "\r\nTMPBUFF is freed\r\n" );
												break;

		case WIP_CEV_PEER_CLOSE:				wip_debug("\r\nhttp_ClientTestDataHandler: Done\r\n" );

												// end of data
												// show response information
												if( wip_getOpts( ev->channel,WIP_COPT_HTTP_STATUS_CODE, &status,WIP_COPT_HTTP_STATUS_REASON, tmpbuf, strlen(tmpbuf),WIP_COPT_END) == OK)
												{
													ascii sbuf[16];
													wip_debug("http_ClientTestDataHandler: Status=" );
													wm_sprintf( sbuf, "%d", status);
													wip_debug(sbuf);
													wip_debug( "\r\nhttp_ClientTestDataHandler: Reason=\"" );
													wip_debug(tmpbuf);
													wip_debug( "\"\r\n" );
												}
												if( wip_getOpts( ev->channel,WIP_COPT_HTTP_HEADER, "content-type", tmpbuf, strlen(tmpbuf),WIP_COPT_END) == OK)
												{
													wip_debug("http_ClientTestDataHandler: Content Type=\"%s\"\n", tmpbuf);
												}
												wip_debug("http_ClientTestDataHandler: Response Length=%d bytes\n",pHttpClientCtx->dataLength );

												// data channel must be closed

												wip_close( ev->channel);

												break;

		case WIP_CEV_ERROR:						wip_debug("http_ClientTestDataHandler: WIP_CEV_ERROR %d\n",ev->content.error.errnum);
												//adl_atSendResponse ( ADL_AT_UNS, "http_ClientTestDataHandler: ERROR\r\n" );
												wip_debug( "\r\nhttp_ClientTestDataHandler: ERROR\r\n");
												// connection to server broken
												wip_close( ev->channel);
												break;

		default:								wip_debug("http_ClientTestDataHandler: unexpected event: %d\n",ev->kind);
												wip_debug("\r\nunexpected event\r\n");
												break;
	}
}

 s32 http_Client(void)
{
	s32 ret = 0;
	char conlen[3];

	// HTTP Session creation
	// ---------------------------
	wm_sprintf(conlen,"%03d",strlen(Data_PCKT)+3);
	wip_debug("\nCONLEN = %s\n",conlen);


	wip_debug( "\nCX Channel State before Initialisation....\n" );
	switch(wip_getState(http_ClientTestCtx.CnxChannel))
	{
		case WIP_CSTATE_BUSY: 	wip_debug( "\nCX Channel Busy....\n" );
								break;
		case WIP_CSTATE_READY: 	wip_debug( "\nCX Channel Open and Ready...\n" );

								wip_close(http_ClientTestCtx.CnxChannel);
								http_Client();
								return 0;
		case WIP_CSTATE_TO_CLOSE: 	wip_debug( "\nCX Channel Ready to close....\n" );
								break;


	}
//	http_ClientTestCtx.CnxChannel = NULL;
	http_ClientTestCtx.CnxChannel = wip_HTTPClientCreateOpts(	NULL, // no handler
																NULL, // no context
																// default headers
																WIP_COPT_HTTP_HEADER, "User-Agent", "HTTP/1.1",
																WIP_COPT_END);
	if (http_ClientTestCtx.CnxChannel == NULL)
	{
		wip_debug( "\ncannot create http session channel\n" );
		//adl_atSendResponse ( ADL_AT_UNS, "cannot create http session channel\r\n" );
		wip_debug("\r\ncannot create http session channel\r\n");
		ret = -1;
	}
	else
	{
		wip_debug( "\r\nhttp session channel created\r\n");

		// HTTP POST command
//		http_ClientTestCtx.DataChannel = NULL;
		http_ClientTestCtx.DataChannel = wip_getFileOpts(
															http_ClientTestCtx.CnxChannel, // session channel
															HTTP_STR_URL, // URL to receive the data
															http_ClientTestDataHandler, // data handler
															&http_ClientTestCtx, // context
															WIP_COPT_HTTP_METHOD, WIP_HTTP_METHOD_POST,
															// request headers
															WIP_COPT_HTTP_HEADER, "Content-Type", "application/x-www-form-urlencoded",
															WIP_COPT_HTTP_HEADER, "Content-Length", conlen,
															WIP_COPT_HTTP_HEADER, "Accept", "text/html", WIP_COPT_END);
		if (http_ClientTestCtx.DataChannel == NULL)
		{
			wip_debug( "cannot create http data channel\n" );
			wip_debug( "\r\ncannot create http data channel\r\n");
			wip_close( http_ClientTestCtx.CnxChannel);
			// ret =-1;
		}
		else
			wip_debug( "\r\nHTTP data channel created\r\n");
	}

	return(ret);
}

#6

https://forum.sierrawireless.com/t/http-failed-the-second-time/4554/1