static void sca_notify_reply_cb( struct cell *t, int cb_type, struct tmcb_params *cbp ) { struct sip_msg *notify_reply = NULL; str to_aor = STR_NULL; str *contact_uri; if ( cbp == NULL ) { LM_ERR( "Empty parameters passed to NOTIFY callback!" ); return; } if (( notify_reply = cbp->rpl ) == NULL ) { LM_ERR( "Empty reply passed to NOTIFY callback!" ); return; } contact_uri = &t->uac[ 0 ].uri; if ( notify_reply != FAKED_REPLY && REPLY_CLASS( notify_reply ) == 2 ) { LM_DBG( "NOTIFY %.*s returned %d", STR_FMT( contact_uri ), notify_reply->REPLY_STATUS ); return; } /* * after this, we've either gotten an error from the client, or a faked * reply from the proxy. remove the subscription in either case. it's * possible the client will return 481 (no such transaction), but that's * still grounds for us to remove the subscription, since the dialog * we have associated with the subscription is no longer valid. */ if ( notify_reply == FAKED_REPLY ) { LM_ERR( "NOTIFY %.*s resulted in FAKED_REPLY from proxy: " "failed to deliver NOTIFY to client", STR_FMT( contact_uri )); } else { LM_ERR( "NOTIFY %.*s returned %d %.*s removing call-info " "subscription for %.*s", STR_FMT( contact_uri ), notify_reply->REPLY_STATUS, STR_FMT( ¬ify_reply->first_line.u.reply.reason ), STR_FMT( contact_uri )); } return; if ( sca_uri_extract_aor( &t->to, &to_aor ) < 0 ) { LM_ERR( "Failed to extract AoR from %.*s", STR_FMT( &t->to )); return; } /* t->to is the entire To header: "To: sip:....", so move to_aor.s ahead */ if ( memcmp( to_aor.s, "To: ", strlen( "To: " )) == 0 ) { to_aor.s += strlen( "To: " ); to_aor.len -= strlen( "To: " ); } if ( sca_subscription_delete_subscriber_for_event( sca, contact_uri, &SCA_EVENT_NAME_CALL_INFO, &to_aor ) < 0 ) { LM_ERR( "Failed to delete %.*s %.*s subscription", STR_FMT( contact_uri ), STR_FMT( &SCA_EVENT_NAME_CALL_INFO )); } }
int sca_create_canonical_aor_for_ua( sip_msg_t *msg, str *c_aor, int ua_opts ) { struct to_body *tf = NULL; sip_uri_t c_uri; str tf_aor = STR_NULL; str contact_uri = STR_NULL; int rc = -1; assert( msg != NULL ); assert( c_aor != NULL ); memset( c_aor, 0, sizeof( str )); if (( ua_opts & SCA_AOR_TYPE_AUTO )) { if ( msg->first_line.type == SIP_REQUEST ) { ua_opts = SCA_AOR_TYPE_UAC; } else { ua_opts = SCA_AOR_TYPE_UAS; } } if (( ua_opts & SCA_AOR_TYPE_UAC )) { if ( sca_get_msg_from_header( msg, &tf ) < 0 ) { LM_ERR( "sca_create_canonical_aor: failed to get From header" ); goto done; } } else { if ( sca_get_msg_to_header( msg, &tf ) < 0 ) { LM_ERR( "sca_create_canonical_aor: failed to get To header" ); goto done; } } if ( sca_uri_extract_aor( &tf->uri, &tf_aor ) < 0 ) { LM_ERR( "sca_create_canonical_aor: failed to extract AoR from " "URI <%.*s>", STR_FMT( &tf->uri )); goto done; } memset( &c_uri, 0, sizeof( sip_uri_t )); if (( rc = sca_get_msg_contact_uri( msg, &contact_uri )) < 0 ) { LM_ERR( "sca_create_canonical_aor: failed to get contact URI from " "Contact <%.*s>", STR_FMT( &msg->contact->body )); goto done; } if ( rc > 0 ) { if ( parse_uri( contact_uri.s, contact_uri.len, &c_uri ) < 0 ) { LM_ERR( "sca_create_canonical_aor: failed to parse Contact URI " "<%.*s>", STR_FMT( &contact_uri )); rc = -1; goto done; } } if ( SCA_STR_EMPTY( &c_uri.user ) || SCA_STR_EQ( &c_uri.user, &tf->parsed_uri.user )) { /* empty contact header or Contact user matches To/From AoR */ c_aor->s = (char *)pkg_malloc( tf_aor.len ); c_aor->len = tf_aor.len; memcpy( c_aor->s, tf_aor.s, tf_aor.len ); } else { /* Contact user and To/From user mismatch */ if ( sca_aor_create_from_info( c_aor, c_uri.type, &c_uri.user, &tf->parsed_uri.host, &tf->parsed_uri.port ) < 0 ) { LM_ERR( "sca_create_canonical_aor: failed to create AoR from " "Contact <%.*s> and URI <%.*s>", STR_FMT( &contact_uri ), STR_FMT( &tf_aor )); goto done; } } rc = 1; done: return( rc ); }