HOW send SPI buffer by TCP socket

Hello,

I’m newbie in the HTTP communications and i want to send the data received from the SPI bus to a server using a HTTP connection. I have studied the user guide and I have saw the examples.
The sample code is:

AT+WIPCFG=1      // Istart IP stack


AT+WIPBR=1,6     // I open GPRS bearer


AT+WIPBR=2,6,11,"APN name"   //I set APN name GPRS bearer

AT+WIPBR=2,6,0,"USER NAME"   //I set user name (login)

AT+WIPBR=2,6,1,"PASSWORD"    // I set password

AT+WIPBR=4,6,0     //start GPRS bearer

AT+WIPCREATE=2,1,"102.221.xxx.254",80   //create theTCP client on port 80,idx=1

AT+WIPDATA=2,1,1      //exchange data on socket index 1

My question is: How can i put the data saved in the buffer in the socket 1 for send it :question: CAn I use the WIP_write function??

Thank you

Hello,

I’ve read the “wip user command guide” and i wrote this code, but it doesn’t work.

wip_bearer_t myBearer

wip_netInit(); //Initialize the TCP/IP stack

wip_write(channel,data,len);

Could someone help me? somebody has an example? My goal is send a buffer to a server.

Thank you.

Here are the steps required to send data to a server (assuming you already have a TCP server running on the server and that all the required ports are opened):

  1. Create a GPRS Connection (MUST be on the highest priority task)

To do this, you must do the following:
a) wip_netInitOpts to initialise the stack
b) wip_bearerOpen to open the bearer
c) if the response to the wip_bearerOpen is OK, you can set your bearer APN and options using wip_bearerSetOpts
d) When the options are set, call wip_bearerStart to start the bearer connection
e) When you receive a WIP_BEV_IP_CONNECTED event in the handler you declared in wip_bearerOpen, GPRS is now connected.

  1. Create a TCP connection to the server (this can be on another task of lower priority if you want)

To do this you must have an active GPRS connection, and then do the following:
a)wip_netInitOpts to initialise the stack if you are on a separate task to the GPRS connection, otherwise skip this step if it is the same task.
b) wip_TCPClientCreateOpts to create the client. Make sure to fill in the correct server details in the options, as well as an event handler.
c) When you receive a WIP_CEV_WRITE event in your event handler, you can send the data using wip_write using the channel passed in the event handler

Hello,

I write this code

#define SERVER_PORT 1234
#define SERVER_ADDRESS "192.168.1.4"
#define MSG "Hello"


wip_bearer_t my_Bearer;

void myHandler(wip_bearer_t br, s8 event, void *context)
{
	switch(event){
	case WIP_BEV_IP_CONNECTED:
		/*IP connectivity we can start IP app from here*/
		TRACE((7,"GPRS connected"));
		break;
	case WIP_BEV_IP_DISCONNECTED:
		/*stop IP app*/
		TRACE((7,"GPRS disconnected"));
		break;
		/*other events*/
	default:
		/*cannot start bearer:report error to higher levels*/
		break;
	}
}

bool connectGPRS(void){
	wip_netInit();
	/* open bearer and install our event handler */
	if((wip_bearerOpen(&my_Bearer,"GPRS",myHandler,NULL))!=0){
		TRACE((7,"bearer open error"));
		/*cannot open the bearer*/
		return FALSE;
	}
	/* configure GPRS interface */
	if (wip_bearerSetOpts( my_Bearer,
						  WIP_BOPT_GPRS_APN, "my_apn",
						  WIP_BOPT_LOGIN,"my_login",
						  WIP_BOPT_PASSWORD,"my_password",
						  WIP_BOPT_END)!=0){
		/* cannot configure bearer */
		wip_bearerClose(my_Bearer);
		TRACE((7,"set bearer options error"));
		return FALSE;
	}
	if (wip_bearerStart(my_Bearer)!=0){
		/* cannot start bearer */
		wip_bearerClose(my_Bearer);
		return FALSE;
	}
	/*connection status will be reported to the event handler*/
	return TRUE;
}


void commHandler (wip_event_t *ev, void *ctx){
	switch (ev->kind){

	case WIP_CEV_OPEN:
		TRACE((4,"OPEN"));
		break;
	case WIP_CEV_READ:
		TRACE((4,"READ"));
		break;
	case WIP_CEV_WRITE:
		TRACE((4,"WRITE"));
		break;
	case WIP_CEV_ERROR:
		TRACE((4,"ERROR"));
		break;
	case WIP_CEV_DONE:
		TRACE((4,"DONE"));
		break;
	case WIP_CEV_PING:
		TRACE((4,"PING"));
		break;
	case WIP_CEV_PEER_CLOSE:
		TRACE((4,"PEER_CLOSE"));
		break;
	}
}


void startClient(){
	wip_channel_t client = wip_TCPClientCreate(SERVER_ADDRESS,SERVER_PORT,&commHandler,NULL);
	
}


void main(){

/* I connect GPRS */
connectGPRS();

/* I start TCP connection */
startClient();

/* I send 'Hello' to the server */
 wip_write(client,MSG,strlen(MSG));
}

My question is: Do I have to write in the ‘void main’ like my example :question: or do I have do the wip_write in the ‘case WIP_CEV_WRITE’ into the commhandler :question: :question:

Thank you

You first have to wait for both the GPRS connection to open, and then for the TCP client to open. Just calling one after the other doesn’t mean the GPRS connection will be open. OpenAT is event driven, have a look at [url]https://forum.sierrawireless.com/t/good-paper-on-event-driven-programming/3848/2] for more help on this.

Change your code to the following:

#define SERVER_PORT 1234
#define SERVER_ADDRESS "192.168.1.4"
#define MSG "Hello"


wip_bearer_t my_Bearer;

void myHandler(wip_bearer_t br, s8 event, void *context)
{
   switch(event){
   case WIP_BEV_IP_CONNECTED:
      /*IP connectivity we can start IP app from here*/

    /* I start TCP connection */
    startClient();

      TRACE((7,"GPRS connected"));
      break;
   case WIP_BEV_IP_DISCONNECTED:
      /*stop IP app*/
      TRACE((7,"GPRS disconnected"));
      break;
      /*other events*/
   default:
      /*cannot start bearer:report error to higher levels*/
      break;
   }
}

bool connectGPRS(void){
   wip_netInit();
   /* open bearer and install our event handler */
   if((wip_bearerOpen(&my_Bearer,"GPRS",myHandler,NULL))!=0){
      TRACE((7,"bearer open error"));
      /*cannot open the bearer*/
      return FALSE;
   }
   /* configure GPRS interface */
   if (wip_bearerSetOpts( my_Bearer,
                    WIP_BOPT_GPRS_APN, "my_apn",
                    WIP_BOPT_LOGIN,"my_login",
                    WIP_BOPT_PASSWORD,"my_password",
                    WIP_BOPT_END)!=0){
      /* cannot configure bearer */
      wip_bearerClose(my_Bearer);
      TRACE((7,"set bearer options error"));
      return FALSE;
   }
   if (wip_bearerStart(my_Bearer)!=0){
      /* cannot start bearer */
      wip_bearerClose(my_Bearer);
      return FALSE;
   }
   /*connection status will be reported to the event handler*/
   return TRUE;
}


void commHandler (wip_event_t *ev, void *ctx){
   switch (ev->kind){

   case WIP_CEV_OPEN:
      TRACE((4,"OPEN"));
      break;
   case WIP_CEV_READ:
      TRACE((4,"READ"));
      break;
   case WIP_CEV_WRITE:
      TRACE((4,"WRITE"));

    /* I send 'Hello' to the server */
    wip_write(client,MSG,strlen(MSG));

      break;
   case WIP_CEV_ERROR:
      TRACE((4,"ERROR"));
      break;
   case WIP_CEV_DONE:
      TRACE((4,"DONE"));
      break;
   case WIP_CEV_PING:
      TRACE((4,"PING"));
      break;
   case WIP_CEV_PEER_CLOSE:
      TRACE((4,"PEER_CLOSE"));
      break;
   }
}


void startClient(){
   wip_channel_t client = wip_TCPClientCreate(SERVER_ADDRESS,SERVER_PORT,&commHandler,NULL);
   
}


void main(){

/* I connect GPRS */
connectGPRS();
}

Thanks tomridl

I have only one doubt. In this code, you put wip_write function inside the CEV_WRITE case. I don’t understand how it works. When will i go to be in this case? How many times(only one or more)? I will send hello’s message one time or more. I’m sorry, but i’m not informatic and for me its a little hard understand how i will have and event in the GPRS. I have read the GUide but i don’t get the idea :confused:

void commHandler (wip_event_t *ev, void *ctx){
   switch (ev->kind){

   case WIP_CEV_OPEN:
      TRACE((4,"OPEN"));
      break;
   case WIP_CEV_READ:
      TRACE((4,"READ"));
      break;
   case WIP_CEV_WRITE:
      TRACE((4,"WRITE"));

    /* I send 'Hello' to the server */
    wip_write(client,MSG,strlen(MSG));

      break;
   case WIP_CEV_ERROR:
      TRACE((4,"ERROR"));
      break;
   case WIP_CEV_DONE:
      TRACE((4,"DONE"));
      break;
   case WIP_CEV_PING:
      TRACE((4,"PING"));
      break;
   case WIP_CEV_PEER_CLOSE:
      TRACE((4,"PEER_CLOSE"));
      break;
   }
}

Thank you

Once the TCP client is open, you will get a WIP_CEV_OPEN event, and when the client is ready to write, you will get a WIP_CEV_WRITE event (see the picture below). So once you get the WIP_CEV_WRITE event, you can write to the client whenever or however you like using wip_write with the correct channel. The example code above will only write once to the client, so if you want to write regularly, set up a timer that is started by the WIP_CEV_WRITE event, and that periodically calls wip_write to write the data. Or you can use whatever other trigger you like to write the data.


A lot of thanks tomridl.

I have understand the idea with your explanation :smiley:

i think, in the firmware, it would be more understandable if WIP_CEV_WRITE were named as WIP_CEV_WRITABLE etc.

I don’t understand how I have to call wip_write with a timer.

I implemented a timer which starts with the Wip_CEV_Write Event. After the time is up a timer handler is called. The problem now is that in this handler I can’t call wip write because the channel is not know.

Have somebody an idea how I can solve this problem?

WIP_CEV_WRite Code:

case WIP_CEV_WRITE:
        {
        	int nwrite;
        	int close;

        	timer=adl_tmrSubscribeExt ( ADL_TMR_CYCLIC_OPT_ON_RECEIVE,timeout_period,ADL_TMR_TYPE_100MS,Timer_Handler2,NULL,FALSE );

           nwrite=wip_write (ev->channel, snd_buffer ,buflen);
    break;
        }

Timer Handler

void Timer_Handler2( u8 Id, void * Context )
{
	//Unsubscribe from the timer resource

	adl_tmrUnSubscribe (timer, Timer_Handler2, ADL_TMR_TYPE_100MS) ;
	
}

You can keep your channel in a global variable like the following:

wip_channel_t myChannel;

//in tcp handler
case WIP_CEV_WRITE:
 myChannel = ev->channel;
break;

Then in timer handler function, you can call this variable to send data over your channel:

wip_write(myChannel  ,data, dataLen);

Thanks zafer,

now I have another problem. The timer is subscribed, but in the Handler function of the Timer it writes only once to Server. I think the timer doesen´t start again. I also get an error -992 (no more TCP buffers available).

This is my TCP Create function:

wip_channel_t socket;
void AppliEntryPoint ( void )
{

    TRACE ( ( NORMAL_TRACE_LEVEL, "[SAMPLE]: connecting to client %d", TCP_PEER_PORT ) );

    socket = wip_TCPClientCreateOpts ( TCP_PEER_STRADDR, TCP_PEER_PORT, cbevh,NULL,WIP_COPT_SND_BUFSIZE,5000,WIP_COPT_SND_LOWAT,1024,WIP_COPT_NODELAY, TRUE,WIP_COPT_FINALIZER, my_finalizer,WIP_COPT_END );

    if ( !socket )
    {
        TRACE ( ( ERROR_TRACE_LEVEL, "[SAMPLE] Can't connect" ) );
        return;
    }
}

This is the piece of WIP_CEV_WRITE:

case WIP_CEV_WRITE:
        {
        	socket=ev->channel;
        	timer=adl_tmrSubscribeExt ( ADL_TMR_CYCLIC_OPT_ON_RECEIVE,timeout_period,ADL_TMR_TYPE_100MS,Timer_Handler2,NULL,FALSE );
        	
        	break;
        }

And this is my Timer Handler function

void Timer_Handler2( u8 Id, void * Context )
{
	//if ( socket!=0 )
  //{

	nwrite=wip_write (socket, snd_buffer ,buflen);

	if ( nwrite < 0 )
	{
	TRACE ( ( ERROR_TRACE_LEVEL, "[SAMPLE] write error %i", nwrite ) );
	
	return;
	}

	
}

Have anyone an idea what is not correct?

Thanks

i think if your bufferLen parameter is too big which is greater than internal buffers then you can get this error.
i think you shouldnt put your timer under WIP_CEV_WRITE event. Insead of this logic, you can set a continoue timer seperately and start this timer when you create your socket. it will make sure that you start the timer once.
Then in the handler of the timer, you can check your socket and if it is not null and it is alive, you can use wip_write function to send your data in spi buffer.
if you get -992 error code, just let the timer tick again. At next time, wip_write function may send your data.

Hello Zafer,

thank you for your reply. It was a problem with the Server, programmed in C.

I put my timer to WIP_CEV_OPEN.

At the moment I don’t get the error 992.

Thank you

asem84, were you able to get SPI to HTTP working? Adding SPI to TCP,UDP,HTTP passthrough to ClearComm (clearconnex.com/content/clearcomm) is nearing the top of our list of features we are planning on adding. If you still need it I’d be very interested in hearing more of your requirements for SPI side of your application.