00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00032 #include <string.h>
00033 #include "../../dprint.h"
00034 #include "../../mem/mem.h"
00035 #include "../../mod_fix.h"
00036 #include "../usrloc/usrloc.h"
00037 #include "reg_mod.h"
00038 #include "common.h"
00039 #include "regpv.h"
00040
00041 typedef struct _regpv_profile {
00042 str pname;
00043 str domain;
00044 str aor;
00045 int flags;
00046 unsigned int aorhash;
00047 int nrc;
00048 ucontact_t* contacts;
00049 struct _regpv_profile *next;
00050 } regpv_profile_t;
00051
00052 typedef struct _regpv_name {
00053 regpv_profile_t *rp;
00054 int attr;
00055 } regpv_name_t;
00056
00057 static regpv_profile_t *_regpv_profile_list = NULL;
00058
00059 static inline regpv_profile_t* regpv_get_profile(str *name)
00060 {
00061 regpv_profile_t *rp;
00062
00063 if(name==NULL || name->len<=0)
00064 {
00065 LM_ERR("invalid parameters\n");
00066 return NULL;
00067 }
00068
00069 rp = _regpv_profile_list;
00070 while(rp)
00071 {
00072 if(rp->pname.len == name->len
00073 && strncmp(rp->pname.s, name->s, name->len)==0)
00074 return rp;
00075 rp = rp->next;
00076 }
00077
00078 rp = (regpv_profile_t*)pkg_malloc(sizeof(regpv_profile_t));
00079 if(rp==NULL)
00080 {
00081 LM_ERR("no more pkg\n");
00082 return NULL;
00083 }
00084 memset(rp, 0, sizeof(regpv_profile_t));
00085 rp->pname.s = (char*)pkg_malloc((name->len+1)*sizeof(char));
00086 if(rp->pname.s==NULL)
00087 {
00088 LM_ERR("no more pkg\n");
00089 pkg_free(rp);
00090 return NULL;
00091 }
00092 memcpy(rp->pname.s, name->s, name->len);
00093 rp->pname.s[name->len] = '\0';
00094 rp->pname.len = name->len;
00095
00096 rp->next = _regpv_profile_list;
00097 _regpv_profile_list = rp;
00098 return rp;
00099 }
00100
00101 static void regpv_free_profile(regpv_profile_t *rpp)
00102 {
00103 ucontact_t* ptr;
00104 ucontact_t* ptr0;
00105
00106 if(rpp==NULL)
00107 return;
00108
00109 ptr = rpp->contacts;
00110 while(ptr)
00111 {
00112 ptr0 = ptr;
00113 ptr = ptr->next;
00114 pkg_free(ptr0);
00115 }
00116 if(rpp->domain.s!=NULL)
00117 {
00118 rpp->domain.s = 0;
00119 rpp->domain.len = 0;
00120 }
00121 if(rpp->aor.s!=NULL)
00122 {
00123 pkg_free(rpp->aor.s);
00124 rpp->aor.s = 0;
00125 rpp->aor.len = 0;
00126 }
00127
00128 rpp->flags = 0;
00129 rpp->aorhash = 0;
00130 rpp->nrc = 0;
00131 rpp->contacts = 0;
00132
00133 }
00134
00135 void regpv_free_profiles(void)
00136 {
00137 regpv_profile_t *rp;
00138 regpv_profile_t *rp0;
00139
00140 rp = _regpv_profile_list;
00141
00142 while(rp)
00143 {
00144 if(rp->pname.s!=NULL)
00145 pkg_free(rp->pname.s);
00146 rp0 = rp;
00147 regpv_free_profile(rp0);
00148 rp = rp->next;
00149 }
00150 _regpv_profile_list = 0;
00151 }
00152
00153 int pv_get_ulc(struct sip_msg *msg, pv_param_t *param,
00154 pv_value_t *res)
00155 {
00156 regpv_name_t *rp;
00157 regpv_profile_t *rpp;
00158 ucontact_t *c;
00159 int idx;
00160 int i;
00161
00162 if(param==NULL)
00163 {
00164 LM_ERR("invalid params\n");
00165 return -1;
00166 }
00167 rp = (regpv_name_t*)param->pvn.u.dname;
00168 if(rp==NULL || rp->rp==NULL)
00169 {
00170 LM_DBG("no profile in params\n");
00171 return pv_get_null(msg, param, res);
00172 }
00173 rpp = rp->rp;
00174
00175 if(rpp->flags==0 || rpp->contacts==NULL)
00176 {
00177 LM_DBG("profile not set or no contacts there\n");
00178 return pv_get_null(msg, param, res);
00179 }
00180
00181 if(pv_get_spec_index(msg, param, &idx, &i)!=0)
00182 {
00183 LM_ERR("invalid index\n");
00184 return -1;
00185 }
00186
00187
00188 if(idx<0)
00189 idx = 0;
00190
00191
00192 i = 0;
00193 c = rpp->contacts;
00194 while(rpp)
00195 {
00196 if(i == idx)
00197 break;
00198 i++;
00199 c = c->next;
00200 }
00201 if(c==NULL)
00202 return pv_get_null(msg, param, res);
00203
00204 switch(rp->attr)
00205 {
00206 case 0:
00207 return pv_get_strval(msg, param, res, &rpp->aor);
00208 break;
00209 case 1:
00210 return pv_get_strval(msg, param, res, &rpp->domain);
00211 break;
00212 case 2:
00213 return pv_get_uintval(msg, param, res, rpp->aorhash);
00214 break;
00215 case 3:
00216 return pv_get_strval(msg, param, res, &c->c);
00217 break;
00218 case 4:
00219 return pv_get_strval(msg, param, res, &c->path);
00220 break;
00221 case 5:
00222 return pv_get_strval(msg, param, res, &c->received);
00223 break;
00224 case 6:
00225 return pv_get_uintval(msg, param, res,
00226 (unsigned int)c->expires);
00227 break;
00228 case 7:
00229 return pv_get_strval(msg, param, res, &c->callid);
00230 break;
00231 case 8:
00232 return pv_get_sintval(msg, param, res, (int)c->q);
00233 break;
00234 case 9:
00235 return pv_get_sintval(msg, param, res, c->cseq);
00236 break;
00237 case 10:
00238 return pv_get_uintval(msg, param, res, c->flags);
00239 break;
00240 case 11:
00241 return pv_get_uintval(msg, param, res, c->cflags);
00242 break;
00243 case 12:
00244 return pv_get_strval(msg, param, res, &c->user_agent);
00245 break;
00246 case 14:
00247 if(c->sock==NULL)
00248 return pv_get_null(msg, param, res);
00249 return pv_get_strval(msg, param, res, &c->sock->sock_str);
00250 break;
00251 case 15:
00252 return pv_get_uintval(msg, param, res,
00253 (unsigned int)c->last_modified);
00254 break;
00255 case 16:
00256 return pv_get_uintval(msg, param, res, c->methods);
00257 break;
00258 case 17:
00259 return pv_get_sintval(msg, param, res, rpp->nrc);
00260 break;
00261 }
00262
00263 return pv_get_null(msg, param, res);
00264 }
00265
00266 int pv_set_ulc(struct sip_msg* msg, pv_param_t *param,
00267 int op, pv_value_t *val)
00268 {
00269 return 0;
00270 }
00271
00272 int pv_parse_ulc_name(pv_spec_p sp, str *in)
00273 {
00274 str pn;
00275 str pa;
00276 regpv_name_t *rp;
00277 regpv_profile_t *rpp;
00278
00279 if(sp==NULL || in==NULL || in->len<=0)
00280 return -1;
00281
00282 pa.s = in->s;
00283 while(pa.s < in->s + in->len - 2)
00284 {
00285 if(*pa.s=='=')
00286 break;
00287 pa.s++;
00288 }
00289
00290 if(pa.s >= in->s + in->len - 2)
00291 {
00292 LM_ERR("invalid contact pv name %.*s\n", in->len, in->s);
00293 return -1;
00294 }
00295 if(*(pa.s+1) != '>')
00296 {
00297 LM_ERR("invalid contact pv name %.*s.\n", in->len, in->s);
00298 return -1;
00299 }
00300
00301 pn.s = in->s;
00302 pn.len = pa.s - pn.s;
00303
00304 LM_DBG("get profile [%.*s]\n", pn.len, pn.s);
00305
00306 rpp = regpv_get_profile(&pn);
00307 if(rpp==NULL)
00308 {
00309 LM_ERR("cannot get profile [%.*s]\n", pn.len, pn.s);
00310 return -1;
00311 }
00312 pa.s += 2;
00313 pa.len = in->s + in->len - pa.s;
00314 LM_DBG("get attr [%.*s]\n", pa.len, pa.s);
00315
00316 rp = (regpv_name_t*)pkg_malloc(sizeof(regpv_name_t));
00317 if(rp==0)
00318 {
00319 LM_ERR("no more pkg\n");
00320 return -1;
00321 }
00322 memset(rp, 0, sizeof(regpv_name_t));
00323 rp->rp = rpp;
00324
00325 switch(pa.len)
00326 {
00327 case 1:
00328 if(strncmp(pa.s, "q", 1)==0)
00329 rp->attr = 8;
00330 else goto error;
00331 break;
00332 case 3:
00333 if(strncmp(pa.s, "aor", 3)==0)
00334 rp->attr = 0;
00335 else goto error;
00336 break;
00337 case 4:
00338 if(strncmp(pa.s, "addr", 4)==0)
00339 rp->attr = 3;
00340 else if(strncmp(pa.s, "path", 4)==0)
00341 rp->attr = 4;
00342 else if(strncmp(pa.s, "cseq", 4)==0)
00343 rp->attr = 9;
00344 else goto error;
00345 break;
00346 case 5:
00347 if(strncmp(pa.s, "flags", 5)==0)
00348 rp->attr = 10;
00349 else if(strncmp(pa.s, "count", 5)==0)
00350 rp->attr = 17;
00351 else goto error;
00352 break;
00353 case 6:
00354 if(strncmp(pa.s, "domain", 6)==0)
00355 rp->attr = 1;
00356 else if(strncmp(pa.s, "callid", 6)==0)
00357 rp->attr = 7;
00358 else if(strncmp(pa.s, "cflags", 6)==0)
00359 rp->attr = 11;
00360 else if(strncmp(pa.s, "socket", 6)==0)
00361 rp->attr = 14;
00362 else goto error;
00363 break;
00364 case 7:
00365 if(strncmp(pa.s, "aorhash", 7)==0)
00366 rp->attr = 2;
00367 else if(strncmp(pa.s, "expires", 7)==0)
00368 rp->attr = 6;
00369 else if(strncmp(pa.s, "methods", 7)==0)
00370 rp->attr = 16;
00371 else goto error;
00372 break;
00373 case 8:
00374 if(strncmp(pa.s, "received", 8)==0)
00375 rp->attr = 5;
00376 else if(strncmp(pa.s, "modified", 8)==0)
00377 rp->attr = 15;
00378 else goto error;
00379 break;
00380 case 10:
00381 if(strncmp(pa.s, "user_agent", 10)==0)
00382 rp->attr = 12;
00383 else goto error;
00384 break;
00385 default:
00386 goto error;
00387 }
00388 sp->pvp.pvn.u.dname = (void*)rp;
00389 sp->pvp.pvn.type = PV_NAME_PVAR;
00390
00391 return 0;
00392
00393 error:
00394 LM_ERR("unknown contact attr name in %.*s\n", in->len, in->s);
00395 return -1;
00396 }
00397
00398 int pv_fetch_contacts(struct sip_msg* msg, char* table, char* uri,
00399 char* profile)
00400 {
00401 urecord_t* r;
00402 ucontact_t* ptr;
00403 ucontact_t* ptr0;
00404 ucontact_t* c0;
00405 regpv_profile_t *rpp;
00406 str aor = {0, 0};
00407 str u = {0, 0};
00408 int res;
00409 int olen;
00410 int ilen;
00411 int n;
00412 char *p;
00413
00414 rpp = regpv_get_profile((str*)profile);
00415 if(rpp==0)
00416 {
00417 LM_ERR("invalid parameters\n");
00418 return -1;
00419 }
00420
00421
00422 if(rpp->flags)
00423 regpv_free_profile(rpp);
00424
00425 if(fixup_get_svalue(msg, (gparam_p)uri, &u)!=0 || u.len<=0)
00426 {
00427 LM_ERR("invalid uri parameter\n");
00428 return -1;
00429 }
00430
00431 if (extract_aor(&u, &aor, NULL) < 0) {
00432 LM_ERR("failed to extract Address Of Record\n");
00433 return -1;
00434 }
00435
00436
00437 rpp->aor.s = (char*)pkg_malloc(aor.len*sizeof(char));
00438 if(rpp->aor.s==NULL)
00439 {
00440 LM_ERR("no more pkg\n");
00441 return -1;
00442 }
00443 memcpy(rpp->aor.s, aor.s, aor.len);
00444 rpp->aor.len = aor.len;
00445 rpp->domain = *((udomain_head_t*)table)->name;
00446 rpp->flags = 1;
00447
00448
00449 ilen = sizeof(ucontact_t);
00450 ul.lock_udomain((udomain_t*)table, &aor);
00451 res = ul.get_urecord((udomain_t*)table, &aor, &r);
00452 if (res > 0) {
00453 LM_DBG("'%.*s' Not found in usrloc\n", aor.len, ZSW(aor.s));
00454 ul.unlock_udomain((udomain_t*)table, &aor);
00455 return -1;
00456 }
00457
00458 ptr = r->contacts;
00459 ptr0 = NULL;
00460 n = 0;
00461 while(ptr)
00462 {
00463 olen = (ptr->c.len + ptr->received.len + ptr->path.len
00464 + ptr->callid.len + ptr->user_agent.len)*sizeof(char) + ilen;
00465 c0 = (ucontact_t*)pkg_malloc(olen);
00466 if(c0==NULL)
00467 {
00468 LM_ERR("no more pkg\n");
00469 ul.unlock_udomain((udomain_t*)table, &aor);
00470 goto error;
00471 }
00472 memcpy(c0, ptr, ilen);
00473 c0->domain = NULL;
00474 c0->aor = NULL;
00475 c0->next = NULL;
00476 c0->prev = NULL;
00477
00478 c0->c.s = (char*)c0 + ilen;
00479 memcpy(c0->c.s, ptr->c.s, ptr->c.len);
00480 c0->c.len = ptr->c.len;
00481 p = c0->c.s + c0->c.len;
00482
00483 if(ptr->received.s!=NULL)
00484 {
00485 c0->received.s = p;
00486 memcpy(c0->received.s, ptr->received.s, ptr->received.len);
00487 c0->received.len = ptr->received.len;
00488 p += c0->received.len;
00489 }
00490 if(ptr->path.s!=NULL)
00491 {
00492 c0->path.s = p;
00493 memcpy(c0->path.s, ptr->path.s, ptr->path.len);
00494 c0->path.len = ptr->path.len;
00495 p += c0->path.len;
00496 }
00497 c0->callid.s = p;
00498 memcpy(c0->callid.s, ptr->callid.s, ptr->callid.len);
00499 c0->callid.len = ptr->callid.len;
00500 p += c0->callid.len;
00501 if(ptr->user_agent.s!=NULL)
00502 {
00503 c0->user_agent.s = p;
00504 memcpy(c0->user_agent.s, ptr->user_agent.s, ptr->user_agent.len);
00505 c0->user_agent.len = ptr->user_agent.len;
00506 p += c0->user_agent.len;
00507 }
00508
00509 if(ptr0==NULL)
00510 {
00511 rpp->contacts = c0;
00512 } else {
00513 ptr0->next = c0;
00514 c0->prev = ptr0;
00515 }
00516 n++;
00517 ptr0 = c0;
00518 ptr = ptr->next;
00519 }
00520 ul.unlock_udomain((udomain_t*)table, &aor);
00521 rpp->nrc = n;
00522 LM_DBG("fetched <%d> contacts for <%.*s> in [%.*s]\n",
00523 n, aor.len, aor.s, rpp->pname.len, rpp->pname.s);
00524 return 1;
00525
00526 error:
00527 regpv_free_profile(rpp);
00528 return -1;
00529 }
00530 int pv_free_contacts(struct sip_msg* msg, char* profile, char* s2)
00531 {
00532 regpv_profile_t *rpp;
00533
00534 rpp = regpv_get_profile((str*)profile);
00535 if(rpp==0)
00536 return -1;
00537
00538 regpv_free_profile(rpp);
00539
00540 return 1;
00541 }