24 #include "syncml_internals.h"
25 #include "sml_error_internals.h"
26 #include "sml_queue_internals.h"
27 #include "sml_session_internals.h"
28 #include "sml_command_internals.h"
29 #include "sml_elements_internals.h"
30 #include "sml_parse_internals.h"
31 #include "sml_transport_internals.h"
32 #include "objects/sml_auth_internals.h"
42 typedef enum SmlSessionCommandType {
43 SML_SESSION_COMMAND_START,
44 SML_SESSION_COMMAND_END,
47 } SmlSessionCommandType;
50 SmlSessionCommandType type;
54 SmlStatusReplyCb callback;
55 void *callbackUserdata;
62 smlTrace(TRACE_ENTRY,
"%s(%p, %i, %p, %p, %p, %p)", __func__, session, type, cmd, parent, headerreply, error);
64 smlAssert(session->eventCallback);
66 session->eventCallback(session, type, cmd, parent, headerreply, error, session->eventCallbackUserdata);
68 smlTrace(TRACE_EXIT,
"%s", __func__);
71 static void _smlSessionFreePendingReplies(
SmlSession *session)
73 while (session->pendingReplies) {
74 smlSafeFree((gpointer *)&(session->pendingReplies->data));
75 session->pendingReplies = g_list_delete_link(session->pendingReplies, session->pendingReplies);
93 static SmlBool _smlSessionFlushInternal(
SmlSession *session, SmlBool
final,
SmlError **error)
95 smlTrace(TRACE_ENTRY,
"%s(%p, %i, %p)", __func__, session,
final, error);
98 smlAssert(session->dataCallback);
101 unsigned int size = 0;
109 if (!
smlAssemblerRun(session->assembler, &data, &size, &end,
final, error))
111 if (session->authenticate)
115 if (session->lastCommandID > 1)
121 smlTrace(TRACE_INTERNAL,
"%s: flushed assembler - last command id is %i now",
122 __func__, session->lastCommandID);
124 SmlTransportData *tspdata = smlTransportDataNew(data, size, session->type, TRUE, error);
126 goto error_free_data;
129 if (end && session->sessionType == SML_SESSION_TYPE_SERVER)
133 if (!session->authenticate)
134 smlSessionDispatchEvent(session, SML_SESSION_EVENT_FLUSH, NULL, NULL, NULL, NULL);
137 session->dataCallback(session, tspdata, session->dataCallbackUserdata);
139 smlTransportDataDeref(tspdata);
141 session->waiting = TRUE;
144 session->sending = FALSE;
146 if (end && session->sessionType == SML_SESSION_TYPE_SERVER) {
147 smlTrace(TRACE_INTERNAL,
"%s: Ending session now", __func__);
149 smlSessionRestoreTargetURI(session);
150 g_mutex_lock(session->reportEnd);
151 if (!session->reportedEnd) {
153 session->reportedEnd = TRUE;
154 smlSessionDispatchEvent(session, SML_SESSION_EVENT_END,
155 NULL, NULL, NULL, NULL);
157 g_mutex_unlock(session->reportEnd);
160 smlTrace(TRACE_INTERNAL,
"%s: incrementing lastMessageID %d (old)",
161 __func__, session->lastMessageID);
162 session->lastMessageID++;
164 session->hasCommand = FALSE;
166 smlTrace(TRACE_EXIT,
"%s", __func__);
178 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, session, status, userdata);
180 smlTrace(TRACE_EXIT,
"%s", __func__);
183 static void _smlSessionFragmentStatus(
SmlSession *session,
SmlStatus *status,
void *userdata)
185 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, session, status, userdata);
188 smlTrace(TRACE_INTERNAL,
"%s: Got a status reply %i", __func__, status->type);
190 if (smlStatusGetCode(status) != SML_CHUNK_ACCEPTED) {
193 smlCommandUnref(session->frag_command);
194 session->frag_command = NULL;
197 smlTrace(TRACE_EXIT,
"%s", __func__);
209 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p, %i, %i, %i, %p)", __func__, session, orig_cmd, parent, space, start, complete_size, error);
215 smlAssert(g_list_length(orig_cmd->private.change.items) == 1);
219 unsigned int size = 0;
220 SmlItem *orig_item = g_list_nth_data(orig_cmd->private.change.items, 0);
227 if (space < size - start) {
230 frag_cmd = smlCommandNew(orig_cmd->type, error);
234 SmlItem *frag_item = smlItemNewForData(data + start, space, error);
237 frag_cmd->private.change.items = g_list_append (NULL, frag_item);
238 if (!frag_cmd->private.change.items)
240 smlItemUnref(frag_item);
244 frag_item->moreData = TRUE;
246 frag_item->target = orig_item->target;
247 if (frag_item->target)
248 smlLocationRef(frag_item->target);
250 frag_item->source = orig_item->source;
251 if (frag_item->source)
252 smlLocationRef(frag_item->source);
254 frag_item->contenttype = g_strdup(orig_item->contenttype);
261 frag_cmd->size = complete_size;
263 session->frag_size += space;
272 smlAssert(g_list_length(orig_cmd->private.change.items) == 1);
273 smlAssert(g_list_remove(orig_cmd->private.change.items, orig_item) == NULL);
274 orig_cmd->private.change.items = NULL;
277 SmlItem *frag_item = smlItemNewForData(data + start, size - start, error);
279 smlItemUnref(orig_item);
282 orig_cmd->private.change.items = g_list_append(NULL, frag_item);
283 if (!orig_cmd->private.change.items)
285 smlItemUnref(orig_item);
286 smlItemUnref(frag_item);
291 frag_item->contenttype = g_strdup(orig_item->contenttype);
292 frag_item->target = orig_item->target;
293 if (frag_item->target)
294 smlLocationRef(frag_item->target);
295 frag_item->source = orig_item->source;
296 if (frag_item->source)
297 smlLocationRef(frag_item->source);
300 smlItemUnref(orig_item);
304 session->frag_size += size - start;
308 smlTrace(TRACE_EXIT,
"%s: %p", __func__, frag_cmd);
312 smlCommandUnref(frag_cmd);
318 static SmlAssemblerResult _smlSessionStartCommandInternal(
SmlSession *session,
SmlCommand *cmd,
SmlCommand *parent, SmlStatusReplyCb callback,
void *userdata, SmlBool addToCommandStack,
SmlError **error)
320 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p, %p, %p, %i, %p)", __func__, session, cmd, parent, callback, userdata, addToCommandStack, error);
325 SmlBool fragmented = FALSE;
327 if (parent && !session->hasCommand) {
331 GList * cmds = g_list_copy(session->commandStack);
332 for (c = cmds; c; c = c->next) {
335 if (_smlSessionStartCommandInternal(session, oldcmd, oldparent, _check_reply, NULL, FALSE, error) != SML_ASSEMBLER_RESULT_OK)
344 if ((cmd->type == SML_COMMAND_TYPE_ADD || cmd->type == SML_COMMAND_TYPE_REPLACE) &&
345 smlAssemblerGetRemoteMaxMsgSize(session->assembler) > 0 && session->version != SML_VERSION_10) {
347 smlTrace(TRACE_INTERNAL,
"%s: Checking if command needs to be fragmented", __func__);
352 smlAssert(g_list_length(cmd->private.change.items) == 1);
355 unsigned int size = 0;
356 SmlItem *item = g_list_nth_data(cmd->private.change.items, 0);
363 if ((sendingmaxobjsize > 0) &&
364 (size > (
unsigned int)sendingmaxobjsize))
370 if (!session->frag_command)
372 item->moreData = TRUE;
377 item->moreData = FALSE;
380 if (session->frag_command ||
382 (
unsigned int) space < size - session->frag_size))
384 smlTrace(TRACE_INTERNAL,
"%s: Space %i, size %i. Fragmenting. Already added: %i", __func__, space, size - session->frag_size, session->frag_size);
388 if (!session->frag_command) {
389 session->frag_size = 0;
391 session->frag_command = cmd;
394 session->frag_callback = callback;
395 session->frag_userdata = userdata;
398 if (!(cmd = _smlSessionFragmentSend(session, session->frag_command, parent, space, session->frag_size, size, error)))
401 callback = _smlSessionFragmentStatus;
409 item = g_list_nth_data(cmd->private.change.items, 0);
410 if (item->moreData == FALSE) {
411 smlTrace(TRACE_INTERNAL,
"%s: This is the last chunk", __func__);
413 callback = session->frag_callback;
414 userdata = session->frag_userdata;
417 session->frag_size = 0;
419 smlCommandUnref(session->frag_command);
420 session->frag_command = NULL;
423 smlTrace(TRACE_INTERNAL,
"%s: Fragmented. Added %i already", __func__, session->frag_size);
428 session->lastCommandID++;
429 cmd->cmdID = session->lastCommandID;
430 smlTrace(TRACE_INTERNAL,
"%s: last command id is %i", __func__, session->lastCommandID);
434 case SML_ASSEMBLER_RESULT_OK:
438 case SML_ASSEMBLER_RESULT_MISMATCH:
440 smlErrorSet(error, SML_ERROR_GENERIC,
"Command is too large");
447 if (!_smlSessionFlushInternal(session, FALSE, error)) {
448 session->lastCommandID--;
452 smlTrace(TRACE_EXIT,
"%s: Mismatch", __func__);
453 return SML_ASSEMBLER_RESULT_MISMATCH;
454 case SML_ASSEMBLER_RESULT_ERROR:
455 session->lastCommandID--;
465 session->lastCommandID--;
469 pending->callback = callback;
470 pending->userdata = userdata;
471 pending->cmdID = cmd->cmdID;
472 pending->msgID = session->lastMessageID;
474 smlTrace(TRACE_INTERNAL,
"%s: Appending pending status with cmdID %i and msgID %i", __func__, pending->cmdID, pending->msgID);
475 session->pendingReplies = g_list_append(session->pendingReplies, pending);
481 if (cmd->type == SML_COMMAND_TYPE_GET) {
484 session->lastCommandID--;
488 pending->callback = callback;
489 pending->userdata = userdata;
490 pending->cmdID = cmd->cmdID;
491 pending->msgID = session->lastMessageID;
493 smlTrace(TRACE_INTERNAL,
"%s: Appending pending status for a result with cmdID %i and msgID %i", __func__, pending->cmdID, pending->msgID);
494 session->pendingReplies = g_list_append(session->pendingReplies, pending);
500 if (!_smlSessionFlushInternal(session, FALSE, error)) {
501 session->lastCommandID--;
505 smlCommandUnref(cmd);
507 smlTrace(TRACE_EXIT,
"%s: Mismatch but fragmented", __func__);
508 return SML_ASSEMBLER_RESULT_MISMATCH;
511 if (addToCommandStack)
512 session->commandStack = g_list_append(session->commandStack, cmd);
513 session->hasCommand = TRUE;
515 smlTrace(TRACE_EXIT,
"%s", __func__);
516 return SML_ASSEMBLER_RESULT_OK;
520 return SML_ASSEMBLER_RESULT_ERROR;
525 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, session, parent, error);
532 session->commandStack = g_list_delete_link(session->commandStack, g_list_last(session->commandStack));
534 smlTrace(TRACE_EXIT,
"%s", __func__);
545 smlCommandUnref(sesscmd->cmd);
548 smlCommandUnref(sesscmd->parent);
551 smlStatusUnref(sesscmd->status);
553 smlSafeFree((gpointer *)&sesscmd);
556 static void _smlSessionCommandHandler(
void *message,
void *userdata)
558 smlTrace(TRACE_ENTRY,
"%s", __func__);
565 smlTrace(TRACE_INTERNAL,
"%s: session cmd type %i", __func__, sesscmd->type);
568 if (!session->assmHasHeader)
572 session->assmHasHeader = TRUE;
579 switch (sesscmd->type) {
580 case SML_SESSION_FLUSH:
583 smlTrace(TRACE_INTERNAL,
"%s: End on flush was set", __func__);
585 if (!_smlSessionFlushInternal(session, sesscmd->final, &error))
588 case SML_SESSION_COMMAND_END:
589 if (!_smlSessionEndCommandInternal(session, parent, &error))
592 case SML_SESSION_COMMAND_START:
593 switch (_smlSessionStartCommandInternal(session, cmd, parent, sesscmd->callback, sesscmd->callbackUserdata, TRUE, &error)) {
594 case SML_ASSEMBLER_RESULT_OK:
597 case SML_ASSEMBLER_RESULT_MISMATCH:
598 smlQueuePushHead(session->command_queue, message);
600 case SML_ASSEMBLER_RESULT_ERROR:
604 case SML_SESSION_STATUS:;
605 unsigned int cmdRef, msgRef = 0;
606 if (!smlAssemblerGetNextCmdRef(session->assembler, &cmdRef, &msgRef)) {
607 smlErrorSet(&error, SML_ERROR_GENERIC,
"No more statuses were needed");
611 if (status->cmdRef != cmdRef || status->msgRef != msgRef) {
615 "%s - next needed command status %d for message %d is not this one (cmd %d, msg %d)",
616 __func__, cmdRef, msgRef, status->cmdRef, status->msgRef);
627 smlTrace(TRACE_INTERNAL,
"%s - try to add status", __func__);
629 case SML_ASSEMBLER_RESULT_OK:
631 session->active = TRUE;
633 case SML_ASSEMBLER_RESULT_MISMATCH:
636 if (!_smlSessionFlushInternal(session, FALSE, &error)) {
637 session->lastCommandID--;
642 smlQueuePushHeadPrio(session->command_queue, message);
643 smlTrace(TRACE_EXIT,
"%s - status cannot be added, so push back", __func__);
646 case SML_ASSEMBLER_RESULT_ERROR:
652 _smlSessionCommandFree(sesscmd);
653 smlTrace(TRACE_EXIT,
"%s", __func__);
658 smlSessionDispatchEvent(session, SML_SESSION_EVENT_ERROR, NULL, NULL, NULL, error);
659 _smlSessionCommandFree(sesscmd);
665 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, session, header, error);
671 if (header->messageID <= session->lastReceivedMessageID) {
672 smlErrorSet(error, SML_ERROR_GENERIC,
"Message ID not incremented");
675 session->lastReceivedMessageID = header->messageID;
676 session->lastCommandID++;
679 if (0 < header->maxmsgsize) {
685 smlAssemblerSetRemoteMaxMsgSize(session->assembler, header->maxmsgsize);
687 if (0 < header->maxmsgsize && header->maxmsgsize < session->localMaxMsgSize)
694 smlSessionSetLocalMaxMsgSize(session, header->maxmsgsize);
704 if (header->responseURI) {
705 if (!session->orgTarget) {
712 session->orgTarget = session->target;
713 session->target = NULL;
716 if (session->target) {
722 smlLocationUnref(session->target);
726 session->target = smlLocationNew(
728 smlLocationGetName(session->orgTarget),
730 if (!session->target)
732 smlSessionDispatchEvent(session, SML_SESSION_EVENT_RESPONSE_URI, NULL, NULL, NULL, NULL);
733 smlTrace(TRACE_INTERNAL,
"%s: RespURI: %s, Target: %s", __func__,
734 VA_STRING(smlLocationGetURI(session->target)),
735 VA_STRING(smlLocationGetURI(session->orgTarget)));
745 const char *header_source = smlLocationGetURI(header->source);
746 const char *session_target = smlLocationGetURI(session->target);
749 strcmp(header_source, session_target))
753 "%s: update session target to header source %s",
754 __func__, header_source);
755 smlLocationSetURI(session->target, header_source);
758 smlTrace(TRACE_EXIT,
"%s", __func__);
768 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, session, status, error);
772 if (status->cmdRef == 0) {
773 smlAssert(status->type == SML_COMMAND_TYPE_HEADER);
774 smlAssert(status->data);
775 SmlErrorType errorCode = atoi(status->data);
776 if (session->sessionType == SML_SESSION_TYPE_SERVER)
788 SmlCommand *cmd = smlCommandNew(SML_COMMAND_TYPE_HEADER, error);
789 smlSessionDispatchEvent(session, SML_SESSION_EVENT_HEADER_REPLY, cmd, NULL, status, NULL);
790 smlCommandUnref(cmd);
792 else if (errorCode == SML_AUTH_ACCEPTED)
798 smlTrace(TRACE_INTERNAL,
"%s - authentication succeeded", __func__);
799 if (session->cred != NULL)
801 smlCredUnref(session->cred);
802 session->cred = NULL;
804 if (!session->established)
806 session->established = TRUE;
807 smlSessionDispatchEvent(
808 session, SML_SESSION_EVENT_ESTABLISHED,
809 NULL, NULL, NULL, NULL);
812 else if (errorCode == SML_ERROR_AUTH_REQUIRED)
819 smlTrace(TRACE_INTERNAL,
"%s - authentication required", __func__);
820 session->authenticate = TRUE;
821 session->established = FALSE;
822 smlAssemblerRestoreCommands(session->assembler);
823 smlTrace(TRACE_INTERNAL,
"%s - restored commands from previous message", __func__);
824 smlAssert(status->chal);
825 smlAssert(session->cred);
826 if (session->cred->type == SML_AUTH_TYPE_MD5 &&
827 status->chal->type != SML_AUTH_TYPE_MD5)
829 smlErrorSet(error, SML_ERROR_AUTH_REJECTED,
"The remote peer tries to enforce an authentication method which violates the local security policy (syncml:auth-md5 is required).");
832 smlTrace(TRACE_INTERNAL,
"%s - authentication type conforms to security policy", __func__);
835 session->cred->data = smlAuthGetCredString(
837 session->cred->username,
838 session->cred->password,
839 status->chal->nonce_b64,
841 if (!session->cred->data)
843 smlTrace(TRACE_INTERNAL,
"%s - credential string set", __func__);
845 if (!session->established)
847 session->established = TRUE;
848 smlSessionDispatchEvent(
849 session, SML_SESSION_EVENT_ESTABLISHED,
850 NULL, NULL, NULL, NULL);
852 SmlCommand *cmd = smlCommandNew(SML_COMMAND_TYPE_HEADER, error);
853 smlSessionDispatchEvent(session, SML_SESSION_EVENT_HEADER_REPLY, cmd, NULL, status, NULL);
854 smlCommandUnref(cmd);
858 smlTrace(TRACE_INTERNAL,
"%s - no header status", __func__);
866 SmlBool foundPending = FALSE;
867 for (o = session->pendingReplies; o; o = o ? o->next : NULL ) {
869 smlTrace(TRACE_INTERNAL,
"%s: check cmd %i of msg %i", __func__, pending->cmdID, pending->msgID);
870 if (pending->cmdID == status->cmdRef && pending->msgID == status->msgRef) {
871 smlTrace(TRACE_INTERNAL,
"%s - Found pending status %s of command %d in message %d",
872 __func__, VA_STRING(status->data), status->cmdRef, status->msgRef);
873 if (session->authenticate)
882 smlTrace(TRACE_INTERNAL,
"%s - update message ID to %d",
883 __func__, session->lastMessageID);
887 smlTrace(TRACE_INTERNAL,
"%s - normal status", __func__);
888 session->pendingReplies = g_list_remove(session->pendingReplies, pending);
890 smlAssert(pending->callback);
891 pending->callback(session, status, pending->userdata);
893 smlSafeFree((gpointer *)&pending);
909 smlTrace(TRACE_INTERNAL,
"%s - no pending reply found", __func__);
914 if (status->type == SML_COMMAND_TYPE_ALERT && !status->anchor) {
915 smlTrace(TRACE_INTERNAL,
"%s: Handling status for server alerted sync", __func__);
916 SmlErrorType errorCode = atoi(status->data);
917 if ((199 < errorCode && errorCode < 300) ||
927 smlErrorSet(error, errorCode,
"The SAN alert was rejected.");
933 "Received unwanted status %s of command %d in message %d",
934 status->data, status->cmdRef, status->msgRef);
937 smlTrace(TRACE_EXIT,
"%s", __func__);
948 if (session->waiting)
950 smlTrace(TRACE_INTERNAL,
"%s: waiting", __func__);
957 result = smlQueueCheck(session->command_queue);
958 smlTrace(TRACE_INTERNAL,
"%s: no status is missing - %i", __func__, result);
962 result = smlQueueCheckPrio(session->command_queue);
963 smlTrace(TRACE_INTERNAL,
"%s: status is missing - %i", __func__, result);
968 SmlBool smlSessionTryLock(
SmlSession *session)
970 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, session);
972 smlAssert(session->dispatch_mutex);
973 SmlBool ret = g_mutex_trylock(session->dispatch_mutex);
974 smlTrace(TRACE_EXIT,
"%s - %d", __func__, ret);
980 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, session);
982 smlAssert(session->dispatch_mutex);
983 g_mutex_lock(session->dispatch_mutex);
984 smlTrace(TRACE_EXIT,
"%s", __func__);
989 smlTrace(TRACE_ENTRY,
"%s", __func__);
991 smlAssert(session->dispatch_mutex);
992 g_mutex_unlock(session->dispatch_mutex);
993 smlTrace(TRACE_EXIT,
"%s", __func__);
998 smlTrace(TRACE_ENTRY,
"%s", __func__);
1001 if (session->waiting)
1003 smlTrace(TRACE_EXIT,
"%s - session is waiting", __func__);
1012 smlTrace(TRACE_INTERNAL,
"%s: dispatch commands", __func__);
1013 smlQueueDispatch(session->command_queue);
1017 smlTrace(TRACE_INTERNAL,
"%s: dispatch status", __func__);
1018 smlQueueDispatchPrio(session->command_queue);
1020 smlTrace(TRACE_EXIT,
"%s - done", __func__);
1025 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, session, parser, error);
1031 SmlParserResult result = SML_PARSER_RESULT_ERROR;
1032 SmlBool isSan = TRUE;
1034 if (session->sessionType == SML_SESSION_TYPE_SERVER)
1044 session->waiting = FALSE;
1045 session->sending = FALSE;
1051 goto error_free_status;
1074 if (session->lastMessageID == 1)
1077 smlTrace(TRACE_INTERNAL,
"%s - reply to SAN detected", __func__);
1078 session->lastMessageID = 2;
1082 if (!smlSessionDispatchStatus(session, status, error))
1083 goto error_free_status;
1085 smlStatusUnref(status);
1091 if (result == SML_PARSER_RESULT_ERROR)
1092 goto error_free_cmd;
1093 if (result == SML_PARSER_RESULT_OTHER)
1097 cmd->msgID = session->lastReceivedMessageID;
1104 if (!session->established && !isSan) {
1105 session->lastCommandID++;
1108 if (!
smlAssemblerReserveStatus(session->assembler, cmd->cmdID, session->lastReceivedMessageID, session->lastCommandID, error))
1109 goto error_free_cmd;
1113 cmd, SML_ERROR_AUTH_REQUIRED, error);
1115 goto error_free_cmd;
1117 goto error_free_cmd;
1118 smlStatusUnref(reply);
1119 smlCommandUnref(cmd);
1124 case SML_PARSER_RESULT_OPEN:
1125 session->lastCommandID++;
1127 if (!
smlAssemblerReserveStatus(session->assembler, cmd->cmdID, session->lastReceivedMessageID, session->lastCommandID, error))
1128 goto error_free_cmd;
1131 if (session->parentCommand) {
1132 smlErrorSet(error, SML_ERROR_GENERIC,
"Already had a parent");
1133 goto error_free_cmd;
1139 if (cmd->type == SML_COMMAND_TYPE_SYNC) {
1140 smlTrace(TRACE_INTERNAL,
"%s: maxObjSize: %i, numbOfChanges: %i, %i",
1142 cmd->private.sync.maxObjSize,
1143 cmd->private.sync.hasNumChanged,
1144 cmd->private.sync.numChanged);
1147 if (cmd->private.sync.maxObjSize >= 0)
1164 session->parentCommand = cmd;
1165 cmd->msgID = session->lastReceivedMessageID;
1167 if (!session->end) {
1168 smlSessionDispatchEvent(session, SML_SESSION_EVENT_COMMAND_START, cmd, NULL, NULL, NULL);
1170 smlTrace(TRACE_INTERNAL,
"%s: Replying with 407 since the session has ended",
1172 SmlStatus *reply = smlCommandNewReply(cmd, SML_ERROR_AUTH_REQUIRED, error);
1174 goto error_free_cmd;
1177 goto error_free_cmd;
1179 smlStatusUnref(reply);
1182 case SML_PARSER_RESULT_NORMAL:
1183 session->lastCommandID++;
1185 if (!
smlAssemblerReserveStatus(session->assembler, cmd->cmdID, session->lastReceivedMessageID, session->lastCommandID, error))
1186 goto error_free_cmd;
1189 if (cmd->type == SML_COMMAND_TYPE_ALERT) {
1190 if (cmd->private.alert.type == SML_ALERT_NEXT_MESSAGE) {
1191 SmlStatus *reply = smlCommandNewReply(cmd, SML_NO_ERROR, error);
1193 goto error_free_cmd;
1196 goto error_free_cmd;
1198 smlStatusUnref(reply);
1200 smlCommandUnref(cmd);
1203 smlTrace(TRACE_INTERNAL,
"%s: Alert maxObjSize: %i",
1204 __func__, cmd->private.alert.maxObjSize);
1205 if (cmd->private.alert.maxObjSize >= 0)
1206 smlAssemblerSetRemoteMaxObjSize(session->assembler, cmd->private.alert.maxObjSize);
1211 if (cmd->type == SML_COMMAND_TYPE_ADD || cmd->type == SML_COMMAND_TYPE_REPLACE) {
1213 SmlItem *lastItem = g_list_nth_data(cmd->private.change.items,
1214 g_list_length(cmd->private.change.items) - 1);
1216 if (session->incomingBuffer) {
1226 smlTrace(TRACE_INTERNAL,
"%s: Appending to incoming buffer", __func__);
1233 "Only the first chunk can have the size set");
1234 goto error_free_cmd;
1242 unsigned int size = 0;
1243 SmlItem *item = g_list_nth_data(cmd->private.change.items, 0);
1245 goto error_free_cmd;
1247 goto error_free_cmd;
1248 lastItem = g_list_nth_data(session->incomingBuffer->private.change.items, g_list_length(session->incomingBuffer->private.change.items) - 1);
1249 if (!smlItemAddData(lastItem, data, size, error))
1250 goto error_free_cmd;
1251 lastItem->moreData = item->moreData;
1253 "%s: Appended %i to buffer. Buffer size: %i. Required: %i",
1255 xmlBufferLength(lastItem->buffer),
1260 for (i=1; i < g_list_length(cmd->private.change.items); i++)
1262 item = g_list_nth_data(cmd->private.change.items, i);
1263 session->incomingBuffer->private.change.items =
1265 session->incomingBuffer->private.change.items,
1268 smlItemUnref(g_list_nth_data(cmd->private.change.items, 0));
1269 g_list_free(cmd->private.change.items);
1270 cmd->private.change.items = NULL;
1275 lastItem = g_list_nth_data(session->incomingBuffer->private.change.items, g_list_length(session->incomingBuffer->private.change.items) - 1);
1276 if (!lastItem->moreData) {
1278 "%s: Command buffer complete. Dispatching.",
1284 SmlStatus *reply = smlCommandNewReply(cmd, SML_ERROR_SIZE_MISMATCH, error);
1286 goto error_free_cmd;
1288 goto error_free_cmd;
1289 smlStatusUnref(reply);
1291 "Chunked item size mismatch");
1292 goto error_free_cmd;
1301 cmd->private.change.items =
1302 session->incomingBuffer->private.change.items;
1303 session->incomingBuffer->private.change.items = NULL;
1304 smlCommandUnref(session->incomingBuffer);
1305 session->incomingBuffer = NULL;
1307 }
else if (lastItem->moreData) {
1315 smlErrorSet(error, SML_ERROR_GENERIC,
"First MoreData item didn't have size set");
1316 goto error_free_cmd;
1319 session->incomingBuffer = cmd;
1321 smlTrace(TRACE_INTERNAL,
"%s: New Buffer started. Buffered item size: %i. Required: %i",
1323 xmlBufferLength(lastItem->buffer),
1326 char *bin =
smlPrintBinary((
char *) xmlBufferContent(lastItem->buffer), xmlBufferLength(lastItem->buffer));
1327 smlTrace(TRACE_INTERNAL,
"%s: Content so far: %s\n",
1328 __func__, VA_STRING(bin));
1332 if (lastItem->moreData == TRUE) {
1333 smlTrace(TRACE_INTERNAL,
"%s: Got item with moreData %i",
1334 __func__, cmd->msgID);
1336 SmlStatus *reply = smlCommandNewReply(cmd, SML_CHUNK_ACCEPTED, error);
1338 goto error_free_cmd;
1341 goto error_free_cmd;
1343 smlStatusUnref(reply);
1345 smlCommandUnref(cmd);
1351 if (cmd->type == SML_COMMAND_TYPE_RESULTS) {
1353 if (!smlSessionDispatchStatus(session, cmd->private.results.status, error))
1354 goto error_free_status;
1357 cmd->msgID = session->lastReceivedMessageID;
1358 if (!session->end) {
1359 if (!session->parentCommand) {
1360 smlSessionDispatchEvent(session, SML_SESSION_EVENT_COMMAND_START, cmd, NULL, NULL, NULL);
1362 smlSessionDispatchEvent(session, SML_SESSION_EVENT_CHILD_COMMAND, cmd, session->parentCommand, NULL, NULL);
1365 smlTrace(TRACE_INTERNAL,
"%s: Replying with 407 since the session has ended2",
1367 SmlStatus *reply = smlCommandNewReply(cmd, SML_ERROR_AUTH_REQUIRED, error);
1369 goto error_free_cmd;
1372 goto error_free_cmd;
1374 smlStatusUnref(reply);
1378 smlCommandUnref(cmd);
1380 case SML_PARSER_RESULT_CLOSE:
1387 if (session->parentCommand->type == SML_COMMAND_TYPE_SYNC) {
1388 smlSessionDispatchEvent(
1390 SML_SESSION_EVENT_COMMAND_END,
1391 session->parentCommand,
1395 smlCommandUnref(session->parentCommand);
1396 session->parentCommand = NULL;
1398 case SML_PARSER_RESULT_STATUS:
1401 goto error_free_cmd;
1410 SmlBool
final = FALSE;
1411 SmlBool end = FALSE;
1413 goto error_free_cmd;
1417 if (
final && !session->authenticate) {
1428 session->sending = TRUE;
1429 smlSessionDispatchEvent(session, SML_SESSION_EVENT_FINAL, NULL, NULL, NULL, NULL);
1438 unsigned int cmdRef, msgRef;
1439 if (!smlAssemblerGetNextCmdRef(session->assembler, &cmdRef, &msgRef))
1441 smlTrace(TRACE_INTERNAL,
"%s: command %d of message %d found",
1442 __func__, cmdRef, msgRef);
1454 unsigned int num = smlQueueLengthPrio(session->command_queue);
1455 smlTrace(TRACE_INTERNAL,
"%s: Now dispatching %i statuses. Session waiting: %i, prio: %i",
1456 __func__, num, session->waiting, smlQueueCheckPrio(session->command_queue));
1468 while (!session->waiting && smlQueueCheckPrio(session->command_queue) && i < num) {
1469 smlSessionDispatch(session);
1491 unsigned int receivedMsg = session->lastReceivedMessageID;
1492 unsigned int lastMsg = session->lastMessageID;
1493 while (!session->waiting && !session->sending &&
1494 smlQueueCheck(session->command_queue) &&
1495 smlQueueLength(session->command_queue) != smlQueueLengthPrio(session->command_queue) &&
1496 receivedMsg == session->lastReceivedMessageID &&
1497 lastMsg == session->lastMessageID)
1507 smlQueueDispatch(session->command_queue);
1510 smlTrace(TRACE_INTERNAL,
"%s: Final %i, waiting %i, sending %i",
1511 __func__,
final, session->waiting, session->sending);
1512 if (session->authenticate) {
1516 smlTrace(TRACE_INTERNAL,
"%s: ongoing authentication", __func__);
1535 if (session->pendingReplies) {
1545 for (o = session->pendingReplies; o; o = o->next) {
1562 if ((!session->waiting && pending->msgID < session->lastMessageID) ||
1563 (session->waiting && pending->msgID < session->lastMessageID - 1))
1565 smlErrorSet(error, SML_ERROR_GENERIC,
"Didn't receive a reply for pending status (actual message %i, received message %i, cmdID %i, msgID %i)", session->lastMessageID, session->lastReceivedMessageID, pending->cmdID, pending->msgID);
1583 if (session->incomingBuffer) {
1584 smlErrorSet(error, SML_ERROR_GENERIC,
"Incoming buffer was open when final arrived");
1585 smlCommandUnref(session->incomingBuffer);
1586 session->incomingBuffer = NULL;
1589 }
else if (!session->waiting && !session->sending) {
1597 smlTrace(TRACE_INTERNAL,
"%s: This is not the final message. Empty? %i",
1598 __func__, smlAssemblerIsEmpty(session->assembler));
1604 if (smlAssemblerIsEmpty(session->assembler)) {
1612 SmlCommand *alert = smlCommandNewAlert(SML_ALERT_NEXT_MESSAGE, NULL, NULL, NULL, NULL, NULL, error);
1616 if (_smlSessionStartCommandInternal(session, alert, NULL, NULL, NULL, TRUE, error) != SML_ASSEMBLER_RESULT_OK)
1618 if (!_smlSessionEndCommandInternal(session, NULL, error))
1621 smlCommandUnref(alert);
1626 if (!_smlSessionFlushInternal(session, FALSE, error))
1630 if (session->authenticate) {
1632 smlTrace(TRACE_INTERNAL,
"%s: ongoing authentication", __func__);
1636 session->end = FALSE;
1637 smlTrace(TRACE_INTERNAL,
"%s: flushing server finally",
1639 if (!_smlSessionFlushInternal(session, TRUE, error))
1644 session->authenticate = FALSE;
1653 smlTrace(TRACE_INTERNAL,
"%s: Ending session now", __func__);
1654 session->end = TRUE;
1667 smlTrace(TRACE_INTERNAL,
"%s: session end on final",
1669 if (session->sessionType == SML_SESSION_TYPE_SERVER)
1671 smlTrace(TRACE_INTERNAL,
"%s: flushing server finally",
1673 if (!_smlSessionFlushInternal(session, TRUE, error))
1677 if (!session->waiting)
1688 "The message from the remote peer does not contain a command.");
1698 if (!
final || session->sessionType != SML_SESSION_TYPE_SERVER)
1700 g_mutex_lock(session->reportEnd);
1701 if (!session->reportedEnd) {
1703 session->reportedEnd = TRUE;
1704 smlSessionRestoreTargetURI(session);
1705 smlSessionDispatchEvent(session, SML_SESSION_EVENT_END,
1706 NULL, NULL, NULL, NULL);
1708 g_mutex_unlock(session->reportEnd);
1712 smlTrace(TRACE_EXIT,
"%s", __func__);
1717 smlCommandUnref(cmd);
1720 smlStatusUnref(status);
1726 void smlSessionSetEventCallback(
SmlSession *session, SmlSessionEventCallback callback,
void *userdata)
1728 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, session, callback, userdata);
1731 session->eventCallback = callback;
1732 session->eventCallbackUserdata = userdata;
1734 smlTrace(TRACE_EXIT,
"%s", __func__);
1737 void smlSessionSetDataCallback(
SmlSession *session, SmlSessionDataCallback callback,
void *userdata)
1739 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, session, callback, userdata);
1742 session->dataCallback = callback;
1743 session->dataCallbackUserdata = userdata;
1745 smlTrace(TRACE_EXIT,
"%s", __func__);
1748 const char *smlSessionGetSessionID(
SmlSession *session)
1752 return session->sessionID;
1755 void smlSessionSetSessionID(
SmlSession *session,
const char *sessionID)
1759 if (session->sessionID)
1760 smlSafeCFree(&(session->sessionID));
1761 session->sessionID = g_strdup(sessionID);
1764 SmlProtocolVersion smlSessionGetVersion(
SmlSession *session)
1768 return session->version;
1774 return session->source;
1780 return session->target;
1786 smlAssert(session->sessionType == SML_SESSION_TYPE_CLIENT);
1789 smlCredUnref(session->cred);
1790 session->cred = cred;
1792 smlLocationSetName(session->source, cred->username);
1793 smlCredRef(session->cred);
1834 smlTrace(TRACE_ENTRY,
"%s(%i, %i, %i, %i, %p, %p, %s, %i, %p)", __func__, sessionType, mimetype, version, protocol, target, source, VA_STRING(sessionID), messageID, error);
1838 if (!g_thread_supported ()) g_thread_init (NULL);
1845 session->dispatch_mutex = g_mutex_new();
1846 session->refCount = 1;
1847 session->eventCallback = NULL;
1848 session->version = version;
1849 session->protocol = protocol;
1850 session->type = mimetype;
1851 session->sessionID = g_strdup(sessionID);
1853 session->lastMessageID = messageID;
1855 session->lastMessageID = 1;
1857 session->end = FALSE;
1858 session->reportEnd = g_mutex_new();
1859 session->reportedEnd = FALSE;
1860 session->sessionType = sessionType;
1861 session->lastCommandID = 0;
1863 if (sessionType == SML_SESSION_TYPE_CLIENT)
1864 session->sending = TRUE;
1866 session->sending = FALSE;
1868 session->source = source;
1869 smlLocationRef(source);
1871 session->target = target;
1872 smlLocationRef(target);
1874 session->cred = NULL;
1875 session->chal = NULL;
1880 if (!session->assembler)
1881 goto error_free_session;
1885 goto error_free_session;
1893 session->assmHasHeader = FALSE;
1896 if (!session->command_queue)
1897 goto error_free_session;
1898 smlQueueSetHandler(session->command_queue, (SmlQueueHandler)_smlSessionCommandHandler, session);
1900 smlTrace(TRACE_EXIT,
"%s: %p", __func__, session);
1904 smlSessionUnref(session);
1912 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, session);
1915 g_atomic_int_inc(&(session->refCount));
1917 smlTrace(TRACE_EXIT,
"%s: New refcount: %i", __func__, session->refCount);
1923 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, session);
1926 if (g_atomic_int_dec_and_test(&(session->refCount))) {
1927 smlTrace(TRACE_INTERNAL,
"%s: Refcount == 0!", __func__);
1929 if (session->target)
1930 smlLocationUnref(session->target);
1932 if (session->responseURI)
1933 smlSafeCFree(&(session->responseURI));
1935 if (session->source)
1936 smlLocationUnref(session->source);
1939 smlCredUnref(session->cred);
1942 smlChalUnref(session->chal);
1944 if (session->sessionID)
1945 smlSafeCFree(&(session->sessionID));
1947 if (session->command_queue) {
1949 while ((sesscmd = smlQueueTryPop(session->command_queue)))
1950 _smlSessionCommandFree(sesscmd);
1952 smlQueueFree(session->command_queue);
1955 _smlSessionFreePendingReplies(session);
1957 if (session->assembler)
1960 if (session->incomingBuffer) {
1961 smlTrace(TRACE_INTERNAL,
"%s: There is an unhandled incoming buffer.", __func__);
1962 smlCommandUnref(session->incomingBuffer);
1965 if (session->parentCommand)
1966 smlCommandUnref(session->parentCommand);
1968 smlTrace(TRACE_INTERNAL,
"%s: cleanup dispatch mutex", __func__);
1969 if (!g_mutex_trylock(session->dispatch_mutex))
1970 g_warning(
"%s: The session is still locked for dispatching - forcing unlock/free.",
1972 g_mutex_unlock(session->dispatch_mutex);
1973 g_mutex_free(session->dispatch_mutex);
1974 smlTrace(TRACE_INTERNAL,
"%s: cleanup reportEnd mutex", __func__);
1976 if (!g_mutex_trylock(session->reportEnd))
1977 g_warning(
"%s: The reportEnd is still locked to set reportEnd - forcing unlock/free.",
1979 g_mutex_unlock(session->reportEnd);
1980 g_mutex_free(session->reportEnd);
1982 smlSafeFree((gpointer *)&session);
1985 smlTrace(TRACE_EXIT,
"%s", __func__);
2012 smlTrace(TRACE_ENTRY,
"%s(%p, %i, %p)", __func__, session,
final, error);
2020 sesscmd->
type = SML_SESSION_FLUSH;
2021 sesscmd->final =
final;
2023 smlTrace(TRACE_INTERNAL,
"%s: sending flush (%i) command %p via queue %p",
2024 __func__, SML_SESSION_FLUSH, sesscmd, session->command_queue);
2029 session->end = FALSE;
2031 smlTrace(TRACE_EXIT,
"%s", __func__);
2059 smlTrace(TRACE_ENTRY,
"%s(%p, %p)", __func__, session, error);
2063 g_mutex_lock(session->reportEnd);
2064 if (session->reportedEnd)
2072 g_mutex_unlock(session->reportEnd);
2073 smlTrace(TRACE_EXIT,
"%s - session end already signalled.", __func__);
2076 session->reportedEnd = TRUE;
2089 if (smlSessionCheck(session) ||
2090 (!session->end && session->lastCommandID))
2095 session->reportedEnd = FALSE;
2101 sesscmd->type = SML_SESSION_FLUSH;
2102 sesscmd->final = TRUE;
2103 sesscmd->end = TRUE;
2104 smlTrace(TRACE_INTERNAL,
"%s: sending command %p", sesscmd);
2111 smlTrace(TRACE_INTERNAL,
"%s: no status/command ... only sending event", __func__);
2112 smlSessionRestoreTargetURI(session);
2113 smlSessionDispatchEvent(session, SML_SESSION_EVENT_END, NULL, NULL, NULL, NULL);
2116 g_mutex_unlock(session->reportEnd);
2117 smlTrace(TRACE_EXIT,
"%s", __func__);
2121 g_mutex_unlock(session->reportEnd);
2127 void smlSessionRestoreTargetURI(
SmlSession *session)
2129 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, session);
2132 if (session->orgTarget) {
2137 smlLocationUnref(session->target);
2138 session->target = session->orgTarget;
2139 session->orgTarget = NULL;
2146 smlTrace(TRACE_EXIT,
"%s", __func__);
2150 SmlBool smlSessionSetResponseURI(
2152 const char *responseURI,
2155 smlTrace(TRACE_ENTRY,
"%s(%p, %s, %p)", __func__, session, VA_STRING(responseURI), error);
2158 if (session->responseURI) {
2159 g_warning(
"The response URI (%s) of a session (%s) should never be overwritten (%s).",
2160 session->responseURI, session->sessionID, responseURI);
2161 smlSafeCFree(&(session->responseURI));
2164 session->responseURI = g_strdup(responseURI);
2166 smlTrace(TRACE_EXIT,
"%s", __func__);
2170 void smlSessionUseStringTable(
SmlSession *session, SmlBool useStringtable)
2172 smlTrace(TRACE_ENTRY,
"%s(%p, %i)", __func__, session, useStringtable);
2177 smlTrace(TRACE_EXIT,
"%s", __func__);
2180 void smlSessionUseNumberOfChanges(
SmlSession *session, SmlBool support)
2182 smlTrace(TRACE_ENTRY,
"%s(%p, %i)", __func__, session, support);
2187 smlTrace(TRACE_EXIT,
"%s", __func__);
2190 void smlSessionUseLargeObjects(
SmlSession *session, SmlBool support)
2192 smlTrace(TRACE_ENTRY,
"%s(%p, %i)", __func__, session, support);
2197 smlTrace(TRACE_EXIT,
"%s", __func__);
2200 void smlSessionUseOnlyReplace(
SmlSession *session, SmlBool onlyReplace)
2202 smlTrace(TRACE_ENTRY,
"%s(%p, %i)", __func__, session, onlyReplace);
2206 session->onlyReplace = onlyReplace;
2208 smlTrace(TRACE_EXIT,
"%s", __func__);
2212 void smlSessionSetSendingLimit(
SmlSession *session,
unsigned int limit)
2214 smlSessionSetRemoteMaxMsgSize(session, limit);
2218 unsigned int smlSessionGetSendingLimit(
SmlSession *session)
2220 return smlSessionGetRemoteMaxMsgSize(session);
2224 void smlSessionSetReceivingLimit(
SmlSession *session,
unsigned int limit)
2226 smlSessionSetLocalMaxMsgSize(session, limit);
2230 void smlSessionSetSendingMaxMsgSize(
SmlSession *session,
unsigned int size)
2232 smlSessionSetRemoteMaxMsgSize(session, size);
2236 unsigned int smlSessionGetSendingMaxMsgSize(
SmlSession *session)
2238 return smlSessionGetRemoteMaxMsgSize(session);
2242 void smlSessionSetReceivingMaxMsgSize(
SmlSession *session,
unsigned int size)
2244 smlSessionSetLocalMaxMsgSize(session, size);
2247 void smlSessionSetRemoteMaxMsgSize(
SmlSession *session,
unsigned int size)
2249 smlTrace(TRACE_ENTRY,
"%s(%p, %u)", __func__, session, size);
2252 smlAssemblerSetRemoteMaxMsgSize(session->assembler, size);
2254 smlTrace(TRACE_EXIT,
"%s", __func__);
2257 unsigned int smlSessionGetRemoteMaxMsgSize(
SmlSession *session)
2260 return smlAssemblerGetRemoteMaxMsgSize(session->assembler);
2263 void smlSessionSetLocalMaxMsgSize(
SmlSession *session,
unsigned int size)
2265 smlTrace(TRACE_ENTRY,
"%s(%p, %u)", __func__, session, size);
2268 if (! smlSessionGetRemoteMaxMsgSize(session) > 0 ||
2269 smlSessionGetRemoteMaxMsgSize(session) > size)
2271 session->localMaxMsgSize = size;
2273 session->localMaxMsgSize = smlSessionGetRemoteMaxMsgSize(session);
2276 smlTrace(TRACE_EXIT,
"%s", __func__);
2279 unsigned int smlSessionGetLocalMaxMsgSize(
SmlSession *session)
2282 return session->localMaxMsgSize;
2286 void smlSessionSetSendingMaxObjSize(
SmlSession *session,
int limit)
2292 void smlSessionSetRequestedMaxObjSize(
SmlSession *session,
int limit)
2298 int smlSessionGetSendingMaxObjSize(
SmlSession *session)
2304 void smlSessionSetReceivingMaxObjSize(
SmlSession *session,
unsigned int limit)
2310 unsigned int smlSessionGetReceivingMaxObjSize(
SmlSession *session)
2312 return smlSessionGetLocalMaxObjSize(session);
2327 smlTrace(TRACE_ENTRY,
"%s(%p, %i)", __func__, session, limit);
2330 smlAssemblerSetRemoteMaxObjSize(session->assembler, limit);
2332 smlTrace(TRACE_EXIT,
"%s", __func__);
2341 smlTrace(TRACE_ENTRY,
"%s(%p)", __func__, session);
2344 int result = smlAssemblerGetRemoteMaxObjSize(session->assembler);
2346 smlTrace(TRACE_EXIT,
"%s => %i", __func__, result);
2365 smlTrace(TRACE_ENTRY,
"%s(%p, %u)", __func__, session, limit);
2370 if (remoteLimit > 0)
2373 if ((
unsigned int)remoteLimit > limit && limit > 0)
2379 session->localMaxObjSize = limit;
2386 session->localMaxObjSize = remoteLimit;
2390 session->localMaxObjSize = limit;
2393 smlTrace(TRACE_EXIT,
"%s => %d", __func__, session->localMaxObjSize);
2396 unsigned int smlSessionGetLocalMaxObjSize(
SmlSession *session)
2399 return session->localMaxObjSize;
2424 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p, %p, %p, %p)", __func__, session, cmd, parent, callback, userdata, error);
2435 smlTrace(TRACE_EXIT,
"%s", __func__);
2456 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p, %p, %p, %p)", __func__, session, cmd, parent, callback, userdata, error);
2465 sesscmd->
type = SML_SESSION_COMMAND_START;
2470 sesscmd->parent = parent;
2471 smlCommandRef(parent);
2474 sesscmd->callback = callback;
2475 sesscmd->callbackUserdata = userdata;
2479 smlTrace(TRACE_EXIT,
"%s", __func__);
2497 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, session, parent, error);
2505 sesscmd->
type = SML_SESSION_COMMAND_END;
2508 sesscmd->parent = parent;
2509 smlCommandRef(parent);
2514 smlTrace(TRACE_EXIT,
"%s", __func__);
2538 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, session, status, error);
2547 sesscmd->
type = SML_SESSION_STATUS;
2548 sesscmd->status = status;
2549 smlStatusRef(status);
2553 smlTrace(TRACE_EXIT,
"%s", __func__);
void smlAssemblerSetOption(SmlAssembler *assm, const char *optionname, const char *value)
Sets a option on the assembler.
SmlBool smlAssemblerAddHeader(SmlAssembler *assm, SmlSession *session, SmlError **error)
Assembles the header.
SmlBool smlSessionSendReply(SmlSession *session, SmlStatus *status, SmlError **error)
Sends a reply to a command.
const char * smlErrorPrint(SmlError **error)
Returns the message of the error.
void smlSessionSetLocalMaxObjSize(SmlSession *session, unsigned int limit)
SmlBool smlSessionFlush(SmlSession *session, SmlBool final, SmlError **error)
Flushes a session.
SmlAssemblerResult smlAssemblerStartCommand(SmlAssembler *assm, SmlCommand *parent, SmlCommand *cmd, SmlError **error)
Starts a parent command.
SmlAssemblerResult smlAssemblerAddStatusFull(SmlAssembler *assm, SmlStatus *status, SmlBool force, SmlError **error)
Assembles a status.
SmlBool smlSessionEndCommand(SmlSession *session, SmlCommand *parent, SmlError **error)
ends a command
unsigned int smlSessionGetRemoteMaxObjSize(SmlSession *session)
void smlQueueSend(SmlQueue *queue, void *data)
Sends a message down a queue.
void smlQueueSetHandler(SmlQueue *queue, SmlQueueHandler handler, void *userdata)
Sets the message handler for a queue.
SmlAssemblerResult smlAssemblerReserveStatus(SmlAssembler *assm, unsigned int cmdRef, unsigned int msgRef, unsigned int cmdID, SmlError **error)
Reserves a place for a status with this assembler.
char * smlPrintBinary(const char *data, int len)
Used for printing binary data.
void smlSessionSetRemoteMaxObjSize(SmlSession *session, unsigned int limit)
SmlQueue * smlQueueNew(SmlError **error)
Creates a new asynchronous queue.
SmlBool smlParserEnd(SmlParser *parser, SmlBool *final, SmlBool *end, SmlError **error)
Ends the parsing.
SmlBool smlAssemblerRun(SmlAssembler *assm, char **data, unsigned int *size, SmlBool *end, SmlBool final, SmlError **error)
Assembles the complete message and returns the result.
SmlBool smlSessionEnd(SmlSession *session, SmlError **error)
Ends the session.
unsigned int smlAssemblerFlush(SmlAssembler *assm)
Flushes the already parsed commands.
SmlBool smlAssemblerStart(SmlAssembler *assm, SmlSession *session, SmlError **error)
Starts a new message.
SmlBool smlAssemblerIsStatusMissing(SmlAssembler *assm)
Checks if there are reserved statuses missing.
SmlBool smlSessionSendCommand(SmlSession *session, SmlCommand *cmd, SmlCommand *parent, SmlStatusReplyCb callback, void *userdata, SmlError **error)
Sends a command with a parent.
SmlBool smlItemGetData(SmlItem *item, char **data, unsigned int *size, SmlError **error)
SmlBool smlItemCheck(SmlItem *item)
void smlTrace(SmlTraceType type, const char *message,...)
Used for tracing the application.
void smlAssemblerFree(SmlAssembler *assm)
Frees a assembler.
SmlBool smlAssemblerEndCommand(SmlAssembler *assm, SmlCommand *parent, SmlError **error)
Ends a parent command.
SmlBool smlSessionStartCommand(SmlSession *session, SmlCommand *cmd, SmlCommand *parent, SmlStatusReplyCb callback, void *userdata, SmlError **error)
starts a command with a parent
SmlBool smlParserGetStatus(SmlParser *parser, SmlStatus **status, SmlError **error)
Parses the next status.
SmlAssembler * smlAssemblerNew(SmlMimeType type, unsigned int limit, SmlError **error)
Creates a new assembler.
SmlSession * smlSessionNew(SmlSessionType sessionType, SmlMimeType mimetype, SmlProtocolVersion version, SmlProtocolType protocol, SmlLocation *target, SmlLocation *source, const char *sessionID, unsigned int messageID, SmlError **error)
Creates a new session.
SmlParserResult smlParserGetCommand(SmlParser *parser, SmlCommand **cmd, SmlError **error)
Parses the next command.
void * smlTryMalloc0(long n_bytes, SmlError **error)
Safely mallocs.
void smlErrorSet(SmlError **error, SmlErrorType type, const char *format,...)
Sets the error.
SmlBool smlAssemblerGetSpace(SmlAssembler *assm, int *space, SmlCommand *parent, SmlCommand *cmd, SmlError **error)
Gets the available space in the assembler.
void smlQueueSendPrio(SmlQueue *queue, void *data)
Sends a message down a queue.