21 #include "data_sync_server.h" 22 #include "data_sync_common.h" 23 #include "libsyncml/sml_error_internals.h" 24 #include "data_sync_callbacks.h" 25 #include "libsyncml/objects/sml_ds_server.h" 26 #include "data_sync_devinf.h" 27 #include "libsyncml/sml_support.h" 29 static SmlBool smlDataSyncClientAlertCallback(
36 smlTrace(TRACE_ENTRY,
"%s(%p, %i, %s, %s, %p)", __func__, dsession, type, VA_STRING(last), VA_STRING(next), userdata);
49 if (type != SML_ALERT_TWO_WAY &&
50 type != SML_ALERT_SLOW_SYNC &&
51 type != SML_ALERT_TWO_WAY_BY_SERVER)
53 smlErrorSet(&error, SML_ERROR_NOT_IMPLEMENTED,
"Unsupported alert type %d.", type);
57 char *remote_key = g_strdup_printf(
"remoteanchor%s", smlDsSessionGetLocation(dsession));
58 datastore->remoteNext = g_strdup(next);
64 if (type == SML_ALERT_TWO_WAY || type == SML_ALERT_TWO_WAY_BY_SERVER)
68 smlTrace(TRACE_INTERNAL,
"%s: TWO-WAY-SYNC is requested but there is no LAST anchor.", __func__);
69 type = SML_ALERT_SLOW_SYNC;
73 if (dsObject->getAnchorCallback)
74 cached = dsObject->getAnchorCallback(
77 dsObject->getAnchorUserdata,
81 if (!cached || strcmp(cached, last))
84 "%s: TWO-WAY-SYNC is requested but the cached LAST anchor (%s) does not match the presented LAST anchor from the remote peer (%s).",
85 __func__, last, cached);
87 smlSafeCFree(&cached);
88 type = SML_ALERT_SLOW_SYNC;
94 if (dsObject->getAlertTypeCallback)
96 SmlAlertType h = dsObject->getAlertTypeCallback(
100 dsObject->getAlertTypeUserdata,
102 if (h == SML_ALERT_UNKNOWN || error)
114 if (h != SML_ALERT_SLOW_SYNC) {
116 "It is not possible to change the alert type after an OMA DS client received the alerts from the OMA DS server.");
121 source = smlLocationNew(datastore->sourceUri, NULL, &error);
125 alert = smlCommandNewAlert(
127 smlDsSessionGetTarget(datastore->session),
129 NULL, datastore->localNext,
132 smlLocationUnref(source);
135 smlLocationUnref(source);
137 smlCommandUnref(alert);
140 smlCommandUnref(alert);
148 smlSafeCFree(&remote_key);
150 smlTrace(TRACE_EXIT,
"%s: %i", __func__, ret);
154 smlDataSyncSendEvent(
155 dsObject, SML_DATA_SYNC_EVENT_ERROR,
156 dsObject->eventUserdata, error);
158 smlErrorDeref(&error);
162 SmlBool smlDataSyncClientSendAlert(
167 smlTrace(TRACE_ENTRY,
"%s(%p, %d, %p)", __func__, datastore, type, error);
172 SmlAlertType alertType = type;
173 char *local_last = NULL;
174 if (dsObject->getAlertTypeCallback)
176 alertType = dsObject->getAlertTypeCallback(
178 datastore->sourceUri,
180 dsObject->getAlertTypeUserdata,
185 if (alertType == SML_ALERT_UNKNOWN)
187 smlTrace(TRACE_INTERNAL,
"%s: no alert type => slow-sync", __func__);
188 alertType = SML_ALERT_SLOW_SYNC;
190 if (alertType != SML_ALERT_SLOW_SYNC)
193 alertType = SML_ALERT_TWO_WAY;
194 char *local_key = g_strdup_printf(
"localanchor%s", smlDsServerGetLocation(datastore->server));
195 if (dsObject->getAnchorCallback)
196 local_last = dsObject->getAnchorCallback(
199 dsObject->getAnchorUserdata,
201 smlSafeCFree(&local_key);
205 if (datastore->localNext)
206 smlSafeCFree(&(datastore->localNext));
207 datastore->localNext = smlDataSyncGetNextAnchor(datastore, local_last, error);
214 while (!dsObject->session) {
215 smlManagerDispatch(dsObject->manager);
221 datastore->session = smlDsServerSendAlert(
225 local_last, datastore->localNext,
226 smlDataSyncAlertStatusCallback, datastore,
229 smlSafeCFree(&local_last);
230 if (!datastore->session)
237 if (dsObject->changeCallback) {
238 smlDsSessionGetSync(datastore->session,
239 smlDataSyncSyncCallback, datastore);
241 smlDataSyncChangeCallback, datastore);
253 if (alertType == SML_ALERT_SLOW_SYNC &&
255 type != SML_ALERT_UNKNOWN) {
259 smlTrace(TRACE_EXIT,
"%s: %i", __func__, ret);
266 static SmlErrorType smlDataSyncSanCallback(
272 smlTrace(TRACE_ENTRY,
"%s(%p, %p, %d, %p)", __func__, server, session, type, userdata);
276 SmlErrorType ret = SML_NO_ERROR;
279 if (!dsObject->session) {
280 dsObject->session = session;
281 smlSessionRef(session);
284 if (!smlDataSyncClientSendAlert(datastore, type, &error)) {
286 ret = SML_ERROR_REQUIRE_REFRESH;
291 smlTrace(TRACE_EXIT,
"%s: %i", __func__, ret);
295 smlDataSyncSendEvent(
296 dsObject, SML_DATA_SYNC_EVENT_ERROR,
297 dsObject->eventUserdata, error);
299 smlErrorDeref(&error);
300 return SML_ERROR_GENERIC;
305 smlTrace(TRACE_ENTRY,
"%s(%p, %p)", __func__, dsObject, error);
308 dsObject->manager = smlManagerNew(dsObject->tsp, error);
309 if (!dsObject->manager)
311 smlManagerSetEventCallback(dsObject->manager, smlDataSyncEventCallback, dsObject);
312 smlManagerSetLocalMaxMsgSize(dsObject->manager, dsObject->maxMsgSize);
313 smlManagerSetLocalMaxObjSize(dsObject->manager, dsObject->maxObjSize);
316 dsObject->funcDatastoreAlert = smlDataSyncClientAlertCallback;
319 if (!smlDataSyncDevInfInit(dsObject, SML_DEVINF_DEVTYPE_WORKSTATION, error))
323 GList *o = dsObject->datastores;
324 for (; o; o = o->next) {
326 smlTrace(TRACE_INTERNAL,
"preparing DsServer (datastore) %s", datastore->sourceUri);
329 SmlLocation *loc = smlLocationNew(datastore->sourceUri, NULL, error);
333 datastore->server = smlDsClientNew(datastore->contentType, loc, loc, error);
334 smlLocationUnref(loc);
335 if (!datastore->server)
338 if (!smlDsServerRegister(datastore->server, dsObject->manager, error))
346 smlDataSyncDatastoreConnectCallback,
349 smlDsServerSetSanSessionCallback(
351 smlDataSyncSanCallback,
355 if (!smlDataSyncDevInfAddDatastore(dsObject->localDevInf, datastore, error))
360 if (!smlManagerStart(dsObject->manager, error))
367 smlTrace(TRACE_EXIT,
"%s - TRUE", __func__);
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.
void smlDsSessionGetAlert(SmlDsSession *dsession, SmlDsSessionAlertCb callback, void *userdata)
Gets a already received alert.
void smlDsServerSetConnectCallback(SmlDsServer *server, SmlDsSessionConnectCb callback, void *userdata)
Registers a callback that will get called once a client connects.
SmlBool smlSessionSendCommand(SmlSession *session, SmlCommand *cmd, SmlCommand *parent, SmlStatusReplyCb callback, void *userdata, SmlError **error)
Sends a command with a parent.
SmlBool smlTransportInitialize(SmlTransport *tsp, SmlError **error)
Initializes the transport with the given config.
void smlTrace(SmlTraceType type, const char *message,...)
Used for tracing the application.
void smlErrorSet(SmlError **error, SmlErrorType type, const char *format,...)
Sets the error.