int sal_publish(SalOp *op, const char *from, const char *to, const char *eventname, int expires, const SalBody *body){ belle_sip_request_t *req=NULL; if(!op->refresher || !belle_sip_refresher_get_transaction(op->refresher)) { if (from) sal_op_set_from(op,from); if (to) sal_op_set_to(op,to); sal_op_publish_fill_cbs(op); req=sal_op_build_request(op,"PUBLISH"); if (sal_op_get_contact(op)){ belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(sal_op_create_contact(op))); } belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("Event",eventname)); sal_op_add_body(op,BELLE_SIP_MESSAGE(req),body); return sal_op_send_and_create_refresher(op,req,expires,publish_refresher_listener); } else { /*update status*/ const belle_sip_client_transaction_t* last_publish_trans=belle_sip_refresher_get_transaction(op->refresher); belle_sip_request_t* last_publish=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(last_publish_trans)); /*update body*/ sal_op_add_body(op,BELLE_SIP_MESSAGE(last_publish),expires!=0 ? body : NULL); return belle_sip_refresher_refresh(op->refresher,expires==-1 ? BELLE_SIP_REFRESHER_REUSE_EXPIRES : expires); } }
int sal_notify_close(SalOp *op){ osip_message_t *msg=NULL; eXosip_lock(); eXosip_insubscription_build_notify(op->did,EXOSIP_SUBCRSTATE_TERMINATED,DEACTIVATED,&msg); if (msg!=NULL){ const char *identity=sal_op_get_contact(op); if (identity==NULL) identity=sal_op_get_to(op); osip_message_set_contact(msg,identity); add_presence_body(msg,SalPresenceOffline); eXosip_insubscription_send_request(op->did,msg); }else ms_error("sal_notify_close(): could not create notify for incoming subscription" " did=%i, nid=%i",op->did,op->nid); eXosip_unlock(); return 0; }
void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){ LinphoneFriend *lf=NULL; char *tmp; LinphoneAddress *uri; LinphoneProxyConfig *cfg; const char *fixed_contact; uri=linphone_address_new(from); linphone_address_clean(uri); tmp=linphone_address_as_string(uri); ms_message("Receiving new subscription from %s.",from); cfg=linphone_core_lookup_known_proxy(lc,uri); if (cfg!=NULL){ if (cfg->op){ fixed_contact=sal_op_get_contact(cfg->op); if (fixed_contact) { sal_op_set_contact (op,fixed_contact); ms_message("Contact for next subscribe answer has been fixed using proxy to %s",fixed_contact); } } } /* check if we answer to this subscription */ if (linphone_find_friend(lc->friends,uri,&lf)!=NULL){ lf->insub=op; lf->inc_subscribe_pending=TRUE; sal_subscribe_accept(op); linphone_friend_done(lf); /*this will do all necessary actions */ }else{ /* check if this subscriber is in our black list */ if (linphone_find_friend(lc->subscribers,uri,&lf)){ if (lf->pol==LinphoneSPDeny){ ms_message("Rejecting %s because we already rejected it once.",from); sal_subscribe_decline(op); } else { /* else it is in wait for approval state, because otherwise it is in the friend list.*/ ms_message("New subscriber found in friend list, in %s state.",__policy_enum_to_str(lf->pol)); } }else { sal_subscribe_accept(op); linphone_core_add_subscriber(lc,tmp,op); } } linphone_address_destroy(uri); ms_free(tmp); }
int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_message){ osip_message_t *msg=NULL; eXosip_ss_t ss=EXOSIP_SUBCRSTATE_ACTIVE; if (op->nid==-1){ ms_warning("Cannot notify, subscription was closed."); return -1; } eXosip_lock(); eXosip_insubscription_build_notify(op->did,ss,DEACTIVATED,&msg); if (msg!=NULL){ const char *identity=sal_op_get_contact(op); if (identity==NULL) identity=sal_op_get_to(op); _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free); osip_message_set_contact(msg,identity); add_presence_body(msg,status); eXosip_insubscription_send_request(op->did,msg); }else ms_error("could not create notify for incoming subscription."); eXosip_unlock(); return 0; }
/*presence publish */ int sal_publish_presence(SalOp *op, const char *from, const char *to, int expires, SalPresenceModel *presence){ belle_sip_request_t *req=NULL; if(!op->refresher || !belle_sip_refresher_get_transaction(op->refresher)) { if (from) sal_op_set_from(op,from); if (to) sal_op_set_to(op,to); op->type=SalOpPublish; req=sal_op_build_request(op,"PUBLISH"); if (sal_op_get_contact(op)){ belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(sal_op_create_contact(op))); } belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("Event","presence")); sal_add_presence_info(op,BELLE_SIP_MESSAGE(req),presence); return sal_op_send_and_create_refresher(op,req,expires,publish_refresher_listener); } else { /*update presence status*/ const belle_sip_client_transaction_t* last_publish_trans=belle_sip_refresher_get_transaction(op->refresher); belle_sip_request_t* last_publish=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(last_publish_trans)); sal_add_presence_info(op,BELLE_SIP_MESSAGE(last_publish),expires!=0 ? presence : NULL); return belle_sip_refresher_refresh(op->refresher,expires); } }
static void process_response_event(void *user_ctx, const belle_sip_response_event_t *event){ belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event); belle_sip_response_t* response = belle_sip_response_event_get_response(event); int response_code = belle_sip_response_get_status_code(response); if (!client_transaction) { ms_warning("Discarding stateless response [%i]",response_code); return; } else { SalOp* op = (SalOp*)belle_sip_transaction_get_application_data(BELLE_SIP_TRANSACTION(client_transaction)); belle_sip_request_t* request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction)); belle_sip_header_contact_t* original_contact; belle_sip_header_address_t* contact_address=NULL; belle_sip_header_via_t* via_header; belle_sip_uri_t* contact_uri; unsigned int contact_port; const char* received; int rport; bool_t contact_updated=FALSE; char* new_contact; if (op->state == SalOpStateTerminated) { belle_sip_message("Op is terminated, nothing to do with this [%i]",response_code); return; } if (!op->base.remote_ua) { sal_op_set_remote_ua(op,BELLE_SIP_MESSAGE(response)); } if (!op->base.call_id) { op->base.call_id=ms_strdup(belle_sip_header_call_id_get_call_id(BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(response), belle_sip_header_call_id_t)))); } sal_op_assign_recv_headers(op,(belle_sip_message_t*)response); if (op->callbacks.process_response_event) { if (op->base.root->nat_helper_enabled) { /*Fix contact if needed*/ via_header= (belle_sip_header_via_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_VIA); received = belle_sip_header_via_get_received(via_header); rport = belle_sip_header_via_get_rport(via_header); if ((original_contact=belle_sip_message_get_header_by_type(request,belle_sip_header_contact_t))) { /*update contact with sent values in any cases*/ contact_address=belle_sip_header_address_create(NULL,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(original_contact))); sal_op_set_contact_address(op,(const SalAddress *)contact_address); belle_sip_object_unref(contact_address); } if (sal_op_get_contact(op)){ if (received!=NULL || rport>0) { contact_address = BELLE_SIP_HEADER_ADDRESS(sal_address_clone(sal_op_get_contact_address(op))); contact_uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact_address)); if (received && strcmp(received,belle_sip_uri_get_host(contact_uri))!=0) { /*need to update host*/ belle_sip_uri_set_host(contact_uri,received); contact_updated=TRUE; } contact_port = belle_sip_uri_get_port(contact_uri); if (rport>0 && rport!=contact_port && (contact_port+rport)!=5060) { /*need to update port*/ belle_sip_uri_set_port(contact_uri,rport); contact_updated=TRUE; } /*try to fix transport if needed (very unlikely)*/ if (strcasecmp(belle_sip_header_via_get_transport(via_header),"UDP")!=0) { if (!belle_sip_uri_get_transport_param(contact_uri) ||strcasecmp(belle_sip_uri_get_transport_param(contact_uri),belle_sip_header_via_get_transport(via_header))!=0) { belle_sip_uri_set_transport_param(contact_uri,belle_sip_header_via_get_transport_lowercase(via_header)); contact_updated=TRUE; } } else { if (belle_sip_uri_get_transport_param(contact_uri)) { contact_updated=TRUE; belle_sip_uri_set_transport_param(contact_uri,NULL); } } if (contact_updated) { char* old_contact=belle_sip_object_to_string(BELLE_SIP_OBJECT(sal_op_get_contact_address(op))); new_contact=belle_sip_object_to_string(BELLE_SIP_OBJECT(contact_address)); ms_message("Updating contact from [%s] to [%s] for [%p]",old_contact,new_contact,op); sal_op_set_contact_address(op,(const SalAddress *)contact_address); belle_sip_free(new_contact); belle_sip_free(old_contact); } if (contact_address)belle_sip_object_unref(contact_address); } } } /*handle authorization*/ switch (response_code) { case 200: { break; } case 401: case 407:{ /*belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(client_transaction),NULL);*//*remove op from trans*/ if (op->state == SalOpStateTerminating && strcmp("BYE",belle_sip_request_get_method(request))!=0) { /*only bye are completed*/ belle_sip_message("Op is in state terminating, nothing else to do "); } else { if (op->pending_auth_transaction){ belle_sip_object_unref(op->pending_auth_transaction); op->pending_auth_transaction=NULL; } op->pending_auth_transaction=(belle_sip_client_transaction_t*)belle_sip_object_ref(client_transaction); sal_process_authentication(op); return; } } } op->callbacks.process_response_event(op,event); } else { ms_error("Unhandled event response [%p]",event); } } }