4 * Export vontact attrs as PV
6 * Copyright (C) 2008 Daniel-Constantin Mierla (asipto.com)
8 * This file is part of Kamailio, a free SIP server.
10 * Kamailio is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version
15 * Kamailio is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 * \brief SIP registrar module - export contacts as PV
33 #include "../../dprint.h"
34 #include "../../mem/mem.h"
35 #include "../../mod_fix.h"
36 #include "../ims_usrloc_scscf/usrloc.h"
41 typedef struct _regpv_profile {
49 struct _regpv_profile *next;
52 typedef struct _regpv_name {
57 static regpv_profile_t *_regpv_profile_list = NULL;
59 static inline regpv_profile_t* regpv_get_profile(str *name)
63 if(name==NULL || name->len<=0)
65 LM_ERR("invalid parameters\n");
69 rp = _regpv_profile_list;
72 if(rp->pname.len == name->len
73 && strncmp(rp->pname.s, name->s, name->len)==0)
78 rp = (regpv_profile_t*)pkg_malloc(sizeof(regpv_profile_t));
81 LM_ERR("no more pkg\n");
84 memset(rp, 0, sizeof(regpv_profile_t));
85 rp->pname.s = (char*)pkg_malloc((name->len+1)*sizeof(char));
88 LM_ERR("no more pkg\n");
92 memcpy(rp->pname.s, name->s, name->len);
93 rp->pname.s[name->len] = '\0';
94 rp->pname.len = name->len;
96 rp->next = _regpv_profile_list;
97 _regpv_profile_list = rp;
101 static void regpv_free_profile(regpv_profile_t *rpp)
116 if(rpp->domain.s!=NULL)
123 pkg_free(rpp->aor.s);
135 void regpv_free_profiles(void)
138 regpv_profile_t *rp0;
140 rp = _regpv_profile_list;
144 if(rp->pname.s!=NULL)
145 pkg_free(rp->pname.s);
147 regpv_free_profile(rp0);
150 _regpv_profile_list = 0;
153 int pv_get_ulc(struct sip_msg *msg, pv_param_t *param,
157 regpv_profile_t *rpp;
164 LM_ERR("invalid params\n");
167 rp = (regpv_name_t*)param->pvn.u.dname;
168 if(rp==NULL || rp->rp==NULL)
170 LM_DBG("no profile in params\n");
171 return pv_get_null(msg, param, res);
175 if(rpp->flags==0 || rpp->contacts==NULL)
177 LM_DBG("profile not set or no contacts there\n");
178 return pv_get_null(msg, param, res);
181 if(pv_get_spec_index(msg, param, &idx, &i)!=0)
183 LM_ERR("invalid index\n");
187 /* work only with positive indexes by now */
202 return pv_get_null(msg, param, res);
207 return pv_get_strval(msg, param, res, &rpp->aor);
210 return pv_get_strval(msg, param, res, &rpp->domain);
212 case 2: /* aorhash */
213 return pv_get_uintval(msg, param, res, rpp->aorhash);
216 return pv_get_strval(msg, param, res, &c->c);
219 return pv_get_strval(msg, param, res, &c->path);
221 case 5: /* received */
222 return pv_get_strval(msg, param, res, &c->received);
224 case 6: /* expires */
225 return pv_get_uintval(msg, param, res,
226 (unsigned int)c->expires);
229 return pv_get_strval(msg, param, res, &c->callid);
232 return pv_get_sintval(msg, param, res, (int)c->q);
235 return pv_get_sintval(msg, param, res, c->cseq);
238 return pv_get_uintval(msg, param, res, c->flags);
240 case 11: /* cflags */
241 return pv_get_uintval(msg, param, res, c->cflags);
243 case 12: /* user agent */
244 return pv_get_strval(msg, param, res, &c->user_agent);
246 case 14: /* socket */
248 return pv_get_null(msg, param, res);
249 return pv_get_strval(msg, param, res, &c->sock->sock_str);
251 case 15: /* modified */
252 return pv_get_uintval(msg, param, res,
253 (unsigned int)c->last_modified);
255 case 16: /* methods */
256 return pv_get_uintval(msg, param, res, c->methods);
259 return pv_get_sintval(msg, param, res, rpp->nrc);
263 return pv_get_null(msg, param, res);
266 int pv_set_ulc(struct sip_msg* msg, pv_param_t *param,
267 int op, pv_value_t *val)
272 int pv_parse_ulc_name(pv_spec_p sp, str *in)
277 regpv_profile_t *rpp;
279 if(sp==NULL || in==NULL || in->len<=0)
283 while(pa.s < in->s + in->len - 2)
290 if(pa.s >= in->s + in->len - 2)
292 LM_ERR("invalid contact pv name %.*s\n", in->len, in->s);
297 LM_ERR("invalid contact pv name %.*s.\n", in->len, in->s);
302 pn.len = pa.s - pn.s;
304 LM_DBG("get profile [%.*s]\n", pn.len, pn.s);
306 rpp = regpv_get_profile(&pn);
309 LM_ERR("cannot get profile [%.*s]\n", pn.len, pn.s);
313 pa.len = in->s + in->len - pa.s;
314 LM_DBG("get attr [%.*s]\n", pa.len, pa.s);
316 rp = (regpv_name_t*)pkg_malloc(sizeof(regpv_name_t));
319 LM_ERR("no more pkg\n");
322 memset(rp, 0, sizeof(regpv_name_t));
328 if(strncmp(pa.s, "q", 1)==0)
333 if(strncmp(pa.s, "aor", 3)==0)
338 if(strncmp(pa.s, "addr", 4)==0)
340 else if(strncmp(pa.s, "path", 4)==0)
342 else if(strncmp(pa.s, "cseq", 4)==0)
347 if(strncmp(pa.s, "flags", 5)==0)
349 else if(strncmp(pa.s, "count", 5)==0)
354 if(strncmp(pa.s, "domain", 6)==0)
356 else if(strncmp(pa.s, "callid", 6)==0)
358 else if(strncmp(pa.s, "cflags", 6)==0)
360 else if(strncmp(pa.s, "socket", 6)==0)
365 if(strncmp(pa.s, "aorhash", 7)==0)
367 else if(strncmp(pa.s, "expires", 7)==0)
369 else if(strncmp(pa.s, "methods", 7)==0)
374 if(strncmp(pa.s, "received", 8)==0)
376 else if(strncmp(pa.s, "modified", 8)==0)
381 if(strncmp(pa.s, "user_agent", 10)==0)
388 sp->pvp.pvn.u.dname = (void*)rp;
389 sp->pvp.pvn.type = PV_NAME_PVAR;
394 LM_ERR("unknown contact attr name in %.*s\n", in->len, in->s);
398 int pv_fetch_contacts(struct sip_msg* msg, char* table, char* uri,
405 regpv_profile_t *rpp;
414 rpp = regpv_get_profile((str*)profile);
417 LM_ERR("invalid parameters\n");
421 /* check and free if profile already set */
423 regpv_free_profile(rpp);
425 if(fixup_get_svalue(msg, (gparam_p)uri, &u)!=0 || u.len<=0)
427 LM_ERR("invalid uri parameter\n");
431 if (extract_aor(&u, &aor) < 0) {
432 LM_ERR("failed to extract Address Of Record\n");
436 /* copy aor and ul domain */
437 rpp->aor.s = (char*)pkg_malloc(aor.len*sizeof(char));
440 LM_ERR("no more pkg\n");
443 memcpy(rpp->aor.s, aor.s, aor.len);
444 rpp->aor.len = aor.len;
445 rpp->domain = *((udomain_head_t*)table)->name;
449 ilen = sizeof(ucontact_t);
450 ul.lock_udomain((udomain_t*)table, &aor);
451 res = ul.get_impurecord((udomain_t*)table, &aor, &r);
453 LM_DBG("'%.*s' Not found in usrloc\n", aor.len, ZSW(aor.s));
454 ul.unlock_udomain((udomain_t*)table, &aor);
463 olen = (ptr->c.len + ptr->received.len + ptr->path.len
464 + ptr->callid.len + ptr->user_agent.len)*sizeof(char) + ilen;
465 c0 = (ucontact_t*)pkg_malloc(olen);
468 LM_ERR("no more pkg\n");
469 ul.unlock_udomain((udomain_t*)table, &aor);
472 memcpy(c0, ptr, ilen);
478 c0->c.s = (char*)c0 + ilen;
479 memcpy(c0->c.s, ptr->c.s, ptr->c.len);
480 c0->c.len = ptr->c.len;
481 p = c0->c.s + c0->c.len;
483 if(ptr->received.s!=NULL)
486 memcpy(c0->received.s, ptr->received.s, ptr->received.len);
487 c0->received.len = ptr->received.len;
488 p += c0->received.len;
490 if(ptr->path.s!=NULL)
493 memcpy(c0->path.s, ptr->path.s, ptr->path.len);
494 c0->path.len = ptr->path.len;
498 memcpy(c0->callid.s, ptr->callid.s, ptr->callid.len);
499 c0->callid.len = ptr->callid.len;
501 if(ptr->user_agent.s!=NULL)
503 c0->user_agent.s = p;
504 memcpy(c0->user_agent.s, ptr->user_agent.s, ptr->user_agent.len);
505 c0->user_agent.len = ptr->user_agent.len;
506 p += c0->user_agent.len;
520 ul.unlock_udomain((udomain_t*)table, &aor);
522 LM_DBG("fetched <%d> contacts for <%.*s> in [%.*s]\n",
523 n, aor.len, aor.s, rpp->pname.len, rpp->pname.s);
527 regpv_free_profile(rpp);
530 int pv_free_contacts(struct sip_msg* msg, char* profile, char* s2)
532 regpv_profile_t *rpp;
534 rpp = regpv_get_profile((str*)profile);
538 regpv_free_profile(rpp);