Reopen socket problem


#1

Hello,

I’m trying to do a post of a value and a Id to a server. My code is:

const u16 wm_apmCustomStackSize = 1024*3;		/* application stack size (trial&error to determine size)*/
static wip_channel_t socket = NULL; 			/* TCP socket variable */
static int snd_offset = 0; 						/* How many bytes of [buffer] have already been sent. */
static char rcv_buffer [RCV_BUFFER_SIZE]; 		/* data in buffer */
static int  rcv_offset = 0; 					/* index of last filled buffer position */
//static ascii snd_buffer[WRITE_LENGTH] = "GET /default.php?id=510&value=12 HTTP/1.1\r\nHost: pollux.comuv.com\r\n\r\nConnection: close\r\n";/* out buffer */
//static ascii snd_buffer2[WRITE_LENGTH] = "POST /default.php?id=510&value=12 HTTP/1.1\r\nHost: pollux.comuv.com\r\n\r\nConnection: close\r\n";/* out buffer */
static UI_16 id=210;
static UI_16 value=32;
static ascii snd_buffer[WRITE_LENGTH];


void initcadena(void)
{
	ascii idbuf;
	ascii valuebuf;
	idbuf=(ascii)id;
	valuebuf=(ascii)value;
	/* I initialize the message that I want send  with the id and the value*/
	sprintf(snd_buffer,"POST /default.php?id=%d&value=%d HTTP/1.1\r\nHost: pollux.comuv.com\r\n\r\n",id,value);
}


/*-------------------------------- Functions --------------------------------*/

static void EvhBearer( wip_bearer_t b, SI_8 event, void *ctx) {

	SI_8 error;
	SI_8 err;
	ascii IpAddr[15];
	wip_in_addr_t appIpAddr;
	ascii Buffer[50];

	/* if event is connected then creates UDP socket to the server*/
	if( WIP_BEV_IP_CONNECTED == event) {
		adl_atSendResponse(ADL_AT_RSP, "\r\nGPRS: Connected");

		/* get public ip address, only for show via terminal*/
		err = wip_bearerGetOpts(b,WIP_BOPT_IP_ADDR,&appIpAddr,WIP_BOPT_END);
		wip_inet_ntoa(appIpAddr, IpAddr,15);
		wm_sprintf(Buffer, "\r\nGPRS: Public IP:[%s]\r\n",IpAddr);
		adl_atSendResponse (ADL_AT_RSP,Buffer);

		socket = wip_TCPClientCreate( PEER_STRADDR, PEER_PORT, EvhTcp, NULL);
	}
	else if(WIP_BEV_CONN_FAILED == event)
	{
		adl_atSendResponse(ADL_AT_RSP, "\r\nGPRS: Failed\r\n");

		if (wip_bearerGetOpts(b, WIP_BOPT_ERROR, &error, WIP_BOPT_END) == 0)
		{
		   switch(error)
		   {
			  case WIP_BERR_NO_DEV: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_NO_DEV"); break;
			  case WIP_BERR_ALREADY: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_ALREADY"); break;
			  case WIP_BERR_NO_IF: adl_atSendResponse(ADL_AT_RSP, "WIP_BERR_NO_IF"); break;
			  case WIP_BERR_NO_HDL: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_NO_HDL"); break;
			  case WIP_BERR_BAD_HDL: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_BAD_HDL"); break;
			  case WIP_BERR_OPTION: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_OPTION"); break;
			  case WIP_BERR_PARAM: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_PARAM"); break;
			  case WIP_BERR_OK_INPROGRESS: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_OK_INPROGRESS"); break;
			  case WIP_BERR_BAD_STATE: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_BAD_STATE"); break;
			  case WIP_BERR_DEV: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_DEV"); break;
			  case WIP_BERR_NOT_SUPPORTED: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_NOT_SUPPORTED"); break;
			  case WIP_BERR_LINE_BUSY: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_LINE_BUSY"); break;
			  case WIP_BERR_NO_ANSWER: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_NO_ANSWER"); break;
			  case WIP_BERR_NO_CARRIER: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_NO_CARRIER"); break;
			  case WIP_BERR_NO_SIM: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_NO_SIM"); break;
			  case WIP_BERR_PIN_NOT_READY: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_PIN_NOT_READY"); break;
			  case WIP_BERR_GPRS_FAILED: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_GPRS_FAILED"); break;
			  case WIP_BERR_PPP_LCP_FAILED: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_PPP_LCP_FAILED"); break;
			  case WIP_BERR_PPP_AUTH_FAILED: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_PPP_AUTH_FAILED"); break;
			  case WIP_BERR_PPP_IPCP_FAILED: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_PPP_IPCP_FAILED"); break;
			  case WIP_BERR_PPP_LINK_FAILED: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_PPP_LINK_FAILED"); break;
			  case WIP_BERR_PPP_TERM_REQ: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_PPP_TERM_REQ"); break;
			  case WIP_BERR_CALL_REFUSED: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_CALL_REFUSED"); break;
			  case WIP_BERR_NO_MEM: adl_atSendResponse(ADL_AT_RSP,"WIP_BERR_NO_MEM"); break;

			  default:
				  adl_atSendResponse(ADL_AT_RSP,"NO ERROR CODE FOUND.");
			  break;
		   }
		}
	}
}/*EvhBearer*/

wip_bearer_t b;

static void OpenAndStartBearer( void) {
	int r;

	adl_atSendResponse(ADL_AT_RSP, "\r\nOPENING BEARER...");

	/* stack tcp/ip init */
	r = wip_netInit();

	/* bearer atach */
	r = wip_bearerOpen( &b, "GPRS", EvhBearer, NULL);
	/* bearer config */
	r = wip_bearerSetOpts( b, WIP_BOPT_GPRS_APN, GPRS_APN,
			WIP_BOPT_LOGIN,       GPRS_USER,
			WIP_BOPT_PASSWORD,    GPRS_PASSWORD,
			WIP_BOPT_END);

	/* start connection */
	r = wip_bearerStart( b);
	TRACE((16,"conectado"));

}/*OpenAndStartBearer*/

static void PollCreg( u8 id, void * Context ) {
	/* AT Command to check network registering status */
	adl_atCmdCreate( "AT+CREG?", FALSE, PollCregCallback, ADL_STR_CREG, NULL);
}/*PollCreg*/

static bool PollCregCallback(adl_atResponse_t *Rsp) {
	ascii *tmp;
	ascii regStateString[3];
	s32 regStateInt;

	tmp = (ascii *)adl_memGet(Rsp->StrLength);
	wm_strRemoveCRLF(tmp, Rsp->StrData, Rsp->StrLength);

	/* parse response to get network register status*/
	wm_strGetParameterString(regStateString, Rsp->StrData, 2);
	regStateInt = wm_atoi(regStateString);

	if ( 1 == regStateInt || 5 == regStateInt) {
		/* if registered start connection */
		OpenAndStartBearer();
	}
	/* else check again after CREG_POLLING_PERIOD */
	else {
		adl_atSendResponse(ADL_AT_RSP, "\r\nREGISTERING TO NETWORK...");
		/* oneshot timer to check registering status */
		adl_tmrSubscribe( FALSE, CREG_POLLING_PERIOD, ADL_TMR_TYPE_100MS,PollCreg);
	}
	return FALSE;
}/*PollCregCallback*/

static void EvhSim( u8 event) {
	if( ADL_SIM_EVENT_FULL_INIT == event) {
		adl_atSendResponse(ADL_AT_RSP, "\r\nSIM OK!!!!");
		PollCreg( 0 , NULL );
	}
}/*EvhSim*/

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

	int nwrite,nread;	/* bytes read/write */
	ascii tmp[200];		/* tmp string to show data */

	switch( ev->kind) {

	case WIP_CEV_OPEN: {
		adl_atSendResponse( ADL_AT_UNS, "\r\nSOCKET: Open\r\n" );
		wip_write(socket, snd_buffer, WRITE_LENGTH);
		break;
	}
	case WIP_CEV_READ: {
		adl_atSendResponse( ADL_AT_UNS, "\r\nSOCKET: Read\r\n" );

		nread = wip_read( ev->channel, rcv_buffer + rcv_offset,sizeof( rcv_buffer) - rcv_offset);

		rcv_offset += nread;

		/* check buffer index */
		if( rcv_offset == sizeof( rcv_buffer)){
			adl_atSendResponse( ADL_AT_UNS, "\r\nSOCKET: Read Error::buffer full\r\n" );
		}
		else{
			wm_sprintf(tmp,"\r\nSOCKET:Read: %d, %u bytes free on buffer\n",nread,sizeof(rcv_buffer)-rcv_offset);
			adl_atSendResponse( ADL_AT_UNS, tmp );
		}
		break;
	}
	case WIP_CEV_WRITE:

		adl_atSendResponse( ADL_AT_UNS, "\r\nSOCKET: Write\r\n" );

		nwrite = wip_write( ev->channel, snd_buffer + snd_offset,sizeof( snd_buffer) - snd_offset);
		snd_offset += nwrite;
		break;
	case WIP_CEV_DONE:
		adl_atSendResponse( ADL_AT_UNS, "\r\nSOCKET: Done\r\n" );
		break;
	case WIP_CEV_PING:
		adl_atSendResponse( ADL_AT_UNS, "\r\nSOCKET: Ping\r\n" );
		break;
	case WIP_CEV_ERROR:
		adl_atSendResponse( ADL_AT_UNS, "\r\nSOCKET: Error\r\n" );

		if( wip_getState( ev->channel) != WIP_CSTATE_READY) {
			adl_atSendResponse(ADL_AT_RSP, "\r\nERROR FATAL SOCKET!!!!");
			wip_close( ev->channel);
		}
		break;
	case WIP_CEV_PEER_CLOSE:
		wip_close(socket);
		wip_close(ev->channel);
		adl_atSendResponse( ADL_AT_UNS, "\r\nSOCKET: Closed by Peer \r\n" );
		adl_atSendResponse( ADL_AT_UNS, rcv_buffer );
		break;
	}
}/*EvhTcp*/


void initGPRS(void)
{
	adl_simSubscribe( EvhSim, SIM_PINCODE);
}

void main_task( void )
{
     initGPRS();
}

This code works well if only i want do a post (initialize GPRS -> open the socket-> write -> read -> close the socket), but when i try to do another post i have problems. I have do a lot of trials and i don’t understand where is my problem. I think that it could be that i close wrongly my socket… Could you help me?? I don’t understand why my socket closes always (its not a timeout). and i don’t know how i can reopen and send info by the same socket.

Thank you


#2

Hi,

I can see in the attached code that in the event handler of TCP client i.e. evhTCP,for WIP_CEV_PEER_CLOSE event,wip_close(socket) and wip_close(ev->channel) both are being done.

socket and ev->channel represents the same.Both are of wip_channel_t type.Both represents the same TCP channel.

Thanks.


#3

Thanks paruthiv,

It’s true, i erase wip_close(socket) from my code.
Now i have detected that when i’m trying to reopen the socket a lot of times, sometimes i have a fatal error socket and im not able to reopen the socket. I’ve solved this problem trying to reopen the sockets after one second. Somebody has another solution??

Thanks