Merge branch 'master' into dev_vcard

Conflicts:
	coreapi/linphonecore.c
	tester/presence_tester.c
This commit is contained in:
Sylvain Berfini 2016-02-03 17:16:33 +01:00
commit 6e38ee18d5
57 changed files with 887 additions and 409 deletions

View file

@ -287,10 +287,10 @@ static LPC_COMMAND advanced_commands[] = {
"'codec list' : list audio codecs\n"
"'codec enable <index>' : enable available audio codec\n"
"'codec disable <index>' : disable audio codec" },
{ "vcodec", lpc_cmd_vcodec, "Video codec configuration",
"'vcodec list' : list video codecs\n"
"'vcodec enable <index>' : enable available video codec\n"
"'vcodec disable <index>' : disable video codec" },
{ "vcodec", lpc_cmd_vcodec, "Video codec configuration",
"'vcodec list' : list video codecs\n"
"'vcodec enable <index>' : enable available video codec\n"
"'vcodec disable <index>' : disable video codec" },
{ "ec", lpc_cmd_echocancellation, "Echo cancellation",
"'ec on [<delay>] [<tail>] [<framesize>]' : turn EC on with given delay, tail length and framesize\n"
"'ec off' : turn echo cancellation (EC) off\n"

View file

@ -208,6 +208,11 @@ void sal_address_set_uri_params(SalAddress *addr, const char *params){
belle_sip_parameters_set(parameters,params);
}
bool_t sal_address_has_uri_param(SalAddress *addr, const char *name){
belle_sip_parameters_t* parameters = BELLE_SIP_PARAMETERS(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(addr)));
return belle_sip_parameters_has_parameter(parameters, name);
}
void sal_address_set_header(SalAddress *addr, const char *header_name, const char *header_value){
belle_sip_uri_set_header(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(addr)),header_name, header_value);
}

View file

@ -464,13 +464,13 @@ static void process_auth_requested(void *sal, belle_sip_auth_event_t *event) {
sal_auth_info_delete(auth_info);
}
Sal * sal_init(){
Sal * sal_init(MSFactory *factory){
belle_sip_listener_callbacks_t listener_callbacks;
Sal * sal=ms_new0(Sal,1);
/*belle_sip_object_enable_marshal_check(TRUE);*/
sal->auto_contacts=TRUE;
sal->factory = factory;
/*first create the stack, which initializes the belle-sip object's pool for this thread*/
belle_sip_set_log_handler(_belle_sip_log);
sal->stack = belle_sip_stack_new(NULL);

View file

@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "belle-sip/belle-sdp.h"
struct Sal{
MSFactory *factory;
SalCallbacks callbacks;
MSList *pending_auths;/*MSList of SalOp */
belle_sip_stack_t* stack;

View file

@ -57,13 +57,13 @@ static void sdp_process(SalOp *h){
h->result=sal_media_description_new();
if (h->sdp_offering){
offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
offer_answer_initiate_outgoing(h->base.root->factory, h->base.local_media,h->base.remote_media,h->result);
}else{
int i;
if (h->sdp_answer){
belle_sip_object_unref(h->sdp_answer);
}
offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
offer_answer_initiate_incoming(h->base.root->factory, h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
/*for backward compatibility purpose*/
if(h->cnx_ip_to_0000_if_sendonly_enabled && sal_media_description_has_dir(h->result,SalStreamSendOnly)) {
set_addr_to_0000(h->result->addr);

View file

@ -236,15 +236,6 @@ int sal_subscribe(SalOp *op, const char *from, const char *to, const char *event
return -1;
}
int sal_subscribe_refresh(SalOp *op) {
if (op->refresher) {
belle_sip_refresher_refresh(op->refresher,belle_sip_refresher_get_expires(op->refresher));
return 0;
}
ms_warning("sal_refresh_subscribe(): no refresher");
return -1;
}
int sal_unsubscribe(SalOp *op){
if (op->refresher){
const belle_sip_transaction_t *tr=(const belle_sip_transaction_t*) belle_sip_refresher_get_transaction(op->refresher);

View file

@ -789,3 +789,11 @@ bool_t sal_op_cnx_ip_to_0000_if_sendonly_enabled(SalOp *op) {
bool_t sal_op_is_forked_of(const SalOp *op1, const SalOp *op2){
return op1->base.call_id && op2->base.call_id && strcmp(op1->base.call_id, op2->base.call_id) == 0;
}
int sal_op_refresh(SalOp *op) {
if (op->refresher) {
belle_sip_refresher_refresh(op->refresher,belle_sip_refresher_get_expires(op->refresher));
return 0;
}
ms_warning("sal_refresh on op [%p] of type [%s] no refresher",op,sal_op_type_to_string(op->type));
return -1;
}

View file

@ -25,17 +25,17 @@ static void publish_refresher_listener (belle_sip_refresher_t* refresher
,const char* reason_phrase) {
SalOp* op = (SalOp*)user_pointer;
const belle_sip_client_transaction_t* last_publish_trans=belle_sip_refresher_get_transaction(op->refresher);
belle_sip_request_t* last_publish=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(last_publish_trans));
belle_sip_response_t *response=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(last_publish_trans));
/*belle_sip_response_t* response=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(belle_sip_refresher_get_transaction(refresher)));*/
ms_message("Publish refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase?reason_phrase:"none",sal_op_get_proxy(op));
if (status_code==412){
/*resubmit the request after removing the SIP-If-Match*/
belle_sip_message_remove_header((belle_sip_message_t*)last_publish,"SIP-If-Match");
belle_sip_refresher_refresh(op->refresher,BELLE_SIP_REFRESHER_REUSE_EXPIRES);
}else if (status_code==0){
if (status_code==0){
op->base.root->callbacks.on_expire(op);
}else if (status_code>=200){
belle_sip_header_t *sip_etag;
const char *sip_etag_string = NULL;
if ((sip_etag = belle_sip_message_get_header(BELLE_SIP_MESSAGE(response), "SIP-ETag"))) {
sip_etag_string = belle_sip_header_get_unparsed_value(sip_etag);
}
sal_op_set_entity_tag(op, sip_etag_string);
sal_error_info_set(&op->error_info,SalReasonUnknown,status_code,reason_phrase,NULL);
sal_op_assign_recv_headers(op,(belle_sip_message_t*)response);
op->base.root->callbacks.on_publish_response(op);
@ -60,42 +60,6 @@ void sal_op_publish_fill_cbs(SalOp *op) {
op->type=SalOpPublish;
}
/*
* Sending a publish with 0 expires removes the event state and such request shall not contain a body.
* See RFC3903, section 4.5
*/
/*presence publish */
int sal_publish_presence(SalOp *op, const char *from, const char *to, int expires, SalPresenceModel *presence){
belle_sip_request_t *req=NULL;
if(!op->refresher || !belle_sip_refresher_get_transaction(op->refresher)) {
if (from)
sal_op_set_from(op,from);
if (to)
sal_op_set_to(op,to);
op->type=SalOpPublish;
req=sal_op_build_request(op,"PUBLISH");
if( req == NULL ){
return -1;
}
if (sal_op_get_contact_address(op)){
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(sal_op_create_contact(op)));
}
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("Event","presence"));
sal_add_presence_info(op,BELLE_SIP_MESSAGE(req),presence);
return sal_op_send_and_create_refresher(op,req,expires,publish_refresher_listener);
} else {
/*update presence status*/
const belle_sip_client_transaction_t* last_publish_trans=belle_sip_refresher_get_transaction(op->refresher);
belle_sip_request_t* last_publish=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(last_publish_trans));
sal_add_presence_info(op,BELLE_SIP_MESSAGE(last_publish),expires!=0 ? presence : NULL);
return belle_sip_refresher_refresh(op->refresher,expires);
}
}
int sal_publish(SalOp *op, const char *from, const char *to, const char *eventname, int expires, const SalBodyHandler *body_handler){
belle_sip_request_t *req=NULL;
if(!op->refresher || !belle_sip_refresher_get_transaction(op->refresher)) {
@ -109,7 +73,11 @@ int sal_publish(SalOp *op, const char *from, const char *to, const char *eventna
if( req == NULL ){
return -1;
}
if (sal_op_get_entity_tag(op)) {
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("SIP-If-Match", sal_op_get_entity_tag(op)));
}
if (sal_op_get_contact_address(op)){
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(sal_op_create_contact(op)));
}
@ -131,3 +99,14 @@ int sal_publish(SalOp *op, const char *from, const char *to, const char *eventna
return belle_sip_refresher_refresh(op->refresher,expires==-1 ? BELLE_SIP_REFRESHER_REUSE_EXPIRES : expires);
}
}
int sal_op_unpublish(SalOp *op){
if (op->refresher){
const belle_sip_transaction_t *tr=(const belle_sip_transaction_t*) belle_sip_refresher_get_transaction(op->refresher);
belle_sip_request_t *last_req=belle_sip_transaction_get_request(tr);
belle_sip_message_set_body(BELLE_SIP_MESSAGE(last_req), NULL, 0);
belle_sip_refresher_refresh(op->refresher,0);
return 0;
}
return -1;
}

View file

@ -405,7 +405,7 @@ static void start_remote_ring(LinphoneCore *lc, LinphoneCall *call) {
if (call->audiostream)
audio_stream_unprepare_sound(call->audiostream);
if( lc->sound_conf.remote_ring ){
lc->ringstream=ring_start(lc->sound_conf.remote_ring,2000,ringcard);
lc->ringstream=ring_start(lc->factory, lc->sound_conf.remote_ring,2000,ringcard);
}
}
}
@ -1038,10 +1038,11 @@ static void register_failure(SalOp *op){
} else {
linphone_proxy_config_set_state(cfg,LinphoneRegistrationFailed,details);
}
if (cfg->publish_op){
if (cfg->long_term_event){
/*prevent publish to be sent now until registration gets successful*/
sal_op_release(cfg->publish_op);
cfg->publish_op=NULL;
linphone_event_terminate(cfg->long_term_event);
linphone_event_unref(cfg->long_term_event);
cfg->long_term_event=NULL;
cfg->send_publish=cfg->publish;
}
}
@ -1137,7 +1138,13 @@ static void parse_presence_requested(SalOp *op, const char *content_type, const
}
static void convert_presence_to_xml_requested(SalOp *op, SalPresenceModel *presence, const char *contact, char **content) {
linphone_notify_convert_presence_to_xml(op, presence, contact, content);
/*for backward compatibility because still used by notify. No loguer used for publish*/
if(linphone_presence_model_get_presentity((LinphonePresenceModel*)presence) == NULL) {
LinphoneAddress * presentity = linphone_address_new(contact);
linphone_presence_model_set_presentity((LinphonePresenceModel*)presence, presentity);
}
*content = linphone_presence_model_to_xml((LinphonePresenceModel*)presence);
}
static void notify_presence(SalOp *op, SalSubscribeStatus ss, SalPresenceModel *model, const char *msg){
@ -1303,7 +1310,7 @@ static void subscribe_response(SalOp *op, SalSubscribeStatus status){
}else if (status==SalSubscribePending){
linphone_event_set_state(lev,LinphoneSubscriptionPending);
}else{
if (lev->subscription_state==LinphoneSubscriptionActive && ei->reason==SalReasonIOError){
if (lev->subscription_state==LinphoneSubscriptionActive && (ei->reason==SalReasonIOError || ei->reason == SalReasonNoMatch)){
linphone_event_set_state(lev,LinphoneSubscriptionOutgoingProgress);
}
else linphone_event_set_state(lev,LinphoneSubscriptionError);

View file

@ -32,31 +32,39 @@
namespace Linphone {
class Participant {
public:
Participant(LinphoneCall *call);
Participant(const Participant &src);
~Participant();
bool operator==(const Participant &src) const;
const LinphoneAddress *getUri() const {return m_uri;}
LinphoneCall *getCall() const {return m_call;}
void setCall(LinphoneCall *call) {m_call = call;}
private:
LinphoneAddress *m_uri;
LinphoneCall *m_call;
};
class Conference {
public:
class Participant {
public:
Participant(LinphoneCall *call);
Participant(const Participant &src);
~Participant();
bool operator==(const Participant &src) const;
const LinphoneAddress *getUri() const {return m_uri;}
LinphoneCall *getCall() const {return m_call;}
void setCall(LinphoneCall *call) {m_call = call;}
private:
LinphoneAddress *m_uri;
LinphoneCall *m_call;
};
class Params {
public:
Params(const LinphoneCore *core = NULL);
void enableVideo(bool enable) {m_enableVideo = enable;}
bool videoRequested() const {return m_enableVideo;}
void setStateChangedCallback(LinphoneConferenceStateChangedCb cb, void *user_data) {
m_state_changed_cb=cb;
m_user_data=user_data;
}
private:
bool m_enableVideo;
LinphoneConferenceStateChangedCb m_state_changed_cb;
void *m_user_data;
friend class Conference;
};
Conference(LinphoneCore *core, const Params *params = NULL);
@ -88,14 +96,19 @@ public:
virtual void onCallStreamStopping(LinphoneCall *call) {};
virtual void onCallTerminating(LinphoneCall *call) {};
LinphoneConferenceState getState() const {return m_state;}
static const char *stateToString(LinphoneConferenceState state);
protected:
const Participant *findParticipant(const LinphoneAddress* uri) const;
void setState(LinphoneConferenceState state);
LinphoneCore *m_core;
AudioStream *m_localParticipantStream;
bool m_isMuted;
std::list<Participant> m_participants;
Params m_currentParams;
LinphoneConferenceState m_state;
};
class LocalConference: public Conference {
@ -153,12 +166,9 @@ public:
virtual int stopRecording() {return 0;}
private:
enum State {
NotConnectedToFocus,
ConnectingToFocus,
ConnectedToFocus,
};
static const char *stateToString(State state);
bool focusIsReady() const;
bool transferToFocus(LinphoneCall *call);
void reset();
void onFocusCallSateChanged(LinphoneCallState state);
void onPendingCallStateChanged(LinphoneCall *call, LinphoneCallState state);
@ -170,10 +180,10 @@ private:
const char *m_focusAddr;
char *m_focusContact;
LinphoneCall *m_focusCall;
State m_state;
LinphoneCoreVTable *m_vtable;
MSList *m_pendingCalls;
MSList *m_transferingCalls;
bool m_isTerminating;
};
};
@ -183,22 +193,22 @@ using namespace Linphone;
using namespace std;
Participant::Participant(LinphoneCall *call) {
Conference::Participant::Participant(LinphoneCall *call) {
m_uri = linphone_address_clone(linphone_call_get_remote_address(call));
m_call = linphone_call_ref(call);
}
Participant::Participant(const Participant &src) {
Conference::Participant::Participant(const Participant &src) {
m_uri = linphone_address_clone(src.m_uri);
m_call = src.m_call ? linphone_call_ref(src.m_call) : NULL;
}
Participant::~Participant() {
Conference::Participant::~Participant() {
linphone_address_unref(m_uri);
if(m_call) linphone_call_unref(m_call);
}
bool Participant::operator==(const Participant &src) const {
bool Conference::Participant::operator==(const Participant &src) const {
return linphone_address_equal(m_uri, src.m_uri);
}
@ -216,7 +226,9 @@ Conference::Params::Params(const LinphoneCore *core): m_enableVideo(false) {
Conference::Conference(LinphoneCore *core, const Conference::Params *params):
m_core(core),
m_localParticipantStream(NULL),
m_isMuted(false) {
m_isMuted(false),
m_currentParams(),
m_state(LinphoneConferenceStopped) {
if(params) m_currentParams = *params;
}
@ -275,7 +287,19 @@ float Conference::getInputVolume() const {
return LINPHONE_VOLUME_DB_LOWEST;
}
const Participant *Conference::findParticipant(const LinphoneAddress *uri) const {
const char *Conference::stateToString(LinphoneConferenceState state) {
switch(state) {
case LinphoneConferenceStopped: return "Stopped";
case LinphoneConferenceStarting: return "Starting";
case LinphoneConferenceReady: return "Ready";
case LinphoneConferenceStartingFailed: return "Startig failed";
default: return "Invalid state";
}
}
const Conference::Participant *Conference::findParticipant(const LinphoneAddress *uri) const {
list<Participant>::const_iterator it = m_participants.begin();
while(it!=m_participants.end()) {
if(linphone_address_equal(uri, it->getUri())) break;
@ -285,6 +309,17 @@ const Participant *Conference::findParticipant(const LinphoneAddress *uri) const
else return &*it;
}
void Conference::setState(LinphoneConferenceState state) {
if(m_state != state) {
ms_message("Switching conference [%p] into state '%s'", this, stateToString(state));
m_state = state;
if(m_currentParams.m_state_changed_cb) {
m_currentParams.m_state_changed_cb((LinphoneConference *)this, state, m_currentParams.m_user_data);
}
}
}
LocalConference::LocalConference(LinphoneCore *core, const Conference::Params *params):
@ -294,9 +329,11 @@ LocalConference::LocalConference(LinphoneCore *core, const Conference::Params *p
m_recordEndpoint(NULL),
m_localDummyProfile(NULL),
m_terminated(FALSE) {
MSAudioConferenceParams ms_conf_params;
ms_conf_params.samplerate = lp_config_get_int(m_core->config, "sound","conference_rate",16000);
m_conf=ms_audio_conference_new(&ms_conf_params);
m_conf=ms_audio_conference_new(&ms_conf_params, core->factory);
m_state=LinphoneConferenceReady;
}
LocalConference::~LocalConference() {
@ -315,7 +352,7 @@ RtpProfile *LocalConference::sMakeDummyProfile(int samplerate){
void LocalConference::addLocalEndpoint() {
/*create a dummy audiostream in order to extract the local part of it */
/* network address and ports have no meaning and are not used here. */
AudioStream *st=audio_stream_new(65000,65001,FALSE);
AudioStream *st=audio_stream_new(m_core->factory, 65000,65001,FALSE);
MSSndCard *playcard=m_core->sound_conf.lsd_card ?
m_core->sound_conf.lsd_card : m_core->sound_conf.play_sndcard;
MSSndCard *captcard=m_core->sound_conf.capt_sndcard;
@ -527,7 +564,7 @@ int LocalConference::startRecording(const char *path) {
return -1;
}
if (m_recordEndpoint==NULL){
m_recordEndpoint=ms_audio_endpoint_new_recorder();
m_recordEndpoint=ms_audio_endpoint_new_recorder(m_core->factory);
ms_audio_conference_add_member(m_conf,m_recordEndpoint);
}
ms_audio_recorder_endpoint_start(m_recordEndpoint,path);
@ -585,10 +622,10 @@ RemoteConference::RemoteConference(LinphoneCore *core, const Conference::Params
m_focusAddr(NULL),
m_focusContact(NULL),
m_focusCall(NULL),
m_state(NotConnectedToFocus),
m_vtable(NULL),
m_pendingCalls(NULL),
m_transferingCalls(NULL) {
m_transferingCalls(NULL),
m_isTerminating(false) {
m_focusAddr = lp_config_get_string(m_core->config, "misc", "conference_focus_addr", "");
m_vtable = linphone_core_v_table_new();
m_vtable->call_state_changed = callStateChangedCb;
@ -598,7 +635,7 @@ RemoteConference::RemoteConference(LinphoneCore *core, const Conference::Params
}
RemoteConference::~RemoteConference() {
if(m_state == ConnectedToFocus) terminate();
terminate();
linphone_core_remove_listener(m_core, m_vtable);
linphone_core_v_table_destroy(m_vtable);
}
@ -608,34 +645,38 @@ int RemoteConference::addParticipant(LinphoneCall *call) {
LinphoneCallParams *params;
switch(m_state) {
case NotConnectedToFocus:
case LinphoneConferenceStopped:
case LinphoneConferenceStartingFailed:
Conference::addParticipant(call);
ms_message("Calling the conference focus (%s)", m_focusAddr);
addr = linphone_address_new(m_focusAddr);
if(addr) {
params = linphone_core_create_call_params(m_core, NULL);
linphone_call_params_enable_video(params, m_currentParams.videoRequested());
m_focusCall = linphone_call_ref(linphone_core_invite_address_with_params(m_core, addr, params));
m_focusCall = linphone_core_invite_address_with_params(m_core, addr, params);
m_focusCall->conf_ref = (LinphoneConference *)this;
m_localParticipantStream = m_focusCall->audiostream;
m_pendingCalls = ms_list_append(m_pendingCalls, call);
m_state = ConnectingToFocus;
LinphoneCallLog *callLog = linphone_call_get_call_log(m_focusCall);
callLog->was_conference = TRUE;
linphone_address_unref(addr);
linphone_call_params_unref(params);
setState(LinphoneConferenceStarting);
return 0;
} else return -1;
case ConnectingToFocus:
case LinphoneConferenceStarting:
Conference::addParticipant(call);
m_pendingCalls = ms_list_append(m_pendingCalls, call);
if(focusIsReady()) {
transferToFocus(call);
} else {
m_pendingCalls = ms_list_append(m_pendingCalls, call);
}
return 0;
case ConnectedToFocus:
case LinphoneConferenceReady:
Conference::addParticipant(call);
m_transferingCalls = ms_list_append(m_transferingCalls, call);
linphone_core_transfer_call(m_core, call, m_focusContact);
transferToFocus(call);
return 0;
default:
@ -649,15 +690,21 @@ int RemoteConference::removeParticipant(const LinphoneAddress *uri) {
int res;
switch(m_state) {
case ConnectedToFocus:
case LinphoneConferenceReady:
tmp = linphone_address_as_string_uri_only(uri);
refer_to = ms_strdup_printf("%s;method=BYE", tmp);
res = sal_call_refer(m_focusCall->op, refer_to);
ms_free(tmp);
ms_free(refer_to);
if(res == 0) return Conference::removeParticipant(uri);
else return -1;
if(res == 0) {
return Conference::removeParticipant(uri);
} else {
char *tmp = linphone_address_as_string(uri);
ms_error("Conference: could not remove participant '%s': REFER with BYE has failed", tmp);
ms_free(tmp);
return -1;
}
default:
ms_error("Cannot remove %s from conference: Bad conference state (%s)", linphone_address_as_string(uri), stateToString(m_state));
@ -666,20 +713,27 @@ int RemoteConference::removeParticipant(const LinphoneAddress *uri) {
}
int RemoteConference::terminate() {
m_isTerminating = true;
switch(m_state) {
case ConnectingToFocus:
case ConnectedToFocus:
case LinphoneConferenceReady:
case LinphoneConferenceStarting:
linphone_core_terminate_call(m_core, m_focusCall);
reset();
Conference::terminate();
m_isTerminating = false;
setState(LinphoneConferenceStopped);
break;
default:
m_isTerminating = false;
break;
}
Conference::terminate();
return 0;
}
int RemoteConference::enter() {
if(m_state != ConnectedToFocus) {
if(m_state != LinphoneConferenceReady) {
ms_error("Could not enter in the conference: bad conference state (%s)", stateToString(m_state));
return -1;
}
@ -697,7 +751,7 @@ int RemoteConference::enter() {
}
int RemoteConference::leave() {
if(m_state != ConnectedToFocus) {
if(m_state != LinphoneConferenceReady) {
ms_error("Could not leave the conference: bad conference state (%s)", stateToString(m_state));
return -1;
}
@ -715,26 +769,45 @@ int RemoteConference::leave() {
}
bool RemoteConference::isIn() const {
if(m_state != ConnectedToFocus) return false;
if(m_state != LinphoneConferenceReady) return false;
LinphoneCallState callState = linphone_call_get_state(m_focusCall);
return callState == LinphoneCallStreamsRunning;
}
const char *RemoteConference::stateToString(RemoteConference::State state) {
switch(state) {
case NotConnectedToFocus: return "NotConnectedToFocus";
case ConnectingToFocus: return "ConnectingToFocus";
case ConnectedToFocus: return "ConnectedToFocus";
default: return "Unknown";
bool RemoteConference::focusIsReady() const {
LinphoneCallState focusState;
if(m_focusCall == NULL) return false;
focusState = linphone_call_get_state(m_focusCall);
return focusState == LinphoneCallStreamsRunning || focusState == LinphoneCallPaused;
}
bool RemoteConference::transferToFocus(LinphoneCall *call) {
if(linphone_core_transfer_call(m_core, call, m_focusContact) == 0) {
m_transferingCalls = ms_list_append(m_transferingCalls, call);
return true;
} else {
ms_error("Conference: could not transfer call [%p] to %s", call, m_focusContact);
return false;
}
}
void RemoteConference::reset() {
m_localParticipantStream = NULL;
m_focusAddr = NULL;
if(m_focusContact) {
ms_free(m_focusContact);
m_focusContact = NULL;
}
m_focusCall = NULL;
m_pendingCalls = ms_list_free(m_pendingCalls);
m_transferingCalls = ms_list_free(m_transferingCalls);
}
void RemoteConference::onFocusCallSateChanged(LinphoneCallState state) {
MSList *it;
switch (state) {
case LinphoneCallConnected:
m_state = ConnectedToFocus;
m_focusContact = ms_strdup(linphone_call_get_remote_contact(m_focusCall));
it = m_pendingCalls;
while (it) {
@ -744,27 +817,21 @@ void RemoteConference::onFocusCallSateChanged(LinphoneCallState state) {
MSList *current_elem = it;
it = it->next;
m_pendingCalls = ms_list_remove_link(m_pendingCalls, current_elem);
m_transferingCalls = ms_list_append(m_transferingCalls, pendingCall);
linphone_core_transfer_call(m_core, pendingCall, m_focusContact);
transferToFocus(pendingCall);
} else {
it = it->next;
}
}
setState(LinphoneConferenceReady);
break;
case LinphoneCallError:
reset();
setState(LinphoneConferenceStartingFailed);
break;
case LinphoneCallEnd:
m_state = NotConnectedToFocus;
linphone_call_unref(m_focusCall);
m_focusCall = NULL;
m_localParticipantStream = NULL;
if(m_focusContact) {
ms_free(m_focusContact);
m_focusContact = NULL;
}
m_pendingCalls = ms_list_free(m_pendingCalls);
m_transferingCalls = ms_list_free(m_transferingCalls);
Conference::terminate();
if(!m_isTerminating) terminate();
break;
default: break;
@ -775,7 +842,7 @@ void RemoteConference::onPendingCallStateChanged(LinphoneCall *call, LinphoneCal
switch(state) {
case LinphoneCallStreamsRunning:
case LinphoneCallPaused:
if(m_state == ConnectedToFocus) {
if(m_state == LinphoneConferenceReady) {
m_pendingCalls = ms_list_remove(m_pendingCalls, call);
m_transferingCalls = ms_list_append(m_transferingCalls, call);
linphone_core_transfer_call(m_core, call, m_focusContact);
@ -825,6 +892,10 @@ void RemoteConference::transferStateChanged(LinphoneCore *lc, LinphoneCall *tran
const char *linphone_conference_state_to_string(LinphoneConferenceState state) {
return Conference::stateToString(state);
}
LinphoneConferenceParams *linphone_conference_params_new(const LinphoneCore *core) {
return (LinphoneConferenceParams *)new Conference::Params(core);
}
@ -845,6 +916,10 @@ bool_t linphone_conference_params_video_requested(const LinphoneConferenceParams
return ((Conference::Params *)params)->videoRequested();
}
void linphone_conference_params_set_state_changed_callback(LinphoneConferenceParams *params, LinphoneConferenceStateChangedCb cb, void *user_data) {
((Conference::Params *)params)->setStateChangedCallback(cb, user_data);
}
LinphoneConference *linphone_local_conference_new(LinphoneCore *core) {
@ -867,6 +942,10 @@ void linphone_conference_free(LinphoneConference *obj) {
delete (Conference *)obj;
}
LinphoneConferenceState linphone_conference_get_state(const LinphoneConference *obj) {
return ((Conference *)obj)->getState();
}
int linphone_conference_add_participant(LinphoneConference *obj, LinphoneCall *call) {
return ((Conference *)obj)->addParticipant(call);
}
@ -916,9 +995,9 @@ int linphone_conference_get_size(const LinphoneConference *obj) {
}
MSList *linphone_conference_get_participants(const LinphoneConference *obj) {
const list<Participant> &participants = ((Conference *)obj)->getParticipants();
const list<Conference::Participant> &participants = ((Conference *)obj)->getParticipants();
MSList *participants_list = NULL;
for(list<Participant>::const_iterator it=participants.begin();it!=participants.end();it++) {
for(list<Conference::Participant>::const_iterator it=participants.begin();it!=participants.end();it++) {
LinphoneAddress *uri = linphone_address_clone(it->getUri());
participants_list = ms_list_append(participants_list, uri);
}

View file

@ -37,11 +37,18 @@ extern "C" {
* @{
*/
/**
* LinphoneConference class
*/
typedef struct _LinphoneConference LinphoneConference;
/**
* Parameters for initialization of conferences
*/
typedef struct _LinphoneCorferenceParams LinphoneConferenceParams;
/**
* Create a #LinphoneConferenceParams with default parameters set.
* @param core #LinphoneCore to use to find out the default parameters. Can be NULL.
@ -73,10 +80,7 @@ LINPHONE_PUBLIC bool_t linphone_conference_params_video_requested(const Linphone
/**
* LinphoneConference class
*/
typedef struct _LinphoneConference LinphoneConference;
/**
* Remove a participant from a conference

View file

@ -37,11 +37,48 @@ typedef enum {
LinphoneConferenceClassRemote
} LinphoneConferenceClass;
/**
* List of states used by #LinphoneConference
*/
typedef enum {
LinphoneConferenceStopped, /*< Initial state */
LinphoneConferenceStarting, /*< A participant has been added but the conference is not running yet */
LinphoneConferenceReady, /*< The conference is running */
LinphoneConferenceStartingFailed /*< A participant has been added but the initialization of the conference has failed */
} LinphoneConferenceState;
/**
* Type of the funtion to pass as callback to linphone_conference_params_set_state_changed_callback()
* @param conference The conference instance which the state has changed
* @param new_state The new state of the conferenece
* @param user_data Pointer pass to user_data while linphone_conference_params_set_state_changed_callback() was being called
*/
typedef void (*LinphoneConferenceStateChangedCb)(LinphoneConference *conference, LinphoneConferenceState new_state, void *user_data);
/**
* A function to converte a #LinphoneConferenceState into a string
*/
const char *linphone_conference_state_to_string(LinphoneConferenceState state);
/**
* Set a callback which will be called when the state of the conferenec is switching
* @param params A #LinphoneConferenceParams object
* @param cb The callback to call
* @param user_data Pointer to pass to the user_data parameter of #LinphoneConferenceStateChangedCb
*/
void linphone_conference_params_set_state_changed_callback(LinphoneConferenceParams *params, LinphoneConferenceStateChangedCb cb, void *user_data);
LinphoneConference *linphone_local_conference_new(LinphoneCore *core);
LinphoneConference *linphone_local_conference_new_with_params(LinphoneCore *core, const LinphoneConferenceParams *params);
LinphoneConference *linphone_remote_conference_new(LinphoneCore *core);
LinphoneConference *linphone_remote_conference_new_with_params(LinphoneCore *core, const LinphoneConferenceParams *params);
void linphone_conference_free(LinphoneConference *obj);
/**
* Get the state of a conference
*/
LinphoneConferenceState linphone_conference_get_state(const LinphoneConference *obj);
int linphone_conference_add_participant(LinphoneConference *obj, LinphoneCall *call);
int linphone_conference_remove_participant_with_call(LinphoneConference *obj, LinphoneCall *call);

View file

@ -41,25 +41,25 @@ static void ecc_init_filters(EcCalibrator *ecc){
ms_filter_call_method(ecc->sndread,MS_FILTER_GET_SAMPLE_RATE,&rate);
ms_filter_call_method(ecc->sndread,MS_FILTER_SET_NCHANNELS,&ecc_channels);
ms_filter_call_method(ecc->sndread,MS_FILTER_GET_NCHANNELS,&channels);
ecc->read_resampler=ms_filter_new(MS_RESAMPLE_ID);
ecc->read_resampler=ms_factory_create_filter(ecc->factory, MS_RESAMPLE_ID);
ms_filter_call_method(ecc->read_resampler,MS_FILTER_SET_SAMPLE_RATE,&rate);
ms_filter_call_method(ecc->read_resampler,MS_FILTER_SET_OUTPUT_SAMPLE_RATE,&ecc->rate);
ms_filter_call_method(ecc->read_resampler,MS_FILTER_SET_NCHANNELS,&ecc_channels);
ms_filter_call_method(ecc->read_resampler,MS_FILTER_SET_OUTPUT_NCHANNELS,&channels);
ecc->det=ms_filter_new(MS_TONE_DETECTOR_ID);
ecc->det=ms_factory_create_filter(ecc->factory, MS_TONE_DETECTOR_ID);
ms_filter_call_method(ecc->det,MS_FILTER_SET_SAMPLE_RATE,&ecc->rate);
ecc->rec=ms_filter_new(MS_VOID_SINK_ID);
ecc->rec=ms_factory_create_filter(ecc->factory, MS_VOID_SINK_ID);
ms_filter_link(ecc->sndread,0,ecc->read_resampler,0);
ms_filter_link(ecc->read_resampler,0,ecc->det,0);
ms_filter_link(ecc->det,0,ecc->rec,0);
ecc->play=ms_filter_new(MS_VOID_SOURCE_ID);
ecc->gen=ms_filter_new(MS_DTMF_GEN_ID);
ecc->play=ms_factory_create_filter(ecc->factory, MS_VOID_SOURCE_ID);
ecc->gen=ms_factory_create_filter(ecc->factory, MS_DTMF_GEN_ID);
ms_filter_call_method(ecc->gen,MS_FILTER_SET_SAMPLE_RATE,&ecc->rate);
ecc->write_resampler=ms_filter_new(MS_RESAMPLE_ID);
ecc->write_resampler=ms_factory_create_filter(ecc->factory, MS_RESAMPLE_ID);
ecc->sndwrite=ms_snd_card_create_writer(ecc->play_card);
ms_filter_call_method(ecc->sndwrite,MS_FILTER_SET_SAMPLE_RATE,&ecc->rate);
@ -281,7 +281,7 @@ static void * ecc_thread(void *p){
return NULL;
}
EcCalibrator * ec_calibrator_new(MSSndCard *play_card, MSSndCard *capt_card, unsigned int rate, LinphoneEcCalibrationCallback cb,
EcCalibrator * ec_calibrator_new(MSFactory *factory, MSSndCard *play_card, MSSndCard *capt_card, unsigned int rate, LinphoneEcCalibrationCallback cb,
LinphoneEcCalibrationAudioInit audio_init_cb, LinphoneEcCalibrationAudioUninit audio_uninit_cb, void *cb_data){
EcCalibrator *ecc=ms_new0(EcCalibrator,1);
@ -292,6 +292,7 @@ EcCalibrator * ec_calibrator_new(MSSndCard *play_card, MSSndCard *capt_card, uns
ecc->audio_uninit_cb=audio_uninit_cb;
ecc->capt_card=capt_card;
ecc->play_card=play_card;
ecc->factory=factory;
return ecc;
}
@ -317,7 +318,7 @@ int linphone_core_start_echo_calibration(LinphoneCore *lc, LinphoneEcCalibration
return -1;
}
rate = lp_config_get_int(lc->config,"sound","echo_cancellation_rate",8000);
lc->ecc=ec_calibrator_new(lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard,rate,cb,audio_init_cb,audio_uninit_cb,cb_data);
lc->ecc=ec_calibrator_new(lc->factory, lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard,rate,cb,audio_init_cb,audio_uninit_cb,cb_data);
lc->ecc->play_cool_tones = lp_config_get_int(lc->config, "sound", "ec_calibrator_cool_tones", 0);
ec_calibrator_start(lc->ecc);
return 0;

View file

@ -201,7 +201,7 @@ int linphone_event_update_subscribe(LinphoneEvent *lev, const LinphoneContent *b
}
int linphone_event_refresh_subscribe(LinphoneEvent *lev) {
return sal_subscribe_refresh(lev->op);
return sal_op_refresh(lev->op);
}
int linphone_event_accept_subscription(LinphoneEvent *lev){
@ -291,6 +291,16 @@ int linphone_event_update_publish(LinphoneEvent* lev, const LinphoneContent* bod
return linphone_event_send_publish(lev,body);
}
int linphone_event_refresh_publish(LinphoneEvent *lev) {
return sal_op_refresh(lev->op);
}
void linphone_event_pause_publish(LinphoneEvent *lev) {
if (lev->op) sal_op_stop_refreshing(lev->op);
}
void linphone_event_unpublish(LinphoneEvent *lev) {
lev->terminating = TRUE; /* needed to get clear event*/
if (lev->op) sal_op_unpublish(lev->op);
}
void linphone_event_set_user_data(LinphoneEvent *ev, void *up){
ev->userdata=up;
}
@ -320,7 +330,7 @@ void linphone_event_terminate(LinphoneEvent *lev){
if (lev->publish_state!=LinphonePublishNone){
if (lev->publish_state==LinphonePublishOk && lev->expires!=-1){
sal_publish(lev->op,NULL,NULL,NULL,0,NULL);
}else sal_op_stop_refreshing(lev->op);
}else sal_op_unpublish(lev->op);
linphone_event_set_publish_state(lev,LinphonePublishCleared);
return;
}

View file

@ -208,6 +208,21 @@ LINPHONE_PUBLIC int linphone_event_send_publish(LinphoneEvent *lev, const Linpho
**/
LINPHONE_PUBLIC int linphone_event_update_publish(LinphoneEvent *lev, const LinphoneContent *body);
/**
* Refresh an outgoing publish keeping the same body.
* @param lev LinphoneEvent object.
* @return 0 if successful, -1 otherwise.
*/
LINPHONE_PUBLIC int linphone_event_refresh_publish(LinphoneEvent *lev);
/**
* Prevent an event from refreshing its publish.
* This is useful to let registrations to expire naturally (or) when the application wants to keep control on when
* refreshes are sent.
* The refreshing operations can be resumed with linphone_proxy_config_refresh_register().
* @param[in] cfg #LinphoneEvent object.
**/
LINPHONE_PUBLIC void linphone_event_pause_publish(LinphoneEvent *lev);
/**
* Return reason code (in case of error state reached).

View file

@ -547,13 +547,25 @@ void linphone_friend_done(LinphoneFriend *fr) {
}
}
#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4)
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
LinphoneFriend * linphone_core_create_friend(LinphoneCore *lc) {
return linphone_friend_new();
LinphoneFriend * lf = linphone_friend_new();
lf->lc = lc;
return lf;
}
LinphoneFriend * linphone_core_create_friend_with_address(LinphoneCore *lc, const char *address) {
return linphone_friend_new_with_address(address);
LinphoneFriend * lf = linphone_friend_new_with_address(address);
if (lf)
lf->lc = lc;
return lf;
}
#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4)
#pragma GCC diagnostic pop
#endif
void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) {
if (linphone_friend_list_add_friend(linphone_core_get_default_friend_list(lc), lf) != LinphoneFriendListOK) return;

View file

@ -723,7 +723,7 @@ void linphone_friend_list_subscription_state_changed(LinphoneCore *lc, LinphoneE
, lev
, list);
if (state == LinphoneSubscriptionOutgoingProgress) {
if (state == LinphoneSubscriptionOutgoingProgress && linphone_event_get_reason(lev) == LinphoneReasonNoMatch) {
ms_message("Resseting version count for friend list [%p]",list);
list->expected_notification_version = 0;
}

View file

@ -48,9 +48,9 @@ static void _linphone_call_set_next_video_frame_decoded_trigger(LinphoneCall *ca
void linphone_call_handle_stream_events(LinphoneCall *call, int stream_index);
MSWebCam *get_nowebcam_device(){
MSWebCam *get_nowebcam_device(MSFactory* f){
#ifdef VIDEO_ENABLED
return ms_web_cam_manager_get_cam(ms_web_cam_manager_get(),"StaticImage: Static picture");
return ms_web_cam_manager_get_cam(ms_factory_get_web_cam_manager(f),"StaticImage: Static picture");
#else
return NULL;
#endif
@ -982,9 +982,9 @@ static void discover_mtu(LinphoneCore *lc, const char *remote){
/*attempt to discover mtu*/
mtu=ms_discover_mtu(remote);
if (mtu>0){
ms_set_mtu(mtu);
ms_factory_set_mtu(lc->factory, mtu);
ms_message("Discovered mtu is %i, RTP payload max size is %i",
mtu, ms_get_payload_max_size());
mtu, ms_factory_get_payload_max_size(lc->factory));
}
}
}
@ -2340,7 +2340,7 @@ void linphone_call_init_audio_stream(LinphoneCall *call){
if (remotedesc)
stream_desc = sal_media_description_find_best_stream(remotedesc, SalAudio);
call->audiostream=audiostream=audio_stream_new2(linphone_call_get_bind_ip_for_stream(call,call->main_audio_stream_index),
call->audiostream=audiostream=audio_stream_new2(lc->factory, linphone_call_get_bind_ip_for_stream(call,call->main_audio_stream_index),
multicast_role == SalMulticastReceiver ? stream_desc->rtp_port : call->media_ports[call->main_audio_stream_index].rtp_port,
multicast_role == SalMulticastReceiver ? 0 /*disabled for now*/ : call->media_ports[call->main_audio_stream_index].rtcp_port);
if (multicast_role == SalMulticastReceiver)
@ -2353,7 +2353,8 @@ void linphone_call_init_audio_stream(LinphoneCall *call){
setup_dtls_params(call, &audiostream->ms);
media_stream_reclaim_sessions(&audiostream->ms, &call->sessions[call->main_audio_stream_index]);
}else{
call->audiostream=audio_stream_new_with_sessions(&call->sessions[call->main_audio_stream_index]);
call->audiostream=audio_stream_new_with_sessions(lc->factory, &call->sessions[call->main_audio_stream_index]);
}
audiostream=call->audiostream;
if (call->media_ports[call->main_audio_stream_index].rtp_port==-1){
@ -2439,7 +2440,7 @@ void linphone_call_init_video_stream(LinphoneCall *call){
if (remotedesc)
stream_desc = sal_media_description_find_best_stream(remotedesc, SalVideo);
call->videostream=video_stream_new2(linphone_call_get_bind_ip_for_stream(call,call->main_video_stream_index),
call->videostream=video_stream_new2(lc->factory, linphone_call_get_bind_ip_for_stream(call,call->main_video_stream_index),
multicast_role == SalMulticastReceiver ? stream_desc->rtp_port : call->media_ports[call->main_video_stream_index].rtp_port,
multicast_role == SalMulticastReceiver ? 0 /*disabled for now*/ : call->media_ports[call->main_video_stream_index].rtcp_port);
if (multicast_role == SalMulticastReceiver)
@ -2452,7 +2453,7 @@ void linphone_call_init_video_stream(LinphoneCall *call){
setup_dtls_params(call, &call->videostream->ms);
media_stream_reclaim_sessions(&call->videostream->ms, &call->sessions[call->main_video_stream_index]);
}else{
call->videostream=video_stream_new_with_sessions(&call->sessions[call->main_video_stream_index]);
call->videostream=video_stream_new_with_sessions(lc->factory, &call->sessions[call->main_video_stream_index]);
}
if (call->media_ports[call->main_video_stream_index].rtp_port==-1){
@ -2505,7 +2506,7 @@ void linphone_call_init_text_stream(LinphoneCall *call){
if (call->op) remotedesc = sal_call_get_remote_media_description(call->op);
if (remotedesc) stream_desc = sal_media_description_find_best_stream(remotedesc, SalText);
call->textstream = textstream = text_stream_new2(linphone_call_get_bind_ip_for_stream(call,call->main_text_stream_index),
call->textstream = textstream = text_stream_new2(lc->factory, linphone_call_get_bind_ip_for_stream(call,call->main_text_stream_index),
multicast_role == SalMulticastReceiver ? stream_desc->rtp_port : call->media_ports[call->main_text_stream_index].rtp_port,
multicast_role == SalMulticastReceiver ? 0 /*disabled for now*/ : call->media_ports[call->main_text_stream_index].rtcp_port);
if (multicast_role == SalMulticastReceiver)
@ -2517,7 +2518,7 @@ void linphone_call_init_text_stream(LinphoneCall *call){
setup_dtls_params(call, &textstream->ms);
media_stream_reclaim_sessions(&textstream->ms, &call->sessions[call->main_text_stream_index]);
} else {
call->textstream = text_stream_new_with_sessions(&call->sessions[call->main_text_stream_index]);
call->textstream = text_stream_new_with_sessions(lc->factory, &call->sessions[call->main_text_stream_index]);
}
textstream = call->textstream;
if (call->media_ports[call->main_text_stream_index].rtp_port == -1) {
@ -2942,7 +2943,7 @@ static RtpSession * create_audio_rtp_io_session(LinphoneCall *call) {
if (pt != NULL) {
call->rtp_io_audio_profile = rtp_profile_new("RTP IO audio profile");
rtp_profile_set_payload(call->rtp_io_audio_profile, ptnum, payload_type_clone(pt));
rtp_session = ms_create_duplex_rtp_session(local_ip, local_port, -1);
rtp_session = ms_create_duplex_rtp_session(local_ip, local_port, -1, ms_factory_get_mtu(lc->factory));
rtp_session_set_profile(rtp_session, call->rtp_io_audio_profile);
rtp_session_set_remote_addr_and_port(rtp_session, remote_ip, remote_port, -1);
rtp_session_enable_rtcp(rtp_session, FALSE);
@ -3143,7 +3144,7 @@ static RtpSession * create_video_rtp_io_session(LinphoneCall *call) {
if (pt != NULL) {
call->rtp_io_video_profile = rtp_profile_new("RTP IO video profile");
rtp_profile_set_payload(call->rtp_io_video_profile, ptnum, payload_type_clone(pt));
rtp_session = ms_create_duplex_rtp_session(local_ip, local_port, -1);
rtp_session = ms_create_duplex_rtp_session(local_ip, local_port, -1, ms_factory_get_mtu(lc->factory));
rtp_session_set_profile(rtp_session, call->rtp_io_video_profile);
rtp_session_set_remote_addr_and_port(rtp_session, remote_ip, remote_port, -1);
rtp_session_enable_rtcp(rtp_session, FALSE);
@ -4772,7 +4773,7 @@ MSWebCam *linphone_call_get_video_device(const LinphoneCall *call) {
LinphoneCallState state = linphone_call_get_state(call);
bool_t paused = (state == LinphoneCallPausing) || (state == LinphoneCallPaused);
if (paused || call->all_muted || (call->camera_enabled == FALSE))
return get_nowebcam_device();
return get_nowebcam_device(call->core->factory);
else
return call->core->video_conf.device;
}

View file

@ -33,6 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <mediastreamer2/zrtp.h>
#include <mediastreamer2/dtls_srtp.h>
#include "mediastreamer2/mediastream.h"
#include "mediastreamer2/msfactory.h"
#include "mediastreamer2/mseventqueue.h"
#include "mediastreamer2/msvolume.h"
#include "mediastreamer2/msequalizer.h"
@ -778,7 +779,7 @@ static void build_sound_devices_table(LinphoneCore *lc){
const char **old;
int ndev;
int i;
const MSList *elem=ms_snd_card_manager_get_list(ms_snd_card_manager_get());
const MSList *elem=ms_snd_card_manager_get_list(ms_factory_get_snd_card_manager(lc->factory));
ndev=ms_list_size(elem);
devices=ms_malloc((ndev+1)*sizeof(const char *));
for (i=0;elem!=NULL;elem=elem->next,i++){
@ -823,13 +824,13 @@ static void sound_config_read(LinphoneCore *lc)
char s=*i;
*i='\0';
card=ms_alsa_card_new_custom(d+l,d+l);
ms_snd_card_manager_add_card(ms_snd_card_manager_get(),card);
ms_snd_card_manager_add_card(ms_factory_get_snd_card_manager(lc->factory),card);
*i=s;
l=i-d+1;
}
if(d[l]!='\0') {
card=ms_alsa_card_new_custom(d+l,d+l);
ms_snd_card_manager_add_card(ms_snd_card_manager_get(),card);
ms_snd_card_manager_add_card(ms_factory_get_snd_card_manager(lc->factory),card);
}
free(d);
}
@ -1157,7 +1158,8 @@ static bool_t linphone_core_codec_supported(LinphoneCore *lc, SalStreamType type
} else if (type == SalText) {
return TRUE;
}
return ms_filter_codec_supported(mime);
//ms_filter_codec_supported(mime)
return ms_factory_codec_supported (lc->factory, mime );
}
@ -1293,7 +1295,7 @@ static void build_video_devices_table(LinphoneCore *lc){
if (lc->video_conf.cams)
ms_free(lc->video_conf.cams);
/* retrieve all video devices */
elem=ms_web_cam_manager_get_list(ms_web_cam_manager_get());
elem=ms_web_cam_manager_get_list(ms_factory_get_web_cam_manager(lc->factory));
ndev=ms_list_size(elem);
devices=ms_malloc((ndev+1)*sizeof(const char *));
for (i=0;elem!=NULL;elem=elem->next,i++){
@ -1526,7 +1528,7 @@ static void misc_config_read(LinphoneCore *lc) {
}
static void linphone_core_start(LinphoneCore * lc) {
sip_setup_register_all();
sip_setup_register_all(lc->factory);
sound_config_read(lc);
net_config_read(lc);
rtp_config_read(lc);
@ -1587,7 +1589,8 @@ static void linphone_core_register_default_codecs(LinphoneCore *lc){
/*default enabled audio codecs, in order of preference*/
#if defined(__arm__) || defined(_M_ARM)
/*hack for opus, that needs to be disabed by default on ARM single processor, otherwise there is no cpu left for video processing*/
if (ms_get_cpu_count()==1) opus_enabled=FALSE;
//if (ms_get_cpu_count()==1) opus_enabled=FALSE;
if (ms_factory_get_cpu_count(lc->factory)==1) opus_enabled=FALSE;
#endif
linphone_core_register_payload_type(lc,&payload_type_opus,"useinbandfec=1",opus_enabled);
linphone_core_register_payload_type(lc,&payload_type_silk_wb,NULL,TRUE);
@ -1686,16 +1689,15 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
linphone_core_set_state(lc,LinphoneGlobalStartup,"Starting up");
ortp_init();
linphone_core_activate_log_serialization_if_needed();
ms_init();
lc->factory = ms_factory_new_with_voip();
linphone_core_register_default_codecs(lc);
linphone_core_register_offer_answer_providers(lc);
/* Get the mediastreamer2 event queue */
/* This allows to run event's callback in linphone_core_iterate() */
lc->msevq=ms_factory_create_event_queue(ms_factory_get_fallback());
lc->sal=sal_init();
lc->msevq=ms_factory_create_event_queue(lc->factory);
lc->sal=sal_init(lc->factory);
sal_set_http_proxy_host(lc->sal, linphone_core_get_http_proxy_host(lc));
sal_set_http_proxy_port(lc->sal, linphone_core_get_http_proxy_port(lc));
@ -3324,7 +3326,7 @@ void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){
if (lc->ringstream && lc->dmfs_playing_start_time!=0){
linphone_core_stop_dtmf_stream(lc);
}
linphone_ringtoneplayer_start(lc->ringtoneplayer, ringcard, lc->sound_conf.local_ring, 2000);
linphone_ringtoneplayer_start(lc->factory, lc->ringtoneplayer, ringcard, lc->sound_conf.local_ring, 2000);
}else{
/* else play a tone within the context of the current call */
call->ringing_beep=TRUE;
@ -4499,10 +4501,10 @@ void linphone_core_set_rec_level(LinphoneCore *lc, int level)
if (sndcard) ms_snd_card_set_level(sndcard,MS_SND_CARD_CAPTURE,level);
}
static MSSndCard *get_card_from_string_id(const char *devid, unsigned int cap){
static MSSndCard *get_card_from_string_id(const char *devid, unsigned int cap, MSFactory *f){
MSSndCard *sndcard=NULL;
if (devid!=NULL){
sndcard=ms_snd_card_manager_get_card(ms_snd_card_manager_get(),devid);
sndcard=ms_snd_card_manager_get_card(ms_factory_get_snd_card_manager(f),devid);
if (sndcard!=NULL &&
(ms_snd_card_get_capabilities(sndcard) & cap)==0 ){
ms_warning("%s card does not have the %s capability, ignoring.",
@ -4513,15 +4515,15 @@ static MSSndCard *get_card_from_string_id(const char *devid, unsigned int cap){
}
if (sndcard==NULL) {
if ((cap & MS_SND_CARD_CAP_CAPTURE) && (cap & MS_SND_CARD_CAP_PLAYBACK)){
sndcard=ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());
sndcard=ms_snd_card_manager_get_default_card(ms_factory_get_snd_card_manager(f));
}else if (cap & MS_SND_CARD_CAP_CAPTURE){
sndcard=ms_snd_card_manager_get_default_capture_card(ms_snd_card_manager_get());
sndcard=ms_snd_card_manager_get_default_capture_card(ms_factory_get_snd_card_manager(f));
}
else if (cap & MS_SND_CARD_CAP_PLAYBACK){
sndcard=ms_snd_card_manager_get_default_playback_card(ms_snd_card_manager_get());
sndcard=ms_snd_card_manager_get_default_playback_card(ms_factory_get_snd_card_manager(f));
}
if (sndcard==NULL){/*looks like a bug! take the first one !*/
const MSList *elem=ms_snd_card_manager_get_list(ms_snd_card_manager_get());
const MSList *elem=ms_snd_card_manager_get_list(ms_factory_get_snd_card_manager(f));
if (elem) sndcard=(MSSndCard*)elem->data;
}
}
@ -4538,7 +4540,7 @@ static MSSndCard *get_card_from_string_id(const char *devid, unsigned int cap){
**/
bool_t linphone_core_sound_device_can_capture(LinphoneCore *lc, const char *devid){
MSSndCard *sndcard;
sndcard=ms_snd_card_manager_get_card(ms_snd_card_manager_get(),devid);
sndcard=ms_snd_card_manager_get_card(ms_factory_get_snd_card_manager(lc->factory),devid);
if (sndcard!=NULL && (ms_snd_card_get_capabilities(sndcard) & MS_SND_CARD_CAP_CAPTURE)) return TRUE;
return FALSE;
}
@ -4552,7 +4554,7 @@ bool_t linphone_core_sound_device_can_capture(LinphoneCore *lc, const char *devi
**/
bool_t linphone_core_sound_device_can_playback(LinphoneCore *lc, const char *devid){
MSSndCard *sndcard;
sndcard=ms_snd_card_manager_get_card(ms_snd_card_manager_get(),devid);
sndcard=ms_snd_card_manager_get_card(ms_factory_get_snd_card_manager(lc->factory),devid);
if (sndcard!=NULL && (ms_snd_card_get_capabilities(sndcard) & MS_SND_CARD_CAP_PLAYBACK)) return TRUE;
return FALSE;
}
@ -4565,7 +4567,7 @@ bool_t linphone_core_sound_device_can_playback(LinphoneCore *lc, const char *dev
* @param devid the device name as returned by linphone_core_get_sound_devices()
**/
int linphone_core_set_ringer_device(LinphoneCore *lc, const char * devid){
MSSndCard *card=get_card_from_string_id(devid,MS_SND_CARD_CAP_PLAYBACK);
MSSndCard *card=get_card_from_string_id(devid,MS_SND_CARD_CAP_PLAYBACK, lc->factory);
lc->sound_conf.ring_sndcard=card;
if (card && linphone_core_ready(lc))
lp_config_set_string(lc->config,"sound","ringer_dev_id",ms_snd_card_get_string_id(card));
@ -4580,7 +4582,7 @@ int linphone_core_set_ringer_device(LinphoneCore *lc, const char * devid){
* @param devid the device name as returned by linphone_core_get_sound_devices()
**/
int linphone_core_set_playback_device(LinphoneCore *lc, const char * devid){
MSSndCard *card=get_card_from_string_id(devid,MS_SND_CARD_CAP_PLAYBACK);
MSSndCard *card=get_card_from_string_id(devid,MS_SND_CARD_CAP_PLAYBACK, lc->factory);
lc->sound_conf.play_sndcard=card;
if (card && linphone_core_ready(lc))
lp_config_set_string(lc->config,"sound","playback_dev_id",ms_snd_card_get_string_id(card));
@ -4595,7 +4597,7 @@ int linphone_core_set_playback_device(LinphoneCore *lc, const char * devid){
* @param devid the device name as returned by linphone_core_get_sound_devices()
**/
int linphone_core_set_capture_device(LinphoneCore *lc, const char * devid){
MSSndCard *card=get_card_from_string_id(devid,MS_SND_CARD_CAP_CAPTURE);
MSSndCard *card=get_card_from_string_id(devid,MS_SND_CARD_CAP_CAPTURE, lc->factory);
lc->sound_conf.capt_sndcard=card;
if (card && linphone_core_ready(lc))
lp_config_set_string(lc->config,"sound","capture_dev_id",ms_snd_card_get_string_id(card));
@ -4678,7 +4680,7 @@ void linphone_core_reload_sound_devices(LinphoneCore *lc){
if (capture != NULL) {
capture_copy = ms_strdup(capture);
}
ms_snd_card_manager_reload(ms_snd_card_manager_get());
ms_snd_card_manager_reload(ms_factory_get_snd_card_manager(lc->factory));
build_sound_devices_table(lc);
if (ringer_copy != NULL) {
linphone_core_set_ringer_device(lc, ringer_copy);
@ -4700,7 +4702,7 @@ void linphone_core_reload_video_devices(LinphoneCore *lc){
if (devid != NULL) {
devid_copy = ms_strdup(devid);
}
ms_web_cam_manager_reload(ms_web_cam_manager_get());
ms_web_cam_manager_reload(ms_factory_get_web_cam_manager(lc->factory));
build_video_devices_table(lc);
if (devid_copy != NULL) {
linphone_core_set_video_device(lc, devid_copy);
@ -4826,13 +4828,16 @@ int linphone_core_preview_ring(LinphoneCore *lc, const char *ring,LinphoneCoreCb
}
lc_callback_obj_init(&lc->preview_finished_cb,end_of_ringtone,userdata);
lc->preview_finished=0;
err = linphone_ringtoneplayer_start_with_cb(lc->ringtoneplayer, ringcard, ring, -1, notify_end_of_ringtone,(void *)lc);
err = linphone_ringtoneplayer_start_with_cb(lc->factory, lc->ringtoneplayer, ringcard, ring, -1, notify_end_of_ringtone,(void *)lc);
if (err) {
lc->preview_finished=1;
}
return err;
}
MSFactory *linphone_core_get_ms_factory(LinphoneCore *lc){
return lc->factory;
}
/**
* Sets the path to a wav file used for ringing back.
*
@ -5268,7 +5273,7 @@ static void toggle_video_preview(LinphoneCore *lc, bool_t val){
if (lc->previewstream==NULL){
const char *display_filter=linphone_core_get_video_display_filter(lc);
MSVideoSize vsize=lc->video_conf.preview_vsize.width!=0 ? lc->video_conf.preview_vsize : lc->video_conf.vsize;
lc->previewstream=video_preview_new();
lc->previewstream=video_preview_new(lc->factory);
video_preview_set_size(lc->previewstream,vsize);
if (display_filter)
video_preview_set_display_filter_name(lc->previewstream,display_filter);
@ -5276,6 +5281,7 @@ static void toggle_video_preview(LinphoneCore *lc, bool_t val){
video_preview_set_native_window_id(lc->previewstream,lc->preview_window_id);
video_preview_set_fps(lc->previewstream,linphone_core_get_preferred_framerate(lc));
video_preview_start(lc->previewstream,lc->video_conf.device);
lc->previewstream->ms.factory = lc->factory;
}
}else{
if (lc->previewstream!=NULL){
@ -5447,13 +5453,13 @@ int linphone_core_set_video_device(LinphoneCore *lc, const char *id){
MSWebCam *olddev=lc->video_conf.device;
const char *vd;
if (id!=NULL){
lc->video_conf.device=ms_web_cam_manager_get_cam(ms_web_cam_manager_get(),id);
lc->video_conf.device=ms_web_cam_manager_get_cam(ms_factory_get_web_cam_manager(lc->factory),id);
if (lc->video_conf.device==NULL){
ms_warning("Could not find video device %s",id);
}
}
if (lc->video_conf.device==NULL)
lc->video_conf.device=ms_web_cam_manager_get_default_cam(ms_web_cam_manager_get());
lc->video_conf.device=ms_web_cam_manager_get_default_cam(ms_factory_get_web_cam_manager(lc->factory));
if (olddev!=NULL && olddev!=lc->video_conf.device){
toggle_video_preview(lc,FALSE);/*restart the video local preview*/
}
@ -5962,7 +5968,7 @@ static MSFilter *get_audio_resource(LinphoneCore *lc, LinphoneAudioResourceType
if (ringcard == NULL)
return NULL;
ringstream=lc->ringstream=ring_start(NULL,0,ringcard);
ringstream=lc->ringstream=ring_start(lc->factory, NULL,0,ringcard);
ms_filter_call_method(lc->ringstream->gendtmf,MS_DTMF_GEN_SET_DEFAULT_AMPLITUDE,&amp);
lc->dmfs_playing_start_time = ms_get_cur_time_ms()/1000;
}else{
@ -6126,9 +6132,9 @@ void linphone_core_set_mtu(LinphoneCore *lc, int mtu){
ms_error("MTU too small !");
mtu=500;
}
ms_set_mtu(mtu);
ms_message("MTU is supposed to be %i, rtp payload max size will be %i",mtu, ms_get_payload_max_size());
}else ms_set_mtu(0);//use mediastreamer2 default value
ms_factory_set_mtu(lc->factory, mtu);
ms_message("MTU is supposed to be %i, rtp payload max size will be %i",mtu, ms_factory_get_payload_max_size(lc->factory));
}else ms_factory_set_mtu(lc->factory, 0);//use mediastreamer2 default value
}
void linphone_core_set_waiting_callback(LinphoneCore *lc, LinphoneCoreWaitingCallback cb, void *user_context){
@ -6224,6 +6230,7 @@ void sip_config_uninit(LinphoneCore *lc)
if (lc->sip_network_reachable) {
for(elem=config->proxies;elem!=NULL;elem=ms_list_next(elem)){
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)(elem->data);
_linphone_proxy_config_unpublish(cfg); /* to unpublish without changing the stored flag enable_publish */
_linphone_proxy_config_unregister(cfg); /* to unregister without changing the stored flag enable_register */
}
@ -6491,10 +6498,12 @@ static void linphone_core_uninit(LinphoneCore *lc)
linphone_core_message_storage_close(lc);
linphone_core_call_log_storage_close(lc);
linphone_core_friends_storage_close(lc);
ms_exit();
linphone_core_set_state(lc,LinphoneGlobalOff,"Off");
linphone_core_deactivate_log_serialization_if_needed();
ms_list_free_with_data(lc->vtable_refs,(void (*)(void *))v_table_reference_destroy);
ms_factory_destroy(lc->factory);
}
static void set_sip_network_reachable(LinphoneCore* lc,bool_t is_sip_reachable, time_t curtime){
@ -7510,18 +7519,30 @@ LinphoneRingtonePlayer *linphone_core_get_ringtoneplayer(LinphoneCore *lc) {
return lc->ringtoneplayer;
}
static void linphone_core_conference_state_changed(LinphoneConference *conf, LinphoneConferenceState cstate, void *user_data) {
LinphoneCore *lc = (LinphoneCore *)user_data;
if(cstate == LinphoneConferenceStartingFailed || cstate == LinphoneConferenceStopped) {
linphone_conference_free(lc->conf_ctx);
lc->conf_ctx = NULL;
}
}
LinphoneConference *linphone_core_create_conference_with_params(LinphoneCore *lc, const LinphoneConferenceParams *params) {
const char *conf_method_name;
if(lc->conf_ctx == NULL) {
LinphoneConferenceParams *params2 = linphone_conference_params_clone(params);
linphone_conference_params_set_state_changed_callback(params2, linphone_core_conference_state_changed, lc);
conf_method_name = lp_config_get_string(lc->config, "misc", "conference_type", "local");
if(strcasecmp(conf_method_name, "local") == 0) {
lc->conf_ctx = linphone_local_conference_new_with_params(lc, params);
lc->conf_ctx = linphone_local_conference_new_with_params(lc, params2);
} else if(strcasecmp(conf_method_name, "remote") == 0) {
lc->conf_ctx = linphone_remote_conference_new_with_params(lc, params);
lc->conf_ctx = linphone_remote_conference_new_with_params(lc, params2);
} else {
ms_error("'%s' is not a valid conference method", conf_method_name);
linphone_conference_params_free(params2);
return NULL;
}
linphone_conference_params_free(params2);
} else {
ms_error("Could not create a conference: a conference instance already exists");
return NULL;
@ -7531,7 +7552,12 @@ LinphoneConference *linphone_core_create_conference_with_params(LinphoneCore *lc
int linphone_core_add_to_conference(LinphoneCore *lc, LinphoneCall *call) {
LinphoneConference *conference = linphone_core_get_conference(lc);
if(conference == NULL) conference = linphone_core_create_conference_with_params(lc, NULL);
if(conference == NULL) {
LinphoneConferenceParams *params = linphone_conference_params_new(lc);
linphone_conference_params_set_state_changed_callback(params, linphone_core_conference_state_changed, lc);
conference = linphone_core_create_conference_with_params(lc, params);
linphone_conference_params_free(params);
}
if(conference) return linphone_conference_add_participant(lc->conf_ctx, call);
else return -1;
}
@ -7557,7 +7583,10 @@ int linphone_core_remove_from_conference(LinphoneCore *lc, LinphoneCall *call) {
}
int linphone_core_terminate_conference(LinphoneCore *lc) {
if(lc->conf_ctx == NULL) return -1;
if(lc->conf_ctx == NULL) {
ms_error("Could not terminate conference: no conference context");
return -1;
}
linphone_conference_terminate(lc->conf_ctx);
linphone_conference_free(lc->conf_ctx);
lc->conf_ctx = NULL;

View file

@ -38,15 +38,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define LINPHONE_HOSTNAME_SIZE 128
#ifndef LINPHONE_PUBLIC
#define LINPHONE_PUBLIC MS2_PUBLIC
#define LINPHONE_PUBLIC MS2_PUBLIC
#endif
#ifndef LINPHONE_DEPRECATED
#if defined(_MSC_VER)
#define LINPHONE_DEPRECATED __declspec(deprecated)
#else
#define LINPHONE_DEPRECATED __attribute__ ((deprecated))
#endif
#define LINPHONE_DEPRECATED MS2_DEPRECATED
#endif
@ -3259,6 +3255,10 @@ LINPHONE_PUBLIC void linphone_core_set_ring_during_incoming_early_media(Linphone
LINPHONE_PUBLIC bool_t linphone_core_get_ring_during_incoming_early_media(const LinphoneCore *lc);
LINPHONE_PUBLIC int linphone_core_preview_ring(LinphoneCore *lc, const char *ring,LinphoneCoreCbFunc func,void * userdata);
/**
* Returns the MSFactory (mediastreamer2 factory) used by the LinphoneCore to control mediastreamer2 library.
**/
LINPHONE_PUBLIC MSFactory* linphone_core_get_ms_factory(LinphoneCore* lc);
LINPHONE_PUBLIC int linphone_core_play_local(LinphoneCore *lc, const char *audiofile);
LINPHONE_PUBLIC void linphone_core_enable_echo_cancellation(LinphoneCore *lc, bool_t val);
LINPHONE_PUBLIC bool_t linphone_core_echo_cancellation_enabled(LinphoneCore *lc);

View file

@ -44,7 +44,7 @@ bool_t lsd_player_loop_enabled(const LsdPlayer *p);
void lsd_player_set_gain(LsdPlayer *p, float gain);
LinphoneSoundDaemon *lsd_player_get_daemon(const LsdPlayer *p);
LinphoneSoundDaemon * linphone_sound_daemon_new(const char *cardname, int rate, int nchannels);
LinphoneSoundDaemon * linphone_sound_daemon_new(MSFactory* factory, const char *cardname, int rate, int nchannels);
LsdPlayer * linphone_sound_daemon_get_player(LinphoneSoundDaemon *lsd);
void linphone_sound_daemon_release_player(LinphoneSoundDaemon *lsd, LsdPlayer *lsdplayer);
void linphone_sound_daemon_stop_all_players(LinphoneSoundDaemon *obj);

View file

@ -119,15 +119,17 @@ typedef struct _LinphoneFriend LinphoneFriend;
/**
* Contructor
* @return a new empty #LinphoneFriend
* @deprecated use #linphone_core_create_friend instead
*/
LINPHONE_PUBLIC LinphoneFriend * linphone_friend_new(void);
LINPHONE_PUBLIC MS2_DEPRECATED LinphoneFriend * linphone_friend_new(void); /*fix me me replace MS2_DEPRECATED by LINPHONE_DEPRECATED*/
/**
* Contructor same as linphone_friend_new() + linphone_friend_set_address()
* @param addr a buddy address, must be a sip uri like sip:joe@sip.linphone.org
* @return a new #LinphoneFriend with \link linphone_friend_get_address() address initialized \endlink
* @deprecated use #linphone_core_create_friend_with_address instead
*/
LINPHONE_PUBLIC LinphoneFriend *linphone_friend_new_with_address(const char *addr);
LINPHONE_PUBLIC MS2_DEPRECATED LinphoneFriend *linphone_friend_new_with_address(const char *addr); /*fix me me replace MS2_DEPRECATED by LINPHONE_DEPRECATED*/
/**
* Contructor same as linphone_friend_new() + linphone_friend_set_address()

View file

@ -261,6 +261,21 @@ LINPHONE_PUBLIC char * linphone_presence_model_get_contact(const LinphonePresenc
*/
LINPHONE_PUBLIC int linphone_presence_model_set_contact(LinphonePresenceModel *model, const char *contact);
/**
* Sets the presentity of a presence model.
* @param[in] model The #LinphonePresenceModel object for which to set the contact.
* @param[in] presentity The presentity address to set (presentity is copied).
* @return 0 if successful, a value < 0 in case of error.
*/
LINPHONE_PUBLIC int linphone_presence_model_set_presentity(LinphonePresenceModel *model, const LinphoneAddress *presentity);
/**
* Gets the presentity of a presence model.
* @param[in] model The #LinphonePresenceModel object to get the contact from.
* @return A pointer to a const LinphoneAddress, or NULL if no contact is found.
*
*/
LINPHONE_PUBLIC const LinphoneAddress * linphone_presence_model_get_presentity(const LinphonePresenceModel *model);
/**
* Gets the first activity of a presence model (there is usually only one).
* @param[in] model The #LinphonePresenceModel object to get the activity from.

View file

@ -36,7 +36,7 @@ LinphonePlayer *linphone_core_create_local_player(LinphoneCore *lc, MSSndCard *s
LinphonePlayer *obj = ms_new0(LinphonePlayer, 1);
if(snd_card == NULL) snd_card = lc->sound_conf.ring_sndcard;
if(video_out == NULL) video_out = linphone_core_get_video_display_filter(lc);
obj->impl = ms_media_player_new(snd_card, video_out, window_id);
obj->impl = ms_media_player_new(lc->factory, snd_card, video_out, window_id);
obj->open = _local_player_open;
obj->start = _local_player_start;
obj->pause = _local_player_pause;

View file

@ -61,7 +61,7 @@ struct _LinphoneSoundDaemon {
static MSFilter *create_writer(MSSndCard *c){
LinphoneSoundDaemon *lsd=(LinphoneSoundDaemon*)c->data;
MSFilter *itcsink=ms_filter_new(MS_ITC_SINK_ID);
MSFilter *itcsink=ms_factory_create_filter(ms_snd_card_get_factory(c), MS_ITC_SINK_ID);
ms_filter_call_method(itcsink,MS_ITC_SINK_CONNECT,lsd->branches[0].player);
return itcsink;
}
@ -114,11 +114,11 @@ int lsd_player_stop(LsdPlayer *p){
return 0;
}
static void lsd_player_init(LsdPlayer *p, MSConnectionPoint mixer, MSFilterId playerid, LinphoneSoundDaemon *lsd){
static void lsd_player_init(MSFactory* factory, LsdPlayer *p, MSConnectionPoint mixer, MSFilterId playerid, LinphoneSoundDaemon *lsd){
MSConnectionHelper h;
p->player=ms_filter_new(playerid);
p->rateconv=ms_filter_new(MS_RESAMPLE_ID);
p->chanadapter=ms_filter_new(MS_CHANNEL_ADAPTER_ID);
p->player=ms_factory_create_filter(factory, playerid);
p->rateconv=ms_factory_create_filter(factory,MS_RESAMPLE_ID);
p->chanadapter=ms_factory_create_filter(factory,MS_CHANNEL_ADAPTER_ID);
ms_connection_helper_start(&h);
ms_connection_helper_link(&h,p->player,-1,0);
@ -219,16 +219,15 @@ void lsd_player_set_gain(LsdPlayer *p, float gain){
ms_filter_call_method(p->lsd->mixer,MS_AUDIO_MIXER_SET_INPUT_GAIN,&gainctl);
}
LinphoneSoundDaemon * linphone_sound_daemon_new(const char *cardname, int rate, int nchannels){
LinphoneSoundDaemon * linphone_sound_daemon_new(MSFactory* factory, const char *cardname, int rate, int nchannels){
int i;
MSConnectionPoint mp;
LinphoneSoundDaemon *lsd;
MSSndCard *card=ms_snd_card_manager_get_card(
ms_snd_card_manager_get(),
MSSndCard *card=ms_snd_card_manager_get_card(ms_factory_get_snd_card_manager(factory),
cardname);
if (card==NULL){
card=ms_snd_card_manager_get_default_playback_card (
ms_snd_card_manager_get());
ms_factory_get_snd_card_manager(factory));
if (card==NULL){
ms_error("linphone_sound_daemon_new(): No playback soundcard available");
return NULL;
@ -237,7 +236,7 @@ LinphoneSoundDaemon * linphone_sound_daemon_new(const char *cardname, int rate,
lsd=ms_new0(LinphoneSoundDaemon,1);
lsd->soundout=ms_snd_card_create_writer(card);
lsd->mixer=ms_filter_new(MS_AUDIO_MIXER_ID);
lsd->mixer=ms_factory_create_filter(ms_snd_card_get_factory(card),MS_AUDIO_MIXER_ID);
lsd->out_rate=rate;
lsd->out_nchans=nchannels;
ms_filter_call_method(lsd->soundout,MS_FILTER_SET_SAMPLE_RATE,&lsd->out_rate);
@ -248,11 +247,11 @@ LinphoneSoundDaemon * linphone_sound_daemon_new(const char *cardname, int rate,
mp.filter=lsd->mixer;
mp.pin=0;
lsd_player_init(&lsd->branches[0],mp,MS_ITC_SOURCE_ID,lsd);
lsd_player_init(factory, &lsd->branches[0],mp,MS_ITC_SOURCE_ID,lsd);
ms_filter_add_notify_callback(lsd->branches[0].player,(MSFilterNotifyFunc)lsd_player_configure,&lsd->branches[0],FALSE);
for(i=1;i<MAX_BRANCHES;++i){
mp.pin=i;
lsd_player_init(&lsd->branches[i],mp,MS_FILE_PLAYER_ID,lsd);
lsd_player_init(factory,&lsd->branches[i],mp,MS_FILE_PLAYER_ID,lsd);
}
ms_filter_link(lsd->mixer,0,lsd->soundout,0);
lsd->ticker=ms_ticker_new();

View file

@ -94,8 +94,9 @@ void linphone_core_set_payload_type_number(LinphoneCore *lc, PayloadType *pt, in
}
const char *linphone_core_get_payload_type_description(LinphoneCore *lc, PayloadType *pt){
if (ms_filter_codec_supported(pt->mime_type)){
MSFilterDesc *desc=ms_filter_get_encoder(pt->mime_type);
//if (ms_filter_codec_supported(pt->mime_type)){
if (ms_factory_codec_supported(lc->factory, pt->mime_type)){
MSFilterDesc *desc=ms_factory_get_encoder(lc->factory, pt->mime_type);
#ifdef ENABLE_NLS
return dgettext("mediastreamer",desc->text);
#else
@ -260,7 +261,7 @@ bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, const Payloa
&& linphone_core_echo_cancellation_enabled(lc)
&& (pt->clock_rate!=16000 && pt->clock_rate!=8000)
&& strcasecmp(pt->mime_type,"opus")!=0
&& ms_filter_lookup_by_name("MSWebRTCAEC")!=NULL){
&& ms_factory_lookup_filter_by_name(lc->factory, "MSWebRTCAEC")!=NULL){
ms_warning("Payload type %s/%i cannot be used because software echo cancellation is required but is unable to operate at this rate.",
pt->mime_type,pt->clock_rate);
ret=FALSE;
@ -1831,7 +1832,7 @@ const char ** linphone_core_get_supported_file_formats(LinphoneCore *core){
if (core->supported_formats==NULL){
core->supported_formats=ms_malloc0(3*sizeof(char*));
core->supported_formats[0]=wav;
if (ms_factory_lookup_filter_by_id(ms_factory_get_fallback(),MS_MKV_RECORDER_ID)){
if (ms_factory_lookup_filter_by_id(core->factory,MS_MKV_RECORDER_ID)){
core->supported_formats[1]=mkv;
}
}

View file

@ -145,7 +145,7 @@ static PayloadType * generic_match(const MSList *local_payloads, const PayloadTy
void linphone_core_register_offer_answer_providers(LinphoneCore *lc){
MSFactory *factory = ms_factory_get_fallback();
MSFactory *factory = lc->factory;
ms_factory_register_offer_answer_provider(factory, &red_offer_answer_provider);
ms_factory_register_offer_answer_provider(factory, &g729a_offer_answer_provider);
ms_factory_register_offer_answer_provider(factory, &opus_offer_answer_provider);
@ -154,10 +154,10 @@ void linphone_core_register_offer_answer_providers(LinphoneCore *lc){
/*
* Returns a PayloadType from the local list that matches a PayloadType offered or answered in the remote list
*/
static PayloadType * find_payload_type_best_match(const MSList *local_payloads, const PayloadType *refpt,
static PayloadType * find_payload_type_best_match(MSFactory *factory, const MSList *local_payloads, const PayloadType *refpt,
const MSList *remote_payloads, bool_t reading_response){
PayloadType *ret = NULL;
MSOfferAnswerContext *ctx = ms_factory_create_offer_answer_context(ms_factory_get_fallback(), refpt->mime_type);
MSOfferAnswerContext *ctx = ms_factory_create_offer_answer_context(factory, refpt->mime_type);
if (ctx){
ms_message("Doing offer/answer processing with specific provider for codec [%s]", refpt->mime_type);
ret = ms_offer_answer_context_match_payload(ctx, local_payloads, refpt, remote_payloads, reading_response);
@ -168,7 +168,7 @@ static PayloadType * find_payload_type_best_match(const MSList *local_payloads,
}
static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t reading_response, bool_t one_matching_codec){
static MSList *match_payloads(MSFactory *factory, const MSList *local, const MSList *remote, bool_t reading_response, bool_t one_matching_codec){
const MSList *e2,*e1;
MSList *res=NULL;
PayloadType *matched;
@ -176,7 +176,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
for(e2=remote;e2!=NULL;e2=e2->next){
PayloadType *p2=(PayloadType*)e2->data;
matched=find_payload_type_best_match(local, p2, remote, reading_response);
matched=find_payload_type_best_match(factory, local, p2, remote, reading_response);
if (matched){
int local_number=payload_type_get_number(matched);
int remote_number=payload_type_get_number(p2);
@ -321,11 +321,11 @@ static SalStreamDir compute_dir_incoming(SalStreamDir local, SalStreamDir offere
return res;
}
static void initiate_outgoing(const SalStreamDescription *local_offer,
static void initiate_outgoing(MSFactory* factory, const SalStreamDescription *local_offer,
const SalStreamDescription *remote_answer,
SalStreamDescription *result){
if (remote_answer->rtp_port!=0)
result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads,TRUE,FALSE);
result->payloads=match_payloads(factory, local_offer->payloads,remote_answer->payloads,TRUE,FALSE);
else {
ms_message("Local stream description [%p] rejected by peer",local_offer);
result->rtp_port=0;
@ -438,10 +438,10 @@ static void initiate_outgoing(const SalStreamDescription *local_offer,
}
static void initiate_incoming(const SalStreamDescription *local_cap,
static void initiate_incoming(MSFactory *factory, const SalStreamDescription *local_cap,
const SalStreamDescription *remote_offer,
SalStreamDescription *result, bool_t one_matching_codec){
result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads, FALSE, one_matching_codec);
result->payloads=match_payloads(factory, local_cap->payloads,remote_offer->payloads, FALSE, one_matching_codec);
result->proto=remote_offer->proto;
result->type=local_cap->type;
result->dir=compute_dir_incoming(local_cap->dir,remote_offer->dir);
@ -513,7 +513,7 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
* Returns a media description to run the streams with, based on a local offer
* and the returned response (remote).
**/
int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
int offer_answer_initiate_outgoing(MSFactory *factory, const SalMediaDescription *local_offer,
const SalMediaDescription *remote_answer,
SalMediaDescription *result){
int i;
@ -524,7 +524,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
ls=&local_offer->streams[i];
rs=&remote_answer->streams[i];
if (rs && ls->proto == rs->proto && rs->type == ls->type) {
initiate_outgoing(ls,rs,&result->streams[i]);
initiate_outgoing(factory, ls,rs,&result->streams[i]);
memcpy(&result->streams[i].rtcp_xr, &ls->rtcp_xr, sizeof(result->streams[i].rtcp_xr));
if ((ls->rtcp_xr.enabled == TRUE) && (rs->rtcp_xr.enabled == FALSE)) {
result->streams[i].rtcp_xr.enabled = FALSE;
@ -552,7 +552,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
* and the received offer.
* The returned media description is an answer and should be sent to the offerer.
**/
int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities,
int offer_answer_initiate_incoming(MSFactory *factory, const SalMediaDescription *local_capabilities,
const SalMediaDescription *remote_offer,
SalMediaDescription *result, bool_t one_matching_codec){
int i;
@ -562,7 +562,7 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities
rs = &remote_offer->streams[i];
ls = &local_capabilities->streams[i];
if (ls && rs->type == ls->type && rs->proto == ls->proto){
initiate_incoming(ls,rs,&result->streams[i],one_matching_codec);
initiate_incoming(factory, ls,rs,&result->streams[i],one_matching_codec);
// Handle global RTCP FB attributes
result->streams[i].rtcp_fb.generic_nack_enabled = rs->rtcp_fb.generic_nack_enabled;
result->streams[i].rtcp_fb.tmmbr_enabled = rs->rtcp_fb.tmmbr_enabled;

View file

@ -30,7 +30,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* Returns a media description to run the streams with, based on a local offer
* and the returned response (remote).
**/
int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
int offer_answer_initiate_outgoing(MSFactory *factory, const SalMediaDescription *local_offer,
const SalMediaDescription *remote_answer,
SalMediaDescription *result);
@ -39,7 +39,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
* and the received offer.
* The returned media description is an answer and should be sent to the offerer.
**/
int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities,
int offer_answer_initiate_incoming(MSFactory* factory, const SalMediaDescription *local_capabilities,
const SalMediaDescription *remote_offer,
SalMediaDescription *result, bool_t one_matching_codec);

View file

@ -67,6 +67,7 @@ struct _LinphonePresencePerson {
* This model is not complete. For example, it does not handle devices.
*/
struct _LinphonePresenceModel {
LinphoneAddress *presentity; /* "The model seeks to describe the presentity, identified by a presentity URI.*/
void *user_data;
int refcnt;
MSList *services; /**< A list of _LinphonePresenceService structures. Also named tuples in the RFC. */
@ -246,7 +247,8 @@ static void presence_model_find_open_basic_status(LinphonePresenceService *servi
static void presence_model_delete(LinphonePresenceModel *model) {
if (model == NULL) return;
if (model->presentity)
linphone_address_unref(model->presentity);
ms_list_for_each(model->services, (MSIterateFunc)linphone_presence_service_unref);
ms_list_free(model->services);
ms_list_for_each(model->persons, (MSIterateFunc)linphone_presence_person_unref);
@ -671,7 +673,22 @@ int linphone_presence_model_clear_persons(LinphonePresenceModel *model) {
return 0;
}
int linphone_presence_model_set_presentity(LinphonePresenceModel *model, const LinphoneAddress *presentity) {
if (model->presentity) {
linphone_address_unref(model->presentity);
model->presentity = NULL;
}
if (presentity) {
model->presentity=linphone_address_clone(presentity);
linphone_address_clean(model->presentity);
}
return 0;
}
const LinphoneAddress * linphone_presence_model_get_presentity(const LinphonePresenceModel *model) {
return model->presentity;
}
/*****************************************************************************
* PRESENCE SERVICE FUNCTIONS TO GET ACCESS TO ALL FUNCTIONALITIES *
@ -1772,24 +1789,28 @@ static void write_xml_presence_person_obj(LinphonePresencePerson *person, struct
if (err < 0) *st->err = err;
}
void linphone_notify_convert_presence_to_xml(SalOp *op, SalPresenceModel *presence, const char *contact, char **content) {
LinphonePresenceModel *model;
xmlBufferPtr buf;
xmlTextWriterPtr writer;
char *linphone_presence_model_to_xml(LinphonePresenceModel *model) {
xmlBufferPtr buf = NULL;
xmlTextWriterPtr writer = NULL;
int err;
if ((contact == NULL) || (content == NULL)) return;
model = (LinphonePresenceModel *)presence;
char *contact = NULL;
char * content = NULL;
if (model->presentity) {
contact = linphone_address_as_string_uri_only(model->presentity);
} else {
ms_error("Cannot convert presence model [%p] to xml because no presentity set", model);
goto end;
}
buf = xmlBufferCreate();
if (buf == NULL) {
ms_error("Error creating the XML buffer");
return;
goto end;
}
writer = xmlNewTextWriterMemory(buf, 0);
if (writer == NULL) {
ms_error("Error creating the XML writer");
return;
goto end;
}
xmlTextWriterSetIndent(writer,1);
@ -1815,7 +1836,7 @@ void linphone_notify_convert_presence_to_xml(SalOp *op, SalPresenceModel *presen
} else {
struct _presence_service_obj_st st={0};
st.writer = writer;
st.contact = contact;
st.contact = contact; /*default value*/
st.err = &err;
ms_list_for_each2(model->services, (MSIterate2Func)write_xml_presence_service_obj, &st);
}
@ -1842,10 +1863,14 @@ void linphone_notify_convert_presence_to_xml(SalOp *op, SalPresenceModel *presen
}
if (err > 0) {
/* xmlTextWriterEndDocument returns the size of the content. */
*content = ms_strdup((char *)buf->content);
content = ms_strdup((char *)buf->content);
}
xmlFreeTextWriter(writer);
xmlBufferFree(buf);
end:
if (contact) ms_free(contact);
if (writer) xmlFreeTextWriter(writer);
if (buf) xmlBufferFree(buf);
return content;
}
void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, SalPresenceModel *model){

View file

@ -399,6 +399,8 @@ void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrat
void linphone_proxy_config_stop_refreshing(LinphoneProxyConfig *obj);
void linphone_proxy_config_write_all_to_config_file(LinphoneCore *lc);
void _linphone_proxy_config_release(LinphoneProxyConfig *cfg);
void _linphone_proxy_config_unpublish(LinphoneProxyConfig *obj);
/*
* returns service route as defined in as defined by rfc3608, might be a list instead of just one.
* Can be NULL
@ -605,7 +607,6 @@ struct _LinphoneProxyConfig
int auth_failures;
char *dial_prefix;
LinphoneRegistrationState state;
SalOp *publish_op;
LinphoneAVPFMode avpf_mode;
bool_t commit;
@ -625,6 +626,8 @@ struct _LinphoneProxyConfig
LinphoneAddress *saved_identity;
/*---*/
LinphoneAddress *pending_contact; /*use to store previous contact in case of network failure*/
LinphoneEvent *long_term_event;
unsigned long long previous_publish_config_hash[2];
};
@ -890,6 +893,7 @@ void linphone_task_list_free(LinphoneTaskList *t);
struct _LinphoneCore
{
MSFactory* factory;
MSList* vtable_refs;
Sal *sal;
LinphoneGlobalState state;
@ -1048,6 +1052,7 @@ bool_t linphone_core_is_payload_type_usable_for_bandwidth(LinphoneCore *lc, cons
void _linphone_core_configure_resolver(void);
struct _EcCalibrator{
MSFactory *factory;
ms_thread_t thread;
MSSndCard *play_card,*capt_card;
MSFilter *sndread,*det,*rec;
@ -1138,6 +1143,7 @@ SalReason linphone_reason_to_sal(LinphoneReason reason);
LinphoneReason linphone_reason_from_sal(SalReason reason);
LinphoneEvent *linphone_event_new(LinphoneCore *lc, LinphoneSubscriptionDir dir, const char *name, int expires);
LinphoneEvent *linphone_event_new_with_op(LinphoneCore *lc, SalOp *op, LinphoneSubscriptionDir dir, const char *name);
void linphone_event_unpublish(LinphoneEvent *lev);
/**
* Useful for out of dialog notify
* */
@ -1496,7 +1502,7 @@ void _linphone_core_add_listener(LinphoneCore *lc, LinphoneCoreVTable *vtable, b
#ifdef VIDEO_ENABLED
LINPHONE_PUBLIC MSWebCam *linphone_call_get_video_device(const LinphoneCall *call);
MSWebCam *get_nowebcam_device(void);
MSWebCam *get_nowebcam_device(MSFactory *f);
#endif
bool_t linphone_core_lime_for_file_sharing_enabled(const LinphoneCore *lc);
@ -1504,6 +1510,8 @@ BELLE_SIP_DECLARE_VPTR(LinphoneTunnelConfig);
int linphone_core_get_default_proxy_config_index(LinphoneCore *lc);
char *linphone_presence_model_to_xml(LinphonePresenceModel *model) ;
#ifdef __cplusplus
}
#endif

View file

@ -130,6 +130,50 @@ LinphoneProxyConfig *linphone_proxy_config_new() {
return linphone_core_create_proxy_config(NULL);
}
static char * append_linphone_address(LinphoneAddress *addr,char *out) {
char *res = out;
if (addr) {
char *tmp;
tmp = linphone_address_as_string(addr);
res = ms_strcat_printf(out, "%s",tmp);
ms_free(tmp);
}
return res;
};
static char * append_string(const char * string,char *out) {
char *res = out;
if (string) {
res = ms_strcat_printf(out, "%s",string);
}
return res;
}
/*
* return true if computed value has changed
*/
bool_t linphone_proxy_config_compute_publish_params_hash(LinphoneProxyConfig * cfg) {
char * source = NULL;
char hash[33];
char saved;
unsigned long long previous_hash[2];
previous_hash[0] = cfg->previous_publish_config_hash[0];
previous_hash[1] = cfg->previous_publish_config_hash[1];
source = ms_strcat_printf(source, "%i",cfg->privacy);
source=append_linphone_address(cfg->identity_address, source);
source=append_string(cfg->reg_proxy,source);
source=append_string(cfg->reg_route,source);
source=append_string(cfg->realm,source);
source = ms_strcat_printf(source, "%i",cfg->publish_expires);
source = ms_strcat_printf(source, "%i",cfg->publish);
belle_sip_auth_helper_compute_ha1(source, "dummy", "dummy", hash);
ms_free(source);
saved = hash[16];
hash[16] = '\0';
cfg->previous_publish_config_hash[0] = strtoull(hash, (char **)NULL, 16);
hash[16] = saved;
cfg->previous_publish_config_hash[1] = strtoull(&hash[16], (char **)NULL, 16);
return previous_hash[0] != cfg->previous_publish_config_hash[0] || previous_hash[1] != cfg->previous_publish_config_hash[1];
}
static void _linphone_proxy_config_destroy(LinphoneProxyConfig *cfg);
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneProxyConfig);
@ -152,9 +196,9 @@ void _linphone_proxy_config_release_ops(LinphoneProxyConfig *cfg){
sal_op_release(cfg->op);
cfg->op=NULL;
}
if (cfg->publish_op){
sal_op_release(cfg->publish_op);
cfg->publish_op=NULL;
if (cfg->long_term_event){
linphone_event_unref(cfg->long_term_event);
cfg->long_term_event=NULL;
}
}
@ -320,15 +364,13 @@ void linphone_proxy_config_pause_register(LinphoneProxyConfig *cfg){
}
void linphone_proxy_config_edit(LinphoneProxyConfig *cfg){
if (cfg->publish && cfg->publish_op){
/*unpublish*/
sal_publish_presence(cfg->publish_op,NULL,NULL,0,(SalPresenceModel *)NULL);
sal_op_release(cfg->publish_op);
cfg->publish_op=NULL;
}
/*store current config related to server location*/
linphone_proxy_config_store_server_config(cfg);
linphone_proxy_config_compute_publish_params_hash(cfg);
if (cfg->publish && cfg->long_term_event){
linphone_event_pause_publish(cfg->long_term_event);
}
/*stop refresher in any case*/
linphone_proxy_config_pause_register(cfg);
}
@ -351,9 +393,10 @@ void linphone_proxy_config_stop_refreshing(LinphoneProxyConfig * cfg){
cfg->pending_contact=contact_addr;
}
if (cfg->publish_op){
sal_op_release(cfg->publish_op);
cfg->publish_op=NULL;
if (cfg->long_term_event){ /*might probably do better*/
linphone_event_terminate(cfg->long_term_event);
linphone_event_unref(cfg->long_term_event);
cfg->long_term_event=NULL;
}
if (cfg->op){
sal_op_release(cfg->op);
@ -1001,6 +1044,26 @@ int linphone_proxy_config_done(LinphoneProxyConfig *cfg)
sal_op_unref(cfg->op); /*but we keep refresher to handle authentication if needed*/
cfg->op=NULL;
}
if (cfg->long_term_event) {
if (res == LinphoneProxyConfigAddressDifferent) {
_linphone_proxy_config_unpublish(cfg);
}
}
}
if (linphone_proxy_config_compute_publish_params_hash(cfg)) {
ms_message("Publish params have changed on proxy config [%p]",cfg);
if (cfg->long_term_event) {
if (!cfg->publish) {
/*publish is terminated*/
linphone_event_terminate(cfg->long_term_event);
}
linphone_event_unref(cfg->long_term_event);
cfg->long_term_event = NULL;
}
if (cfg->publish) cfg->send_publish=TRUE;
} else {
ms_message("Publish params have not changed on proxy config [%p]",cfg);
}
cfg->commit=TRUE;
linphone_proxy_config_write_all_to_config_file(cfg->lc);
@ -1021,28 +1084,46 @@ void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, const char *realm
int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePresenceModel *presence){
int err=0;
if (proxy->state==LinphoneRegistrationOk || proxy->state==LinphoneRegistrationCleared){
if (proxy->publish_op==NULL){
const LinphoneAddress *to=linphone_proxy_config_get_identity_address(proxy);
proxy->publish_op=sal_op_new(proxy->lc->sal);
linphone_configure_op(proxy->lc, proxy->publish_op,
to, NULL, FALSE);
if (lp_config_get_int(proxy->lc->config,"sip","publish_msg_with_contact",0)){
sal_op_set_contact_address(proxy->publish_op,linphone_proxy_config_get_identity_address(proxy));
}
LinphoneContent *content;
char *presence_body;
if (proxy->long_term_event==NULL){
proxy->long_term_event = linphone_core_create_publish(proxy->lc
, linphone_proxy_config_get_identity_address(proxy)
, "presence"
, linphone_proxy_config_get_publish_expires(proxy));
}
err=sal_publish_presence(proxy->publish_op
,NULL
,NULL
,linphone_proxy_config_get_publish_expires(proxy)
,(SalPresenceModel *)presence);
proxy->long_term_event->internal = TRUE;
if (linphone_presence_model_get_presentity(presence) == NULL) {
ms_message("No presentity set for model [%p], using identity from proxy config [%p]", presence, proxy);
linphone_presence_model_set_presentity(presence,linphone_proxy_config_get_identity_address(proxy));
}
if (!(presence_body = linphone_presence_model_to_xml(presence))) {
ms_error("Cannot publish presence model [%p] for proxy config [%p] because of xml serilization error",presence,proxy);
return -1;
}
content = linphone_content_new();
linphone_content_set_buffer(content,presence_body,strlen(presence_body));
linphone_content_set_type(content, "application");
linphone_content_set_subtype(content,"pidf+xml");
err = linphone_event_send_publish(proxy->long_term_event, content);
linphone_content_unref(content);
}else proxy->send_publish=TRUE; /*otherwise do not send publish if registration is in progress, this will be done later*/
return err;
}
void _linphone_proxy_config_unpublish(LinphoneProxyConfig *obj) {
if (obj->long_term_event
&& (linphone_event_get_publish_state(obj->long_term_event) == LinphonePublishOk ||
(linphone_event_get_publish_state(obj->long_term_event) == LinphonePublishProgress && obj->publish_expires != 0))) {
linphone_event_unpublish(obj->long_term_event);
}
}
const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *cfg){
return cfg->reg_route;
}
@ -1376,7 +1457,6 @@ void linphone_proxy_config_update(LinphoneProxyConfig *cfg){
if (can_register(cfg)){
linphone_proxy_config_register(cfg);
cfg->commit=FALSE;
if (cfg->publish) cfg->send_publish=TRUE;
}
}
if (cfg->send_publish && (cfg->state==LinphoneRegistrationOk || cfg->state==LinphoneRegistrationCleared)){

View file

@ -271,8 +271,7 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report,
int ret = 0;
LinphoneEvent *lev;
LinphoneAddress *request_uri;
char * domain;
const char* route;
const char* collector_uri;
/*if we are on a low bandwidth network, do not send reports to not overload it*/
if (linphone_call_params_low_bandwidth_enabled(linphone_call_get_current_params(call))){
@ -353,14 +352,21 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report,
}
route = linphone_proxy_config_get_quality_reporting_collector(call->dest_proxy);
domain = ms_strdup_printf("sip:%s", linphone_proxy_config_get_domain(call->dest_proxy));
request_uri = linphone_address_new(route ? route : domain);
ms_free(domain);
collector_uri = linphone_proxy_config_get_quality_reporting_collector(call->dest_proxy);
if (!collector_uri){
collector_uri = ms_strdup_printf("sip:%s", linphone_proxy_config_get_domain(call->dest_proxy));
}
request_uri = linphone_address_new(collector_uri);
lev=linphone_core_create_publish(call->core, request_uri, "vq-rtcpxr", expires);
if (route) {
ms_message("Publishing report with custom route %s", route);
sal_op_set_route(lev->op, route);
/* Special exception for quality report PUBLISH: if the collector_uri has any transport related parameters
* (port, transport, maddr), then it is sent directly.
* Otherwise it is routed as any LinphoneEvent publish, following proxy config policy.
**/
if (sal_address_has_uri_param((SalAddress*)request_uri, "transport") ||
sal_address_has_uri_param((SalAddress*)request_uri, "maddr") ||
linphone_address_get_port(request_uri) != 0) {
ms_message("Publishing report with custom route %s", collector_uri);
sal_op_set_route(lev->op, collector_uri);
}
if (linphone_event_send_publish(lev, content) != 0){

View file

@ -19,9 +19,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "private.h"
#include <mediastreamer2/msfactory.h>
int linphone_ringtoneplayer_start(LinphoneRingtonePlayer* rp, MSSndCard* card, const char* ringtone, int loop_pause_ms) {
return linphone_ringtoneplayer_start_with_cb(rp, card, ringtone, loop_pause_ms, NULL, NULL);
int linphone_ringtoneplayer_start(MSFactory *factory, LinphoneRingtonePlayer* rp, MSSndCard* card, const char* ringtone, int loop_pause_ms) {
return linphone_ringtoneplayer_start_with_cb(factory, rp, card, ringtone, loop_pause_ms, NULL, NULL);
}
#ifdef __ios
@ -36,7 +37,7 @@ void linphone_ringtoneplayer_destroy(LinphoneRingtonePlayer* rp) {
linphone_ringtoneplayer_ios_destroy(rp);
}
int linphone_ringtoneplayer_start_with_cb(LinphoneRingtonePlayer* rp, MSSndCard* card, const char* ringtone, int loop_pause_ms, LinphoneRingtonePlayerFunc end_of_ringtone, void * user_data) {
int linphone_ringtoneplayer_start_with_cb(MSFactory* f, LinphoneRingtonePlayer* rp, MSSndCard* card, const char* ringtone, int loop_pause_ms, LinphoneRingtonePlayerFunc end_of_ringtone, void * user_data) {
if (linphone_ringtoneplayer_is_started(rp)) {
ms_message("the local ringtone is already started");
return 2;
@ -83,7 +84,7 @@ static void notify_end_of_ringtone(void *ud, MSFilter *f, unsigned int event, vo
}
}
int linphone_ringtoneplayer_start_with_cb(LinphoneRingtonePlayer* rp, MSSndCard* card, const char* ringtone, int loop_pause_ms, LinphoneRingtonePlayerFunc end_of_ringtone, void * user_data) {
int linphone_ringtoneplayer_start_with_cb(MSFactory *factory, LinphoneRingtonePlayer* rp, MSSndCard* card, const char* ringtone, int loop_pause_ms, LinphoneRingtonePlayerFunc end_of_ringtone, void * user_data) {
if (linphone_ringtoneplayer_is_started(rp)) {
ms_message("the local ringtone is already started");
return 2;
@ -92,7 +93,7 @@ int linphone_ringtoneplayer_start_with_cb(LinphoneRingtonePlayer* rp, MSSndCard*
ms_message("Starting local ringtone...");
rp->end_of_ringtone = end_of_ringtone;
rp->end_of_ringtone_ud = user_data;
rp->ringstream=ring_start_with_cb(ringtone,loop_pause_ms,card,notify_end_of_ringtone,rp);
rp->ringstream=ring_start_with_cb(factory, ringtone,loop_pause_ms,card,notify_end_of_ringtone,rp);
return rp->ringstream != NULL ? 0 : 1;
}
return 3;

View file

@ -24,7 +24,7 @@ typedef void (*LinphoneRingtonePlayerFunc)(LinphoneRingtonePlayer* rp, void* use
LINPHONE_PUBLIC LinphoneRingtonePlayer* linphone_ringtoneplayer_new(void);
LINPHONE_PUBLIC void linphone_ringtoneplayer_destroy(LinphoneRingtonePlayer* rp);
LINPHONE_PUBLIC int linphone_ringtoneplayer_start(LinphoneRingtonePlayer* rp, MSSndCard* card, const char* ringtone, int loop_pause_ms);
LINPHONE_PUBLIC int linphone_ringtoneplayer_start(MSFactory *factory, LinphoneRingtonePlayer* rp, MSSndCard* card, const char* ringtone, int loop_pause_ms);
/**
* Start a ringtone player
* @param rp LinphoneRingtonePlayer object
@ -33,7 +33,8 @@ LINPHONE_PUBLIC int linphone_ringtoneplayer_start(LinphoneRingtonePlayer* rp, MS
* @param loop_pause_ms pause interval in milliseconds to be observed between end of play and resuming at start. A value of -1 disables loop mode
* @return 0 if the player successfully started, positive error code otherwise
*/
LINPHONE_PUBLIC int linphone_ringtoneplayer_start_with_cb(LinphoneRingtonePlayer* rp, MSSndCard* card, const char* ringtone, int loop_pause_ms, LinphoneRingtonePlayerFunc end_of_ringtone, void * user_data);
LINPHONE_PUBLIC int linphone_ringtoneplayer_start_with_cb(MSFactory *factory, LinphoneRingtonePlayer* rp, MSSndCard* card,
const char* ringtone, int loop_pause_ms, LinphoneRingtonePlayerFunc end_of_ringtone, void * user_data);
LINPHONE_PUBLIC bool_t linphone_ringtoneplayer_is_started(LinphoneRingtonePlayer* rp);
LINPHONE_PUBLIC int linphone_ringtoneplayer_stop(LinphoneRingtonePlayer* rp);

View file

@ -570,13 +570,6 @@ const SalAddress *sal_op_get_to_address(const SalOp *op){
return ((SalOpBase*)op)->to_address;
}
const char *sal_op_get_route(const SalOp *op){
#ifdef BELLE_SIP
ms_fatal("sal_op_get_route not supported, use sal_op_get_route_addresses instead");
#endif
return ((SalOpBase*)op)->route;
}
const char *sal_op_get_remote_ua(const SalOp *op){
return ((SalOpBase*)op)->remote_ua;
}
@ -696,6 +689,11 @@ void __sal_op_free(SalOp *op){
sal_custom_header_free(b->recv_custom_headers);
if (b->sent_custom_headers)
sal_custom_header_free(b->sent_custom_headers);
if (b->entity_tag != NULL){
ms_free(b->entity_tag);
b->entity_tag = NULL;
}
ms_free(op);
}
@ -1007,3 +1005,17 @@ char* sal_op_get_public_uri(SalOp *op) {
}
return NULL;
}
const char *sal_op_get_entity_tag(const SalOp* op) {
SalOpBase* op_base = (SalOpBase*)op;
return op_base->entity_tag;
}
void sal_op_set_entity_tag(SalOp *op, const char* entity_tag) {
SalOpBase* op_base = (SalOpBase*)op;
if (op_base->entity_tag != NULL){
ms_free(op_base->entity_tag);
}
if (entity_tag)
op_base->entity_tag = ms_strdup(entity_tag);
else
op_base->entity_tag = NULL;
}

View file

@ -35,9 +35,10 @@ void sip_setup_register(SipSetup *ss){
registered_sip_setups=ms_list_append(registered_sip_setups,ss);
}
void sip_setup_register_all(void){
void sip_setup_register_all(MSFactory *factory){
SipSetup **p=all_sip_setups;
ms_load_plugins(LINPHONE_PLUGINS_DIR);
ms_factory_load_plugins(factory, LINPHONE_PLUGINS_DIR);
//ms_load_plugins(LINPHONE_PLUGINS_DIR);
while(*p!=NULL){
sip_setup_register(*p);
p++;

View file

@ -132,7 +132,7 @@ void buddy_lookup_request_set_max_results(BuddyLookupRequest *req, int ncount);
void sip_setup_register(SipSetup *ss);
void sip_setup_register_all(void);
void sip_setup_register_all(MSFactory* factory);
SipSetup *sip_setup_lookup(const char *type_name);
void sip_setup_unregister_all(void);
LINPHONE_PUBLIC unsigned int sip_setup_get_capabilities(SipSetup *s);

View file

@ -250,7 +250,7 @@ void linphone_core_notify_subscription_state_changed(LinphoneCore *lc, LinphoneE
}
void linphone_core_notify_publish_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphonePublishState state) {
NOTIFY_IF_EXIST(publish_state_changed, lc,lev,state);
NOTIFY_IF_EXIST_INTERNAL(publish_state_changed, linphone_event_is_internal(lev), lc, lev, state);
cleanup_dead_vtable_refs(lc);
}

View file

@ -211,14 +211,15 @@ static gboolean linphone_gtk_stop_record(gpointer data){
void linphone_gtk_start_record_sound(GtkWidget *w, gpointer data){
LinphoneCore *lc = linphone_gtk_get_core();
MSFactory *factory = linphone_core_get_ms_factory(lc);
AudioStream *stream = NULL;
MSSndCardManager *manager = ms_snd_card_manager_get();
MSSndCardManager *manager = ms_factory_get_snd_card_manager(factory);
gboolean active=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
gint timeout_id;
if(active){
gchar *path = get_record_file();
stream=audio_stream_new(8888, 8889, FALSE);
stream=audio_stream_new(factory, 8888, 8889, FALSE);
if(stream != NULL){
audio_stream_start_full(stream,&av_profile,"127.0.0.1",8888,"127.0.0.1",8889,0,0,NULL,
path,NULL,ms_snd_card_manager_get_card(manager,linphone_core_get_capture_device(lc)),FALSE);
@ -255,13 +256,14 @@ static void endoffile_cb(void *ud, MSFilter *f, unsigned int ev,void * arg){
void linphone_gtk_start_play_record_sound(GtkWidget *w,gpointer data){
LinphoneCore *lc = linphone_gtk_get_core();
MSFactory *factory = linphone_core_get_ms_factory(lc);
gboolean active=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
AudioStream *stream = NULL;
MSSndCardManager *manager = ms_snd_card_manager_get();
MSSndCardManager *manager = ms_factory_get_snd_card_manager(factory);
if(active){
gchar *path = g_object_get_data(G_OBJECT(audio_assistant),"path");
stream=audio_stream_new(8888, 8889, FALSE);
stream=audio_stream_new(factory, 8888, 8889, FALSE);
if(path != NULL){
audio_stream_start_full(stream,&av_profile,"127.0.0.1",8888,"127.0.0.1",8889,0,0,path,
NULL,ms_snd_card_manager_get_card(manager,linphone_core_get_playback_device(lc)),NULL,FALSE);
@ -446,14 +448,15 @@ static GtkWidget *create_end_page(void){
static void prepare(GtkAssistant *w){
AudioStream *audio_stream = NULL;
LinphoneCore *lc=linphone_gtk_get_core();
MSFactory *factory = linphone_core_get_ms_factory(lc);
int page = gtk_assistant_get_current_page(w);
GtkWidget *mic_audiolevel = get_widget_from_assistant("mic_audiolevel");
GtkWidget *label_audiolevel = get_widget_from_assistant("label_audiolevel");
//Speaker page
if(page == 1){
MSSndCardManager *manager = ms_snd_card_manager_get();
audio_stream = audio_stream_start_with_sndcards(&av_profile,9898,"127.0.0.1",19898,0,0,ms_snd_card_manager_get_card(manager,linphone_core_get_playback_device(lc)),ms_snd_card_manager_get_card(manager,linphone_core_get_capture_device(lc)),FALSE);
MSSndCardManager *manager = ms_factory_get_snd_card_manager(factory);
audio_stream = audio_stream_start_with_sndcards(factory, &av_profile,9898,"127.0.0.1",19898,0,0,ms_snd_card_manager_get_card(manager,linphone_core_get_playback_device(lc)),ms_snd_card_manager_get_card(manager,linphone_core_get_capture_device(lc)),FALSE);
if (mic_audiolevel != NULL && audio_stream != NULL){
g_object_set_data(G_OBJECT(audio_assistant),"stream",audio_stream);
linphone_gtk_init_audio_meter(mic_audiolevel,(get_volume_t)audio_stream_get_record_volume,audio_stream);

View file

@ -301,7 +301,7 @@ void linphone_gtk_call_log_update(GtkWidget *w){
time_t start_date_time=linphone_call_log_get_start_date(cl);
const gchar *call_status_icon_name;
#if GLIB_CHECK_VERSION(2,26,0)
#if GLIB_CHECK_VERSION(2,30,0) // The g_date_time_format function exists since 2.26.0 but the '%c' format is only supported since 2.30.0
if (start_date_time){
GDateTime *dt=g_date_time_new_from_unix_local(start_date_time);
start_date=g_date_time_format(dt,"%c");
@ -309,6 +309,9 @@ void linphone_gtk_call_log_update(GtkWidget *w){
}
#else
start_date=g_strdup(ctime(&start_date_time));
if (start_date[strlen(start_date) - 1] == '\n') {
start_date[strlen(start_date) - 1] = '\0';
}
#endif
lf=linphone_core_get_friend_by_address(linphone_gtk_get_core(),addr);
if(lf != NULL){

View file

@ -1417,8 +1417,9 @@ void linphone_gtk_fill_webcams(GtkWidget *pb){
void linphone_gtk_fill_video_renderers(GtkWidget *pb){
#ifdef VIDEO_ENABLED /* video_stream_get_default_video_renderer requires video enabled */
LinphoneCore *lc=linphone_gtk_get_core();
MSFactory *factory = linphone_core_get_ms_factory(lc);
GtkWidget *combo=linphone_gtk_get_widget(pb,"renderers");
MSList *l=ms_filter_lookup_by_interface(MSFilterVideoDisplayInterface);
MSList *l=ms_factory_lookup_filter_by_interface(factory, MSFilterVideoDisplayInterface);
MSList *elem;
int i;
int active=-1;

View file

@ -61,8 +61,10 @@ static void drag_data_received(GtkWidget *widget, GdkDragContext *context, gint
datalen--;
}
if (player){
const char* filepath = (strstr(path,"file://")==path) ? path+strlen("file://") : path;
if (linphone_player_open(player,filepath,on_end_of_play,NULL)==0){
linphone_player_start(player);
}else{
GtkWidget *warn=gtk_message_dialog_new(GTK_WINDOW(widget),GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,

View file

@ -126,13 +126,14 @@ void sal_address_set_transport_name(SalAddress* addr,const char* transport);
void sal_address_set_method_param(SalAddress *addr, const char *method);
void sal_address_set_params(SalAddress *addr, const char *params);
void sal_address_set_uri_params(SalAddress *addr, const char *params);
bool_t sal_address_has_uri_param(SalAddress *addr, const char *name);
bool_t sal_address_is_ipv6(const SalAddress *addr);
bool_t sal_address_is_sip(const SalAddress *addr);
void sal_address_set_password(SalAddress *addr, const char *passwd);
const char *sal_address_get_password(const SalAddress *addr);
void sal_address_set_header(SalAddress *addr, const char *header_name, const char *header_value);
LINPHONE_PUBLIC Sal * sal_init(void);
LINPHONE_PUBLIC Sal * sal_init(MSFactory *factory);
LINPHONE_PUBLIC void sal_uninit(Sal* sal);
void sal_set_user_pointer(Sal *sal, void *user_data);
void *sal_get_user_pointer(const Sal *sal);
@ -353,6 +354,7 @@ typedef struct SalOpBase{
SalAddress* service_route; /*as defined by rfc3608, might be a list*/
SalCustomHeader *sent_custom_headers;
SalCustomHeader *recv_custom_headers;
char* entity_tag; /*as defined by rfc3903 (I.E publih)*/
} SalOpBase;
@ -641,6 +643,8 @@ void sal_op_set_to(SalOp *op, const char *to);
void sal_op_set_to_address(SalOp *op, const SalAddress *to);
SalOp *sal_op_ref(SalOp* h);
void sal_op_stop_refreshing(SalOp *op);
int sal_op_refresh(SalOp *op);
void sal_op_release(SalOp *h);
/*same as release, but does not stop refresher if any*/
void* sal_op_unref(SalOp* op);
@ -654,7 +658,6 @@ const SalAddress *sal_op_get_from_address(const SalOp *op);
const char *sal_op_get_to(const SalOp *op);
const SalAddress *sal_op_get_to_address(const SalOp *op);
const SalAddress *sal_op_get_contact_address(const SalOp *op);
const char *sal_op_get_route(const SalOp *op);
const MSList* sal_op_get_route_addresses(const SalOp *op);
const char *sal_op_get_proxy(const SalOp *op);
/*raw contact header value with header params*/
@ -684,6 +687,10 @@ const SalErrorInfo *sal_op_get_error_info(const SalOp *op);
void sal_error_info_reset(SalErrorInfo *ei);
void sal_error_info_set(SalErrorInfo *ei, SalReason reason, int code, const char *status_string, const char *warning);
/*entity tag used for publish (see RFC 3903)*/
const char *sal_op_get_entity_tag(const SalOp* op);
void sal_op_set_entity_tag(SalOp *op, const char* entity_tag);
/*Call API*/
int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc);
int sal_call(SalOp *h, const char *from, const char *to);
@ -740,8 +747,9 @@ int sal_notify_presence(SalOp *op, SalPresenceModel *presence);
int sal_notify_presence_close(SalOp *op);
/*presence publish */
int sal_publish_presence(SalOp *op, const char *from, const char *to, int expires, SalPresenceModel *presence);
//int sal_publish_presence(SalOp *op, const char *from, const char *to, int expires, SalPresenceModel *presence);
SalBodyHandler *sal_presence_model_create_body_handler(SalPresenceModel *presence);
/*ping: main purpose is to obtain its own contact address behind firewalls*/
int sal_ping(SalOp *op, const char *from, const char *to);
@ -754,11 +762,11 @@ int sal_subscribe(SalOp *op, const char *from, const char *to, const char *event
int sal_unsubscribe(SalOp *op);
int sal_subscribe_accept(SalOp *op);
int sal_subscribe_decline(SalOp *op, SalReason reason);
int sal_subscribe_refresh(SalOp *op);
int sal_notify(SalOp *op, const SalBodyHandler *body);
int sal_notify_close(SalOp *op);
int sal_publish(SalOp *op, const char *from, const char *to, const char*event_name, int expires, const SalBodyHandler *body);
int sal_op_unpublish(SalOp *op);
/*privacy, must be in sync with LinphonePrivacyMask*/
typedef enum _SalPrivacy {
SalPrivacyNone=0x0,

View file

@ -100,6 +100,7 @@ rm -rf $RPM_BUILD_ROOT
%{_bindir}/lpc2xml_test
%{_bindir}/xml2lpc_test
%{_bindir}/lp-gen-wrappers
%{_bindir}/lp-sendmsg
%{_includedir}/linphone
%{_libdir}/*.a
%{_libdir}/*.la

@ -1 +1 @@
Subproject commit 7053d54e7e3375944ee54671b82c3b5f63eac072
Subproject commit dd5ad1b738989bc6964f889e17f275eea85e11c0

2
oRTP

@ -1 +1 @@
Subproject commit 83bf0a09cc2127086e15817d16793320c9fb9af0
Subproject commit 1d533c7490475b26a29f3fce300ac7004ab74a88

View file

@ -547,14 +547,14 @@ static void call_outbound_with_multiple_proxy(void) {
// set first LPC to unreacheable proxy addr
linphone_proxy_config_edit(lpc);
linphone_proxy_config_set_server_addr(lpc,"12.13.14.15:5223;transport=udp");
linphone_proxy_config_set_route(lpc, "12.13.14.15:5223;transport=udp;lr");
linphone_proxy_config_set_server_addr(lpc,"sip:linphone.org:9016;transport=udp");
linphone_proxy_config_set_route(lpc, "sip:linphone.org:9016;transport=udp;lr");
linphone_proxy_config_done(lpc);
BC_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &pauline->stat.number_of_LinphoneRegistrationOk, 1, 2000));
BC_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &pauline->stat.number_of_LinphoneRegistrationOk, 1, 10000));
BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneRegistrationProgress, 2, 200));
BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneRegistrationOk, 1, 2000));
BC_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneRegistrationOk, 1, 10000));
// calling marie should go through the second proxy config
BC_ASSERT_TRUE(call(marie, pauline));
@ -667,7 +667,7 @@ static void call_with_specified_codec_bitrate(void) {
int max_bw=50;
#ifdef __arm__
if (ms_get_cpu_count() <2) { /*2 opus codec channel + resampler is too much for a single core*/
if (ms_factory_get_cpu_count(marie->lc->factory) <2) { /*2 opus codec channel + resampler is too much for a single core*/
#ifndef ANDROID
codec = "speex";
rate = 8000;
@ -2343,20 +2343,20 @@ static void video_call_using_policy_AVPF_implicit_caller_and_callee(void) {
linphone_core_manager_destroy(callee);
linphone_core_manager_destroy(caller);
}
static void video_call_base_avpf(LinphoneCoreManager* pauline,LinphoneCoreManager* marie, bool_t using_policy,LinphoneMediaEncryption mode, bool_t callee_video_enabled, bool_t caller_video_enabled) {
linphone_core_set_avpf_mode(pauline->lc,LinphoneAVPFEnabled);
linphone_core_set_avpf_mode(marie->lc,LinphoneAVPFEnabled);
video_call_base_3(pauline,marie,using_policy,mode,callee_video_enabled,caller_video_enabled);
end_call(pauline, marie);
static void video_call_base_avpf(LinphoneCoreManager* caller,LinphoneCoreManager* callee, bool_t using_policy,LinphoneMediaEncryption mode, bool_t callee_video_enabled, bool_t caller_video_enabled) {
linphone_core_set_avpf_mode(caller->lc,LinphoneAVPFEnabled);
linphone_core_set_avpf_mode(callee->lc,LinphoneAVPFEnabled);
video_call_base_3(caller,callee,using_policy,mode,callee_video_enabled,caller_video_enabled);
end_call(caller, callee);
}
static void video_call_avpf(void) {
LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_rc");
LinphoneCoreManager* marie = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "marie_rc" : "marie_tcp_rc");
LinphoneCoreManager* callee = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* caller = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
video_call_base_avpf(pauline,marie,FALSE,LinphoneMediaEncryptionNone,TRUE,TRUE);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
video_call_base_avpf(caller,callee,FALSE,LinphoneMediaEncryptionNone,TRUE,TRUE);
linphone_core_manager_destroy(callee);
linphone_core_manager_destroy(caller);
}
@ -2984,7 +2984,8 @@ static void call_with_mkv_file_player(void) {
BC_ASSERT_PTR_NOT_NULL(player);
if (player){
int res = linphone_player_open(player,hellomkv,on_eof,marie);
if(!ms_filter_codec_supported("opus")) {
//if(!ms_filter_codec_supported("opus")) {
if(!ms_factory_codec_supported(marie->lc->factory, "opus") && !ms_factory_codec_supported(pauline->lc->factory, "opus")){
BC_ASSERT_EQUAL(res, -1, int, "%d");
end_call(marie, pauline);
goto end;
@ -5710,7 +5711,8 @@ static void call_logs_sqlite_storage(void) {
MSList *logs = NULL;
LinphoneCallLog *call_log = NULL;
LinphoneAddress *laure = NULL;
time_t start_time = time(NULL);
time_t user_data_time = time(NULL);
time_t start_time = 0;
unlink(logs_db);
linphone_core_set_call_logs_database_path(marie->lc, logs_db);
@ -5719,7 +5721,8 @@ static void call_logs_sqlite_storage(void) {
BC_ASSERT_TRUE(call(marie, pauline));
wait_for_until(marie->lc, pauline->lc, NULL, 5, 500);
call_log = linphone_call_get_call_log(linphone_core_get_current_call(marie->lc));
linphone_call_log_set_user_data(call_log, &start_time);
start_time = linphone_call_log_get_start_date(call_log);
linphone_call_log_set_user_data(call_log, &user_data_time);
linphone_call_log_set_ref_key(call_log, "ref_key");
end_call(marie, pauline);
BC_ASSERT_TRUE(linphone_core_get_call_history_size(marie->lc) == 1);
@ -5752,7 +5755,7 @@ static void call_logs_sqlite_storage(void) {
if (ref_key) {
BC_ASSERT_STRING_EQUAL(ref_key, "ref_key");
}
BC_ASSERT_PTR_EQUAL(linphone_call_log_get_user_data(call_log), &start_time);
BC_ASSERT_PTR_EQUAL(linphone_call_log_get_user_data(call_log), &user_data_time);
call_id = linphone_call_log_get_call_id(call_log);
BC_ASSERT_PTR_NOT_NULL(call_id);
@ -5762,7 +5765,8 @@ static void call_logs_sqlite_storage(void) {
linphone_call_log_get_remote_address(call_log),
linphone_proxy_config_get_identity_address(linphone_core_get_default_proxy_config(pauline->lc))));
BC_ASSERT_PTR_NOT_NULL(linphone_call_log_get_remote_stats(call_log));
BC_ASSERT_GREATER(linphone_call_log_get_start_date(call_log), start_time, int, "%d");
BC_ASSERT_PTR_NOT_NULL(linphone_call_log_get_start_date(call_log));
BC_ASSERT_EQUAL(linphone_call_log_get_start_date(call_log), start_time, int, "%d");
BC_ASSERT_EQUAL(linphone_call_log_get_status(call_log), LinphoneCallSuccess, int, "%d");
}

View file

@ -36,7 +36,9 @@ void send_dtmf_base(LinphoneCoreManager **pmarie, LinphoneCoreManager **ppauline
LinphoneCall *marie_call = NULL;
if (use_opus) {
if (!ms_filter_codec_supported("opus")) {
//if (!ms_filter_codec_supported("opus")) {
if(!ms_factory_codec_supported(marie->lc->factory, "opus") && !ms_factory_codec_supported(pauline->lc->factory, "opus")){
ms_warning("Opus not supported, skipping test.");
return;
}

View file

@ -259,6 +259,7 @@ typedef struct _LinphoneConferenceServer {
LinphoneCoreManager base;
LinphoneCall *first_call;
LinphoneCoreVTable *vtable;
LinphoneRegistrationState reg_state;
} LinphoneConferenceServer;
typedef struct _LinphoneCallTestParams {
@ -362,7 +363,7 @@ void liblinphone_tester_uninit(void);
int liblinphone_tester_set_log_file(const char *filename);
bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, LinphoneIceState state);
LinphoneConferenceServer* linphone_conference_server_new(const char *rc_file);
LinphoneConferenceServer* linphone_conference_server_new(const char *rc_file, bool_t do_registration);
void linphone_conference_server_destroy(LinphoneConferenceServer *conf_srv);
extern const char *liblinphone_tester_mire_id;

View file

@ -108,7 +108,7 @@ bool NativeTester::run(Platform::String^ suiteName, Platform::String^ caseName,
linphone_core_set_log_level_mask(ORTP_FATAL);
}
linphone_core_set_log_handler(libLinphoneNativeOutputTraceHandler);
return bc_tester_run_tests(wssuitename == all ? 0 : csuitename, wscasename == all ? 0 : ccasename) != 0;
return bc_tester_run_tests(wssuitename == all ? 0 : csuitename, wscasename == all ? 0 : ccasename, NULL) != 0;
}
void NativeTester::runAllToXml()

View file

@ -188,6 +188,7 @@ static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManag
LinphoneConference *conference;
const MSList* calls;
bool_t is_remote_conf;
bool_t focus_is_up = (focus && ((LinphoneConferenceServer *)focus)->reg_state == LinphoneRegistrationOk);
MSList* lcs=ms_list_append(NULL,marie->lc);
lcs=ms_list_append(lcs,pauline->lc);
lcs=ms_list_append(lcs,laure->lc);
@ -213,9 +214,21 @@ static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManag
if(!is_remote_conf) {
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallUpdating,initial_marie_stat.number_of_LinphoneCallUpdating+1,5000));
} else {
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,initial_marie_stat.number_of_LinphoneCallStreamsRunning+1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallConnected,initial_marie_stat.number_of_LinphoneTransferCallConnected+1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,initial_marie_stat.number_of_LinphoneCallEnd+1,5000));
if(focus_is_up) {
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,initial_marie_stat.number_of_LinphoneCallStreamsRunning+1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallConnected,initial_marie_stat.number_of_LinphoneTransferCallConnected+1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,initial_marie_stat.number_of_LinphoneCallEnd+1,5000));
} else {
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallError, initial_marie_stat.number_of_LinphoneCallError+1, 5000));
BC_ASSERT_PTR_NULL(linphone_core_get_conference(marie->lc));
BC_ASSERT_EQUAL(linphone_core_terminate_conference(marie->lc), -1, int, "%d");
linphone_core_terminate_call(marie->lc, marie_call_pauline);
linphone_core_terminate_call(marie->lc, marie_call_laure);
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallEnd, initial_marie_stat.number_of_LinphoneCallEnd+2, 10000));
BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallEnd, initial_pauline_stat.number_of_LinphoneCallEnd+1, 5000));
BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneCallEnd, initial_laure_stat.number_of_LinphoneCallEnd+1, 5000));
goto end;
}
}
linphone_core_add_to_conference(marie->lc,marie_call_pauline);
@ -267,11 +280,11 @@ static void simple_conference_base(LinphoneCoreManager* marie, LinphoneCoreManag
}
linphone_core_terminate_conference(marie->lc);
BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,is_remote_conf?2:1,10000));
BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,is_remote_conf?3:1,10000));
BC_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallEnd,is_remote_conf?2:1,10000));
end:
ms_list_free(lcs);
}
@ -766,7 +779,38 @@ void simple_remote_conference(void) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
LinphoneCoreManager *laure = linphone_core_manager_new("laure_rc");
LinphoneConferenceServer *focus = linphone_conference_server_new("conference_focus_rc");
LinphoneConferenceServer *focus = linphone_conference_server_new("conference_focus_rc", TRUE);
LpConfig *marie_config = linphone_core_get_config(marie->lc);
LinphoneProxyConfig *focus_proxy_config = linphone_core_get_default_proxy_config(((LinphoneCoreManager *)focus)->lc);
LinphoneProxyConfig *laure_proxy_config = linphone_core_get_default_proxy_config(((LinphoneCoreManager *)laure)->lc);
const char *laure_proxy_uri = linphone_proxy_config_get_server_addr(laure_proxy_config);
const char *focus_uri = linphone_proxy_config_get_identity(focus_proxy_config);
int laure_n_register = laure->stat.number_of_LinphoneRegistrationOk;
MSList *lcs = NULL;
lp_config_set_string(marie_config, "misc", "conference_type", "remote");
lp_config_set_string(marie_config, "misc", "conference_focus_addr", focus_uri);
linphone_proxy_config_edit(laure_proxy_config);
linphone_proxy_config_set_route(laure_proxy_config, laure_proxy_uri);
linphone_proxy_config_done(laure_proxy_config);
lcs = ms_list_append(lcs, laure->lc);
BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneRegistrationOk, laure_n_register+1, 5000));
ms_list_free(lcs);
simple_conference_base(marie, pauline, laure, (LinphoneCoreManager *)focus);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
linphone_conference_server_destroy(focus);
}
void simple_remote_conference_shut_down_focus(void) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
LinphoneCoreManager *laure = linphone_core_manager_new("laure_rc");
LinphoneConferenceServer *focus = linphone_conference_server_new("conference_focus_rc", FALSE);
LpConfig *marie_config = linphone_core_get_config(marie->lc);
LinphoneProxyConfig *focus_proxy_config = linphone_core_get_default_proxy_config(((LinphoneCoreManager *)focus)->lc);
LinphoneProxyConfig *laure_proxy_config = linphone_core_get_default_proxy_config(((LinphoneCoreManager *)laure)->lc);
@ -797,7 +841,7 @@ void eject_from_3_participants_remote_conference(void) {
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc");
LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc");
LinphoneConferenceServer *focus = linphone_conference_server_new("conference_focus_rc");
LinphoneConferenceServer *focus = linphone_conference_server_new("conference_focus_rc", TRUE);
LpConfig *marie_config = linphone_core_get_config(marie->lc);
LinphoneProxyConfig *focus_proxy_config = linphone_core_get_default_proxy_config(((LinphoneCoreManager *)focus)->lc);
LinphoneProxyConfig *laure_proxy_config = linphone_core_get_default_proxy_config(((LinphoneCoreManager *)laure)->lc);
@ -840,7 +884,8 @@ test_t multi_call_tests[] = {
TEST_NO_TAG("Unattended call transfer with error", unattended_call_transfer_with_error),
TEST_NO_TAG("Call transfer existing call outgoing call", call_transfer_existing_call_outgoing_call),
TEST_NO_TAG("Simple remote conference", simple_remote_conference),
TEST_NO_TAG("Eject from 3 participants in remote conference", eject_from_3_participants_remote_conference)
TEST_NO_TAG("Simple remote conference with shut down focus", simple_remote_conference_shut_down_focus),
TEST_NO_TAG("Eject from 3 participants in remote conference", eject_from_3_participants_remote_conference),
};
test_suite_t multi_call_test_suite = {"Multi call", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,

View file

@ -44,10 +44,12 @@ static void play_file(const char *filename, bool_t supported_format, const char
BC_ASSERT_PTR_NOT_NULL(lc_manager);
if(lc_manager == NULL) return;
audio_codec_supported = (audio_mime && ms_factory_get_decoder(ms_factory_get_fallback(), audio_mime));
video_codec_supported = (video_mime && ms_factory_get_decoder(ms_factory_get_fallback(), video_mime));
audio_codec_supported = (audio_mime && ms_factory_get_decoder(linphone_core_get_ms_factory((void *)lc_manager->lc), audio_mime));
video_codec_supported = (video_mime && ms_factory_get_decoder(linphone_core_get_ms_factory((void *)lc_manager->lc), video_mime));
player = linphone_core_create_local_player(lc_manager->lc, ms_snd_card_manager_get_default_card(ms_snd_card_manager_get()), video_stream_get_default_video_renderer(), 0);
player = linphone_core_create_local_player(lc_manager->lc,
ms_snd_card_manager_get_default_card(ms_factory_get_snd_card_manager(linphone_core_get_ms_factory((void *)lc_manager->lc))),
video_stream_get_default_video_renderer(), 0);
BC_ASSERT_PTR_NOT_NULL(player);
if(player == NULL) goto fail;

View file

@ -130,7 +130,10 @@ static void simple_publish_with_expire(int expires) {
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneProxyConfig* proxy;
LinphonePresenceModel* presence;
LinphoneCoreVTable *vtable = linphone_core_v_table_new();
vtable->publish_state_changed = linphone_publish_state_changed;
_linphone_core_add_listener(marie->lc, vtable, TRUE, TRUE );
proxy = linphone_core_get_default_proxy_config(marie->lc);
linphone_proxy_config_edit(proxy);
if (expires >0) {
@ -138,11 +141,44 @@ static void simple_publish_with_expire(int expires) {
}
linphone_proxy_config_enable_publish(proxy,TRUE);
linphone_proxy_config_done(proxy);
wait_core(marie->lc);
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,1));
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,1));
presence =linphone_presence_model_new_with_activity(LinphonePresenceActivityOffline,NULL);
linphone_core_set_presence_model(marie->lc,presence);
wait_core(marie->lc);
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,2));
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,2));
linphone_proxy_config_edit(proxy);
linphone_proxy_config_done(proxy);
/*make sure no publish is sent*/
BC_ASSERT_FALSE(wait_for_until(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3,expires*1000/2));
linphone_proxy_config_edit(proxy);
linphone_proxy_config_enable_publish(proxy,FALSE);
linphone_proxy_config_done(proxy);
/*BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3));*/
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishCleared,1));
linphone_proxy_config_edit(proxy);
linphone_proxy_config_enable_publish(proxy,TRUE);
linphone_proxy_config_done(proxy);
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3));
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,3));
linphone_proxy_config_edit(proxy);
linphone_proxy_config_set_publish_expires(proxy, linphone_proxy_config_get_publish_expires(proxy)+1);
linphone_proxy_config_done(proxy);
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,4));
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,4));
linphone_core_manager_destroy(marie);
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,2,int,"%i");
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,4,int,"%i");
}
static void simple_publish(void) {
@ -150,7 +186,7 @@ static void simple_publish(void) {
}
static void publish_with_expires(void) {
simple_publish_with_expire(1);
simple_publish_with_expire(2);
}
static bool_t subscribe_to_callee_presence(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr) {
@ -490,7 +526,7 @@ static void test_subscribe_notify_publish(void) {
LpConfig *pauline_lp;
char* lf_identity;
LinphoneFriend *lf;
linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
pauline_lp = linphone_core_get_config(pauline->lc);
@ -502,7 +538,7 @@ static void test_subscribe_notify_publish(void) {
linphone_core_add_friend(pauline->lc,lf);
/*wait for subscribe acknowledgment*/
wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,1,2000);
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,1,2000));
BC_ASSERT_EQUAL(LinphoneStatusOffline,linphone_friend_get_status(lf), int, "%d");
/*enable publish*/
@ -515,18 +551,18 @@ static void test_subscribe_notify_publish(void) {
linphone_proxy_config_done(proxy);
/*wait for marie status*/
wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,2,2000);
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,2,2000));
BC_ASSERT_EQUAL(LinphoneStatusOnline,linphone_friend_get_status(lf), int, "%d");
presence =linphone_presence_model_new_with_activity(LinphonePresenceActivityBusy,NULL);
linphone_core_set_presence_model(marie->lc,presence);
/*wait for new status*/
wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,3,2000);
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,3,2000));
BC_ASSERT_EQUAL(LinphoneStatusBusy,linphone_friend_get_status(lf), int, "%d");
/*wait for refresh*/
wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,4,5000);
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,4,5000));
BC_ASSERT_EQUAL(LinphoneStatusBusy,linphone_friend_get_status(lf), int, "%d");
/*linphone_core_remove_friend(pauline->lc,lf);*/
@ -535,10 +571,24 @@ static void test_subscribe_notify_publish(void) {
BC_ASSERT_EQUAL(LinphonePresenceActivityOffline,linphone_friend_get_status(lf), int, "%d");
*/
/*Expect a notify at publication expiration*/
wait_for_until(pauline->lc,pauline->lc,&pauline->stat.number_of_NotifyPresenceReceived,6,5000);
/*Expect a notify at publication expiration because marie is no longuer scheduled*/
BC_ASSERT_TRUE(wait_for_until(pauline->lc,pauline->lc,&pauline->stat.number_of_NotifyPresenceReceived,6,5000));
BC_ASSERT_EQUAL(LinphoneStatusOffline,linphone_friend_get_status(lf), int, "%d");
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphonePresenceActivityBusy,4,5000));/*re- schedule marie to clean up things*/
/*simulate a rapid presence change to make sure only first and last are transmited*/
linphone_core_set_presence_model(marie->lc,linphone_presence_model_new_with_activity(LinphonePresenceActivityAway,NULL));
linphone_core_set_presence_model(marie->lc,linphone_presence_model_new_with_activity(LinphonePresenceActivityBreakfast,NULL));
linphone_core_set_presence_model(marie->lc,linphone_presence_model_new_with_activity(LinphonePresenceActivityAppointment,NULL));
BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphonePresenceActivityAppointment,1,5000));
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityAway, 1, int,"%i");
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityBreakfast, 0, int,"%i");
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityAppointment, 1, int,"%i");
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
@ -731,6 +781,7 @@ static void test_presence_list(void) {
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(pauline->lc), marie_identity);
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnThePhone, int, "%d");
ms_message("Disabling publish");
enable_publish(laure, FALSE);
enable_publish(marie, FALSE);
enable_publish(pauline, FALSE);
@ -826,7 +877,7 @@ static void test_presence_list_subscription_expire_for_unknown(void) {
linphone_core_manager_destroy(laure);
}
static void test_presence_list_subscribe_dialog_expire(void) {
static void test_presence_list_subscribe_with_error(bool_t io_error) {
LinphoneCoreManager *laure = linphone_core_manager_new("laure_tcp_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc");
const char *rls_uri = "sip:rls@sip.example.org";
@ -835,7 +886,7 @@ static void test_presence_list_subscribe_dialog_expire(void) {
const char *pauline_identity;
MSList* lcs = NULL;
int dummy = 0;
lp_config_set_int(laure->lc->config, "sip", "rls_presence_expires", 3);
lp_config_set_int(laure->lc->config, "sip", "rls_presence_expires", 5);
pauline_identity = get_identity(pauline);
@ -860,7 +911,7 @@ static void test_presence_list_subscribe_dialog_expire(void) {
wait_for_list(lcs, &dummy, 1, 2000); /* Wait a little bit for the subscribe to happen */
enable_publish(pauline, TRUE);
wait_for_list(lcs, &pauline->stat.number_of_NotifyPresenceReceived, 1, 2000);
BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_LinphonePresenceActivityVacation, 1, 6000));
BC_ASSERT_GREATER(laure->stat.number_of_NotifyPresenceReceived, 1, int, "%d");
BC_ASSERT_GREATER(linphone_core_get_default_friend_list(laure->lc)->expected_notification_version, 1, int, "%d");
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity);
@ -872,21 +923,26 @@ static void test_presence_list_subscribe_dialog_expire(void) {
BC_ASSERT_EQUAL(lf->presence_received, FALSE, int, "%d");
BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");
BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_NotifyPresenceReceived, 2, 5000));
ms_message("Simulating in/out packets losses");
sal_set_send_error(laure->lc->sal,1500); /*make sure no refresh is sent, trash the message without generating error*/
sal_set_recv_error(laure->lc->sal, 1500); /*make sure server notify to close the dialog is also ignored*/
wait_for_list(lcs, &dummy, 1, 3000); /* Wait a little bit for the subscribe to happen */
BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_LinphonePresenceActivityVacation, 2, 6000));
if (io_error) {
ms_message("Simulating socket error");
sal_set_recv_error(laure->lc->sal, -1);
wait_for_list(lcs, &dummy, 1, 500); /* just time for socket to be closed */
} else {
ms_message("Simulating in/out packets losses");
sal_set_send_error(laure->lc->sal,1500); /*make sure no refresh is sent, trash the message without generating error*/
sal_set_recv_error(laure->lc->sal, 1500); /*make sure server notify to close the dialog is also ignored*/
wait_for_list(lcs, &dummy, 1, 5000); /* Wait a little bit for the subscribe to happen */
}
/*restart normal behavior*/
sal_set_send_error(laure->lc->sal,0);
sal_set_recv_error(laure->lc->sal, 1);
BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_LinphonePresenceActivityVacation, 3, 6000)); /* give time for subscription to recover to avoid to receive 491 Request pending*/
linphone_core_set_presence_model(pauline->lc, linphone_core_create_presence_model_with_activity(pauline->lc, LinphonePresenceActivityAway, NULL));
BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_NotifyPresenceReceived, 3, 5000));
BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_LinphonePresenceActivityAway, 1, 6000));
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity);
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusAway, int, "%d");
@ -894,7 +950,13 @@ static void test_presence_list_subscribe_dialog_expire(void) {
linphone_core_manager_destroy(pauline);
}
static void test_presence_list_subscribe_dialog_expire(void) {
test_presence_list_subscribe_with_error(FALSE);
}
static void test_presence_list_subscribe_io_error(void) {
test_presence_list_subscribe_with_error(TRUE);
}
test_t presence_tests[] = {
TEST_NO_TAG("Simple Subscribe", simple_subscribe),
@ -911,7 +973,8 @@ test_t presence_tests[] = {
TEST_NO_TAG("Forked subscribe with late publish", test_forked_subscribe_notify_publish),
TEST_NO_TAG("Presence list", test_presence_list),
TEST_NO_TAG("Presence list, subscription expiration for unknown contact",test_presence_list_subscription_expire_for_unknown),
TEST_NO_TAG("Presence list, silent subscription expiration", test_presence_list_subscribe_dialog_expire)
TEST_NO_TAG("Presence list, silent subscription expiration", test_presence_list_subscribe_dialog_expire),
TEST_NO_TAG("Presence list, io error",test_presence_list_subscribe_io_error)
};
test_suite_t presence_test_suite = {"Presence", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,

View file

@ -235,7 +235,7 @@ static void change_expires(void){
LinphoneProxyConfig* proxy_config;
register_with_refresh_base(lcm->lc,FALSE,NULL,NULL);
linphone_core_get_default_proxy(lcm->lc,&proxy_config);
proxy_config = linphone_core_get_default_proxy_config(lcm->lc);
linphone_proxy_config_edit(proxy_config);
reset_counters(counters); /*clear stats*/

View file

@ -248,7 +248,7 @@ LinphoneCoreManager *get_manager(LinphoneCore *lc){
}
bool_t transport_supported(LinphoneTransportType transport) {
Sal *sal = sal_init();
Sal *sal = sal_init(NULL);
bool_t supported = sal_transport_available(sal,(SalTransport)transport);
if (!supported) ms_message("TLS transport not supported, falling back to TCP if possible otherwise skipping test.");
sal_uninit(sal);
@ -296,13 +296,13 @@ void linphone_core_manager_init(LinphoneCoreManager *mgr, const char* rc_file) {
{
MSWebCam *cam;
cam = ms_web_cam_manager_get_cam(ms_web_cam_manager_get(), "Mire: Mire (synthetic moving picture)");
cam = ms_web_cam_manager_get_cam(ms_factory_get_web_cam_manager(mgr->lc->factory), "Mire: Mire (synthetic moving picture)");
if (cam == NULL) {
MSWebCamDesc *desc = ms_mire_webcam_desc_get();
if (desc){
cam=ms_web_cam_new(desc);
ms_web_cam_manager_add_cam(ms_web_cam_manager_get(), cam);
ms_web_cam_manager_add_cam(ms_factory_get_web_cam_manager(mgr->lc->factory), cam);
}
}
}
@ -668,7 +668,7 @@ bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, Linph
return video_enabled ? (realtime_text_enabled ? text_success && audio_success && video_success : audio_success && video_success) : realtime_text_enabled ? text_success && audio_success : audio_success;
}
void linphone_conference_server_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg) {
static void linphone_conference_server_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg) {
LinphoneCoreVTable *vtable = linphone_core_get_current_vtable(lc);
LinphoneConferenceServer *conf_srv = (LinphoneConferenceServer *)vtable->user_data;
@ -697,7 +697,7 @@ void linphone_conference_server_call_state_changed(LinphoneCore *lc, LinphoneCal
}
}
void linphone_conference_server_refer_received(LinphoneCore *core, const char *refer_to) {
static void linphone_conference_server_refer_received(LinphoneCore *core, const char *refer_to) {
char method[20];
LinphoneAddress *refer_to_addr = linphone_address_new(refer_to);
char *uri;
@ -715,17 +715,30 @@ void linphone_conference_server_refer_received(LinphoneCore *core, const char *r
linphone_address_destroy(refer_to_addr);
}
LinphoneConferenceServer* linphone_conference_server_new(const char *rc_file) {
static void linphone_conference_server_registration_state_changed(LinphoneCore *core,
LinphoneProxyConfig *cfg,
LinphoneRegistrationState cstate,
const char *message) {
LinphoneCoreVTable *vtable = linphone_core_get_current_vtable(core);
LinphoneConferenceServer *m = (LinphoneConferenceServer *)linphone_core_v_table_get_user_data(vtable);
if(cfg == linphone_core_get_default_proxy_config(core)) {
m->reg_state = cstate;
}
}
LinphoneConferenceServer* linphone_conference_server_new(const char *rc_file, bool_t do_registration) {
LinphoneConferenceServer *conf_srv = (LinphoneConferenceServer *)ms_new0(LinphoneConferenceServer, 1);
LinphoneCoreManager *lm = (LinphoneCoreManager *)conf_srv;
conf_srv->vtable = linphone_core_v_table_new();
conf_srv->vtable->call_state_changed = linphone_conference_server_call_state_changed;
conf_srv->vtable->refer_received = linphone_conference_server_refer_received;
conf_srv->vtable->registration_state_changed = linphone_conference_server_registration_state_changed;
conf_srv->vtable->user_data = conf_srv;
conf_srv->reg_state = LinphoneRegistrationNone;
linphone_core_manager_init(lm, rc_file);
linphone_core_add_listener(lm->lc, conf_srv->vtable);
linphone_core_manager_start(lm, TRUE);
linphone_core_manager_start(lm, do_registration);
return conf_srv;
}

View file

@ -164,7 +164,7 @@ int main(int argc, char *argv[]){
{
MSWebCamDesc *desc = ms_mire_webcam_desc_get();
if (desc){
ms_web_cam_manager_add_cam(ms_web_cam_manager_get(),ms_web_cam_new(desc));
ms_web_cam_manager_add_cam(ms_factory_get_web_cam_manager(linphone_core_get_ms_factory(lc)),ms_web_cam_new(desc));
linphone_core_set_video_device(lc,"Mire: Mire (synthetic moving picture)");
}
}

View file

@ -51,7 +51,7 @@ int main(int argc, char *argv[]) {
linphone_core_enable_logs(stdout);
lc = linphone_core_new(&vtable, NULL, NULL, NULL);
lsd = linphone_sound_daemon_new(NULL, 44100, 1);
lsd = linphone_sound_daemon_new(linphone_core_get_ms_factory(lc), NULL, 44100, 1);
linphone_core_use_sound_daemon(lc, lsd);