Home | History | Annotate | Download | only in src
      1 /*************************************************************************/
      2 /* module:          SyncML Command Dispatcher                            */
      3 /*                                                                       */
      4 /* file:            mgrcmddispatcher.c                                   */
      5 /* target system:   all                                                  */
      6 /* target OS:       all                                                  */
      7 /*                                                                       */
      8 /* Description:                                                          */
      9 /* Core module for dispatching parsed commands and invoking callback     */
     10 /* functions of the application                                          */
     11 /*************************************************************************/
     12 
     13 
     14 /*
     15  * Copyright Notice
     16  * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication
     17  * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc.,
     18  * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001).
     19  * All Rights Reserved.
     20  * Implementation of all or part of any Specification may require
     21  * licenses under third party intellectual property rights,
     22  * including without limitation, patent rights (such a third party
     23  * may or may not be a Supporter). The Sponsors of the Specification
     24  * are not responsible and shall not be held responsible in any
     25  * manner for identifying or failing to identify any or all such
     26  * third party intellectual property rights.
     27  *
     28  * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED
     29  * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM,
     30  * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA,
     31  * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML
     32  * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
     33  * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
     34  * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
     35  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
     36  * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO.,
     37  * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY
     38  * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF
     39  * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF
     40  * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL,
     41  * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH
     42  * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED
     43  * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE.
     44  *
     45  * The above notice and this paragraph must be included on all copies
     46  * of this document that are made.
     47  *
     48  */
     49 
     50 
     51 
     52 
     53 /*************************************************************************
     54  *  Definitions
     55  *************************************************************************/
     56 
     57 
     58 #include <define.h>
     59 /* Include Headers */
     60 #include <smldef.h>
     61 #include <smldtd.h>
     62 #include <smlerr.h>
     63 
     64 #include "libmem.h"
     65 #include "xltdec.h"
     66 #include "mgr.h"
     67 
     68 
     69 
     70 /* Used external functions */
     71 #ifndef __SML_LITE__  /* these API calls are NOT included in the Toolkit lite version */
     72   extern Ret_t addInfo(InstanceInfoPtr_t pInfo);
     73   extern InstanceInfoPtr_t findInfo(InstanceID_t id);
     74   extern Ret_t removeInfo(InstanceID_t id);
     75 #endif
     76 Ret_t smlLockReadBuffer(InstanceID_t id, MemPtr_t *pReadPosition, MemSize_t *usedSize);
     77 Ret_t smlUnlockReadBuffer(InstanceID_t id, MemSize_t processedBytes);
     78 
     79 /* Prototypes of exported SyncML API functions */
     80 extern Ret_t smlProcessData(InstanceID_t id, SmlProcessMode_t mode);
     81 
     82 /* Private function prototypes */
     83 static Ret_t mgrProcessNextCommand(InstanceID_t id, InstanceInfoPtr_t pInstanceInfo);
     84 static Ret_t mgrProcessStartMessage(InstanceID_t id, InstanceInfoPtr_t pInstanceInfo);
     85 Ret_t mgrResetWorkspace (InstanceID_t id);
     86 
     87 
     88 
     89 /*************************************************************************
     90  *  Exported SyncML API functions
     91  *************************************************************************/
     92 
     93 
     94 
     95 
     96 /**
     97  * FUNCTION:  smlProcessData
     98  *
     99  * Start the parsing of the XML code in the workspace buffer,
    100  * dispatches the interpreted command and calls the corresponding callback
    101  * functions provided by the application.
    102  *
    103  * IN:              InstanceID_t
    104  *                  The SyncML instance id is used for referencing the
    105  *                  workspace buffer from the XML content is parsed
    106  *
    107  * IN:              ProcessMode_t
    108  *                  Mode of processing, Defines, if only the first or next
    109  *                  XML command is parsed or if all commands are processed
    110  *                  subsequently until the end of the entire workspace buffer
    111  *                  is reached. The NEXT_COMMAND flag defines the blocking mode,
    112  *                  the ALL_COMMANDS tag defines the non-blocking mode.
    113  *
    114  * RETURN:          Ret_t
    115  */
    116 SML_API Ret_t smlProcessData(InstanceID_t id, SmlProcessMode_t mode)
    117 {
    118   /* --- Definitions --- */
    119   InstanceInfoPtr_t   pInstanceInfo;               // state info for the given instanceID
    120   Ret_t               rc;                          // Temporary return code saver
    121 
    122 
    123   #ifdef NOWSM
    124     pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
    125   #else
    126     /* --- Find that instance --- */
    127     #ifdef __SML_LITE__  /* Only ONE instance is supported in the Toolkit lite version */
    128       pInstanceInfo = mgrGetInstanceListAnchor();
    129     #else
    130       pInstanceInfo = (InstanceInfoPtr_t) findInfo(id);
    131     #endif
    132   #endif
    133 
    134   if (pInstanceInfo==NULL) return SML_ERR_MGR_INVALID_INSTANCE_INFO;
    135 
    136   /* --- Are callback functions defined? --- */
    137   if (pInstanceInfo->callbacks==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    138 
    139   /* --- Is parsing already in progress? --- */
    140   if (pInstanceInfo->decoderState==NULL)
    141     {
    142     /* No! Parse the Message header section first */
    143     rc = mgrProcessStartMessage(id, pInstanceInfo);
    144 
    145     if (rc!=SML_ERR_OK) return rc;
    146     }
    147 
    148 
    149   /* --- Parse now the Message body section! --- */
    150   do {
    151     rc=mgrProcessNextCommand(id, pInstanceInfo);
    152   } while (
    153     // keep processing while no error occurs,
    154     // AND the document end was not reached (decoderState has been invalidated),
    155     // AND the ALL_COMMAND mode is used
    156     (rc==SML_ERR_OK)
    157     &&((pInstanceInfo->decoderState)!=NULL)
    158     &&(mode==SML_ALL_COMMANDS)
    159   );
    160 
    161   if (rc != SML_ERR_OK) {
    162     // abort, unlock the buffer again without changing it's current position
    163     smlUnlockReadBuffer(id, (MemSize_t)0);
    164     // Reset the decoder module (free the decoding object)
    165     xltDecReset(pInstanceInfo->decoderState);
    166     // this decoding job is over! reset Instance Info pointer
    167     pInstanceInfo->decoderState=NULL;
    168     // Reset the Workspace (the remaining unparsed document fragment will be lost)
    169     mgrResetWorkspace(id);
    170   }
    171 
    172   return rc;
    173 }
    174 
    175 
    176 /*************************************************************************
    177  *  Private Functions
    178  *************************************************************************/
    179 
    180 
    181 
    182 
    183 /**
    184  * FUNCTION:
    185  * Parses the header information at the beginning of an SyncML document.
    186  *
    187  * IN:              InstanceID
    188  *                  current InstanceID to pass to callback functions
    189  *
    190  * IN/OUT:          InstanceInfo
    191  *                  state information of the given InstanceID (decoder state will be changed)
    192  *
    193  * RETURN:          Return value of the Parser,
    194  *                  SML_ERR_OK if next command was handled successfully
    195  */
    196 static Ret_t mgrProcessStartMessage(InstanceID_t id, InstanceInfoPtr_t pInstanceInfo)
    197 {
    198 
    199 
    200   /* --- Definitions --- */
    201   Ret_t               rc;                          // Temporary return code saver
    202   SmlSyncHdrPtr_t     pContent=NULL;               // data of the command to process
    203   MemPtr_t            pCurrentReadPosition ;        // current Position from which is read
    204   MemPtr_t            pBeginPosition;              // saves the first position which has been reading
    205   MemSize_t           usedSize ;                    // size of used memory to be read
    206 
    207 
    208   /* --- Get Read Access to the workspace --- */
    209   rc = smlLockReadBuffer(id, &pCurrentReadPosition, &usedSize);
    210 
    211   if (rc!=SML_ERR_OK) {
    212     // abort, unlock the buffer again without changing it's current position
    213     smlUnlockReadBuffer(id, (MemSize_t)0);
    214     return rc;
    215     }
    216 
    217   // Remember the position we have started reading
    218   pBeginPosition=pCurrentReadPosition;
    219 
    220   /* --- Start new decoding sequence and pass returned decoder status structure to instanceInfo --- */
    221   rc = xltDecInit(pInstanceInfo->instanceOptions->encoding,
    222                   pCurrentReadPosition+usedSize-1, &pCurrentReadPosition,
    223                   (XltDecoderPtr_t *)&(pInstanceInfo->decoderState), &pContent);
    224 
    225   if (rc!=SML_ERR_OK) {
    226     // abort, unlock the buffer again without changing it's current position
    227     smlUnlockReadBuffer(id, (MemSize_t)0);
    228   	// Reset the decoder module (free the decoding object)
    229 	  xltDecReset(pInstanceInfo->decoderState);
    230     // this decoding job is over! reset Instance Info pointer
    231     pInstanceInfo->decoderState=NULL;
    232     // Reset the Workspace (the remaining unparsed document fragment will be lost)
    233 	  mgrResetWorkspace(id);
    234     return rc;
    235   }
    236 
    237   /* --- End Read Access to the workspace --- */
    238   rc = smlUnlockReadBuffer(id, (MemSize_t)pCurrentReadPosition-(MemSize_t)pBeginPosition);
    239   if (rc!=SML_ERR_OK) return rc;
    240 
    241   /* --- Perform callback to handle the beginning of a new message --- */
    242   if (pInstanceInfo->callbacks->startMessageFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    243   rc=pInstanceInfo->callbacks->startMessageFunc(id, pInstanceInfo->userData, pContent);
    244 
    245   if (rc != SML_ERR_OK)
    246   {
    247     // abort, unlock the buffer again without changing it's current position
    248     smlUnlockReadBuffer(id, (MemSize_t)0);
    249     // Reset the decoder module (free the decoding object)
    250     xltDecReset(pInstanceInfo->decoderState);
    251     // this decoding job is over! reset Instance Info pointer
    252     pInstanceInfo->decoderState=NULL;
    253  	  // Reset the Workspace (the remaining unparsed document fragment will be lost)
    254  	  mgrResetWorkspace(id);
    255   }
    256 
    257   return rc;
    258 }
    259 
    260 
    261 
    262 /**
    263  * FUNCTION:
    264  * Parses the next Sync Command in the sync document.
    265  *
    266  * IN:              InstanceID
    267  *                  current InstanceID to pass to callback functions
    268  *
    269  * IN:              InstanceInfo
    270  *                  state information of the given InstanceID
    271  *
    272  * RETURN:          Return value of the Parser of the called application callback,
    273  *                  SML_ERR_OK if next command was handled successfully
    274  */
    275 static Ret_t mgrProcessNextCommand(InstanceID_t id, InstanceInfoPtr_t pInstanceInfo)
    276 {
    277 
    278   /* --- Definitions --- */
    279   Ret_t               rc;                          // Temporary return code saver
    280   SmlProtoElement_t   cmdType;                     // ID of the command to process
    281   VoidPtr_t           pContent=NULL;               // data of the command to process
    282   MemPtr_t            pCurrentReadPosition;        // current Position from which is read
    283   MemPtr_t            pBeginPosition;              // saves the first position which has been reading
    284   MemSize_t           usedSize;                    // size of used memory to be read
    285   Boolean_t           final;                       // flag indicates last message within a package
    286 
    287 
    288   /* --- Get Read Access to the workspace --- */
    289   rc = smlLockReadBuffer(id, &pCurrentReadPosition, &usedSize);
    290 
    291   if (rc!=SML_ERR_OK) {
    292     // abort, unlock the buffer again without changing it's current position
    293     smlUnlockReadBuffer(id, (MemSize_t)0);
    294     return rc;
    295     }
    296 
    297   // Remember the position we have started reading
    298   pBeginPosition=pCurrentReadPosition;
    299 
    300 
    301   /* --- Parse next Command --- */
    302   rc = xltDecNext(pInstanceInfo->decoderState, pCurrentReadPosition+usedSize, &pCurrentReadPosition, &cmdType, &pContent);
    303 
    304   if (rc!=SML_ERR_OK) {
    305     // abort, unlock the buffer again without changing it's current position
    306     smlUnlockReadBuffer(id, (MemSize_t)0);
    307   	// Reset the decoder module (free the decoding object)
    308 	  xltDecReset(pInstanceInfo->decoderState);
    309     // this decoding job is over! reset Instance Info pointer
    310     pInstanceInfo->decoderState=NULL;
    311   	// Reset the Workspace (the remaining unparsed document fragment will be lost)
    312 	  mgrResetWorkspace(id);
    313     return rc;
    314   }
    315 
    316   /* --- End Read Access to the workspace --- */
    317   rc = smlUnlockReadBuffer(id, (MemSize_t)pCurrentReadPosition-(MemSize_t)pBeginPosition);
    318 
    319   if (rc!=SML_ERR_OK) {
    320     // abort, unlock the buffer again without changing it's current position
    321     smlUnlockReadBuffer(id, (MemSize_t)0);
    322     return rc;
    323   }
    324 
    325   /* --- Did we reach end of synchronization document? --- */
    326   if (((XltDecoderPtr_t)(pInstanceInfo->decoderState))->finished!=0) {
    327     final = ((XltDecoderPtr_t)(pInstanceInfo->decoderState))->final; // flag is returned to appl. with callback
    328     rc=xltDecTerminate(pInstanceInfo->decoderState);
    329 
    330     if (rc!=SML_ERR_OK)
    331 	  {
    332       // abort, unlock the buffer again without changing it's current position
    333       smlUnlockReadBuffer(id, (MemSize_t)0);
    334       // Reset the decoder module (free the decoding object)
    335 	    xltDecReset(pInstanceInfo->decoderState);
    336       // this decoding job is over! reset Instance Info pointer
    337       pInstanceInfo->decoderState=NULL;
    338 	    // Reset the Workspace (the remaining unparsed document fragment will be lost)
    339     	mgrResetWorkspace(id);
    340       return rc;
    341 	  }
    342 
    343     // this decoding job is over! reset Instance Info pointer
    344 	  // (the decoding object itself has been freed by the decoder)
    345     pInstanceInfo->decoderState=NULL;
    346 
    347     // Call the callback for handling an message ending
    348     if (pInstanceInfo->callbacks->endMessageFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    349 
    350     rc=pInstanceInfo->callbacks->endMessageFunc(id, pInstanceInfo->userData, final);
    351     return rc;
    352   }
    353 
    354   /* --- Dispatch parsed command (and call the applications command handler function)--- */
    355   switch (cmdType)
    356   {
    357     /* Handle ADD Command */
    358     case SML_PE_ADD:
    359       if (pInstanceInfo->callbacks->addCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    360       return pInstanceInfo->callbacks->addCmdFunc (id, pInstanceInfo->userData, pContent);
    361       break;
    362 
    363     /* Handle ALERT Command */
    364     case SML_PE_ALERT:
    365       if (pInstanceInfo->callbacks->alertCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    366       return pInstanceInfo->callbacks->alertCmdFunc (id, pInstanceInfo->userData, pContent);
    367       break;
    368 
    369     /* Handle DELETE Command */
    370     case SML_PE_DELETE:
    371       if (pInstanceInfo->callbacks->deleteCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    372       return pInstanceInfo->callbacks->deleteCmdFunc (id, pInstanceInfo->userData, pContent);
    373       break;
    374 
    375     /* Handle PUT Command */
    376     case SML_PE_PUT:
    377       if (pInstanceInfo->callbacks->putCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    378       return pInstanceInfo->callbacks->putCmdFunc (id, pInstanceInfo->userData, pContent);
    379       break;
    380 
    381     /* Handle GET Command */
    382     case SML_PE_GET:
    383       if (pInstanceInfo->callbacks->getCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    384       return pInstanceInfo->callbacks->getCmdFunc (id, pInstanceInfo->userData, pContent);
    385       break;
    386 
    387     #ifdef MAP_RECEIVE
    388     /* Handle MAP Command */
    389     case SML_PE_MAP:
    390       if (pInstanceInfo->callbacks->mapCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    391       return pInstanceInfo->callbacks->mapCmdFunc (id, pInstanceInfo->userData, pContent);
    392       break;
    393     #endif
    394 
    395     #ifdef RESULT_RECEIVE
    396     /* Handle RESULTS Command */
    397     case SML_PE_RESULTS:
    398       if (pInstanceInfo->callbacks->resultsCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    399       return pInstanceInfo->callbacks->resultsCmdFunc (id, pInstanceInfo->userData, pContent);
    400       break;
    401     #endif
    402 
    403     /* Handle STATUS Command */
    404     case SML_PE_STATUS:
    405       if (pInstanceInfo->callbacks->statusCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    406       return pInstanceInfo->callbacks->statusCmdFunc (id, pInstanceInfo->userData, pContent);
    407       break;
    408 
    409     /* Handle START SYNC Command */
    410     case SML_PE_SYNC_START:
    411       if (pInstanceInfo->callbacks->startSyncFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    412       return pInstanceInfo->callbacks->startSyncFunc (id, pInstanceInfo->userData, pContent);
    413       break;
    414 
    415     /* Handle END SYNC Command */
    416     case SML_PE_SYNC_END:
    417       if (pInstanceInfo->callbacks->endSyncFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    418       return pInstanceInfo->callbacks->endSyncFunc (id, pInstanceInfo->userData);
    419       break;
    420 
    421     /* Handle REPLACE Command */
    422     case SML_PE_REPLACE:
    423       if (pInstanceInfo->callbacks->replaceCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    424       return pInstanceInfo->callbacks->replaceCmdFunc (id, pInstanceInfo->userData, pContent);
    425       break;
    426 
    427     /* Handle Final Flag */
    428     case SML_PE_FINAL:
    429       // if a FINAL Flag appears do nothing
    430       return SML_ERR_OK;
    431       break;
    432 
    433 
    434     #ifdef SEARCH_RECEIVE  /* these API calls are NOT included in the Toolkit lite version */
    435 
    436     /* Handle SEARCH Command */
    437     case SML_PE_SEARCH:
    438       if (pInstanceInfo->callbacks->searchCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    439       return pInstanceInfo->callbacks->searchCmdFunc (id, pInstanceInfo->userData, pContent);
    440       break;
    441     #endif
    442 
    443     #ifdef SEQUENCE_RECEIVE
    444     /* Handle START SEQUENCE Command */
    445     case SML_PE_SEQUENCE_START:
    446       if (pInstanceInfo->callbacks->startSequenceFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    447       return pInstanceInfo->callbacks->startSequenceFunc (id, pInstanceInfo->userData, pContent);
    448       break;
    449 
    450     /* Handle END SEQUENCE Command */
    451     case SML_PE_SEQUENCE_END:
    452       if (pInstanceInfo->callbacks->endSequenceFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    453       return pInstanceInfo->callbacks->endSequenceFunc (id, pInstanceInfo->userData);
    454       break;
    455     #endif
    456 
    457     #ifdef ATOMIC_RECEIVE
    458 
    459     /* Handle START ATOMIC Command */
    460     case SML_PE_ATOMIC_START:
    461       if (pInstanceInfo->callbacks->startAtomicFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    462       return pInstanceInfo->callbacks->startAtomicFunc (id, pInstanceInfo->userData, pContent);
    463       break;
    464 
    465     /* Handle END ATOMIC Command */
    466     case SML_PE_ATOMIC_END:
    467       if (pInstanceInfo->callbacks->endAtomicFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    468       return pInstanceInfo->callbacks->endAtomicFunc (id, pInstanceInfo->userData);
    469       break;
    470     #endif
    471 
    472     #ifdef COPY_RECEIVE
    473 
    474     /* Handle COPY Command */
    475     case SML_PE_COPY:
    476       if (pInstanceInfo->callbacks->copyCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    477       return pInstanceInfo->callbacks->copyCmdFunc (id, pInstanceInfo->userData, pContent);
    478       break;
    479     #endif
    480 
    481     #ifdef EXEC_RECEIVE
    482 
    483     /* Handle EXEC Command */
    484     case SML_PE_EXEC:
    485       if (pInstanceInfo->callbacks->execCmdFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    486       return pInstanceInfo->callbacks->execCmdFunc (id, pInstanceInfo->userData, pContent);
    487       break;
    488 
    489     #endif
    490 
    491     /* Handle ERROR DETECTED  */
    492     //case SML_PE_ERROR:
    493     //  if (pInstanceInfo->callbacks->handleErrorFunc==NULL) return SML_ERR_COMMAND_NOT_HANDLED;
    494     //  return pInstanceInfo->callbacks->handleErrorFunc (id, pInstanceInfo->userData);
    495     //  break;
    496 
    497     /* --- Invalid Command Element --- */
    498     default:
    499       return SML_ERR_XLT_INVAL_PROTO_ELEM;
    500       break;
    501   } // switch
    502 }
    503 
    504 /* eof */
    505