libsyncml 0.5.4

- Main Page
- Modules
- Data Structures
- Files

- File List

sml_devinf_obj.c
1 /*
2 * libsyncml - A syncml protocol implementation
3 * Copyright (C) 2005 Armin Bauer <armin.bauer@opensync.org>
4 * Copyright (C) 2007-2009 Michael Bell <michael.bell@opensync.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22 #include <libsyncml/syncml.h>
23 #include "sml_devinf_obj.h"
24
25 #include <libsyncml/syncml_internals.h>
26 #include "sml_devinf_obj_internals.h"
27 #include <libsyncml/sml_session_internals.h>
28 #include <libsyncml/sml_elements_internals.h>
29 #include <libsyncml/sml_command_internals.h>
30 #include "libsyncml/sml_error_internals.h"
31
32 #ifdef WIN32
33 #include <windef.h>
34 #else
35 #include<sys/utsname.h>
36 #endif
37
38 /* Design notice
39 *
40 * There is only one SmlDevInfAgent per SmlManager
41 * because there is only one local device information.
42 * Therefore the agent must be able to manage one
43 * device information per session because every remote
44 * device can have different capabilities.
45 */
46
47 /* functions to manage SmlDevInfAgentSession */
48
49 static SmlDevInfAgentSession* _new_session(
50 SmlDevInfAgent *agent,
51 SmlSession *session,
52 SmlError **error)
53 {
54 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, agent, session, error);
55
56 CHECK_ERROR_REF
57 smlAssert(agent);
58 smlAssert(agent->sessions);
59 smlAssert(session);
60
61 SmlDevInfAgentSession *as = smlTryMalloc0(sizeof(SmlDevInfAgentSession), error);
62 if (!as)
63 goto error;
64
65 g_hash_table_insert(agent->sessions, session, as);
66
67 smlTrace(TRACE_EXIT, "%s - %p", __func__, as);
68 return as;
69 error:
70 smlSafeFree((gpointer *) &as);
71 smlTrace(TRACE_EXIT_ERROR, "%s - %s", __func__, smlErrorPrint(error));
72 return NULL;
73 }
74
75 static SmlDevInfAgentSession* _get_session(
76 SmlDevInfAgent *agent,
77 SmlSession *session)
78 {
79 smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, agent, session);
80
81 smlAssert(agent);
82 smlAssert(agent->sessions);
83 smlAssert(session);
84
85 SmlDevInfAgentSession *as = g_hash_table_lookup(agent->sessions, session);
86 smlTrace(TRACE_EXIT, "%s - %p", __func__, as);
87 return as;
88 }
89
90 static void _free_session (gpointer data)
91 {
92 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, data);
93
94 SmlDevInfAgentSession *as = data;
95 if (as->recvDevInf)
96 smlDevInfUnref(as->recvDevInf);
97 smlSafeFree((gpointer *) &as);
98
99 smlTrace(TRACE_EXIT, "%s", __func__);
100 }
101
102 /* functions to manage SmlDevInfAgent */
103
104 static void _get_devinf_reply(SmlSession *session, SmlStatus *status, void *userdata)
105 {
106 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, status, userdata);
107 SmlError *error = NULL;
108 SmlDevInfAgent *agent = userdata;
109
110 if (smlStatusIsResult(status)) {
111 SmlCommand *result = smlStatusGetResult(status);
112
113 /* get cached session or add session to agent cache */
114
115 SmlDevInfAgentSession *as = _get_session(agent, session);
116 if (!as) {
117 as = _new_session(agent, session, &error);
118 if (!as)
119 goto error;
120 }
121
122 /* cache device information */
123
124 as->recvDevInf = smlDevInfFromResult(result, &error);
125 if (!as->recvDevInf)
126 goto error;
127
128 /* send answer */
129
130 SmlStatus *reply = smlCommandNewReply(result, SML_NO_ERROR, &error);
131 if (!reply)
132 goto error;
133
134 if (!smlSessionSendReply(session, reply, &error)) {
135 smlStatusUnref(reply);
136 goto error;
137 }
138
139 smlStatusUnref(reply);
140 }
141
142 smlTrace(TRACE_EXIT, "%s", __func__);
143 return;
144
145 error:
146 smlSessionDispatchEvent(session, SML_SESSION_EVENT_ERROR, NULL, NULL, NULL, error);
147 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(&error));
148 smlErrorDeref(&error);
149 }
150
151 static void _devinf_reply(SmlSession *session, SmlStatus *status, void *userdata)
152 {
153 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, status, userdata);
154
155 smlTrace(TRACE_EXIT, "%s", __func__);
156 }
157
158 static SmlBool _send_devinf(SmlDevInfAgent *agent, SmlSession *session, SmlCommand *get, SmlError **error)
159 {
160 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, agent, session, get, error);
161 CHECK_ERROR_REF
162 SmlCommand *result = NULL;
163 SmlCommand *cmd = NULL;
164
165 /* It is a good idea to perform some sanity checks on the
166 * configuration before the device information is sent.
167 */
168
169 /* If this is SyncML 1.1 or higher then large object support is
170 * required for OMA DS servers.
171 */
172 if (smlSessionGetVersion(session) >= SML_VERSION_11 &&
173 session->sessionType == SML_SESSION_TYPE_SERVER &&
174 !smlDevInfSupportsLargeObjs(agent->devinf))
175 {
176 smlErrorSet(error, SML_ERROR_INTERNAL_MISCONFIGURATION,
177 "OMA DS Server must support large object handling if SyncML 1.1 or higher is used.");
178 goto error;
179 }
180
181 /* If large object support is enabled then MaxMsgSize and
182 * MaxObjSize must be set.
183 */
184 if (smlDevInfSupportsLargeObjs(agent->devinf))
185 {
186 if (smlSessionGetLocalMaxMsgSize(session) < 1)
187 {
188 smlErrorSet(error, SML_ERROR_INTERNAL_MISCONFIGURATION,
189 "If large object support is enabled then MaxMsgSize must be set.");
190 goto error;
191 }
192 if (smlSessionGetLocalMaxObjSize(session) < 1)
193 {
194 smlErrorSet(error, SML_ERROR_INTERNAL_MISCONFIGURATION,
195 "If large object support is enabled then MaxObjSize must be set.");
196 goto error;
197 }
198 }
199
200 /* get cached session or add session to agent cache */
201
202 SmlDevInfAgentSession *as = _get_session(agent, session);
203 if (!as) {
204 as = _new_session(agent, session, error);
205 if (!as)
206 goto error;
207 }
208
209 /* Sanity checks complete. Sending device information ... */
210
211 if (!as->devinfSent) {
212 if (get) {
213 if (smlSessionGetVersion(session) == SML_VERSION_10)
214 result = smlDevInfNewResult(get, agent->devinf, SML_DEVINF_VERSION_10, error);
215 else if (smlSessionGetVersion(session) == SML_VERSION_12)
216 result = smlDevInfNewResult(get, agent->devinf, SML_DEVINF_VERSION_12, error);
217 else
218 result = smlDevInfNewResult(get, agent->devinf, SML_DEVINF_VERSION_11, error);
219
220 if (!result)
221 goto error;
222
223 if (!smlSessionSendCommand(session, result, NULL, _devinf_reply, agent, error)) {
224 smlCommandUnref(result);
225 goto error;
226 }
227
228 smlCommandUnref(result);
229
230 SmlStatus *reply = smlCommandNewReply(get, SML_NO_ERROR, error);
231 if (!reply)
232 goto error;
233
234 if (!smlSessionSendReply(session, reply, error)) {
235 smlStatusUnref(reply);
236 goto error;
237 }
238
239 smlStatusUnref(reply);
240 } else {
241 if (smlSessionGetVersion(session) == SML_VERSION_10)
242 cmd = smlDevInfNewPut(agent->devinf, SML_DEVINF_VERSION_10, error);
243 else if (smlSessionGetVersion(session) == SML_VERSION_12)
244 cmd = smlDevInfNewPut(agent->devinf, SML_DEVINF_VERSION_12, error);
245 else
246 cmd = smlDevInfNewPut(agent->devinf, SML_DEVINF_VERSION_11, error);
247
248 if (!cmd)
249 goto error;
250
251 if (!smlSessionSendCommand(session, cmd, NULL, _devinf_reply, agent, error)) {
252 smlCommandUnref(cmd);
253 goto error;
254 }
255
256 smlCommandUnref(cmd);
257 }
258 as->devinfSent = TRUE;
259 } else {
260 smlTrace(TRACE_INTERNAL, "%s: Already sent the devinf!", __func__);
261
262 if (get) {
263 /* We return a generic error if we dont want to send the devinf to a get
264 * request. Hope that all devices like this */
265 SmlStatus *reply = smlCommandNewReply(get, SML_ERROR_GENERIC, error);
266 if (!reply)
267 goto error;
268
269 if (!smlSessionSendReply(session, reply, error)) {
270 smlStatusUnref(reply);
271 goto error;
272 }
273
274 smlStatusUnref(reply);
275 } else {
276 /* This means that a software component tries to
277 * send the device information but it was already
278 * sent. This can happen if the local library
279 * user is missing the remote device information
280 * and wants to send the get request together
281 * with its own device information. Nevertheless
282 * this is an error - but it can be ignored.
283 */
284 smlTrace(TRACE_INTERNAL,
285 "%s: libsyncml does not send local device information twice.",
286 __func__);
287 }
288 }
289
290 smlTrace(TRACE_EXIT, "%s", __func__);
291 return TRUE;
292
293 error:
294 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
295 return FALSE;
296 }
297
298 static void _recv_devinf(SmlSession *session, SmlCommand *cmd, void *userdata)
299 {
300 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, cmd, userdata);
301 SmlDevInfAgent *agent = userdata;
302 SmlError *error = NULL;
303 char *data = NULL;
304 unsigned int size = 0;
305
306 if (!smlItemGetData(cmd->private.access.item, &data, &size, &error))
307 goto error;
308
309 SmlDevInfAgentSession *as = _get_session(agent, session);
310 if (!as) {
311 as = _new_session(agent, session, &error);
312 if (!as)
313 goto error;
314 }
315
316 as->recvDevInf = smlDevInfParse(data, size, &error);
317 if (!as->recvDevInf)
318 goto error;
319
320 SmlStatus *reply = smlCommandNewReply(cmd, SML_NO_ERROR, &error);
321 if (!reply)
322 goto error;
323
324 if (!smlSessionSendReply(session, reply, &error)) {
325 smlStatusUnref(reply);
326 goto error;
327 }
328
329 smlStatusUnref(reply);
330
331 smlTrace(TRACE_EXIT, "%s", __func__);
332 return;
333
334 error:
335 smlSessionDispatchEvent(session, SML_SESSION_EVENT_ERROR, NULL, NULL, NULL, error);
336 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(&error));
337 smlErrorDeref(&error);
338 }
339
340 static void _request_devinf(SmlSession *session, SmlCommand *cmd, void *userdata)
341 {
342 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, session, cmd, userdata);
343 SmlDevInfAgent *agent = userdata;
344 SmlError *error = NULL;
345
346 if (!_send_devinf(agent, session, cmd, &error))
347 goto error;
348
349 smlTrace(TRACE_EXIT, "%s", __func__);
350 return;
351
352 error:
353 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(&error));
354 }
355
356 SmlDevInfAgent *smlDevInfAgentNew(SmlDevInf *devinf, SmlError **error)
357 {
358 smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, devinf, error);
359 CHECK_ERROR_REF
360 smlAssert(devinf);
361
362 SmlDevInfAgent *agent = smlTryMalloc0(sizeof(SmlDevInfAgent), error);
363 if (!agent)
364 goto error;
365
366 agent->devinf = devinf;
367 agent->sessions = g_hash_table_new_full(NULL, NULL, NULL, _free_session);
368 if (!agent->sessions) {
369 smlErrorSet(error, SML_ERROR_INTERNAL_NO_MEMORY, "Cannot create new hash table.");
370 goto error;
371 }
372
373 if (!smlDevInfGetManufacturer(devinf))
374 smlDevInfSetManufacturer(devinf, "OpenSync");
375 if (!smlDevInfGetModel(devinf))
376 smlDevInfSetModel(devinf, "libsyncml");
377 if (!smlDevInfGetOEM(devinf))
378 {
379 #ifdef WIN32
380 smlDevInfSetOEM(devinf, "Windows");
381 DWORD dwVersion = GetVersion();
382 DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
383 DWORD dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
384 DWORD dwBuild = 0;
385 if (dwVersion < 0x80000000) dwBuild = (DWORD)(HIWORD(dwVersion));
386
387 char szVersion[1024];
388 sprintf(szVersion, "%d.%d (%d)", dwMajorVersion, dwMinorVersion, dwBuild);
389 smlDevInfSetFirmwareVersion(devinf, szVersion);
390 #else
391 struct utsname *buf = malloc(sizeof(struct utsname));
392 if (uname(buf) == 0)
393 {
394 smlDevInfSetOEM(devinf, buf->sysname);
395 smlDevInfSetFirmwareVersion(devinf, buf->release);
396 }
397 smlSafeFree((gpointer *)&buf);
398 #endif
399 }
400 if (!smlDevInfGetSoftwareVersion(devinf))
401 smlDevInfSetSoftwareVersion(devinf, VERSION);
402
403 smlTrace(TRACE_EXIT, "%s: %p", __func__, agent);
404 return agent;
405
406 error:
407 if (agent)
408 smlSafeFree((gpointer *) &agent);
409 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
410 return NULL;
411 }
412
413
414 void smlDevInfAgentFree(SmlDevInfAgent *agent)
415 {
416 smlTrace(TRACE_ENTRY, "%s(%p)", __func__, agent);
417 smlAssert(agent);
418
419 if (agent->devinf)
420 smlDevInfUnref(agent->devinf);
421 g_hash_table_destroy(agent->sessions);
422 smlSafeFree((gpointer *)&agent);
423
424 smlTrace(TRACE_EXIT, "%s", __func__);
425 }
426
427 /* FIXME: DEPRECATED */
428 void smlDevInfAgentSetDevInf(SmlDevInfAgent *agent, SmlDevInf *devinf)
429 {
430 smlTrace(TRACE_ERROR, "%s(%p, %p)", __func__, agent, devinf);
431 smlAssertMsg(NULL, "This function is a design bug.");
432 }
433
434 /* FIXME: DEPRECATED */
435 SmlDevInf *smlDevInfAgentGetDevInf(SmlDevInfAgent *agent)
436 {
437 smlTrace(TRACE_ERROR, "%s(%p, %p)", __func__, agent);
438 smlAssertMsg(NULL, "This function is a design bug.");
439 return NULL;
440 }
441
442 /* Set the devinf of the remote peer. */
443 SmlBool smlDevInfAgentSetSessionDevInf(
444 SmlDevInfAgent *agent,
445 SmlSession *session,
446 SmlDevInf *devinf,
447 SmlError **error)
448 {
449 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, agent, session, devinf, error);
450
451 CHECK_ERROR_REF
452 smlAssert(agent);
453 smlAssert(agent->sessions);
454 smlAssert(session);
455 smlAssert(devinf);
456
457 SmlDevInfAgentSession *as = _get_session(agent, session);
458 if (!as) {
459 as = _new_session(agent, session, error);
460 if (!as)
461 goto error;
462 }
463
464 as->recvDevInf = devinf;
465
466 smlTrace(TRACE_EXIT, "%s", __func__);
467 return TRUE;
468 error:
469 smlTrace(TRACE_EXIT_ERROR, "%s - %s", __func__, smlErrorPrint(error));
470 return FALSE;
471 }
472
473 /* Get the devinf that was sent in the session. Returns FALSE if no devinf was received yet. */
474 SmlDevInf *smlDevInfAgentGetSessionDevInf(SmlDevInfAgent *agent, SmlSession *session)
475 {
476 smlTrace(TRACE_ENTRY, "%s(%p, %p)", __func__, agent, session);
477
478 smlAssert(agent);
479 smlAssert(agent->sessions);
480 smlAssert(session);
481
482 SmlDevInfAgentSession *as = _get_session(agent, session);
483 if (!as)
484 {
485 smlTrace(TRACE_EXIT, "%s - the session is not cached until now", __func__);
486 return NULL;
487 }
488
489 smlTrace(TRACE_EXIT, "%s - %p", __func__, as->recvDevInf);
490 return as->recvDevInf;
491 }
492
494 SmlBool smlDevInfAgentSendDevInf(SmlDevInfAgent *agent, SmlSession *session, SmlError **error)
495 {
496 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, agent, session, error);
497 CHECK_ERROR_REF
498 smlAssert(agent);
499
500 if (!_send_devinf(agent, session, NULL, error))
501 goto error;
502
503 smlTrace(TRACE_EXIT, "%s", __func__);
504 return TRUE;
505
506 error:
507 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
508 return FALSE;
509 }
510
512 SmlBool smlDevInfAgentRequestDevInf(SmlDevInfAgent *agent, SmlSession *session, SmlError **error)
513 {
514 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, agent, session, error);
515 CHECK_ERROR_REF
516 smlAssert(agent);
517 SmlCommand *get = NULL;
518
519 SmlDevInfAgentSession *as = _get_session(agent, session);
520 if (!as) {
521 as = _new_session(agent, session, error);
522 if (!as)
523 goto error;
524 }
525
526 if (as->recvDevInf) {
527 smlTrace(TRACE_EXIT, "%s: Already have the devinf", __func__);
528 return TRUE;
529 }
530
531 if (!as->devinfRequested)
532 {
533 if (smlSessionGetVersion(session) == SML_VERSION_10)
534 get = smlDevInfNewGet(SML_DEVINF_VERSION_10, error);
535 else if (smlSessionGetVersion(session) == SML_VERSION_12)
536 get = smlDevInfNewGet(SML_DEVINF_VERSION_12, error);
537 else
538 get = smlDevInfNewGet(SML_DEVINF_VERSION_11, error);
539
540 if (!get)
541 goto error;
542
543 if (!smlSessionSendCommand(session, get, NULL, _get_devinf_reply, agent, error)) {
544 smlCommandUnref(get);
545 goto error;
546 }
547
548 smlCommandUnref(get);
549
550 as->devinfRequested = TRUE;
551 } else {
552 smlTrace(TRACE_INTERNAL, "%s: Already requested the devinf!", __func__);
553 }
554
555 smlTrace(TRACE_EXIT, "%s", __func__);
556 return TRUE;
557
558 error:
559 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
560 return FALSE;
561 }
562
563 SmlBool smlDevInfAgentRegisterSession(SmlDevInfAgent *agent, SmlManager *manager, SmlSession *session, SmlError **error)
564 {
565 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p, %p)", __func__, agent, manager, session, error);
566 CHECK_ERROR_REF
567 smlAssert(agent);
568 smlAssert(manager);
569
570 SmlLocation *devinf12 = smlLocationNew("./devinf12", NULL, error);
571 SmlLocation *devinf11 = smlLocationNew("./devinf11", NULL, error);
572 SmlLocation *devinf10 = smlLocationNew("./devinf10", NULL, error);
573
574 if (!devinf12 || !devinf11 || !devinf10)
575 goto error;
576
577 /* PUT callbacks
578 *
579 * This command is used to actively send device information without
580 * being asked for. Usually a client do this if it is the first
581 * connection with the server or the client has no problems with
582 * its bandwith.
583 *
584 * Sometimes a server is missing the client's device information.
585 * In this situation the server can send a PUT and a GET to force
586 * the client to send the device information. This can happen if
587 * the client know that server should have its device information
588 * because of an earlier synchronization but the server does not
589 * have the device information. Sometimes server databases (incl.
590 * the device information database) are lost or it is simply a
591 * new server but with the old server address (IP) or name (DNS).
592 *
593 * Please note that a client can ignore a PUT from a server.
594 * Nevertheless it is recommended that a client does not ignore
595 * the device information of a server.
596 */
597
598 smlTrace(TRACE_INTERNAL, "%s: register callbacks for PUT command", __func__);
599 if (!smlManagerObjectRegister(
600 manager, SML_COMMAND_TYPE_PUT, session,
601 NULL, devinf10, NULL, _recv_devinf, NULL, agent,
602 error))
603 goto error_free_loc;
604 if (!smlManagerObjectRegister(
605 manager, SML_COMMAND_TYPE_PUT, session,
606 NULL, devinf11, NULL, _recv_devinf, NULL, agent,
607 error))
608 goto error_free_loc;
609 if (!smlManagerObjectRegister(
610 manager, SML_COMMAND_TYPE_PUT, session,
611 NULL, devinf12, NULL, _recv_devinf, NULL, agent,
612 error))
613 goto error_free_loc;
614
615 /* GET callbacks
616 *
617 * This command is used to request the device information of a
618 * remote peer. Usually the client do this if it is the first
619 * connection with this server or the client does not remember
620 * the server's device information. The most mobiles only do
621 * this for the first successful connection. Data costs usually
622 * high amounts of money in the mobile world and the bandwith is
623 * small in the mobile world.
624 *
625 * Nevertheless if a mobile does not perform the PUT command and
626 * the server does not know the device information of the client
627 * then the server can send a GET command and the client has to
628 * react on it. Please see above why this can happen.
629 *
630 * Please note that client and server must be able to handle the
631 * GET command. A RESULTS command must be send with the local
632 * device information.
633 */
634
635 smlTrace(TRACE_INTERNAL, "%s: register callbacks for GET command", __func__);
636 if (!smlManagerObjectRegister(
637 manager, SML_COMMAND_TYPE_GET, session,
638 devinf10, NULL, NULL, _request_devinf, NULL, agent,
639 error))
640 goto error_free_loc;
641 if (!smlManagerObjectRegister(
642 manager, SML_COMMAND_TYPE_GET, session,
643 devinf11, NULL, NULL, _request_devinf, NULL, agent,
644 error))
645 goto error_free_loc;
646 if (!smlManagerObjectRegister(
647 manager, SML_COMMAND_TYPE_GET, session,
648 devinf12, NULL, NULL, _request_devinf, NULL, agent,
649 error))
650 goto error_free_loc;
651
652 /* RESULTS callbacks
653 *
654 * This command is used to send the device information which
655 * was requested with a GET command. This command can be send by
656 * server and clients. Please see above when this happens.
657 *
658 * A server must be able to handle and interpret a RESULTS
659 * command from a client. Especially this is required because a
660 * server must explicitly request such a command with a previous
661 * GET command.
662 *
663 * Please note that a client can ignore a RESULTS from a server.
664 * Nevertheless it is recommended that a client does not ignore
665 * the device information of a server.
666 */
667
668 smlTrace(TRACE_INTERNAL, "%s: register callbacks for RESULTS command", __func__);
669 if (!smlManagerObjectRegister(
670 manager, SML_COMMAND_TYPE_RESULTS, session,
671 devinf10, NULL, NULL, _recv_devinf, NULL, agent,
672 error))
673 goto error_free_loc;
674 if (!smlManagerObjectRegister(
675 manager, SML_COMMAND_TYPE_RESULTS, session,
676 devinf11, NULL, NULL, _recv_devinf, NULL, agent,
677 error))
678 goto error_free_loc;
679 if (!smlManagerObjectRegister(
680 manager, SML_COMMAND_TYPE_RESULTS, session,
681 devinf12, NULL, NULL, _recv_devinf, NULL, agent,
682 error))
683 goto error_free_loc;
684
685 smlLocationUnref(devinf10);
686 smlLocationUnref(devinf11);
687 smlLocationUnref(devinf12);
688
689 smlTrace(TRACE_EXIT, "%s", __func__);
690 return TRUE;
691
692 error_free_loc:
693 if (devinf10)
694 smlLocationUnref(devinf10);
695 if (devinf11)
696 smlLocationUnref(devinf11);
697 if (devinf12)
698 smlLocationUnref(devinf12);
699 error:
700 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
701 return FALSE;
702 }
703
704 SmlBool smlDevInfAgentRegister(SmlDevInfAgent *agent, SmlManager *manager, SmlError **error)
705 {
706 smlTrace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, agent, manager, error);
707 CHECK_ERROR_REF
708
709 SmlBool retval = smlDevInfAgentRegisterSession(agent, manager, NULL, error);
710
711 if (!retval)
712 goto error;
713
714 smlTrace(TRACE_EXIT, "%s", __func__);
715 return TRUE;
716
717 error:
718 smlTrace(TRACE_EXIT_ERROR, "%s: %s", __func__, smlErrorPrint(error));
719 return FALSE;
720 }
721