22 #include <libsyncml/syncml.h> 24 #include <libsyncml/syncml_internals.h> 25 #include <libsyncml/sml_elements_internals.h> 26 #include <libsyncml/sml_command_internals.h> 27 #include <libsyncml/sml_devinf_internals.h> 28 #include <libsyncml/sml_session_internals.h> 29 #include "libsyncml/sml_error_internals.h" 31 #include "sml_xml_assm.h" 32 #include "sml_xml_assm_internals.h" 34 #define BUFFER_SIZE 500 44 static SmlBool _smlXmlAssemblerStartNodeNS(
SmlXmlAssembler *assm,
const char *name,
const char *uri,
SmlError **error)
48 smlAssert(assm->writer);
49 smlAssert(name != NULL);
50 smlAssert(strlen(name) > 0);
51 smlTrace(TRACE_INTERNAL,
"%s: Starting \"%s\"", __func__, VA_STRING(name));
52 int rc = xmlTextWriterStartElementNS(assm->writer, NULL, (xmlChar *)name, (xmlChar *)uri);
54 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to start node");
63 return _smlXmlAssemblerStartNodeNS(assm, name, NULL, error);
69 smlTrace(TRACE_INTERNAL,
"%s: Ending node", __func__);
70 int rc = xmlTextWriterEndElement(assm->writer);
72 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to end node (%d).", rc);
78 static SmlBool _smlXmlAssemblerAddStringNS(
SmlXmlAssembler *assm,
const char *name,
const char *uri,
const char *value,
SmlError **error)
81 int rc = xmlTextWriterWriteElementNS(assm->writer, NULL, (xmlChar *)name, (xmlChar *)uri, (xmlChar *)value);
83 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to add string (%d - %s:%s -> %s).", rc, VA_STRING(uri), VA_STRING(name), VA_STRING(value));
89 static SmlBool _smlXmlAssemblerAddString(
SmlXmlAssembler *assm,
const char *name,
const char *value,
SmlError **error)
92 int rc = xmlTextWriterWriteElement(assm->writer, (xmlChar *)name, (xmlChar *)value);
94 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to add pure string (%d - %s -> %s).", rc, VA_STRING(name), VA_STRING(value));
100 static SmlBool _smlXmlAssemblerAddData(
SmlXmlAssembler *assm,
const char *name,
const char *value,
unsigned int size, SmlBool raw,
SmlError **error)
104 if (!_smlXmlAssemblerStartNode(assm, name, error))
108 rc = xmlTextWriterWriteRawLen(assm->writer, (xmlChar *)value, size);
110 rc = xmlTextWriterWriteFormatCDATA(assm->writer,
"%*s", size, (xmlChar *)value);
113 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to add data (%d).", rc);
117 if (!_smlXmlAssemblerEndNode(assm, error))
123 static SmlBool _smlXmlAssemblerAddID(
SmlXmlAssembler *assm,
const char *name,
unsigned int id,
SmlError **error)
126 int rc = xmlTextWriterWriteFormatElement(assm->writer, (xmlChar *)name,
"%i",
id);
128 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to add id");
134 static SmlBool _smlXmlAssemblerAddIDNS(
SmlXmlAssembler *assm,
const char *name,
const char *uri,
unsigned int id,
SmlError **error)
137 int rc = xmlTextWriterWriteFormatElementNS(assm->writer, NULL, (xmlChar *)name, (xmlChar *)uri,
"%i",
id);
139 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to add id");
147 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, assm);
151 SmlBool supportsLargeObjects = (opt && !atoi(opt)) ? FALSE : TRUE;
154 if (assm->session->sessionType == SML_SESSION_TYPE_SERVER)
156 if (smlAssemblerGetRemoteMaxObjSize(assm->assembler) <= 0)
157 supportsLargeObjects = FALSE;
158 if (smlAssemblerGetRemoteMaxMsgSize(assm->assembler) <= 0)
159 supportsLargeObjects = FALSE;
163 if (assm->session->version == SML_VERSION_10)
164 supportsLargeObjects = FALSE;
169 if (smlSessionGetLocalMaxObjSize(assm->session) <= 0)
170 supportsLargeObjects = FALSE;
172 smlTrace(TRACE_EXIT,
"%s - %d", __func__, supportsLargeObjects);
173 return supportsLargeObjects;
178 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, assm);
199 if (!_smlXmlAssemblerAddIDNS(assm, SML_ELEMENT_MAXOBJSIZE, SML_NAMESPACE_METINF, smlSessionGetLocalMaxObjSize(assm->session), error))
202 smlTrace(TRACE_EXIT,
"%s", __func__);
212 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %s, %p)", __func__, location, assm, VA_STRING(name), error);
218 if (!_smlXmlAssemblerStartNode(assm, name, error))
222 if (!location->locURI) {
223 smlErrorSet(error, SML_ERROR_GENERIC,
"No locURI set");
227 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_LOCURI, location->locURI, error))
230 if (location->locName) {
231 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_LOCNAME, location->locName, error))
236 if (!_smlXmlAssemblerEndNode(assm, error))
240 smlTrace(TRACE_EXIT,
"%s", __func__);
252 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, anchor, assm, error);
265 if (!_smlXmlAssemblerStartNodeNS(assm, SML_ELEMENT_ANCHOR, SML_NAMESPACE_METINF, error))
269 smlErrorSet(error, SML_ERROR_GENERIC,
"No next set");
277 if (!_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_LAST, SML_NAMESPACE_METINF, anchor->last, error))
282 if (!_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_NEXT, SML_NAMESPACE_METINF, anchor->next, error))
285 if (!_smlXmlAssemblerEndNode(assm, error))
288 smlTrace(TRACE_EXIT,
"%s", __func__);
298 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, item, assm, error);
303 if (assm->moreDataSet) {
304 smlErrorSet(error, SML_ERROR_GENERIC,
"Trying to start a new item while last item had more data");
309 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_ITEM, error))
313 if (smlItemGetTarget(item)) {
314 if (!smlLocationAssemble(smlItemGetTarget(item), assm, SML_ELEMENT_TARGET, error))
319 if (smlItemGetSource(item)) {
320 if (!smlLocationAssemble(smlItemGetSource(item), assm, SML_ELEMENT_SOURCE, error))
325 if (smlItemGetSourceParent(item)) {
326 if (!smlLocationAssemble(smlItemGetSourceParent(item), assm, SML_ELEMENT_SOURCE_PARENT, error))
331 if (smlItemGetTargetParent(item)) {
332 if (!smlLocationAssemble(smlItemGetTargetParent(item), assm, SML_ELEMENT_TARGET_PARENT, error))
337 if (smlItemHasData(item)) {
338 if (item->disabled) {
339 if (!_smlXmlAssemblerAddData(assm, SML_ELEMENT_DATA,
"", 0, item->
raw, error))
343 unsigned int size = 0;
347 if (!_smlXmlAssemblerAddData(assm, SML_ELEMENT_DATA, data, size, item->
raw, error))
353 if (item->moreData) {
354 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_MOREDATA,
"", error))
357 assm->moreDataSet = TRUE;
361 if (!_smlXmlAssemblerEndNode(assm, error))
364 smlTrace(TRACE_EXIT,
"%s", __func__);
374 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, cred, assm, error);
379 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_CRED, error))
383 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_META, error))
386 switch (cred->format) {
387 case SML_FORMAT_TYPE_BASE64:
388 if (!_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_FORMAT, SML_NAMESPACE_METINF, SML_BASE64, error))
392 smlErrorSet(error, SML_ERROR_GENERIC,
"SyncML credential: Unknown format %d.", cred->format);
396 switch (cred->type) {
397 case SML_AUTH_TYPE_BASIC:
398 if (!_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_TYPE, SML_NAMESPACE_METINF, SML_AUTH_BASIC, error))
401 case SML_AUTH_TYPE_MD5:
402 if (!_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_TYPE, SML_NAMESPACE_METINF, SML_AUTH_MD5, error))
406 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown format");
411 if (!_smlXmlAssemblerEndNode(assm, error))
414 if (!_smlXmlAssemblerAddData(assm, SML_ELEMENT_DATA, cred->data, strlen(cred->data), TRUE, error))
417 if (!_smlXmlAssemblerEndNode(assm, error))
420 smlTrace(TRACE_EXIT,
"%s", __func__);
430 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, assm, change, error);
435 if (!change->private.access.item) {
436 smlErrorSet(error, SML_ERROR_GENERIC,
"Missing item");
440 if (!change->private.access.item->contenttype) {
441 smlErrorSet(error, SML_ERROR_GENERIC,
"Missing contenttype");
446 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_META, error))
449 if (!_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_TYPE, SML_NAMESPACE_METINF, change->private.access.item->contenttype, error))
453 if (!_smlXmlAssemblerEndNode(assm, error))
456 if (!smlItemAssemble(change->private.access.item, assm, error))
459 smlTrace(TRACE_EXIT,
"%s", __func__);
469 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, assm, change, error);
474 if (!change->private.change.items ||
475 !g_list_length(change->private.change.items)) {
476 smlErrorSet(error, SML_ERROR_GENERIC,
"Missing items");
481 smlAssert(g_list_length(change->private.change.items) == 1);
482 SmlItem *item = g_list_nth_data(change->private.change.items, 0);
485 smlErrorSet(error, SML_ERROR_GENERIC,
"One item of the item list is NULL.");
488 if (!item->contenttype) {
489 smlErrorSet(error, SML_ERROR_GENERIC,
"Missing contenttype");
494 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_META, error))
497 if (!_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_TYPE, SML_NAMESPACE_METINF, item->contenttype, error))
503 SmlBool supportsLargeObjects = (opt && !atoi(opt)) ? FALSE : TRUE;
505 smlTrace(TRACE_INTERNAL,
"%s: Large object: use %i, server %i, requestedSize %i", __func__, supportsLargeObjects, assm->session->sessionType == SML_SESSION_TYPE_SERVER ? 1 : 0, smlAssemblerGetRemoteMaxObjSize(assm->assembler));
507 if (supportsLargeObjects && change->size) {
508 if (!_smlXmlAssemblerAddIDNS(assm, SML_ELEMENT_SIZE, SML_NAMESPACE_METINF, change->size, error))
513 if (!_smlXmlAssemblerEndNode(assm, error))
542 SmlSessionType sessionType = assm->session->sessionType;
544 if (change->type == SML_COMMAND_TYPE_ADD)
546 if (opt && atoi(opt) &&
547 sessionType == SML_SESSION_TYPE_SERVER) {
550 smlLocationUnref(item->target);
551 item->target = item->source;
556 smlLocationUnref(item->target);
560 if (sessionType == SML_SESSION_TYPE_SERVER) {
563 smlLocationUnref(item->source);
568 smlLocationUnref(item->target);
573 if (!smlItemAssemble(item, assm, error))
576 smlTrace(TRACE_EXIT,
"%s", __func__);
586 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, assm, cmd, error);
592 smlErrorSet(error, SML_ERROR_GENERIC,
"No target set");
602 if (!smlLocationAssemble(cmd->target, assm, SML_ELEMENT_TARGET, error))
606 smlErrorSet(error, SML_ERROR_GENERIC,
"No source set");
610 if (!smlLocationAssemble(cmd->source, assm, SML_ELEMENT_SOURCE, error))
613 if (_smlAssembleUseMaxObjSize(assm))
615 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_META, error))
618 if (!_smlAssembleMaxObjSize(assm, error))
621 if (!_smlXmlAssemblerEndNode(assm, error))
626 SmlBool supportsNumberOfChanges = (opt && !atoi(opt)) ? FALSE : TRUE;
627 if (supportsNumberOfChanges && assm->session->version != SML_VERSION_10) {
628 if (!_smlXmlAssemblerAddID(assm, SML_ELEMENT_NUMBEROFCHANGES, cmd->private.sync.numChanged, error))
632 smlTrace(TRACE_EXIT,
"%s", __func__);
642 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, assm, item, error);
647 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_MAPITEM, error))
651 if (!smlLocationAssemble(item->source, assm, SML_ELEMENT_SOURCE, error))
656 if (!smlLocationAssemble(item->target, assm, SML_ELEMENT_TARGET, error))
661 if (!_smlXmlAssemblerEndNode(assm, error))
664 smlTrace(TRACE_EXIT,
"%s", __func__);
674 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, assm, cmd, error);
680 smlErrorSet(error, SML_ERROR_GENERIC,
"No target set");
684 if (!smlLocationAssemble(cmd->target, assm, SML_ELEMENT_TARGET, error))
688 smlErrorSet(error, SML_ERROR_GENERIC,
"No source set");
692 if (!smlLocationAssemble(cmd->source, assm, SML_ELEMENT_SOURCE, error))
696 for (m = cmd->private.map.items; m; m = m->next) {
698 if (!smlMapItemAssemble(assm, item, error))
702 smlTrace(TRACE_EXIT,
"%s", __func__);
712 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, assm, cmd, error);
726 if (!_smlXmlAssemblerAddID(assm, SML_ELEMENT_DATA, cmd->private.alert.type, error))
732 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_ITEM, error))
737 if (!smlLocationAssemble(cmd->target, assm, SML_ELEMENT_TARGET, error))
743 if (!smlLocationAssemble(cmd->source, assm, SML_ELEMENT_SOURCE, error))
747 if (cmd->private.alert.type != SML_ALERT_NEXT_MESSAGE) {
748 smlErrorSet(error, SML_ERROR_GENERIC,
"No source set");
759 SmlBool meta = FALSE;
760 if (cmd->private.alert.contentType)
762 if (cmd->private.alert.anchor)
764 if (_smlAssembleUseMaxObjSize(assm))
767 if (meta && !_smlXmlAssemblerStartNode(assm, SML_ELEMENT_META, error))
770 if (cmd->private.alert.contentType &&
771 !_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_TYPE, SML_NAMESPACE_METINF,
772 cmd->private.alert.contentType, error))
775 if (cmd->private.alert.anchor &&
776 !smlAnchorAssemble(cmd->private.alert.anchor, assm, error))
779 if (_smlAssembleUseMaxObjSize(assm) &&
780 !_smlAssembleMaxObjSize(assm, error))
783 if (meta && !_smlXmlAssemblerEndNode(assm, error))
789 if (!_smlXmlAssemblerEndNode(assm, error))
792 smlTrace(TRACE_EXIT,
"%s", __func__);
802 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, assm, cmd, error);
812 if (!_smlXmlAssemblerAddID(assm, SML_ELEMENT_MSGREF, cmd->private.results.status->msgRef, error))
816 if (!_smlXmlAssemblerAddID(assm, SML_ELEMENT_CMDREF, cmd->private.results.status->cmdRef, error))
820 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_META, error))
822 if (!_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_TYPE, SML_NAMESPACE_METINF, cmd->private.results.status->item->contenttype, error))
824 if (!_smlXmlAssemblerEndNode(assm, error))
828 if (cmd->private.results.status->targetRef) {
829 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_TARGETREF, cmd->private.results.status->targetRef->locURI, error))
834 if (cmd->private.results.status->sourceRef) {
835 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_SOURCEREF, cmd->private.results.status->sourceRef->locURI, error))
840 if (!smlItemAssemble(cmd->private.results.status->item, assm, error))
843 smlTrace(TRACE_EXIT,
"%s", __func__);
853 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, assm, session, error);
856 smlAssert(g_mutex_trylock(assm->mutex));
860 if (assm->header_buffer) {
861 xmlBufferFree(assm->header_buffer);
862 assm->header_buffer = NULL;
866 assm->header_buffer = xmlBufferCreateSize(BUFFER_SIZE);
867 if (!assm->header_buffer) {
868 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to create new buffer");
872 assm->writer = xmlNewTextWriterMemory(assm->header_buffer, 0);
874 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to create new writer");
878 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_SYNCHDR, error))
881 if (!session->protocol) {
882 smlErrorSet(error, SML_ERROR_GENERIC,
"No version set");
886 if (!session->version) {
887 smlErrorSet(error, SML_ERROR_GENERIC,
"No dtd set");
891 switch (session->protocol) {
892 case SML_PROTOCOL_SYNCML:
893 switch (session->version) {
895 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_VERDTD,
"1.0", error))
898 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_VERPROTO, SML_VERSION_STRING_10, error))
902 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_VERDTD,
"1.1", error))
905 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_VERPROTO, SML_VERSION_STRING_11, error))
909 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_VERDTD,
"1.2", error))
912 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_VERPROTO, SML_VERSION_STRING_12, error))
916 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown version");
921 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown protocol");
925 if (session->sessionID) {
926 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_SESSIONID, session->sessionID, error))
930 if (!_smlXmlAssemblerAddID(assm, SML_ELEMENT_MSGID, session->lastMessageID, error))
933 if (!smlLocationAssemble(session->target, assm, SML_ELEMENT_TARGET, error))
936 if (!smlLocationAssemble(session->source, assm, SML_ELEMENT_SOURCE, error))
939 if (session->responseURI &&
940 !_smlXmlAssemblerAddString(assm, SML_ELEMENT_RESPURI, session->responseURI, error))
946 if (session->cred != NULL && session->cred->data != NULL) {
947 if (!smlCredAssemble(session->cred, assm, error))
964 if (session->protocol == SML_PROTOCOL_SYNCML &&
965 session->version > SML_VERSION_10)
970 if (session->sessionType == SML_SESSION_TYPE_SERVER ||
971 smlSessionGetLocalMaxObjSize(session) > 0)
974 if (smlSessionGetLocalMaxMsgSize(session) < 1)
976 smlErrorSet(error, SML_ERROR_INTERNAL_MISCONFIGURATION,
977 "MaxMsgSize must be set.");
980 if (smlSessionGetLocalMaxObjSize(session) < 1)
982 smlErrorSet(error, SML_ERROR_INTERNAL_MISCONFIGURATION,
983 "MaxObjSize must be set.");
990 unsigned int localMaxMsgSize = smlSessionGetLocalMaxMsgSize(session);
991 if (localMaxMsgSize) {
992 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_META, error))
998 if (!_smlXmlAssemblerAddIDNS(assm, SML_ELEMENT_MAXMSGSIZE, SML_NAMESPACE_METINF, localMaxMsgSize, error))
1002 if (!_smlXmlAssemblerEndNode(assm, error))
1006 if (!_smlXmlAssemblerEndNode(assm, error))
1010 if (xmlTextWriterEndDocument(assm->writer) < 0) {
1011 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to end writer");
1015 xmlFreeTextWriter(assm->writer);
1016 assm->writer = NULL;
1018 g_mutex_unlock(assm->mutex);
1019 smlTrace(TRACE_EXIT,
"%s", __func__);
1024 xmlFreeTextWriter(assm->writer);
1025 assm->writer = NULL;
1027 if (assm->header_buffer) {
1028 xmlBufferFree(assm->header_buffer);
1029 assm->header_buffer = NULL;
1031 g_mutex_unlock(assm->mutex);
1042 if (cmd->type == SML_COMMAND_TYPE_UNKNOWN) {
1043 smlErrorSet(error, SML_ERROR_GENERIC,
"No cmd set");
1048 smlErrorSet(error, SML_ERROR_GENERIC,
"No cmd ID set");
1053 if (!assm->header_buffer) {
1054 smlErrorSet(error, SML_ERROR_GENERIC,
"Header not yet added");
1061 assmcmd->
nodeType = SML_ASSEMBLER_NODE_OPEN;
1062 assmcmd->
cmdID = cmd->cmdID;
1065 GList **appendto = &(assm->commands);
1070 for (b = assm->commands; b; b = b->next) {
1072 if (excmd->
cmdID == parentID)
1073 appendto = &(excmd->children);
1078 assmcmd->
buffer = xmlBufferCreateSize(BUFFER_SIZE);
1080 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to create new buffer");
1081 goto error_free_cmd;
1084 assm->writer = xmlNewTextWriterMemory(assmcmd->
buffer, 0);
1085 if (!assm->writer) {
1086 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to create new writer");
1087 goto error_free_buffer;
1091 if (!_smlXmlAssemblerAddID(assm, SML_ELEMENT_CMDID, cmd->cmdID, error))
1092 goto error_free_writer;
1094 switch (cmd->type) {
1095 case SML_COMMAND_TYPE_ALERT:
1096 if (!smlAlertAssemble(assm, cmd, error))
1097 goto error_free_writer;
1099 case SML_COMMAND_TYPE_SYNC:
1100 if (!smlSyncAssemble(assm, cmd, error))
1101 goto error_free_writer;
1103 case SML_COMMAND_TYPE_ADD:
1104 case SML_COMMAND_TYPE_REPLACE:
1105 case SML_COMMAND_TYPE_DELETE:
1106 if (!smlChangeAssemble(assm, cmd, error))
1107 goto error_free_writer;
1109 case SML_COMMAND_TYPE_PUT:
1110 case SML_COMMAND_TYPE_GET:
1111 if (!smlAccessAssemble(assm, cmd, error))
1112 goto error_free_writer;
1114 case SML_COMMAND_TYPE_MAP:
1115 if (!smlMapAssemble(assm, cmd, error))
1116 goto error_free_writer;
1118 case SML_COMMAND_TYPE_RESULTS:
1119 if (!smlResultsAssemble(assm, cmd, error))
1120 goto error_free_writer;
1123 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown command type");
1124 goto error_free_writer;
1128 if (xmlTextWriterEndDocument(assm->writer) < 0) {
1129 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to end writer");
1130 goto error_free_writer;
1133 xmlFreeTextWriter(assm->writer);
1134 assm->writer = NULL;
1137 *appendto = g_list_append(*appendto, assmcmd);
1142 xmlFreeTextWriter(assm->writer);
1143 assm->writer = NULL;
1145 xmlBufferFree(assmcmd->
buffer);
1147 smlSafeFree((gpointer *)&assmcmd);
1158 if (!assm->header_buffer) {
1159 smlErrorSet(error, SML_ERROR_GENERIC,
"Header not yet added");
1166 assmcmd->
nodeType = SML_ASSEMBLER_NODE_CLOSE;
1168 GList **appendto = &(assm->commands);
1173 for (b = assm->commands; b; b = b->next) {
1175 if (excmd->
cmdID == parentID)
1176 appendto = &(excmd->children);
1181 *appendto = g_list_append(*appendto, assmcmd);
1191 smlTrace(TRACE_ENTRY,
"%s(%p, %i, %p)", __func__, assm, parentID, error);
1195 GList **removefrom = &(assm->commands);
1200 for (b = assm->commands; b; b = b->next) {
1202 if (excmd->
cmdID == parentID)
1203 removefrom = &(excmd->children);
1208 smlErrorSet(error, SML_ERROR_GENERIC,
"Nothing to remove");
1212 GList *b = g_list_last(*removefrom);
1214 *removefrom = g_list_delete_link(*removefrom, b);
1215 if (cmd->
nodeType != SML_ASSEMBLER_NODE_OPEN) {
1216 smlErrorSet(error, SML_ERROR_GENERIC,
"Trying to remove not a starting command");
1220 assm->moreDataSet = FALSE;
1222 xmlBufferFree(cmd->
buffer);
1223 smlSafeFree((gpointer *)&cmd);
1225 smlTrace(TRACE_EXIT,
"%s", __func__);
1235 smlTrace(TRACE_ENTRY,
"%s(%p, %p)", __func__, assm, error);
1239 if (!assm->statuses) {
1240 smlErrorSet(error, SML_ERROR_GENERIC,
"Trying to remove status but no status available");
1246 for (b = assm->statuses; b; b = b->next) {
1255 xmlBufferFree(last->
buffer);
1259 assm->added_statuses--;
1261 smlTrace(TRACE_EXIT,
"%s", __func__);
1269 SmlBool smlXmlAssemblerReserveStatus(
SmlXmlAssembler *assm,
unsigned int cmdRef,
unsigned int msgRef,
unsigned int cmdID,
SmlError **error)
1271 smlTrace(TRACE_ENTRY,
"%s(%p, %i, %i, %i, %p)", __func__, assm, cmdRef, msgRef, cmdID, error);
1281 res->msgRef = msgRef;
1285 assm->statuses = g_list_append(assm->statuses, res);
1287 assm->statuses = g_list_prepend(assm->statuses, res);
1288 assm->reserved_statuses++;
1290 smlTrace(TRACE_EXIT,
"%s", __func__);
1300 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, assm, status, error);
1303 smlAssert(g_mutex_trylock(assm->mutex));
1307 smlTrace(TRACE_INTERNAL,
"Adding status with cmdRef %i, msgRef %i, cmd %s", status->cmdRef, status->msgRef, smlCommandTypeToString(status->type, error));
1312 if (!status->msgRef) {
1313 smlErrorSet(error, SML_ERROR_GENERIC,
"No msgref set");
1317 if (status->type == SML_COMMAND_TYPE_UNKNOWN) {
1318 smlErrorSet(error, SML_ERROR_GENERIC,
"No cmd set");
1323 if (!assm->header_buffer) {
1324 smlErrorSet(error, SML_ERROR_GENERIC,
"Header not yet added");
1330 for (s = assm->statuses; s; s = s->next) {
1332 if (res->
cmdRef == status->cmdRef && res->msgRef == status->msgRef)
1338 smlErrorSet(error, SML_ERROR_GENERIC,
"Status not reserved");
1343 smlErrorSet(error, SML_ERROR_GENERIC,
"No cmd ID set");
1348 smlErrorSet(error, SML_ERROR_GENERIC,
"Status already added");
1353 res->
buffer = xmlBufferCreateSize(BUFFER_SIZE);
1355 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to create new buffer");
1359 assm->writer = xmlNewTextWriterMemory(res->
buffer, 0);
1360 if (!assm->writer) {
1361 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to create new writer");
1362 goto error_free_buffer;
1366 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_STATUS, error))
1370 if (!_smlXmlAssemblerAddID(assm, SML_ELEMENT_CMDID, res->
cmdID, error))
1374 if (!_smlXmlAssemblerAddID(assm, SML_ELEMENT_MSGREF, status->msgRef, error))
1378 if (!_smlXmlAssemblerAddID(assm, SML_ELEMENT_CMDREF, res->
cmdRef, error))
1382 const char *cmdname = smlCommandTypeToString(status->type, error);
1385 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_CMD, cmdname, error))
1389 if (status->targetRef) {
1390 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_TARGETREF, status->targetRef->locURI, error))
1395 if (status->sourceRef) {
1396 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_SOURCEREF, status->sourceRef->locURI, error))
1403 if (status->type == SML_COMMAND_TYPE_HEADER && status->chal)
1405 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_CHAL, error))
1408 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_META, error))
1411 if (!_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_FORMAT, SML_NAMESPACE_METINF, SML_BASE64, error))
1414 switch (status->chal->type) {
1415 case SML_AUTH_TYPE_BASIC:
1416 if (!_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_TYPE, SML_NAMESPACE_METINF, SML_AUTH_BASIC, error))
1419 case SML_AUTH_TYPE_MD5:
1420 if (!_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_TYPE, SML_NAMESPACE_METINF, SML_AUTH_MD5, error))
1422 if (status->chal->nonce_b64 &&
1423 !_smlXmlAssemblerAddStringNS(assm, SML_ELEMENT_NEXTNONCE, SML_NAMESPACE_METINF, status->chal->nonce_b64, error))
1427 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown auth type");
1432 if (!_smlXmlAssemblerEndNode(assm, error))
1436 if (!_smlXmlAssemblerEndNode(assm, error))
1442 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_DATA, status->data, error))
1447 if (status->type == SML_COMMAND_TYPE_ALERT && status->anchor)
1449 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_ITEM, error))
1452 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_DATA, error))
1455 if (!smlAnchorAssemble(status->anchor, assm, error))
1459 if (!_smlXmlAssemblerEndNode(assm, error))
1463 if (!_smlXmlAssemblerEndNode(assm, error))
1468 if (!_smlXmlAssemblerEndNode(assm, error))
1472 if (xmlTextWriterEndDocument(assm->writer) < 0) {
1473 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to end writer");
1474 goto error_free_writer;
1477 xmlFreeTextWriter(assm->writer);
1478 assm->writer = NULL;
1480 assm->added_statuses++;
1482 g_mutex_unlock(assm->mutex);
1483 smlTrace(TRACE_EXIT,
"%s", __func__);
1487 xmlFreeTextWriter(assm->writer);
1488 assm->writer = NULL;
1490 xmlBufferFree(res->
buffer);
1493 g_mutex_unlock(assm->mutex);
1502 if (assm->reserved_statuses - assm->added_statuses > 0)
1508 static void flush_list(GList *list)
1511 for (l = list; l; l = l->next) {
1514 if (cmd->
nodeType != SML_ASSEMBLER_NODE_CLOSE && cmd->children)
1515 flush_list(cmd->children);
1517 xmlBufferFree(cmd->
buffer);
1518 smlSafeFree((gpointer *)&cmd);
1526 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, assm);
1529 if (assm->header_buffer) {
1530 xmlBufferFree(assm->header_buffer);
1531 assm->header_buffer = NULL;
1534 while (assm->statuses) {
1538 xmlBufferFree(status->
buffer);
1540 smlSafeFree((gpointer *)&status);
1541 assm->statuses = g_list_delete_link(assm->statuses, assm->statuses);
1544 flush_list(assm->commands);
1545 flush_list(assm->last_commands);
1547 g_mutex_free(assm->mutex);
1548 smlSafeFree((gpointer *)&assm);
1550 smlTrace(TRACE_EXIT,
"%s", __func__);
1557 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, assm);
1560 unsigned int newid = 1;
1561 SmlBool missing = FALSE;
1565 GList *s2 = g_list_copy(assm->statuses);
1566 for (s = s2; s; s = s->next) {
1576 }
else if (!missing) {
1577 xmlBufferFree(status->
buffer);
1578 assm->statuses = g_list_remove(assm->statuses, status);
1579 smlSafeFree((gpointer *)&status);
1580 assm->reserved_statuses--;
1581 assm->added_statuses--;
1591 if (assm->last_commands)
1592 flush_list(assm->last_commands);
1593 assm->last_commands = assm->commands;
1594 assm->commands = NULL;
1597 assm->moreDataSet = FALSE;
1599 smlTrace(TRACE_EXIT,
"%s: %i", __func__, newid);
1605 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, assm, session, error);
1608 smlAssert(g_mutex_trylock(assm->mutex));
1611 assm->session = session;
1613 g_mutex_unlock(assm->mutex);
1614 smlTrace(TRACE_EXIT,
"%s", __func__);
1621 smlTrace(TRACE_ENTRY,
"%s(%p, %p)", __func__, assm, error);
1624 smlAssert(g_mutex_trylock(assm->mutex));
1627 if (!_smlXmlAssemblerEndNode(assm, error))
1630 if (_smlXmlAssemblerEndNode(assm, NULL)) {
1631 smlErrorSet(error, SML_ERROR_GENERIC,
"Extra node open");
1635 g_mutex_unlock(assm->mutex);
1636 smlTrace(TRACE_EXIT,
"%s", __func__);
1640 g_mutex_unlock(assm->mutex);
1647 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, assm, b, error);
1651 SmlBool onlyReplace = (opt && atoi(opt)) ? TRUE : FALSE;
1654 const char *cmdname = NULL;
1656 for (; b; b = b->next) {
1659 case SML_ASSEMBLER_NODE_OPEN:
1662 if (cmd->
cmdType == SML_COMMAND_TYPE_ADD && onlyReplace)
1663 cmdname = SML_ELEMENT_REPLACE;
1665 cmdname = smlCommandTypeToString(cmd->
cmdType, error);
1669 smlTrace(TRACE_INTERNAL,
"opening node %s", cmdname);
1671 if (!_smlXmlAssemblerStartNode(assm, cmdname, error))
1674 int rc = xmlTextWriterWriteRawLen(assm->writer, xmlBufferContent(cmd->
buffer), xmlBufferLength(cmd->
buffer));
1676 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to write raw node data (%d).", rc);
1680 if (cmd->children) {
1681 if (!smlXmlAssemblerAddChildren(assm, cmd->children, error))
1685 smlTrace(TRACE_INTERNAL,
"%s: closing node", __func__);
1686 if (!_smlXmlAssemblerEndNode(assm, error))
1689 case SML_ASSEMBLER_NODE_CLOSE:
1697 smlTrace(TRACE_EXIT,
"%s", __func__);
1705 SmlBool smlXmlAssemblerRunFull(
SmlXmlAssembler *assm,
char **data,
unsigned int *size, SmlBool *end, SmlBool
final, SmlBool check,
unsigned int maxsize,
SmlError **error)
1707 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p, %p, %i, %i, %i, %p)", __func__, assm, data, size, end,
final, check, maxsize, error);
1710 smlAssert(g_mutex_trylock(assm->mutex));
1713 smlAssert(assm->session);
1714 unsigned int buffersize = 0;
1717 if (!assm->header_buffer) {
1718 smlErrorSet(error, SML_ERROR_GENERIC,
"No header available");
1725 if (check && !assm->statuses && !assm->commands) {
1726 smlErrorSet(error, SML_ERROR_GENERIC,
"No status/command available");
1730 if (check && assm->statuses &&
final) {
1733 smlErrorSet(error, SML_ERROR_GENERIC,
"Missing the first status with cmdRef %i", status->
cmdRef);
1739 xmlBuffer *buffer = xmlBufferCreateSize(BUFFER_SIZE);
1741 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to create new buffer");
1745 assm->writer = xmlNewTextWriterMemory(buffer, 0);
1746 if (!assm->writer) {
1747 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to create new writer");
1748 goto error_free_buffer;
1755 if (xmlTextWriterStartDocument(assm->writer, NULL,
"UTF-8", NULL) < 0) {
1756 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to create new writer");
1757 goto error_free_writer;
1761 switch (assm->session->version) {
1762 case SML_VERSION_10:
1763 xmlTextWriterWriteRaw(assm->writer, (xmlChar *)
"<!DOCTYPE SyncML PUBLIC \"-//SYNCML//DTD SyncML 1.0//EN\" \"http://www.syncml.org/docs/syncml_represent_v10_20001207.dtd\">");
1764 if (!_smlXmlAssemblerStartNodeNS(assm, SML_ELEMENT_SYNCML, SML_NAMESPACE_SYNCML10, error))
1765 goto error_free_writer;
1767 case SML_VERSION_11:
1768 xmlTextWriterWriteRaw(assm->writer, (xmlChar *)
"<!DOCTYPE SyncML PUBLIC \"-//SYNCML//DTD SyncML 1.1//EN\" \"http://www.syncml.org/docs/syncml_represent_v11_20020213.dtd\">");
1769 if (!_smlXmlAssemblerStartNodeNS(assm, SML_ELEMENT_SYNCML, SML_NAMESPACE_SYNCML11, error))
1770 goto error_free_writer;
1772 case SML_VERSION_12:
1773 xmlTextWriterWriteRaw(assm->writer, (xmlChar *)
"<!DOCTYPE SyncML PUBLIC \"-//SYNCML//DTD SyncML 1.2//EN\" \"http://www.openmobilealliance.org/tech/DTD/OMA-TS-SyncML_RepPro_DTD-V1_2.dtd\">");
1774 if (!_smlXmlAssemblerStartNodeNS(assm, SML_ELEMENT_SYNCML, SML_NAMESPACE_SYNCML12, error))
1775 goto error_free_writer;
1778 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown version");
1779 goto error_free_writer;
1783 int rc = xmlTextWriterWriteRawLen(assm->writer, xmlBufferContent(assm->header_buffer), xmlBufferLength(assm->header_buffer));
1785 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to write raw header data (%d).", rc);
1786 goto error_free_writer;
1790 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_SYNCBODY, error))
1791 goto error_free_writer;
1795 buffersize += 20 + xmlBufferLength(assm->header_buffer);
1799 SmlBool missingstatus = FALSE;
1800 smlTrace(TRACE_INTERNAL,
"%s: Now adding %i statuses",
1801 __func__, g_list_length(assm->statuses));
1802 for (b = assm->statuses; b; b = b->next) {
1804 if (!status->
buffer || xmlBufferLength(status->
buffer) == 0) {
1805 if (status->
cmdRef == 0 && check) {
1806 smlErrorSet(error, SML_ERROR_GENERIC,
"Reserved status 0 has not been added");
1807 goto error_free_writer;
1809 smlTrace(TRACE_INTERNAL,
"%s: Reserved status %i is missing",
1810 __func__, status->
cmdRef);
1811 missingstatus = TRUE;
1815 buffersize += xmlBufferLength(status->
buffer);
1818 rc = xmlTextWriterWriteRawLen(assm->writer, xmlBufferContent(status->
buffer), xmlBufferLength(status->
buffer));
1820 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to write raw status data (%d - %d of %d: %s).",
1821 rc, xmlBufferLength(status->
buffer),
1822 buffersize, xmlBufferContent(status->
buffer));
1823 goto error_free_writer;
1828 if (missingstatus &&
final && check) {
1829 smlErrorSet(error, SML_ERROR_GENERIC,
"Reserved status has not been added");
1830 goto error_free_writer;
1834 if (!smlXmlAssemblerAddChildren(assm, assm->commands, error))
1835 goto error_free_writer;
1838 smlTrace(TRACE_INTERNAL,
"%s: setting final", __func__);
1839 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_FINAL,
"", error))
1840 goto error_free_writer;
1844 if (!_smlXmlAssemblerEndNode(assm, error))
1845 goto error_free_writer;
1848 if (!_smlXmlAssemblerEndNode(assm, error))
1849 goto error_free_writer;
1851 if (xmlTextWriterEndDocument(assm->writer) < 0) {
1852 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to end writer");
1857 xmlFreeTextWriter(assm->writer);
1858 assm->writer = NULL;
1862 *size = xmlBufferLength(buffer);
1863 *data = g_strndup((
const char *) xmlBufferContent(buffer), *size);
1864 xmlBufferFree(buffer);
1866 if (
final && !assm->commands)
1871 smlTrace(TRACE_INTERNAL,
"%s: Message Assembled: %s",
1872 __func__, VA_STRING(*data));
1874 g_mutex_unlock(assm->mutex);
1875 smlTrace(TRACE_EXIT,
"%s", __func__);
1879 xmlFreeTextWriter(assm->writer);
1880 assm->writer = NULL;
1882 xmlBufferFree(buffer);
1884 g_mutex_unlock(assm->mutex);
1889 static unsigned int calc_list(GList *list)
1891 unsigned int size = 0;
1893 for (; list; list = list->next) {
1896 if (cmd->
nodeType != SML_ASSEMBLER_NODE_CLOSE) {
1897 size += xmlBufferLength(cmd->
buffer);
1899 size += calc_list(cmd->children);
1906 SmlBool smlXmlAssemblerRun(
SmlXmlAssembler *assm,
char **data,
unsigned int *size, SmlBool *end, SmlBool
final,
unsigned int maxsize,
SmlError **error)
1909 SmlBool ans = smlXmlAssemblerRunFull(assm, data, size, end,
final, TRUE, maxsize, error);
1912 smlLog(
"sent-%i.xml", *data, *size);
1924 unsigned int size = 0;
1930 if (assm->header_buffer)
1931 size += xmlBufferLength(assm->header_buffer);
1936 for (b = assm->statuses; b; b = b->next) {
1941 size += xmlBufferLength(status->
buffer);
1945 size += calc_list(assm->commands);
1951 SmlBool smlXmlAssemblerNextCmdRef(
SmlXmlAssembler *assm,
unsigned int *cmdRef,
unsigned int *msgRef)
1959 for (b = assm->statuses; b; b = b->next) {
1962 *cmdRef = status->
cmdRef;
1963 *msgRef = status->msgRef;
1980 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, assembler, functions, error);
1986 assm->assembler = assembler;
1987 assm->mutex = g_mutex_new();
1991 functions->start = (SmlAssemblerStartFunction)smlXmlAssemblerStart;
1992 functions->free = (SmlAssemblerFreeFunction)smlXmlAssemblerFree;
1993 functions->run = (SmlAssemblerRunFunction)smlXmlAssemblerRun;
1994 functions->end = (SmlAssemblerEndFunction)smlXmlAssemblerEnd;
1995 functions->add_header = (SmlAssemblerHeaderFunction)smlXmlAssemblerAddHeader;
1996 functions->start_cmd = (SmlAssemblerStartCommandFunction)smlXmlAssemblerStartCommand;
1997 functions->end_cmd = (SmlAssemblerEndCommandFunction)smlXmlAssemblerEndCommand;
1998 functions->rem_cmd = (SmlAssemblerRemCommandFunction)smlXmlAssemblerRemCommand;
1999 functions->add_status = (SmlAssemblerStatusFunction)smlXmlAssemblerAddStatus;
2000 functions->rem_status = (SmlAssemblerRemStatusFunction)smlXmlAssemblerRemStatus;
2001 functions->reserve_status = (SmlAssemblerReserveStatusFunction)smlXmlAssemblerReserveStatus;
2002 functions->missing_status = (SmlAssemblerStatusMissingFunction)smlXmlAssemblerMissingStatus;
2003 functions->check_size = (SmlAssemblerCheckFunction)smlXmlAssemblerCheckSize;
2004 functions->next_cmdref = (SmlAssemblerNextCmdRefFunction)smlXmlAssemblerNextCmdRef;
2005 functions->flush = (SmlAssemblerFlushFunction)smlXmlAssemblerFlush;
2006 functions->restore_cmds = (SmlAssemblerRestoreCommandsFunction)smlXmlAssemblerRestoreCommands;
2008 smlTrace(TRACE_EXIT,
"%s: %p", __func__, assm);
2012 smlSafeFree((gpointer *)&assm);
2013 smlErrorSet(error, SML_ERROR_GENERIC,
"%s - Cannot create new mutex.", __func__);
2019 static SmlBool _smlXmlDevInfDataStoreAssembleRxTx(
SmlXmlAssembler *assm,
const char *element,
const char *cttype,
const char *version,
SmlError **error)
2021 smlTrace(TRACE_ENTRY,
"%s(%p, %s, %s, %s, %p)", __func__, assm, VA_STRING(element), VA_STRING(cttype), VA_STRING(version), error);
2027 if (!_smlXmlAssemblerStartNode(assm, element, error))
2030 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_CTTYPE, cttype, error))
2033 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_VERCT, version, error))
2036 if (!_smlXmlAssemblerEndNode(assm, error))
2039 smlTrace(TRACE_EXIT,
"%s", __func__);
2047 static SmlBool _smlXmlDevInfDataStoreAssembleCTCap(
2053 smlTrace(TRACE_ENTRY,
"%s(%p, %p)", __func__, assm, ctcap, error);
2061 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_CTCAP, error))
2066 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_CTTYPE, ctcap->ct->cttype, error))
2074 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_VERCT, ctcap->ct->verct, error))
2079 GList *hprop = NULL;
2080 for (hprop = ctcap->properties; hprop; hprop = hprop->next)
2087 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_PROPERTY, error))
2092 if (property->propName != NULL &&
2093 !_smlXmlAssemblerAddString(assm, SML_ELEMENT_PROPNAME, property->propName, error))
2097 if (property->dataType != NULL &&
2098 !_smlXmlAssemblerAddString(assm, SML_ELEMENT_DATATYPE, property->dataType, error))
2102 if (property->maxOccur > 0 &&
2103 !_smlXmlAssemblerAddID(assm, SML_ELEMENT_MAXOCCUR, property->maxOccur, error))
2107 if (property->maxSize > 0) {
2110 if (!_smlXmlAssemblerAddID(
2117 if (!_smlXmlAssemblerAddID(
2119 SML_ELEMENT_MAXSIZE,
2127 if (property->noTruncate)
2129 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_NOTRUNCATE, error))
2131 if (!_smlXmlAssemblerEndNode(assm, error))
2136 if (property->displayName != NULL &&
2137 !_smlXmlAssemblerAddString(assm, SML_ELEMENT_DISPLAYNAME, property->displayName, error))
2141 GList *hvalue = NULL;
2142 for (hvalue = property->valEnums; hvalue; hvalue = hvalue->next)
2144 char *valEnum = hvalue->data;
2147 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_VALENUM, valEnum, error))
2153 GList *hparam = NULL;
2154 for (hparam = property->propParams; hparam; hparam = hparam->next)
2161 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_PROPPARAM, error))
2166 if (param->paramName != NULL &&
2167 !_smlXmlAssemblerAddString(assm, SML_ELEMENT_PARAMNAME, param->paramName, error))
2171 if (param->dataType != NULL &&
2172 !_smlXmlAssemblerAddString(assm, SML_ELEMENT_DATATYPE, param->dataType, error))
2176 if (param->displayName != NULL &&
2177 !_smlXmlAssemblerAddString(assm, SML_ELEMENT_DISPLAYNAME, param->displayName, error))
2182 for (hvalue = param->valEnums; hvalue; hvalue = hvalue->next)
2184 char *valEnum = hvalue->data;
2187 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_VALENUM, valEnum, error))
2195 if (!_smlXmlAssemblerEndNode(assm, error))
2204 if (!_smlXmlAssemblerEndNode(assm, error))
2213 if (!_smlXmlAssemblerEndNode(assm, error))
2217 smlTrace(TRACE_EXIT,
"%s", __func__);
2225 static SmlBool _smlXmlDevInfDataStoreAssemble(
2231 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p, %p)", __func__, assm, datastore, devinf, error);
2233 smlAssert(datastore);
2236 GList *contentTypes = NULL;
2238 if (!datastore->sourceref) {
2239 smlErrorSet(error, SML_ERROR_GENERIC,
"Missing sourceref");
2243 if (!datastore->rxPrefContentType) {
2244 smlErrorSet(error, SML_ERROR_GENERIC,
"Missing rx-pref");
2248 if (!datastore->txPrefContentType) {
2249 smlErrorSet(error, SML_ERROR_GENERIC,
"Missing tx-pref");
2253 if (!datastore->synccap) {
2254 smlErrorSet(error, SML_ERROR_GENERIC,
"No sync capabilities");
2259 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_DATASTORE, error))
2263 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_SOURCEREF, datastore->sourceref, error))
2267 if (datastore->displayname) {
2268 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_DISPLAYNAME, datastore->displayname, error))
2273 if (datastore->maxGUIDSize) {
2274 if (!_smlXmlAssemblerAddID(assm, SML_ELEMENT_MAXGUIDSIZE, datastore->maxGUIDSize, error))
2279 if (!_smlXmlDevInfDataStoreAssembleRxTx(assm, SML_ELEMENT_RXPREF, datastore->rxPrefContentType, datastore->rxPrefVersion, error))
2281 contentTypes = g_list_append(
2283 smlDevInfNewContentType(
2284 datastore->rxPrefContentType,
2285 datastore->rxPrefVersion, error));
2288 if (datastore->rx) {
2290 for (hl = datastore->rx; hl; hl = hl->next)
2293 if (!_smlXmlDevInfDataStoreAssembleRxTx(assm, SML_ELEMENT_RX, ct->cttype, ct->verct, error))
2295 contentTypes = g_list_append(
2297 smlDevInfNewContentType(ct->cttype, ct->verct, error));
2302 if (!_smlXmlDevInfDataStoreAssembleRxTx(assm, SML_ELEMENT_TXPREF, datastore->txPrefContentType, datastore->txPrefVersion, error))
2304 contentTypes = g_list_append(
2306 smlDevInfNewContentType(
2307 datastore->txPrefContentType,
2308 datastore->txPrefVersion, error));
2311 if (datastore->tx) {
2313 for (hl = datastore->tx; hl; hl = hl->next)
2316 if (!_smlXmlDevInfDataStoreAssembleRxTx(assm, SML_ELEMENT_TX, ct->cttype, ct->verct, error))
2318 contentTypes = g_list_append(
2320 smlDevInfNewContentType(ct->cttype, ct->verct, error));
2325 if (devinf->version >= SML_DEVINF_VERSION_12)
2328 for (hct = contentTypes; hct; hct = hct->next) {
2335 if (!_smlXmlDevInfDataStoreAssembleCTCap(assm, ctcap, FALSE, error))
2341 smlTrace(TRACE_INTERNAL,
"%s: found a content type (%s %d) without CTCap",
2342 __func__, VA_STRING(ct->cttype), ct->verct);
2351 contentTypes = g_list_remove(contentTypes, ct);
2352 smlDevInfFreeContentType(ct);
2356 if (datastore->maxmem || datastore->maxid) {
2358 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_DSMEM, error))
2362 if (datastore->sharedMem) {
2363 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_SHAREDMEM,
"", error))
2368 if (datastore->maxid) {
2369 if (!_smlXmlAssemblerAddID(assm, SML_ELEMENT_MAXID, datastore->maxid, error))
2374 if (datastore->maxmem) {
2375 if (!_smlXmlAssemblerAddID(assm, SML_ELEMENT_MAXMEM, datastore->maxmem, error))
2380 if (!_smlXmlAssemblerEndNode(assm, error))
2385 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_SYNCCAP, error))
2389 if (smlDevInfDataStoreGetSyncCap(datastore, SML_DEVINF_SYNCTYPE_TWO_WAY)) {
2390 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_SYNCTYPE,
"1", error))
2393 if (smlDevInfDataStoreGetSyncCap(datastore, SML_DEVINF_SYNCTYPE_SLOW_SYNC)) {
2394 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_SYNCTYPE,
"2", error))
2397 if (smlDevInfDataStoreGetSyncCap(datastore, SML_DEVINF_SYNCTYPE_ONE_WAY_FROM_CLIENT)) {
2398 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_SYNCTYPE,
"3", error))
2401 if (smlDevInfDataStoreGetSyncCap(datastore, SML_DEVINF_SYNCTYPE_REFRESH_FROM_CLIENT)) {
2402 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_SYNCTYPE,
"4", error))
2405 if (smlDevInfDataStoreGetSyncCap(datastore, SML_DEVINF_SYNCTYPE_ONE_WAY_FROM_SERVER)) {
2406 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_SYNCTYPE,
"5", error))
2409 if (smlDevInfDataStoreGetSyncCap(datastore, SML_DEVINF_SYNCTYPE_REFRESH_FROM_SERVER)) {
2410 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_SYNCTYPE,
"6", error))
2413 if (smlDevInfDataStoreGetSyncCap(datastore, SML_DEVINF_SYNCTYPE_SERVER_ALERTED_SYNC)) {
2414 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_SYNCTYPE,
"7", error))
2419 if (!_smlXmlAssemblerEndNode(assm, error))
2423 if (!_smlXmlAssemblerEndNode(assm, error))
2426 smlTrace(TRACE_EXIT,
"%s", __func__);
2434 SmlBool smlXmlDevInfAssemble(
SmlDevInf *devinf, SmlDevInfVersion version,
char **data,
unsigned int *size,
SmlError **error)
2436 smlTrace(TRACE_ENTRY,
"%s(%p, %i, %p, %p, %p)", __func__, devinf, version, data, size, error);
2444 smlTrace(TRACE_INTERNAL,
"%s: devinf version: %i, version: %i", __func__, devinf->version, version);
2445 if (devinf->version == SML_DEVINF_VERSION_UNKNOWN)
2446 devinf->version = version;
2447 if (version == SML_DEVINF_VERSION_UNKNOWN)
2448 version = devinf->version;
2449 smlAssert(devinf->version == version);
2456 xmlBuffer *buffer = xmlBufferCreateSize(BUFFER_SIZE);
2458 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to create new buffer");
2459 goto error_free_assm;
2462 assm->writer = xmlNewTextWriterMemory(buffer, 0);
2463 if (!assm->writer) {
2464 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to create new writer");
2465 goto error_free_buffer;
2469 if (!_smlXmlAssemblerStartNodeNS(assm, SML_ELEMENT_DEVINF, SML_NAMESPACE_DEVINF, error))
2470 goto error_free_writer;
2474 case SML_DEVINF_VERSION_12:
2475 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_VERDTD,
"1.2", error))
2476 goto error_free_writer;
2478 case SML_DEVINF_VERSION_11:
2479 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_VERDTD,
"1.1", error))
2480 goto error_free_writer;
2482 case SML_DEVINF_VERSION_10:
2483 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_VERDTD,
"1.0", error))
2484 goto error_free_writer;
2486 case SML_DEVINF_VERSION_UNKNOWN:
2487 smlErrorSet(error, SML_ERROR_GENERIC,
"Unknown devinf version");
2488 goto error_free_writer;
2493 if (devinf->manufacturer) {
2494 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_MAN, devinf->manufacturer, error))
2495 goto error_free_writer;
2499 if (devinf->model) {
2500 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_MOD, devinf->model, error))
2501 goto error_free_writer;
2506 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_OEM, devinf->oem, error))
2507 goto error_free_writer;
2511 if (devinf->firmwareVersion) {
2512 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_FWV, devinf->firmwareVersion, error))
2513 goto error_free_writer;
2517 if (devinf->softwareVersion) {
2518 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_SWV, devinf->softwareVersion, error))
2519 goto error_free_writer;
2523 if (devinf->hardwareVersion) {
2524 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_HWV, devinf->hardwareVersion, error))
2525 goto error_free_writer;
2529 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_DEVID, devinf->devid, error))
2530 goto error_free_writer;
2533 const char *devtype = smlDevInfDevTypeToString(devinf->devtyp, error);
2535 goto error_free_writer;
2537 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_DEVTYPE, devtype, error))
2538 goto error_free_writer;
2541 if (devinf->supportsUTC && version != SML_DEVINF_VERSION_10) {
2542 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_UTC,
"", error))
2543 goto error_free_writer;
2547 if (devinf->supportsLargeObjs && version != SML_DEVINF_VERSION_10) {
2548 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_SUPPORTLARGEOBJS,
"", error))
2549 goto error_free_writer;
2553 if (devinf->supportsNumberOfChanges && version != SML_DEVINF_VERSION_10) {
2554 if (!_smlXmlAssemblerAddString(assm, SML_ELEMENT_SUPPORTNUMBEROFCHANGES,
"", error))
2555 goto error_free_writer;
2560 for (d = devinf->datastores; d; d = d->next) {
2562 if (!_smlXmlDevInfDataStoreAssemble(assm, datastore, devinf, error))
2563 goto error_free_writer;
2568 devinf->version < SML_DEVINF_VERSION_12 &&
2570 if (!_smlXmlAssemblerStartNode(assm, SML_ELEMENT_CTCAP, error))
2571 goto error_free_writer;
2573 for (d = devinf->ctcaps; d; d = d->next) {
2576 if (!_smlXmlDevInfDataStoreAssembleCTCap(assm, ctcap, TRUE, error))
2577 goto error_free_writer;
2580 if (!_smlXmlAssemblerEndNode(assm, error))
2581 goto error_free_writer;
2585 if (!_smlXmlAssemblerEndNode(assm, error))
2586 goto error_free_writer;
2589 if (xmlTextWriterEndDocument(assm->writer) < 0) {
2590 smlErrorSet(error, SML_ERROR_GENERIC,
"Unable to end writer");
2591 goto error_free_writer;
2594 xmlFreeTextWriter(assm->writer);
2595 assm->writer = NULL;
2597 *size = xmlBufferLength(buffer);
2598 *data = g_strndup((
const char *) xmlBufferContent(buffer), *size);
2600 xmlBufferFree(buffer);
2602 smlSafeFree((gpointer *)&assm);
2604 smlTrace(TRACE_INTERNAL,
"Message Assembled: %s", *data);
2606 smlTrace(TRACE_EXIT,
"%s", __func__);
2610 xmlFreeTextWriter(assm->writer);
2611 assm->writer = NULL;
2613 xmlBufferFree(buffer);
2615 smlSafeFree((gpointer *)&assm);
2624 smlTrace(TRACE_ENTRY,
"%s", __func__);
2625 smlAssert(assm->commands == NULL);
2627 assm->commands = assm->last_commands;
2628 assm->last_commands = NULL;
2630 smlTrace(TRACE_EXIT,
"%s", __func__);
const char * smlErrorPrint(SmlError **error)
Returns the message of the error.
const char * smlAssemblerGetOption(SmlAssembler *assm, const char *optionname)
Gets a option from the assembler.
SmlXmlAssemblerNodeType nodeType
SmlBool smlItemGetData(SmlItem *item, char **data, unsigned int *size, SmlError **error)
SmlXmlAssembler * smlXmlAssemblerNew(SmlAssembler *assembler, SmlAssemblerFunctions *functions, SmlError **error)
Creates a new XML assembler.
void smlTrace(SmlTraceType type, const char *message,...)
Used for tracing the application.
void * smlTryMalloc0(long n_bytes, SmlError **error)
Safely mallocs.
void smlErrorSet(SmlError **error, SmlErrorType type, const char *format,...)
Sets the error.