LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op){ LinphoneCall *call=ms_new0(LinphoneCall,1); char *from_str; call->dir=LinphoneCallIncoming; sal_op_set_user_pointer(op,call); call->op=op; call->core=lc; if (lc->sip_conf.ping_with_options){ /*the following sends an option request back to the caller so that we get a chance to discover our nat'd address before answering.*/ call->ping_op=sal_op_new(lc->sal); from_str=linphone_address_as_string(from); sal_op_set_route(call->ping_op,sal_op_get_network_origin(call->op)); sal_op_set_user_pointer(call->ping_op,call); sal_ping(call->ping_op,linphone_core_find_best_identity(lc,from,NULL),from_str); ms_free(from_str); } linphone_address_clean(from); linphone_core_get_local_ip(lc,linphone_address_get_domain(from),call->localip); linphone_call_init_common(call, from, to); call->params.has_video=linphone_core_video_enabled(lc); call->localdesc=create_local_media_description (lc,call); call->camera_active=call->params.has_video; if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseStun) linphone_core_run_stun_tests(call->core,call); discover_mtu(lc,linphone_address_get_domain(from)); return call; }
int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphoneOnlineStatus presence_mode){ int err; SalOp *op=sal_op_new(proxy->lc->sal); err=sal_publish(op,linphone_proxy_config_get_identity(proxy), linphone_proxy_config_get_identity(proxy),linphone_online_status_to_sal(presence_mode)); if (proxy->publish_op!=NULL) sal_op_release(proxy->publish_op); proxy->publish_op=op; return err; }
static void _sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev){ SalOp *op=sal_op_new(sal); char *tmp; op->did=ev->did; op->tid=ev->tid; op->nid=ev->nid; osip_from_to_str(ev->request->from,&tmp); sal_op_set_from(op,tmp); ms_free(tmp); osip_from_to_str(ev->request->to,&tmp); sal_op_set_to(op,tmp); ms_free(tmp); sal_add_in_subscribe(sal,op,ev->request); sal->callbacks.subscribe_received(op,sal_op_get_from(op)); }
static void linphone_proxy_config_register(LinphoneProxyConfig *obj){ if (obj->reg_sendregister){ char *contact; if (obj->op) sal_op_release(obj->op); obj->op=sal_op_new(obj->lc->sal); contact=guess_contact_for_register(obj); sal_op_set_contact(obj->op,contact); ms_free(contact); sal_op_set_user_pointer(obj->op,obj); if (sal_register(obj->op,obj->reg_proxy,obj->reg_identity,obj->expires)==0) { linphone_proxy_config_set_state(obj,LinphoneRegistrationProgress,"Registration in progress"); } else { linphone_proxy_config_set_state(obj,LinphoneRegistrationFailed,"Registration failed"); } } }
static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage* msg){ SalOp *op=NULL; LinphoneCall *call; char* content_type; const char *identity=NULL; time_t t=time(NULL); if (lp_config_get_int(cr->lc->config,"sip","chat_use_call_dialogs",0)){ if((call = linphone_core_get_call_by_remote_address(cr->lc,cr->peer))!=NULL){ if (call->state==LinphoneCallConnected || call->state==LinphoneCallStreamsRunning || call->state==LinphoneCallPaused || call->state==LinphoneCallPausing || call->state==LinphoneCallPausedByRemote){ ms_message("send SIP message through the existing call."); op = call->op; call->pending_message=msg; identity=linphone_core_find_best_identity(cr->lc,linphone_call_get_remote_address(call)); } } } msg->time=t; if (op==NULL){ LinphoneProxyConfig *proxy=linphone_core_lookup_known_proxy(cr->lc,cr->peer_url); if (proxy){ identity=linphone_proxy_config_get_identity(proxy); }else identity=linphone_core_get_primary_contact(cr->lc); /*sending out of calls*/ op = sal_op_new(cr->lc->sal); linphone_configure_op(cr->lc,op,cr->peer_url,msg->custom_headers,lp_config_get_int(cr->lc->config,"sip","chat_msg_with_contact",0)); sal_op_set_user_pointer(op, msg); /*if out of call, directly store msg*/ } if (msg->external_body_url) { content_type=ms_strdup_printf("message/external-body; access-type=URL; URL=\"%s\"",msg->external_body_url); sal_message_send(op,identity,cr->peer,content_type, NULL); ms_free(content_type); } else { sal_text_send(op, identity, cr->peer,msg->message); } msg->dir=LinphoneChatMessageOutgoing; msg->from=linphone_address_new(identity); msg->storage_id=linphone_chat_message_store(msg); }
void __linphone_friend_do_subscribe(LinphoneFriend *fr){ LinphoneCore *lc=fr->lc; if (fr->outsub==NULL){ /* people for which we don't have yet an answer should appear as offline */ fr->presence=NULL; /* if (fr->lc->vtable.notify_recv) fr->lc->vtable.notify_recv(fr->lc,(LinphoneFriend*)fr); */ }else{ sal_op_release(fr->outsub); fr->outsub=NULL; } fr->outsub=sal_op_new(lc->sal); linphone_configure_op(lc,fr->outsub,fr->uri,NULL,TRUE); sal_subscribe_presence(fr->outsub,NULL,NULL,lp_config_get_int(lc->config,"sip","subscribe_expires",600)); fr->subscribe_active=TRUE; }
LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, const LinphoneCallParams *params) { LinphoneCall *call=ms_new0(LinphoneCall,1); call->dir=LinphoneCallOutgoing; call->op=sal_op_new(lc->sal); sal_op_set_user_pointer(call->op,call); call->core=lc; linphone_core_get_local_ip(lc,linphone_address_get_domain(to),call->localip); linphone_call_init_common(call,from,to); call->params=*params; call->localdesc=create_local_media_description (lc,call); call->camera_active=params->has_video; if (linphone_core_get_firewall_policy(call->core)==LinphonePolicyUseStun) linphone_core_run_stun_tests(call->core,call); discover_mtu(lc,linphone_address_get_domain (to)); if (params->referer){ sal_call_set_referer (call->op,params->referer->op); } return call; }
static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage* msg) { const char *route=NULL; const char *identity=linphone_core_find_best_identity(cr->lc,cr->peer_url,&route); SalOp *op=NULL; LinphoneCall *call; char* content_type; if (lp_config_get_int(cr->lc->config,"sip","chat_use_call_dialogs",1)) { if((call = linphone_core_get_call_by_remote_address(cr->lc,cr->peer))!=NULL) { if (call->state==LinphoneCallConnected || call->state==LinphoneCallStreamsRunning || call->state==LinphoneCallPaused || call->state==LinphoneCallPausing || call->state==LinphoneCallPausedByRemote) { ms_message("send SIP message through the existing call."); op = call->op; call->pending_message=msg; } } } if (op==NULL) { /*sending out of calls*/ op = sal_op_new(cr->lc->sal); sal_op_set_route(op,route); sal_op_set_user_pointer(op, msg); /*if out of call, directly store msg*/ } if (msg->external_body_url) { content_type=ms_strdup_printf("message/external-body; access-type=URL; URL=\"%s\"",msg->external_body_url); sal_message_send(op,identity,cr->peer,content_type,NULL); ms_free(content_type); } else { sal_text_send(op, identity, cr->peer, msg->message); } }
LinphoneEvent *linphone_event_new(LinphoneCore *lc, LinphoneSubscriptionDir dir, const char *name){ LinphoneEvent *lev=linphone_event_new_base(lc, dir, name, sal_op_new(lc->sal)); return lev; }
static void process_request_event(void *sal, const belle_sip_request_event_t *event) { SalOp* op=NULL; belle_sip_request_t* req = belle_sip_request_event_get_request(event); belle_sip_dialog_t* dialog=belle_sip_request_event_get_dialog(event); belle_sip_header_address_t* origin_address; belle_sip_header_address_t* address; belle_sip_header_from_t* from_header; belle_sip_header_to_t* to; belle_sip_response_t* resp; belle_sip_header_t *evh; const char *method=belle_sip_request_get_method(req); from_header=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_from_t); if (dialog) { op=(SalOp*)belle_sip_dialog_get_application_data(dialog); if (op==NULL || op->state==SalOpStateTerminated){ ms_warning("Receiving request for null or terminated op [%p], ignored",op); return; } }else if (strcmp("INVITE",method)==0) { op=sal_op_new((Sal*)sal); op->dir=SalOpDirIncoming; sal_op_call_fill_cbs(op); }else if ((strcmp("SUBSCRIBE",method)==0 || strcmp("NOTIFY",method)==0) && (evh=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Event"))!=NULL) { op=sal_op_new((Sal*)sal); op->dir=SalOpDirIncoming; if (strncmp(belle_sip_header_get_unparsed_value(evh),"presence",strlen("presence"))==0){ sal_op_presence_fill_cbs(op); }else sal_op_subscribe_fill_cbs(op); }else if (strcmp("MESSAGE",method)==0) { op=sal_op_new((Sal*)sal); op->dir=SalOpDirIncoming; sal_op_message_fill_cbs(op); }else if (strcmp("OPTIONS",method)==0) { resp=belle_sip_response_create_from_request(req,200); belle_sip_provider_send_response(((Sal*)sal)->prov,resp); return; }else if (strcmp("INFO",method)==0) { resp=belle_sip_response_create_from_request(req,481);/*INFO out of call dialogs are not allowed*/ belle_sip_provider_send_response(((Sal*)sal)->prov,resp); return; }else if (strcmp("BYE",method)==0) { resp=belle_sip_response_create_from_request(req,481);/*out of dialog BYE */ belle_sip_provider_send_response(((Sal*)sal)->prov,resp); return; }else { ms_error("sal process_request_event not implemented yet for method [%s]",belle_sip_request_get_method(req)); resp=belle_sip_response_create_from_request(req,501); belle_sip_provider_send_response(((Sal*)sal)->prov,resp); return; } if (!op->base.from_address) { address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header)) ,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header))); sal_op_set_from_address(op,(SalAddress*)address); belle_sip_object_unref(address); } if (!op->base.to_address) { to=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_to_t); address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(to)) ,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(to))); sal_op_set_to_address(op,(SalAddress*)address); belle_sip_object_unref(address); } if (!op->base.origin) { /*set origin uri*/ origin_address=belle_sip_header_address_create(NULL,belle_sip_request_extract_origin(req)); __sal_op_set_network_origin_address(op,(SalAddress*)origin_address); belle_sip_object_unref(origin_address); } if (!op->base.remote_ua) { sal_op_set_remote_ua(op,BELLE_SIP_MESSAGE(req)); } 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(req), belle_sip_header_call_id_t)))); } /*It is worth noting that proxies can (and will) remove this header field*/ sal_op_set_privacy_from_message(op,(belle_sip_message_t*)req); sal_op_assign_recv_headers(op,(belle_sip_message_t*)req); if (op->callbacks.process_request_event) { op->callbacks.process_request_event(op,event); } else { ms_error("sal process_request_event not implemented yet"); } }
static void process_request_event(void *ud, const belle_sip_request_event_t *event) { Sal *sal=(Sal*)ud; SalOp* op=NULL; belle_sip_request_t* req = belle_sip_request_event_get_request(event); belle_sip_dialog_t* dialog=belle_sip_request_event_get_dialog(event); belle_sip_header_address_t* origin_address; belle_sip_header_address_t* address=NULL; belle_sip_header_from_t* from_header; belle_sip_header_to_t* to; belle_sip_response_t* resp; belle_sip_header_t *evh; const char *method=belle_sip_request_get_method(req); belle_sip_header_contact_t* remote_contact = belle_sip_message_get_header_by_type(req, belle_sip_header_contact_t); from_header=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_from_t); if (dialog) { op=(SalOp*)belle_sip_dialog_get_application_data(dialog); if (op == NULL && strcmp("NOTIFY",method) == 0) { /*special case for Dialog created by notify mathing subscribe*/ belle_sip_transaction_t * sub_trans = belle_sip_dialog_get_last_transaction(dialog); op = (SalOp*)belle_sip_transaction_get_application_data(sub_trans); } if (op==NULL || op->state==SalOpStateTerminated){ ms_warning("Receiving request for null or terminated op [%p], ignored",op); return; } }else{ /*handle the case where we are receiving a request with to tag but it is not belonging to any dialog*/ belle_sip_header_to_t *to = belle_sip_message_get_header_by_type(req, belle_sip_header_to_t); if ((strcmp("INVITE",method)==0 || strcmp("NOTIFY",method)==0) && (belle_sip_header_to_get_tag(to) != NULL)) { ms_warning("Receiving %s with to-tag but no know dialog here. Rejecting.", method); resp=belle_sip_response_create_from_request(req,481); belle_sip_provider_send_response(sal->prov,resp); return; /* by default (eg. when a to-tag is present), out of dialog ACK are automatically handled in lower layers (belle-sip) but in case it misses, it will be forwarded to us */ } else if (strcmp("ACK",method)==0 && (belle_sip_header_to_get_tag(to) == NULL)) { ms_warning("Receiving ACK without to-tag but no know dialog here. Ignoring"); return; } if (strcmp("INVITE",method)==0) { op=sal_op_new(sal); op->dir=SalOpDirIncoming; sal_op_call_fill_cbs(op); }else if ((strcmp("SUBSCRIBE",method)==0 || strcmp("NOTIFY",method)==0) && (evh=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Event"))!=NULL) { op=sal_op_new(sal); op->dir=SalOpDirIncoming; if (strncmp(belle_sip_header_get_unparsed_value(evh),"presence",strlen("presence"))==0){ sal_op_presence_fill_cbs(op); }else sal_op_subscribe_fill_cbs(op); }else if (strcmp("MESSAGE",method)==0) { op=sal_op_new(sal); op->dir=SalOpDirIncoming; sal_op_message_fill_cbs(op); }else if (strcmp("OPTIONS",method)==0) { resp=belle_sip_response_create_from_request(req,200); belle_sip_provider_send_response(sal->prov,resp); return; }else if (strcmp("INFO",method)==0) { resp=belle_sip_response_create_from_request(req,481);/*INFO out of call dialogs are not allowed*/ belle_sip_provider_send_response(sal->prov,resp); return; }else if (strcmp("BYE",method)==0) { resp=belle_sip_response_create_from_request(req,481);/*out of dialog BYE */ belle_sip_provider_send_response(sal->prov,resp); return; }else if (strcmp("CANCEL",method)==0) { resp=belle_sip_response_create_from_request(req,481);/*out of dialog CANCEL */ belle_sip_provider_send_response(sal->prov,resp); return; }else if (sal->enable_test_features && strcmp("PUBLISH",method)==0) { resp=belle_sip_response_create_from_request(req,200);/*out of dialog PUBLISH */ belle_sip_message_add_header((belle_sip_message_t*)resp,belle_sip_header_create("SIP-Etag","4441929FFFZQOA")); belle_sip_provider_send_response(sal->prov,resp); return; }else { ms_error("sal process_request_event not implemented yet for method [%s]",belle_sip_request_get_method(req)); resp=belle_sip_response_create_from_request(req,405); belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp) ,BELLE_SIP_HEADER(belle_sip_header_allow_create("INVITE, CANCEL, ACK, BYE, SUBSCRIBE, NOTIFY, MESSAGE, OPTIONS, INFO"))); belle_sip_provider_send_response(sal->prov,resp); return; } } if (!op->base.from_address) { if (belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header))) address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header)) ,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header))); else if ((belle_sip_header_address_get_absolute_uri(BELLE_SIP_HEADER_ADDRESS(from_header)))) address=belle_sip_header_address_create2(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header)) ,belle_sip_header_address_get_absolute_uri(BELLE_SIP_HEADER_ADDRESS(from_header))); else ms_error("Cannot not find from uri from request [%p]",req); sal_op_set_from_address(op,(SalAddress*)address); belle_sip_object_unref(address); } if( remote_contact ){ __sal_op_set_remote_contact(op, belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(remote_contact))); } if (!op->base.to_address) { to=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_to_t); if (belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(to))) address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(to)) ,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(to))); else if ((belle_sip_header_address_get_absolute_uri(BELLE_SIP_HEADER_ADDRESS(to)))) address=belle_sip_header_address_create2(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(to)) ,belle_sip_header_address_get_absolute_uri(BELLE_SIP_HEADER_ADDRESS(to))); else ms_error("Cannot not find to uri from request [%p]",req); sal_op_set_to_address(op,(SalAddress*)address); belle_sip_object_unref(address); } if (!op->base.origin) { /*set origin uri*/ origin_address=belle_sip_header_address_create(NULL,belle_sip_request_extract_origin(req)); __sal_op_set_network_origin_address(op,(SalAddress*)origin_address); belle_sip_object_unref(origin_address); } if (!op->base.remote_ua) { sal_op_set_remote_ua(op,BELLE_SIP_MESSAGE(req)); } 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(req), belle_sip_header_call_id_t)))); } /*It is worth noting that proxies can (and will) remove this header field*/ sal_op_set_privacy_from_message(op,(belle_sip_message_t*)req); sal_op_assign_recv_headers(op,(belle_sip_message_t*)req); if (op->callbacks && op->callbacks->process_request_event) { op->callbacks->process_request_event(op,event); } else { ms_error("sal process_request_event not implemented yet"); } }