From f28e7960a1076646013a3e5ba82a2f078f5fc9c4 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Wed, 29 Aug 2012 18:16:26 +0200 Subject: [PATCH] add sip message delivery notification --- coreapi/chat.c | 51 ++++++++++++++++++++++++++++++++--- coreapi/linphonecall.c | 3 +++ coreapi/linphonecore.h | 61 +++++++++++++++++++++++++++++++++++++++++- coreapi/private.h | 15 +++++++++++ coreapi/sal_eXosip2.c | 13 ++++++++- 5 files changed, 138 insertions(+), 5 deletions(-) diff --git a/coreapi/chat.c b/coreapi/chat.c index 9847c2c3..3d336dbc 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -48,8 +48,9 @@ if (cr->op) sal_op_release(cr->op); } - -void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg){ + + +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; @@ -62,6 +63,7 @@ void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg){ call->state==LinphoneCallPausedByRemote){ ms_message("send SIP message through the existing call."); op = call->op; + call->pending_message=msg; } } if (op==NULL){ @@ -73,10 +75,14 @@ void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg){ cr->op=NULL; } cr->op=op; + sal_op_set_user_pointer(op, msg); /*if out of call, directly store msg*/ } - sal_text_send(op,identity,cr->peer,msg); + sal_text_send(op,identity,cr->peer,msg->message); } +void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg) { + _linphone_chat_room_send_message(cr,linphone_chat_room_create_message(cr,msg)); +} bool_t linphone_chat_room_matches(LinphoneChatRoom *cr, const LinphoneAddress *from){ if (linphone_address_get_username(cr->peer_url) && linphone_address_get_username(from) && strcmp(linphone_address_get_username(cr->peer_url),linphone_address_get_username(from))==0) return TRUE; @@ -123,3 +129,42 @@ void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr){ const LinphoneAddress* linphone_chat_room_get_peer_address(LinphoneChatRoom *cr) { return cr->peer_url; } + +LinphoneChatMessage* linphone_chat_room_create_message(const LinphoneChatRoom *cr,const char* message) { + LinphoneChatMessage* msg = ms_new0(LinphoneChatMessage,1); + msg->chat_room=(LinphoneChatRoom*)cr; + msg->message=ms_strdup(message); + return msg; +} +void linphone_chat_message_destroy(LinphoneChatMessage* msg) { + if (msg->message) ms_free((void*)msg->message); + ms_free((void*)msg); +} +void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* msg,LinphoneChatMessageStateChangeCb status_cb,void* ud) { + msg->cb=status_cb; + msg->cb_ud=ud; + _linphone_chat_room_send_message(cr, msg); +} + +const char* linphone_chat_message_state_to_string(const LinphoneChatMessageState state) { + switch (state) { + case LinphoneChatMessageStateIdle:return "LinphoneChatMessageStateIdle"; + case LinphoneChatMessageStateInProgress:return "LinphoneChatMessageStateInProgress"; + case LinphoneChatMessageStateDelivered:return "LinphoneChatMessageStateDelivered"; + case LinphoneChatMessageStateNotDelivered:return "LinphoneChatMessageStateNotDelivered"; + default: return "Unknown state"; + } + +} +/** + * user pointer set function + */ +void linphone_chat_message_set_user_data(LinphoneChatMessage* message,void* ud) { + message->message_userdata=ud; +} +/** + * user pointer get function + */ +void* linphone_chat_message_get_user_data(const LinphoneChatMessage* message) { + return message->message_userdata; +} \ No newline at end of file diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index f1823165..68e5936e 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1915,3 +1915,6 @@ void linphone_call_set_transfer_state(LinphoneCall* call, LinphoneCallState stat } } +bool_t linphone_call_is_in_conference(const LinphoneCall *call) { + return call->params.in_conference; +} diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 72477c90..4d5f5fd5 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -360,7 +360,14 @@ void *linphone_call_get_user_pointer(LinphoneCall *call); void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer); void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, LinphoneCallCbFunc cb, void* user_data); LinphoneCallState linphone_call_get_transfer_state(LinphoneCall *call); - +/** + * Return TRUE if this call is currently part of a conference + *@param call #LinphoneCall + *@return TRUE if part of a conference. + * + @ingroup call_control + */ +bool_t linphone_call_is_in_conference(const LinphoneCall *call); /** * Enables or disable echo cancellation for this call * @param call @@ -579,11 +586,19 @@ struct _LinphoneChatRoom; * @addtogroup chatroom * @{ */ + +/** + * A chat room message to old content to be sent. + *
Can be created by linphone_chat_room_create_message(). + */ +typedef struct _LinphoneChatMessage LinphoneChatMessage; + /** * A chat room is the place where text messages are exchanged. *
Can be created by linphone_core_create_chat_room(). */ typedef struct _LinphoneChatRoom LinphoneChatRoom; + /** * Create a new chat room for messaging from a sip uri like sip:joe@sip.linphone.org * @param lc #LinphoneCore object @@ -597,6 +612,12 @@ LinphoneChatRoom * linphone_core_create_chat_room(LinphoneCore *lc, const char * */ void linphone_chat_room_destroy(LinphoneChatRoom *cr); +/** + * create a message attached to a dedicated chat room; + */ +LinphoneChatMessage* linphone_chat_room_create_message(const LinphoneChatRoom *cr,const char* message); + + /** * get peer address \link linphone_core_create_chat_room() associated to \endlink this #LinphoneChatRoom @@ -610,6 +631,44 @@ const LinphoneAddress* linphone_chat_room_get_peer_address(LinphoneChatRoom *cr) * @param msg message to be sent */ void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg); +/** + *LinphoneChatMessageStatus used to notify if message has been succesfully delivered or not + */ +typedef enum _LinphoneChatMessageStates { + LinphoneChatMessageStateIdle, /** initial state*/ + LinphoneChatMessageStateInProgress, /*delivery in progress**/ + LinphoneChatMessageStateDelivered, /** message succesffully delivered an acknoleged by remote end point*/ + LinphoneChatMessageStateNotDelivered /** message was not delivered*/ +}LinphoneChatMessageState; + +/** + * to string function + */ +const char* linphone_chat_message_state_to_string(const LinphoneChatMessageState state); +/** + * user pointer set function + */ +void linphone_chat_message_set_user_data(LinphoneChatMessage* message,void*); +/** + * user pointer get function + */ +void* linphone_chat_message_get_user_data(const LinphoneChatMessage* message); + +/** + * Call back used to notify message delivery status + *@param msg #LinphoneChatMessage object + *@param status #LinphoneChatMessageStatus + *@param ud us user data + */ +typedef void (*LinphoneChatMessageStateChangeCb)(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud); +/** + * send a message to peer member of this chat room. + * @param cr #LinphoneChatRoom object + * @param msg #LinphoneChatMessage message to be sent + * @param status_cb #LinphoneChatMessageStatus status call back invoked when to message is delivered or not. May be NULL + * @param ud user data for the status cb. + */ +void linphone_chat_room_send_message2(LinphoneChatRoom *cr, LinphoneChatMessage* msg,LinphoneChatMessageStateChangeCb status_cb,void* ud); void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud); void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr); diff --git a/coreapi/private.h b/coreapi/private.h index d1c15e41..6c9ba8d2 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -86,6 +86,14 @@ typedef struct _CallCallbackObj static const int linphone_call_magic=0x3343; +struct _LinphoneChatMessage { + const char* message; + LinphoneChatRoom* chat_room; + LinphoneChatMessageStateChangeCb cb; + void* cb_ud; + void* message_userdata; +}; + struct _LinphoneCall { int magic; /*used to distinguish from proxy config*/ @@ -138,6 +146,7 @@ struct _LinphoneCall CallCallbackObj nextVideoFrameDecoded; LinphoneCallStats stats[2]; IceSession *ice_session; + LinphoneChatMessage* pending_message; }; @@ -277,6 +286,10 @@ LinphoneProxyConfig * is_a_linphone_proxy_config(void *user_pointer); static const int linphone_proxy_config_magic=0x7979; +/*chat*/ +void linphone_chat_message_destroy(LinphoneChatMessage* msg); +/**/ + struct _LinphoneProxyConfig { int magic; @@ -324,6 +337,8 @@ struct _LinphoneChatRoom{ void * user_data; }; + + struct _LinphoneFriend{ LinphoneAddress *uri; SalOp *insub; diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index aa9116aa..b98a9464 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -1952,7 +1952,8 @@ static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){ static void other_request_reply(Sal *sal,eXosip_event_t *ev){ SalOp *op=find_op(sal,ev); - + LinphoneChatMessage* chat_msg; + ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request)); if (op==NULL){ ms_warning("other_request_reply(): Receiving response to unknown request."); return; @@ -1961,6 +1962,16 @@ static void other_request_reply(Sal *sal,eXosip_event_t *ev){ update_contact_from_response(op,ev->response); if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0) sal->callbacks.ping_reply(op); + else if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) { + /*out of call message acknolegment*/ + chat_msg=(LinphoneChatMessage* )op->base.user_pointer; + if (chat_msg->cb) { + chat_msg->cb(chat_msg + ,(ev->response->status_code==200?LinphoneChatMessageStateDelivered:LinphoneChatMessageStateNotDelivered) + ,chat_msg->cb_ud); + } + linphone_chat_message_destroy(chat_msg); + } } } -- 2.39.2