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/