Bug Summary

File:libsynthesis/src/syncml_tk/src/sml/mgr/all/mgrinstancemgr.c
Warning:line 204, column 24
Access to field 'status' results in a dereference of a null pointer (loaded from variable 'pInstanceInfo')

Annotated Source Code

1/**
2 * @file
3 * Managing SyncML Instances
4 *
5 * @target_system all
6 * @target_os all
7 * @description Core module for managing creation and usage of instances
8 */
9
10
11/*
12 * Copyright Notice
13 * Copyright (c) Ericsson, IBM, Lotus, Matsushita Communication
14 * Industrial Co., Ltd., Motorola, Nokia, Openwave Systems, Inc.,
15 * Palm, Inc., Psion, Starfish Software, Symbian, Ltd. (2001).
16 * All Rights Reserved.
17 * Implementation of all or part of any Specification may require
18 * licenses under third party intellectual property rights,
19 * including without limitation, patent rights (such a third party
20 * may or may not be a Supporter). The Sponsors of the Specification
21 * are not responsible and shall not be held responsible in any
22 * manner for identifying or failing to identify any or all such
23 * third party intellectual property rights.
24 *
25 * THIS DOCUMENT AND THE INFORMATION CONTAINED HEREIN ARE PROVIDED
26 * ON AN "AS IS" BASIS WITHOUT WARRANTY OF ANY KIND AND ERICSSON, IBM,
27 * LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO. LTD, MOTOROLA,
28 * NOKIA, PALM INC., PSION, STARFISH SOFTWARE AND ALL OTHER SYNCML
29 * SPONSORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
30 * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
31 * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
32 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
33 * SHALL ERICSSON, IBM, LOTUS, MATSUSHITA COMMUNICATION INDUSTRIAL CO.,
34 * LTD, MOTOROLA, NOKIA, PALM INC., PSION, STARFISH SOFTWARE OR ANY
35 * OTHER SYNCML SPONSOR BE LIABLE TO ANY PARTY FOR ANY LOSS OF
36 * PROFITS, LOSS OF BUSINESS, LOSS OF USE OF DATA, INTERRUPTION OF
37 * BUSINESS, OR FOR DIRECT, INDIRECT, SPECIAL OR EXEMPLARY, INCIDENTAL,
38 * PUNITIVE OR CONSEQUENTIAL DAMAGES OF ANY KIND IN CONNECTION WITH
39 * THIS DOCUMENT OR THE INFORMATION CONTAINED HEREIN, EVEN IF ADVISED
40 * OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE.
41 *
42 * The above notice and this paragraph must be included on all copies
43 * of this document that are made.
44 *
45 */
46
47
48/*************************************************************************
49 * Definitions
50 *************************************************************************/
51
52#include "syncml_tk_prefix_file.h" // %%% luz: needed for precompiled headers in eVC++
53
54/* Include Headers */
55#include <smldef.h>
56#include <sml.h>
57#include <smlerr.h>
58#include "libmem.h"
59#include "libstr.h"
60#include "liblock.h"
61#include "wsm.h"
62#include "mgr.h"
63#include <xltenc.h>
64
65
66
67/* Used external functions */
68#ifndef NOWSM1
69 #ifndef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */
70 extern Ret_t addInfo(InstanceInfoPtr_t pInfo);
71 extern InstanceInfoPtr_t findInfo(InstanceID_t id);
72 extern Ret_t removeInfo(InstanceID_t id);
73 #endif
74 SyncMLInfoPtr_t mgrGetSyncMLAnchor(void);
75#endif
76
77/* Prototypes of exported SyncML API functions */
78SML_API Ret_t smlInitInstance(SmlCallbacksCPtr_t callbacks, SmlInstanceOptionsPtr_t pOptions, VoidPtr_t pUserData, InstanceID_t *pInstanceID);
79SML_API Ret_t smlTerminateInstance (InstanceID_t id);
80SML_API Ret_t smlLockReadBuffer(InstanceID_t id, MemPtr_t *pReadPosition, MemSize_t *usedSize);
81SML_API Ret_t smlUnlockReadBuffer(InstanceID_t id, MemSize_t processedBytes);
82#ifdef NOWSM1
83SML_API Ret_t smlSetMaxOutgoingSize(InstanceID_t id, MemSize_t maxOutgoingSize);
84SML_API Ret_t smlSetOutgoingBegin(InstanceID_t id);
85#endif
86SML_API Ret_t smlLockWriteBuffer(InstanceID_t id, MemPtr_t *pWritePosition, MemSize_t *freeSize);
87SML_API Ret_t smlUnlockWriteBuffer(InstanceID_t id, MemSize_t writtenBytes);
88SML_API Ret_t smlSetCallbacks (InstanceID_t id, SmlCallbacksCPtr_t pCallbacks);
89SML_API Ret_t smlSetUserData (InstanceID_t id, VoidPtr_t pUserData);
90// added by luz %%%:
91SML_API Ret_t smlGetUserData(InstanceID_t id, VoidPtr_t *ppUserData);
92SML_API Ret_t smlGetEncoding(InstanceID_t id, SmlEncoding_t *pEncoding);
93#ifndef __SML_LITE__ /* these API calls are NOT included in the Toolkit lite version */
94 SML_API Ret_t smlSetEncoding (InstanceID_t id, SmlEncoding_t encoding);
95#endif
96
97
98
99/* Private function prototypes */
100Ret_t freeInstanceOptions (InstanceInfoPtr_t pInstanceInfo);
101static Ret_t freeInstanceInfo (InstanceInfoPtr_t pInfo);
102Ret_t mgrResetWorkspace (InstanceID_t id);
103Ret_t setInstanceOptions (InstanceID_t id, SmlInstanceOptionsPtr_t pOptions);
104
105
106/*************************************************************************
107 * Public SyncML API Functions
108 *************************************************************************/
109
110
111/**
112 * Creates a SyncML instance and assigns a corresponding workspace buffer in
113 * which XML documents are assembled or parsed.
114 * All callback functions implemented by a particular application are defined.
115 * Instance specific options can be passed. This function has to be called
116 * before the first synchronization tasks can be performed. A reference valid
117 * for a SyncML instance is returned.
118 * An instance is active when processing a synchronization request
119 * otherwise it is idle. An instance is terminated when smlTerminateInstance
120 * is called.
121 *
122 * @param pCallbacks (IN)
123 * A structure holding references to the callback functions
124 * implemented by the application
125 * @param pOptions (IN)
126 * Option settings of a particular SyncML instance
127 * @param pUserData (IN)
128 * UserData is a pointer to a void structure the application
129 * can pass into the SyncML Toolkit instance info. It will
130 * be returned to the application with every called callback
131 * function call!\n
132 * NOTE: This is only a pointer, the memory object itself
133 * remains within the responsibility of the calling application.
134 * The memory object will not be copied, moved or freed by the Toolkit.
135 * @param pInstanceID (OUT)
136 * Instance ID assigned to the initialized instance
137 * @return Error Code
138 */
139SML_API Ret_t smlInitInstance(SmlCallbacksCPtr_t pCallbacks, SmlInstanceOptionsPtr_t pOptions, VoidPtr_t pUserData, InstanceID_t *pInstanceID)
140{
141
142 /* --- Definitions --- */
143 InstanceInfoPtr_t pInstanceInfo;
144 Ret_t rc;
145
146
147 #ifndef NOWSM1
148 /* --- Check pOptions, which have been passed by the application --- */
149 if (!pOptions || !pOptions->workspaceName)
150 return SML_ERR_WRONG_USAGE0x13;
151
152 #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */
153 /* if ONE instance is already initialized */
154 if (mgrGetInstanceListAnchor()!=NULL((void*)0))
155 return SML_ERR_WRONG_USAGE0x13;
156 #endif
157
158 /* --- check wether we already know about this instance --- */
159 #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */
160 pInstanceInfo = mgrGetInstanceListAnchor();
161 #else
162 pInstanceInfo = (InstanceInfoPtr_t) findInfo(*pInstanceID);
163 #endif
164
165 /* --- bail outh when we already have a instance with that id --- */
166 if (pInstanceInfo != NULL((void*)0)) return SML_ERR_WRONG_USAGE0x13;
167
168
169 /* --- Create a workspace for this instance --- */
170 LOCKTOOLKIT("smlInitInstance");
171 if ((rc = wsmCreate(pOptions->workspaceName, pOptions->workspaceSize, pInstanceID)) != SML_ERR_OK0x00) {
172 RELEASETOOLKIT("smlInitInstance after wsmCreate failure");
173 return rc;
174 }
175 RELEASETOOLKIT("smlInitInstance");
176 #else // NOWSM
177 /* --- Check pOptions, which have been passed by the application --- */
178 if (!pOptions || !pOptions->workspaceSize)
1
Assuming 'pOptions' is non-null
2
Assuming the condition is false
3
Taking false branch
179 return SML_ERR_WRONG_USAGE0x13;
180 // ok so far
181 rc=SML_ERR_OK0x00;
182 #endif
183
184 /* --- Create an instance info memory object --- */
185 pInstanceInfo = (InstanceInfoPtr_t)smlLibMalloc((MemSize_t)sizeof(InstanceInfo_t));
4
Value assigned to 'pInstanceInfo'
186 if (pInstanceInfo==NULL((void*)0)) {
5
Assuming 'pInstanceInfo' is equal to NULL
6
Taking true branch
187 #ifndef NOWSM1
188 wsmDestroy(pOptions->workspaceName);
189 return SML_ERR_NOT_ENOUGH_SPACE0x11;
190 #endif
191 }
192 #ifdef NOWSM1
193 else {
194 // instance info created, return pointer as instanceID
195 *pInstanceID = (InstanceID_t)pInstanceInfo;
196 }
197 #endif
198
199 smlLibMemset(pInstanceInfo,0,(MemSize_t)sizeof(InstanceInfo_t));
200
201
202
203 /* --- Set mandatory instance infos for this instance to defaults --- */
204 pInstanceInfo->status=MGR_IDLE;
7
Access to field 'status' results in a dereference of a null pointer (loaded from variable 'pInstanceInfo')
205 pInstanceInfo->encoderState=NULL((void*)0); // no encoding in progress, currently not used
206 pInstanceInfo->decoderState=NULL((void*)0); // no decoding in progress, currently not used
207 #ifndef NOWSM1
208 pInstanceInfo->id=*pInstanceID;
209 pInstanceInfo->workspaceState=NULL((void*)0); // to do: some workspace status info
210 pInstanceInfo->nextInfo=NULL((void*)0);
211 #else
212 // create a instance buffer
213 pInstanceInfo->instanceBufSiz=pOptions->workspaceSize; // get requested size for the buffer
214 pInstanceInfo->maxOutgoingSize=pOptions->maxOutgoingSize; // set max outgoing message size
215 pInstanceInfo->instanceBuffer=smlLibMalloc(pInstanceInfo->instanceBufSiz);
216 if (pInstanceInfo->instanceBuffer==NULL((void*)0))
217 return SML_ERR_NOT_ENOUGH_SPACE0x11;
218 // init buffer pointers
219 pInstanceInfo->readPointer=pInstanceInfo->instanceBuffer;
220 pInstanceInfo->writePointer=pInstanceInfo->instanceBuffer;
221 pInstanceInfo->readLocked=0;
222 pInstanceInfo->writeLocked=0;
223 pInstanceInfo->outgoingMsgStart=NULL((void*)0);
224 pInstanceInfo->incomingMsgStart=NULL((void*)0);
225 #endif
226
227
228 #ifndef NOWSM1
229 /* --- Add instance infos memory object to the instance info list --- */
230 #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */
231 mgrSetInstanceListAnchor(pInstanceInfo);
232 #else
233 rc = addInfo( pInstanceInfo );
234 if (rc!=SML_ERR_OK0x00) return rc;
235 #endif
236 #endif
237
238
239 /* --- Set the values of instance Infos as defined by the calling application ---*/
240
241 /* Set user data pointer */
242 pInstanceInfo->userData=pUserData;
243 /* Set callback functions implemented by applications */
244 if (smlSetCallbacks(*pInstanceID, pCallbacks) != SML_ERR_OK0x00) {
245 #ifndef NOWSM1
246 wsmDestroy(pOptions->workspaceName);
247 #endif
248 return rc;
249 }
250
251 // luz: %%% this was called twice, probably this is a bug, so I disabled the second call
252 //smlSetCallbacks(*pInstanceID, pCallbacks);
253
254 /* Set other application defined options for that instance */
255 if (setInstanceOptions (*pInstanceID, pOptions) != SML_ERR_OK0x00) {
256 #ifndef NOWSM1
257 wsmDestroy(pOptions->workspaceName);
258 #endif
259 return rc;
260 }
261
262 return SML_ERR_OK0x00;
263
264}
265
266
267
268/**
269 * Terminates a SyncML instance. The instance info is removed from the instances
270 * list. Allmemory allocated for the workspace and the options variables is
271 * freed.
272 *
273 * @param id (IN)
274 * ID of the instance to be terminated
275 * @return Error Code
276 */
277SML_API Ret_t smlTerminateInstance (InstanceID_t id)
278{
279
280 /* --- Definitions --- */
281 InstanceInfoPtr_t pInstanceInfo;
282
283 #ifdef NOWSM1
284 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
285 #else
286 Ret_t rc;
287
288 /* --- Find that instance --- */
289 #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */
290 pInstanceInfo = mgrGetInstanceListAnchor();
291 #else
292 pInstanceInfo = (InstanceInfoPtr_t) findInfo(id);
293 #endif
294 #endif
295
296 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
297
298 #ifndef NOWSM1
299 /* --- Close the workspace --- */
300 if (pInstanceInfo->instanceOptions != NULL((void*)0)) {
301 LOCKTOOLKIT("smlTerminateInstance");
302 rc = wsmDestroy(pInstanceInfo->instanceOptions->workspaceName);
303 RELEASETOOLKIT("smlTerminateInstance");
304 if (rc!=SML_ERR_OK0x00) {
305 // freeInstanceInfo(pInstanceInfo);
306 return rc;
307 }
308 }
309
310 /* --- Delete instance info and options --- */
311 #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */
312 mgrSetInstanceListAnchor(NULL((void*)0));
313 #else
314 removeInfo(id);
315 #endif
316 #endif
317
318 freeInstanceInfo (pInstanceInfo);
319
320 return SML_ERR_OK0x00;
321}
322
323
324
325/**
326 * Sets new callback functions to an instance
327 *
328 * @param id (IN)
329 * ID of the Instance
330 * @param pCallbacks (IN)
331 * A structure holding references to the callback functions
332 * implemented by the application
333 * @return Return value,\n
334 * SML_ERR_OK if successful
335 */
336SML_API Ret_t smlSetCallbacks(InstanceID_t id, SmlCallbacksCPtr_t pCallbacks)
337{
338
339 /* --- Definitions --- */
340 InstanceInfoPtr_t pInstanceInfo;
341 SmlCallbacksPtr_t pCallbacksCopy;
342
343 /* --- Check pCallbacks, which have been passed by the application --- */
344 if (!pCallbacks)
345 return SML_ERR_WRONG_USAGE0x13;
346
347
348 #ifdef NOWSM1
349 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
350 #else
351 /* --- Find that instance --- */
352 #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */
353 pInstanceInfo = mgrGetInstanceListAnchor();
354 #else
355 pInstanceInfo = (InstanceInfoPtr_t) findInfo(id);
356 #endif
357
358 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
359 #endif
360
361 /* --- free old callback structure ---*/
362 smlLibFree(pInstanceInfo->callbacks);
363
364
365 /* --- Use a copy of pCallbacksCopy --- */
366 pCallbacksCopy = (SmlCallbacksPtr_t)smlLibMalloc((MemSize_t)sizeof(SmlCallbacks_t));
367 if (pCallbacksCopy==NULL((void*)0)) return SML_ERR_NOT_ENOUGH_SPACE0x11;
368 smlLibMemcpy(pCallbacksCopy,pCallbacks,(MemSize_t)sizeof(SmlCallbacks_t));
369
370
371 /* --- set new Callbacks --- */
372 pInstanceInfo->callbacks = pCallbacksCopy;
373
374 return SML_ERR_OK0x00;
375}
376
377
378
379/**
380 * Sets a new Pointer to application specific user data,
381 * which is passed to all invoked callback functions
382 *
383 * @param id (IN)
384 * ID of the Instance
385 * @param pUserData (IN)
386 * UserData is a pointer to a void structure the application
387 * can pass into the SyncML Toolkit instance info. It will
388 * be returned to the application with every called callback
389 * function call!\n
390 * NOTE: This is only a pointer, the memory object itself
391 * remains within the responsibility of the calling application.
392 * The memory object will not be copied, moved or freed by the Toolkit.
393 * @return Return value,\n
394 * SML_ERR_OK if successful
395 */
396SML_API Ret_t smlSetUserData(InstanceID_t id, VoidPtr_t pUserData)
397{
398
399 /* --- Definitions --- */
400 InstanceInfoPtr_t pInstanceInfo;
401
402
403 #ifdef NOWSM1
404 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
405 #else
406 /* --- Find that instance --- */
407 #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */
408 pInstanceInfo = mgrGetInstanceListAnchor();
409 #else
410 pInstanceInfo = (InstanceInfoPtr_t) findInfo(id);
411 #endif
412 #endif
413
414 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
415
416
417 /* --- set new user data pointer ---*/
418 pInstanceInfo->userData=pUserData;
419
420 return SML_ERR_OK0x00;
421}
422
423
424/**
425 * Returns Pointer to application specific user data,
426 * which is passed to all invoked callback functions
427 *
428 * @param id (IN)
429 * ID of the Instance
430 * @param ppUserData (OUT)
431 * Receives current Userdata pointer
432 * @return Return value,\n
433 * SML_ERR_OK if successful
434 * @note (added by luz %%%)
435 */
436SML_API Ret_t smlGetUserData(InstanceID_t id, VoidPtr_t *ppUserData)
437{
438
439 /* --- Definitions --- */
440 InstanceInfoPtr_t pInstanceInfo;
441
442 #ifdef NOWSM1
443 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
444 #else
445 /* --- Find that instance --- */
446 #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */
447 pInstanceInfo = mgrGetInstanceListAnchor();
448 #else
449 pInstanceInfo = (InstanceInfoPtr_t) findInfo(id);
450 #endif
451 #endif
452
453 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
454
455
456 /* --- get userdata pointer ---*/
457 *ppUserData = pInstanceInfo->userData;
458
459 return SML_ERR_OK0x00;
460} // smlGetUserData
461
462
463/**
464 * Returns Currently set encoding type
465 *
466 * @param id (IN)
467 * ID of the Instance
468 * @param pEncoding (OUT)
469 * Receives current encoding
470 * @return Return value,\n
471 * SML_ERR_OK if successful
472 * @note (added by luz %%%)
473 */
474SML_API Ret_t smlGetEncoding(InstanceID_t id, SmlEncoding_t *pEncoding)
475{
476
477 /* --- Definitions --- */
478 InstanceInfoPtr_t pInstanceInfo;
479
480 #ifdef NOWSM1
481 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
482 #else
483 /* --- Find that instance --- */
484 #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */
485 pInstanceInfo = mgrGetInstanceListAnchor();
486 #else
487 pInstanceInfo = (InstanceInfoPtr_t) findInfo(id);
488 #endif
489 #endif
490
491 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
492
493 /* --- get encoding ---*/
494 *pEncoding = pInstanceInfo->instanceOptions->encoding;
495
496 return SML_ERR_OK0x00;
497} // smlGetEncoding
498
499
500/**
501 * Sets new encoding type for this Instance
502 *
503 * @param id (IN)
504 * ID of the Instance
505 * @param encoding (IN)
506 * Type of Encoding to be used within this Instance
507 * @return Return value,\n
508 * SML_ERR_OK if successful
509 */
510#ifndef __SML_LITE__ /* these API calls are NOT included in the Toolkit lite version */
511SML_API Ret_t smlSetEncoding(InstanceID_t id, SmlEncoding_t encoding)
512{
513
514 /* --- Definitions --- */
515 InstanceInfoPtr_t pInstanceInfo;
516
517 /* --- Check pCallbacks, which have been passed by the application --- */
518 if (encoding==SML_UNDEF)
519 return SML_ERR_WRONG_USAGE0x13;
520
521
522 #ifdef NOWSM1
523 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
524 #else
525 /* --- Find that instance --- */
526 #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */
527 pInstanceInfo = mgrGetInstanceListAnchor();
528 #else
529 pInstanceInfo = (InstanceInfoPtr_t) findInfo(id);
530 #endif
531 #endif
532
533 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
534
535
536 /* --- free old callback structure ---*/
537 pInstanceInfo->instanceOptions->encoding = encoding;
538
539 return SML_ERR_OK0x00;
540}
541#endif
542
543
544
545
546/**
547 * Locks the workspace buffer, which is assigned to the given instance
548 * for reading. After this function is called, the application has
549 * access to the workspace buffer, beginning at the address pReadPosition which
550 * is returned by this function. SyncML will not change the workspace
551 * buffer until smlUnlockReadBuffer is called.
552 * pReadPosition returns a pointer to a valid position in the SyncML workspace
553 * buffer. The pointer can be used by the application for copying outgoing
554 * synchronization data from the buffer into some transport layer. usedSize
555 * retrieves the size of synchronization data currently stored in the
556 * workspace buffer beginning from the address to which pReadPosition points to.
557 * This information is needed by the application when copying XML code out
558 * of the buffer (while sending synchronization data)
559 *
560 * @param id (IN)
561 * ID of the Instance
562 * @param pReadPosition (OUT)
563 * Workspace Pointer from which data can be read
564 * @param usedSize (OUT)
565 * Size of used data in workspace which may be read
566 * @return Return value,\n
567 * SML_ERR_OK if successful
568 */
569SML_API Ret_t smlLockReadBuffer(InstanceID_t id, MemPtr_t *pReadPosition, MemSize_t *usedSize)
570{
571 #ifdef NOWSM1
572 InstanceInfoPtr_t pInstanceInfo;
573
574 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
575 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
576 // must not be already locked here
577 if (pInstanceInfo->readLocked)
578 return SML_ERR_WRONG_USAGE0x13;
579 // everything that is already written can also be read
580 *pReadPosition = pInstanceInfo->readPointer;
581 // used portion is what is between read and write pointers
582 *usedSize = pInstanceInfo->writePointer-pInstanceInfo->readPointer;
583 // lock
584 pInstanceInfo->readLocked=1;
585 #else
586 Ret_t rc;
587
588 LOCKTOOLKIT("smlLockReadBuffer");
589 /* --- Lock Workspace exclusively for reading and get a "Read" pointer --- */
590 rc = wsmLockH(id, SML_FIRST_DATA_ITEM, pReadPosition);
591 RELEASETOOLKIT("smlLockReadBuffer");
592 if (rc!=SML_ERR_OK0x00) return rc;
593
594 /* --- Check, how much data has to be read ---*/
595 LOCKTOOLKIT("smlLockReadBuffer");
596 rc = wsmGetUsedSize(id,usedSize);
597 RELEASETOOLKIT("smlLockReadBuffer");
598 if (rc!=SML_ERR_OK0x00) return rc;
599 #endif
600
601 return SML_ERR_OK0x00;
602}
603
604
605
606
607/**
608 * End the read access of the application to the workspace buffer.
609 * SyncML is now owner of the buffer again and is able to manipulate its contents.
610 * processedBytes passes the number of bytes, which the application has
611 * successfully read and processed (e.g. when the application has copied
612 * outgoing synchronization data from the workspace into a communication module).
613 * SyncML removes the given number of bytes from the workspace!
614 *
615 * @param id (IN)
616 * ID of the Instance
617 * @param processedBytes (IN)
618 * Actually read and processed bytes
619 * @return Return value,\n
620 * SML_ERR_OK if successful
621 */
622SML_API Ret_t smlUnlockReadBuffer(InstanceID_t id, MemSize_t processedBytes)
623{
624 #ifdef NOWSM1
625 InstanceInfoPtr_t pInstanceInfo;
626
627 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
628 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
629 // must be already locked here
630 if (!pInstanceInfo->readLocked)
631 return SML_ERR_WRONG_USAGE0x13;
632 // advance read pointer by number of bytes processed
633 if (pInstanceInfo->readPointer+processedBytes>pInstanceInfo->writePointer)
634 return SML_ERR_WRONG_USAGE0x13; // too many bytes processed
635 // update read pointer
636 pInstanceInfo->readPointer+=processedBytes;
637 /* %%% moved from here to smlLockWriteBuffer to leave buffer intact until we actually
638 need to write more data (important for re-sending retries)
639 // auto-reset pointers if we have now read everything
640 if (pInstanceInfo->readPointer == pInstanceInfo->writePointer) {
641 // clear the buffer
642 mgrResetWorkspace(pInstanceInfo);
643 }
644 */
645 // unlock
646 pInstanceInfo->readLocked=0;
647 #else
648 Ret_t rc;
649
650 /* --- Pass the number of bytes which have been read --- */
651 LOCKTOOLKIT("smlUnlockReadBuffer");
652 rc = wsmProcessedBytes (id,processedBytes);
653 RELEASETOOLKIT("smlUnlockReadBuffer");
654 if (rc!=SML_ERR_OK0x00) return rc;
655
656 /* --- Unlock Workspace --- */
657 LOCKTOOLKIT("smlUnlockReadBuffer");
658 rc = wsmUnlockH(id);
659 RELEASETOOLKIT("smlUnlockReadBuffer");
660 if (rc!=SML_ERR_OK0x00) return rc;
661 #endif
662
663 return SML_ERR_OK0x00;
664}
665
666
667#ifdef NOWSM1
668
669/**
670 * Set max outgoing message size
671 *
672 * @param id (IN)
673 * ID of the Instance
674 * @param maxOutgoingSize (IN)
675 * maximum size of outgoing message
676 * (0=no limit except buffer size)
677 * @return Return value,\n
678 * SML_ERR_OK if successful
679 */
680SML_API Ret_t smlSetMaxOutgoingSize(InstanceID_t id, MemSize_t maxOutgoingSize)
681{
682 InstanceInfoPtr_t pInstanceInfo;
683
684 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
685 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
686
687 // set max outgoing message size
688 pInstanceInfo->maxOutgoingSize = maxOutgoingSize;
689
690 return SML_ERR_OK0x00;
691}
692
693
694/**
695 * Marks the current write pointer position as beginning of a new outgoing
696 * message. This is used to track outgoing message size while writing it
697 *
698 * @param id (IN)
699 * ID of the Instance
700 * @return Return value,\n
701 * SML_ERR_OK if successful
702 */
703SML_API Ret_t smlSetOutgoingBegin(InstanceID_t id)
704{
705 InstanceInfoPtr_t pInstanceInfo;
706
707 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
708 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
709
710 // remember current write pointer
711 pInstanceInfo->outgoingMsgStart=pInstanceInfo->writePointer;
712
713 return SML_ERR_OK0x00;
714}
715
716
717/**
718 * resets the read pointer to the beginning of the outgoing message
719 * (must be set previously using smlSetOutgoingBegin())
720 * Note: this can also be used to make sure next smlLockReadBuffer()
721 * does not return unprocessed garbage from a message
722 * written previously to the buffer (as it can be the case
723 * when using the same sml instance for both request and
724 * response processing, as in libsynthesis). In this case
725 * calling smlReadOutgoingAgain() ADVANCES the read
726 * pointer past unprocessed garbage to the point in the
727 * buffer where the next outgoing message starts.
728 *
729 * @param id (IN)
730 * ID of the Instance
731 * @return Return value,\n
732 * SML_ERR_OK if successful
733 */
734SML_API Ret_t smlReadOutgoingAgain(InstanceID_t id)
735{
736 InstanceInfoPtr_t pInstanceInfo;
737
738 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
739 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
740
741 // reset read pointer back to beginning of outgoing message (can be used for message retries)
742 if (pInstanceInfo->outgoingMsgStart==NULL((void*)0)) return SML_ERR_WRONG_USAGE0x13; // no outgoing start set
743 pInstanceInfo->readPointer=pInstanceInfo->outgoingMsgStart;
744
745 return SML_ERR_OK0x00;
746}
747
748
749/**
750 * gets pointer to message in buffer for dumping purposes
751 * @note This is only valid for incoming messages BEFORE outgoing message writing has started
752 * into the same instance buffer!
753 *
754 * @param id (IN)
755 * ID of the Instance
756 * @param outgoing (IN)
757 * if set, outgoing message is returned, incoming otherwise
758 * @param message (OUT)
759 * pointer to message
760 * @param msgsize (OUT)
761 * message size
762 * @return Return value,\n
763 * SML_ERR_OK if successful
764 */
765SML_API Ret_t smlPeekMessageBuffer(InstanceID_t id, Boolean_t outgoing, MemPtr_t *message, MemSize_t *msgsize)
766{
767 InstanceInfoPtr_t pInstanceInfo;
768
769 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
770 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
771
772 if (outgoing) {
773 if (pInstanceInfo->outgoingMsgStart==NULL((void*)0)) return SML_ERR_WRONG_USAGE0x13; // no outgoing message yet
774 *message = pInstanceInfo->outgoingMsgStart;
775 }
776 else {
777 if (pInstanceInfo->incomingMsgStart) {
778 // incoming message start already detected, return it
779 *message = pInstanceInfo->incomingMsgStart;
780 }
781 else {
782 // apparently not started analyzing, assume read pointer as beginning of message
783 if (pInstanceInfo->readPointer==0)
784 return SML_ERR_WRONG_USAGE0x13; // no outgoing message yet
785 *message = pInstanceInfo->readPointer;
786 }
787 }
788 if (*message>=pInstanceInfo->writePointer) return SML_ERR_WRONG_USAGE0x13; // invalid pointer positions
789 // size is space between start and write pointer
790 *msgsize = pInstanceInfo->writePointer-*message;
791 return SML_ERR_OK0x00;
792}
793
794
795#endif
796
797/**
798 * Locks the workspace buffer, which is assigned to the given
799 * instance for writing. After this function is called, the
800 * application has access to the workspace buffer, beginning
801 * at the address pWritePosition which is returned by this
802 * function. SyncML will not change the workspace buffer until
803 * smlUnlockWriteBuffer is called.
804 * pWritePosition returns a pointer to a valid position in the
805 * SyncML workspace buffer. The pointer can be used by the application
806 * for copying incoming synchronization data from some transport
807 * layer into the buffer. freeSize retrieves the maximum usable
808 * size of the workspace buffer beginning from the address to
809 * which pWritePosition points to. This information is needed by
810 * the application when copying XML code into the buffer (while
811 * receiving synchronization data)
812 *
813 * @param id (IN)
814 * ID of the Instance
815 * @param pWritePosition (OUT)
816 * Workspace Pointer to which data can be written
817 * @param freeSize (OUT)
818 * Max free Size of available space for data
819 * @return Return value,\n
820 * SML_ERR_OK if successful
821 */
822SML_API Ret_t smlLockWriteBuffer(InstanceID_t id, MemPtr_t *pWritePosition, MemSize_t *freeSize)
823{
824 #ifdef NOWSM1
825 InstanceInfoPtr_t pInstanceInfo;
826 Boolean_t ogs;
827
828 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
829 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
830 // must not be already locked here
831 if (pInstanceInfo->writeLocked)
832 return SML_ERR_WRONG_USAGE0x13;
833 // auto-reset pointers if buffer is empty by now
834 if (pInstanceInfo->readPointer == pInstanceInfo->writePointer) {
835 // remember if we were at outgoing message start point
836 ogs = pInstanceInfo->outgoingMsgStart == pInstanceInfo->writePointer;
837 // clear the buffer
838 mgrResetWorkspace(pInstanceInfo);
839 // restore outgoingMsgStart (to beginning of buffer now!) if it was set before
840 if (ogs) pInstanceInfo->outgoingMsgStart=pInstanceInfo->writePointer;
841 }
842
843 // return current write pointer
844 *pWritePosition = pInstanceInfo->writePointer;
845 // free portion is either determined by actual room in buffer, or maximum outgoing size if set
846 if (
847 pInstanceInfo->maxOutgoingSize &&
848 pInstanceInfo->outgoingMsgStart &&
849 pInstanceInfo->outgoingMsgStart<pInstanceInfo->writePointer
850 ) {
851 // calculate what is allowed according to maxOutgoingSize
852 *freeSize =
853 (pInstanceInfo->maxOutgoingSize) - // maximum outgoing size
854 (pInstanceInfo->writePointer-pInstanceInfo->outgoingMsgStart); // size of outgoing message so far
855 if (pInstanceInfo->writePointer+*freeSize > pInstanceInfo->instanceBuffer+pInstanceInfo->instanceBufSiz) {
856 // actual space in buffer is smaller
857 *freeSize =
858 (pInstanceInfo->instanceBuffer+pInstanceInfo->instanceBufSiz) - // end of buffer
859 pInstanceInfo->writePointer; // current write position
860 }
861 }
862 else {
863 // simply return available size in buffer
864 *freeSize =
865 (pInstanceInfo->instanceBuffer+pInstanceInfo->instanceBufSiz) - // end of buffer
866 pInstanceInfo->writePointer; // current write position
867 }
868 // lock
869 pInstanceInfo->writeLocked=1;
870 #else
871 Ret_t rc;
872
873 /* --- Lock Workspace exclusively for writing and get a "Write" pointer --- */
874 LOCKTOOLKIT("smlLockWriteBuffer");
875 rc = wsmLockH(id, SML_FIRST_FREE_ITEM, pWritePosition);
876 RELEASETOOLKIT("smlLockWriteBuffer");
877 if (rc!=SML_ERR_OK0x00) return rc;
878
879 /* --- Check, how much free space is available for writing --- */
880 LOCKTOOLKIT("smlLockWriteBuffer");
881 rc = wsmGetFreeSize(id, freeSize);
882 RELEASETOOLKIT("smlLockWriteBuffer");
883 if (rc!=SML_ERR_OK0x00) return rc;
884 #endif
885
886 return SML_ERR_OK0x00;
887}
888
889
890
891
892/**
893 *
894 * End the write access of the application to the workspace buffer.
895 * SyncML is now owner of the buffer again and is able to manipulate its
896 * contents. writtenBytes passes the number of bytes which have been
897 * written into the workspace buffer (e.g. when the application has copied
898 * incoming synchronization data from a communication module into the
899 * workspace). This information is needed by SyncML when processing received
900 * synchronization data.
901 *
902 * @param id (IN)
903 * ID of the Instance
904 * @param writtenBytes (IN)
905 * Actually written bytes
906 * @return Return value,\n
907 * SML_ERR_OK if successful
908 */
909SML_API Ret_t smlUnlockWriteBuffer(InstanceID_t id, MemSize_t writtenBytes)
910{
911 #ifdef NOWSM1
912 InstanceInfoPtr_t pInstanceInfo;
913
914 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
915 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
916 // must be already locked here
917 if (!pInstanceInfo->writeLocked)
918 return SML_ERR_WRONG_USAGE0x13;
919 if (writtenBytes > 0) {
920 // advance write pointer by number of bytes written
921 if (pInstanceInfo->writePointer+writtenBytes>pInstanceInfo->instanceBuffer+pInstanceInfo->instanceBufSiz)
922 return SML_ERR_WRONG_USAGE0x13; // too many bytes written
923 // update write pointer
924 pInstanceInfo->writePointer+=writtenBytes;
925 }
926 // unlock
927 pInstanceInfo->writeLocked=0;
928 #else
929 Ret_t rc;
930
931 if (writtenBytes > 0)
932 {
933 /* --- Pass the number of bytes which have been written --- */
934 LOCKTOOLKIT("smlUnlockWriteBuffer");
935 rc = wsmSetUsedSize(id,writtenBytes);
936 RELEASETOOLKIT("smlUnlockWriteBuffer");
937 if (rc!=SML_ERR_OK0x00) return rc;
938 }
939 /* --- Unlock Workspace --- */
940 LOCKTOOLKIT("smlUnlockWriteBuffer");
941 rc = wsmUnlockH(id);
942 RELEASETOOLKIT("smlUnlockWriteBuffer");
943 if (rc!=SML_ERR_OK0x00) return rc;
944 #endif
945
946 return SML_ERR_OK0x00;
947}
948
949
950
951
952/*************************************************************************
953 * SyncML internal functions
954 *************************************************************************/
955
956
957/**
958 * Reset the Workspace Buffer position to the beginning of the workspace
959 * (clears all data in the buffer)
960 *
961 * @param id (IN)
962 * ID of the Instance
963 * @return Return value,\n
964 * SML_ERR_OK if successful
965 */
966Ret_t mgrResetWorkspace (InstanceID_t id) {
967 #ifdef NOWSM1
968 InstanceInfoPtr_t pInstanceInfo;
969
970 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
971 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
972
973 pInstanceInfo->readPointer=pInstanceInfo->instanceBuffer;
974 pInstanceInfo->writePointer=pInstanceInfo->instanceBuffer;
975 pInstanceInfo->outgoingMsgStart=NULL((void*)0); // no outgoing message in the buffer
976 pInstanceInfo->incomingMsgStart=NULL((void*)0); // no incoming message in the buffer
977 return SML_ERR_OK0x00; // ok
978 #else
979 Ret_t rc;
980 LOCKTOOLKIT("mgrResetWorkspace");
981 rc=wsmReset (id);
982 RELEASETOOLKIT("mgrResetWorkspace");
983 return rc;
984 #endif
985}
986
987
988
989/**
990 * The options settings of an instance are set to a new value
991 *
992 * @param id (IN)
993 * Instance ID assigned to the instance
994 * @param pOptions (IN)
995 * New option settings of that particular SyncML instance\n
996 * NOTE: only the encoding can be changed during life-time of an
997 * instance. The other parameters of the instance options
998 * (workspace size and name cannot be changed)
999 * @return Error Code
1000 */
1001Ret_t setInstanceOptions (InstanceID_t id, SmlInstanceOptionsPtr_t pOptions)
1002{
1003
1004 /* --- Definitions --- */
1005 InstanceInfoPtr_t pInstanceInfo;
1006 SmlInstanceOptionsPtr_t pOptionsCopy;
1007
1008
1009 #ifdef NOWSM1
1010 /* --- Ckeck pOptions, which have been passed by the application --- */
1011 if (!pOptions || (pOptions->encoding==SML_UNDEF))
1012 return SML_ERR_WRONG_USAGE0x13;
1013
1014 pInstanceInfo = (InstanceInfoPtr_t)id; // ID is the instance info pointer
1015 #else
1016 /* --- Ckeck pOptions, which have been passed by the application --- */
1017 if (!pOptions || !pOptions->workspaceName|| (pOptions->encoding==SML_UNDEF))
1018 return SML_ERR_WRONG_USAGE0x13;
1019
1020 /* --- Find that instance --- */
1021 #ifdef __SML_LITE__ /* Only ONE instance is supported in the Toolkit lite version */
1022 pInstanceInfo = mgrGetInstanceListAnchor();
1023 #else
1024 pInstanceInfo = (InstanceInfoPtr_t) findInfo(id);
1025 #endif
1026 #endif
1027
1028 if (pInstanceInfo==NULL((void*)0)) return SML_ERR_MGR_INVALID_INSTANCE_INFO0x1002;
1029
1030 /* --- free old instance options ---*/
1031 freeInstanceOptions(pInstanceInfo);
1032
1033 /* --- Use a copy of pOptionsCopy --- */
1034 pOptionsCopy = (SmlInstanceOptionsPtr_t)smlLibMalloc((MemSize_t)sizeof(SmlInstanceOptions_t));
1035 if (pOptionsCopy==NULL((void*)0)) return SML_ERR_NOT_ENOUGH_SPACE0x11;
1036 smlLibMemcpy(pOptionsCopy,pOptions,(MemSize_t)sizeof(SmlInstanceOptions_t));
1037
1038 #ifndef NOWSM1
1039 pOptionsCopy->workspaceName=smlLibStrdup(pOptions->workspaceName);
1040
1041 if (pOptionsCopy->workspaceName == NULL((void*)0)) {
1042 pInstanceInfo->instanceOptions=NULL((void*)0);
1043 smlLibFree(pOptionsCopy);
1044 return SML_ERR_NOT_ENOUGH_SPACE0x11;
1045 }
1046 #endif
1047
1048 /* --- Assign the new options --- */
1049 pInstanceInfo->instanceOptions=pOptionsCopy;
1050
1051
1052 /* --- Let the new settingds take effect --- */
1053 /* --- Adjust workspace size ---*/
1054 /* --- Change workspace name ---*/
1055 // NOT SUPPORTED FOR YELLOW
1056
1057 return SML_ERR_OK0x00;
1058}
1059
1060
1061
1062/**
1063 * Free Instances Options
1064 *
1065 * @param pInfo (IN)
1066 * Pointer to the pInstance Info, which options should be freed
1067 * @return SML_ERR_OK
1068 */
1069Ret_t freeInstanceOptions (InstanceInfoPtr_t pInfo) {
1070
1071 /* --- Delete instance options (if there are any) --- */
1072 if (pInfo->instanceOptions!=NULL((void*)0)) {
1073 #ifndef NOWSM1
1074 if (pInfo->instanceOptions->workspaceName!=NULL((void*)0))
1075 smlLibFree(pInfo->instanceOptions->workspaceName); // don't forget the substructures
1076 #endif
1077 smlLibFree(pInfo->instanceOptions);
1078 }
1079
1080 return SML_ERR_OK0x00;
1081}
1082
1083/**
1084 * Free the memory of an removed Instance Info
1085 * (including referenced sub structures)
1086 *
1087 * @param id (IN)
1088 * ID of the InstanceInfo structure to be freed
1089 */
1090static Ret_t freeInstanceInfo(InstanceInfoPtr_t pInfo) {
1091
1092 if (pInfo) {
1093
1094 #ifdef NOWSM1
1095 // return the instance buffer
1096 if (pInfo->instanceBuffer)
1097 smlLibFree(pInfo->instanceBuffer);
1098 #else
1099 if (pInfo->workspaceState)
1100 smlLibFree(pInfo->workspaceState);
1101 #endif
1102 if (pInfo->encoderState)
1103 xltEncReset((XltEncoderPtr_t)pInfo->encoderState);
1104 if (pInfo->decoderState)
1105 xltDecReset((XltDecoderPtr_t)pInfo->decoderState);
1106 if (pInfo->callbacks)
1107 smlLibFree(pInfo->callbacks);
1108
1109 freeInstanceOptions(pInfo);
1110
1111 smlLibFree(pInfo);
1112 }
1113
1114 return SML_ERR_OK0x00;
1115}