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_devinf_obj.h"
00024
00025 #include <libsyncml/syncml_internals.h>
00026 #include "sml_devinf_obj_internals.h"
00027 #include <libsyncml/sml_session_internals.h>
00028 #include <libsyncml/sml_elements_internals.h>
00029 #include <libsyncml/sml_command_internals.h>
00030 #include "libsyncml/sml_error_internals.h"
00031
00032 #ifdef WIN32
00033 #include <windef.h>
00034 #else
00035 #include<sys/utsname.h>
00036 #endif
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 static SmlDevInfAgentSession* _new_session(
00050 SmlDevInfAgent *agent,
00051 SmlSession *session,
00052 SmlError **error)
00053 {
00054 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, agent, session, error);
00055
00056 CHECK_ERROR_REF
00057 smlAssert(agent);
00058 smlAssert(agent->sessions);
00059 smlAssert(session);
00060
00061 SmlDevInfAgentSession *as = smlTryMalloc0(sizeof(SmlDevInfAgentSession), error);
00062 if (!as)
00063 goto error;
00064
00065 g_hash_table_insert(agent->sessions, session, as);
00066
00067 smlTrace(TRACE_EXIT, "%s - %p", __func__, as);
00068 return as;
00069 error:
00070 smlSafeFree((gpointer *) &as);
00071 smlTrace(TRACE_EXIT_ERROR, "%s - %s", __func__, smlErrorPrint(error));
00072 return NULL;
00073 }
00074
00075 static SmlDevInfAgentSession* _get_session(
00076 SmlDevInfAgent *agent,
00077 SmlSession *session)
00078 {
00079 smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, agent, session);
00080
00081 smlAssert(agent);
00082 smlAssert(agent->sessions);
00083 smlAssert(session);
00084
00085 SmlDevInfAgentSession *as = g_hash_table_lookup(agent->sessions, session);
00086 smlTrace(TRACE_EXIT, "%s - %p", __func__, as);
00087 return as;
00088 }
00089
00090 static void _free_session (gpointer data)
00091 {
00092 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, data);
00093
00094 SmlDevInfAgentSession *as = data;
00095 if (as->recvDevInf)
00096 smlDevInfUnref(as->recvDevInf);
00097 smlSafeFree((gpointer *) &as);
00098
00099 smlTrace(TRACE_EXIT, "%s", __func__);
00100 }
00101
00102
00103
00104 static void _get_devinf_reply(SmlSession *session, SmlStatus *status, void *userdata)
00105 {
00106 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, status, userdata);
00107 SmlError *error = NULL;
00108 SmlDevInfAgent *agent = userdata;
00109
00110 if (smlStatusIsResult(status)) {
00111 SmlCommand *result = smlStatusGetResult(status);
00112
00113
00114
00115 SmlDevInfAgentSession *as = _get_session(agent, session);
00116 if (!as) {
00117 as = _new_session(agent, session, &error);
00118 if (!as)
00119 goto error;
00120 }
00121
00122
00123
00124 as->recvDevInf = smlDevInfFromResult(result, &error);
00125 if (!as->recvDevInf)
00126 goto error;
00127
00128
00129
00130 SmlStatus *reply = smlCommandNewReply(result, SML_NO_ERROR, &error);
00131 if (!reply)
00132 goto error;
00133
00134 if (!smlSessionSendReply(session, reply, &error)) {
00135 smlStatusUnref(reply);
00136 goto error;
00137 }
00138
00139 smlStatusUnref(reply);
00140 }
00141
00142 smlTrace(TRACE_EXIT, "%s", __func__);
00143 return;
00144
00145 error:
00146 smlSessionDispatchEvent(session, SML_SESSION_EVENT_ERROR, NULL, NULL, NULL, error);
00147 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(&error));
00148 smlErrorDeref(&error);
00149 }
00150
00151 static void _devinf_reply(SmlSession *session, SmlStatus *status, void *userdata)
00152 {
00153 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, status, userdata);
00154
00155 smlTrace(TRACE_EXIT, "%s", __func__);
00156 }
00157
00158 static SmlBool _send_devinf(SmlDevInfAgent *agent, SmlSession *session, SmlCommand *get, SmlError **error)
00159 {
00160 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, agent, session, get, error);
00161 CHECK_ERROR_REF
00162 SmlCommand *result = NULL;
00163 SmlCommand *cmd = NULL;
00164
00165
00166
00167
00168
00169
00170
00171
00172 if (smlSessionGetVersion(session) >= SML_VERSION_11 &&
00173 session->sessionType == SML_SESSION_TYPE_SERVER &&
00174 !smlDevInfSupportsLargeObjs(agent->devinf))
00175 {
00176 smlErrorSet(error, SML_ERROR_INTERNAL_MISCONFIGURATION,
00177 "OMA DS Server must support large object handling if SyncML 1.1 or higher is used.");
00178 goto error;
00179 }
00180
00181
00182
00183
00184 if (smlDevInfSupportsLargeObjs(agent->devinf))
00185 {
00186 if (smlSessionGetLocalMaxMsgSize(session) < 1)
00187 {
00188 smlErrorSet(error, SML_ERROR_INTERNAL_MISCONFIGURATION,
00189 "If large object support is enabled then MaxMsgSize must be set.");
00190 goto error;
00191 }
00192 if (smlSessionGetLocalMaxObjSize(session) < 1)
00193 {
00194 smlErrorSet(error, SML_ERROR_INTERNAL_MISCONFIGURATION,
00195 "If large object support is enabled then MaxObjSize must be set.");
00196 goto error;
00197 }
00198 }
00199
00200
00201
00202 SmlDevInfAgentSession *as = _get_session(agent, session);
00203 if (!as) {
00204 as = _new_session(agent, session, error);
00205 if (!as)
00206 goto error;
00207 }
00208
00209
00210
00211 if (!as->devinfSent) {
00212 if (get) {
00213 if (smlSessionGetVersion(session) == SML_VERSION_10)
00214 result = smlDevInfNewResult(get, agent->devinf, SML_DEVINF_VERSION_10, error);
00215 else if (smlSessionGetVersion(session) == SML_VERSION_12)
00216 result = smlDevInfNewResult(get, agent->devinf, SML_DEVINF_VERSION_12, error);
00217 else
00218 result = smlDevInfNewResult(get, agent->devinf, SML_DEVINF_VERSION_11, error);
00219
00220 if (!result)
00221 goto error;
00222
00223 if (!smlSessionSendCommand(session, result, NULL, _devinf_reply, agent, error)) {
00224 smlCommandUnref(result);
00225 goto error;
00226 }
00227
00228 smlCommandUnref(result);
00229
00230 SmlStatus *reply = smlCommandNewReply(get, SML_NO_ERROR, error);
00231 if (!reply)
00232 goto error;
00233
00234 if (!smlSessionSendReply(session, reply, error)) {
00235 smlStatusUnref(reply);
00236 goto error;
00237 }
00238
00239 smlStatusUnref(reply);
00240 } else {
00241 if (smlSessionGetVersion(session) == SML_VERSION_10)
00242 cmd = smlDevInfNewPut(agent->devinf, SML_DEVINF_VERSION_10, error);
00243 else if (smlSessionGetVersion(session) == SML_VERSION_12)
00244 cmd = smlDevInfNewPut(agent->devinf, SML_DEVINF_VERSION_12, error);
00245 else
00246 cmd = smlDevInfNewPut(agent->devinf, SML_DEVINF_VERSION_11, error);
00247
00248 if (!cmd)
00249 goto error;
00250
00251 if (!smlSessionSendCommand(session, cmd, NULL, _devinf_reply, agent, error)) {
00252 smlCommandUnref(cmd);
00253 goto error;
00254 }
00255
00256 smlCommandUnref(cmd);
00257 }
00258 as->devinfSent = TRUE;
00259 } else {
00260 smlTrace(TRACE_INTERNAL, "%s: Already sent the devinf!", __func__);
00261
00262 if (get) {
00263
00264
00265 SmlStatus *reply = smlCommandNewReply(get, SML_ERROR_GENERIC, error);
00266 if (!reply)
00267 goto error;
00268
00269 if (!smlSessionSendReply(session, reply, error)) {
00270 smlStatusUnref(reply);
00271 goto error;
00272 }
00273
00274 smlStatusUnref(reply);
00275 } else {
00276
00277
00278
00279
00280
00281
00282
00283
00284 smlTrace(TRACE_INTERNAL,
00285 "%s: libsyncml does not send local device information twice.",
00286 __func__);
00287 }
00288 }
00289
00290 smlTrace(TRACE_EXIT, "%s", __func__);
00291 return TRUE;
00292
00293 error:
00294 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00295 return FALSE;
00296 }
00297
00298 static void _recv_devinf(SmlSession *session, SmlCommand *cmd, void *userdata)
00299 {
00300 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, cmd, userdata);
00301 SmlDevInfAgent *agent = userdata;
00302 SmlError *error = NULL;
00303 char *data = NULL;
00304 unsigned int size = 0;
00305
00306 if (!smlItemGetData(cmd->private.access.item, &data, &size, &error))
00307 goto error;
00308
00309 SmlDevInfAgentSession *as = _get_session(agent, session);
00310 if (!as) {
00311 as = _new_session(agent, session, &error);
00312 if (!as)
00313 goto error;
00314 }
00315
00316 as->recvDevInf = smlDevInfParse(data, size, &error);
00317 if (!as->recvDevInf)
00318 goto error;
00319
00320 SmlStatus *reply = smlCommandNewReply(cmd, SML_NO_ERROR, &error);
00321 if (!reply)
00322 goto error;
00323
00324 if (!smlSessionSendReply(session, reply, &error)) {
00325 smlStatusUnref(reply);
00326 goto error;
00327 }
00328
00329 smlStatusUnref(reply);
00330
00331 smlTrace(TRACE_EXIT, "%s", __func__);
00332 return;
00333
00334 error:
00335 smlSessionDispatchEvent(session, SML_SESSION_EVENT_ERROR, NULL, NULL, NULL, error);
00336 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(&error));
00337 smlErrorDeref(&error);
00338 }
00339
00340 static void _request_devinf(SmlSession *session, SmlCommand *cmd, void *userdata)
00341 {
00342 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, cmd, userdata);
00343 SmlDevInfAgent *agent = userdata;
00344 SmlError *error = NULL;
00345
00346 if (!_send_devinf(agent, session, cmd, &error))
00347 goto error;
00348
00349 smlTrace(TRACE_EXIT, "%s", __func__);
00350 return;
00351
00352 error:
00353 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(&error));
00354 }
00355
00356 SmlDevInfAgent *smlDevInfAgentNew(SmlDevInf *devinf, SmlError **error)
00357 {
00358 smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, devinf, error);
00359 CHECK_ERROR_REF
00360 smlAssert(devinf);
00361
00362 SmlDevInfAgent *agent = smlTryMalloc0(sizeof(SmlDevInfAgent), error);
00363 if (!agent)
00364 goto error;
00365
00366 agent->devinf = devinf;
00367 agent->sessions = g_hash_table_new_full(NULL, NULL, NULL, _free_session);
00368 if (!agent->sessions) {
00369 smlErrorSet(error, SML_ERROR_INTERNAL_NO_MEMORY, "Cannot create new hash table.");
00370 goto error;
00371 }
00372
00373 if (!smlDevInfGetManufacturer(devinf))
00374 smlDevInfSetManufacturer(devinf, "OpenSync");
00375 if (!smlDevInfGetModel(devinf))
00376 smlDevInfSetModel(devinf, "libsyncml");
00377 if (!smlDevInfGetOEM(devinf))
00378 {
00379 #ifdef WIN32
00380 smlDevInfSetOEM(devinf, "Windows");
00381 DWORD dwVersion = GetVersion();
00382 DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
00383 DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
00384 DWORD dwBuild = 0;
00385 if (dwVersion < 0x80000000) dwBuild = (DWORD)(HIWORD(dwVersion));
00386
00387 char szVersion[1024];
00388 sprintf(szVersion, "%d.%d (%d)", dwMajorVersion, dwMinorVersion, dwBuild);
00389 smlDevInfSetFirmwareVersion(devinf, szVersion);
00390 #else
00391 struct utsname *buf = malloc(sizeof(struct utsname));
00392 if (uname(buf) == 0)
00393 {
00394 smlDevInfSetOEM(devinf, buf->sysname);
00395 smlDevInfSetFirmwareVersion(devinf, buf->release);
00396 }
00397 smlSafeFree((gpointer *)&buf);
00398 #endif
00399 }
00400 if (!smlDevInfGetSoftwareVersion(devinf))
00401 smlDevInfSetSoftwareVersion(devinf, VERSION);
00402
00403 smlTrace(TRACE_EXIT, "%s: %p", __func__, agent);
00404 return agent;
00405
00406 error:
00407 if (agent)
00408 smlSafeFree((gpointer *) &agent);
00409 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00410 return NULL;
00411 }
00412
00413
00414 void smlDevInfAgentFree(SmlDevInfAgent *agent)
00415 {
00416 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, agent);
00417 smlAssert(agent);
00418
00419 if (agent->devinf)
00420 smlDevInfUnref(agent->devinf);
00421 g_hash_table_destroy(agent->sessions);
00422 smlSafeFree((gpointer *)&agent);
00423
00424 smlTrace(TRACE_EXIT, "%s", __func__);
00425 }
00426
00427
00428 void smlDevInfAgentSetDevInf(SmlDevInfAgent *agent, SmlDevInf *devinf)
00429 {
00430 smlTrace(TRACE_ERROR, "%s(%p, %p)", __func__, agent, devinf);
00431 smlAssertMsg(NULL, "This function is a design bug.");
00432 }
00433
00434
00435 SmlDevInf *smlDevInfAgentGetDevInf(SmlDevInfAgent *agent)
00436 {
00437 smlTrace(TRACE_ERROR, "%s(%p, %p)", __func__, agent);
00438 smlAssertMsg(NULL, "This function is a design bug.");
00439 return NULL;
00440 }
00441
00442
00443 SmlBool smlDevInfAgentSetSessionDevInf(
00444 SmlDevInfAgent *agent,
00445 SmlSession *session,
00446 SmlDevInf *devinf,
00447 SmlError **error)
00448 {
00449 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, agent, session, devinf, error);
00450
00451 CHECK_ERROR_REF
00452 smlAssert(agent);
00453 smlAssert(agent->sessions);
00454 smlAssert(session);
00455 smlAssert(devinf);
00456
00457 SmlDevInfAgentSession *as = _get_session(agent, session);
00458 if (!as) {
00459 as = _new_session(agent, session, error);
00460 if (!as)
00461 goto error;
00462 }
00463
00464 as->recvDevInf = devinf;
00465
00466 smlTrace(TRACE_EXIT, "%s", __func__);
00467 return TRUE;
00468 error:
00469 smlTrace(TRACE_EXIT_ERROR, "%s - %s", __func__, smlErrorPrint(error));
00470 return FALSE;
00471 }
00472
00473
00474 SmlDevInf *smlDevInfAgentGetSessionDevInf(SmlDevInfAgent *agent, SmlSession *session)
00475 {
00476 smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, agent, session);
00477
00478 smlAssert(agent);
00479 smlAssert(agent->sessions);
00480 smlAssert(session);
00481
00482 SmlDevInfAgentSession *as = _get_session(agent, session);
00483 if (!as)
00484 {
00485 smlTrace(TRACE_EXIT, "%s - the session is not cached until now", __func__);
00486 return NULL;
00487 }
00488
00489 smlTrace(TRACE_EXIT, "%s - %p", __func__, as->recvDevInf);
00490 return as->recvDevInf;
00491 }
00492
00494 SmlBool smlDevInfAgentSendDevInf(SmlDevInfAgent *agent, SmlSession *session, SmlError **error)
00495 {
00496 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, agent, session, error);
00497 CHECK_ERROR_REF
00498 smlAssert(agent);
00499
00500 if (!_send_devinf(agent, session, NULL, error))
00501 goto error;
00502
00503 smlTrace(TRACE_EXIT, "%s", __func__);
00504 return TRUE;
00505
00506 error:
00507 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00508 return FALSE;
00509 }
00510
00512 SmlBool smlDevInfAgentRequestDevInf(SmlDevInfAgent *agent, SmlSession *session, SmlError **error)
00513 {
00514 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, agent, session, error);
00515 CHECK_ERROR_REF
00516 smlAssert(agent);
00517 SmlCommand *get = NULL;
00518
00519 SmlDevInfAgentSession *as = _get_session(agent, session);
00520 if (!as) {
00521 as = _new_session(agent, session, error);
00522 if (!as)
00523 goto error;
00524 }
00525
00526 if (as->recvDevInf) {
00527 smlTrace(TRACE_EXIT, "%s: Already have the devinf", __func__);
00528 return TRUE;
00529 }
00530
00531 if (!as->devinfRequested)
00532 {
00533 if (smlSessionGetVersion(session) == SML_VERSION_10)
00534 get = smlDevInfNewGet(SML_DEVINF_VERSION_10, error);
00535 else if (smlSessionGetVersion(session) == SML_VERSION_12)
00536 get = smlDevInfNewGet(SML_DEVINF_VERSION_12, error);
00537 else
00538 get = smlDevInfNewGet(SML_DEVINF_VERSION_11, error);
00539
00540 if (!get)
00541 goto error;
00542
00543 if (!smlSessionSendCommand(session, get, NULL, _get_devinf_reply, agent, error)) {
00544 smlCommandUnref(get);
00545 goto error;
00546 }
00547
00548 smlCommandUnref(get);
00549
00550 as->devinfRequested = TRUE;
00551 } else {
00552 smlTrace(TRACE_INTERNAL, "%s: Already requested the devinf!", __func__);
00553 }
00554
00555 smlTrace(TRACE_EXIT, "%s", __func__);
00556 return TRUE;
00557
00558 error:
00559 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00560 return FALSE;
00561 }
00562
00563 SmlBool smlDevInfAgentRegisterSession(SmlDevInfAgent *agent, SmlManager *manager, SmlSession *session, SmlError **error)
00564 {
00565 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, agent, manager, session, error);
00566 CHECK_ERROR_REF
00567 smlAssert(agent);
00568 smlAssert(manager);
00569
00570 SmlLocation *devinf12 = smlLocationNew("./devinf12", NULL, error);
00571 SmlLocation *devinf11 = smlLocationNew("./devinf11", NULL, error);
00572 SmlLocation *devinf10 = smlLocationNew("./devinf10", NULL, error);
00573
00574 if (!devinf12 || !devinf11 || !devinf10)
00575 goto error;
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 smlTrace(TRACE_INTERNAL, "%s: register callbacks for PUT command", __func__);
00599 if (!smlManagerObjectRegister(
00600 manager, SML_COMMAND_TYPE_PUT, session,
00601 NULL, devinf10, NULL, _recv_devinf, NULL, agent,
00602 error))
00603 goto error_free_loc;
00604 if (!smlManagerObjectRegister(
00605 manager, SML_COMMAND_TYPE_PUT, session,
00606 NULL, devinf11, NULL, _recv_devinf, NULL, agent,
00607 error))
00608 goto error_free_loc;
00609 if (!smlManagerObjectRegister(
00610 manager, SML_COMMAND_TYPE_PUT, session,
00611 NULL, devinf12, NULL, _recv_devinf, NULL, agent,
00612 error))
00613 goto error_free_loc;
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 smlTrace(TRACE_INTERNAL, "%s: register callbacks for GET command", __func__);
00636 if (!smlManagerObjectRegister(
00637 manager, SML_COMMAND_TYPE_GET, session,
00638 devinf10, NULL, NULL, _request_devinf, NULL, agent,
00639 error))
00640 goto error_free_loc;
00641 if (!smlManagerObjectRegister(
00642 manager, SML_COMMAND_TYPE_GET, session,
00643 devinf11, NULL, NULL, _request_devinf, NULL, agent,
00644 error))
00645 goto error_free_loc;
00646 if (!smlManagerObjectRegister(
00647 manager, SML_COMMAND_TYPE_GET, session,
00648 devinf12, NULL, NULL, _request_devinf, NULL, agent,
00649 error))
00650 goto error_free_loc;
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 smlTrace(TRACE_INTERNAL, "%s: register callbacks for RESULTS command", __func__);
00669 if (!smlManagerObjectRegister(
00670 manager, SML_COMMAND_TYPE_RESULTS, session,
00671 devinf10, NULL, NULL, _recv_devinf, NULL, agent,
00672 error))
00673 goto error_free_loc;
00674 if (!smlManagerObjectRegister(
00675 manager, SML_COMMAND_TYPE_RESULTS, session,
00676 devinf11, NULL, NULL, _recv_devinf, NULL, agent,
00677 error))
00678 goto error_free_loc;
00679 if (!smlManagerObjectRegister(
00680 manager, SML_COMMAND_TYPE_RESULTS, session,
00681 devinf12, NULL, NULL, _recv_devinf, NULL, agent,
00682 error))
00683 goto error_free_loc;
00684
00685 smlLocationUnref(devinf10);
00686 smlLocationUnref(devinf11);
00687 smlLocationUnref(devinf12);
00688
00689 smlTrace(TRACE_EXIT, "%s", __func__);
00690 return TRUE;
00691
00692 error_free_loc:
00693 if (devinf10)
00694 smlLocationUnref(devinf10);
00695 if (devinf11)
00696 smlLocationUnref(devinf11);
00697 if (devinf12)
00698 smlLocationUnref(devinf12);
00699 error:
00700 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00701 return FALSE;
00702 }
00703
00704 SmlBool smlDevInfAgentRegister(SmlDevInfAgent *agent, SmlManager *manager, SmlError **error)
00705 {
00706 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, agent, manager, error);
00707 CHECK_ERROR_REF
00708
00709 SmlBool retval = smlDevInfAgentRegisterSession(agent, manager, NULL, error);
00710
00711 if (!retval)
00712 goto error;
00713
00714 smlTrace(TRACE_EXIT, "%s", __func__);
00715 return TRUE;
00716
00717 error:
00718 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
00719 return FALSE;
00720 }
00721