blob: 9d35f96eaf0b58b977bcb2522660ffe215fd99ec [file] [log] [blame]
Benny Prijono5dcb38d2005-11-21 01:55:47 +00001/* $Id$ */
2/*
Benny Prijono844653c2008-12-23 17:27:53 +00003 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
Benny Prijono32177c02008-06-20 22:44:47 +00004 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijono5dcb38d2005-11-21 01:55:47 +00005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program 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
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
Benny Prijono834aee32006-02-19 01:38:06 +000020#include <pjsip-simple/pidf.h>
Benny Prijono5dcb38d2005-11-21 01:55:47 +000021#include <pj/string.h>
22#include <pj/pool.h>
Benny Prijono834aee32006-02-19 01:38:06 +000023#include <pj/assert.h>
24
Benny Prijono5dcb38d2005-11-21 01:55:47 +000025
26struct pjpidf_op_desc pjpidf_op =
27{
28 {
29 &pjpidf_pres_construct,
30 &pjpidf_pres_add_tuple,
31 &pjpidf_pres_get_first_tuple,
32 &pjpidf_pres_get_next_tuple,
33 &pjpidf_pres_find_tuple,
34 &pjpidf_pres_remove_tuple,
35 &pjpidf_pres_add_note,
36 &pjpidf_pres_get_first_note,
37 &pjpidf_pres_get_next_note
38 },
39 {
40 &pjpidf_tuple_construct,
41 &pjpidf_tuple_get_id,
42 &pjpidf_tuple_set_id,
43 &pjpidf_tuple_get_status,
44 &pjpidf_tuple_get_contact,
45 &pjpidf_tuple_set_contact,
46 &pjpidf_tuple_set_contact_prio,
47 &pjpidf_tuple_get_contact_prio,
48 &pjpidf_tuple_add_note,
49 &pjpidf_tuple_get_first_note,
50 &pjpidf_tuple_get_next_note,
51 &pjpidf_tuple_get_timestamp,
52 &pjpidf_tuple_set_timestamp,
53 &pjpidf_tuple_set_timestamp_np
54 },
55 {
56 &pjpidf_status_construct,
57 &pjpidf_status_is_basic_open,
58 &pjpidf_status_set_basic_open
59 }
60};
61
62static pj_str_t PRESENCE = { "presence", 8 };
63static pj_str_t ENTITY = { "entity", 6};
64static pj_str_t TUPLE = { "tuple", 5 };
65static pj_str_t ID = { "id", 2 };
66static pj_str_t NOTE = { "note", 4 };
67static pj_str_t STATUS = { "status", 6 };
68static pj_str_t CONTACT = { "contact", 7 };
69static pj_str_t PRIORITY = { "priority", 8 };
70static pj_str_t TIMESTAMP = { "timestamp", 9 };
71static pj_str_t BASIC = { "basic", 5 };
72static pj_str_t OPEN = { "open", 4 };
73static pj_str_t CLOSED = { "closed", 6 };
74static pj_str_t EMPTY_STRING = { NULL, 0 };
75
Benny Prijono9db591a2007-04-04 10:17:10 +000076static pj_str_t XMLNS = { "xmlns", 5 };
77static pj_str_t PIDF_XMLNS = { "urn:ietf:params:xml:ns:pidf", 27 };
78
Benny Prijono5dcb38d2005-11-21 01:55:47 +000079static void xml_init_node(pj_pool_t *pool, pj_xml_node *node,
80 pj_str_t *name, const pj_str_t *value)
81{
82 pj_list_init(&node->attr_head);
83 pj_list_init(&node->node_head);
84 node->name = *name;
85 if (value) pj_strdup(pool, &node->content, value);
86 else node->content.ptr=NULL, node->content.slen=0;
87}
88
89static pj_xml_attr* xml_create_attr(pj_pool_t *pool, pj_str_t *name,
90 const pj_str_t *value)
91{
Benny Prijono9d4469d2007-05-02 05:14:29 +000092 pj_xml_attr *attr = PJ_POOL_ALLOC_T(pool, pj_xml_attr);
Benny Prijono5dcb38d2005-11-21 01:55:47 +000093 attr->name = *name;
94 pj_strdup(pool, &attr->value, value);
95 return attr;
96}
97
98/* Presence */
99PJ_DEF(void) pjpidf_pres_construct(pj_pool_t *pool, pjpidf_pres *pres,
100 const pj_str_t *entity)
101{
102 pj_xml_attr *attr;
103
104 xml_init_node(pool, pres, &PRESENCE, NULL);
105 attr = xml_create_attr(pool, &ENTITY, entity);
106 pj_xml_add_attr(pres, attr);
Benny Prijono9db591a2007-04-04 10:17:10 +0000107 attr = xml_create_attr(pool, &XMLNS, &PIDF_XMLNS);
108 pj_xml_add_attr(pres, attr);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000109}
110
111PJ_DEF(pjpidf_tuple*) pjpidf_pres_add_tuple(pj_pool_t *pool, pjpidf_pres *pres,
112 const pj_str_t *id)
113{
Benny Prijono9d4469d2007-05-02 05:14:29 +0000114 pjpidf_tuple *t = PJ_POOL_ALLOC_T(pool, pjpidf_tuple);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000115 pjpidf_tuple_construct(pool, t, id);
116 pj_xml_add_node(pres, t);
117 return t;
118}
119
120PJ_DEF(pjpidf_tuple*) pjpidf_pres_get_first_tuple(pjpidf_pres *pres)
121{
122 return pj_xml_find_node(pres, &TUPLE);
123}
124
125PJ_DEF(pjpidf_tuple*) pjpidf_pres_get_next_tuple(pjpidf_pres *pres,
126 pjpidf_tuple *tuple)
127{
128 return pj_xml_find_next_node(pres, tuple, &TUPLE);
129}
130
Benny Prijonoadb04952009-06-01 15:31:35 +0000131static pj_bool_t find_tuple_by_id(const pj_xml_node *node, const void *id)
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000132{
Benny Prijono9d4469d2007-05-02 05:14:29 +0000133 return pj_xml_find_attr(node, &ID, (const pj_str_t*)id) != NULL;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000134}
135
136PJ_DEF(pjpidf_tuple*) pjpidf_pres_find_tuple(pjpidf_pres *pres, const pj_str_t *id)
137{
138 return pj_xml_find(pres, &TUPLE, id, &find_tuple_by_id);
139}
140
141PJ_DEF(void) pjpidf_pres_remove_tuple(pjpidf_pres *pres, pjpidf_tuple *t)
142{
Benny Prijono834aee32006-02-19 01:38:06 +0000143 PJ_UNUSED_ARG(pres);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000144 pj_list_erase(t);
145}
146
147PJ_DEF(pjpidf_note*) pjpidf_pres_add_note(pj_pool_t *pool, pjpidf_pres *pres,
148 const pj_str_t *text)
149{
Benny Prijono9d4469d2007-05-02 05:14:29 +0000150 pjpidf_note *note = PJ_POOL_ALLOC_T(pool, pjpidf_note);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000151 xml_init_node(pool, note, &NOTE, text);
152 pj_xml_add_node(pres, note);
153 return note;
154}
155
156PJ_DEF(pjpidf_note*) pjpidf_pres_get_first_note(pjpidf_pres *pres)
157{
158 return pj_xml_find_node( pres, &NOTE);
159}
160
161PJ_DEF(pjpidf_note*) pjpidf_pres_get_next_note(pjpidf_pres *t, pjpidf_note *note)
162{
163 return pj_xml_find_next_node(t, note, &NOTE);
164}
165
166
167/* Tuple */
168PJ_DEF(void) pjpidf_tuple_construct(pj_pool_t *pool, pjpidf_tuple *t,
169 const pj_str_t *id)
170{
171 pj_xml_attr *attr;
172 pjpidf_status *st;
173
174 xml_init_node(pool, t, &TUPLE, NULL);
175 attr = xml_create_attr(pool, &ID, id);
176 pj_xml_add_attr(t, attr);
Benny Prijono9d4469d2007-05-02 05:14:29 +0000177 st = PJ_POOL_ALLOC_T(pool, pjpidf_status);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000178 pjpidf_status_construct(pool, st);
179 pj_xml_add_node(t, st);
180}
181
182PJ_DEF(const pj_str_t*) pjpidf_tuple_get_id(const pjpidf_tuple *t)
183{
184 const pj_xml_attr *attr = pj_xml_find_attr((pj_xml_node*)t, &ID, NULL);
185 pj_assert(attr);
186 return &attr->value;
187}
188
189PJ_DEF(void) pjpidf_tuple_set_id(pj_pool_t *pool, pjpidf_tuple *t, const pj_str_t *id)
190{
191 pj_xml_attr *attr = pj_xml_find_attr(t, &ID, NULL);
192 pj_assert(attr);
193 pj_strdup(pool, &attr->value, id);
194}
195
196
197PJ_DEF(pjpidf_status*) pjpidf_tuple_get_status(pjpidf_tuple *t)
198{
199 pjpidf_status *st = (pjpidf_status*)pj_xml_find_node(t, &STATUS);
200 pj_assert(st);
201 return st;
202}
203
204
205PJ_DEF(const pj_str_t*) pjpidf_tuple_get_contact(const pjpidf_tuple *t)
206{
207 pj_xml_node *node = pj_xml_find_node((pj_xml_node*)t, &CONTACT);
208 if (!node)
209 return &EMPTY_STRING;
210 return &node->content;
211}
212
213PJ_DEF(void) pjpidf_tuple_set_contact(pj_pool_t *pool, pjpidf_tuple *t,
214 const pj_str_t *contact)
215{
216 pj_xml_node *node = pj_xml_find_node(t, &CONTACT);
217 if (!node) {
Benny Prijono9d4469d2007-05-02 05:14:29 +0000218 node = PJ_POOL_ALLOC_T(pool, pj_xml_node);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000219 xml_init_node(pool, node, &CONTACT, contact);
220 pj_xml_add_node(t, node);
221 } else {
222 pj_strdup(pool, &node->content, contact);
223 }
224}
225
226PJ_DEF(void) pjpidf_tuple_set_contact_prio(pj_pool_t *pool, pjpidf_tuple *t,
227 const pj_str_t *prio)
228{
229 pj_xml_node *node = pj_xml_find_node(t, &CONTACT);
230 pj_xml_attr *attr;
231
232 if (!node) {
Benny Prijono9d4469d2007-05-02 05:14:29 +0000233 node = PJ_POOL_ALLOC_T(pool, pj_xml_node);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000234 xml_init_node(pool, node, &CONTACT, NULL);
235 pj_xml_add_node(t, node);
236 }
237 attr = pj_xml_find_attr(node, &PRIORITY, NULL);
238 if (!attr) {
239 attr = xml_create_attr(pool, &PRIORITY, prio);
240 pj_xml_add_attr(node, attr);
241 } else {
242 pj_strdup(pool, &attr->value, prio);
243 }
244}
245
246PJ_DEF(const pj_str_t*) pjpidf_tuple_get_contact_prio(const pjpidf_tuple *t)
247{
248 pj_xml_node *node = pj_xml_find_node((pj_xml_node*)t, &CONTACT);
249 pj_xml_attr *attr;
250
251 if (!node)
252 return &EMPTY_STRING;
253 attr = pj_xml_find_attr(node, &PRIORITY, NULL);
254 if (!attr)
255 return &EMPTY_STRING;
256 return &attr->value;
257}
258
259
260PJ_DEF(pjpidf_note*) pjpidf_tuple_add_note(pj_pool_t *pool, pjpidf_tuple *t,
261 const pj_str_t *text)
262{
Benny Prijono9d4469d2007-05-02 05:14:29 +0000263 pjpidf_note *note = PJ_POOL_ALLOC_T(pool, pjpidf_note);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000264 xml_init_node(pool, note, &NOTE, text);
265 pj_xml_add_node(t, note);
266 return note;
267}
268
269PJ_DEF(pjpidf_note*) pjpidf_tuple_get_first_note(pjpidf_tuple *t)
270{
271 return pj_xml_find_node(t, &NOTE);
272}
273
274PJ_DEF(pjpidf_note*) pjpidf_tuple_get_next_note(pjpidf_tuple *t, pjpidf_note *n)
275{
276 return pj_xml_find_next_node(t, n, &NOTE);
277}
278
279
280PJ_DEF(const pj_str_t*) pjpidf_tuple_get_timestamp(const pjpidf_tuple *t)
281{
282 pj_xml_node *node = pj_xml_find_node((pj_xml_node*)t, &TIMESTAMP);
283 return node ? &node->content : &EMPTY_STRING;
284}
285
286PJ_DEF(void) pjpidf_tuple_set_timestamp(pj_pool_t *pool, pjpidf_tuple *t,
287 const pj_str_t *ts)
288{
289 pj_xml_node *node = pj_xml_find_node(t, &TIMESTAMP);
290 if (!node) {
Benny Prijono9d4469d2007-05-02 05:14:29 +0000291 node = PJ_POOL_ALLOC_T(pool, pj_xml_node);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000292 xml_init_node(pool, node, &TIMESTAMP, ts);
Benny Prijono7bc69242009-07-30 19:45:10 +0000293 pj_xml_add_node(t, node);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000294 } else {
295 pj_strdup(pool, &node->content, ts);
296 }
297}
298
299
300PJ_DEF(void) pjpidf_tuple_set_timestamp_np(pj_pool_t *pool, pjpidf_tuple *t,
301 pj_str_t *ts)
302{
303 pj_xml_node *node = pj_xml_find_node(t, &TIMESTAMP);
304 if (!node) {
Benny Prijono9d4469d2007-05-02 05:14:29 +0000305 node = PJ_POOL_ALLOC_T(pool, pj_xml_node);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000306 xml_init_node(pool, node, &TIMESTAMP, ts);
307 } else {
308 node->content = *ts;
309 }
310}
311
312
313/* Status */
314PJ_DEF(void) pjpidf_status_construct(pj_pool_t *pool, pjpidf_status *st)
315{
316 pj_xml_node *node;
317
318 xml_init_node(pool, st, &STATUS, NULL);
Benny Prijono9d4469d2007-05-02 05:14:29 +0000319 node = PJ_POOL_ALLOC_T(pool, pj_xml_node);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000320 xml_init_node(pool, node, &BASIC, &CLOSED);
321 pj_xml_add_node(st, node);
322}
323
324PJ_DEF(pj_bool_t) pjpidf_status_is_basic_open(const pjpidf_status *st)
325{
326 pj_xml_node *node = pj_xml_find_node((pj_xml_node*)st, &BASIC);
327 pj_assert(node != NULL);
328 return pj_stricmp(&node->content, &OPEN)==0;
329}
330
331PJ_DEF(void) pjpidf_status_set_basic_open(pjpidf_status *st, pj_bool_t open)
332{
333 pj_xml_node *node = pj_xml_find_node(st, &BASIC);
334 pj_assert(node != NULL);
335 node->content = open ? OPEN : CLOSED;
336}
337
338PJ_DEF(pjpidf_pres*) pjpidf_create(pj_pool_t *pool, const pj_str_t *entity)
339{
Benny Prijono9d4469d2007-05-02 05:14:29 +0000340 pjpidf_pres *pres = PJ_POOL_ALLOC_T(pool, pjpidf_pres);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000341 pjpidf_pres_construct(pool, pres, entity);
342 return pres;
343}
344
345PJ_DEF(pjpidf_pres*) pjpidf_parse(pj_pool_t *pool, char *text, int len)
346{
347 pjpidf_pres *pres = pj_xml_parse(pool, text, len);
Benny Prijonoa13314a2007-05-29 04:09:51 +0000348 if (pres && pres->name.slen >= 8) {
349 pj_str_t name;
350
351 name.ptr = pres->name.ptr + (pres->name.slen - 8);
352 name.slen = 8;
353
354 if (pj_stricmp(&name, &PRESENCE) == 0)
355 return pres;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000356 }
Benny Prijonoa13314a2007-05-29 04:09:51 +0000357 return NULL;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000358}
359
360PJ_DEF(int) pjpidf_print(const pjpidf_pres* pres, char *buf, int len)
361{
362 return pj_xml_print(pres, buf, len, PJ_TRUE);
363}
364