static gboolean search_process_cb(GIOChannel *chan, GIOCondition cond, gpointer user_data) { struct search_context *ctxt = user_data; int err = 0; if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) { err = EIO; goto failed; } if (sdp_process(ctxt->session) < 0) goto failed; return TRUE; failed: if (err) { sdp_close(ctxt->session); ctxt->session = NULL; if (ctxt->cb) ctxt->cb(NULL, err, ctxt->user_data); search_context_cleanup(ctxt); } return FALSE; }
static void handle_offer_answer_response(SalOp* op, belle_sip_response_t* response) { if (op->base.local_media){ /*this is the case where we received an invite without SDP*/ if (op->sdp_offering) { set_sdp_from_desc(BELLE_SIP_MESSAGE(response),op->base.local_media); }else{ if ( op->sdp_answer==NULL ) { if( op->sdp_handling == SalOpSDPSimulateRemove ){ ms_warning("Simulating SDP removal in answer for op %p", op); } else { sdp_process(op); } } if (op->sdp_answer){ set_sdp(BELLE_SIP_MESSAGE(response),op->sdp_answer); belle_sip_object_unref(op->sdp_answer); op->sdp_answer=NULL; } } }else{ ms_error("You are accepting a call but not defined any media capabilities !"); } }
static void handle_sdp_from_response(SalOp* op,belle_sip_response_t* response) { belle_sdp_session_description_t* sdp; if ((sdp=belle_sdp_session_description_create(BELLE_SIP_MESSAGE(response)))) { op->base.remote_media=sal_media_description_new(); sdp_to_media_description(sdp,op->base.remote_media); if (op->base.local_media) sdp_process(op); } }
static gboolean process_callback(GIOChannel *io, GIOCondition cond, gpointer user_data) { struct bluetooth_session *session = user_data; if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) return FALSE; if (sdp_process(session->sdp) < 0) return FALSE; return TRUE; }
static void handle_sdp_from_response(SalOp* op,belle_sip_response_t* response) { belle_sdp_session_description_t* sdp; SalReason reason; if (op->base.remote_media){ sal_media_description_unref(op->base.remote_media); op->base.remote_media=NULL; } if (extract_sdp(op,BELLE_SIP_MESSAGE(response),&sdp,&reason)==0) { if (sdp){ op->base.remote_media=sal_media_description_new(); sdp_to_media_description(sdp,op->base.remote_media); }/*if no sdp in response, what can we do ?*/ } /* process sdp in any case to reset result media description*/ if (op->base.local_media) sdp_process(op); }
SalMediaDescription * sal_call_get_final_media_description(SalOp *h){ if (h->base.local_media && h->base.remote_media && !h->result){ sdp_process(h); } return h->result; }
static void process_request_event(void *op_base, const belle_sip_request_event_t *event) { SalOp* op = (SalOp*)op_base; belle_sip_server_transaction_t* server_transaction=NULL; belle_sdp_session_description_t* sdp; belle_sip_request_t* req = belle_sip_request_event_get_request(event); belle_sip_dialog_state_t dialog_state; belle_sip_response_t* resp; belle_sip_header_t* call_info; const char *method=belle_sip_request_get_method(req); bool_t is_update=FALSE; if (strcmp("ACK",method)!=0){ /*ACK does'nt create srv transaction*/ server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,belle_sip_request_event_get_request(event)); belle_sip_object_ref(server_transaction); belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(server_transaction),sal_op_ref(op)); } if (strcmp("INVITE",method)==0) { if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans); /*updating pending invite transaction*/ op->pending_server_trans=server_transaction; belle_sip_object_ref(op->pending_server_trans); } if (strcmp("UPDATE",method)==0) { if (op->pending_update_server_trans) belle_sip_object_unref(op->pending_update_server_trans); /*updating pending update transaction*/ op->pending_update_server_trans=server_transaction; belle_sip_object_ref(op->pending_update_server_trans); } if (!op->dialog) { set_or_update_dialog(op,belle_sip_provider_create_dialog(op->base.root->prov,BELLE_SIP_TRANSACTION(op->pending_server_trans))); ms_message("new incoming call from [%s] to [%s]",sal_op_get_from(op),sal_op_get_to(op)); } dialog_state=belle_sip_dialog_get_state(op->dialog); switch(dialog_state) { case BELLE_SIP_DIALOG_NULL: { if (strcmp("INVITE",method)==0) { if (!op->replaces && (op->replaces=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_replaces_t))) { belle_sip_object_ref(op->replaces); } else if(op->replaces) { ms_warning("replace header already set"); } if (process_sdp_for_invite(op,req) == 0) { if ((call_info=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Call-Info"))) { if( strstr(belle_sip_header_get_unparsed_value(call_info),"answer-after=") != NULL) { op->auto_answer_asked=TRUE; ms_message("The caller asked to automatically answer the call(Emergency?)\n"); } } op->base.root->callbacks.call_received(op); } break; } /* else same behavior as for EARLY state*/ } case BELLE_SIP_DIALOG_EARLY: { //hmm probably a cancel if (strcmp("CANCEL",method)==0) { if(belle_sip_request_event_get_server_transaction(event)) { /*first answer 200 ok to cancel*/ belle_sip_server_transaction_send_response(server_transaction ,sal_op_create_response_from_request(op,req,200)); /*terminate invite transaction*/ call_terminated(op ,op->pending_server_trans ,belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_server_trans)),487); } else { /*call leg does not exist*/ belle_sip_server_transaction_send_response(server_transaction ,sal_op_create_response_from_request(op,req,481)); } } else if (strcmp("PRACK",method)==0) { resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); } else if (strcmp("UPDATE",method)==0) { sal_op_reset_descriptions(op); if (process_sdp_for_invite(op,req)==0) op->base.root->callbacks.call_updating(op,TRUE); } else { belle_sip_error("Unexpected method [%s] for dialog state BELLE_SIP_DIALOG_EARLY",belle_sip_request_get_method(req)); unsupported_method(server_transaction,req); } break; } case BELLE_SIP_DIALOG_CONFIRMED: /*great ACK received*/ if (strcmp("ACK",method)==0) { if (op->sdp_offering){ SalReason reason; if (extract_sdp(op,BELLE_SIP_MESSAGE(req),&sdp,&reason)==0){ if (sdp){ if (op->base.remote_media) sal_media_description_unref(op->base.remote_media); op->base.remote_media=sal_media_description_new(); sdp_to_media_description(sdp,op->base.remote_media); sdp_process(op); belle_sip_object_unref(sdp); }else{ ms_warning("SDP expected in ACK but not found."); } } } op->base.root->callbacks.call_ack(op); } else if(strcmp("BYE",method)==0) { resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op)); op->state=SalOpStateTerminating; /*call end not notified by dialog deletion because transaction can end before dialog*/ } else if(strcmp("INVITE",method)==0 || (is_update=(strcmp("UPDATE",method)==0)) ) { if (is_update && !belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))) { /*session timer case*/ /*session expire should be handled. to be done when real session timer (rfc4028) will be implemented*/ resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); belle_sip_object_unref(op->pending_update_server_trans); op->pending_update_server_trans=NULL; } else { /*re-invite*/ sal_op_reset_descriptions(op); if (process_sdp_for_invite(op,req)==0) op->base.root->callbacks.call_updating(op,is_update); } } else if (strcmp("INFO",method)==0){ if (belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)) && strstr(belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)),"picture_fast_update")) { /*vfu request*/ ms_message("Receiving VFU request on op [%p]",op); if (op->base.root->callbacks.vfu_request){ op->base.root->callbacks.vfu_request(op); } }else{ SalBody salbody; if (sal_op_get_body(op,(belle_sip_message_t*)req,&salbody)) { if (sal_body_has_type(&salbody,"application","dtmf-relay")){ char tmp[10]; if (sal_lines_get_value(salbody.data, "Signal",tmp, sizeof(tmp))){ op->base.root->callbacks.dtmf_received(op,tmp[0]); } }else op->base.root->callbacks.info_received(op,&salbody); } else { op->base.root->callbacks.info_received(op,NULL); } } resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); }else if (strcmp("REFER",method)==0) { sal_op_process_refer(op,event,server_transaction); } else if (strcmp("NOTIFY",method)==0) { sal_op_call_process_notify(op,event,server_transaction); } else if (strcmp("OPTIONS",method)==0) { resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); } else if (strcmp("CANCEL",method)==0) { /*call leg does not exist because 200ok already sent*/ belle_sip_server_transaction_send_response(server_transaction,sal_op_create_response_from_request(op,req,481)); } else if (strcmp("MESSAGE",method)==0){ sal_process_incoming_message(op,event); }else{ ms_error("unexpected method [%s] for dialog [%p]",belle_sip_request_get_method(req),op->dialog); unsupported_method(server_transaction,req); } break; default: ms_error("unexpected dialog state [%s]",belle_sip_dialog_state_to_string(dialog_state)); break; } if (server_transaction) belle_sip_object_unref(server_transaction); }
static void process_request_event(void *op_base, const belle_sip_request_event_t *event) { SalOp* op = (SalOp*)op_base; belle_sip_server_transaction_t* server_transaction=NULL; belle_sdp_session_description_t* sdp; belle_sip_request_t* req = belle_sip_request_event_get_request(event); belle_sip_dialog_state_t dialog_state; belle_sip_response_t* resp; belle_sip_header_t* call_info; if (strcmp("ACK",belle_sip_request_get_method(req))!=0){ /*ACK does'nt create srv transaction*/ server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,belle_sip_request_event_get_request(event)); belle_sip_object_ref(server_transaction); belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(server_transaction),op); sal_op_ref(op); } if (strcmp("INVITE",belle_sip_request_get_method(req))==0) { if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans); /*updating pending invite transaction*/ op->pending_server_trans=server_transaction; belle_sip_object_ref(op->pending_server_trans); } if (!op->dialog) { set_or_update_dialog(op,belle_sip_provider_create_dialog(op->base.root->prov,BELLE_SIP_TRANSACTION(op->pending_server_trans))); ms_message("new incoming call from [%s] to [%s]",sal_op_get_from(op),sal_op_get_to(op)); } dialog_state=belle_sip_dialog_get_state(op->dialog); switch(dialog_state) { case BELLE_SIP_DIALOG_NULL: { if (strcmp("INVITE",belle_sip_request_get_method(req))==0) { if (!op->replaces && (op->replaces=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_replaces_t))) { belle_sip_object_ref(op->replaces); } else if(op->replaces) { ms_warning("replace header already set"); } process_sdp_for_invite(op,req); if ((call_info=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Call-Info"))) { if( strstr(belle_sip_header_extension_get_value(BELLE_SIP_HEADER_EXTENSION(call_info)),"answer-after=") != NULL) { op->auto_answer_asked=TRUE; ms_message("The caller asked to automatically answer the call(Emergency?)\n"); } } op->base.root->callbacks.call_received(op); break; } /* else same behavior as for EARLY state*/ } case BELLE_SIP_DIALOG_EARLY: { //hmm probably a cancel if (strcmp("CANCEL",belle_sip_request_get_method(req))==0) { if(belle_sip_request_event_get_server_transaction(event)) { /*first answer 200 ok to cancel*/ belle_sip_server_transaction_send_response(server_transaction ,sal_op_create_response_from_request(op,req,200)); /*terminate invite transaction*/ call_terminated(op ,op->pending_server_trans ,belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_server_trans)),487); } else { /*call leg does not exist*/ belle_sip_server_transaction_send_response(server_transaction ,sal_op_create_response_from_request(op,req,481)); } } else if (strcmp("PRACK",belle_sip_request_get_method(req))==0) { resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); } else { belle_sip_error("Unexpected method [%s] for dialog state BELLE_SIP_DIALOG_EARLY",belle_sip_request_get_method(req)); unsupported_method(server_transaction,req); } break; } case BELLE_SIP_DIALOG_CONFIRMED: /*great ACK received*/ if (strcmp("ACK",belle_sip_request_get_method(req))==0) { if (op->sdp_offering){ if ((sdp=belle_sdp_session_description_create(BELLE_SIP_MESSAGE(req)))){ if (op->base.remote_media) sal_media_description_unref(op->base.remote_media); op->base.remote_media=sal_media_description_new(); sdp_to_media_description(sdp,op->base.remote_media); sdp_process(op); belle_sip_object_unref(sdp); } } /*FIXME if (op->reinvite){ op->reinvite=FALSE; }*/ op->base.root->callbacks.call_ack(op); } else if(strcmp("BYE",belle_sip_request_get_method(req))==0) { resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op)); op->state=SalOpStateTerminating; /*call end not notified by dialog deletion because transaction can end before dialog*/ } else if(strcmp("INVITE",belle_sip_request_get_method(req))==0) { /*re-invite*/ if (op->base.remote_media){ sal_media_description_unref(op->base.remote_media); op->base.remote_media=NULL; } if (op->result){ sal_media_description_unref(op->result); op->result=NULL; } process_sdp_for_invite(op,req); op->base.root->callbacks.call_updating(op); } else if (strcmp("INFO",belle_sip_request_get_method(req))==0){ if (belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)) && strstr(belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)),"picture_fast_update")) { /*vfu request*/ ms_message("Receiving VFU request on op [%p]",op); if (op->base.root->callbacks.vfu_request){ op->base.root->callbacks.vfu_request(op); } }else{ SalBody salbody; if (sal_op_get_body(op,(belle_sip_message_t*)req,&salbody)) { op->base.root->callbacks.info_received(op,&salbody); } else { op->base.root->callbacks.info_received(op,NULL); } } resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); }else if (strcmp("REFER",belle_sip_request_get_method(req))==0) { sal_op_process_refer(op,event,server_transaction); } else if (strcmp("NOTIFY",belle_sip_request_get_method(req))==0) { sal_op_call_process_notify(op,event,server_transaction); } else if (strcmp("OPTIONS",belle_sip_request_get_method(req))==0) { resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); } else if (strcmp("CANCEL",belle_sip_request_get_method(req))==0) { /*call leg does not exist because 200ok already sent*/ belle_sip_server_transaction_send_response( server_transaction ,sal_op_create_response_from_request(op,req,481)); } else{ ms_error("unexpected method [%s] for dialog [%p]",belle_sip_request_get_method(req),op->dialog); unsupported_method(server_transaction,req); } break; default: { ms_error("unexpected dialog state [%s]",belle_sip_dialog_state_to_string(dialog_state)); } /* no break */ } if (server_transaction) belle_sip_object_unref(server_transaction); }