Hello,

I posted something similar to this a while back, but am still having
trouble. I am trying to re-assemble packets that my program receives using
the WAP WTP protocol with Segmentation and Reassembly.
It looks as if some data is making it into the data global in SARType, but
not all, and I am getting errors
reassembling these packets afterwards. My question is does anybody know how
to do this a better way? I have included my code
relevant to SAR support below.


Thanks,
Donald

The Code:

In WspGetReply sock refers to the currently open socket, buf refers to a
buffer that was created with MemPtrNew,
buflen refers to the size of the buffer, maxTimer is the maximum timeout,
and g is a pointer to the GlobalsType.


typedef struct SARType {
  Int32 pos;  // Packet position, so we can receive out of order packets?
  Boolean last;  // Tells if it is the last packet
  char *data;  // The data
  UInt32 size;  // length of data
  struct SARType *next; // More packets
} SARType;

typedef SARType *SARPtr;

typedef struct {
 /* at least 50 many non-relavant globals */
 SARPtr    segment;
} GlobalsType;


#define Malloc MemPtrNew
#define Free MemPtrFree


Int16 WspGetReply(Int16 sock, char *buf, Int16 buflen, UInt32
maxTimer,GlobalsType *g)
{
    Int16     ret;
    int t = 0;

    AppNetTimeout = 4 * SysTicksPerSecond();

    // please don't turn me off now
    EvtResetAutoOffTimer();


for(;;) {

start:

    ret = recv(sock,buf,buflen,0);

    if ((errno==netErrTimeout) && ( TimGetTicks() < maxTimer ) ) {
        return(0);
    }

    if (ret <= 0) {
     /* non-relavent error handling */
 break;
    } else {
 if (g->conn.connectionType == 'O') {
  switch ((buf[0] & 0x78) >> 3) {
   case WTP_Result:
    switch ((buf[0] & 0x07) >> 1) {
     case 0x03: // SAR Not supported
     case 0x01: // End of transmission
      if (buf[2] != g->tid) //need better tid handeling
       return(0);
      else
       WTPAck(sock, g);
      break;
     case 0x00: // Not Last
      SARaddSegment(0, false, buf, (UInt32) ret, 1, g);
      goto start;
      break;
    }
    break;
   case WTP_SAR_Result:
    t++;

    switch ((buf[0] & 0x07) >> 1) {
     case 0x02: // Last packet of group
      SARaddSegment(StrAToI(buf+3), false, buf, (UInt32) (ret-3), 2, g);
      SARWTPAck(sock, t, true, g);
      goto start;
      break;
     case 0x01: // End of transmission
      SARaddSegment(StrAToI(buf+3), true, buf, (UInt32) (ret-3), 2, g);
      SARWTPAck(sock, t, false, g);
      SARreassemble(buf, buflen, g);
      SARdeleteData(g);
      break;
     case 0x00: // Not Last
      SARaddSegment(StrAToI(buf+3), false, buf, (UInt32) (ret-3), 2, g);
      goto start;
      break;
    }
    break;
   case WTP_Ack:
   // Some gateways are too concerned and send Ack after just about anything
we send, so
   // we must learn to ignore unwanted Ack's
    ret = WspGetReply(sock,buf,buflen,maxTimer,g);
    return(ret);
    break;
   case WTP_Abort:
    MyErrorFunc2("Could not receive data from server. Remote host sent
Abort.","Receive");
    return(-20);
    break;
   default:
    if (buf[2] != g->tid) //need better tid handeling
     return(0);
    else
     WTPAck(sock, g);
        break;
  }
  break;
     }

    }

break;
}

    return(ret);
}

void WSPCloseSocket(Int16 sock)
{
    if (sock >= 0)
        close (sock);
    sock = -1;

}

Boolean SARaddSegment(Int32 pos, Boolean last, char *data, UInt32 size, int
type, GlobalsType *g)
{
  SARPtr tmp, sar;

 sar = g->segment;
 while(sar != NULL)
 {

  if (pos == sar->pos)
  {
   return(false); // We already added this segment, I hope...
  }
  sar = sar->next;
 }

 tmp = Malloc (sizeof(SARType));
 MemSet(tmp,sizeof(SARType),0);
 ErrFatalDisplayIf (!tmp, "Malloc Failed");
 tmp->pos = pos;
 tmp->last = last;
 tmp->size = StrLen(data); // or size?
 tmp->data = Malloc(StrLen(data)+1); // or MemPtrNew(size+1);
 ErrFatalDisplayIf (!tmp->data, "Malloc Failed");
 if (type == 2)
  StrCopy(tmp->data, data+4);
 else
  StrCopy(tmp->data, data);

 tmp->next = g->segment;
     g->segment = tmp;

return(true);
}


Boolean SARreassemble(char *buf, Int16 buflen, GlobalsType *g)
{
  SARPtr tmp;
  Int32 o = 0;
  UInt32 offset=0;
  Boolean finished = false;
  Int32 lastpkt = 0;

 tmp = g->segment;

 while (tmp != NULL) {
  if (tmp->last) {
   lastpkt = tmp->pos;
   break;
  }

  tmp = tmp->next;
 }

 tmp = g->segment;
 while(!finished)
   {
    while((tmp->pos != o) && (tmp != NULL)){
   tmp = tmp->next;
    }
  if (tmp == NULL) {
   tmp = g->segment; // start over
  }
  if (MemPtrSize(buf) < (offset+tmp->size))
   MemPtrResize(buf, offset+tmp->size);
  StrCopy(buf+offset, tmp->data);
  offset += tmp->size;
  o++; // increase offeset

  if (o == lastpkt)
   break;

  tmp = g->segment; //start over

   }

 return true;
}

Boolean SARdeleteData(GlobalsType *g)
{
  SARPtr tmp;

 while(g->segment != NULL){
  tmp = g->segment;
  g->segment = g->segment->next;
  tmp->pos = 0;
  tmp->size = 0;
  tmp->last = false;
  if(tmp->data)
   Free(tmp->data);
  Free(tmp);
 }
   return(true);
}



-- 
For information on using the Palm Developer Forums, or to unsubscribe, please 
see http://www.palmos.com/dev/support/forums/

Reply via email to