📄 object.c
字号:
** We're using setpath. SetPath also has meta data, although it's of ** a diffrent format and length than the connect meta. */ prefixSize = 5; } else { /* ** No meta data... just one byte of op code followed by two bytes of length. */ prefixSize = 3; } return prefixSize;}/*** The current object is sent using the transport associated with the passed ObxHandle.** This method will send any leading information, then iterate through the headers sending** each of them.** Note, this function will send what it can, it's up to the caller to deal with partial** sends (by reinvoking after receiving a continue response from the peer).*/ObxRc iobxObjectSendObject( ObxObject *object, ObxHandle *handle ) { ObxRc rc = OBX_RC_OK; int nonBodyHeaderSize = 0; int bodyHeaderSize = 0; int prefixSize = 0; int thisHeaderSize = 0; short sendLength = 0; short nboLength = 0; int wrote = 0; ObxIterator *iterator = NULL; ObxHeader *header = NULL; short done = FALSE; short fsmState = OBJECT_FSM_CHECK_PRECONDITONS; OBXDBGFLOW(("iobxObjectSendObject() entry, object=0x%08x\thandle=0x%08x\n", object, handle)); while ( rc == OBX_RC_OK && !done ) { switch ( fsmState ) { /* ** Ensure plist is ok and object is in the correct state. */ case OBJECT_FSM_CHECK_PRECONDITONS: OBXDBGINFO(("iobxObjectSendObject() check preconditions\n")); if ( object && handle ) { if ( object->state == STATE_ERROR ) { OBXDBGERR(("[ERROR] iobxObjectSendObject() object is in STATE_ERROR, inappropriate call.\n")); rc = OBX_RC_ERR_INAPPROPRIATE; } } else { OBXDBGERR(("[ERROR] iobxObjectSendObject() bad plist on call.\n")); rc = OBX_RC_ERR_BADPLIST; } fsmState = OBJECT_FSM_DETERMINE_LENGTHS; break; /* ** Determine the prefix and non-body header lengths. ** Ensure that the non-body headers (and the prefix data) will fit within the ** maximum packet length. */ case OBJECT_FSM_DETERMINE_LENGTHS: OBXDBGINFO(("iobxObjectSendObject() determine lengths\n")); prefixSize = iobxObjectPrefixSize( object, handle ); /* ** Determine size of body headers and non-body headers. */ nonBodyHeaderSize = 0; bodyHeaderSize = 0; if ( (iterator = iobxListGetIterator( object->headers )) ) { iterator = iobxIteratorReset( iterator ); while ( iobxIteratorHasNext( iterator ) ) { if ( (header = (ObxHeader *)iobxIteratorNext( iterator )) ) { if ( header->state != STATE_SENT ) { if ( header->identifier == OBEX_HEADER_BODY || header->identifier == OBEX_HEADER_BODY_END ) { bodyHeaderSize += iobxHeaderSize( header ); } else { nonBodyHeaderSize += iobxHeaderSize( header ); } } } } /* ** Will all non-body headers fit within this single packet? */ if ( (prefixSize + nonBodyHeaderSize) > handle->maxPacketLen ) { OBXDBGERR(("[ERROR] iobxObjectSendObject() headers appear to exceed maximum packet length of %d.\n", handle->maxPacketLen)); rc = OBX_RC_ERR_OBJ_BAD_HEADER; } } else { OBXDBGERR(("[ERROR] iobxObjectSendObject() unable to obtain header list iterator.\n")); rc = OBX_RC_ERR_NOTINITIALIZED; } fsmState = OBJECT_FSM_CHECK_FOR_FINAL; break; /* ** Set the final bit, if required. Also establish the actual send length and ** set the object state as required. */ case OBJECT_FSM_CHECK_FOR_FINAL: OBXDBGINFO(("iobxObjectSendObject() check for final\n")); /* ** We make allowences for Win32 here... */ if ( nonBodyHeaderSize ) { /* ** Non-body headers exist and so do ** Clear final bit, must send body seperately. ** We bow to Win32 here... spec says that it's allowed, win32 won't allow it... chumps. */ if ( bodyHeaderSize ) { /* ** Body headers will be sent on a susuquent call. *///Every response must have final bit set.// object->cmd &= (~OBEX_CMD_FINAL); object->state = STATE_SENDING; } else { /* ** No body headers, we're done unless we're in a stream. *///The last response of Get command have response code of 0xA0, i.e. OBEX_RSP_SUCCESS | OBEX_CMD_FINAL. if(handle->lastRecv == (OBEX_CMD_GET | OBEX_CMD_FINAL) ) { object->cmd = ( object->stream ?// (object->cmd & ~OBEX_CMD_FINAL) : /* Stream, clear final, more to come. */// (object->cmd | OBEX_CMD_FINAL) ); /* Non Stream, set final */ object->cmd : /* Stream */ (OBEX_RSP_SUCCESS | OBEX_CMD_FINAL) ); /* Non Stream */ object->state = STATE_SENT; } else { object->cmd = ( object->stream ? (object->cmd & ~OBEX_CMD_FINAL) : /* Stream, clear final, more to come. */ (object->cmd | OBEX_CMD_FINAL) ); /* Non Stream, set final */ object->state = STATE_SENT; } } sendLength = prefixSize + nonBodyHeaderSize; } else if ( prefixSize + bodyHeaderSize <= handle->maxPacketLen ) { /* ** Existing body content will fit in a single send. ** Set final bit, if not in a stream. A stream implies that more ** data will be sent at a later date... but that will be a seperate ** object... in either case, this one's SENT. *///The last response of Get command have response code of 0xA0, i.e. OBEX_RSP_SUCCESS | OBEX_CMD_FINAL. if(handle->lastRecv == (OBEX_CMD_GET | OBEX_CMD_FINAL) ) { object->cmd = ( object->stream ?// (object->cmd & ~OBEX_CMD_FINAL) : /* Stream, clear final, more to come. */// (object->cmd | OBEX_CMD_FINAL) ); /* Non Stream, set final */ object->cmd : /* Stream */ (OBEX_RSP_SUCCESS | OBEX_CMD_FINAL) ); /* Non Stream */ object->state = STATE_SENT; } else { object->cmd = ( object->stream ? (object->cmd & ~OBEX_CMD_FINAL) : /* Stream, clear final, more to come. */ (object->cmd | OBEX_CMD_FINAL) ); /* Non Stream, set final */ object->state = STATE_SENT; } sendLength = prefixSize + bodyHeaderSize; } else { /* ** We have body that will require multiple sends. ** Clear final bit. *///Every response of Get command must have final bit set.// object->cmd &= (~OBEX_CMD_FINAL); object->state = STATE_SENDING; sendLength = handle->maxPacketLen; } fsmState = OBJECT_FSM_SEND_OPCODE; break; /* ** Send the opcode. */ case OBJECT_FSM_SEND_OPCODE: OBXDBGINFO(("iobxObjectSendObject() *** outbound *** opcode = %02x\n", object->cmd)); rc = handle->transport->send( &handle->connectionId, &object->cmd, 1, &wrote, FALSE ); handle->lastSent = object->cmd; fsmState = OBJECT_FSM_SEND_LENGTH; break; /* ** Send the two byte length. */ case OBJECT_FSM_SEND_LENGTH: OBXDBGINFO(("iobxObjectSendObject() sending length, %d\n", sendLength)); nboLength = htons( sendLength ); rc = handle->transport->send( &handle->connectionId, &nboLength, sizeof( nboLength ), &wrote, FALSE ); /* ** Where to next? */ if ( handle->lastRecv == OBEX_CMD_CONNECT /* Connect response */ || object->cmd == OBEX_CMD_CONNECT /* Connect anew */ || object->cmd == OBEX_CMD_SETPATH ) { /* SetPath anew */ /* ** These situations (Connect response, connect, setpath) all ** have meta data send requirements. */ fsmState = OBJECT_FSM_SEND_META; } else if ( nonBodyHeaderSize ) { /* ** If non body headers exist, we must send them. */ fsmState = OBJECT_FSM_SEND_NONBODY; } else { /* ** No non-body headers, we're free to send body headers. */ fsmState = OBJECT_FSM_SEND_BODY; } /* ** We've sent the opcode and length, reduce remaining send amount. */ sendLength -= 3; break; /* ** Send the meta data associated with this object (if appropriate). */ case OBJECT_FSM_SEND_META: OBXDBGINFO(("iobxObjectSendObject() sending meta\n")); if ( handle->lastRecv == OBEX_CMD_CONNECT || object->cmd == OBEX_CMD_CONNECT ) { /* ** We're either connecting, or responding to a connect in this case. */ rc = handle->transport->send( &handle->connectionId, object->meta.connectMeta, sizeof(object->meta.connectMeta), &wrote, FALSE ); sendLength -= sizeof(object->meta.connectMeta); OBXDBGINFO(("iobxObjectSendObject() sent meta for Connect / Connect response.\n")); } else if ( (object->cmd & ~OBEX_CMD_FINAL) == OBEX_CMD_SETPATH ) { rc = handle->transport->send( &handle->connectionId, object->meta.setPathMeta, sizeof(object->meta.setPathMeta), &wrote, FALSE ); sendLength -= sizeof(object->meta.setPathMeta); OBXDBGINFO(("iobxObjectSendObject() sent meta for SetPath.\n")); } else { OBXDBGERR(("[ERROR] iobxObjectSendObject() FSM attempts to send meta data when it's inappropriate.\n")); rc = OBX_RC_ERR_UNSPECIFIED; } if ( nonBodyHeaderSize ) { /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -