Definition in file registrar_notify.h.
#include "../../sr_module.h"
#include "../../locking.h"
#include "../tm/tm_load.h"
#include "ims_pm.h"
Go to the source code of this file.
Data Structures | |
| struct | _r_notification |
| reg event notification structure More... | |
| struct | r_notification_list |
| Notification List Structure. More... | |
Defines | |
| #define | MSG_REG_SUBSCRIBE_OK "Subscription to REG saved" |
| #define | MSG_REG_UNSUBSCRIBE_OK "Subscription to REG dropped" |
Typedefs | |
| typedef _r_notification | r_notification |
| reg event notification structure | |
Enumerations | |
| enum | { IMS_REGISTRAR_NONE, IMS_REGISTRAR_SUBSCRIBE, IMS_REGISTRAR_UNSUBSCRIBE, IMS_REGISTRAR_SUBSCRIBE_EXPIRED, IMS_REGISTRAR_CONTACT_REGISTERED, IMS_REGISTRAR_CONTACT_CREATED, IMS_REGISTRAR_CONTACT_REFRESHED, IMS_REGISTRAR_CONTACT_SHORTENED, IMS_REGISTRAR_CONTACT_EXPIRED, IMS_REGISTRAR_CONTACT_DEACTIVATED, IMS_REGISTRAR_CONTACT_PROBATION, IMS_REGISTRAR_CONTACT_UNREGISTERED, IMS_REGISTRAR_CONTACT_REJECTED } |
| Event types for "reg" to generated notifications after. More... | |
Functions | |
| int | r_notify_init () |
| Initializes the reg notifications list. | |
| void | r_notify_destroy () |
| Destroys the reg notifications list. | |
| int | S_can_subscribe (struct sip_msg *msg, char *str1, char *str2) |
| Check if this message quallifies for a subscription. | |
| int | S_subscribe (struct sip_msg *msg, char *str1, char *str2) |
| Save this subscription. | |
| int | S_SUBSCRIBE_reply (struct sip_msg *msg, int code, char *text, int *expires, str *contact) |
| Replies to a SUBSCRIBE and also adds the need headers. | |
| int | S_event_reg (void *p, void *c, void *s, int event_type, int send_now) |
| Generate notifications and put them in the notification queue to be sent. | |
| void | send_notification (r_notification *n) |
| Creates a NOTIFY message and sends it. | |
| void | notification_timer (unsigned int ticks, void *param) |
| The Notification timer looks for unsent notifications and sends them. | |
| r_notification * | new_r_notification (str req_uri, str uri, str subscription_state, str event, str content_type, str content, dlg_t *dialog, int version) |
| Creates a notification based on the given parameters. | |
| void | add_r_notification (r_notification *n) |
| Adds a notification to the list of notifications at the end (FIFO). | |
| void | free_r_notification (r_notification *n) |
| Frees up space taken by a notification. | |
Variables | |
| enum { ... } | IMS_Registrar_events |
| Event types for "reg" to generated notifications after. | |
| #define MSG_REG_SUBSCRIBE_OK "Subscription to REG saved" |
| #define MSG_REG_UNSUBSCRIBE_OK "Subscription to REG dropped" |
| typedef struct _r_notification r_notification |
reg event notification structure
| anonymous enum |
Event types for "reg" to generated notifications after.
Definition at line 69 of file registrar_notify.h.
00069 { 00070 IMS_REGISTRAR_NONE, 00071 IMS_REGISTRAR_SUBSCRIBE, 00072 IMS_REGISTRAR_UNSUBSCRIBE, 00073 IMS_REGISTRAR_SUBSCRIBE_EXPIRED, 00075 IMS_REGISTRAR_CONTACT_REGISTERED, 00076 IMS_REGISTRAR_CONTACT_CREATED, 00077 IMS_REGISTRAR_CONTACT_REFRESHED, 00078 IMS_REGISTRAR_CONTACT_SHORTENED, 00079 IMS_REGISTRAR_CONTACT_EXPIRED, 00080 IMS_REGISTRAR_CONTACT_DEACTIVATED, 00081 IMS_REGISTRAR_CONTACT_PROBATION, 00082 IMS_REGISTRAR_CONTACT_UNREGISTERED, 00083 IMS_REGISTRAR_CONTACT_REJECTED 00084 }IMS_Registrar_events;
| int r_notify_init | ( | ) |
Initializes the reg notifications list.
Definition at line 85 of file registrar_notify.c.
References r_notification_list::lock, and notification_list.
Referenced by mod_init().
00086 { 00087 notification_list = shm_malloc(sizeof(r_notification_list)); 00088 if (!notification_list) return 0; 00089 memset(notification_list,0,sizeof(r_notification_list)); 00090 notification_list->lock = lock_alloc(); 00091 if (!notification_list->lock) return 0; 00092 notification_list->lock = lock_init(notification_list->lock); 00093 return 1; 00094 }
| void r_notify_destroy | ( | ) |
Destroys the reg notifications list.
Definition at line 99 of file registrar_notify.c.
References free_r_notification(), r_notification_list::head, r_notification_list::lock, and notification_list.
Referenced by mod_destroy().
00100 { 00101 r_notification *n,*nn; 00102 lock_get(notification_list->lock); 00103 n = notification_list->head; 00104 while(n){ 00105 nn = n->next; 00106 free_r_notification(n); 00107 n = nn; 00108 } 00109 lock_destroy(notification_list->lock); 00110 lock_dealloc(notification_list->lock); 00111 shm_free(notification_list); 00112 }
| int S_can_subscribe | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Check if this message quallifies for a subscription.
Only 3 entities can subscribe:
| msg | - the SIP SUBSCRIBE message | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 128 of file registrar_notify.c.
References _r_public::aor, ims_public_identity::barring, cscf_get_asserted_identity(), cscf_get_event(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, get_r_public(), if, lookup_sip, M_NAME, ims_service_profile::public_identities, ims_service_profile::public_identities_cnt, ims_public_identity::public_identity, _r_public::s, ims_subscription::service_profiles, and ims_subscription::service_profiles_cnt.
00129 { 00130 int ret=CSCF_RETURN_FALSE; 00131 struct sip_uri puri; 00132 str uri={0,0}; 00133 str event; 00134 str asserted_id; 00135 r_public *p=0; 00136 r_contact *c=0; 00137 ims_public_identity *pi=0; 00138 int i,j; 00139 00140 LOG(L_DBG,"DBG:"M_NAME":S_can_subscribe: Checking if allowed to SUBSCRIBE\n"); 00141 00142 /* First check the parameters */ 00143 if (msg->first_line.type!=SIP_REQUEST) 00144 { 00145 LOG(L_ERR,"ERR:"M_NAME":S_can_subscribe: This message is not a request\n"); 00146 goto error; 00147 } 00148 if (msg->first_line.u.request.method.len != 9 || 00149 memcmp(msg->first_line.u.request.method.s,"SUBSCRIBE",9)!=0) 00150 { 00151 LOG(L_ERR,"ERR:"M_NAME":S_can_subscribe: This message is not a SUBSCRIBE\n"); 00152 goto error; 00153 } 00154 00155 /* 1. Get the event */ 00156 event = cscf_get_event(msg); 00157 if (event.len!=3||strncasecmp(event.s,"reg",3)!=0){ 00158 LOG(L_ERR,"ERR:"M_NAME":S_can_subscribe: Accepting only <Event: reg>. Found: <%.*s>\n", 00159 event.len,event.s); 00160 ret = CSCF_RETURN_FALSE; 00161 goto done; 00162 } 00163 00164 /* 2. Get the target of the SUBSCRIBE from RequestURI */ 00165 if (msg->new_uri.s) uri = msg->new_uri; 00166 else uri = msg->first_line.u.request.uri; 00167 00168 if (parse_uri(uri.s, uri.len, &puri) < 0) { 00169 LOG(L_ERR,"ERR:"M_NAME":S_can_subscribe: Error parsing uri <%.*s>\n", 00170 uri.len,uri.s); 00171 goto error; 00172 } 00173 uri.len = lookup_sip.len+puri.user.len+1+puri.host.len; 00174 uri.s = pkg_malloc(uri.len); 00175 if (!uri.s){ 00176 LOG(L_ERR,"ERR:"M_NAME":S_can_subscribe: Error allocating %d bytes\n",uri.len); 00177 goto error; 00178 } 00179 uri.len=0; 00180 memcpy(uri.s,lookup_sip.s,lookup_sip.len); 00181 uri.len+=lookup_sip.len; 00182 memcpy(uri.s+uri.len,puri.user.s,puri.user.len); 00183 uri.len+=puri.user.len; 00184 uri.s[uri.len++]='@'; 00185 memcpy(uri.s+uri.len,puri.host.s,puri.host.len); 00186 uri.len+=puri.host.len; 00187 00188 /* 3. Check if the asserted identity is in the same group with the ReqURI */ 00189 asserted_id = cscf_get_asserted_identity(msg); 00190 if (!asserted_id.len){ 00191 LOG(L_ERR,"ERR:"M_NAME":S_can_subscribe: P-Asserted-Identity empty.\n"); 00192 ret = CSCF_RETURN_FALSE; 00193 goto done; 00194 } 00195 LOG(L_DBG,"DBG:"M_NAME":S_can_subscribe: P-Asserted-Identity <%.*s>.\n", 00196 asserted_id.len,asserted_id.s); 00197 00198 p = get_r_public(uri); 00199 00200 if (!p){ 00201 LOG(L_ERR,"ERR:"M_NAME":S_can_subscribe: Identity not found <%.*s>\n", 00202 uri.len,uri.s); 00203 ret = CSCF_RETURN_FALSE; 00204 goto done; 00205 } 00206 if (p->aor.len == asserted_id.len && 00207 strncasecmp(p->aor.s,asserted_id.s,asserted_id.len)==0) 00208 { 00209 LOG(L_DBG,"DBG:"M_NAME":S_can_subscribe: Identity found as AOR <%.*s>\n", 00210 uri.len,uri.s); 00211 ret = CSCF_RETURN_TRUE; 00212 goto done; 00213 } 00214 if (p->s){ 00215 for(i=0;i<p->s->service_profiles_cnt;i++) 00216 for(j=0;j<p->s->service_profiles[i].public_identities_cnt;j++) 00217 { 00218 pi = &(p->s->service_profiles[i].public_identities[j]); 00219 if (!pi->barring && 00220 pi->public_identity.len == asserted_id.len && 00221 strncasecmp(pi->public_identity.s,asserted_id.s,asserted_id.len)==0) 00222 { 00223 LOG(L_DBG,"DBG:"M_NAME":S_can_subscribe: Identity found in SP[%d][%d]\n", 00224 i,j); 00225 ret = CSCF_RETURN_TRUE; 00226 goto done; 00227 } 00228 } 00229 } 00230 00231 /* 4. Check if it present in any of the Path headers */ 00232 c=p->head; 00233 00234 while(c){ 00235 if (c->path.len){ 00236 for(i=0;i<c->path.len-asserted_id.len;i++) 00237 if (strncasecmp(c->path.s+i,asserted_id.s,asserted_id.len)==0){ 00238 LOG(L_DBG,"DBG:"M_NAME":S_can_subscribe: Identity found in Path <%.*s>\n", 00239 c->path.len,c->path.s); 00240 ret = CSCF_RETURN_TRUE; 00241 goto done; 00242 } 00243 } 00244 c = c->next; 00245 } 00246 00247 00248 done: 00249 if (p) r_unlock(p->hash); 00250 if (uri.s) pkg_free(uri.s); 00251 return ret; 00252 error: 00253 if (p) r_unlock(p->hash); 00254 if (uri.s) pkg_free(uri.s); 00255 ret=CSCF_RETURN_ERROR; 00256 return ret; 00257 }
| int S_subscribe | ( | struct sip_msg * | msg, | |
| char * | str1, | |||
| char * | str2 | |||
| ) |
Save this subscription.
| msg | - the SIP SUBSCRIBE message | |
| str1 | - not used | |
| str2 | - not used |
Definition at line 267 of file registrar_notify.c.
References add_r_public(), cscf_get_contact(), cscf_get_event(), cscf_get_expires_hdr(), CSCF_RETURN_FALSE, CSCF_RETURN_TRUE, del_r_subscriber(), _r_subscriber::dialog, _r_subscriber::expires, get_r_public(), get_r_subscriber(), _r_public::hash, IMS_EVENT_NONE, IMS_EVENT_REG, IMS_REGISTRAR_SUBSCRIBE, IMS_REGISTRAR_UNSUBSCRIBE, lookup_sip, M_NAME, MSG_REG_SUBSCRIBE_OK, MSG_REG_UNSUBSCRIBE_OK, r_act_time(), r_unlock(), S_event_reg(), S_SUBSCRIBE_reply(), subscription_default_expires, subscription_max_expires, subscription_min_expires, time_now, tmb, and update_r_subscriber().
00268 { 00269 int ret=CSCF_RETURN_FALSE; 00270 struct sip_uri puri; 00271 str uri={0,0}; 00272 str event; 00273 int event_i=IMS_EVENT_NONE; 00274 int expires=0,expires_time=0; 00275 str subscriber; 00276 r_public *p=0; 00277 r_subscriber *s=0,*new_s=0; 00278 dlg_t *dialog=0; 00279 00280 LOG(L_DBG,"DBG:"M_NAME":S_subscribe: Saving SUBSCRIBE\n"); 00281 00282 /* First check the parameters */ 00283 if (msg->first_line.type!=SIP_REQUEST) 00284 { 00285 LOG(L_ERR,"ERR:"M_NAME":S_subscribe: This message is not a request\n"); 00286 goto error; 00287 } 00288 if (msg->first_line.u.request.method.len != 9 || 00289 memcmp(msg->first_line.u.request.method.s,"SUBSCRIBE",9)!=0) 00290 { 00291 LOG(L_ERR,"ERR:"M_NAME":S_subscribe: This message is not a SUBSCRIBE\n"); 00292 goto error; 00293 } 00294 00295 /* 1. Get the event */ 00296 event = cscf_get_event(msg); 00297 if (event.len!=3||strncasecmp(event.s,"reg",3)!=0){ 00298 LOG(L_ERR,"ERR:"M_NAME":S_subscribe: Accepting only <Event: reg>. Found: <%.*s>\n", 00299 event.len,event.s); 00300 ret = CSCF_RETURN_FALSE; 00301 goto done; 00302 } 00303 if (event.len==0 && strncasecmp(event.s,"reg",3)==0) 00304 event_i = IMS_EVENT_REG; 00305 00306 /* 2. Get the target of the SUBSCRIBE from RequestURI */ 00307 if (msg->new_uri.s) uri = msg->new_uri; 00308 else uri = msg->first_line.u.request.uri; 00309 00310 if (parse_uri(uri.s, uri.len, &puri) < 0) { 00311 LOG(L_ERR,"ERR:"M_NAME":S_subscribe: Error parsing uri <%.*s>\n", 00312 uri.len,uri.s); 00313 goto error; 00314 } 00315 uri.len = lookup_sip.len+puri.user.len+1+puri.host.len; 00316 uri.s = pkg_malloc(uri.len); 00317 if (!uri.s){ 00318 LOG(L_ERR,"ERR:"M_NAME":S_subscribe: Error allocating %d bytes\n",uri.len); 00319 goto error; 00320 } 00321 uri.len=0; 00322 memcpy(uri.s,lookup_sip.s,lookup_sip.len); 00323 uri.len+=lookup_sip.len; 00324 memcpy(uri.s+uri.len,puri.user.s,puri.user.len); 00325 uri.len+=puri.user.len; 00326 uri.s[uri.len++]='@'; 00327 memcpy(uri.s+uri.len,puri.host.s,puri.host.len); 00328 uri.len+=puri.host.len; 00329 00330 /* 3. Get the Subscriber's Identity */ 00331 subscriber = cscf_get_contact(msg); 00332 if (!subscriber.len){ 00333 LOG(L_ERR,"ERR:"M_NAME":S_subscribe: Contact empty.\n"); 00334 ret = CSCF_RETURN_FALSE; 00335 goto done; 00336 } 00337 LOG(L_DBG,"DBG:"M_NAME":S_subscribe: Contact <%.*s>.\n", 00338 subscriber.len,subscriber.s); 00339 00340 p = get_r_public(uri); 00341 00342 /* Registration is possible even if the user is not registered... so just create one */ 00343 if (!p){ 00344 p = add_r_public(uri,0,0); 00345 } 00346 if (!p){ 00347 LOG(L_ERR,"ERR:"M_NAME":S_subscribe: Identity not found and error on creation <%.*s>\n", 00348 uri.len,uri.s); 00349 ret = CSCF_RETURN_FALSE; 00350 goto done; 00351 } 00352 00353 expires = cscf_get_expires_hdr(msg); 00354 if (expires == -1) expires = subscription_default_expires; 00355 if (expires > 0) { 00356 if (expires < subscription_min_expires) expires = subscription_min_expires; 00357 if (expires > subscription_max_expires) expires = subscription_max_expires; 00358 r_act_time(); 00359 expires_time = expires + time_now; 00360 00361 /* get the old subscriber - if any */ 00362 s = get_r_subscriber(p,subscriber,event_i); 00363 if (!s){ 00364 /* create a new dialog */ 00365 if (tmb.new_dlg_uas(msg, 200, &dialog) < 0) { 00366 LOG(L_ERR,"ERR:"M_NAME":S_subscribe: Error while creating dialog state\n"); 00367 ret = CSCF_RETURN_FALSE; 00368 goto error; 00369 } 00370 }else 00371 dialog = s->dialog; 00372 00373 /* update the subscriber */ 00374 if ((new_s=update_r_subscriber(p,subscriber,event_i,&expires_time,dialog))!=0){ 00375 //if (!s) /* Only on first subscription, not on refreshes, send a notify */ 00376 S_event_reg(p,0,new_s,IMS_REGISTRAR_SUBSCRIBE,0); 00377 ret = CSCF_RETURN_TRUE; 00378 } 00379 else 00380 ret = CSCF_RETURN_FALSE; 00381 }else{ 00382 /* Unsubscribe */ 00383 /* get the old subscriber - if any */ 00384 r_act_time(); 00385 s = get_r_subscriber(p,subscriber,event_i); 00386 if (s) { 00387 s->expires = time_now; 00388 S_event_reg(p,0,s,IMS_REGISTRAR_UNSUBSCRIBE,1); 00389 del_r_subscriber(p,s); 00390 } 00391 ret = CSCF_RETURN_TRUE; 00392 } 00393 done: 00394 r_unlock(p->hash); 00395 if (expires ==0 )S_SUBSCRIBE_reply(msg,200,MSG_REG_UNSUBSCRIBE_OK,&expires,&uri); 00396 else S_SUBSCRIBE_reply(msg,200,MSG_REG_SUBSCRIBE_OK,&expires,&uri); 00397 if (uri.s) pkg_free(uri.s); 00398 return ret; 00399 error: 00400 if (p) r_unlock(p->hash); 00401 if (uri.s) pkg_free(uri.s); 00402 ret=CSCF_RETURN_FALSE; 00403 return ret; 00404 }
| int S_SUBSCRIBE_reply | ( | struct sip_msg * | msg, | |
| int | code, | |||
| char * | text, | |||
| int * | expires, | |||
| str * | contact | |||
| ) |
Replies to a SUBSCRIBE and also adds the need headers.
Path for example.
| msg | - the SIP SUBSCRIBE message | |
| code | - response code to send | |
| text | - response phrase to send | |
| expires | - expiration interval in seconds | |
| contact | - contact to add to reply |
Definition at line 422 of file registrar_notify.c.
References cscf_add_header_rpl(), M_NAME, STR_APPEND, and tmb.
Referenced by S_subscribe().
00423 { 00424 str hdr={0,0}; 00425 tmb.t_newtran(msg); 00426 00427 if (expires){ 00428 hdr.len = expires_hdr1.len+12+expires_hdr1.len; 00429 hdr.s = pkg_malloc(hdr.len); 00430 if (!hdr.s){ 00431 LOG(L_ERR,"ERR:"M_NAME":S_SUBSCRIBE_reply: Error allocating %d bytes.\n", 00432 hdr.len); 00433 }else{ 00434 hdr.len=0; 00435 STR_APPEND(hdr,expires_hdr1); 00436 sprintf(hdr.s+hdr.len,"%d",*expires); 00437 hdr.len += strlen(hdr.s+hdr.len); 00438 STR_APPEND(hdr,expires_hdr2); 00439 cscf_add_header_rpl(msg,&hdr); 00440 pkg_free(hdr.s); 00441 } 00442 } 00443 00444 if (contact){ 00445 hdr.len = contact_hdr1.len+contact->len+contact_hdr2.len; 00446 hdr.s = pkg_malloc(hdr.len); 00447 if (!hdr.s){ 00448 LOG(L_ERR,"ERR:"M_NAME":S_SUBSCRIBE_reply: Error allocating %d bytes.\n", 00449 hdr.len); 00450 }else{ 00451 hdr.len=0; 00452 STR_APPEND(hdr,contact_hdr1); 00453 STR_APPEND(hdr,*contact); 00454 STR_APPEND(hdr,contact_hdr2); 00455 cscf_add_header_rpl(msg,&hdr); 00456 pkg_free(hdr.s); 00457 } 00458 } 00459 00460 return tmb.t_reply(msg,code,text); 00461 }
| int S_event_reg | ( | void * | pv, | |
| void * | c, | |||
| void * | ps, | |||
| int | event_type, | |||
| int | send_now | |||
| ) |
Generate notifications and put them in the notification queue to be sent.
| pv | - r_public to generate for | |
| c | - r_contact to generate for or NULL if for all | |
| ps | - r_subscriber to generated for or NULL if for all | |
| event_type | - event type | |
| send_now | - whether to send immediately or delay |
Definition at line 810 of file registrar_notify.c.
References IMS_REGISTRAR_CONTACT_CREATED, IMS_REGISTRAR_CONTACT_DEACTIVATED, IMS_REGISTRAR_CONTACT_EXPIRED, IMS_REGISTRAR_CONTACT_PROBATION, IMS_REGISTRAR_CONTACT_REFRESHED, IMS_REGISTRAR_CONTACT_REGISTERED, IMS_REGISTRAR_CONTACT_REJECTED, IMS_REGISTRAR_CONTACT_SHORTENED, IMS_REGISTRAR_CONTACT_UNREGISTERED, IMS_REGISTRAR_NONE, IMS_REGISTRAR_SUBSCRIBE, IMS_REGISTRAR_UNSUBSCRIBE, M_NAME, notification_timer(), r_act_time(), r_create_notifications(), r_get_reginfo_full(), and r_get_reginfo_partial().
Referenced by registrar_timer(), S_subscribe(), and update_contacts().
00811 { 00812 r_public *p=(r_public*)pv; 00813 r_subscriber *s=(r_subscriber*)ps; 00814 str content={0,0}; 00815 long subsExpires=-1; 00816 00817 r_act_time(); 00818 switch (event_type){ 00819 case IMS_REGISTRAR_NONE: 00820 if (send_now) notification_timer(0,0); 00821 return 0; 00822 break; 00823 case IMS_REGISTRAR_SUBSCRIBE: 00824 content = r_get_reginfo_full(p,event_type,&subsExpires); 00825 r_create_notifications(p,0,s,content,subsExpires); 00826 if (content.s) pkg_free(content.s); 00827 if (send_now) notification_timer(0,0); 00828 return 1; 00829 break; 00830 case IMS_REGISTRAR_UNSUBSCRIBE: 00831 subsExpires=0; 00832 r_create_notifications(p,0,s,content,subsExpires); 00833 if (content.s) pkg_free(content.s); 00834 if (send_now) notification_timer(0,0); 00835 return 1; 00836 break; 00837 00838 case IMS_REGISTRAR_CONTACT_REGISTERED: 00839 case IMS_REGISTRAR_CONTACT_CREATED: 00840 case IMS_REGISTRAR_CONTACT_REFRESHED: 00841 case IMS_REGISTRAR_CONTACT_SHORTENED: 00842 case IMS_REGISTRAR_CONTACT_EXPIRED: 00843 case IMS_REGISTRAR_CONTACT_DEACTIVATED: 00844 case IMS_REGISTRAR_CONTACT_PROBATION: 00845 case IMS_REGISTRAR_CONTACT_UNREGISTERED: 00846 case IMS_REGISTRAR_CONTACT_REJECTED: 00847 content = r_get_reginfo_partial(p,c,event_type,&subsExpires); 00848 r_create_notifications(p,c,s,content,subsExpires); 00849 if (content.s) pkg_free(content.s); 00850 if (send_now) notification_timer(0,0); 00851 return 1; 00852 break; 00853 00854 default: 00855 LOG(L_ERR,"ERR:"M_NAME":S_event_reg: Unknown event %d\n",event_type); 00856 if (send_now) notification_timer(0,0); 00857 return 0; 00858 } 00859 }
| void send_notification | ( | r_notification * | n | ) |
Creates a NOTIFY message and sends it.
| n | - the r_notification to create the NOTIFY after |
Definition at line 891 of file registrar_notify.c.
References contact_hdr1, contact_hdr2, IMS_PM_LOG11, M_NAME, STR_APPEND, tmb, and uac_request_cb().
Referenced by notification_timer().
00892 { 00893 str h={0,0}; 00894 int k=0; 00895 00896 LOG(L_DBG,"DBG:"M_NAME":send_notification: NOTIFY about <%.*s>\n",n->uri.len,n->uri.s); 00897 00898 //tmb.print_dlg(stdout,n->dialog); 00899 00900 h.len = 0; 00901 h.len += contact_hdr1.len + n->uri.len + contact_hdr2.len ; 00902 if (n->subscription_state.len) h.len += subss_hdr1.len + subss_hdr2.len + n->subscription_state.len; 00903 h.len+=event_hdr.len; 00904 h.len+=maxfwds_hdr.len; 00905 if (n->content_type.len) h.len += ctype_hdr1.len + ctype_hdr2.len + n->content_type.len; 00906 h.s = pkg_malloc(h.len); 00907 if (!h.s){ 00908 LOG(L_ERR,"ERR:"M_NAME":send_notification: Error allocating %d bytes\n",h.len); 00909 h.len = 0; 00910 } 00911 00912 h.len = 0; 00913 STR_APPEND(h,contact_hdr1); 00914 STR_APPEND(h,n->uri); 00915 STR_APPEND(h,contact_hdr2); 00916 00917 STR_APPEND(h,event_hdr); 00918 STR_APPEND(h,maxfwds_hdr); 00919 if (n->subscription_state.len) { 00920 STR_APPEND(h,subss_hdr1); 00921 STR_APPEND(h,n->subscription_state); 00922 STR_APPEND(h,subss_hdr2); 00923 } 00924 if (n->content_type.len) { 00925 STR_APPEND(h,ctype_hdr1); 00926 STR_APPEND(h,n->content_type); 00927 STR_APPEND(h,ctype_hdr2); 00928 } 00929 00930 //LOG(L_CRIT,"DLG:%p\n",n->dialog); 00931 #ifdef WITH_IMS_PM 00932 k = n->is_scscf_dereg; 00933 #endif 00934 if (n->content.len) 00935 tmb.t_request_within(&method, &h, &(n->content), n->dialog, uac_request_cb, (void*)k); 00936 else 00937 tmb.t_request_within(&method, &h, 0, n->dialog, uac_request_cb, (void*)k); 00938 if (h.s) pkg_free(h.s); 00939 00940 #ifdef WITH_IMS_PM 00941 if (n->is_scscf_dereg) IMS_PM_LOG11(UR_AttDeRegCscf,n->dialog->id.call_id,n->dialog->loc_seq.value); 00942 #endif 00943 }
| void notification_timer | ( | unsigned int | ticks, | |
| void * | param | |||
| ) |
The Notification timer looks for unsent notifications and sends them.
| ticks | - the current time | |
| param | - pointer to the domain_list |
Definition at line 954 of file registrar_notify.c.
References free_r_notification(), r_notification_list::head, r_notification_list::lock, notification_list, send_notification(), and r_notification_list::tail.
Referenced by mod_init(), and S_event_reg().
00955 { 00956 r_notification *n; 00957 lock_get(notification_list->lock); 00958 while(notification_list->head){ 00959 n = notification_list->head; 00960 notification_list->head = n->next; 00961 if (n->next) n->next->prev=0; 00962 else notification_list->tail=n->next; 00963 lock_release(notification_list->lock); 00964 00965 send_notification(n); 00966 free_r_notification(n); 00967 lock_get(notification_list->lock); 00968 } 00969 lock_release(notification_list->lock); 00970 }
| r_notification* new_r_notification | ( | str | req_uri, | |
| str | uri, | |||
| str | subscription_state, | |||
| str | event, | |||
| str | content_type, | |||
| str | content, | |||
| dlg_t * | dialog, | |||
| int | version | |||
| ) |
Creates a notification based on the given parameters.
| req_uri | - the Request-URI for the NOTIFY | |
| uri | - uri to send to | |
| subscription_state | - the Subscription-State header value | |
| event | - the event | |
| content_type | - content type | |
| content | - content | |
| dialog | - dialog to send on |
Definition at line 985 of file registrar_notify.c.
References free_r_notification(), M_NAME, MAX_REGINFO_SIZE, and STR_SHM_DUP.
Referenced by r_create_notifications().
00987 { 00988 r_notification *n=0; 00989 str buf; 00990 char bufc[MAX_REGINFO_SIZE]; 00991 00992 n = shm_malloc(sizeof(r_notification)); 00993 if (!n){ 00994 LOG(L_ERR,"ERR:"M_NAME":new_r_notification: Error allocating %d bytes\n", 00995 sizeof(r_notification)); 00996 goto error; 00997 } 00998 memset(n,0,sizeof(r_notification)); 00999 01000 STR_SHM_DUP(n->req_uri,req_uri,"new_r_notification"); 01001 01002 STR_SHM_DUP(n->uri,uri,"new_r_notification"); 01003 01004 STR_SHM_DUP(n->subscription_state,subscription_state,"new_r_notification"); 01005 01006 STR_SHM_DUP(n->event,event,"new_r_notification"); 01007 01008 STR_SHM_DUP(n->content_type,content_type,"new_r_notification"); 01009 01010 sprintf(bufc,content.s,version); 01011 buf.s = bufc; 01012 buf.len = strlen(bufc); 01013 STR_SHM_DUP(n->content,buf,"new_r_notification"); 01014 01015 n->dialog = dialog; 01016 01017 return n; 01018 error: 01019 out_of_memory: 01020 free_r_notification(n); 01021 return 0; 01022 }
| void add_r_notification | ( | r_notification * | n | ) |
Adds a notification to the list of notifications at the end (FIFO).
| n | - the notification to be added |
Definition at line 1028 of file registrar_notify.c.
References r_notification_list::head, r_notification_list::lock, notification_list, and r_notification_list::tail.
Referenced by r_create_notifications().
01029 { 01030 if (!n) return; 01031 lock_get(notification_list->lock); 01032 n->next = 0; 01033 n->prev = notification_list->tail; 01034 if (notification_list->tail) notification_list->tail->next = n; 01035 notification_list->tail = n; 01036 if (!notification_list->head) notification_list->head = n; 01037 lock_release(notification_list->lock); 01038 }
| void free_r_notification | ( | r_notification * | n | ) |
Frees up space taken by a notification.
| n | - the notification to be freed |
Definition at line 1044 of file registrar_notify.c.
Referenced by new_r_notification(), notification_timer(), and r_notify_destroy().
01045 { 01046 if (n){ 01047 if (n->req_uri.s) shm_free(n->req_uri.s); 01048 if (n->uri.s) shm_free(n->uri.s); 01049 if (n->subscription_state.s) shm_free(n->subscription_state.s); 01050 if (n->event.s) shm_free(n->event.s); 01051 if (n->content_type.s) shm_free(n->content_type.s); 01052 if (n->content.s) shm_free(n->content.s); 01053 shm_free(n); 01054 } 01055 }
| enum { ... } IMS_Registrar_events |
Event types for "reg" to generated notifications after.
1.5.2