diff --git a/coreapi/chat.c b/coreapi/chat.c index 9847c2c3b..3d336dbcd 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 f1823165f..68e5936ed 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.c b/coreapi/linphonecore.c index 76b823d0f..47f8a61ae 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -4678,11 +4678,8 @@ static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t cu lc->netup_time=curtime; lc->network_reachable=isReachable; if(!isReachable) { - sal_unlisten_ports (lc->sal); - } else { - apply_transports(lc); + sal_reset_transports(lc->sal); } - } void linphone_core_refresh_registers(LinphoneCore* lc) { @@ -4811,20 +4808,15 @@ static PayloadType* find_payload_type_from_list(const char* type, int rate, int for(elem=from;elem!=NULL;elem=elem->next){ PayloadType *pt=(PayloadType*)elem->data; if ((strcasecmp((char*)type, payload_type_get_mime(pt)) == 0) - && (rate == -1 || rate==pt->clock_rate) - && (channels == 0 || channels==pt->channels)) { + && (rate == LINPHONE_FIND_PAYLOAD_IGNORE_RATE || rate==pt->clock_rate) + && (channels == LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS || channels==pt->channels)) { return pt; } } return NULL; } -/** - * Get payload type from mime type and clock rate - * @ingroup media_parameters - * This function searches in audio and video codecs for the given payload type name and clockrate. - * Returns NULL if not found. - */ + PayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels) { PayloadType* result = find_payload_type_from_list(type, rate, channels, linphone_core_get_audio_codecs(lc)); if (result) { diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 72477c903..4895ccb93 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); @@ -869,6 +928,26 @@ bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const PayloadType *p int linphone_core_enable_payload_type(LinphoneCore *lc, PayloadType *pt, bool_t enable); +/** + * Wildcard value used by #linphone_core_find_payload_type to ignore rate in search algirithm + * @ingroup media_parameters + */ +#define LINPHONE_FIND_PAYLOAD_IGNORE_RATE -1 +/** + * Wildcard value used by #linphone_core_find_payload_type to ignore channel in search algirithm + * @ingroup media_parameters + */ +#define LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS -1 +/** + * Get payload type from mime type and clock rate + * @ingroup media_parameters + * This function searches in audio and video codecs for the given payload type name and clockrate. + * @param lc #LinphoneCore object + * @param type payload mime type (I.E SPEEX, PCMU, VP8) + * @param rate, can be #LINPHONE_FIND_PAYLOAD_IGNORE_RATE + * @param channels, number of channels, can be #LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS + * @return Returns NULL if not found. + */ PayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels) ; int linphone_core_get_payload_type_number(LinphoneCore *lc, const PayloadType *pt); diff --git a/coreapi/private.h b/coreapi/private.h index d1c15e41c..6c9ba8d29 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.h b/coreapi/sal.h index 0d2b631d8..616b0aba9 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -321,6 +321,7 @@ void sal_auth_info_delete(const SalAuthInfo* auth_info); void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs); int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure); int sal_unlisten_ports(Sal *ctx); +int sal_reset_transports(Sal *ctx); ortp_socket_t sal_get_socket(Sal *ctx); void sal_set_user_agent(Sal *ctx, const char *user_agent); /*keepalive period in ms*/ diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 76d7973d9..076839a10 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -353,6 +353,32 @@ int sal_unlisten_ports(Sal *ctx){ return 0; } +int sal_reset_transports(Sal *ctx){ +#ifdef HAVE_EXOSIP_RESET_TRANSPORTS + if (ctx->running){ + ms_message("Exosip transports reset."); + eXosip_reset_transports(); + } + return 0; +#else + ms_warning("sal_reset_transports() not implemented in this version."); + return -1; +#endif +} + + +static void set_tls_options(Sal *ctx){ + if (ctx->rootCa) { + eXosip_tls_ctx_t tlsCtx; + memset(&tlsCtx, 0, sizeof(tlsCtx)); + snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa); + eXosip_set_tls_ctx(&tlsCtx); + } +#ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE + eXosip_tls_verify_certificate(ctx->verify_server_certs); +#endif +} + int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){ int err; bool_t ipv6; @@ -369,16 +395,7 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i proto= IPPROTO_TCP; keepalive=-1; eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive); - - if (ctx->rootCa) { - eXosip_tls_ctx_t tlsCtx; - memset(&tlsCtx, 0, sizeof(tlsCtx)); - snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa); - eXosip_set_tls_ctx(&tlsCtx); - } -#ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE - eXosip_tls_verify_certificate(ctx->verify_server_certs); -#endif + set_tls_options(ctx); break; default: ms_warning("unexpected proto, using datagram"); @@ -445,6 +462,7 @@ void sal_set_root_ca(Sal* ctx, const char* rootCa) { if (ctx->rootCa) ms_free(ctx->rootCa); ctx->rootCa = ms_strdup(rootCa); + set_tls_options(ctx); } void sal_verify_server_certificates(Sal *ctx, bool_t verify){ @@ -1935,7 +1953,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; @@ -1944,6 +1963,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); + } } } diff --git a/m4/exosip.m4 b/m4/exosip.m4 index 51419d48a..129b28570 100644 --- a/m4/exosip.m4 +++ b/m4/exosip.m4 @@ -50,6 +50,10 @@ AC_CHECK_LIB([eXosip2],[eXosip_trylock], [AC_DEFINE([HAVE_EXOSIP_TRYLOCK],[1],[Defined when eXosip_get_socket is available])], [], [-losipparser2 -losip2 ]) +AC_CHECK_LIB([eXosip2],[eXosip_reset_transports], + [AC_DEFINE([HAVE_EXOSIP_RESET_TRANSPORTS],[1],[Defined when eXosip_reset_transports is available])], + [], + [-losipparser2 -losip2 ]) dnl AC_CHECK_LIB([eXosip2],[eXosip_get_naptr], dnl [AC_DEFINE([HAVE_EXOSIP_NAPTR_SUPPORT],[1],[Defined when eXosip_get_naptr is available])], dnl [], diff --git a/mediastreamer2 b/mediastreamer2 index d622cd514..1a267bd2f 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit d622cd51499ad0745e519eb129ea133fa8fd168b +Subproject commit 1a267bd2fb946b51b877a8cbc78f3445c11ab361 diff --git a/oRTP b/oRTP index cba069472..716ac0178 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit cba069472f6a464c0d7372cd97be0215cf165995 +Subproject commit 716ac0178612a7416c828fd74261e4dda44930de