# HOW send SPI buffer by TCP socket

**URL:** <https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537>\
**Category:** Open AT\
**Created:** [April 3, 2012, 10:01am UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537 "2012-04-03T10:01:08Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![asem84](https://avatars.discourse-cdn.com/v4/letter/a/41988e/32.png) [@asem84](https://forum.sierrawireless.com/u/asem84)\
**Post date:** [April 3, 2012, 10:01am UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537/1 "2012-04-03T10:01:08Z")

</div>

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:

```auto
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 ❓ CAn I use the WIP\_write function??

Thank you

---

<div class="post-metadata">

**Author:** ![asem84](https://avatars.discourse-cdn.com/v4/letter/a/41988e/32.png) [@asem84](https://forum.sierrawireless.com/u/asem84)\
**Post date:** [April 4, 2012, 10:36am UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537/2 "2012-04-04T10:36:16Z")

</div>

Hello,

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

```auto
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.

---

<div class="post-metadata">

**Author:** ![tomridl](https://sea1.discourse-cdn.com/flex025/user_avatar/forum.sierrawireless.com/tomridl/32/2704_2.png) [@tomridl](https://forum.sierrawireless.com/u/tomridl)\
**Post date:** [April 4, 2012, 12:21pm UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537/3 "2012-04-04T12:21:58Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![asem84](https://avatars.discourse-cdn.com/v4/letter/a/41988e/32.png) [@asem84](https://forum.sierrawireless.com/u/asem84)\
**Post date:** [April 11, 2012, 10:17am UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537/4 "2012-04-11T10:17:43Z")

</div>

Hello,

I write this code

```auto
#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 ❓ or do I have do the wip\_write in the ‘case WIP\_CEV\_WRITE’ into the commhandler ❓❓

Thank you

---

<div class="post-metadata">

**Author:** ![tomridl](https://sea1.discourse-cdn.com/flex025/user_avatar/forum.sierrawireless.com/tomridl/32/2704_2.png) [@tomridl](https://forum.sierrawireless.com/u/tomridl)\
**Post date:** [April 11, 2012, 2:04pm UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537/5 "2012-04-11T14:04:09Z")

</div>

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](https://forum.sierrawireless.com/t/good-paper-on-event-driven-programming/3848/2)] for more help on this.

Change your code to the following:

```auto
#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();
}
```

---

<div class="post-metadata">

**Author:** ![asem84](https://avatars.discourse-cdn.com/v4/letter/a/41988e/32.png) [@asem84](https://forum.sierrawireless.com/u/asem84)\
**Post date:** [April 12, 2012, 10:23am UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537/6 "2012-04-12T10:23:35Z")

</div>

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 😕

```auto
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

---

<div class="post-metadata">

**Author:** ![tomridl](https://sea1.discourse-cdn.com/flex025/user_avatar/forum.sierrawireless.com/tomridl/32/2704_2.png) [@tomridl](https://forum.sierrawireless.com/u/tomridl)\
**Post date:** [April 12, 2012, 1:04pm UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537/7 "2012-04-12T13:04:12Z")

</div>

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.

 ![](https://us1.discourse-cdn.com/flex025/uploads/sierrawireless/original/2X/4/48abff2c8f8c23ed5775449e99586962a6d46acf.jpg)

---

<div class="post-metadata">

**Author:** ![asem84](https://avatars.discourse-cdn.com/v4/letter/a/41988e/32.png) [@asem84](https://forum.sierrawireless.com/u/asem84)\
**Post date:** [April 13, 2012, 8:48am UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537/8 "2012-04-13T08:48:11Z")

</div>

A lot of thanks tomridl.

I have understand the idea with your explanation 😃

---

<div class="post-metadata">

**Author:** ![zafer](https://avatars.discourse-cdn.com/v4/letter/z/439d5e/32.png) [@zafer](https://forum.sierrawireless.com/u/zafer)\
**Post date:** [April 16, 2012, 8:32am UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537/9 "2012-04-16T08:32:40Z")

</div>

i think, in the firmware, it would be more understandable if WIP\_CEV\_WRITE were named as WIP\_CEV\_WRITABLE etc.

---

<div class="post-metadata">

**Author:** ![enymotion](https://avatars.discourse-cdn.com/v4/letter/e/bb73d2/32.png) [@enymotion](https://forum.sierrawireless.com/u/enymotion)\
**Post date:** [June 12, 2012, 11:24am UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537/10 "2012-06-12T11:24:46Z")

</div>

> [@tomridl](#):
>
> 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.

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:

```auto
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

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

	adl_tmrUnSubscribe (timer, Timer_Handler2, ADL_TMR_TYPE_100MS) ;
	
}
```

---

<div class="post-metadata">

**Author:** ![zafer](https://avatars.discourse-cdn.com/v4/letter/z/439d5e/32.png) [@zafer](https://forum.sierrawireless.com/u/zafer)\
**Post date:** [June 12, 2012, 1:14pm UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537/11 "2012-06-12T13:14:16Z")

</div>

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

```auto
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:

```auto
wip_write(myChannel ,data, dataLen);
```

---

<div class="post-metadata">

**Author:** ![enymotion](https://avatars.discourse-cdn.com/v4/letter/e/bb73d2/32.png) [@enymotion](https://forum.sierrawireless.com/u/enymotion)\
**Post date:** [June 13, 2012, 9:58am UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537/12 "2012-06-13T09:58:01Z")

</div>

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:

```auto
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:

```auto
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

```auto
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

---

<div class="post-metadata">

**Author:** ![zafer](https://avatars.discourse-cdn.com/v4/letter/z/439d5e/32.png) [@zafer](https://forum.sierrawireless.com/u/zafer)\
**Post date:** [June 13, 2012, 12:03pm UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537/13 "2012-06-13T12:03:33Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![enymotion](https://avatars.discourse-cdn.com/v4/letter/e/bb73d2/32.png) [@enymotion](https://forum.sierrawireless.com/u/enymotion)\
**Post date:** [June 14, 2012, 11:00am UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537/14 "2012-06-14T11:00:13Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Ryan](https://avatars.discourse-cdn.com/v4/letter/r/a8b319/32.png) [@Ryan](https://forum.sierrawireless.com/u/Ryan)\
**Post date:** [July 5, 2012, 1:41pm UTC](https://forum.sierrawireless.com/t/how-send-spi-buffer-by-tcp-socket/5537/15 "2012-07-05T13:41:42Z")

</div>

asem84, were you able to get SPI to HTTP working? Adding SPI to TCP,UDP,HTTP passthrough to ClearComm ([clearconnex.com/content/clearcomm](http://www.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.
