registrar_notify.h File Reference


Detailed Description

Serving-CSCF - "reg" Event Operations.

Author:
Dragos Vingarzan vingarzan -at- fokus dot fraunhofer dot de

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_notificationnew_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 Documentation

#define MSG_REG_SUBSCRIBE_OK   "Subscription to REG saved"

Definition at line 64 of file registrar_notify.h.

Referenced by S_subscribe().

#define MSG_REG_UNSUBSCRIBE_OK   "Subscription to REG dropped"

Definition at line 65 of file registrar_notify.h.

Referenced by S_subscribe().


Typedef Documentation

typedef struct _r_notification r_notification

reg event notification structure


Enumeration Type Documentation

anonymous enum

Event types for "reg" to generated notifications after.

Enumerator:
IMS_REGISTRAR_NONE  no event - donothing
IMS_REGISTRAR_SUBSCRIBE  Initial SUBSCRIBE - just send all data - this should not be treated though.
IMS_REGISTRAR_UNSUBSCRIBE  Final UnSUBSCRIBE - just send a NOTIFY which will probably fail.
IMS_REGISTRAR_SUBSCRIBE_EXPIRED  The subscribe has expired.
IMS_REGISTRAR_CONTACT_REGISTERED  Registered with REGISTER.
IMS_REGISTRAR_CONTACT_CREATED  Registered administratively.
IMS_REGISTRAR_CONTACT_REFRESHED  The expiration was refreshed.
IMS_REGISTRAR_CONTACT_SHORTENED  The expiration was administratively shortened.
IMS_REGISTRAR_CONTACT_EXPIRED  A contact has expired and will be removed.
IMS_REGISTRAR_CONTACT_DEACTIVATED  Administratively removed, user should retry.
IMS_REGISTRAR_CONTACT_PROBATION  Administratively removed, user should retry later.
IMS_REGISTRAR_CONTACT_UNREGISTERED  User unregistered with Expires 0.
IMS_REGISTRAR_CONTACT_REJECTED  Administratively removed, user should not retry.

Definition at line 69 of file registrar_notify.h.


Function Documentation

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:

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.

Parameters:
msg - the SIP SUBSCRIBE message
str1 - not used
str2 - not used
Returns:
CSCF_RETURN_TRUE if allowed, CSCF_RETURN_FALSE if not, CSCF_RETURN_ERROR on error

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.

Parameters:
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
Returns:
the tmn.r_reply returned value value

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.

Note:
Must be called with a lock on the r_public pv
Parameters:
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
Returns:
1 on success, 0 on failure

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.

Parameters:
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.

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.

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
Returns:
the r_notification or NULL on error

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).

Parameters:
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.

Parameters:
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 }


Variable Documentation

enum { ... } IMS_Registrar_events

Event types for "reg" to generated notifications after.


Generated on Thu Oct 23 04:14:45 2008 for Open IMS Core CSCFs by  doxygen 1.5.2