00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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) < 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_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 }