📄 obexbinding.c
字号:
// Copy data to output buffer MEM_COPY( ocb->outgoing->cursor, dataBuffer, bufferLen ); ocb->outgoing->cursor += bufferLen; // move cursor to new position ocb->outgoing->length += bufferLen; // update new data length *bytesSent = bufferLen; // always send every byte return OBP_RC_OK;} // obpSendData()/** * FUNCTION: Called when xptSendData() is called by the application, after * sending the last byte of the document. * * Complete send processing for an outgoing document. * * IN: privateConnectionInfo, pointer to the transport binding's private * information about the connection instance. This is the same * value that was returned by the "openCommunication" function when * the connection instance was created. * * NOTES: * * The xpt interface layer counts the number of bytes the application * writes using the xptSendData() function. When the transport * implementation has written the last byte of the document, the xpt * interface layer calls this function in the transport implementation to * allow it to perform any desired completion processing. The length of * the document is known because it was specified by the application in the * xptSetDocumentInfo() call. * * Any error returned from sendComplete() is returned to the application * as the result value of the application's call to xptSendData(). * * Note that this function call does NOT correspond to an xptSendComplete() * function call available to the application. Instead, it is called * automatically by the xpt interface layer when the application has * successfully written the last byte of the document. */Ret_t XPTAPI obpSendComplete( void *privateConnectionInfo ) { ObpConnectionBlock *ocb = (ObpConnectionBlock *)privateConnectionInfo; ErrFatalDisplayIf( !ocb, "null pointer" ); if ( ocb->flags == XPT_REQUEST_SENDER ) { // send document, then wait for response obpSendRequest( ocb ); } // end if else if ( ocb->flags == XPT_REQUEST_RECEIVER ) { // send document, then immediately return obpSendResponse( ocb ); } // end else if return OBP_RC_OK;} // obpSendComplete()/** * FUNCTION: Called when xptSetDocumentInfo() is called * * Provide document information for an outgoing document. * * IN: privateConnectionInfo, pointer to the transport binding's private * information about the connection instance. This is the same * value that was returned by the "openCommunication" function when * the connection instance was created. * * pDoc, passed directly from the xptSetDocumentInfo() call. */Ret_t XPTAPI obpSetDocumentInfo( void *privateConnectionInfo, const XptCommunicationInfo_t *pDoc ) { ObpConnectionBlock *ocb = (ObpConnectionBlock *)privateConnectionInfo; ErrFatalDisplayIf( !ocb, "null pointer" ); // Create a CommunicationInfo block if one does not exist if ( !ocb->docInfo ) { ocb->docInfo = (XptCommunicationInfo_t *)MEM_ALLOC( sizeof( XptCommunicationInfo_t) ); ErrFatalDisplayIf( !ocb->docInfo, "memory allocation" ); ocb->docInfo->cbSize = sizeof( XptCommunicationInfo_t ); } // end if // Copy document information into newly-created ConnectionInfo block STR_COPY( ocb->docInfo->docName, pDoc->docName ); STR_COPY( ocb->docInfo->mimeType, pDoc->mimeType ); ocb->docInfo->cbLength = pDoc->cbLength; ErrFatalDisplayIf( !ocb->outgoing, "null pointer" ); MEM_FREE( ocb->outgoing->buf ); ocb->outgoing->buf = (unsigned char *)MEM_ALLOC( ocb->docInfo->cbLength ); ErrFatalDisplayIf( !ocb->outgoing->buf, "null pointer" ); ocb->outgoing->cursor = ocb->outgoing->buf; ocb->outgoing->length = ocb->docInfo->cbLength; return OBP_RC_OK;} // obpSetDocumentInfo()/** * FUNCTION: Called when xptGetDocumentInfo() is called * * Retrieve the document information associated with an incoming document. * * IN: privateConnectionInfo, pointer to the transport binding's private * information about the connection instance. This is the same * value that was returned by the "openCommunication" function when * the connection instance was created. * * pDoc, passed directly from the xptGetDocumentInfo() call. */Ret_t XPTAPI obpGetDocumentInfo( void *privateConnectionInfo, XptCommunicationInfo_t *pDoc ) { ObpConnectionBlock *ocb = (ObpConnectionBlock *)privateConnectionInfo; ErrFatalDisplayIf( !ocb, "null pointer" ); if ( ocb->flags == XPT_REQUEST_RECEIVER ) { // this caller is a "receiver" obpReceiveResponse( ocb ); // read the entire document } // end if // Copy document information into CommunicationInfo block STR_COPY( pDoc->docName, ocb->docInfo->docName ); STR_COPY( pDoc->mimeType, ocb->docInfo->mimeType ); pDoc->cbLength = ocb->docInfo->cbLength; return OBP_RC_OK;} // obpGetDocumentInfo()/************************************************************************* * * * Functions dealing with protocol initialization * * * *************************************************************************//** * FUNCTION: Called when initializeTransport() is called. * * Setup xptTransportDescription information and call xptRegisterTransport(). */static Ret_t obpRegisterTransport(void) { // MHB: Check for existence of SyncBmr and return an error if not present. struct xptTransportDescription xptBlock; // input to xptRegisterTransport() ObpTransportBlock *otb; // private transport information xptBlock.shortName = "OBEX/IR"; xptBlock.description = "OBEX transport over IR"; xptBlock.flags = XPT_CLIENT | XPT_SERVER; xptBlock.selectProtocol = obpSelectProtocol; xptBlock.deselectProtocol = obpDeselectProtocol; xptBlock.openCommunication = obpOpenCommunication; xptBlock.closeCommunication = obpCloseCommunication; xptBlock.beginExchange = obpBeginExchange; xptBlock.endExchange = obpEndExchange; xptBlock.receiveData = obpReceiveData; xptBlock.sendData = obpSendData; xptBlock.sendComplete = obpSendComplete; xptBlock.setDocumentInfo = obpSetDocumentInfo; xptBlock.getDocumentInfo = obpGetDocumentInfo; // MHB: Currently, there is no "DeregisterTransport()" // MHB: function where this block can be released... otb = (ObpTransportBlock *)MEM_ALLOC( sizeof( ObpTransportBlock ) ); ErrFatalDisplayIf( !otb, "memory allocation" ); xptBlock.privateTransportInfo = otb; // MHB: Any info required here? return xptRegisterTransport( &xptBlock ); // call XPT layer to register} // obpRegisterTransport()/** * FUNCTION: Called to deregister the transport. * * NOTE: This function is not part of the existing specification * and, therefore, is not called from anywhere. */static Ret_t obpDeregisterTransport( struct xptTransportDescription *xptBlock ) { MEM_FREE( xptBlock->privateTransportInfo ); // free up the transport block return OBP_RC_OK;} // obpDeregisterTransport()/************************************************************************* * * * Functions used to communicate with the SyncBmr application * * * *************************************************************************//** * FUNCTION: Called by obpSendComplete to tansmit request. * This function blocks until a response has been * been received. * * IN: privateConnectionInfo, pointer to the transport binding's private * information about the connection instance. This is the same * value that was returned by the "openCommunication" function when * the connection instance was created. */static Ret_t obpSendRequest( void *privateConnectionInfo ) { ObpConnectionBlock *ocb = (ObpConnectionBlock *)privateConnectionInfo; SyncBmrRequest_t *reqP = NULL; SyncBmrResponse_t *respP = NULL; obpProcessRequest( ocb, &reqP ); // validate and build request sbuSendRequest( &reqP, &respP ); // send request and wait for response obpProcessResponse( ocb, respP ); // validate and build response return OBP_RC_OK;} // obpSendRequest()/** * FUNCTION: Called by obpSendComplete to tansmit request. * This function does not wait for a response. * * IN: privateConnectionInfo, pointer to the transport binding's private * information about the connection instance. This is the same * value that was returned by the "openCommunication" function when * the connection instance was created. */static Ret_t obpSendResponse( void *privateConnectionInfo ) { ObpConnectionBlock *ocb = (ObpConnectionBlock *)privateConnectionInfo; SyncBmrRequest_t *reqP = NULL; obpProcessRequest( ocb, &reqP ); // validate and build request sbuSendResponse( &reqP ); // send request and do not wait for response return OBP_RC_OK;} // obpSendResponse()/** * FUNCTION: Called by obpGetDocumentInfo to receive request. * * IN: privateConnectionInfo, pointer to the transport binding's private * information about the connection instance. This is the same * value that was returned by the "openCommunication" function when * the connection instance was created. */static Ret_t obpReceiveResponse( void *privateConnectionInfo ) { ObpConnectionBlock *ocb = (ObpConnectionBlock *)privateConnectionInfo; SyncBmrResponse_t *respP = NULL; sbuReceiveResponse( &respP ); // wait for an in coming response obpProcessResponse( ocb, respP ); // validate and build response return OBP_RC_OK;} // obpReceiveRequest()/************************************************************************* * * * Internal Functions * * * *************************************************************************//** * FUNCTION: Called to obtain an ObpBuffer block. */static Ret_t obpObtainBuffer( ObpBuffer *ob, size_t length ) { ErrFatalDisplayIf( !ob, "null pointer" ); MEM_FREE( ob->buf ); // free up existing buffer ob->buf = (unsigned char *)MEM_ALLOC( length ); // allocate actually data buffer ErrFatalDisplayIf( !ob->buf, "memory allocation" ); ob->cursor = ob->buf; // initialize cursor to start of data buffer ob->length = MemPtrSize( ob->buf ); // set the data buffer length return OBP_RC_OK;} // obpObtainBuffer()/** * FUNCTION: Called by obpSendRequest and obpSendResponse. * Common code to provide validation and assembly of request. */static Ret_t obpProcessRequest( ObpConnectionBlock *ocb, SyncBmrRequest_t **reqP ) { ErrFatalDisplayIf( !ocb, "null pointer" ); ErrFatalDisplayIf( !ocb->outgoing, "null pointer" ); ErrFatalDisplayIf( !ocb->docInfo, "null pointer" ); *reqP = (SyncBmrResponse_t *)MEM_ALLOC( sizeof( SyncBmrRequest_t ) ); ErrFatalDisplayIf( !*reqP, "memory allocation" ); (*reqP)->targetID = 0x7FFFFFFF; // dummy id - not used (*reqP)->data = ocb->outgoing->buf; // point to outgoing data buffer (*reqP)->length = ocb->docInfo->cbLength; // total number of bytes for all objects STR_COPY( (*reqP)->name, ocb->docInfo->docName ); // filename and extension of data STR_COPY( (*reqP)->type, ocb->docInfo->mimeType ); // MIME type of data return OBP_RC_OK;} // obpProcessRequest()/** * FUNCTION: Called by obpSendRequest and obpReceiveResponse. * Common code to provide validation and assembly of response. */static Ret_t obpProcessResponse( ObpConnectionBlock *ocb, SyncBmrResponse_t *respP ) { ErrFatalDisplayIf( !ocb, "null pointer" ); ErrFatalDisplayIf( !ocb->docInfo, "null pointer" ); ErrFatalDisplayIf( !ocb->incoming, "null pointer" ); ErrFatalDisplayIf( !respP, "receive error" ); ErrFatalDisplayIf( !respP->data, "null pointer" ); STR_COPY( ocb->docInfo->docName, respP->name ); // copy name from response STR_COPY( ocb->docInfo->mimeType, respP->type ); // copy type from response ocb->docInfo->cbLength = respP->length; // copy length from response MEM_FREE( ocb->incoming->buf ); // free up existing buffer ocb->incoming->buf = respP->data; // point to new data buffer ocb->incoming->cursor = respP->data; // update cursor ocb->incoming->length = respP->length; // copy length return OBP_RC_OK;} // obpProcessResponse()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -