📄 obex.c
字号:
*/ if ( request->state == STATE_SENT ) { /* ** In this situation, the object has been completely sent, but we got a ** continue from the peer. This indicates that more objects will follow */ done = TRUE; } break; default: OBXDBGERR(("[ERROR] ObxTransactionSend() *unexpected* response (%02x) from our send attempt.\n", response->cmd)); done = TRUE; break; } } else { OBXDBGERR(("[ERROR] ObxTransactionSend() bad return code from iobxObjectRecvObject(), rc=%d\n", rc)); done = TRUE; } } else { OBXDBGERR(("[ERROR] ObxTransactionSend() bad return code from iobxObjectReset(), rc=%d\n", rc)); done = TRUE; } } else { // Response not expected, we return immediately. done = TRUE; } } else { OBXDBGERR(("[ERROR] ObxTransactionSend() bad return code from iobxObjectSendObject(), rc=%d\n", rc)); done = TRUE; } } } return rc;}OBEX_EXPORT ObxRc ObxTransactionRecv( ObxHandle *handle, ObxObject *requestOut, short coalesce ) { short done = FALSE; ObxRc rc = OBX_RC_OK; ObxObject *response = NULL; ObxObject *request = NULL; ObxIterator *obxiterator = NULL; ObxList *obxlist = NULL; ObxHeader *obxheader = NULL; ObxHeader *bodyheader = NULL; ObxHeader *header = NULL; void *bytebuffer; int dataLength; ObxBuffer *obxbuffer; int targetHeaderCount=0; OBXDBGFLOW(("ObxTransactionRecv() entry, handle=0x%08x\trequest=0x%08x\n", handle, request)); if ( !(response = iobxObjectNew()) || !(request = iobxObjectNew()) ) { OBXDBGERR(("[ERROR] ObxTransactionRecv() Error creating request/response objects.\n")); return OBX_RC_ERR_MEMORY; } while ( !done ) { if ( (rc=iobxObjectReset( request )) == OBX_RC_OK ) { if ( (rc=iobxObjectRecvObject( request, handle )) == OBX_RC_OK ) { requestOut->cmd = request->cmd; if ( request->cmd == OBEX_CMD_GET ) { /* ** They are on their own. */ return OBX_RC_ERR_NO_GET_SUPPORT; } if ( (rc=iobxObjectReset( response )) == OBX_RC_OK ) { /* ** Acumulate or coalesce headers, in either case, we iterate all new inbound headers. */ if ( (obxlist=iobxObjectGetHeaderList( request )) ) { if ( (obxiterator=iobxListGetIterator( obxlist )) ) { iobxIteratorReset( obxiterator ); while ( iobxIteratorHasNext( obxiterator ) ) { if ( (obxheader = (ObxHeader *)iobxIteratorNext( obxiterator )) ) {//OBEX_HEADER_BODY_END is also a kind of body chunk.// if ( obxheader->identifier == OBEX_HEADER_BODY || obxheader->identifier == OBEX_HEADER_BODY ) { if ( obxheader->identifier == OBEX_HEADER_BODY || obxheader->identifier == OBEX_HEADER_BODY_END ) { /* ** We may need to bind this data with some data that's already arrived. */ if ( coalesce ) { if ( bodyheader ) { /* ** A header is already in the output request. Append. */ dataLength = iobxBufSize( obxheader->value.byteSequenceValue ); if ( ( bytebuffer=(void *)malloc( dataLength )) ) { OBXDBGBUF(("ObxTransactionRecv() malloc, addr=0x%08x, len=%d.\n", bytebuffer, dataLength )); if ( iobxBufRead( obxheader->value.byteSequenceValue, bytebuffer, dataLength ) == dataLength) { OBXDBGINFO(("ObxTransactionRecv() appending body to existing header.\n")); if ( (iobxBufWrite( bodyheader->value.byteSequenceValue, bytebuffer, dataLength )) ) { OBXDBGERR(("[ERROR] ObxTransactionRecv() Error appending to header.\n")); return OBX_RC_ERR_TRANSPORT; } } else { OBXDBGERR(("[ERROR] ObxTransactionRecv() not enough data in buffer?.\n")); return OBX_RC_ERR_MEMORY; } free( bytebuffer ); } else { OBXDBGERR(("[ERROR] ObxTransactionRecv() creating byte buffer.\n")); return OBX_RC_ERR_MEMORY; } /* ** We don't want to add this one.. since we've combined with an existing one. */ // T.K. we don't free it here, as it gets freed later on. // freeing it now will cause memory coruption. Just set the pointer // to NULL and it gets cleaned up in the end //iobxHeaderFree( obxheader ); obxheader = NULL; } else { /* ** First one we've seen, so, we'll add it. */ bodyheader = obxheader; } } } else if ( obxheader->identifier == OBEX_HEADER_TARGET ) {//Check if the Target header, which is sent from OBEX client in Connect command, conforms to the specified SyncML UUID. if ( request->cmd != OBEX_CMD_CONNECT ) { rc = OBX_RC_ERR_SML_TARGET_HDR; break; } targetHeaderCount++; if(targetHeaderCount>1) { rc = OBX_RC_ERR_SML_TARGET_HDR; break; } dataLength = iobxBufSize( obxheader->value.byteSequenceValue ); if ( ( bytebuffer=(void *)malloc( dataLength+1 )) ) { memset(bytebuffer,0,dataLength+1); if ( iobxBufRead( obxheader->value.byteSequenceValue, bytebuffer, dataLength ) == dataLength) { if(strcmp(bytebuffer,SYNCML_TARGET)) { rc = OBX_RC_ERR_SML_TARGET_HDR; free( bytebuffer ); break; } } else { OBXDBGERR(("[ERROR] ObxTransactionRecv() not enough data in buffer?.\n")); free( bytebuffer ); return OBX_RC_ERR_MEMORY; } free( bytebuffer ); } else { OBXDBGERR(("[ERROR] ObxTransactionRecv() creating byte buffer.\n")); return OBX_RC_ERR_MEMORY; } } /* ** If we haven't coalesced this header we simply add it. ** Note that this could result in duplicate headers from the peer. We make ** no effort to stop them from sending them... we're just a conduit. */ if ( obxheader ) { if ( (rc=iobxObjectAddHeader( requestOut, obxheader, handle )) != OBX_RC_OK ) { OBXDBGERR(("[ERROR] ObxTransactionRecv() bad return code from iobxObjectAddHeader(), rc=%d\n", rc)); return rc; } /* ** Remove this header from the 'request' since 'requestOut' now owns it. ** The itterator will be 'backed up' from the removed item. All ready for ** the next pass through the loop. */ if ( !(iobxListRemove( obxlist, obxiterator )) ) { OBXDBGERR(("[ERROR] ObxTransactionRecv() Error removing header from response.\n")); return OBX_RC_ERR_TRANSPORT; } } } else { OBXDBGERR(("[ERROR] ObxTransactionRecv() bad return code from iobxIteratorNext(), rc=%d\n", rc)); return rc; } } /* ** Done with iterator */ iobxIteratorFree( obxiterator ); } else { OBXDBGERR(("[ERROR] ObxTransactionRecv() bad return code from iobxListGetIterator(), rc=%d\n", rc)); return rc; } } else { OBXDBGERR(("[ERROR] ObxTransactionRecv() bad return code from iobxObjectGetHeaderList(), rc=%d\n", rc)); return rc; } if(rc != OBX_RC_OK) break; /* ** Inbound request a CONNECT? ** If so, we see if we can honor their proposed MTU, adjust up only if needed. */ if ( request->cmd == OBEX_CMD_CONNECT ) { /* ** If one's set for us, we must respect our own (not climb above it). */ handle->maxPacketLen = min( handle->maxPacketLen, max( OBEX_MINIMUM_PACKET_LENGTH, request->meta.connectMeta->max_packet_length ) ); } /* ** Do we send SUCCESS or CONTINUE?... build response. */// requestOut->cmd = request->cmd; if ( request->cmd & OBEX_CMD_FINAL ) { OBXDBGINFO(("ObxTransactionRecv() FINAL bit from peer.\n")); response->cmd = (OBEX_RSP_SUCCESS | OBEX_CMD_FINAL); /* ** Response could be a response to a Connect or SetPath... ** If so, we use our default meta data in the response ** NOTE: ** We could avoid this by using ObxObjectNewResponse() but ** since we're 'inside' we can just do the adjustment ourselves ** that way we can reuse the response object. */ if ( request->cmd == OBEX_CMD_CONNECT ) {//There must be Target header in Connect command. if( targetHeaderCount ==0 ) { rc=OBX_RC_ERR_SML_TARGET_HDR; break; } if ( (rc=iobxObjectSetConnectMeta( response, OBX_CONNECT_META_VERSION, OBX_CONNECT_META_FLAGS, handle->maxPacketLen )) != OBX_RC_OK ) { OBXDBGERR(("[ERROR] ObxTransactionRecv() unexpected rc from iobxObjectSetConnectMeta(), rc=%d!\n", rc)); return rc; }//There must be headers of ConnectionID and Who in the response of Connection command.//At the same time, ConnectionID must be saved for later use. srand( (unsigned)time( NULL ) ); if ( !(header = iobxHeaderNew( OBEX_HEADER_CONNECTION )) ) { OBXDBGERR(("[ERROR] ObxTransactionRecv() Error creating header.\n")); rc = OBX_RC_ERR_MEMORY; } else if ( (rc=ObxHeaderSetIntValue( header, (handle->OBEXConnectionID=rand()) )) != OBX_RC_OK ) { iobxHeaderFree(header); OBXDBGERR(("[ERROR] ObxTransactionRecv() unexpected rc calling ObxHeaderSetIntValue().\n")); } else if ( (rc=iobxObjectAddHeader( response, header, handle )) != OBX_RC_OK ) { iobxHeaderFree(header); OBXDBGERR(("[ERROR] ObxTransactionRecv() unexpected rc calling iobxObjectAddHeader().\n")); } header=NULL; if( rc !=OBX_RC_OK ) return rc; if ( !(header = iobxHeaderNew( OBEX_HEADER_WHO ))) { OBXDBGERR(("[ERROR] ObxTransactionRecv() Error creating header.\n")); rc = OBX_RC_ERR_MEMORY; } else if ( !(obxbuffer = ObxBufNew( strlen( SYNCML_TARGET ) )) ) { iobxHeaderFree(header); OBXDBGERR(("[ERROR] ObxTransactionRecv() Error creating buffer.\n")); rc = OBX_RC_ERR_MEMORY; } else if((ObxBufWrite( obxbuffer, SYNCML_TARGET, strlen( SYNCML_TARGET )))) { iobxHeaderFree(header); ObxBufFree(obxbuffer); OBXDBGERR(("[ERROR] ObxTransactionRecv() Error appending to header.\n")); rc = OBX_RC_ERR_TRANSPORT; } else if ( (rc=ObxHeaderSetByteSequenceValue( header, obxbuffer )) != OBX_RC_OK ) { ObxBufFree(obxbuffer); iobxHeaderFree(header); OBXDBGERR(("[ERROR] ObxTransactionRecv() unexpected rc calling ObxHeaderSetByteSequenceValue().\n")); } else if ( (rc=iobxObjectAddHeader( response, header, handle )) != OBX_RC_OK ) { ObxBufFree(obxbuffer); iobxHeaderFree(header); OBXDBGERR(("[ERROR] ObxTransactionRecv() unexpected rc calling iobxObjectAddHeader().\n")); } obxbuffer=NULL; header=NULL; if( rc !=OBX_RC_OK ) return rc; } done = TRUE; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -