blob: 1bd719c4982c9e50d6c85d1bb142b5ef13d1d602 [file] [log] [blame]
Benny Prijono5dcb38d2005-11-21 01:55:47 +00001/* $Id$ */
2/*
3 * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
Benny Prijono834aee32006-02-19 01:38:06 +000019#include <pjsip-simple/xpidf.h>
20#include <pj/assert.h>
21#include <pj/guid.h>
Benny Prijono5dcb38d2005-11-21 01:55:47 +000022#include <pj/pool.h>
23#include <pj/string.h>
Benny Prijono5dcb38d2005-11-21 01:55:47 +000024
25static pj_str_t PRESENCE = { "presence", 8 };
26static pj_str_t STATUS = { "status", 6 };
27static pj_str_t OPEN = { "open", 4 };
28static pj_str_t CLOSED = { "closed", 6 };
29static pj_str_t URI = { "uri", 3 };
30static pj_str_t ATOM = { "atom", 4 };
31static pj_str_t ATOMID = { "atomid", 6 };
Benny Prijonobcaed6c2006-02-19 15:37:19 +000032static pj_str_t ID = { "id", 2 };
Benny Prijono5dcb38d2005-11-21 01:55:47 +000033static pj_str_t ADDRESS = { "address", 7 };
34static pj_str_t SUBSCRIBE_PARAM = { ";method=SUBSCRIBE", 17 };
35static pj_str_t PRESENTITY = { "presentity", 10 };
36static pj_str_t EMPTY_STRING = { NULL, 0 };
37
38static pj_xml_node* xml_create_node(pj_pool_t *pool,
39 pj_str_t *name, const pj_str_t *value)
40{
41 pj_xml_node *node;
42
43 node = pj_pool_alloc(pool, sizeof(pj_xml_node));
44 pj_list_init(&node->attr_head);
45 pj_list_init(&node->node_head);
46 node->name = *name;
47 if (value) pj_strdup(pool, &node->content, value);
48 else node->content.ptr=NULL, node->content.slen=0;
49
50 return node;
51}
52
53static pj_xml_attr* xml_create_attr(pj_pool_t *pool, pj_str_t *name,
54 const pj_str_t *value)
55{
56 pj_xml_attr *attr = pj_pool_alloc(pool, sizeof(*attr));
57 attr->name = *name;
58 pj_strdup(pool, &attr->value, value);
59 return attr;
60}
61
62
63PJ_DEF(pjxpidf_pres*) pjxpidf_create(pj_pool_t *pool, const pj_str_t *uri_cstr)
64{
65 pjxpidf_pres *pres;
66 pj_xml_node *presentity;
67 pj_xml_node *atom;
68 pj_xml_node *addr;
69 pj_xml_node *status;
70 pj_xml_attr *attr;
71 pj_str_t uri;
72 pj_str_t tmp;
73
74 /* <presence> */
75 pres = xml_create_node(pool, &PRESENCE, NULL);
76
77 /* <presentity> */
78 presentity = xml_create_node(pool, &PRESENTITY, NULL);
79 pj_xml_add_node(pres, presentity);
80
81 /* uri attribute */
82 uri.ptr = pj_pool_alloc(pool, uri_cstr->slen + SUBSCRIBE_PARAM.slen);
83 pj_strcpy( &uri, uri_cstr);
84 pj_strcat( &uri, &SUBSCRIBE_PARAM);
85 attr = xml_create_attr(pool, &URI, &uri);
86 pj_xml_add_attr(presentity, attr);
87
88 /* <atom> */
89 atom = xml_create_node(pool, &ATOM, NULL);
90 pj_xml_add_node(pres, atom);
91
92 /* atom id */
93 pj_create_unique_string(pool, &tmp);
94 attr = xml_create_attr(pool, &ATOMID, &tmp);
95 pj_xml_add_attr(atom, attr);
96
97 /* address */
98 addr = xml_create_node(pool, &ADDRESS, NULL);
99 pj_xml_add_node(atom, addr);
100
101 /* address'es uri */
102 attr = xml_create_attr(pool, &URI, uri_cstr);
103 pj_xml_add_attr(addr, attr);
104
105 /* status */
106 status = xml_create_node(pool, &STATUS, NULL);
107 pj_xml_add_node(addr, status);
108
109 /* status attr */
110 attr = xml_create_attr(pool, &STATUS, &OPEN);
111 pj_xml_add_attr(status, attr);
112
113 return pres;
114}
115
116
117
118PJ_DEF(pjxpidf_pres*) pjxpidf_parse(pj_pool_t *pool, char *text, pj_size_t len)
119{
120 pjxpidf_pres *pres;
121 pj_xml_node *node;
122
123 pres = pj_xml_parse(pool, text, len);
124 if (!pres)
125 return NULL;
126
127 /* Validate <presence> */
128 if (pj_stricmp(&pres->name, &PRESENCE) != 0)
129 return NULL;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000130
131 /* Validate <presentity> */
132 node = pj_xml_find_node(pres, &PRESENTITY);
133 if (node == NULL)
134 return NULL;
Benny Prijonobcaed6c2006-02-19 15:37:19 +0000135 if (pj_xml_find_attr(node, &URI, NULL) == NULL)
136 return NULL;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000137
138 /* Validate <atom> */
139 node = pj_xml_find_node(pres, &ATOM);
140 if (node == NULL)
141 return NULL;
Benny Prijonobcaed6c2006-02-19 15:37:19 +0000142 if (pj_xml_find_attr(node, &ATOMID, NULL) == NULL &&
143 pj_xml_find_attr(node, &ID, NULL) == NULL)
144 {
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000145 return NULL;
Benny Prijonobcaed6c2006-02-19 15:37:19 +0000146 }
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000147
148 /* Address */
149 node = pj_xml_find_node(node, &ADDRESS);
150 if (node == NULL)
151 return NULL;
152 if (pj_xml_find_attr(node, &URI, NULL) == NULL)
153 return NULL;
154
155
156 /* Status */
157 node = pj_xml_find_node(node, &STATUS);
158 if (node == NULL)
159 return NULL;
160 if (pj_xml_find_attr(node, &STATUS, NULL) == NULL)
161 return NULL;
162
163 return pres;
164}
165
166
167PJ_DEF(int) pjxpidf_print( pjxpidf_pres *pres, char *text, pj_size_t len)
168{
169 return pj_xml_print(pres, text, len, PJ_TRUE);
170}
171
172
173PJ_DEF(pj_str_t*) pjxpidf_get_uri(pjxpidf_pres *pres)
174{
175 pj_xml_node *presentity;
176 pj_xml_attr *attr;
177
178 presentity = pj_xml_find_node(pres, &PRESENTITY);
179 if (!presentity)
180 return &EMPTY_STRING;
181
182 attr = pj_xml_find_attr(presentity, &URI, NULL);
183 if (!attr)
184 return &EMPTY_STRING;
185
186 return &attr->value;
187}
188
189
190PJ_DEF(pj_status_t) pjxpidf_set_uri(pj_pool_t *pool, pjxpidf_pres *pres,
191 const pj_str_t *uri)
192{
193 pj_xml_node *presentity;
194 pj_xml_node *atom;
195 pj_xml_node *addr;
196 pj_xml_attr *attr;
197 pj_str_t dup_uri;
198
199 presentity = pj_xml_find_node(pres, &PRESENTITY);
200 if (!presentity) {
201 pj_assert(0);
202 return -1;
203 }
204 atom = pj_xml_find_node(pres, &ATOM);
205 if (!atom) {
206 pj_assert(0);
207 return -1;
208 }
209 addr = pj_xml_find_node(atom, &ADDRESS);
210 if (!addr) {
211 pj_assert(0);
212 return -1;
213 }
214
215 /* Set uri in presentity */
216 attr = pj_xml_find_attr(presentity, &URI, NULL);
217 if (!attr) {
218 pj_assert(0);
219 return -1;
220 }
221 pj_strdup(pool, &dup_uri, uri);
222 attr->value = dup_uri;
223
224 /* Set uri in address. */
225 attr = pj_xml_find_attr(addr, &URI, NULL);
226 if (!attr) {
227 pj_assert(0);
228 return -1;
229 }
230 attr->value = dup_uri;
231
232 return 0;
233}
234
235
236PJ_DEF(pj_bool_t) pjxpidf_get_status(pjxpidf_pres *pres)
237{
238 pj_xml_node *atom;
239 pj_xml_node *addr;
240 pj_xml_node *status;
241 pj_xml_attr *attr;
242
243 atom = pj_xml_find_node(pres, &ATOM);
244 if (!atom) {
245 pj_assert(0);
246 return PJ_FALSE;
247 }
248 addr = pj_xml_find_node(atom, &ADDRESS);
249 if (!addr) {
250 pj_assert(0);
251 return PJ_FALSE;
252 }
Benny Prijonobcaed6c2006-02-19 15:37:19 +0000253 status = pj_xml_find_node(addr, &STATUS);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000254 if (!status) {
255 pj_assert(0);
256 return PJ_FALSE;
257 }
258 attr = pj_xml_find_attr(status, &STATUS, NULL);
259 if (!attr) {
260 pj_assert(0);
261 return PJ_FALSE;
262 }
263
Benny Prijonobcaed6c2006-02-19 15:37:19 +0000264 return pj_stricmp(&attr->value, &OPEN)==0 ? PJ_TRUE : PJ_FALSE;
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000265}
266
267
268PJ_DEF(pj_status_t) pjxpidf_set_status(pjxpidf_pres *pres, pj_bool_t online_status)
269{
270 pj_xml_node *atom;
271 pj_xml_node *addr;
272 pj_xml_node *status;
273 pj_xml_attr *attr;
274
275 atom = pj_xml_find_node(pres, &ATOM);
276 if (!atom) {
277 pj_assert(0);
278 return -1;
279 }
280 addr = pj_xml_find_node(atom, &ADDRESS);
281 if (!addr) {
282 pj_assert(0);
283 return -1;
284 }
285 status = pj_xml_find_node(addr, &STATUS);
286 if (!status) {
287 pj_assert(0);
288 return -1;
289 }
290 attr = pj_xml_find_attr(status, &STATUS, NULL);
291 if (!attr) {
292 pj_assert(0);
293 return -1;
294 }
295
296 attr->value = ( online_status ? OPEN : CLOSED );
297 return 0;
298}
299