libsyncml 0.5.4

- Main Page
- Modules
- Data Structures
- Files

- File List

sml_command.c
1 /*
2 * libsyncml - A syncml protocol implementation
3 * Copyright (C) 2005 Armin Bauer <armin.bauer@opensync.org>
4 * Copyright (C) 2008 Michael Bell <michael.bell@opensync.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22 #include "syncml.h"
23
24 #include "syncml_internals.h"
25 #include "sml_parse_internals.h"
26 #include "sml_command_internals.h"
27 #include "sml_session_internals.h"
28 #include "sml_elements_internals.h"
29 #include "sml_error_internals.h"
30
31 SmlCommandType smlCommandTypeFromString(const char *name, SmlError **error)
32 {
33 CHECK_ERROR_REF
34 if (!name)
35 return SML_COMMAND_TYPE_UNKNOWN;
36
37 if (!strcmp(name, SML_ELEMENT_ALERT)) {
38 return SML_COMMAND_TYPE_ALERT;
39 } else if (!strcmp(name, SML_ELEMENT_SYNC)) {
40 return SML_COMMAND_TYPE_SYNC;
41 } else if (!strcmp(name, SML_ELEMENT_PUT)) {
42 return SML_COMMAND_TYPE_PUT;
43 } else if (!strcmp(name, SML_ELEMENT_SYNCHDR)) {
44 return SML_COMMAND_TYPE_HEADER;
45 } else if (!strcmp(name, SML_ELEMENT_ADD)) {
46 return SML_COMMAND_TYPE_ADD;
47 } else if (!strcmp(name, SML_ELEMENT_REPLACE)) {
48 return SML_COMMAND_TYPE_REPLACE;
49 } else if (!strcmp(name, SML_ELEMENT_MAP)) {
50 return SML_COMMAND_TYPE_MAP;
51 } else if (!strcmp(name, SML_ELEMENT_DELETE)) {
52 return SML_COMMAND_TYPE_DELETE;
53 } else if (!strcmp(name, SML_ELEMENT_RESULTS)) {
54 return SML_COMMAND_TYPE_RESULTS;
55 } else if (!strcmp(name, SML_ELEMENT_GET)) {
56 return SML_COMMAND_TYPE_GET;
57 }
58
59 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown command name \"%s\"", name);
60 return SML_COMMAND_TYPE_UNKNOWN;
61 }
62
63 const char *smlCommandTypeToString(SmlCommandType type, SmlError **error)
64 {
65 CHECK_ERROR_REF
66 switch (type) {
67 case SML_COMMAND_TYPE_ALERT:
68 return SML_ELEMENT_ALERT;
69 case SML_COMMAND_TYPE_SYNC:
70 return SML_ELEMENT_SYNC;
71 case SML_COMMAND_TYPE_PUT:
72 return SML_ELEMENT_PUT;
73 case SML_COMMAND_TYPE_HEADER:
74 return SML_ELEMENT_SYNCHDR;
75 case SML_COMMAND_TYPE_ADD:
76 return SML_ELEMENT_ADD;
77 case SML_COMMAND_TYPE_REPLACE:
78 return SML_ELEMENT_REPLACE;
79 case SML_COMMAND_TYPE_DELETE:
80 return SML_ELEMENT_DELETE;
81 case SML_COMMAND_TYPE_MAP:
82 return SML_ELEMENT_MAP;
83 case SML_COMMAND_TYPE_GET:
84 return SML_ELEMENT_GET;
85 case SML_COMMAND_TYPE_RESULTS:
86 return SML_ELEMENT_RESULTS;
87 default:
88 ;
89 }
90
91 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown command type \"%i\"", type);
92 return NULL;
93 }
94
95 SmlStatus *smlStatusNew(SmlErrorType data, unsigned int cmdref, unsigned int msgref, SmlLocation *sourceref, SmlLocation *targetref, SmlCommandType type, SmlError **error)
96 {
97 smlTrace(TRACE_ENTRY, "%s(%i, %i, %i, %p, %p, %i, %p)", __func__, data, cmdref, msgref, sourceref, targetref, type, error);
98 CHECK_ERROR_REF
99 SmlStatus *status = smlTryMalloc0(sizeof(SmlStatus), error);
100 if (!status)
101 goto error;
102
103 status->refCount = 1;
104 status->cmdRef = cmdref;
105 status->msgRef = msgref;
106 status->type = type;
107 if (data != SML_ERROR_UNKNOWN)
108 status->data = g_strdup_printf("%i", data);
109
110 if (sourceref) {
111 status->sourceRef = sourceref;
112 smlLocationRef(sourceref);
113 }
114
115 if (targetref) {
116 status->targetRef = targetref;
117 smlLocationRef(targetref);
118 }
119
120 smlTrace(TRACE_EXIT, "%s: %p", __func__, status);
121 return status;
122
123 error:
124 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
125 return NULL;
126 }
127
128 SmlStatus *smlStatusRef(SmlStatus *status)
129 {
130 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, status);
131 smlAssert(status);
132
133 g_atomic_int_inc(&(status->refCount));
134
135 smlTrace(TRACE_EXIT, "%s: New refcount: %i", __func__, status->refCount);
136 return status;
137 }
138
139 void smlStatusUnref(SmlStatus *status)
140 {
141 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, status);
142 smlAssert(status);
143
144 if (g_atomic_int_dec_and_test(&(status->refCount))) {
145 smlTrace(TRACE_INTERNAL, "%s: Refcount == 0!", __func__);
146
147 if (status->sourceRef)
148 smlLocationUnref(status->sourceRef);
149
150 if (status->targetRef)
151 smlLocationUnref(status->targetRef);
152
153 if (status->data)
154 smlSafeCFree(&(status->data));
155
156 if (status->anchor)
157 smlAnchorFree(status->anchor);
158
159 if (status->item)
160 smlItemUnref(status->item);
161
162 smlSafeFree((gpointer *)&status);
163 }
164
165 smlTrace(TRACE_EXIT, "%s", __func__);
166 }
167
168 SmlErrorType smlStatusGetCode(SmlStatus *status)
169 {
170 smlAssert(status);
171 smlAssert(status->data);
172 return atoi(status->data);
173 }
174
175 SmlErrorClass smlStatusGetClass(SmlStatus *status)
176 {
177 smlAssert(status);
178 smlAssert(status->data);
179 return (atoi(status->data) / 100);
180 }
181
182 SmlCommand *smlStatusGetResult(SmlStatus *status)
183 {
184 if (status->type == SML_COMMAND_TYPE_RESULTS)
185 return status->result;
186 return NULL;
187 }
188
189 SmlBool smlStatusIsResult(SmlStatus *status)
190 {
191 return status->type == SML_COMMAND_TYPE_RESULTS ? TRUE : FALSE;
192 }
193
194 SmlCommand *smlCommandNew(SmlCommandType type, SmlError **error)
195 {
196 smlTrace(TRACE_ENTRY, "%s(%i, %p)", __func__, type, error);
197 CHECK_ERROR_REF
198
199 SmlCommand *cmd = smlTryMalloc0(sizeof(SmlCommand), error);
200 if (!cmd)
201 goto error;
202
203 cmd->refCount = 1;
204 cmd->type = type;
205
206 smlTrace(TRACE_EXIT, "%s: %p", __func__, cmd);
207 return cmd;
208
209 error:
210 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
211 return NULL;
212 }
213
214 SmlStatus *smlCommandNewReply(const SmlCommand *cmd, SmlErrorType code, SmlError **error)
215 {
216 smlTrace(TRACE_ENTRY, "%s(%p, %i, %p)", __func__, cmd, code, error);
217 CHECK_ERROR_REF
218 smlAssert(cmd);
219
220 SmlStatus *reply = smlStatusNew(code, cmd->cmdID, cmd->msgID, cmd->source, cmd->target, cmd->type, error);
221 if (!reply)
222 goto error;
223
224 switch (cmd->type) {
225 case SML_COMMAND_TYPE_ALERT:
226 if (cmd->private.alert.anchor) {
227 reply->anchor = smlAnchorNew(NULL, cmd->private.alert.anchor->next, error);
228 if (!reply->anchor)
229 goto error;
230 }
231 break;
232 default:
233 ;
234 }
235
236 smlTrace(TRACE_EXIT, "%s: %p", __func__, reply);
237 return reply;
238
239 error:
240 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
241 return NULL;
242 }
243
244 SmlCommand *smlCommandNewResult(SmlCommand *cmd, SmlLocation *source, char *data, unsigned int size, const char *contenttype, SmlError **error)
245 {
246 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %i, %s, %p)", __func__, cmd, source, data, size, VA_STRING(contenttype), error);
247 CHECK_ERROR_REF
248 smlAssert(cmd);
249
250 SmlCommand *result = smlCommandNew(SML_COMMAND_TYPE_RESULTS, error);
251 if (!result)
252 goto error;
253
254 result->private.results.status = smlStatusNew(SML_NO_ERROR, cmd->cmdID, cmd->msgID, cmd->source, cmd->target, SML_COMMAND_TYPE_RESULTS, error);
255 if (!result->private.results.status)
256 goto error_free_cmd;
257
258 result->private.results.status->item = smlItemNewForData(data, size, error);
259 smlSafeCFree(&data);
260 if (!result->private.results.status->item)
261 goto error_free_cmd;
262
263 result->private.results.status->item->contenttype = g_strdup(contenttype);
264 result->private.results.status->item->source = smlLocationClone(source, error);
265
266 if (!result->private.results.status->item->source)
267 goto error_free_cmd;
268
269 smlTrace(TRACE_EXIT, "%s: %p", __func__, result);
270 return result;
271
272 error_free_cmd:
273 smlCommandUnref(result);
274 error:
275 if (data)
276 smlSafeCFree(&data);
277 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
278 return NULL;
279 }
280
281 SmlCommand *smlCommandRef(SmlCommand *cmd)
282 {
283 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, cmd);
284 smlAssert(cmd);
285
286 g_atomic_int_inc(&(cmd->refCount));
287
288 smlTrace(TRACE_EXIT, "%s: New refcount: %i", __func__, cmd->refCount);
289 return cmd;
290 }
291
292 void smlCommandUnref(SmlCommand *cmd)
293 {
294 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, cmd);
295 smlAssert(cmd);
296
297 if (g_atomic_int_dec_and_test(&(cmd->refCount))) {
298 smlTrace(TRACE_INTERNAL, "%s: Refcount == 0!", __func__);
299
300 if (cmd->parent) {
301 cmd->parent->children = g_list_remove(cmd->parent->children, cmd);
302
303 smlCommandUnref(cmd->parent);
304 cmd->parent = NULL;
305 }
306
307 switch (cmd->type) {
308 case SML_COMMAND_TYPE_UNKNOWN:
309 case SML_COMMAND_TYPE_HEADER:
310 case SML_COMMAND_TYPE_SYNC:
311 break;
312 case SML_COMMAND_TYPE_ALERT:
313 if (cmd->private.alert.anchor)
314 smlAnchorFree(cmd->private.alert.anchor);
315 if (cmd->private.alert.contentType)
316 smlSafeCFree(&(cmd->private.alert.contentType));
317 break;
318 case SML_COMMAND_TYPE_PUT:
319 case SML_COMMAND_TYPE_GET:
320 if (cmd->private.access.type)
321 smlSafeCFree(&(cmd->private.access.type));
322
323 if (cmd->private.access.item)
324 smlItemUnref(cmd->private.access.item);
325 break;
326 case SML_COMMAND_TYPE_ADD:
327 case SML_COMMAND_TYPE_REPLACE:
328 case SML_COMMAND_TYPE_DELETE:
329 if (cmd->private.change.items)
330 {
331 guint i;
332 for (i = 0; i < g_list_length(cmd->private.change.items); i++)
333 {
334 SmlItem *item = g_list_nth_data(cmd->private.change.items, i);
335 smlItemUnref(item);
336 }
337 g_list_free(cmd->private.change.items);
338 }
339 break;
340 case SML_COMMAND_TYPE_MAP:
341 while (cmd->private.map.items) {
342 SmlMapItem *item = cmd->private.map.items->data;
343 smlMapItemUnref(item);
344 cmd->private.map.items = g_list_delete_link(cmd->private.map.items, cmd->private.map.items);
345 }
346 break;
347 case SML_COMMAND_TYPE_RESULTS:
348 if (cmd->private.results.status)
349 smlStatusUnref(cmd->private.results.status);
350 break;
351 }
352
353 if (cmd->target)
354 smlLocationUnref(cmd->target);
355
356 if (cmd->source)
357 smlLocationUnref(cmd->source);
358
359 smlSafeFree((gpointer *)&cmd);
360 }
361
362 smlTrace(TRACE_EXIT, "%s", __func__);
363 }
364
365 SmlCommand *smlCommandNewChange(SmlChangeType type, const char *uid, const char *data, unsigned int size, const char *contenttype, SmlError **error)
366 {
367 smlTrace(TRACE_ENTRY, "%s(%i, %s, %p, %i, %s, %p)", __func__, type, VA_STRING(uid), data, size, VA_STRING(contenttype), error);
368 CHECK_ERROR_REF
369 SmlCommand *cmd = NULL;
370
371 switch (type) {
372 case SML_CHANGE_ADD:
373 cmd = smlCommandNew(SML_COMMAND_TYPE_ADD, error);
374 break;
375 case SML_CHANGE_REPLACE:
376 cmd = smlCommandNew(SML_COMMAND_TYPE_REPLACE, error);
377 break;
378 case SML_CHANGE_DELETE:
379 cmd = smlCommandNew(SML_COMMAND_TYPE_DELETE, error);
380 break;
381 default:
382 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown changetype");
383 }
384 if (!cmd)
385 goto error;
386
387 SmlItem *item = smlItemNewForData(data, size, error);
388 if (!item)
389 goto error_free_cmd;
390 cmd->private.change.items = g_list_append(NULL, item);
391 if (!cmd->private.change.items)
392 {
393 smlItemUnref(item);
394 goto error_free_cmd;
395 }
396
397 SmlLocation *loc = smlLocationNew(uid, NULL, error);
398 if (!loc)
399 goto error_free_cmd;
400
401 /* The usage of target and source depends on the role of the
402 * local peer. We cannot determine if the local peer is an
403 * OMA DS client or server. This function is only used by
404 * smlDsSessionQueueChange. So the correct usage of target
405 * and source must be ensured by the XML assembler.
406 */
407 item->source = loc;
408 if (type != SML_CHANGE_ADD) {
409 /* If this is an Add command then nobody knows
410 * which ID the remote peer will be use for this item.
411 */
412 smlLocationRef(loc);
413 item->target = loc;
414 }
415
416 item->contenttype = g_strdup(contenttype);
417
418 smlTrace(TRACE_EXIT, "%s: %p", __func__, cmd);
419 return cmd;
420
421 error_free_cmd:
422 smlCommandUnref(cmd);
423 error:
424 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
425 return NULL;
426 }
427
433 SmlCommand *smlCommandNewPartialChange(SmlChangeType type, const char *uid, const char *data, unsigned int complete_size, unsigned int partial_size, const char *contenttype, SmlError **error)
434 {
435 smlTrace(TRACE_ENTRY, "%s(%i, %s, %p, %i, %i, %s, %p)", __func__, type, VA_STRING(uid), data, complete_size, partial_size, VA_STRING(contenttype), error);
436 CHECK_ERROR_REF
437 SmlCommand *cmd = NULL;
438
439 switch (type) {
440 case SML_CHANGE_ADD:
441 cmd = smlCommandNew(SML_COMMAND_TYPE_ADD, error);
442 break;
443 case SML_CHANGE_REPLACE:
444 cmd = smlCommandNew(SML_COMMAND_TYPE_REPLACE, error);
445 break;
446 case SML_CHANGE_DELETE:
447 cmd = smlCommandNew(SML_COMMAND_TYPE_DELETE, error);
448 break;
449 default:
450 smlErrorSet(error, SML_ERROR_GENERIC, "Unknown changetype");
451 }
452 if (!cmd)
453 goto error;
454 cmd->size = complete_size;
455
456 SmlItem *item = smlItemNewForData(data, partial_size, error);
457 if (!item)
458 goto error_free_cmd;
459 cmd->private.change.items = g_list_append(NULL, item);
460 if (!cmd->private.change.items)
461 {
462 smlItemUnref(item);
463 goto error_free_cmd;
464 }
465
466 SmlLocation *loc = smlLocationNew(uid, NULL, error);
467 if (!loc)
468 goto error_free_cmd;
469
470 if (type != SML_CHANGE_ADD)
471 item->target = loc;
472 else
473 item->source = loc;
474
475 item->moreData = TRUE;
476 item->contenttype = g_strdup(contenttype);
477
478 smlTrace(TRACE_EXIT, "%s: %p", __func__, cmd);
479 return cmd;
480
481 error_free_cmd:
482 smlCommandUnref(cmd);
483 error:
484 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
485 return NULL;
486 }
487
488 SmlCommand *smlCommandNewAlert(SmlAlertType type, SmlLocation *target, SmlLocation *source, const char *next, const char *last, const char *contenttype, SmlError **error)
489 {
490 smlTrace(TRACE_ENTRY, "%s(%i, %p, %p, %s, %s, %s, %p)", __func__, type, target, source, VA_STRING(next), VA_STRING(last), VA_STRING(contenttype), error);
491 CHECK_ERROR_REF
492
493 SmlCommand *cmd = smlCommandNew(SML_COMMAND_TYPE_ALERT, error);
494 if (!cmd)
495 goto error;
496
497 if (target) {
498 cmd->target = target;
499 smlLocationRef(target);
500 }
501
502 if (source) {
503 cmd->source = source;
504 smlLocationRef(source);
505 }
506
507 /* A synchronization anchor makes only sense if it is not an
508 * alert for the next part of an incomplete package (next
509 * message alert) or SAN.
510 */
511 if (type != SML_ALERT_NEXT_MESSAGE && type != SML_ALERT_TWO_WAY_BY_SERVER) {
512 /* If this is a slow sync alert then it makes no sense
513 * to send the last sync anchor because a slow sync is
514 * only necessary if there was no earlier sync or
515 * something goes wrong since then which means there is
516 * no safe last anchor.
517 */
518 if (type == SML_ALERT_SLOW_SYNC) {
519 if (last)
520 smlTrace(TRACE_INTERNAL,
521 "%s: removing last anchor (%s) from slow sync alert",
522 __func__, VA_STRING(last));
523 cmd->private.alert.anchor = smlAnchorNew(NULL, next, error);
524 } else
525 cmd->private.alert.anchor = smlAnchorNew(last, next, error);
526 if (!cmd->private.alert.anchor)
527 goto error;
528 }
529 cmd->private.alert.type = type;
530 cmd->private.alert.contentType = g_strdup(contenttype);
531
532 smlTrace(TRACE_EXIT, "%s: %p", __func__, cmd);
533 return cmd;
534
535 error:
536 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
537 return NULL;
538 }
539
540 SmlCommand *smlCommandNewSync(SmlLocation *target, SmlLocation *source, unsigned int num_changes, SmlError **error)
541 {
542 smlTrace(TRACE_ENTRY, "%s(%p, %p, %i, %p)", __func__, target, source, num_changes, error);
543 CHECK_ERROR_REF
544 SmlCommand *cmd = smlCommandNew(SML_COMMAND_TYPE_SYNC, error);
545 if (!cmd)
546 goto error;
547
548 cmd->target = target;
549 smlLocationRef(target);
550
551 cmd->source = source;
552 smlLocationRef(source);
553
554 cmd->private.sync.numChanged = num_changes;
555
556 smlTrace(TRACE_EXIT, "%s: %p", __func__, cmd);
557 return cmd;
558
559 error:
560 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
561 return NULL;
562 }
563
564 SmlCommand *smlCommandNewPut(SmlLocation *target, SmlLocation *source, const char *data, unsigned int size, const char *contenttype, SmlError **error)
565 {
566 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %i, %s, %p)", __func__, target, source, data, size, VA_STRING(contenttype), error);
567 CHECK_ERROR_REF
568
569 SmlCommand *cmd = smlCommandNew(SML_COMMAND_TYPE_PUT, error);
570 if (!cmd)
571 goto error;
572
573 cmd->private.access.item = smlItemNewForData(data, size, error);
574 if (!cmd->private.access.item)
575 goto error_free_cmd;
576
577 if (target) {
578 cmd->target = target;
579 smlLocationRef(target);
580 smlItemSetTarget(cmd->private.access.item, cmd->target);
581 }
582
583 if (source) {
584 cmd->source = source;
585 smlLocationRef(source);
586 smlItemSetSource(cmd->private.access.item, cmd->source);
587 }
588
589 cmd->private.access.item->contenttype = g_strdup(contenttype);
590
591 smlTrace(TRACE_EXIT, "%s: %p", __func__, cmd);
592 return cmd;
593
594 error_free_cmd:
595 smlCommandUnref(cmd);
596 error:
597 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
598 return NULL;
599 }
600
601 SmlCommand *smlCommandNewGet(SmlLocation *target, const char *contenttype, SmlError **error)
602 {
603 smlTrace(TRACE_ENTRY, "%s(%p, %s, %p)", __func__, target, VA_STRING(contenttype), error);
604 CHECK_ERROR_REF
605 smlAssert(target);
606
607 SmlCommand *cmd = smlCommandNew(SML_COMMAND_TYPE_GET, error);
608 if (!cmd)
609 goto error;
610
611 cmd->private.access.item = smlItemNew(0, error);
612 if (!cmd->private.access.item)
613 goto error_free_cmd;
614
615 cmd->target = target;
616 smlLocationRef(target);
617 smlItemSetTarget(cmd->private.access.item, cmd->target);
618
619 cmd->private.access.item->contenttype = g_strdup(contenttype);
620
621 smlTrace(TRACE_EXIT, "%s: %p", __func__, cmd);
622 return cmd;
623
624 error_free_cmd:
625 smlCommandUnref(cmd);
626 error:
627 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
628 return NULL;
629 }
630
631 SmlCommand *smlCommandNewMap(SmlLocation *target, SmlLocation *source, SmlError **error)
632 {
633 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, target, source, error);
634 CHECK_ERROR_REF
635
636 SmlCommand *cmd = smlCommandNew(SML_COMMAND_TYPE_MAP, error);
637 if (!cmd)
638 goto error;
639
640 cmd->target = target;
641 smlLocationRef(target);
642
643 cmd->source = source;
644 smlLocationRef(source);
645
646 smlTrace(TRACE_EXIT, "%s: %p", __func__, cmd);
647 return cmd;
648
649 error:
650 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
651 return NULL;
652 }
653
654 SmlBool smlCommandAddMapItem(SmlCommand *map, SmlMapItem *item, SmlError **error)
655 {
656 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, map, item, error);
657 CHECK_ERROR_REF
658 smlAssert(map);
659 smlAssert(map->type == SML_COMMAND_TYPE_MAP);
660 smlAssert(item);
661
662 smlMapItemRef(item);
663 map->private.map.items = g_list_append(map->private.map.items, item);
664
665 smlTrace(TRACE_EXIT, "%s", __func__);
666 return TRUE;
667 }
668
669 SmlAlertType smlAlertTypeConvert(unsigned int id, SmlError **error)
670 {
671 smlTrace(TRACE_ENTRY, "%s(%u, %p)", __func__, id, error);
672 CHECK_ERROR_REF
673
674 if (id == 0 ||
675 id == 100 ||
676 (200 <= id && id <= 210) ||
677 (221 <= id && id <= 223))
678 {
679 SmlAlertType result = (SmlAlertType) id;
680 smlTrace(TRACE_EXIT, "%s - %u", __func__, result);
681 return result;
682 } else {
683 smlErrorSet(error, SML_ERROR_GENERIC,
684 "The unknown alert code %u was detected.", id);
685 smlTrace(TRACE_EXIT_ERROR, "%s - %s", __func__, smlErrorPrint(error));
686 return SML_ALERT_UNKNOWN;
687 }
688 }
689