📄 xptcomm.c
字号:
/*************************************************************************//* module: SyncML Communication Protocol selection module *//* file: src/xpt/all/xptcomm.c *//* target system: all *//* target OS: all *//*************************************************************************//* * Copyright Notice * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc., * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001). * All Rights Reserved. * Implementation of all or part of any Specification may require * licenses under third party intellectual property rights, * including without limitation, patent rights (such a third party * may or may not be a Supporter). The Sponsors of the Specification * are not responsible and shall not be held responsible in any * manner for identifying or failing to identify any or all such * third party intellectual property rights. * * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM, * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA, * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO., * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL, * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE. * * The above notice and this paragraph must be included on all copies * of this document that are made. * *//** * This file implements the SyncML transport protocol to invoke the * miscellaneous protocol drivers. A transport protocol implementation may be * either statically linked or dynamically linked. A dynamically-loaded * transport binding (e.g., a DLL on Windows, or a shared library on Unix) is * loaded by name when the xpt layer is initialized and thereafter is used just * like a statically-linked binding. */#include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++//#define TRACE_TO_STDOUT//#define TRACE#include <xpt.h>#include <xptTransport.h>#include <xptcomm.h>#include <utilities.h>#include <xptport.h>#ifdef __EPOC_OS__#include "xpt_globals_epoc.h"#endif/***********************************************************************//* The following define statements determine which protocols should be *//* statically linked with the xpt service. *//***********************************************************************//*#ifdef __PALM_OS__ // If no transports are explicitly called for, compile them all in #if !defined(INCLUDE_HTTP_STATICALLY) && !defined(INCLUDE_OBEX_STATICALLY) \ && !defined(INCLUDE_WSP_STATICALLY) #define INCLUDE_HTTP_STATICALLY #define INCLUDE_OBEX_STATICALLY// #define INCLUDE_WSP_STATICALLY #endif#else // luz %%%: for statical link, transport are static linked, too #ifdef LINK_TRANSPORT_STATICALLY #if !defined(INCLUDE_HTTP_STATICALLY) && !defined(INCLUDE_OBEX_STATICALLY) \ && !defined(INCLUDE_WSP_STATICALLY) #error No Transports included statically #endif #else #define INCLUDE_TRANSPORTS_DYNAMICALLY #endif#endif#define XPT_ID SML_ERR_A_XPT_ERROR // Starting trace message number*/// %%% luz#ifndef TRACE_TO_STDOUT #include <libutil.h> // For smlLibPrint() prototype#endif// This is information that could go in the XptProtocolInfo stucture, but// we put it in a different one to avoid defining all these internal fields// in a public header file.struct xptInternalTransportInfo { struct xptTransportDescription desc; int transportInstancesOpen; // Count of the number of service id // handles open for this transport.};#define TransportInstanceControlBlockId 0x07020811// An instance of this control block exists for each allocated// XptServiceIDPtr_t handle. In fact, such a handle is really a pointer to// one of these control blocks.struct TransportInstance { unsigned long controlBlockId; // Helps us to verify that a handle is // really a pointer to one of these. void *privateInstanceInfo; // Field of use to the transport implementation struct XptProtocolInfo *info; // Pointer to info about the protocol int communicationHandlesOpen; // Count of the number of communication // handles open under this transport // handle.};#define CommunicationInstanceControlBlockId 0x34243508#define CI_STATE_READY_FOR_EXCHANGE 1 // Connection just opened#define CI_STATE_EXPECTING_SET_DOC 2 // Client exchange just initiated#define CI_STATE_EXPECTING_GET_DOC 3 // Server exchange just initiated#define CI_STATE_SENDING 4 // Okay to send data#define CI_STATE_RECEIVING 5 // Okay to receive data#define CI_STATE_EXPECTING_END_EXCHANGE 6 // Sending/receiving finished// An instance of this control block exists for each allocated// XptCommunicationID_t handle. In fact, such a handle is really a pointer to// one of these control blocks.struct CommunicationInstance { unsigned long controlBlockId; // Helps us to verify that a handle is // really a pointer to one of these. void *privateCommunicationInfo; // Field of use to the transport implementation struct TransportInstance *transport; // Pointer to associated transport int state; // Communication state. We verify that // function calls are made only at times // they are valid so the transport // implementation doesn't have to. The // value here is one of CI_STATE_* int role; // One of XPT_REQUEST_SENDER or // XPT_REQUEST_RECEIVER, indicating whether // the communication instance is in client // or server mode. size_t bytesRemaining; // Number of bytes remaining to be sent, // if an outgoing document is currently // being sent, or the number of bytes // remaining to be read, if an incoming // document is currently being read, or // (size_t) -1 is the length is unknown.};/* Create a table containing initialization routines for statically-linked *//* transport bindings. */#ifdef INCLUDE_HTTP_STATICALLY Ret_t XPTAPI HTTP_initializeTransport(void);#endif#ifdef INCLUDE_OBEX_STATICALLY Ret_t XPTAPI obexInitializeTransport(void);#endif#ifdef INCLUDE_WSP_STATICALLY Ret_t XPTAPI wspInitializeTransport(void) WSP_SECTION;#endif// Ret_t XPTAPI initializeTestTransport(void);#ifndef INCLUDE_TRANSPORTS_DYNAMICALLYstatic const struct staticallyLinkedTransport { const char *name; Ret_t (XPTAPI *initFunction)(void);} staticallyLinkedTransports[] XPT_DATA_SECTION = {#ifdef INCLUDE_HTTP_STATICALLY {"HTTP", HTTP_initializeTransport},#endif#ifdef INCLUDE_OBEX_STATICALLY {"OBEX", obexInitializeTransport},#endif#ifdef INCLUDE_WSP_STATICALLY {"WSP", wspInitializeTransport},#endif {NULL, NULL} // Marker for end of address list};#endif#ifndef __EPOC_OS__static char const *noError XPT_DATA_SECTION = "No error message provided";static char const *noMemory XPT_DATA_SECTION = "Out of memory";static struct XptProtocolInfo *availableTransports XPT_DATA_SECTION = NULL;static int availableTransportCount XPT_DATA_SECTION = 0;static int transportIdCounter XPT_DATA_SECTION = 0;// On a multithreaded system, this information would be kept in a per-thread// control block.static XptErrorInformation_t lastError XPT_DATA_SECTION = {0, 0, "", "", 0, ""};#endif#ifdef __EPOC_OS__#define noError TheXptGlobalsEpoc()->noError#define noMemory TheXptGlobalsEpoc()->noMemory#define availableTransports TheXptGlobalsEpoc()->availableTransports#define availableTransportCount TheXptGlobalsEpoc()->availableTransportCount#define transportIdCounter TheXptGlobalsEpoc()->transportIdCounter#define lastError TheXptGlobalsEpoc()->lastError#define closeBindingTLS TheXptGlobalsEpoc()->closeBindingTLS#endif// Prototypes for internal functionsstatic Ret_t initializeTransports(void) XPT_SECTION;static struct TransportInstance *validateServiceId(XptServiceID_t id) XPT_SECTION;static struct CommunicationInstance *validateCommunicationId(XptCommunicationID_t id) XPT_SECTION;static Ret_t setLastErrorInfo(struct XptProtocolInfo *pi, const char *function, Ret_t rc) XPT_SECTION;// Initialize all statically-linked transports and dynamically load any// loadable modules implementing other transports.static Ret_t initializeTransports(void) {#ifndef __EPOC_OS__ static Ret_t initializationStatus XPT_DATA_SECTION = SML_ERR_OK;#endif#ifdef __EPOC_OS__#define initializationStatus TheXptGlobalsEpoc()->initializationStatus#endif#ifndef __EPOC_OS__#ifndef INCLUDE_TRANSPORTS_DYNAMICALLY const struct staticallyLinkedTransport *transport;#endif#endif Ret_t exitStatus = SML_ERR_OK; // See if a previous initialization attempt failed. if (initializationStatus != SML_ERR_OK) return initializationStatus; // We assume single threaded, and thus no competition calling initializeTransports() XPTDEBUG(("Initializing transports\n"));#ifndef INCLUDE_TRANSPORTS_DYNAMICALLY // First, initialize all the statically-linked transport implementations for (transport = staticallyLinkedTransports; transport->initFunction; ++transport) { Ret_t status; XPTDEBUG(("Initializing statically-linked transport %s\n", transport->name)); status = transport->initFunction(); if (status) { XPTDEBUG(("The initializeTransport() function of statically-linked transport %s failed with return status %d\n", transport->name, (int) status)); exitStatus = status; } }#endif#ifdef INCLUDE_TRANSPORTS_DYNAMICALLY /* Now initialize any transports that are to be dynamically loaded */ // First read the names of the dynamic library files (e.g., DLLs). This is // platform dependent, so call a platform dependent routine here. { char **libraries; libraries = getLibrariesToLoad(); if (libraries) { char **p; // Try to load and initialize each library for (p=libraries; *p; ++p) { char *libname = *p; Ret_t (XPTAPI *initFunction)(void); Ret_t status; int transportsRegisteredSoFar; void *handle = loadLibrary(libname); if (!handle) continue; // Error loading library initFunction = lookupLibrarySymbol("initializeTransport", 0, handle); if (!initFunction) { XPTDEBUG(("Dynamically-loaded transport library %s doesn't export an \"initializeTransport\" symbol\n", libname)); unloadLibrary(handle); continue; } transportsRegisteredSoFar = availableTransportCount; XPTDEBUG(("Initializing dynamically-loaded transport in library %s\n", libname)); status = initFunction(); if (status) { XPTDEBUG(("The initializeTransport() function of dynamically-loaded transport in library %s failed with return status %d\n", libname, (int) status)); exitStatus = status; } if (availableTransportCount == transportsRegisteredSoFar) { // The library registered no new transports. We don't need it. unloadLibrary(handle); } } releaseLibraryList(libraries); } }#endif if (!availableTransportCount) exitStatus = SML_ERR_A_XPT_NO_TRANSPORTS; initializationStatus = exitStatus; // Save for future return exitStatus;}static struct TransportInstance *validateServiceId(XptServiceID_t id) { struct TransportInstance *ti = (struct TransportInstance *) id; if (!ti || ti->controlBlockId != TransportInstanceControlBlockId) return NULL; return ti;}static struct CommunicationInstance *validateCommunicationId(XptCommunicationID_t id) { struct CommunicationInstance *ci = (struct CommunicationInstance *) id; if (!ci || ci->controlBlockId != CommunicationInstanceControlBlockId) return NULL; return ci;}static Ret_t setLastErrorInfo(struct XptProtocolInfo *pi, const char *function, Ret_t rc) { // On a multithreaded system, this information would be kept in a per-thread // control block. if (pi) { lastError.protocolId = pi->id; lastError.shortProtocolName = pi->shortName; } else { lastError.protocolId = 0; lastError.shortProtocolName = "none"; } // We don't need to make a copy of the name of the failing function, because // we know the caller will always provide a pointer to a static constant. lastError.failingFunction = function; lastError.status = rc; if (!lastError.errorMessage || !*lastError.errorMessage) { if (lastError.status == SML_ERR_A_XPT_MEMORY) lastError.errorMessage = noMemory; else lastError.errorMessage = noError; } return rc; // This makes it easier to use setLastErrorInfo() on a return statement}XPTEXP1 Ret_t XPTAPI XPTEXP2 xptRegisterTransport(const struct xptTransportDescription *pTransport) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -