Definition in file registrar_subscribe.c.
#include "registrar_subscribe.h"
#include <libxml/xmlschemas.h>
#include <libxml/parser.h>
#include "registrar_storage.h"
#include "mod.h"
#include "../../mem/mem.h"
#include "../../mem/shm_mem.h"
#include "../../parser/parse_uri.h"
#include "../../locking.h"
#include "../tm/tm_load.h"
#include "../dialog/dlg_mod.h"
#include "sip.h"
#include "ims_pm.h"
Go to the source code of this file.
Defines | |
| #define | h_inc h+=v^(v>>3) |
Functions | |
| unsigned int | get_subscription_hash (str uri) |
| Computes the hash for a contact. | |
| void | subs_lock (unsigned int hash) |
| Lock a subscription hash slot. | |
| void | subs_unlock (unsigned int hash) |
| UnLock a subscriptions hash slot. | |
| int | r_subscription_init () |
| Initialize the subscription list. | |
| void | r_subscription_destroy () |
| Destroys the subscription list. | |
| int | P_subscribe (struct sip_msg *rpl, char *str1, char *str2) |
| Subscribe to the reg event to the S-CSCF. | |
| int | r_subscribe (str uri, int duration) |
| Creates a subcription and starts the timer resubscription for the given contact. | |
| int | r_send_subscribe (r_subscription *s, int duration) |
| Send a subscription. | |
| void | r_subscribe_response (struct cell *t, int type, struct tmcb_params *ps) |
| Response callback for subscribe. | |
| void | subscription_timer (unsigned int ticks, void *param) |
| The Subscription timer looks for almost expired subscriptions and subscribes again. | |
| r_subscription * | new_r_subscription (str req_uri, int duration) |
| Creates a subscription based on the given parameters. | |
| void | add_r_subscription (r_subscription *s) |
| Adds a subscription to the list of subscriptions at the end (FIFO). | |
| int | update_r_subscription (r_subscription *s, int expires) |
| Updates the expiration time of a subscription. | |
| r_subscription * | get_r_subscription (str aor) |
| Returns a subscription if it exists. | |
| int | is_r_subscription (str aor) |
| Finds out if a subscription exists. | |
| void | del_r_subscription (r_subscription *s) |
| Deletes a subscription from the list of subscriptions. | |
| void | del_r_subscription_nolock (r_subscription *s) |
| Deletes a subscription from the list of subscriptions. | |
| void | free_r_subscription (r_subscription *s) |
| Frees up space taken by a subscription. | |
| void | print_subs (int log_level) |
| int | parser_init (char *dtd_filename) |
| Initializes the libxml parser. | |
| void | parser_destroy () |
| Destroys the parser. | |
| static void | space_trim_dup (str *dest, char *src) |
| Trims spaces and duplicate content into pkg. | |
| r_notification * | r_notification_parse (str xml) |
| Parses a notification and creates the r_notification object. | |
| int | r_notification_process (r_notification *n, int expires) |
| Processes a notification and updates the registrar info. | |
| void | r_notification_print (r_notification *n) |
| Prints the content of a notification. | |
| void | r_notification_free (r_notification *n) |
| Frees up the space taken by a notification. | |
Variables | |
| tm_binds | tmb |
| Structure with pointers to tm funcs. | |
| dlg_func_t | dialogb |
| Structure with pointers to dialog funcs. | |
| str | pcscf_name_str |
| fixed SIP URI of this P-CSCF | |
| str | pcscf_path_str |
| fixed Path URI | |
| time_t | time_now |
| current time | |
| r_hash_slot * | registrar |
| the actual registrar | |
| int | r_hash_size |
| number of hash slots in the registrar | |
| int | pcscf_subscribe_retries |
| times to retry subscribe to reg on failure | |
| r_subscription_hash_slot * | subscriptions = 0 |
| The P-CSCF subscriptions. | |
| int | subscriptions_hash_size |
| the size of the hash table for subscriptions | |
| static str | method = {"SUBSCRIBE",9} |
| static str | event_hdr = {"Event: reg\r\n",12} |
| static str | accept_hdr = {"Accept: application/reginfo+xml\r\n",33} |
| static str | content_len_hdr = {"Content-Length: 0\r\n",19} |
| static str | max_fwds_hdr = {"Max-Forwards: 10\r\n",18} |
| static str | expires_s = {"Expires: ",9} |
| static str | expires_e = {"\r\n",2} |
| static str | contact_s = {"Contact: <",10} |
| static str | contact_e = {">\r\n",3} |
| static str | p_asserted_identity_s = {"P-Asserted-Identity: <",22} |
| static str | p_asserted_identity_e = {">\r\n",3} |
| char * | pcscf_reginfo_dtd |
| DTD to check the reginfo/xml in the NOTIFY to reg. | |
| static xmlDtdPtr | dtd = 0 |
| DTD file. | |
| static xmlValidCtxt | cvp |
| XML Validating context. | |
| #define h_inc h+=v^(v>>3) |
| unsigned int get_subscription_hash | ( | str | uri | ) | [inline] |
Computes the hash for a contact.
| aor | - the string of the contact | |
| port | - the port of the contact | |
| transport | - transport for the contact - ignored for now | |
| hash_size | - size of the hash, to % with |
Definition at line 98 of file registrar_subscribe.c.
References h_inc, and subscriptions_hash_size.
Referenced by add_r_subscription(), bin_decode_r_subscription(), get_r_subscription(), and is_r_subscription().
00099 { 00100 #define h_inc h+=v^(v>>3) 00101 char* p; 00102 register unsigned v; 00103 register unsigned h; 00104 h=0; 00105 for (p=uri.s; p<=(uri.s+uri.len-4); p+=4){ 00106 v=(*p<<24)+(p[1]<<16)+(p[2]<<8)+p[3]; 00107 h_inc; 00108 } 00109 v=0; 00110 for (;p<(uri.s+uri.len); p++) { 00111 v<<=8; 00112 v+=*p; 00113 } 00114 h_inc; 00115 h=((h)+(h>>11))+((h>>13)+(h>>23)); 00116 return (h)%subscriptions_hash_size; 00117 #undef h_inc 00118 }
| void subs_lock | ( | unsigned int | hash | ) | [inline] |
Lock a subscription hash slot.
| hash | - index to lock |
Definition at line 124 of file registrar_subscribe.c.
References subscriptions.
Referenced by add_r_subscription(), bin_cache_dump_subs_to_table(), bin_cache_load_subscriptions_from_table(), del_r_subscription(), get_r_subscription(), is_r_subscription(), load_snapshot_subscriptions(), make_snapshot_subscriptions(), print_subs(), r_subscription_destroy(), and subscription_timer().
00125 { 00126 // LOG(L_CRIT,"GET %d\n",hash); 00127 lock_get(subscriptions[hash].lock); 00128 // LOG(L_CRIT,"GOT %d\n",hash); 00129 }
| void subs_unlock | ( | unsigned int | hash | ) | [inline] |
UnLock a subscriptions hash slot.
| hash | - index to unlock |
Definition at line 134 of file registrar_subscribe.c.
References subscriptions.
Referenced by add_r_subscription(), bin_cache_dump_subs_to_table(), bin_cache_load_subscriptions_from_table(), del_r_subscription(), get_r_subscription(), is_r_subscription(), load_snapshot_subscriptions(), make_snapshot_subscriptions(), print_subs(), r_notification_process(), r_subscribe(), r_subscribe_response(), subscription_timer(), and update_r_subscription().
00135 { 00136 // LOG(L_CRIT,"REL %d\n",hash); 00137 lock_release(subscriptions[hash].lock); 00138 }
| int r_subscription_init | ( | ) |
Initialize the subscription list.
Definition at line 143 of file registrar_subscribe.c.
References r_subscription_hash_slot::lock, subscriptions, and subscriptions_hash_size.
Referenced by mod_init().
00144 { 00145 int i; 00146 subscriptions = shm_malloc(sizeof(r_subscription_hash_slot)*subscriptions_hash_size); 00147 if (!subscriptions) return 0; 00148 memset(subscriptions,0,sizeof(r_subscription_hash_slot)*subscriptions_hash_size); 00149 for(i=0;i<subscriptions_hash_size;i++){ 00150 subscriptions[i].lock = lock_alloc(); 00151 if (!subscriptions[i].lock) return 0; 00152 subscriptions[i].lock = lock_init(subscriptions[i].lock); 00153 } 00154 return 1; 00155 }
| void r_subscription_destroy | ( | ) |
Destroys the subscription list.
Definition at line 160 of file registrar_subscribe.c.
References free_r_subscription(), r_subscription_hash_slot::head, _r_subscription::next, subs_lock(), subscriptions, and subscriptions_hash_size.
Referenced by mod_destroy().
00161 { 00162 int i; 00163 r_subscription *s,*ns; 00164 for(i=0;i<subscriptions_hash_size;i++){ 00165 subs_lock(i); 00166 s = subscriptions[i].head; 00167 while(s){ 00168 ns = s->next; 00169 //TODO send out unSUBSCRIBE 00170 free_r_subscription(s); 00171 s = ns; 00172 } 00173 lock_destroy(subscriptions[i].lock); 00174 lock_dealloc(subscriptions[i].lock); 00175 } 00176 shm_free(subscriptions); 00177 }
| int P_subscribe | ( | struct sip_msg * | rpl, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Subscribe to the reg event to the S-CSCF.
| rpl | - 200 OK response to REGISTER containing contacts and Service-Route header | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 187 of file registrar_subscribe.c.
References cscf_get_expires_hdr(), cscf_get_first_p_associated_uri(), cscf_parse_contacts(), CSCF_RETURN_ERROR, CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, M_NAME, and r_subscribe().
00188 { 00189 int expires_hdr=0,r,max_expires; 00190 str public_id={0,0}; 00191 contact_t* c=0; 00192 contact_body_t* b=0; 00193 00194 cscf_get_first_p_associated_uri(rpl,&public_id); 00195 00196 expires_hdr = cscf_get_expires_hdr(rpl); 00197 00198 if (parse_headers(rpl, HDR_EOH_F, 0) <0) { 00199 LOG(L_ERR,"ERR:"M_NAME":P_subscribe: error parsing headers\n"); 00200 return CSCF_RETURN_ERROR; 00201 } 00202 00203 b = cscf_parse_contacts(rpl); 00204 00205 if (!b||!b->contacts) { 00206 LOG(L_DBG,"DBG:"M_NAME":P_subscribe: No contacts found\n"); 00207 return CSCF_RETURN_FALSE; 00208 } 00209 00210 if (b) c = b->contacts; 00211 00212 max_expires = expires_hdr; 00213 while(c){ 00214 r = expires_hdr; 00215 if (str2int(&(c->expires->body), (unsigned int*)&r) < 0) { 00216 r = 0; 00217 } 00218 if (r>max_expires) max_expires = r; 00219 c = c->next; 00220 } 00221 if (max_expires<=0){ 00222 LOG(L_INFO,"DBG:"M_NAME":P_subscribe: skipped because de-register\n"); 00223 return CSCF_RETURN_FALSE; 00224 } 00225 00226 if (public_id.s){ 00227 // if (max_expires==0) 00228 // r_subscribe(public_id,0); 00229 // else 00230 r_subscribe(public_id,max_expires+30); 00231 return CSCF_RETURN_TRUE; 00232 }else{ 00233 return CSCF_RETURN_FALSE; 00234 } 00235 }
| int r_subscribe | ( | str | uri, | |
| int | duration | |||
| ) |
Creates a subcription and starts the timer resubscription for the given contact.
| uri | - the contact to subscribe to (actually to its default public id) | |
| duration | - SUBCRIBE expires |
Definition at line 243 of file registrar_subscribe.c.
References add_r_subscription(), _r_subscription::attempts_left, _r_subscription::duration, get_r_subscription(), _r_subscription::hash, M_NAME, new_r_subscription(), pcscf_subscribe_retries, and subs_unlock().
Referenced by P_subscribe().
00244 { 00245 r_subscription *s; 00246 /* first we try to update. if not found, add it */ 00247 s = get_r_subscription(uri); 00248 if (s){ 00249 s->duration = duration; 00250 s->attempts_left=pcscf_subscribe_retries; 00251 subs_unlock(s->hash); 00252 }else{ 00253 s = new_r_subscription(uri,duration); 00254 if (!s){ 00255 LOG(L_ERR,"ERR:"M_NAME":r_subscribe: Error creating new subscription\n"); 00256 return 0; 00257 } 00258 add_r_subscription(s); 00259 s->attempts_left=pcscf_subscribe_retries; 00260 } 00261 00262 return 1; 00263 }
| int r_send_subscribe | ( | r_subscription * | s, | |
| int | duration | |||
| ) |
Send a subscription.
| s | - the subsription to send for | |
| duration | - expires time |
Definition at line 284 of file registrar_subscribe.c.
References accept_hdr, contact_e, contact_s, content_len_hdr, _r_subscription::dialog, dialogb, event_hdr, expires_e, expires_s, M_NAME, max_fwds_hdr, method, p_asserted_identity_e, p_asserted_identity_s, pcscf_name_str, pcscf_path_str, r_subscribe_response(), _r_subscription::req_uri, STR_APPEND, and tmb.
Referenced by subscription_timer().
00285 { 00286 str h={0,0}; 00287 00288 LOG(L_DBG,"DBG:"M_NAME":r_send_subscribe: SUBSCRIBE to <%.*s>\n", 00289 s->req_uri.len,s->req_uri.s); 00290 00291 h.len = event_hdr.len+accept_hdr.len+content_len_hdr.len+max_fwds_hdr.len; 00292 h.len += expires_s.len + 12 + expires_e.len; 00293 00294 h.len += contact_s.len + pcscf_name_str.len + contact_e.len; 00295 if (pcscf_path_str.len) h.len += p_asserted_identity_s.len + 00296 p_asserted_identity_e.len + pcscf_path_str.len; 00297 00298 h.s = pkg_malloc(h.len); 00299 if (!h.s){ 00300 LOG(L_ERR,"ERR:"M_NAME":r_send_subscribe: Error allocating %d bytes\n",h.len); 00301 h.len = 0; 00302 return 0; 00303 } 00304 00305 h.len = 0; 00306 STR_APPEND(h,event_hdr); 00307 STR_APPEND(h,accept_hdr); 00308 STR_APPEND(h,content_len_hdr); 00309 STR_APPEND(h,max_fwds_hdr); 00310 00311 STR_APPEND(h,expires_s); 00312 sprintf(h.s+h.len,"%d",duration); 00313 h.len += strlen(h.s+h.len); 00314 STR_APPEND(h,expires_e); 00315 00316 STR_APPEND(h,contact_s); 00317 STR_APPEND(h,pcscf_name_str); 00318 STR_APPEND(h,contact_e); 00319 00320 if (pcscf_path_str.len) { 00321 STR_APPEND(h,p_asserted_identity_s); 00322 STR_APPEND(h,pcscf_path_str); 00323 STR_APPEND(h,p_asserted_identity_e); 00324 } 00325 00326 if (!s->dialog){ 00327 /* this is the first request in the dialog */ 00328 if (tmb.new_dlg_uac(0,0,1,&pcscf_name_str,&s->req_uri,&s->dialog)<0){ 00329 LOG(L_ERR,"ERR:"M_NAME":r_send_subscribe: Error creating a dialog for SUBSCRIBE\n"); 00330 goto error; 00331 } 00332 if (dialogb.request_outside(&method, &h, 0, s->dialog, r_subscribe_response, 0) < 0){ 00333 LOG(L_ERR,"ERR:"M_NAME":r_send_subscribe: Error sending initial request in a SUBSCRIBE dialog\n"); 00334 goto error; 00335 } 00336 }else{ 00337 /* this is a subsequent subscribe */ 00338 if (dialogb.request_inside(&method, &h, 0, s->dialog, r_subscribe_response, 0) < 0){ 00339 LOG(L_ERR,"ERR:"M_NAME":r_send_subscribe: Error sending subsequent request in a SUBSCRIBE dialog\n"); 00340 goto error; 00341 } 00342 } 00343 00344 if (h.s) pkg_free(h.s); 00345 return 1; 00346 00347 error: 00348 if (h.s) pkg_free(h.s); 00349 return 0; 00350 }
| void r_subscribe_response | ( | struct cell * | t, | |
| int | type, | |||
| struct tmcb_params * | ps | |||
| ) |
Response callback for subscribe.
Definition at line 355 of file registrar_subscribe.c.
References cscf_get_expires_hdr(), cscf_get_to_uri(), _r_subscription::dialog, get_r_subscription(), _r_subscription::hash, M_NAME, subs_unlock(), tmb, and update_r_subscription().
Referenced by r_send_subscribe().
00356 { 00357 str req_uri; 00358 int expires; 00359 r_subscription *s=0; 00360 LOG(L_DBG,"DBG:"M_NAME":r_subscribe_response: code %d\n",ps->code); 00361 if (!ps->rpl || ps->rpl==(void*) -1) { 00362 LOG(L_ERR,"INF:"M_NAME":r_subscribe_response: No reply\n"); 00363 return; 00364 } 00365 if (!cscf_get_to_uri(ps->rpl,&req_uri)){ 00366 LOG(L_ERR,"INF:"M_NAME":r_subscribe_response: Error extracting the original Req-URI from To header\n"); 00367 return; 00368 } 00369 s = get_r_subscription(req_uri); 00370 if (!s){ 00371 LOG(L_ERR,"INF:"M_NAME":r_subscribe_response: received a SUBSCRIBE response but no subscription for <%.*s>\n", 00372 req_uri.len,req_uri.s); 00373 return; 00374 } 00375 if (ps->code>=200 && ps->code<300){ 00376 expires = cscf_get_expires_hdr(ps->rpl); 00377 update_r_subscription(s,expires); 00378 tmb.dlg_response_uac(s->dialog, ps->rpl, IS_TARGET_REFRESH); 00379 }else 00380 if (ps->code==404){ 00381 update_r_subscription(s,0); 00382 //tmb.dlg_response_uac(s->dialog, ps->rpl, IS_TARGET_REFRESH); 00383 }else{ 00384 LOG(L_INFO,"INF:"M_NAME":r_subscribe_response: SUBSCRIRE response code %d ignored\n",ps->code); 00385 } 00386 if (s) subs_unlock(s->hash); 00387 }
| void subscription_timer | ( | unsigned int | ticks, | |
| void * | param | |||
| ) |
The Subscription timer looks for almost expired subscriptions and subscribes again.
| ticks | - the current time | |
| param | - the generic parameter |
Definition at line 399 of file registrar_subscribe.c.
References _r_subscription::attempts_left, del_r_subscription_nolock(), _r_subscription::duration, _r_subscription::expires, r_subscription_hash_slot::head, IMS_PM_LOG01, M_NAME, _r_subscription::next, pcscf_subscribe_retries, print_subs(), r_act_time(), r_send_subscribe(), subs_lock(), subs_unlock(), subscriptions, subscriptions_hash_size, and time_now.
Referenced by mod_init().
00400 { 00401 r_subscription *s,*ns; 00402 int i; 00403 #ifdef WITH_IMS_PM 00404 int subs_cnt=0; 00405 #endif 00406 for(i=0;i<subscriptions_hash_size;i++){ 00407 subs_lock(i); 00408 s = subscriptions[i].head; 00409 r_act_time(); 00410 while(s){ 00411 ns = s->next; 00412 if (s->attempts_left > 0 ){ 00413 /* attempt to send a subscribe */ 00414 if (!r_send_subscribe(s,s->duration)){ 00415 LOG(L_ERR,"ERR:"M_NAME":subscription_timer: Error on SUBSCRIBE (%d times)... droping\n", 00416 pcscf_subscribe_retries); 00417 del_r_subscription_nolock(s); 00418 }else{ 00419 s->attempts_left--; 00420 #ifdef WITH_IMS_PM 00421 subs_cnt++; 00422 #endif 00423 } 00424 }else if (s->attempts_left==0) { 00425 /* we failed to many times, drop the subscription */ 00426 LOG(L_ERR,"ERR:"M_NAME":subscription_timer: Error on SUBSCRIBE for %d times... aborting\n",pcscf_subscribe_retries); 00427 del_r_subscription_nolock(s); 00428 }else{ 00429 /* we are subscribed already */ 00430 /* if expired, drop it */ 00431 if (s->expires<time_now) 00432 del_r_subscription_nolock(s); 00433 #ifdef WITH_IMS_PM 00434 else subs_cnt++; 00435 #endif 00436 00437 /* if not expired, check for renewal */ 00438 // Commented as the S-CSCF should adjust the subscription time accordingly 00439 // if ((s->duration<1200 && s->expires-time_now<s->duration/2)|| 00440 // (s->duration>=1200 && s->expires-time_now<600)) 00441 // { 00442 // /* if we need a resubscribe, we mark it as such and try to subscribe again */ 00443 // s->attempts_left = pcscf_subscribe_retries; 00444 // ns = s; 00445 // } 00446 } 00447 s = ns; 00448 } 00449 subs_unlock(i); 00450 } 00451 print_subs(L_INFO); 00452 #ifdef WITH_IMS_PM 00453 IMS_PM_LOG01(RD_NbrSubs,subs_cnt); 00454 #endif 00455 }
| r_subscription* new_r_subscription | ( | str | req_uri, | |
| int | duration | |||
| ) |
Creates a subscription based on the given parameters.
| req_uri | - the AOR of the user to subcribe to | |
| from | - the From header | |
| duration | - expires time in seconds | |
| asserted_identity | - P-Asserted-Identity-Header to use |
Definition at line 469 of file registrar_subscribe.c.
References _r_subscription::duration, _r_subscription::expires, M_NAME, _r_subscription::req_uri, and STR_SHM_DUP.
Referenced by r_subscribe().
00470 { 00471 r_subscription *s=0; 00472 00473 s = shm_malloc(sizeof(r_subscription)); 00474 if (!s){ 00475 LOG(L_ERR,"ERR:"M_NAME":new_r_subscription: Error allocating %d bytes\n", 00476 sizeof(r_subscription)); 00477 goto error; 00478 } 00479 memset(s,0,sizeof(r_subscription)); 00480 00481 STR_SHM_DUP(s->req_uri,req_uri,"new_r_subscription"); 00482 if (!s->req_uri.s) goto error; 00483 00484 s->duration = duration; 00485 s->expires = 0; 00486 00487 return s; 00488 error: 00489 out_of_memory: 00490 if (s->req_uri.s) shm_free(s->req_uri.s); 00491 if (s) shm_free(s); 00492 return 0; 00493 }
| void add_r_subscription | ( | r_subscription * | s | ) |
Adds a subscription to the list of subscriptions at the end (FIFO).
| s | - the subscription to be added |
Definition at line 499 of file registrar_subscribe.c.
References get_subscription_hash(), _r_subscription::hash, r_subscription_hash_slot::head, _r_subscription::next, _r_subscription::prev, _r_subscription::req_uri, subs_lock(), subs_unlock(), subscriptions, and r_subscription_hash_slot::tail.
Referenced by r_subscribe().
00500 { 00501 if (!s) return; 00502 s->hash = get_subscription_hash(s->req_uri); 00503 subs_lock(s->hash); 00504 s->next = 0; 00505 s->prev = subscriptions[s->hash].tail; 00506 if (subscriptions[s->hash].tail) subscriptions[s->hash].tail->next = s; 00507 subscriptions[s->hash].tail = s; 00508 if (!subscriptions[s->hash].head) subscriptions[s->hash].head = s; 00509 subs_unlock(s->hash); 00510 }
| int update_r_subscription | ( | r_subscription * | s, | |
| int | expires | |||
| ) |
Updates the expiration time of a subscription.
| aor | - aor to look for | |
| expires | - new expiration time |
Definition at line 519 of file registrar_subscribe.c.
References _r_subscription::attempts_left, del_r_subscription_nolock(), _r_subscription::expires, _r_subscription::hash, M_NAME, _r_subscription::req_uri, subs_unlock(), and time_now.
Referenced by r_notification_process(), and r_subscribe_response().
00520 { 00521 LOG(L_DBG,"DBG:"M_NAME":update_r_subscription: refreshing subscription for <%.*s> [%d]\n", 00522 s->req_uri.len,s->req_uri.s,expires); 00523 s->attempts_left = -1; 00524 if (expires == 0) del_r_subscription_nolock(s); 00525 else s->expires = expires+time_now;; 00526 subs_unlock(s->hash); 00527 return 1; 00528 }
| r_subscription* get_r_subscription | ( | str | aor | ) |
Returns a subscription if it exists.
| aor | - AOR to look for |
Definition at line 536 of file registrar_subscribe.c.
References get_subscription_hash(), r_subscription_hash_slot::head, _r_subscription::next, _r_subscription::req_uri, subs_lock(), subs_unlock(), and subscriptions.
Referenced by r_notification_process(), r_subscribe(), and r_subscribe_response().
00537 { 00538 r_subscription *s; 00539 unsigned int hash = get_subscription_hash(aor); 00540 subs_lock(hash); 00541 s = subscriptions[hash].head; 00542 while(s){ 00543 if (s->req_uri.len == aor.len && 00544 strncasecmp(s->req_uri.s,aor.s,aor.len)==0) 00545 { 00546 return s; 00547 } 00548 s = s->next; 00549 } 00550 subs_unlock(hash); 00551 return 0; 00552 }
| int is_r_subscription | ( | str | aor | ) |
Finds out if a subscription exists.
| aor | - AOR to look for |
Definition at line 559 of file registrar_subscribe.c.
References get_subscription_hash(), r_subscription_hash_slot::head, _r_subscription::next, _r_subscription::req_uri, subs_lock(), subs_unlock(), and subscriptions.
00560 { 00561 r_subscription *s; 00562 unsigned int hash = get_subscription_hash(aor); 00563 subs_lock(hash); 00564 s = subscriptions[hash].head; 00565 while(s){ 00566 if (s->req_uri.len == aor.len && 00567 strncasecmp(s->req_uri.s,aor.s,aor.len)==0) 00568 { 00569 subs_unlock(hash); 00570 return 1; 00571 } 00572 s = s->next; 00573 } 00574 subs_unlock(hash); 00575 return 0; 00576 }
| void del_r_subscription | ( | r_subscription * | s | ) |
Deletes a subscription from the list of subscriptions.
| s | - the subscription to be deleted |
Definition at line 582 of file registrar_subscribe.c.
References free_r_subscription(), _r_subscription::hash, r_subscription_hash_slot::head, _r_subscription::next, _r_subscription::prev, subs_lock(), subs_unlock(), subscriptions, and r_subscription_hash_slot::tail.
00583 { 00584 if (!s) return; 00585 subs_lock(s->hash); 00586 if (subscriptions[s->hash].head == s) subscriptions[s->hash].head = s->next; 00587 else s->prev->next = s->next; 00588 if (subscriptions[s->hash].tail == s) subscriptions[s->hash].tail = s->prev; 00589 else s->next->prev = s->prev; 00590 subs_unlock(s->hash); 00591 free_r_subscription(s); 00592 }
| void del_r_subscription_nolock | ( | r_subscription * | s | ) |
Deletes a subscription from the list of subscriptions.
| s | - the subscription to be deleted |
Definition at line 599 of file registrar_subscribe.c.
References free_r_subscription(), _r_subscription::hash, r_subscription_hash_slot::head, _r_subscription::next, _r_subscription::prev, subscriptions, and r_subscription_hash_slot::tail.
Referenced by subscription_timer(), and update_r_subscription().
00600 { 00601 if (!s) return; 00602 if (subscriptions[s->hash].head == s) subscriptions[s->hash].head = s->next; 00603 else s->prev->next = s->next; 00604 if (subscriptions[s->hash].tail == s) subscriptions[s->hash].tail = s->prev; 00605 else s->next->prev = s->prev; 00606 free_r_subscription(s); 00607 }
| void free_r_subscription | ( | r_subscription * | s | ) |
Frees up space taken by a subscription.
| s | - the subscription to free |
Definition at line 613 of file registrar_subscribe.c.
References _r_subscription::dialog, _r_subscription::req_uri, and tmb.
Referenced by del_r_subscription(), del_r_subscription_nolock(), and r_subscription_destroy().
00614 { 00615 if (s){ 00616 if (s->req_uri.s) shm_free(s->req_uri.s); 00617 if (s->dialog) tmb.free_dlg(s->dialog); 00618 shm_free(s); 00619 } 00620 }
| void print_subs | ( | int | log_level | ) |
Definition at line 622 of file registrar_subscribe.c.
References ANSI_BLUE, ANSI_CYAN, ANSI_GREEN, ANSI_MAGENTA, _r_subscription::attempts_left, _r_subscription::duration, _r_subscription::expires, _r_subscription::hash, r_subscription_hash_slot::head, M_NAME, _r_subscription::next, r_act_time(), _r_subscription::req_uri, subs_lock(), subs_unlock(), subscriptions, subscriptions_hash_size, and time_now.
Referenced by subscription_timer().
00623 { 00624 r_subscription *s; 00625 int i; 00626 if (debug<log_level) return; /* to avoid useless calls when nothing will be printed */ 00627 LOG(log_level,ANSI_GREEN"INF:"M_NAME":---------- Subscription list begin ---------\n"); 00628 for(i=0;i<subscriptions_hash_size;i++){ 00629 subs_lock(i); 00630 s = subscriptions[i].head; 00631 r_act_time(); 00632 while(s){ 00633 LOG(log_level,ANSI_GREEN"INF:"M_NAME":[%4u]\tP: <"ANSI_BLUE"%.*s"ANSI_GREEN"> D:["ANSI_CYAN"%5d"ANSI_GREEN"] E:["ANSI_MAGENTA"%5d"ANSI_GREEN"] Att:[%2d]\n", 00634 s->hash,s->req_uri.len,s->req_uri.s,s->duration,(int)(s->expires-time_now),s->attempts_left); 00635 s = s->next;