21 #include "data_sync_callbacks.h"
22 #include "libsyncml/syncml_internals.h"
23 #include "libsyncml/sml_support.h"
24 #include "libsyncml/sml_error_internals.h"
28 #include "data_sync_devinf.h"
29 #include "libsyncml/objects/sml_ds_server_internals.h"
30 #include "libsyncml/sml_manager_internals.h"
43 void smlDataSyncEventCallback(
45 SmlManagerEventType type,
50 smlTrace(TRACE_ENTRY,
"%s(%p, %i, %p, %p, %p)", __func__, manager, type, session, error, userdata);
57 g_mutex_lock(dsObject->managerMutex);
60 case SML_MANAGER_SESSION_FLUSH:
61 case SML_MANAGER_CONNECT_DONE:
62 smlTrace(TRACE_INTERNAL,
"%s: ignored event %d ", __func__, type);
63 dsObject->internalState = SML_DATA_SYNC_STATE_CONNECTED;
65 case SML_MANAGER_SESSION_ESTABLISHED:
66 smlTrace(TRACE_INTERNAL,
"%s: session established", __func__);
67 dsObject->internalState = SML_DATA_SYNC_STATE_SESSION_READY;
69 dsObject, SML_DATA_SYNC_EVENT_CONNECT,
70 dsObject->eventUserdata, NULL);
72 case SML_MANAGER_DISCONNECT_DONE:
73 smlTrace(TRACE_INTERNAL,
"%s: connection with device has ended", __func__);
78 if (dsObject->internalState < SML_DATA_SYNC_STATE_CONNECTED)
81 "%s: ignored disconnect because never connected",
86 if (dsObject->setAnchorCallback)
88 o = dsObject->datastores;
89 for (; o; o = o->next) {
92 char *anchor = g_strdup_printf(
94 smlDsSessionGetLocation(datastore->session));
95 if (!dsObject->setAnchorCallback(
97 anchor, datastore->localNext,
98 dsObject->setAnchorUserdata,
101 anchor = g_strdup_printf(
103 smlDsSessionGetLocation(datastore->session));
104 if (!dsObject->setAnchorCallback(
106 anchor, datastore->remoteNext,
107 dsObject->setAnchorUserdata,
113 dsObject->internalState = SML_DATA_SYNC_STATE_DISCONNECTED;
114 smlDataSyncSendEvent(
115 dsObject, SML_DATA_SYNC_EVENT_DISCONNECT,
116 dsObject->eventUserdata, NULL);
117 smlDataSyncSendEvent(
118 dsObject, SML_DATA_SYNC_EVENT_FINISHED,
119 dsObject->eventUserdata, NULL);
121 case SML_MANAGER_TRANSPORT_ERROR:
123 "There was an error in the transport: %s",
125 if (SML_DATA_SYNC_STATE_CONNECTED <= dsObject->internalState &&
126 dsObject->internalState < SML_DATA_SYNC_STATE_DISCONNECTED) {
127 if (dsObject->internalState < SML_DATA_SYNC_STATE_DISCONNECT_IN_PROGRESS) {
128 dsObject->internalState = SML_DATA_SYNC_STATE_DISCONNECT_IN_PROGRESS;
130 SmlLink *link_ = smlManagerSessionGetLink(
134 if (link_ || !locerror)
135 smlTransportDisconnect(
145 smlErrorDeref(&locerror);
165 dsObject->internalState = SML_DATA_SYNC_STATE_DISCONNECTED;
170 case SML_MANAGER_SESSION_NEW:
171 smlTrace(TRACE_INTERNAL,
"%s: Just received a new session with ID %s",
172 __func__, VA_STRING(smlSessionGetSessionID(session)));
173 if (dsObject->session) {
175 "%s: WARNING: There was an old session %s in the environment.",
176 __func__, VA_STRING(smlSessionGetSessionID(dsObject->session)));
177 smlSessionUnref(dsObject->session);
178 dsObject->session = NULL;
180 smlSessionUseStringTable(session, dsObject->useStringTable);
181 smlSessionUseOnlyReplace(session, dsObject->onlyReplace);
182 smlSessionUseNumberOfChanges(session, dsObject->useNumberOfChanges);
184 smlTrace(TRACE_INTERNAL,
"%s: maxObjSize %d",
185 __func__, dsObject->maxObjSize);
187 dsObject->session = session;
188 smlSessionRef(session);
191 if (dsObject->dsType == SML_SESSION_TYPE_CLIENT &&
192 (dsObject->username || dsObject->password))
195 SmlCred *cred = smlCredNewAuth(dsObject->authType,
196 dsObject->username, dsObject->password,
200 smlSessionRegisterCred(dsObject->session, cred);
201 smlTrace(TRACE_INTERNAL,
"%s: credential initialized", __func__);
205 case SML_MANAGER_SESSION_FINAL:
206 smlTrace(TRACE_INTERNAL,
"%s: Session %s reported final",
207 __func__, VA_STRING(smlSessionGetSessionID(session)));
211 if (dsObject->dsType == SML_SESSION_TYPE_CLIENT)
214 if (dsObject->actualPackage < SML_PACKAGE_1)
215 dsObject->actualPackage = SML_PACKAGE_1;
217 dsObject->actualPackage += 2;
220 if (dsObject->actualPackage < SML_PACKAGE_2)
221 dsObject->actualPackage = SML_PACKAGE_2;
223 dsObject->actualPackage += 2;
225 smlTrace(TRACE_INTERNAL,
"%s: package == %d", __func__, dsObject->actualPackage);
229 switch(dsObject->actualPackage)
238 if (!smlDataSyncManageDevInf(dsObject, TRUE, &error))
250 if (!smlDataSyncManageDevInf(dsObject, TRUE, &error))
256 smlDataSyncSendEvent(
257 dsObject, SML_DATA_SYNC_EVENT_GOT_ALL_ALERTS,
258 dsObject->eventUserdata, NULL);
261 smlDataSyncSendEvent(
262 dsObject, SML_DATA_SYNC_EVENT_GOT_ALL_ALERTS,
263 dsObject->eventUserdata, NULL);
266 smlDataSyncSendEvent(
267 dsObject, SML_DATA_SYNC_EVENT_GOT_ALL_CHANGES,
268 dsObject->eventUserdata, NULL);
271 if (!smlDataSyncSendMap(dsObject, &error))
275 smlDataSyncSendEvent(
276 dsObject, SML_DATA_SYNC_EVENT_GOT_ALL_CHANGES,
277 dsObject->eventUserdata, NULL);
283 case SML_PACKAGE_END:
289 "The package %d is actually not supported.",
290 dsObject->actualPackage);
294 case SML_MANAGER_SESSION_END:
295 smlTrace(TRACE_INTERNAL,
"%s: Session %s has ended",
296 __func__, VA_STRING(smlSessionGetSessionID(session)));
297 SmlLink *link_ = smlManagerSessionGetLink(
310 if (!smlTransportDisconnect(dsObject->tsp, link_, &error))
319 case SML_MANAGER_SESSION_ERROR:
322 "There was an error in the session %s: %s",
323 VA_STRING(smlSessionGetSessionID(session)),
327 "There was a general error in the manager. %s",
332 case SML_MANAGER_SESSION_WARNING:
336 g_warning(
"%s: Unknown event received: %d.", __func__, type);
340 g_mutex_unlock(dsObject->managerMutex);
341 smlTrace(TRACE_EXIT,
"%s", __func__);
345 g_mutex_unlock(dsObject->managerMutex);
347 smlDataSyncSendEvent(
348 dsObject, SML_DATA_SYNC_EVENT_ERROR,
349 dsObject->eventUserdata, error);
356 void smlDataSyncDatastoreConnectCallback(
360 smlTrace(TRACE_ENTRY,
"%s(%p, %p)", __func__, dsession, userdata);
372 while (!dsObject->session) {
373 smlManagerDispatch(dsObject->manager);
377 if (!datastore->session || datastore->session != dsession)
379 smlTrace(TRACE_INTERNAL,
"%s: should be an OMA DS server", __func__);
380 smlAssert(dsObject->funcDatastoreAlert);
381 datastore->session = dsession;
383 if (dsObject->changeCallback) {
384 smlDsSessionGetSync(datastore->session,
385 smlDataSyncSyncCallback, datastore);
387 smlDataSyncChangeCallback, datastore);
388 smlDsSessionGetMapping(datastore->session,
389 smlDataSyncMappingCallback, datastore);
391 smlDsSessionRef(dsession);
394 smlTrace(TRACE_EXIT,
"%s", __func__);
400 smlDataSyncSendEvent(
401 dsObject, SML_DATA_SYNC_EVENT_ERROR,
402 dsObject->eventUserdata, error);
411 void smlDataSyncAlertStatusCallback(
416 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, session, status, userdata);
428 unsigned int code = smlStatusGetCode(status);
429 if (code >= 300 && code != SML_ERROR_REQUIRE_REFRESH)
434 "The alert response signals an error - %d.", code);
436 smlDataSyncSendEvent(
437 datastore->dsObject, SML_DATA_SYNC_EVENT_ERROR,
438 datastore->dsObject->eventUserdata, error);
440 smlErrorDeref(&error);
442 smlTrace(TRACE_EXIT,
"%s", __func__);
450 void smlDataSyncSyncCallback(
452 unsigned int numchanges,
455 smlTrace(TRACE_ENTRY,
"%s(%p, %i, %p)", __func__, dsession, numchanges, userdata);
464 if (!smlDataSyncManageDevInf(datastore->dsObject, FALSE, &error))
467 smlTrace(TRACE_EXIT,
"%s", __func__);
471 smlDataSyncSendEvent(
472 datastore->dsObject, SML_DATA_SYNC_EVENT_ERROR,
473 datastore->dsObject->eventUserdata, error);
476 void smlDataSyncSyncStatusCallback(
481 smlTrace(TRACE_ENTRY,
"%s(%p, %p)", __func__, session, status, userdata);
484 if (smlStatusGetClass(status) != SML_ERRORCLASS_SUCCESS)
487 smlTrace(TRACE_INTERNAL,
"%s: The synchronisation request failed.", __func__);
488 smlTrace(TRACE_INTERNAL,
"%s: Location => %s", __func__, VA_STRING(datastore->dsObject->url));
489 smlTrace(TRACE_INTERNAL,
"%s: Database => %s", __func__, VA_STRING(datastore->sourceUri));
490 smlTrace(TRACE_INTERNAL,
"%s: Error => %d", __func__, smlStatusGetCode(status));
491 if (smlStatusGetCode(status) == SML_ERROR_SERVICE_UNAVAILABLE &&
492 (strstr(datastore->dsObject->url,
"ocst") ||
493 strstr(datastore->dsObject->url,
"ocas")))
498 "%s: Oracle Collaboration Suite detected.",
501 "%s: Typical undefined error from OCS (503 - SyncML timeout error).",
504 "%s: Please wait 5 minutes before retry - default session timeout.",
520 "Sync failed with error %d.",
521 smlStatusGetCode(status));
523 smlDataSyncSendEvent(
524 datastore->dsObject, SML_DATA_SYNC_EVENT_ERROR,
525 datastore->dsObject->eventUserdata, error);
527 smlErrorDeref(&error);
529 smlTrace(TRACE_EXIT,
"%s", __func__);
537 SmlBool smlDataSyncChangeCallback(
543 const char *contenttype,
547 smlTrace(TRACE_ENTRY,
"%s(%p, %i, %s, %p, %i, %s, %p, %p)", __func__, dsession, type, VA_STRING(uid), data, size, VA_STRING(contenttype), userdata, error);
553 smlAssert(datastore);
554 smlAssert(datastore->dsObject);
555 smlAssert(datastore->dsObject->changeCallback);
558 if (datastore->alertType == SML_ALERT_SLOW_SYNC &&
559 type == SML_CHANGE_REPLACE)
560 type = SML_CHANGE_ADD;
563 size_t appClassLength = ((size_t) index(datastore->contentType,
'/')) -
564 ((
size_t) datastore->contentType);
565 if ( ( strstr(datastore->contentType, SML_CONTENT_TYPE_APPLICATION) == datastore->contentType &&
566 appClassLength == strlen(SML_CONTENT_TYPE_APPLICATION) ) ||
567 ( strstr(datastore->contentType, SML_CONTENT_TYPE_AUDIO) == datastore->contentType &&
568 appClassLength == strlen(SML_CONTENT_TYPE_AUDIO) ) ||
569 ( strstr(datastore->contentType, SML_CONTENT_TYPE_IMAGE) == datastore->contentType &&
570 appClassLength == strlen(SML_CONTENT_TYPE_IMAGE) ) ||
571 ( strstr(datastore->contentType, SML_CONTENT_TYPE_MESSAGE) == datastore->contentType &&
572 appClassLength == strlen(SML_CONTENT_TYPE_MESSAGE) ) ||
573 ( strstr(datastore->contentType, SML_CONTENT_TYPE_VIDEO) == datastore->contentType &&
574 appClassLength == strlen(SML_CONTENT_TYPE_AUDIO) ) )
577 char *b64data = data;
579 data = (
char *) g_base64_decode(b64data, &length);
581 smlSafeCFree(&b64data);
584 "The base 64 decoding of glib failed.");
590 if (!datastore->dsObject->changeCallback(
591 datastore->dsObject, datastore->sourceUri,
592 type, uid, data, size,
593 datastore->dsObject->changeUserdata,
599 smlTrace(TRACE_EXIT,
"%s", __func__);
606 void smlDataSyncChangeStatusCallback(
612 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %s, %p)", __func__, dsession, status, VA_STRING(newuid), userdata);
621 if (dsObject->changeStatusCallback &&
622 !dsObject->changeStatusCallback(
624 smlStatusGetCode(status),
626 change->userdata, &error))
629 smlTrace(TRACE_EXIT,
"%s", __func__);
633 smlDataSyncSendEvent(
634 dsObject, SML_DATA_SYNC_EVENT_ERROR,
635 dsObject->eventUserdata, error);
637 smlErrorDeref(&error);
640 void smlDataSyncMappingCallback(
646 smlTrace(TRACE_ENTRY,
"%s(%p, %s, %s, %p)", __func__, dsession, VA_STRING(smlLocationGetURI(orig)), VA_STRING(smlLocationGetURI(newuid)), userdata);
651 smlAssert(datastore);
652 smlAssert(datastore->dsObject);
653 smlAssert(datastore->dsObject->mappingCallback);
656 if (!datastore->dsObject->mappingCallback(
657 datastore->dsObject, datastore->sourceUri,
658 smlLocationGetURI(orig),
659 smlLocationGetURI(newuid),
660 datastore->dsObject->mappingUserdata,
664 smlTrace(TRACE_EXIT,
"%s", __func__);
668 smlDataSyncSendEvent(
669 datastore->dsObject, SML_DATA_SYNC_EVENT_ERROR,
670 datastore->dsObject->eventUserdata, error);
672 smlErrorDeref(&error);
679 void smlDataSyncMapStatusCallback(
684 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %p)", __func__, session, status, userdata);
685 if (smlStatusGetClass(status) != SML_ERRORCLASS_SUCCESS)
690 "Map of datastore %s was rejected with error code %d",
691 datastore->sourceUri, smlStatusGetCode(status));
692 smlDataSyncSendEvent(
693 datastore->dsObject, SML_DATA_SYNC_EVENT_ERROR,
694 datastore->dsObject->eventUserdata, error);
696 smlTrace(TRACE_EXIT,
"%s", __func__);
703 SmlBool smlDataSyncVerifyUserCallback(
706 const char *username,
710 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %s, %p)", __func__, chal, cred, VA_STRING(username), userdata);
716 smlTrace(TRACE_EXIT,
"%s", __func__);
717 return smlAuthVerify(chal, cred, dsObject->username, dsObject->password, error);
void smlDsSessionGetChanges(SmlDsSession *dsession, SmlDsSessionChangesCb chgCallback, void *userdata)
Gets a already received sync command.
This object represents an OMA DS datastore.
const char * smlErrorPrint(SmlError **error)
Returns the message of the error.
This is the central synchronization object.
SmlBool smlSessionFlush(SmlSession *session, SmlBool final, SmlError **error)
Flushes a session.
void smlDsSessionGetAlert(SmlDsSession *dsession, SmlDsSessionAlertCb callback, void *userdata)
Gets a already received alert.
void smlTrace(SmlTraceType type, const char *message,...)
Used for tracing the application.
void smlErrorSet(SmlError **error, SmlErrorType type, const char *format,...)
Sets the error.
This internal structure represents exactly one change.