00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <libsyncml/syncml.h>
00023 #include "sml_ds_server.h"
00024
00025 #include <libsyncml/syncml_internals.h>
00026 #include "sml_ds_server_internals.h"
00027 #include <libsyncml/sml_error_internals.h>
00028 #include <libsyncml/sml_manager_internals.h>
00029 #include <libsyncml/sml_session_internals.h>
00030 #include <libsyncml/sml_command_internals.h>
00031 #include <libsyncml/sml_elements_internals.h>
00032
00033 static SmlWriteContext *_write_context_find(SmlDsSession *dsession, const char *uid, SmlChangeType type)
00034 {
00035 smlTrace(TRACE_ENTRY, "%s(%p, %s, %i)", __func__, dsession, VA_STRING(uid), type);
00036
00037 g_mutex_lock(dsession->pendingMapsLock);
00038 GList *c = NULL;
00039 for (c = dsession->pendingMaps; c; c = c->next) {
00040 SmlWriteContext *ctx = c->data;
00041 if (!strcmp(uid, ctx->uid) && ctx->type == type) {
00042 g_mutex_unlock(dsession->pendingMapsLock);
00043 smlTrace(TRACE_EXIT, "%s: %p", __func__, ctx);
00044 return ctx;
00045 }
00046 }
00047 g_mutex_unlock(dsession->pendingMapsLock);
00048
00049 smlTrace(TRACE_EXIT_ERROR, "%s: Not found", __func__);
00050 return NULL;
00051 }
00052
00053 static void _write_context_free(SmlWriteContext *ctx)
00054 {
00055 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, ctx);
00056
00057 if (ctx->status)
00058 smlStatusUnref(ctx->status);
00059
00060 if (ctx->uid)
00061 smlSafeCFree(&(ctx->uid));
00062
00063 if (ctx->newuid)
00064 smlSafeCFree(&(ctx->newuid));
00065
00066 smlSafeFree((gpointer *)&ctx);
00067
00068 smlTrace(TRACE_EXIT, "%s", __func__);
00069 }
00070
00071 static void _write_context_dispatch(SmlDsSession *dsession, SmlWriteContext *ctx)
00072 {
00073 smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, dsession, ctx);
00074
00075 if (!ctx->status) {
00076 smlTrace(TRACE_EXIT, "%s: No status yet", __func__);
00077 return;
00078 }
00079
00080 smlTrace(TRACE_INTERNAL, "%s: Dispatching: uid %s, Type %i, newuid %s, result %i", __func__, VA_STRING(ctx->uid), ctx->type, VA_STRING(ctx->newuid), smlStatusGetCode(ctx->status));
00081
00082 if (ctx->type == SML_CHANGE_ADD &&
00083 smlStatusGetClass(ctx->status) == SML_ERRORCLASS_SUCCESS &&
00084 !dsession->recvMappingCallback &&
00085 !ctx->newuid &&
00086 dsession->server->servertype == SML_DS_SERVER)
00087 {
00088 smlTrace(TRACE_EXIT, "%s: No mapitem yet", __func__);
00089 return;
00090 }
00091
00092 ctx->callback(dsession, ctx->status, ctx->newuid, ctx->userdata);
00093
00094 g_mutex_lock(dsession->pendingMapsLock);
00095 dsession->pendingMaps = g_list_remove(dsession->pendingMaps, ctx);
00096 g_mutex_unlock(dsession->pendingMapsLock);
00097
00098 if (ctx->type == SML_CHANGE_ADD &&
00099 smlStatusGetClass(ctx->status) == SML_ERRORCLASS_SUCCESS &&
00100 dsession->recvEventCallback &&
00101 !dsession->pendingMaps)
00102 {
00103
00104
00105
00106
00107
00108 dsession->recvEventCallback(dsession, SML_DS_EVENT_COMMITEDCHANGES, dsession->recvEventCallbackUserdata);
00109 smlTrace(TRACE_INTERNAL, "%s: recvEventCallback commited changes callback", __func__);
00110 }
00111
00112 _write_context_free(ctx);
00113
00114 smlTrace(TRACE_EXIT, "%s", __func__);
00115 }
00116
00117 static void _alert_reply(SmlSession *session, SmlStatus *status, void *userdata)
00118 {
00119 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, status, userdata);
00120 SmlDsSession *dsession = userdata;
00121
00122 if (dsession->sentAlertCallback)
00123 dsession->sentAlertCallback(session, status, dsession->sentAlertCallbackUserdata);
00124
00125 dsession->sentAlertCallback = NULL;
00126 dsession->sentAlertCallbackUserdata = NULL;
00127
00128 smlTrace(TRACE_EXIT, "%s", __func__);
00129 }
00130
00131 static void _sync_reply(SmlSession *session, SmlStatus *status, void *userdata)
00132 {
00133 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, status, userdata);
00134 SmlDsSession *dsession = userdata;
00135
00136 if (dsession->sentSyncCallback)
00137 dsession->sentSyncCallback(session, status, dsession->sentSyncCallbackUserdata);
00138
00139 dsession->sentSyncCallback = NULL;
00140 dsession->sentSyncCallbackUserdata = NULL;
00141
00142
00143 if (dsession->recvEventCallback && !dsession->pendingMaps) {
00144 dsession->recvEventCallback(dsession, SML_DS_EVENT_COMMITEDCHANGES, dsession->recvEventCallbackUserdata);
00145 smlTrace(TRACE_INTERNAL, "%s: recvEventCallback commited changes callback", __func__);
00146 }
00147
00148 smlTrace(TRACE_EXIT, "%s", __func__);
00149 }
00150
00151 static void _change_reply(SmlSession *session, SmlStatus *status, void *userdata)
00152 {
00153 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, status, userdata);
00154 smlAssert(session);
00155 smlAssert(status);
00156 SmlWriteContext *ctx = userdata;
00157 SmlDsSession *dsession = ctx->session;
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 if (status->type == SML_COMMAND_TYPE_ADD ||
00168 session->sessionType == SML_SESSION_TYPE_CLIENT) {
00169
00170
00171
00172
00173
00174 if (!status->sourceRef) {
00175 smlTrace(TRACE_EXIT_ERROR, "%s: Received add status or change reply from an OMA DS server without sourceRef", __func__);
00176 return;
00177 }
00178 } else {
00179 if (!status->targetRef) {
00180 smlTrace(TRACE_EXIT_ERROR, "%s: Received delete or modify status or change reply from an OMA DS client without targetRef", __func__);
00181 return;
00182 }
00183 }
00184
00185 ctx->status = status;
00186 smlStatusRef(status);
00187 _write_context_dispatch(dsession, ctx);
00188
00189 smlTrace(TRACE_EXIT, "%s", __func__);
00190 }
00191
00192 SmlDsServer *smlDsServerNew(const char *type, SmlLocation *location, SmlError **error)
00193 {
00194 smlTrace(TRACE_ENTRY, "%s(%s, %p, %p)", __func__, VA_STRING(type), location, error);
00195 smlAssert(location);
00196 CHECK_ERROR_REF
00197
00198 SmlDsServer *server = smlTryMalloc0(sizeof(SmlDsServer), error);
00199 if (!server)
00200 goto error;
00201
00202 server->location = location;
00203 smlLocationRef(location);
00204
00205 server->contenttype = g_strdup(type);
00206 server->servertype = SML_DS_SERVER;
00207
00208 smlTrace(TRACE_EXIT, "%s: %p", __func__, server);
00209 return server;
00210
00211 error:
00212 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00213 return NULL;
00214 }
00215
00216 SmlDsServer *smlDsClientNew(const char *type, SmlLocation *location, SmlLocation *target, SmlError **error)
00217 {
00218 smlTrace(TRACE_ENTRY, "%s(%s, %p, %p, %p)", __func__, VA_STRING(type), location, target, error);
00219 smlAssert(location);
00220 smlAssert(target);
00221 CHECK_ERROR_REF
00222
00223 SmlDsServer *server = smlTryMalloc0(sizeof(SmlDsServer), error);
00224 if (!server)
00225 goto error;
00226
00227 server->location = location;
00228 smlLocationRef(location);
00229
00230 server->target = target;
00231 smlLocationRef(target);
00232
00233 server->contenttype = g_strdup(type);
00234 server->servertype = SML_DS_CLIENT;
00235
00236 smlTrace(TRACE_EXIT, "%s: %p", __func__, server);
00237 return server;
00238
00239 error:
00240 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00241 return NULL;
00242 }
00243
00244 SmlDsServerType smlDsServerGetServerType(SmlDsServer *server)
00245 {
00246 smlAssert(server);
00247 return server->servertype;
00248 }
00249
00250 void smlDsServerFree(SmlDsServer *server)
00251 {
00252 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, server);
00253 smlAssert(server);
00254
00255 if (server->location)
00256 smlLocationUnref(server->location);
00257
00258 if (server->target)
00259 smlLocationUnref(server->target);
00260
00261 if (server->contenttype)
00262 smlSafeCFree(&(server->contenttype));
00263
00264 smlSafeFree((gpointer *)&server);
00265
00266 smlTrace(TRACE_EXIT, "%s", __func__);
00267 }
00268
00279 void smlDsServerSetConnectCallback(SmlDsServer *server, SmlDsSessionConnectCb callback, void *userdata)
00280 {
00281 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, server, callback, userdata);
00282 smlAssert(server);
00283
00284 server->connectCallback = callback;
00285 server->connectCallbackUserdata = userdata;
00286
00287 smlTrace(TRACE_EXIT, "%s", __func__);
00288 }
00289
00290 void smlDsServerSetSanCallback(SmlDsServer *server, SmlDsServerSanCb callback, void *userdata)
00291 {
00292 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, server, callback, userdata);
00293 smlAssert(server);
00294 smlAssert(server->servertype == SML_DS_CLIENT);
00295
00296 server->sanCallback = callback;
00297 server->sanCallbackUserdata = userdata;
00298
00299 smlTrace(TRACE_EXIT, "%s", __func__);
00300 }
00301
00302 void smlDsServerSetSanSessionCallback(SmlDsServer *server, SmlDsServerSanSessionCb callback, void *userdata)
00303 {
00304 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, server, callback, userdata);
00305 smlAssert(server);
00306 smlAssert(server->servertype == SML_DS_CLIENT);
00307
00308 server->sanSessionCallback = callback;
00309 server->sanSessionCallbackUserdata = userdata;
00310
00311 smlTrace(TRACE_EXIT, "%s", __func__);
00312 }
00313
00314 const char *smlDsServerGetLocation(SmlDsServer *server)
00315 {
00316 smlAssert(server);
00317 if (server->location)
00318 return server->location->locURI;
00319 return NULL;
00320 }
00321
00322 const char *smlDsServerGetContentType(SmlDsServer *server)
00323 {
00324 smlAssert(server);
00325 return server->contenttype;
00326 }
00327
00328 SmlBool smlDsServerAddSan(SmlDsServer *server, SmlNotification *san, SmlError **error)
00329 {
00330 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, server, san, error);
00331 smlAssert(server);
00332 smlAssert(san);
00333 CHECK_ERROR_REF
00334
00335 if (!smlNotificationNewAlert(san, SML_ALERT_TWO_WAY_BY_SERVER, server->contenttype, smlLocationGetURI(server->location), error))
00336 goto error;
00337
00338 smlTrace(TRACE_EXIT, "%s", __func__);
00339 return TRUE;
00340
00341 error:
00342 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00343 return FALSE;
00344 }
00345
00346 SmlDsSession *smlDsServerRecvAlert(SmlDsServer *server, SmlSession *session, SmlCommand *cmd)
00347 {
00348 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, server, session, cmd);
00349 SmlError *error = NULL;
00350
00351 SmlDsSession *dsession = smlDsSessionNew(server, session, &error);
00352 if (!dsession)
00353 goto error;
00354
00355 smlDsSessionRecvAlert(session, cmd, dsession);
00356
00357 if (server->connectCallback)
00358 server->connectCallback(dsession, server->connectCallbackUserdata);
00359
00360 smlDsSessionUnref(dsession);
00361
00362 smlTrace(TRACE_EXIT, "%s", __func__);
00363 return dsession;
00364
00365 error:
00366 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(&error));
00367 smlErrorDeref(&error);
00368 return NULL;
00369 }
00370
00371 SmlDsSession *smlDsServerSendAlert(SmlDsServer *server, SmlSession *session, SmlAlertType type, const char *last, const char *next, SmlStatusReplyCb callback, void *userdata, SmlError **error)
00372 {
00373 smlTrace(TRACE_ENTRY, "%s(%p, %p, %i, %s, %s, %p)", __func__, server, session, type, VA_STRING(last), VA_STRING(next), error);
00374 smlAssert(server);
00375 smlAssert(session);
00376 CHECK_ERROR_REF
00377
00378 SmlDsSession *dsession = smlDsSessionNew(server, session, error);
00379 if (!dsession)
00380 goto error;
00381
00382 if (server->manager) {
00383 if (!smlManagerObjectRegister(server->manager, SML_COMMAND_TYPE_SYNC, session, server->location, NULL, NULL, smlDsSessionRecvSync, smlDsSessionRecvChange, dsession, error))
00384 goto error_free_dsession;
00385
00386 if (!smlManagerObjectRegister(server->manager, SML_COMMAND_TYPE_MAP, session, server->location, NULL, NULL, smlDsSessionRecvMap, NULL, dsession, error))
00387 goto error_free_dsession;
00388
00389 if (!smlManagerObjectRegister(server->manager, SML_COMMAND_TYPE_ALERT, session, server->location, NULL, NULL, smlDsSessionRecvAlert, NULL, dsession, error))
00390 goto error_free_dsession;
00391 }
00392
00393 if (!smlDsSessionSendAlert(dsession, type, last, next, callback, userdata, error))
00394 goto error_free_dsession;
00395
00396 smlTrace(TRACE_EXIT, "%s", __func__);
00397 return dsession;
00398
00399 error_free_dsession:
00400 smlSafeFree((gpointer *)&dsession);
00401 error:
00402 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00403 return NULL;
00404 }
00405
00406 SmlDsSession *smlDsSessionNew(SmlDsServer *server, SmlSession *session, SmlError **error)
00407 {
00408 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, server, session, error);
00409 smlAssert(server);
00410 CHECK_ERROR_REF
00411
00412 SmlDsSession *dsession = smlTryMalloc0(sizeof(SmlDsSession), error);
00413 if (!dsession)
00414 goto error;
00415
00416 dsession->server = server;
00417 dsession->session = session;
00418 dsession->write_lock = g_mutex_new();
00419 dsession->lock = g_mutex_new();
00420 dsession->syncReply = SML_ERROR_UNKNOWN;
00421 dsession->refCount = 1;
00422
00423 if (server->servertype == SML_DS_CLIENT) {
00424 dsession->target = server->target;
00425 smlLocationRef(dsession->target);
00426 }
00427
00428 dsession->location = server->location;
00429 smlLocationRef(dsession->location);
00430
00431 dsession->pendingMapsLock = g_mutex_new();
00432
00433 smlTrace(TRACE_EXIT, "%s: %p", __func__, dsession);
00434 return dsession;
00435
00436 error:
00437 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00438 return NULL;
00439 }
00440
00441 SmlDsSession *smlDsSessionRef(SmlDsSession *dsession)
00442 {
00443 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, dsession);
00444 smlAssert(dsession);
00445
00446 g_atomic_int_inc(&(dsession->refCount));
00447
00448 smlTrace(TRACE_EXIT, "%s: New refcount: %i", __func__, dsession->refCount);
00449 return dsession;
00450 }
00451
00452 void smlDsSessionUnref(SmlDsSession *dsession)
00453 {
00454 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, dsession);
00455 smlAssert(dsession);
00456
00457 if (g_atomic_int_dec_and_test(&(dsession->refCount))) {
00458 smlTrace(TRACE_INTERNAL, "%s: Refcount == 0!", __func__);
00459
00460 if (dsession->target)
00461 smlLocationUnref(dsession->target);
00462
00463 if (dsession->location)
00464 smlLocationUnref(dsession->location);
00465
00466 if (dsession->alertCommand)
00467 smlCommandUnref(dsession->alertCommand);
00468
00469 while (dsession->recvSync) {
00470 SmlCommand *cmd = dsession->recvSync->data;
00471 smlCommandUnref(cmd);
00472 dsession->recvSync = g_list_delete_link(dsession->recvSync, dsession->recvSync);
00473 }
00474
00475 while (dsession->recvChanges) {
00476 SmlCommand *cmd = dsession->recvChanges->data;
00477 smlCommandUnref(cmd);
00478 dsession->recvChanges = g_list_delete_link(dsession->recvChanges, dsession->recvChanges);
00479 }
00480
00481 if (dsession->syncCommand)
00482 smlCommandUnref(dsession->syncCommand);
00483
00484 if (!g_mutex_trylock(dsession->pendingMapsLock)) {
00485 smlTrace(TRACE_ERROR,
00486 "%s: somebody still uses this object", __func__);
00487 g_mutex_lock(dsession->pendingMapsLock);
00488 }
00489 while (dsession->pendingMaps) {
00490 SmlWriteContext *ctx = dsession->pendingMaps->data;
00491 _write_context_free(ctx);
00492 dsession->pendingMaps = g_list_delete_link(dsession->pendingMaps, dsession->pendingMaps);
00493 }
00494 g_mutex_unlock(dsession->pendingMapsLock);
00495 g_mutex_free(dsession->pendingMapsLock);
00496
00497 while (dsession->mapItems) {
00498 SmlMapItem *item = dsession->mapItems->data;
00499 smlMapItemUnref(item);
00500 dsession->mapItems = g_list_delete_link(dsession->mapItems, dsession->mapItems);
00501 }
00502
00503 if (dsession->lock)
00504 g_mutex_free(dsession->lock);
00505 if (dsession->write_lock)
00506 g_mutex_free(dsession->write_lock);
00507
00508 smlSafeFree((gpointer *)&dsession);
00509 }
00510
00511 smlTrace(TRACE_EXIT, "%s", __func__);
00512 }
00513
00514 void smlDsSessionDispatch(SmlDsSession *dsession)
00515 {
00516 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, dsession);
00517 SmlError *error = NULL;
00518 SmlStatus *reply = NULL;
00519
00520
00521
00522
00523
00524
00525
00526 if (!g_mutex_trylock(dsession->lock))
00527 {
00528 smlTrace(TRACE_EXIT, "%s - DsSession is already locked", __func__);
00529 return;
00530 }
00531 smlTrace(TRACE_INTERNAL, "%s - locked DsSession successfully", __func__);
00532
00533 if (dsession->alertCommand && dsession->recvAlertCallback) {
00534 smlTrace(TRACE_INTERNAL, "%s: Dispatching alert", __func__);
00535
00536 SmlErrorType type = SML_NO_ERROR;
00537 if (!dsession->recvAlertCallback(dsession, dsession->alertCommand->private.alert.type, dsession->alertCommand->private.alert.anchor->last, dsession->alertCommand->private.alert.anchor->next, dsession->recvAlertCallbackUserdata))
00538 type = SML_ERROR_REQUIRE_REFRESH;
00539 dsession->recvAlertCallback = NULL;
00540
00541 reply = smlCommandNewReply(dsession->alertCommand, type, &error);
00542 if (!reply)
00543 goto error;
00544
00545 if (!smlSessionSendReply(dsession->session, reply, &error))
00546 goto error;
00547
00548
00549 smlStatusUnref(reply);
00550
00551 smlCommandUnref(dsession->alertCommand);
00552 dsession->alertCommand = NULL;
00553
00554
00555
00556
00557
00558
00559 if (dsession->server->manager && dsession->finalLock)
00560 {
00561 dsession->finalLock = FALSE;
00562 smlManagerSessionFinalLockUnref(dsession->server->manager, dsession->session);
00563 }
00564
00565 } else if (dsession->recvSync && dsession->recvSyncCallback) {
00566 smlTrace(TRACE_INTERNAL, "%s: Dispatching sync", __func__);
00567
00568 dsession->recvSyncCallback(dsession, ((SmlCommand *)(dsession->recvSync->data))->private.sync.numChanged, dsession->recvSyncCallbackUserdata);
00569 dsession->recvSyncCallback = NULL;
00570
00571 while (dsession->recvSync) {
00572 SmlCommand *cmd = dsession->recvSync->data;
00573
00574 smlTrace(TRACE_INTERNAL, "%s: answering sync command with cmdRef %i and msgRef %i", __func__, cmd->cmdID, cmd->msgID);
00575 reply = smlCommandNewReply(cmd, SML_NO_ERROR, &error);
00576 if (!reply)
00577 goto error;
00578
00579 if (!smlSessionSendReply(dsession->session, reply, &error))
00580 goto error;
00581
00582 smlStatusUnref(reply);
00583
00584 smlCommandUnref(cmd);
00585 dsession->recvSync = g_list_delete_link(dsession->recvSync, dsession->recvSync);
00586 }
00587
00588 dsession->syncReply = SML_NO_ERROR;
00589
00590 if (!dsession->recvChanges) {
00591
00592
00593
00594 if (dsession->recvEventCallback) {
00595 dsession->recvEventCallback(dsession, SML_DS_EVENT_GOTCHANGES, dsession->recvEventCallbackUserdata);
00596 smlTrace(TRACE_INTERNAL, "%s: recvEventCallback no changes in recvSync callback", __func__);
00597 }
00598
00599
00600
00601
00602
00603 if (dsession->server->manager && dsession->finalLock)
00604 {
00605 dsession->finalLock = FALSE;
00606 smlManagerSessionFinalLockUnref(dsession->server->manager, dsession->session);
00607 }
00608 smlTrace(TRACE_INTERNAL, "%s: final handling done", __func__);
00609 }
00610 } else if (dsession->recvChanges && dsession->changesCallback) {
00611 smlTrace(TRACE_INTERNAL, "%s: Dispatching changes", __func__);
00612
00613 while (dsession->recvChanges) {
00614
00615 SmlCommand *cmd = dsession->recvChanges->data;
00616
00617 if (cmd) {
00618 if (!cmd->private.change.items ||
00619 !g_list_length(cmd->private.change.items))
00620 {
00621 smlErrorSet(&error, SML_ERROR_GENERIC, "No items found in command.");
00622 goto error;
00623 }
00624
00625
00626
00627
00628
00629
00630
00631 guint i;
00632 for (i=0; i < g_list_length(cmd->private.change.items); i++)
00633 {
00634 SmlItem *item = g_list_nth_data(cmd->private.change.items, i);
00635 if (!item)
00636 {
00637 smlErrorSet(&error, SML_ERROR_GENERIC,
00638 "Item %i of the command's item list is NULL.", i);
00639 goto error;
00640 }
00641
00642
00643
00644 if ((!item->source && !item->target)) {
00645 smlErrorSet(&error, SML_ERROR_GENERIC,
00646 "Cannot determine UID because source an target are missing on item %i.", i);
00647 goto error;
00648 }
00649
00650 char *data = NULL;
00651 unsigned int size = 0;
00652 if (!smlItemStealData(item, &data, &size, &error))
00653 goto error;
00654
00655 if (!dsession->changesCallback(dsession, cmd->private.change.type, item->target ? item->target->locURI : item->source->locURI, data, size, item->contenttype, dsession->changesCallbackUserdata, &error))
00656 goto error;
00657 }
00658
00659 if (cmd->private.change.type == SML_CHANGE_ADD)
00660 reply = smlCommandNewReply(cmd, SML_ITEM_ADDED, &error);
00661 else
00662 reply = smlCommandNewReply(cmd, SML_NO_ERROR, &error);
00663
00664 if (!reply)
00665 goto error;
00666
00667 if (!smlSessionSendReply(dsession->session, reply, &error))
00668 goto error;
00669
00670 smlStatusUnref(reply);
00671
00672 smlCommandUnref(cmd);
00673 }
00674
00675 dsession->recvChanges = g_list_delete_link(dsession->recvChanges, dsession->recvChanges);
00676 }
00677
00678
00679 if (dsession->recvEventCallback) {
00680 dsession->recvEventCallback(dsession, SML_DS_EVENT_GOTCHANGES, dsession->recvEventCallbackUserdata);
00681 smlTrace(TRACE_INTERNAL, "%s: recvEventCallback all changes sent in recvChanges callback", __func__);
00682 }
00683
00684
00685
00686
00687
00688 if (dsession->server->manager)
00689 {
00690 dsession->finalLock = FALSE;
00691 smlManagerSessionFinalLockUnref(dsession->server->manager, dsession->session);
00692 }
00693 else
00694 smlTrace(TRACE_INTERNAL, "%s - no manager so should be a test", __func__);
00695 } else {
00696
00697 smlTrace(TRACE_INTERNAL, "%s: recvChanges: %p changesCallback: %p", __func__, dsession->recvChanges, dsession->changesCallback);
00698 }
00699
00700 smlTrace(TRACE_EXIT, "%s()", __func__);
00701 g_mutex_unlock(dsession->lock);
00702
00703 return;
00704
00705 error:
00706 if (reply)
00707 smlStatusUnref(reply);
00708 g_mutex_unlock(dsession->lock);
00709 smlTrace(TRACE_EXIT_ERROR, "%s: Unable to dispatch: %s", __func__, smlErrorPrint(&error));
00710 smlErrorDeref(&error);
00711 }
00712
00713 SmlBool smlDsSessionCheck(SmlDsSession *dsession)
00714 {
00715 if ((dsession->alertCommand && dsession->recvAlertCallback) || \
00716 (dsession->recvSync && dsession->recvSyncCallback) || \
00717 (dsession->recvChanges && dsession->changesCallback))
00718 return TRUE;
00719 return FALSE;
00720 }
00721
00722 void smlDsSessionRecvAlert(SmlSession *session, SmlCommand *cmd, void *userdata)
00723 {
00724 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, cmd, userdata);
00725 SmlDsSession *dsession = userdata;
00726 SmlError *error = NULL;
00727 smlAssert(dsession->location);
00728
00729 g_mutex_lock(dsession->lock);
00730
00731 if (!cmd->target || !cmd->source) {
00732 SmlStatus *reply = smlCommandNewReply(cmd, SML_ERROR_BAD_REQUEST, &error);
00733 if (!reply)
00734 goto error;
00735
00736 if (!smlSessionSendReply(session, reply, &error)) {
00737 smlStatusUnref(reply);
00738 goto error;
00739 }
00740
00741 smlStatusUnref(reply);
00742
00743 smlTrace(TRACE_EXIT, "%s: Alert had no target or source", __func__);
00744 return;
00745 }
00746
00747 if (!smlLocationCompare(NULL, dsession->location, NULL, cmd->target)) {
00748 SmlStatus *reply = smlCommandNewReply(cmd, SML_ERROR_NOT_FOUND, &error);
00749 if (!reply)
00750 goto error;
00751
00752 if (!smlSessionSendReply(session, reply, &error)) {
00753 smlStatusUnref(reply);
00754 goto error;
00755 }
00756
00757 smlStatusUnref(reply);
00758
00759 smlTrace(TRACE_EXIT, "%s: Alert does not match our location", __func__);
00760 return;
00761 }
00762
00763 smlCommandRef(cmd);
00764
00765 if (!dsession->target) {
00766 dsession->target = cmd->source;
00767 smlLocationRef(cmd->source);
00768 }
00769
00770 dsession->alertCommand = cmd;
00771
00772
00773
00774
00775
00776
00777 if (dsession->server->manager)
00778 {
00779 smlManagerSessionFinalLockRef(dsession->server->manager, session);
00780 dsession->finalLock = TRUE;
00781 }
00782 else
00783 smlTrace(TRACE_INTERNAL, "%s - no manager so should be a test", __func__);
00784
00785 g_mutex_unlock(dsession->lock);
00786
00787 smlTrace(TRACE_EXIT, "%s", __func__);
00788 return;
00789
00790 error:
00791 g_mutex_unlock(dsession->lock);
00792 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(&error));
00793 smlErrorDeref(&error);
00794 return;
00795 }
00796
00797 void smlDsSessionRecvSync(SmlSession *session, SmlCommand *cmd, void *userdata)
00798 {
00799 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, cmd, userdata);
00800 SmlDsSession *dsession = userdata;
00801 SmlError *error = NULL;
00802
00803
00804
00805
00806
00807 if (g_mutex_trylock(dsession->write_lock))
00808 {
00809
00810 g_mutex_lock(dsession->lock);
00811 smlTrace(TRACE_INTERNAL, "%s - write lock enabled", __func__);
00812
00813
00814
00815
00816
00817 if (dsession->server->manager)
00818 {
00819 smlManagerSessionFinalLockRef(dsession->server->manager, session);
00820 dsession->finalLock = TRUE;
00821 dsession->emptySync = TRUE;
00822 }
00823 else
00824 smlTrace(TRACE_INTERNAL, "%s - no manager so should be a test", __func__);
00825 } else {
00826
00827 if (dsession->finalLock && dsession->emptySync)
00828 {
00829 smlTrace(TRACE_INTERNAL, "%s - empty sync of moreData ?", __func__);
00830 dsession->finalLock = FALSE;
00831 smlManagerSessionFinalLockUnref(dsession->server->manager, session);
00832 }
00833 g_mutex_unlock(dsession->lock);
00834 g_mutex_unlock(dsession->write_lock);
00835 smlTrace(TRACE_EXIT, "%s - removed write lock", __func__);
00836 return;
00837 }
00838
00839 if (dsession->syncReply == SML_ERROR_UNKNOWN) {
00840 smlTrace(TRACE_INTERNAL, "%s: Storing sync command with cmdRef %i and msgRef %i", __func__, cmd->cmdID, cmd->msgID);
00841 smlCommandRef(cmd);
00842 dsession->recvSync = g_list_append(dsession->recvSync, cmd);
00843 } else {
00844 smlTrace(TRACE_INTERNAL, "%s: Using stored sync reply on cmd with cmdRef %i and msgRef %i", __func__, cmd->cmdID, cmd->msgID);
00845 SmlStatus *reply = smlCommandNewReply(cmd, dsession->syncReply, &error);
00846 if (!reply)
00847 goto error;
00848
00849 if (!smlSessionSendReply(dsession->session, reply, &error))
00850 goto error;
00851
00852 smlStatusUnref(reply);
00853 }
00854
00855 smlTrace(TRACE_EXIT, "%s", __func__);
00856 return;
00857
00858 error:
00859 g_mutex_unlock(dsession->lock);
00860 g_mutex_unlock(dsession->write_lock);
00861 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(&error));
00862 smlErrorDeref(&error);
00863 }
00864
00865 void smlDsSessionRecvChange(SmlSession *session, SmlCommand *cmd, void *userdata)
00866 {
00867 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, cmd, userdata);
00868 SmlDsSession *dsession = userdata;
00869
00870
00871
00872
00873 dsession->recvChanges = g_list_append(dsession->recvChanges, cmd);
00874 smlCommandRef(cmd);
00875
00876
00877 dsession->emptySync = FALSE;
00878
00879 smlTrace(TRACE_EXIT, "%s", __func__);
00880 }
00881
00882 void smlDsSessionRecvMap(SmlSession *session, SmlCommand *cmd, void *userdata)
00883 {
00884 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, cmd, userdata);
00885 SmlDsSession *dsession = userdata;
00886 SmlError *error = NULL;
00887
00888 g_mutex_lock(dsession->lock);
00889
00890 SmlStatus *reply = smlCommandNewReply(cmd, SML_NO_ERROR, &error);
00891 if (!reply)
00892 goto error;
00893
00894 if (!smlSessionSendReply(session, reply, &error))
00895 goto error;
00896
00897 smlStatusUnref(reply);
00898
00899 GList *m = NULL;
00900 for (m = cmd->private.map.items; m; m = m->next) {
00901 SmlMapItem *item = m->data;
00902
00903 if (dsession->recvMappingCallback) {
00904 dsession->recvMappingCallback(
00905 dsession,
00906 item->target,
00907 item->source,
00908 dsession->recvMappingCallbackUserdata);
00909 } else {
00910 SmlWriteContext *ctx = _write_context_find(dsession, item->target->locURI, SML_CHANGE_ADD);
00911 if (ctx) {
00912 ctx->newuid = g_strdup(item->source->locURI);
00913 _write_context_dispatch(dsession, ctx);
00914 } else {
00915 smlTrace(TRACE_ERROR, "%s: Unknown map ... %s => %s",
00916 __func__,
00917 VA_STRING(item->target->locURI),
00918 VA_STRING(item->source->locURI));
00919 }
00920 }
00921 }
00922
00923 g_mutex_unlock(dsession->lock);
00924
00925 smlTrace(TRACE_EXIT, "%s", __func__);
00926 return;
00927
00928 error:
00929 g_mutex_unlock(dsession->lock);
00930 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(&error));
00931 smlErrorDeref(&error);
00932 }
00933
00946 void smlDsSessionGetAlert(SmlDsSession *dsession, SmlDsSessionAlertCb callback, void *userdata)
00947 {
00948 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, dsession, callback, userdata);
00949 smlAssert(dsession);
00950 smlAssert(callback);
00951
00952 dsession->recvAlertCallback = callback;
00953 dsession->recvAlertCallbackUserdata = userdata;
00954
00955 smlDsSessionDispatch(dsession);
00956
00957 smlTrace(TRACE_EXIT, "%s", __func__);
00958 }
00959
00972 SmlBool smlDsSessionSendAlert(SmlDsSession *dsession, SmlAlertType type, const char *last, const char *next, SmlStatusReplyCb callback, void *userdata, SmlError **error)
00973 {
00974 smlTrace(TRACE_ENTRY, "%s(%p, %i, %s, %s, %p)", __func__, dsession, type, VA_STRING(last), VA_STRING(next), error);
00975 smlAssert(dsession);
00976 CHECK_ERROR_REF
00977
00978 SmlCommand *alert = smlCommandNewAlert(type, dsession->target, dsession->location, next, last, NULL, error);
00979 if (!alert)
00980 goto error;
00981
00982 dsession->sentAlertCallback = callback;
00983 dsession->sentAlertCallbackUserdata = userdata;
00984
00985 if (!smlSessionSendCommand(dsession->session, alert, NULL, _alert_reply, dsession, error))
00986 goto error;
00987
00988 smlCommandUnref(alert);
00989
00990 smlTrace(TRACE_EXIT, "%s", __func__);
00991 return TRUE;
00992
00993 error:
00994 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00995 return FALSE;
00996 }
00997
00998 void smlDsSessionGetMapping(
00999 SmlDsSession *dsession,
01000 SmlDsSessionMapCb mapCallback,
01001 void *userdata)
01002 {
01003 smlTrace(TRACE_ENTRY, "%s", __func__);
01004 dsession->recvMappingCallback = mapCallback;
01005 dsession->recvMappingCallbackUserdata = userdata;
01006 smlTrace(TRACE_EXIT, "%s", __func__);
01007 }
01008
01022 void smlDsSessionGetChanges(SmlDsSession *dsession, SmlDsSessionChangesCb chgCallback, void *userdata)
01023 {
01024 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, dsession, chgCallback, userdata);
01025 smlAssert(dsession);
01026 smlAssert(chgCallback);
01027
01028 dsession->changesCallback = chgCallback;
01029 dsession->changesCallbackUserdata = userdata;
01030
01031 smlDsSessionDispatch(dsession);
01032
01033 smlTrace(TRACE_EXIT, "%s", __func__);
01034 }
01035
01036 void smlDsSessionGetSync(SmlDsSession *dsession, SmlDsSessionSyncCb syncCallback, void *userdata)
01037 {
01038 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, dsession, syncCallback, userdata);
01039 smlAssert(dsession);
01040 smlAssert(syncCallback);
01041
01042 dsession->recvSyncCallback = syncCallback;
01043 dsession->recvSyncCallbackUserdata = userdata;
01044
01045 smlDsSessionDispatch(dsession);
01046
01047 smlTrace(TRACE_EXIT, "%s", __func__);
01048 }
01049
01050 void smlDsSessionGetEvent(SmlDsSession *dsession, SmlDsSessionEventCb eventCallback, void *userdata)
01051 {
01052 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, dsession, eventCallback, userdata);
01053 smlAssert(dsession);
01054 smlAssert(eventCallback);
01055
01056 dsession->recvEventCallback = eventCallback;
01057 dsession->recvEventCallbackUserdata = userdata;
01058
01059 smlDsSessionDispatch(dsession);
01060
01061 smlTrace(TRACE_EXIT, "%s", __func__);
01062 }
01063
01064
01077 SmlBool smlDsSessionSendSync(SmlDsSession *dsession, unsigned int num_changes, SmlStatusReplyCb callback, void *userdata, SmlError **error)
01078 {
01079 smlTrace(TRACE_ENTRY, "%s(%p, %i, %p, %p, %p)", __func__, dsession, num_changes, callback, userdata, error);
01080 smlAssert(dsession);
01081 CHECK_ERROR_REF
01082
01083 if (dsession->syncCommand) {
01084 smlErrorSet(error, SML_ERROR_GENERIC, "There already was a sync command started");
01085 goto error;
01086 }
01087
01088 dsession->sentSyncCallback = callback;
01089 dsession->sentSyncCallbackUserdata = userdata;
01090
01091 dsession->syncCommand = smlCommandNewSync(dsession->target, dsession->location, num_changes, error);
01092 if (!dsession->syncCommand)
01093 goto error;
01094
01095 if (!smlSessionStartCommand(dsession->session, dsession->syncCommand, NULL, _sync_reply, dsession, error))
01096 goto error;
01097
01098 smlTrace(TRACE_EXIT, "%s", __func__);
01099 return TRUE;
01100
01101 error:
01102 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
01103 return FALSE;
01104 }
01105
01106
01107 SmlBool smlDsSessionQueueChange(SmlDsSession *dsession, SmlChangeType type, const char *uid, const char *data, unsigned int size, const char *contenttype, SmlDsSessionWriteCb callback, void *userdata, SmlError **error)
01108 {
01109 smlTrace(TRACE_ENTRY, "%s(%p, %i, %s, %p, %i, %s, %p, %p, %p)", __func__, dsession, type, VA_STRING(uid), data, size, VA_STRING(contenttype), callback, userdata, error);
01110 smlAssert(dsession);
01111 CHECK_ERROR_REF
01112
01113 if (!dsession->syncCommand) {
01114 smlErrorSet(error, SML_ERROR_GENERIC, "You have to start a sync command first");
01115 goto error;
01116 }
01117
01118 SmlCommand *cmd = smlCommandNewChange(type, uid, data, size, contenttype, error);
01119 if (!cmd)
01120 goto error;
01121
01122 SmlWriteContext *ctx = smlTryMalloc0(sizeof(SmlWriteContext), error);
01123 if (!ctx)
01124 goto error_free_cmd;
01125
01126 ctx->callback = callback;
01127 ctx->userdata = userdata;
01128 ctx->uid = g_strdup(uid);
01129 ctx->type = type;
01130 ctx->session = dsession;
01131
01132 g_mutex_lock(dsession->pendingMapsLock);
01133 dsession->pendingMaps = g_list_append(dsession->pendingMaps, ctx);
01134 g_mutex_unlock(dsession->pendingMapsLock);
01135
01136 if (!smlSessionSendCommand(dsession->session, cmd, dsession->syncCommand, _change_reply, ctx, error))
01137 goto error_free_ctx;
01138
01139 smlCommandUnref(cmd);
01140
01141 smlTrace(TRACE_EXIT, "%s", __func__);
01142 return TRUE;
01143
01144 error_free_ctx:
01145 smlSafeCFree(&(ctx->uid));
01146 smlSafeFree((gpointer *)&ctx);
01147 error_free_cmd:
01148 smlCommandUnref(cmd);
01149 error:
01150 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
01151 return FALSE;
01152 }
01153
01160 SmlBool smlDsSessionCloseSync(SmlDsSession *dsession, SmlError **error)
01161 {
01162 smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, dsession, error);
01163 smlAssert(dsession);
01164 CHECK_ERROR_REF
01165
01166 if (!dsession->syncCommand) {
01167 smlErrorSet(error, SML_ERROR_GENERIC, "There already was a sync command started");
01168 goto error;
01169 }
01170
01171 if (!smlSessionEndCommand(dsession->session, NULL, error))
01172 goto error;
01173
01174 smlCommandUnref(dsession->syncCommand);
01175 dsession->syncCommand = NULL;
01176
01177 smlTrace(TRACE_EXIT, "%s", __func__);
01178 return TRUE;
01179
01180 error:
01181 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
01182 return FALSE;
01183 }
01184
01185 SmlBool smlDsSessionQueueMap(SmlDsSession *dsession, const char *uid, const char *newuid, SmlError **error)
01186 {
01187 smlTrace(TRACE_ENTRY, "%s(%p, %s, %s, %p)", __func__, dsession, VA_STRING(uid), VA_STRING(newuid), error);
01188 smlAssert(dsession);
01189 CHECK_ERROR_REF
01190
01191 SmlMapItem *item = smlMapItemNew(uid, newuid, error);
01192 if (!item)
01193 goto error;
01194
01195 dsession->mapItems = g_list_append(dsession->mapItems, item);
01196
01197 smlTrace(TRACE_EXIT, "%s", __func__);
01198 return TRUE;
01199
01200 error:
01201 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
01202 return FALSE;
01203 }
01204
01214 SmlBool smlDsSessionCloseMap(SmlDsSession *dsession, SmlStatusReplyCb callback, void *userdata, SmlError **error)
01215 {
01216 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, dsession, callback, userdata, error);
01217 smlAssert(dsession);
01218 CHECK_ERROR_REF
01219
01220 if (!dsession->mapItems) {
01221 smlTrace(TRACE_EXIT, "%s: No mapitems", __func__);
01222 return TRUE;
01223 }
01224
01225 SmlCommand *cmd = smlCommandNewMap(dsession->server->target, dsession->server->location, error);
01226 if (!cmd)
01227 goto error;
01228
01229 while (dsession->mapItems) {
01230 SmlMapItem *item = dsession->mapItems->data;
01231 if (!smlCommandAddMapItem(cmd, item, error))
01232 goto error_free_cmd;
01233 smlMapItemUnref(item);
01234
01235 dsession->mapItems = g_list_remove(dsession->mapItems, item);
01236 }
01237
01238 if (!smlSessionSendCommand(dsession->session, cmd, NULL, callback, userdata, error))
01239 goto error_free_cmd;
01240
01241 smlCommandUnref(cmd);
01242
01243 smlTrace(TRACE_EXIT, "%s", __func__);
01244 return TRUE;
01245
01246 error_free_cmd:
01247 smlCommandUnref(cmd);
01248 error:
01249 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
01250 return FALSE;
01251 }
01252
01253 const char *smlDsSessionGetLocation(SmlDsSession *dsession)
01254 {
01255 smlAssert(dsession);
01256 return smlDsServerGetLocation(dsession->server);
01257 }
01258
01259 SmlDsServer *smlDsSessionGetServer(SmlDsSession *dsession)
01260 {
01261 smlAssert(dsession);
01262 return dsession->server;
01263 }
01264
01265 const char *smlDsSessionGetContentType(SmlDsSession *dsession)
01266 {
01267 smlAssert(dsession);
01268 return smlDsServerGetContentType(dsession->server);
01269 }
01270
01271 static void _recv_manager_alert(SmlSession *session, SmlCommand *cmd, void *userdata)
01272 {
01273 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, cmd, userdata);
01274 SmlDsServer *server = userdata;
01275 SmlError *error = NULL;
01276
01277 SmlDsSession *dsession = smlDsServerRecvAlert(server, session, cmd);
01278 if (!dsession)
01279 goto error;
01280
01281 if (!smlManagerObjectRegister(server->manager, SML_COMMAND_TYPE_SYNC, session, server->location, NULL, NULL, smlDsSessionRecvSync, smlDsSessionRecvChange, dsession, &error))
01282 goto error_free_dsession;
01283
01284 if (!smlManagerObjectRegister(server->manager, SML_COMMAND_TYPE_MAP, session, server->location, NULL, NULL, smlDsSessionRecvMap, NULL, dsession, &error))
01285 goto error_free_dsession;
01286
01287 smlTrace(TRACE_EXIT, "%s", __func__);
01288 return;
01289
01290 error_free_dsession:
01291 smlSafeFree((gpointer *)&dsession);
01292 error:
01293 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(&error));
01294 if (error)
01295 smlErrorDeref(&error);
01296 }
01297
01298 static void _recv_manager_san(SmlSession *session, SmlCommand *cmd, void *userdata)
01299 {
01300 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, cmd, userdata);
01301 SmlDsServer *server = userdata;
01302 SmlError *error = NULL;
01303
01304
01305 session->sessionType = SML_SESSION_TYPE_CLIENT;
01306
01307
01308 smlLocationUnref(server->target);
01309 server->target = cmd->source;
01310 smlLocationRef(server->target);
01311
01312
01313 if (server->sanSessionCallback) {
01314 SmlErrorType type = server->sanSessionCallback(
01315 server,
01316 session,
01317 cmd->private.alert.type,
01318 server->sanSessionCallbackUserdata);
01319
01320 SmlStatus *reply = smlCommandNewReply(cmd, type, &error);
01321 if (!reply)
01322 goto error;
01323
01324 if (!smlSessionSendReply(session, reply, &error))
01325 goto error;
01326
01327 smlStatusUnref(reply);
01328 } else if (server->sanCallback) {
01329 SmlErrorType type = server->sanCallback(server, cmd->private.alert.type, server->sanCallbackUserdata);
01330
01331 SmlStatus *reply = smlCommandNewReply(cmd, type, &error);
01332 if (!reply)
01333 goto error;
01334
01335 if (!smlSessionSendReply(session, reply, &error))
01336 goto error;
01337
01338 smlStatusUnref(reply);
01339 } else {
01340 smlTrace(TRACE_INTERNAL, "%s: SAN ignored", __func__);
01341
01342 SmlStatus *reply = smlCommandNewReply(cmd, SML_ERROR_NOT_IMPLEMENTED, &error);
01343 if (!reply)
01344 goto error;
01345
01346 if (!smlSessionSendReply(session, reply, &error))
01347 goto error;
01348
01349 smlStatusUnref(reply);
01350 }
01351
01352 smlTrace(TRACE_EXIT, "%s", __func__);
01353 return;
01354
01355 error:
01356 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(&error));
01357 if (error)
01358 smlErrorDeref(&error);
01359 }
01360
01361 SmlBool smlDsServerRegister(SmlDsServer *server, SmlManager *manager, SmlError **error)
01362 {
01363 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, server, manager, error);
01364 smlAssert(server);
01365 smlAssert(manager);
01366 CHECK_ERROR_REF
01367
01368 if (!smlManagerObjectRegister(manager, SML_COMMAND_TYPE_ALERT, NULL, server->location, NULL, NULL, _recv_manager_alert, NULL, server, error))
01369 goto error;
01370
01371 if (!smlManagerObjectRegister(manager, SML_COMMAND_TYPE_ALERT, NULL, NULL, NULL,server->contenttype, _recv_manager_san, NULL, server, error))
01372 goto error;
01373
01374 server->manager = manager;
01375
01376 smlTrace(TRACE_EXIT, "%s", __func__);
01377 return TRUE;
01378
01379 error:
01380 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
01381 return FALSE;
01382 }
01383
01384 SmlLocation *smlDsSessionGetTarget(SmlDsSession *dsession)
01385 {
01386 smlAssert(dsession);
01387 return dsession->target;
01388 }
01389