From 6885ebf0ec0f6bb02a79cd4e31aa9e57b5f6b7f2 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 1 Apr 2010 11:41:13 +0200 Subject: [PATCH] support for in call MESSAGEs refer improvements. --- console/commands.c | 34 ++++++++++++++++++++++++ console/linphonec.c | 14 +++++++++- coreapi/callbacks.c | 13 +++++++++ coreapi/chat.c | 14 +++++++--- coreapi/linphonecore.c | 19 ++++++++++++++ coreapi/private.h | 1 + coreapi/sal_eXosip2.c | 44 ++++++++++++++++++++++++++++++- coreapi/sal_eXosip2_presence.c | 48 ++++++++++++++++++++++++++-------- 8 files changed, 171 insertions(+), 16 deletions(-) diff --git a/console/commands.c b/console/commands.c index 82044797e..8232a26fd 100644 --- a/console/commands.c +++ b/console/commands.c @@ -53,6 +53,7 @@ extern char *lpc_strip_blanks(char *input); static int lpc_cmd_help(LinphoneCore *, char *); static int lpc_cmd_proxy(LinphoneCore *, char *); static int lpc_cmd_call(LinphoneCore *, char *); +static int lpc_cmd_chat(LinphoneCore *, char *); static int lpc_cmd_answer(LinphoneCore *, char *); static int lpc_cmd_autoanswer(LinphoneCore *, char *); static int lpc_cmd_terminate(LinphoneCore *, char *); @@ -122,6 +123,10 @@ LPC_COMMAND commands[] = { "'call ' " ": initiate a call to the specified destination." }, + { "chat", lpc_cmd_chat, "Chat with a SIP uri", + "'chat \"message\"' " + ": send a chat message \"message\" to the specified destination." + }, { "terminate", lpc_cmd_terminate, "Terminate the current call", NULL }, { "answer", lpc_cmd_answer, "Answer a call", @@ -388,6 +393,35 @@ lpc_cmd_call(LinphoneCore *lc, char *args) return 1; } +static int +lpc_cmd_chat(LinphoneCore *lc, char *args) +{ + char *arg1 = args; + char *arg2 = NULL; + char *ptr = args; + + if (!args) return 0; + + /* Isolate first and second arg */ + while(*ptr && !isspace(*ptr)) ++ptr; + if ( *ptr ) + { + *ptr='\0'; + arg2=ptr+1; + while(*arg2 && isspace(*arg2)) ++arg2; + } + else + { + /* missing one parameter */ + return 0; + } + LinphoneChatRoom *cr = linphone_core_create_chat_room(lc,arg1); + linphone_chat_room_send_message(cr,arg2); + linphone_chat_room_destroy(cr); + + return 1; +} + const char *linphonec_get_callee(){ return callee_name; } diff --git a/console/linphonec.c b/console/linphonec.c index ff68fbecd..a64c3ba27 100644 --- a/console/linphonec.c +++ b/console/linphonec.c @@ -115,6 +115,7 @@ static char **linephonec_readline_completion(const char *text, static void linphonec_call_received(LinphoneCore *lc, const char *from); static void linphonec_prompt_for_auth(LinphoneCore *lc, const char *realm, const char *username); +static void linphonec_display_refer (LinphoneCore * lc,const char *refer_to); static void linphonec_display_something (LinphoneCore * lc, const char *something); static void linphonec_display_url (LinphoneCore * lc, const char *something, const char *url); static void linphonec_display_warning (LinphoneCore * lc, const char *something); @@ -188,7 +189,8 @@ LinphoneCoreVTable linphonec_vtable .display_question=(DisplayQuestionCb)stub, .text_received=linphonec_text_received, .general_state=linphonec_general_state, - .dtmf_received=linphonec_dtmf_received + .dtmf_received=linphonec_dtmf_received, + .refer_received=linphonec_display_refer } #endif /*_WIN32_WCE*/ ; @@ -201,6 +203,16 @@ LinphoneCoreVTable linphonec_vtable * ***************************************************************************/ +/* + * Linphone core callback + */ +static void +linphonec_display_refer (LinphoneCore * lc,const char *refer_to) +{ + fprintf (stdout, "The distant end point asked to transfer the call to %s,don't forget to terminate the call\n%s", refer_to,prompt); + fflush(stdout); +} + /* * Linphone core callback */ diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 7da3b4b30..edc8cfa5e 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphonecore.h" #include "private.h" #include "mediastreamer2/mediastream.h" +#include "sal_eXosip2.h" static void linphone_connect_incoming(LinphoneCore *lc, LinphoneCall *call){ if (lc->vtable.show) @@ -391,7 +392,19 @@ static void dtmf_received(SalOp *op, char dtmf){ } static void refer_received(Sal *sal, SalOp *op, const char *referto){ + osip_message_t *msg; LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal); + if(op != NULL) + { + eXosip_call_build_notify(op->tid,EXOSIP_SUBCRSTATE_ACTIVE,&msg); + if(msg != NULL) + { + osip_message_set_header(msg,(const char *)"event","refer"); + osip_message_set_content_type(msg,"message/sipfrag"); + osip_message_set_body(msg,"SIP/2.0 100 Trying",sizeof("SIP/2.0 100 Trying")); + eXosip_call_send_request(op->tid,msg); + } + } if (lc->vtable.refer_received) lc->vtable.refer_received(lc,referto); } diff --git a/coreapi/chat.c b/coreapi/chat.c index c1a884964..73a5f7c9a 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -51,9 +51,17 @@ void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg){ const char *identity=linphone_core_get_identity(cr->lc); - SalOp *op=sal_op_new(cr->lc->sal); - - sal_op_set_route(op,cr->route); + SalOp *op; + if(linphone_core_is_in_communication_with(cr->lc,cr->peer)) + { + ms_message("send SIP message into the call\n"); + op = cr->lc->call->op; + } + else + { + op = sal_op_new(cr->lc->sal); + sal_op_set_route(op,cr->route); + } sal_text_send(op,identity,cr->peer,msg); } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 3e911cee1..263277070 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1769,6 +1769,25 @@ const char * linphone_core_get_route(LinphoneCore *lc){ return route; } +bool_t linphone_core_is_in_communication_with(LinphoneCore *lc, const char *to) +{ + char *tmp; + bool_t returned; + const LinphoneAddress *la=linphone_core_get_remote_uri(lc); + if(la == NULL) + { + return FALSE; + } + tmp = linphone_address_as_string(la); + if(!strcmp(tmp,to)) + returned = TRUE; + else + returned = FALSE; + if(tmp) + ms_free(tmp); + return returned; +} + LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri){ const MSList *elem; LinphoneProxyConfig *found_cfg=NULL; diff --git a/coreapi/private.h b/coreapi/private.h index 50de9c9c6..d3da450b9 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -177,6 +177,7 @@ void linphone_core_start_media_streams(LinphoneCore *lc, struct _LinphoneCall *c void linphone_core_stop_media_streams(LinphoneCore *lc, struct _LinphoneCall *call); const char * linphone_core_get_identity(LinphoneCore *lc); const char * linphone_core_get_route(LinphoneCore *lc); +bool_t linphone_core_is_in_communication_with(LinphoneCore *lc, const char *to); void linphone_core_start_waiting(LinphoneCore *lc, const char *purpose); void linphone_core_update_progress(LinphoneCore *lc, const char *purpose, float progresses); void linphone_core_stop_waiting(LinphoneCore *lc); diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index b160a03bd..82bae962a 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -26,6 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. /*this function is not declared in some versions of eXosip*/ extern void *eXosip_call_get_reference(int cid); +static void text_received(Sal *sal, eXosip_event_t *ev); + static void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){ void *data; while((data=osip_list_get(l,0))!=NULL){ @@ -1075,6 +1077,45 @@ static void call_message_new(Sal *sal, eXosip_event_t *ev){ eXosip_unlock(); } } + if(MSG_IS_MESSAGE(ev->request)){ + /* SIP messages could be received into call */ + text_received(sal, ev); + eXosip_lock(); + eXosip_call_build_answer(ev->tid,200,&ans); + if (ans) + eXosip_call_send_answer(ev->tid,200,ans); + eXosip_unlock(); + } + if(MSG_IS_REFER(ev->request)){ + osip_header_t *h=NULL; + ms_message("Receiving REFER request !"); + osip_message_header_get_byname(ev->request,"Refer-To",0,&h); + eXosip_lock(); + eXosip_call_build_answer(ev->tid,202,&ans); + if (ans) + eXosip_call_send_answer(ev->tid,202,ans); + eXosip_unlock(); + if (h){ + SalOp *op=(SalOp*)ev->external_reference; + sal->callbacks.refer_received(sal,op,h->hvalue); + } + } + if(MSG_IS_NOTIFY(ev->request)){ + osip_header_t *h=NULL; + ms_message("Receiving NOTIFY request !"); + osip_message_header_get_byname(ev->request,"Event",0,&h); + if (h){ + if(!strcmp(h->hvalue,"refer")) + { + ms_message("get the notify of the Refer sent"); + } + } + eXosip_lock(); + eXosip_call_build_answer(ev->tid,200,&ans); + if (ans) + eXosip_call_send_answer(ev->tid,200,ans); + eXosip_unlock(); + } }else ms_warning("call_message_new: No request ?"); } @@ -1146,7 +1187,8 @@ static void other_request(Sal *sal, eXosip_event_t *ev){ osip_message_header_get_byname(ev->request,"Refer-To",0,&h); eXosip_message_send_answer(ev->tid,200,NULL); if (h){ - sal->callbacks.refer_received(sal,NULL,h->hvalue); + SalOp *op=(SalOp*)ev->external_reference; + sal->callbacks.refer_received(sal,op,h->hvalue); } }else ms_warning("Ignored REFER not coming from this local loopback interface."); }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){ diff --git a/coreapi/sal_eXosip2_presence.c b/coreapi/sal_eXosip2_presence.c index 9d5641024..ed775abc3 100644 --- a/coreapi/sal_eXosip2_presence.c +++ b/coreapi/sal_eXosip2_presence.c @@ -71,18 +71,44 @@ void sal_remove_in_subscribe(Sal *sal, SalOp *op){ int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){ osip_message_t *sip=NULL; - if (from) - sal_op_set_from(op,from); - if (to) - sal_op_set_to(op,to); - eXosip_lock(); - eXosip_message_build_request(&sip,"MESSAGE",sal_op_get_to(op), - sal_op_get_from(op),sal_op_get_route(op)); - osip_message_set_content_type(sip,"text/plain"); - osip_message_set_body(sip,msg,strlen(msg)); - eXosip_message_send_request(sip); - eXosip_unlock(); + if(op->cid == -1) + { + /* we are not currently in communication with the destination */ + if (from) + sal_op_set_from(op,from); + if (to) + sal_op_set_to(op,to); + + eXosip_lock(); + eXosip_message_build_request(&sip,"MESSAGE",sal_op_get_to(op), + sal_op_get_from(op),sal_op_get_route(op)); + osip_message_set_content_type(sip,"text/plain"); + osip_message_set_body(sip,msg,strlen(msg)); + eXosip_message_send_request(sip); + eXosip_unlock(); + } + else + { + /* we are currently in communication with the destination */ + eXosip_lock(); + //First we generate an INFO message to get the current call_id and a good cseq + eXosip_call_build_info(op->did,&sip); + if(sip == NULL) + { + ms_warning("could not get a build info to send MESSAGE, maybe no previous call established ?"); + osip_message_free(sip); + eXosip_unlock(); + return -1; + } + osip_free(sip->sip_method); + //change the sip_message to be a MESSAGE ... + osip_message_set_method(sip,osip_strdup("MESSAGE")); + osip_message_set_content_type(sip,"text/plain"); + osip_message_set_body(sip,msg,strlen(msg)); + eXosip_message_send_request(sip); + eXosip_unlock(); + } return 0; }