Remove C strings and bctoolbox lists where possible in the sal.

This commit is contained in:
Ghislain MARY 2018-05-11 14:57:44 +02:00
parent 044ad7be6d
commit 579485228c
17 changed files with 460 additions and 557 deletions

View file

@ -452,8 +452,6 @@ LinphoneAuthInfo * linphone_core_create_auth_info(LinphoneCore *lc, const char *
void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info){
LinphoneAuthInfo *ai;
bctbx_list_t *elem;
bctbx_list_t *l;
int restarted_op_count=0;
bool_t updating=FALSE;
@ -472,8 +470,8 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info)
lc->auth_info=bctbx_list_append(lc->auth_info,linphone_auth_info_clone(info));
/* retry pending authentication operations */
for(l=elem=lc->sal->getPendingAuths();elem!=NULL;elem=elem->next){
LinphonePrivate::SalOp *op= static_cast<LinphonePrivate::SalOp*>(elem->data);
auto pendingAuths = lc->sal->getPendingAuths();
for (const auto &op : pendingAuths) {
LinphoneAuthInfo *ai;
const SalAuthInfo *req_sai=op->getAuthRequested();
ai=(LinphoneAuthInfo*)_linphone_core_find_auth_info(lc,req_sai->realm,req_sai->username,req_sai->domain, FALSE);
@ -504,7 +502,7 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info)
restarted_op_count++;
}
}
if (l){
if (!pendingAuths.empty()) {
ms_message("linphone_core_add_auth_info(): restarted [%i] operation(s) after %s auth info for\n"
"\tusername: [%s]\n"
"\trealm [%s]\n"
@ -515,7 +513,6 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info)
info->realm ? info->realm : "",
info->domain ? info->domain : "");
}
bctbx_list_free(l);
write_auth_infos(lc);
}

View file

@ -77,7 +77,7 @@ static void call_received(SalCallOp *h) {
if (pAssertedId) {
LinphoneAddress *pAssertedIdAddr = linphone_address_new(pAssertedId);
if (pAssertedIdAddr) {
ms_message("Using P-Asserted-Identity [%s] instead of from [%s] for op [%p]", pAssertedId, h->getFrom(), h);
ms_message("Using P-Asserted-Identity [%s] instead of from [%s] for op [%p]", pAssertedId, h->getFrom().c_str(), h);
fromAddr = pAssertedIdAddr;
} else
ms_warning("Unsupported P-Asserted-Identity header for op [%p] ", h);
@ -86,8 +86,8 @@ static void call_received(SalCallOp *h) {
}
if (!fromAddr)
fromAddr = linphone_address_new(h->getFrom());
LinphoneAddress *toAddr = linphone_address_new(h->getTo());
fromAddr = linphone_address_new(h->getFrom().c_str());
LinphoneAddress *toAddr = linphone_address_new(h->getTo().c_str());
if (_linphone_core_is_conference_creation(lc, toAddr)) {
linphone_address_unref(toAddr);
@ -136,7 +136,7 @@ static void call_received(SalCallOp *h) {
);
if (!chatRoom) {
chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom(
L_C_TO_STRING(h->getSubject()), h->getRemoteContact(), h->getRemoteBody(), false
h->getSubject(), h->getRemoteContact(), h->getRemoteBody(), false
);
}
L_GET_PRIVATE(static_pointer_cast<ClientGroupChatRoom>(chatRoom))->confirmJoining(h);
@ -218,7 +218,7 @@ static void call_rejected(SalCallOp *h){
LinphoneCore *lc = reinterpret_cast<LinphoneCore *>(h->getSal()->getUserPointer());
LinphoneErrorInfo *ei = linphone_error_info_new();
linphone_error_info_from_sal_op(ei, h);
linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, linphone_address_new(h->getFrom()), linphone_address_new(h->getTo()), ei);
linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, linphone_address_new(h->getFrom().c_str()), linphone_address_new(h->getTo().c_str()), ei);
}
static void call_ringing(SalOp *h) {

View file

@ -124,8 +124,8 @@ LinphoneChatRoom *linphone_core_find_one_to_one_chat_room (
int linphone_core_message_received(LinphoneCore *lc, LinphonePrivate::SalOp *op, const SalMessage *sal_msg) {
LinphoneReason reason = LinphoneReasonNotAcceptable;
const char *peerAddress;
const char *localAddress;
std::string peerAddress;
std::string localAddress;
if (linphone_core_conference_server_enabled(lc)) {
localAddress = peerAddress = op->getTo();
} else {

View file

@ -1305,7 +1305,7 @@ static void sip_config_read(LinphoneCore *lc) {
lc->sal->useNoInitialRoute(!!lp_config_get_int(lc->config,"sip","use_no_initial_route",0));
lc->sal->useRport(!!lp_config_get_int(lc->config,"sip","use_rport",1));
lc->sal->setContactLinphoneSpecs(lp_config_get_string(lc->config, "sip", "linphone_specs", NULL));
lc->sal->setContactLinphoneSpecs(lp_config_get_string(lc->config, "sip", "linphone_specs", ""));
if (!lp_config_get_int(lc->config,"sip","ipv6_migration_done",FALSE) && lp_config_has_entry(lc->config,"sip","use_ipv6")) {
lp_config_clean_entry(lc->config,"sip","use_ipv6");
@ -2233,7 +2233,7 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig
lc->sal=new Sal(NULL);
lc->sal->setRefresherRetryAfter(lp_config_get_int(lc->config, "sip", "refresher_retry_after", 60000));
lc->sal->setHttpProxyHost(linphone_core_get_http_proxy_host(lc));
lc->sal->setHttpProxyHost(L_C_TO_STRING(linphone_core_get_http_proxy_host(lc)));
lc->sal->setHttpProxyPort(linphone_core_get_http_proxy_port(lc));
lc->sal->setUserPointer(lc);
@ -2332,8 +2332,8 @@ void linphone_core_start (LinphoneCore *lc) {
}else if (strcmp(uuid,"0")!=0) /*to allow to disable sip.instance*/
lc->sal->setUuid(uuid);
if (lc->sal->getRootCa()) {
belle_tls_crypto_config_set_root_ca(lc->http_crypto_config, lc->sal->getRootCa());
if (!lc->sal->getRootCa().empty()) {
belle_tls_crypto_config_set_root_ca(lc->http_crypto_config, lc->sal->getRootCa().c_str());
belle_http_provider_set_tls_crypto_config(lc->http_provider, lc->http_crypto_config);
}
@ -2868,7 +2868,7 @@ void linphone_core_set_user_agent(LinphoneCore *lc, const char *name, const char
}
}
const char *linphone_core_get_user_agent(LinphoneCore *lc){
return lc->sal->getUserAgent();
return lc->sal->getUserAgent().c_str();
}
const char *linphone_core_get_user_agent_name(void){
@ -3554,7 +3554,7 @@ void linphone_configure_op_with_proxy(LinphoneCore *lc, SalOp *op, const Linphon
op->setToAddress(L_GET_PRIVATE_FROM_C_OBJECT(dest)->getInternalAddress());
op->setFrom(identity);
op->setSentCustomHeaders(headers);
op->setRealm(linphone_proxy_config_get_realm(proxy));
op->setRealm(L_C_TO_STRING(linphone_proxy_config_get_realm(proxy)));
if (with_contact && proxy && proxy->op){
const LinphoneAddress *contact = linphone_proxy_config_get_contact(proxy);
@ -4310,7 +4310,7 @@ const char *linphone_core_get_ring(const LinphoneCore *lc){
}
void linphone_core_set_root_ca(LinphoneCore *lc, const char *path) {
lc->sal->setRootCa(path);
lc->sal->setRootCa(L_C_TO_STRING(path));
if (lc->http_crypto_config) {
belle_tls_crypto_config_set_root_ca(lc->http_crypto_config, path);
}
@ -4318,8 +4318,8 @@ void linphone_core_set_root_ca(LinphoneCore *lc, const char *path) {
}
void linphone_core_set_root_ca_data(LinphoneCore *lc, const char *data) {
lc->sal->setRootCa(NULL);
lc->sal->setRootCaData(data);
lc->sal->setRootCa("");
lc->sal->setRootCaData(L_C_TO_STRING(data));
if (lc->http_crypto_config) {
belle_tls_crypto_config_set_root_ca_data(lc->http_crypto_config, data);
}
@ -6778,12 +6778,12 @@ const char * linphone_core_get_file_transfer_server(LinphoneCore *core) {
void linphone_core_add_supported_tag(LinphoneCore *lc, const char *tag){
lc->sal->addSupportedTag(tag);
lp_config_set_string(lc->config,"sip","supported",lc->sal->getSupportedTags());
lp_config_set_string(lc->config,"sip","supported",lc->sal->getSupportedTags().c_str());
}
void linphone_core_remove_supported_tag(LinphoneCore *lc, const char *tag){
lc->sal->removeSupportedTag(tag);
lp_config_set_string(lc->config,"sip","supported",lc->sal->getSupportedTags());
lp_config_set_string(lc->config,"sip","supported",lc->sal->getSupportedTags().c_str());
}
void linphone_core_set_avpf_mode(LinphoneCore *lc, LinphoneAVPFMode mode){
@ -7339,5 +7339,5 @@ const char *linphone_core_get_linphone_specs (const LinphoneCore *core) {
void linphone_core_set_linphone_specs (LinphoneCore *core, const char *specs) {
lp_config_set_string(linphone_core_get_config(core), "sip", "linphone_specs", specs);
core->sal->setContactLinphoneSpecs(specs);
core->sal->setContactLinphoneSpecs(L_C_TO_STRING(specs));
}

View file

@ -2000,7 +2000,7 @@ void linphone_subscription_closed(LinphoneCore *lc, SalOp *op){
linphone_friend_remove_incoming_subscription(lf, op);
}else{
/*case of an op that we already released because the friend was destroyed*/
ms_message("Receiving unsuscribe for unknown in-subscribtion from %s", op->getFrom());
ms_message("Receiving unsuscribe for unknown in-subscribtion from %s", op->getFrom().c_str());
}
}

View file

@ -505,13 +505,12 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) {
const LinphoneCallParams * current_params = linphone_call_get_current_params(call);
LinphoneCallLog *log = L_GET_CPP_PTR_FROM_C_OBJECT(call)->getLog();
reporting_session_report_t * report = log->reporting.reports[stats_type];
char * dialog_id;
// call->op might be already released if hanging up in state LinphoneCallOutgoingInit
if (!media_report_enabled(call, stats_type) || !L_GET_PRIVATE_FROM_C_OBJECT(call)->getOp())
return;
dialog_id = L_GET_PRIVATE_FROM_C_OBJECT(call)->getOp()->getDialogId();
std::string dialogId = L_GET_PRIVATE_FROM_C_OBJECT(call)->getOp()->getDialogId();
STR_REASSIGN(report->info.call_id, ms_strdup(log->call_id));
@ -521,13 +520,13 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) {
// RFC states: "LocalGroupID provides the identification for the purposes
// of aggregation for the local endpoint.".
STR_REASSIGN(report->info.local_addr.group, ms_strdup_printf("%s-%s-%s"
, dialog_id ? dialog_id : ""
, dialogId.c_str()
, "local"
, report->local_metrics.user_agent ? report->local_metrics.user_agent : ""
)
);
STR_REASSIGN(report->info.remote_addr.group, ms_strdup_printf("%s-%s-%s"
, dialog_id ? dialog_id : ""
, dialogId.c_str()
, "remote"
, report->remote_metrics.user_agent ? report->remote_metrics.user_agent : ""
)
@ -582,7 +581,7 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) {
}
}
STR_REASSIGN(report->dialog_id, ms_strdup_printf("%s;%u", dialog_id ? dialog_id : "", report->info.local_addr.ssrc));
STR_REASSIGN(report->dialog_id, ms_strdup_printf("%s;%u", dialogId.c_str(), report->info.local_addr.ssrc));
if (local_payload != NULL) {
report->local_metrics.session_description.payload_type = local_payload->type;
@ -597,8 +596,6 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) {
report->remote_metrics.session_description.sample_rate = remote_payload->clock_rate;
STR_REASSIGN(report->remote_metrics.session_description.fmtp, ms_strdup(remote_payload->recv_fmtp));
}
ms_free(dialog_id);
}
/* generate random float in interval ] 0.9 t ; 1.1 t [*/

View file

@ -576,7 +576,7 @@ void linphone_call_ogl_render (const LinphoneCall *call) {
LinphoneStatus linphone_call_send_info_message (LinphoneCall *call, const LinphoneInfoMessage *info) {
SalBodyHandler *body_handler = sal_body_handler_from_content(linphone_info_message_get_content(info));
linphone_call_get_op(call)->setSentCustomHeaders(linphone_info_message_get_headers(info));
return linphone_call_get_op(call)->sendInfo(nullptr, nullptr, body_handler);
return linphone_call_get_op(call)->sendInfo(body_handler);
}
LinphoneCallStats *linphone_call_get_stats (LinphoneCall *call, LinphoneStreamType type) {

View file

@ -177,11 +177,11 @@ bool CallSessionPrivate::startPing () {
pingReplied = false;
pingOp = new SalOp(q->getCore()->getCCore()->sal);
if (direction == LinphoneCallIncoming) {
const char *from = pingOp->getFrom();
const char *to = pingOp->getTo();
string from = pingOp->getFrom();
string to = pingOp->getTo();
linphone_configure_op(q->getCore()->getCCore(), pingOp, log->from, nullptr, false);
pingOp->setRoute(op->getNetworkOrigin());
pingOp->ping(from, to);
pingOp->ping(from.c_str(), to.c_str());
} else if (direction == LinphoneCallOutgoing) {
char *from = linphone_address_as_string(log->from);
char *to = linphone_address_as_string(log->to);
@ -786,12 +786,12 @@ void CallSessionPrivate::reinviteToRecoverFromConnectionLoss () {
void CallSessionPrivate::repairByInviteWithReplaces () {
L_Q();
const char *callId = op->getCallId();
string callId = op->getCallId();
const char *fromTag = op->getLocalTag();
const char *toTag = op->getRemoteTag();
op->killDialog();
createOp();
op->setReplaces(callId, fromTag, toTag);
op->setReplaces(callId.c_str(), fromTag, toTag);
q->startInvite(nullptr);
}
@ -937,7 +937,7 @@ void CallSession::configure (LinphoneCallDir direction, LinphoneProxyConfig *cfg
linphone_core_get_config(getCore()->getCCore()), "sip", "cnx_ip_to_0000_if_sendonly_enabled", 0
)
);
d->log->call_id = ms_strdup(op->getCallId()); /* Must be known at that time */
d->log->call_id = ms_strdup(op->getCallId().c_str()); /* Must be known at that time */
}
if (direction == LinphoneCallOutgoing) {
@ -1109,7 +1109,7 @@ int CallSession::startInvite (const Address *destination, const string &subject,
d->setState(CallSession::State::Error, "Call failed");
}
} else {
d->log->call_id = ms_strdup(d->op->getCallId()); /* Must be known at that time */
d->log->call_id = ms_strdup(d->op->getCallId().c_str()); /* Must be known at that time */
d->setState(CallSession::State::OutgoingProgress, "Outgoing call in progress");
}
return result;
@ -1326,7 +1326,7 @@ string CallSession::getToHeader (const string &name) const {
string CallSession::getRemoteUserAgent () const {
L_D();
if (d->op && d->op->getRemoteUserAgent())
if (d->op)
return d->op->getRemoteUserAgent();
return string();
}

View file

@ -66,10 +66,8 @@ bool CorePrivate::inviteReplacesABrokenCall (SalCallOp *op) {
shared_ptr<CallSession> session = call->getPrivate()->getActiveSession();
if (session
&& ((session->getPrivate()->isBroken() && op->compareOp(session->getPrivate()->getOp()))
|| ((replacedSession == session.get())
&& (strcmp(op->getFrom(), replacedOp->getFrom()) == 0)
&& (strcmp(op->getTo(), replacedOp->getTo()) == 0)))
) {
|| (replacedSession == session.get() && op->getFrom() == replacedOp->getFrom() && op->getTo() == replacedOp->getTo())
)) {
session->getPrivate()->replaceOp(op);
return true;
}

View file

@ -464,7 +464,7 @@ void SalCallOp::processResponseCb(void *op_base, const belle_sip_response_event_
belle_sip_object_unref(op->mSdpAnswer);
op->mSdpAnswer=NULL;
}
belle_sip_message_add_header(BELLE_SIP_MESSAGE(ack),BELLE_SIP_HEADER(op->mRoot->mUserAgent));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(ack),BELLE_SIP_HEADER(op->mRoot->mUserAgentHeader));
op->mRoot->mCallbacks.call_accepted(op); /*INVITE*/
op->mRoot->mCallbacks.call_ack_being_sent(op, (SalCustomHeader*)ack);
belle_sip_dialog_send_ack(op->mDialog,ack);
@ -495,7 +495,7 @@ void SalCallOp::processResponseCb(void *op_base, const belle_sip_response_event_
break;
case State::Terminated:
default:
ms_error("Call op [%p] receives unexpected answer [%i] while in state [%s].",op,code, toString(op->mState));
lError() << "Call op [" << op << "] receives unexpected answer [" << code << "] while in state [" << toString(op->mState) << "]";
}
}
break;
@ -645,7 +645,7 @@ void SalCallOp::callTerminated(belle_sip_server_transaction_t* server_transactio
setReasonErrorInfo(BELLE_SIP_MESSAGE(cancel_request ? cancel_request : server_req));
resp=createResponseFromRequest(server_req,status_code);
belle_sip_server_transaction_send_response(server_transaction,resp);
mRoot->mCallbacks.call_terminated(this,mDir==Dir::Incoming?getFrom():getTo());
mRoot->mCallbacks.call_terminated(this,mDir==Dir::Incoming?getFrom().c_str():getTo().c_str());
}
void SalCallOp::resetDescriptions() {
@ -704,7 +704,7 @@ void SalCallOp::processRequestEventCb(void *op_base, const belle_sip_request_eve
if (!op->mDialog) {
op->setOrUpdateDialog(belle_sip_provider_create_dialog(op->mRoot->mProvider, BELLE_SIP_TRANSACTION(op->mPendingServerTransaction)));
ms_message("new incoming call from [%s] to [%s]",op->getFrom(),op->getTo());
ms_message("new incoming call from [%s] to [%s]",op->getFrom().c_str(),op->getTo().c_str());
}
dialog_state=belle_sip_dialog_get_state(op->mDialog);
switch(dialog_state) {
@ -874,7 +874,7 @@ void SalCallOp::processDialogTerminatedCb(void *ctx, const belle_sip_dialog_term
case BELLE_SIP_DIALOG_CONFIRMED:
if (op->mState!=State::Terminated && op->mState!=State::Terminating) {
/*this is probably a normal termination from a BYE*/
op->mRoot->mCallbacks.call_terminated(op,op->mDir==Dir::Incoming?op->getFrom():op->getTo());
op->mRoot->mCallbacks.call_terminated(op,op->mDir==Dir::Incoming?op->getFrom().c_str():op->getTo().c_str());
op->mState=State::Terminating;
}
break;
@ -1091,9 +1091,7 @@ int SalCallOp::update(const char *subject, bool no_user_consent) {
if (mDialog == NULL) {
/* If the dialog does not exist, this is that we are trying to recover from a connection loss
during a very early state of outgoing call initiation (the dialog has not been created yet). */
const char *from = getFrom();
const char *to = getTo();
return call(from, to, subject);
return call(mFrom.c_str(), mTo.c_str(), subject);
}
state = belle_sip_dialog_get_state(mDialog);
@ -1126,7 +1124,7 @@ int SalCallOp::update(const char *subject, bool no_user_consent) {
int SalCallOp::cancelInvite(const SalErrorInfo *info) {
belle_sip_request_t* cancel;
ms_message("Cancelling INVITE request from [%s] to [%s] ",getFrom(), getTo());
ms_message("Cancelling INVITE request from [%s] to [%s] ",getFrom().c_str(), getTo().c_str());
if (mPendingClientTransaction == NULL) {
ms_warning("There is no transaction to cancel.");
@ -1315,7 +1313,7 @@ int SalCallOp::terminate(const SalErrorInfo *info) {
p_sei = info;
}
if (mState==State::Terminating || mState==State::Terminated) {
ms_error("Cannot terminate op [%p] in state [%s]",this,toString(mState));
lError() << "Cannot terminate op [" << this << "] in state [" << toString(mState) << "]";
ret = -1;
goto end;
}
@ -1393,10 +1391,10 @@ void SalCallOp::sendVfuRequest() {
error=sendRequest(info);
}
if (error)
ms_warning("Cannot send vfu request to [%s] ", getTo());
ms_warning("Cannot send vfu request to [%s] ", getTo().c_str());
} else {
ms_warning("Cannot send vfu request to [%s] because dialog [%p] in wrong state [%s]",getTo()
ms_warning("Cannot send vfu request to [%s] because dialog [%p] in wrong state [%s]",getTo().c_str()
,mDialog
,belle_sip_dialog_state_to_string(dialog_state));
}
@ -1538,7 +1536,7 @@ int SalCallOp::sendMessage (const Content &content) {
}
bool SalCallOp::compareOp(const SalCallOp *op2) const {
return (strcmp(mCallId, op2->mCallId) == 0);
return mCallId == op2->mCallId;
}
void SalCallOp::handleOfferAnswerResponse(belle_sip_response_t* response) {

View file

@ -80,7 +80,7 @@ void SalSubscribeOp::handleNotify(belle_sip_request_t *req, const char *eventnam
if (!subscription_state_header || strcasecmp(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,belle_sip_header_subscription_state_get_state(subscription_state_header)) ==0) {
sub_state=SalSubscribeTerminated;
ms_message("Outgoing subscription terminated by remote [%s]",getTo());
ms_message("Outgoing subscription terminated by remote [%s]",getTo().c_str());
} else
sub_state=SalSubscribeActive;
ref();
@ -133,7 +133,7 @@ void SalSubscribeOp::subscribeProcessRequestEventCb(void *op_base, const belle_s
return;
}
op->setOrUpdateDialog(dialog);
ms_message("new incoming subscription from [%s] to [%s]",op->getFrom(),op->getTo());
ms_message("new incoming subscription from [%s] to [%s]",op->getFrom().c_str(),op->getTo().c_str());
}else{ /*this is a NOTIFY*/
op->handleNotify(req, eventname, (SalBodyHandler *)body_handler);
return;
@ -162,7 +162,7 @@ void SalSubscribeOp::subscribeProcessRequestEventCb(void *op_base, const belle_s
resp=op->createResponseFromRequest(req,200);
belle_sip_server_transaction_send_response(server_transaction,resp);
} else if(expires) {
ms_message("Unsubscribe received from [%s]",op->getFrom());
ms_message("Unsubscribe received from [%s]",op->getFrom().c_str());
resp=op->createResponseFromRequest(req,200);
belle_sip_server_transaction_send_response(server_transaction,resp);
op->mRoot->mCallbacks.incoming_subscribe_closed(op);
@ -366,16 +366,16 @@ void SalPublishOp::publishRefresherListenerCb (belle_sip_refresher_t* refresher,
SalPublishOp * op = (SalPublishOp *)user_pointer;
const belle_sip_client_transaction_t* last_publish_trans=belle_sip_refresher_get_transaction(op->mRefresher);
belle_sip_response_t *response=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(last_publish_trans));
ms_message("Publish refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase?reason_phrase:"none",op->getProxy());
ms_message("Publish refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase?reason_phrase:"none",op->getProxy().c_str());
if (status_code==0){
op->mRoot->mCallbacks.on_expire(op);
}else if (status_code>=200){
belle_sip_header_t *sip_etag;
const char *sip_etag_string = NULL;
string sipEtagStr;
if (response && (sip_etag = belle_sip_message_get_header(BELLE_SIP_MESSAGE(response), "SIP-ETag"))) {
sip_etag_string = belle_sip_header_get_unparsed_value(sip_etag);
sipEtagStr = belle_sip_header_get_unparsed_value(sip_etag);
}
op->setEntityTag(sip_etag_string);
op->setEntityTag(sipEtagStr);
sal_error_info_set(&op->mErrorInfo,SalReasonUnknown, "SIP", (int)status_code, reason_phrase, NULL);
op->assignRecvHeaders((belle_sip_message_t*)response);
op->mRoot->mCallbacks.on_publish_response(op);
@ -395,11 +395,10 @@ int SalPublishOp::publish(const char *from, const char *to, const char *eventnam
if( req == NULL ){
return -1;
}
if (getEntityTag()) {
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("SIP-If-Match", getEntityTag()));
}
if (!mEntityTag.empty())
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req), belle_sip_header_create("SIP-If-Match", mEntityTag.c_str()));
if (getContactAddress()){
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(createContact()));
}

View file

@ -19,6 +19,7 @@
#include <cstring>
#include "c-wrapper/internal/c-tools.h"
#include "sal/op.h"
#include "bellesip_sal/sal_impl.h"
@ -35,7 +36,7 @@ SalOp::SalOp(Sal *sal) {
}
SalOp::~SalOp() {
ms_message("Destroying op [%p] of type [%s]",this,toString(mType));
lInfo() << "Destroying op [" << this << "] of type [" << toString(mType) << "]";
if (mPendingAuthTransaction) belle_sip_object_unref(mPendingAuthTransaction);
mRoot->removePendingAuth(this);
@ -77,62 +78,21 @@ SalOp::~SalOp() {
mOriginAddress=NULL;
}
if (mFrom) {
ms_free(mFrom);
mFrom=NULL;
}
if (mTo) {
ms_free(mTo);
mTo=NULL;
}
if (mSubject) {
ms_free(mSubject);
mSubject = NULL;
}
if (mRoute) {
ms_free(mRoute);
mRoute=NULL;
}
if (mRealm) {
ms_free(mRealm);
mRealm=NULL;
}
if (mContactAddress) {
sal_address_destroy(mContactAddress);
}
if (mOrigin){
ms_free(mOrigin);
mOrigin=NULL;
}
if (mRemoteUserAgent){
ms_free(mRemoteUserAgent);
mRemoteUserAgent=NULL;
}
if (mRemoteContact){
ms_free(mRemoteContact);
mRemoteContact=NULL;
}
if (mRemoteContactAddress){
sal_address_destroy(mRemoteContactAddress);
}
if (mCallId)
ms_free(mCallId);
if (mServiceRoute) {
sal_address_destroy(mServiceRoute);
}
if (mRouteAddresses){
bctbx_list_for_each(mRouteAddresses,(void (*)(void*)) sal_address_destroy);
mRouteAddresses=bctbx_list_free(mRouteAddresses);
}
for (auto &addr : mRouteAddresses)
sal_address_unref(addr);
if (mRecvCustomHeaders)
sal_custom_header_free(mRecvCustomHeaders);
if (mSentCustomHeaders)
sal_custom_header_free(mSentCustomHeaders);
if (mEntityTag != NULL){
ms_free(mEntityTag);
mEntityTag = NULL;
}
}
SalOp *SalOp::ref() {
@ -155,37 +115,28 @@ void SalOp::setContactAddress(const SalAddress *address) {
mContactAddress=address?sal_address_clone(address):NULL;
}
void SalOp::assignAddress(SalAddress** address, const char *value) {
if (*address){
void SalOp::assignAddress (SalAddress **address, const string &value) {
if (*address) {
sal_address_destroy(*address);
*address=NULL;
*address = nullptr;
}
if (value)
*address=sal_address_new(value);
if (!value.empty())
*address = sal_address_new(value.c_str());
}
void SalOp::assignString(char **str, const char *arg) {
if (*str){
ms_free(*str);
*str=NULL;
void SalOp::setRoute (const string &value) {
for (auto &address : mRouteAddresses)
sal_address_unref(address);
mRouteAddresses.clear();
if (value.empty()) {
mRoute.clear();
} else {
auto address = sal_address_new(value.c_str());
mRouteAddresses.push_back(address);
char *routeStr = sal_address_as_string(address);
mRoute = routeStr;
ms_free(routeStr);
}
if (arg)
*str=ms_strdup(arg);
}
void SalOp::setRoute(const char *route) {
char* route_string=NULL;
if (mRouteAddresses) {
bctbx_list_for_each(mRouteAddresses,(void (*)(void *))sal_address_destroy);
mRouteAddresses=bctbx_list_free(mRouteAddresses);
}
if (route) {
mRouteAddresses=bctbx_list_append(NULL,NULL);
assignAddress((SalAddress**)&(mRouteAddresses->data),route);
route_string=sal_address_as_string((SalAddress*)mRouteAddresses->data);
}
assignString(&mRoute,route_string);
if(route_string) ms_free(route_string);
}
void SalOp::setRouteAddress(const SalAddress *address){
@ -194,33 +145,22 @@ void SalOp::setRouteAddress(const SalAddress *address){
ms_free(address_string);
}
void SalOp::addRouteAddress(const SalAddress *address) {
if (mRouteAddresses) {
mRouteAddresses=bctbx_list_append(mRouteAddresses,(void*)sal_address_clone(address));
} else {
setRouteAddress(address);
}
void SalOp::addRouteAddress (const SalAddress *address) {
if (mRouteAddresses.empty())
setRouteAddress(address);
else
mRouteAddresses.push_back(sal_address_clone(address));
}
void SalOp::setRealm(const char *realm) {
if (mRealm != NULL){
ms_free(mRealm);
}
mRealm = ms_strdup(realm);
}
void SalOp::setSubject (const char *subject) {
assignString(&mSubject, subject);
}
void SalOp::setFrom (const char *value) {
char *valueStr = nullptr;
void SalOp::setFrom (const string &value) {
assignAddress(&mFromAddress, value);
if (mFromAddress)
valueStr = sal_address_as_string(mFromAddress);
assignString(&mFrom, valueStr);
if (valueStr)
if (mFromAddress) {
char *valueStr = sal_address_as_string(mFromAddress);
mFrom = valueStr;
ms_free(valueStr);
} else {
mFrom.clear();
}
}
void SalOp::setFromAddress(const SalAddress *from) {
@ -229,14 +169,15 @@ void SalOp::setFromAddress(const SalAddress *from) {
ms_free(address_string);
}
void SalOp::setTo (const char *value) {
char *valueStr = nullptr;
void SalOp::setTo (const string &value) {
assignAddress(&mToAddress, value);
if (mToAddress)
valueStr = sal_address_as_string(mToAddress);
assignString(&mTo, valueStr);
if (valueStr)
if (mToAddress) {
char *valueStr = sal_address_as_string(mToAddress);
mTo = valueStr;
ms_free(valueStr);
} else {
mTo.clear();
}
}
void SalOp::setToAddress(const SalAddress *to) {
@ -255,7 +196,7 @@ int SalOp::refresh() {
belle_sip_refresher_refresh(mRefresher,belle_sip_refresher_get_expires(mRefresher));
return 0;
}
ms_warning("sal_refresh on op [%p] of type [%s] no refresher",this,toString(mType));
lWarning() << "No refresher on op [" << this << "] of type [" << toString(mType) << "]";
return -1;
}
@ -281,7 +222,6 @@ void SalOp::release() {
int SalOp::sendRequestWithContact(belle_sip_request_t* request, bool add_contact) {
belle_sip_client_transaction_t* client_transaction;
belle_sip_provider_t* prov=mRoot->mProvider;
belle_sip_uri_t* outbound_proxy=NULL;
belle_sip_header_contact_t* contact;
int result =-1;
belle_sip_uri_t *next_hop_uri=NULL;
@ -295,17 +235,15 @@ int SalOp::sendRequestWithContact(belle_sip_request_t* request, bool add_contact
if (!mDialog || belle_sip_dialog_get_state(mDialog) == BELLE_SIP_DIALOG_NULL) {
/*don't put route header if dialog is in confirmed state*/
const MSList *elem=getRouteAddresses();
auto routeAddresses = getRouteAddresses();
const char *transport;
const char *method=belle_sip_request_get_method(request);
belle_sip_listening_point_t *udplp=belle_sip_provider_get_listening_point(prov,"UDP");
if (elem) {
outbound_proxy=belle_sip_header_address_get_uri((belle_sip_header_address_t*)elem->data);
next_hop_uri=outbound_proxy;
}else{
next_hop_uri=(belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)belle_sip_request_get_uri(request));
}
if (routeAddresses.empty())
next_hop_uri = (belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)belle_sip_request_get_uri(request));
else
next_hop_uri = belle_sip_header_address_get_uri((belle_sip_header_address_t*)routeAddresses.front());
transport=belle_sip_uri_get_transport_param(next_hop_uri);
if (transport==NULL){
/*compatibility mode: by default it should be udp as not explicitely set and if no udp listening point is available, then use
@ -350,18 +288,19 @@ int SalOp::sendRequestWithContact(belle_sip_request_t* request, bool add_contact
belle_sip_object_ref(mPendingClientTransaction);
if (belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request),belle_sip_header_user_agent_t)==NULL)
belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(mRoot->mUserAgent));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(mRoot->mUserAgentHeader));
if (!belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_AUTHORIZATION)
&& !belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_PROXY_AUTHORIZATION)) {
/*hmm just in case we already have authentication param in cache*/
belle_sip_provider_add_authorization(mRoot->mProvider,request,NULL,NULL,NULL,mRealm);
belle_sip_provider_add_authorization(mRoot->mProvider,request,NULL,NULL,NULL,L_STRING_TO_C(mRealm));
}
result = belle_sip_client_transaction_send_request_to(client_transaction,next_hop_uri/*might be null*/);
/*update call id if not set yet for this OP*/
if (result == 0 && !mCallId) {
mCallId=ms_strdup(belle_sip_header_call_id_get_call_id(BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request), belle_sip_header_call_id_t))));
if (result == 0 && mCallId.empty()) {
mCallId = belle_sip_header_call_id_get_call_id(
BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request), belle_sip_header_call_id_t)));
}
return result;
@ -421,11 +360,7 @@ int SalOp::processRedirect(){
setOrUpdateDialog(NULL);
belle_sip_message_remove_header_from_ptr((belle_sip_message_t*)request, (belle_sip_header_t*)callid);
belle_sip_message_add_header((belle_sip_message_t*)request, (belle_sip_header_t*)(callid = belle_sip_provider_create_call_id(getSal()->mProvider)));
if (mCallId){
/*reset the call-id of op, it will be set when new request will be sent*/
ms_free(mCallId);
mCallId = NULL;
}
mCallId.clear(); // Reset the call-id of op, it will be set when new request will be sent
belle_sip_request_set_uri(request, redirect_uri);
redirect_uri = BELLE_SIP_URI(belle_sip_object_clone(BELLE_SIP_OBJECT(redirect_uri)));
belle_sip_uri_set_port(redirect_uri, 0);
@ -465,7 +400,7 @@ void SalOp::processAuthentication() {
return;
}
if (belle_sip_provider_add_authorization(mRoot->mProvider,new_request,response,from_uri,&auth_list,mRealm)) {
if (belle_sip_provider_add_authorization(mRoot->mProvider,new_request,response,from_uri,&auth_list,L_STRING_TO_C(mRealm))) {
if (is_within_dialog)
sendRequest(new_request);
else
@ -494,12 +429,12 @@ void SalOp::processAuthentication() {
}
}
char *SalOp::getDialogId() const {
if (mDialog != NULL) {
return ms_strdup_printf("%s;to-tag=%s;from-tag=%s", mCallId,
belle_sip_dialog_get_remote_tag(mDialog), belle_sip_dialog_get_local_tag(mDialog));
}
return NULL;
string SalOp::getDialogId () const {
if (!mDialog)
return string();
stringstream ss;
ss << mCallId << ";to-tag=" << belle_sip_dialog_get_remote_tag(mDialog) << ";from-tag=" << belle_sip_dialog_get_local_tag(mDialog);
return ss.str();
}
int SalOp::getAddressFamily() const {
@ -545,45 +480,38 @@ bool SalOp::isIdle() const {
return true;
}
void SalOp::setEntityTag(const char* entity_tag) {
if (mEntityTag != NULL) ms_free(mEntityTag);
mEntityTag = entity_tag ? ms_strdup(entity_tag) : NULL;
}
void SalOp::setEvent(const char *eventname) {
belle_sip_header_event_t *header = NULL;
if (mEvent) belle_sip_object_unref(mEvent);
if (eventname){
header = belle_sip_header_event_create(eventname);
void SalOp::setEvent (const string &eventName) {
belle_sip_header_event_t *header = nullptr;
if (mEvent)
belle_sip_object_unref(mEvent);
if (!eventName.empty()) {
header = belle_sip_header_event_create(eventName.c_str());
belle_sip_object_ref(header);
}
mEvent = header;
}
void SalOp::addInitialRouteSet(belle_sip_request_t *request, const MSList *list) {
const MSList *elem;
for (elem=list;elem!=NULL;elem=elem->next){
SalAddress *addr=(SalAddress*)elem->data;
belle_sip_header_route_t *route;
belle_sip_uri_t *uri;
/*Optimization: if the initial route set only contains one URI which is the same as the request URI, ommit it*/
if (elem==list && list->next==NULL){
belle_sip_uri_t *requri=belle_sip_request_get_uri(request);
/*skip the first route it is the same as the request uri*/
if (strcmp(sal_address_get_domain(addr),belle_sip_uri_get_host(requri))==0 ){
ms_message("Skipping top route of initial route-set because same as request-uri.");
void SalOp::addInitialRouteSet (belle_sip_request_t *request, const list<SalAddress *> &routeAddresses) {
bool uniqueRoute = routeAddresses.size() == 1;
for (const auto &address : routeAddresses) {
// Optimization: if the initial route set only contains one URI which is the same as the request URI, ommit it
if (uniqueRoute) {
belle_sip_uri_t *requestUri = belle_sip_request_get_uri(request);
// Skip the first route it is the same as the request uri
if (strcmp(sal_address_get_domain(address), belle_sip_uri_get_host(requestUri)) == 0) {
ms_message("Skipping top route of initial route-set because same as request-uri");
continue;
}
}
route=belle_sip_header_route_create((belle_sip_header_address_t*)addr);
uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)route);
belle_sip_uri_set_lr_param(uri,1);
belle_sip_message_add_header((belle_sip_message_t*)request,(belle_sip_header_t*)route);
belle_sip_header_route_t *route = belle_sip_header_route_create((belle_sip_header_address_t *)address);
belle_sip_uri_t *uri = belle_sip_header_address_get_uri((belle_sip_header_address_t *)route);
belle_sip_uri_set_lr_param(uri, 1);
belle_sip_message_add_header((belle_sip_message_t *)request, (belle_sip_header_t *)route);
}
}
belle_sip_request_t* SalOp::buildRequest(const char* method) {
belle_sip_request_t* SalOp::buildRequest (const string &method) {
belle_sip_header_from_t* from_header;
belle_sip_header_to_t* to_header;
belle_sip_provider_t* prov=mRoot->mProvider;
@ -593,7 +521,6 @@ belle_sip_request_t* SalOp::buildRequest(const char* method) {
belle_sip_header_call_id_t *call_id_header;
const SalAddress* to_address;
const MSList *elem=getRouteAddresses();
char token[10];
/* check that the op has a correct to address */
@ -609,7 +536,7 @@ belle_sip_request_t* SalOp::buildRequest(const char* method) {
return NULL;
}
if (strcmp("REGISTER",method)==0 || mPrivacy==SalPrivacyNone) {
if ((method == "REGISTER") || (mPrivacy == SalPrivacyNone)) {
from_header = belle_sip_header_from_create(BELLE_SIP_HEADER_ADDRESS(getFromAddress())
,belle_sip_random_token(token,sizeof(token)));
} else {
@ -622,15 +549,14 @@ belle_sip_request_t* SalOp::buildRequest(const char* method) {
to_header = belle_sip_header_to_create(BELLE_SIP_HEADER_ADDRESS(to_address),NULL);
call_id_header = belle_sip_provider_create_call_id(prov);
if (getCallId()) {
belle_sip_header_call_id_set_call_id(call_id_header, getCallId());
}
if (!mCallId.empty())
belle_sip_header_call_id_set_call_id(call_id_header, mCallId.c_str());
req=belle_sip_request_create(
req_uri,
method,
method.c_str(),
call_id_header,
belle_sip_header_cseq_create(20,method),
belle_sip_header_cseq_create(20,method.c_str()),
from_header,
to_header,
belle_sip_header_via_new(),
@ -641,11 +567,11 @@ belle_sip_request_t* SalOp::buildRequest(const char* method) {
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(p_preferred_identity));
}
if (elem && strcmp(method,"REGISTER")!=0 && !mRoot->mNoInitialRoute){
addInitialRouteSet(req,elem);
}
auto routeAddresses = getRouteAddresses();
if (!routeAddresses.empty() && (method != "REGISTER") && !mRoot->mNoInitialRoute)
addInitialRouteSet(req, routeAddresses);
if (strcmp("REGISTER",method)!=0 && mPrivacy!=SalPrivacyNone ){
if ((method != "REGISTER") && (mPrivacy != SalPrivacyNone)) {
belle_sip_header_privacy_t* privacy_header=belle_sip_header_privacy_new();
if (mPrivacy&SalPrivacyCritical)
belle_sip_header_privacy_add_privacy(privacy_header,sal_privacy_to_string(SalPrivacyCritical));
@ -661,7 +587,7 @@ belle_sip_request_t* SalOp::buildRequest(const char* method) {
belle_sip_header_privacy_add_privacy(privacy_header,sal_privacy_to_string(SalPrivacyUser));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(privacy_header));
}
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),mRoot->mSupported);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),mRoot->mSupportedHeader);
return req;
}
@ -677,14 +603,18 @@ void SalOp::setErrorInfoFromResponse(belle_sip_response_t *response) {
setReasonErrorInfo(BELLE_SIP_MESSAGE(response));
}
const char* SalOp::toString(const State value) {
switch(value) {
case State::Early: return"SalOpStateEarly";
case State::Active: return "SalOpStateActive";
case State::Terminating: return "SalOpStateTerminating";
case State::Terminated: return "SalOpStateTerminated";
default:
return "Unknown";
string SalOp::toString (const State value) {
switch (value) {
case State::Early:
return"SalOpStateEarly";
case State::Active:
return "SalOpStateActive";
case State::Terminating:
return "SalOpStateTerminating";
case State::Terminated:
return "SalOpStateTerminated";
default:
return "Unknown";
}
}
@ -743,7 +673,7 @@ int SalOp::sendRequestAndCreateRefresher(belle_sip_request_t* req, int expires,b
notify the user as a normal transaction*/
belle_sip_refresher_set_listener(mRefresher,listener, this);
belle_sip_refresher_set_retry_after(mRefresher,mRoot->mRefresherRetryAfter);
belle_sip_refresher_set_realm(mRefresher,mRealm);
belle_sip_refresher_set_realm(mRefresher,L_STRING_TO_C(mRealm));
belle_sip_refresher_enable_manual_mode(mRefresher, mManualRefresher);
return 0;
} else {
@ -777,18 +707,19 @@ belle_sip_header_contact_t *SalOp::createContact() {
/*don't touch contact in case of gruu*/
if (!belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact_header))),"gr")) {
belle_sip_header_contact_set_automatic(contact_header,mRoot->mAutoContacts);
if (mRoot->mUuid) {
if (belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(contact_header),"+sip.instance")==0){
char *instance_id=belle_sip_strdup_printf("\"<urn:uuid:%s>\"",mRoot->mUuid);
belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(contact_header),"+sip.instance",instance_id);
belle_sip_free(instance_id);
}
if (!mRoot->mUuid.empty()
&& !belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(contact_header), "+sip.instance")
) {
stringstream ss;
ss << "\"<urn:uuid:" << mRoot->mUuid << ">\"";
string instanceId = ss.str();
belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(contact_header), "+sip.instance", instanceId.c_str());
}
}
if (mRoot->mLinphoneSpecs && strlen(mRoot->mLinphoneSpecs) > 0) {
if (belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(contact_header),"+org.linphone.specs") == 0) {
belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(contact_header), "+org.linphone.specs", mRoot->mLinphoneSpecs);
}
if (!mRoot->mLinphoneSpecs.empty()
&& !belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(contact_header), "+org.linphone.specs")
) {
belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(contact_header), "+org.linphone.specs", mRoot->mLinphoneSpecs.c_str());
}
return contact_header;
}
@ -822,21 +753,20 @@ void SalOp::setOrUpdateDialog(belle_sip_dialog_t* dialog) {
unref();
}
int SalOp::ping(const char *from, const char *to) {
setFrom(from);
setTo(to);
int SalOp::ping (const string &from, const string &to) {
setFrom(from);
setTo(to);
return sendRequest(buildRequest("OPTIONS"));
}
int SalOp::sendInfo(const char *from, const char *to, const SalBodyHandler *body_handler) {
if (mDialog && belle_sip_dialog_get_state(mDialog) == BELLE_SIP_DIALOG_CONFIRMED) {
belle_sip_request_t *req;
belle_sip_dialog_enable_pending_trans_checking(mDialog,mRoot->mPendingTransactionChecking);
req=belle_sip_dialog_create_queued_request(mDialog,"INFO");
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(body_handler));
return sendRequest(req);
}else{
ms_error("Cannot send INFO message on op [%p] because dialog is not in confirmed state yet.", this);
int SalOp::sendInfo (const SalBodyHandler *bodyHandler) {
if (mDialog && (belle_sip_dialog_get_state(mDialog) == BELLE_SIP_DIALOG_CONFIRMED)) {
belle_sip_dialog_enable_pending_trans_checking(mDialog, mRoot->mPendingTransactionChecking);
belle_sip_request_t *request = belle_sip_dialog_create_queued_request(mDialog, "INFO");
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(request), BELLE_SIP_BODY_HANDLER(bodyHandler));
return sendRequest(request);
} else {
lError() << "Cannot send INFO message on op [" << this << "] because dialog is not in confirmed state yet";
}
return -1;
}
@ -865,26 +795,26 @@ void SalOp::assignRecvHeaders(belle_sip_message_t *incoming) {
}
}
void SalOp::setRemoteContact(const char* remote_contact) {
assignAddress(&mRemoteContactAddress,remote_contact);
/*to preserve header params*/
assignString(&mRemoteContact,remote_contact);
void SalOp::setRemoteContact (const string &value) {
assignAddress(&mRemoteContactAddress, value);
mRemoteContact = value; // To preserve header params
}
void SalOp::setNetworkOrigin (const char *value) {
char *valueStr = nullptr;
void SalOp::setNetworkOrigin (const string &value) {
assignAddress(&mOriginAddress, value);
if (mOriginAddress)
valueStr = sal_address_as_string(mOriginAddress);
assignString(&mOrigin, valueStr);
if (valueStr)
if (mOriginAddress) {
char *valueStr = sal_address_as_string(mOriginAddress);
mOrigin = valueStr;
ms_free(valueStr);
} else {
mOrigin.clear();
}
}
void SalOp::setNetworkOriginAddress(SalAddress *origin){
char* address_string=sal_address_as_string(origin); /*can probably be optimized*/
setNetworkOrigin(address_string);
ms_free(address_string);
void SalOp::setNetworkOriginAddress (SalAddress *value) {
char *valueStr = sal_address_as_string(value); // Can probably be optimized
setNetworkOrigin(valueStr);
ms_free(valueStr);
}
/*
@ -922,24 +852,28 @@ void SalOp::setPrivacyFromMessage(belle_sip_message_t* msg) {
}
}
void SalOp::setRemoteUserAgent(belle_sip_message_t* message) {
belle_sip_header_user_agent_t* user_agent=belle_sip_message_get_header_by_type(message,belle_sip_header_user_agent_t);
char user_agent_string[256];
if (user_agent && belle_sip_header_user_agent_get_products_as_string(user_agent,user_agent_string,sizeof(user_agent_string))>0) {
if (mRemoteUserAgent!=NULL){
ms_free(mRemoteUserAgent);
}
mRemoteUserAgent=ms_strdup(user_agent_string);
void SalOp::setRemoteUserAgent (belle_sip_message_t *message) {
belle_sip_header_user_agent_t *userAgentHeader = belle_sip_message_get_header_by_type(message, belle_sip_header_user_agent_t);
char userAgentStr[256];
if (userAgentHeader
&& belle_sip_header_user_agent_get_products_as_string(userAgentHeader, userAgentStr, sizeof(userAgentStr)) > 0
) {
mRemoteUserAgent = userAgentStr;
}
}
const char *SalOp::toString(const Type type) {
switch(type) {
case Type::Register: return "SalOpRegister";
case Type::Call: return "SalOpCall";
case Type::Message: return "SalOpMessage";
case Type::Presence: return "SalOpPresence";
default: return "SalOpUnknown";
string SalOp::toString (const Type type) {
switch (type) {
case Type::Register:
return "SalOpRegister";
case Type::Call:
return "SalOpCall";
case Type::Message:
return "SalOpMessage";
case Type::Presence:
return "SalOpPresence";
default:
return "SalOpUnknown";
}
}
@ -1081,21 +1015,13 @@ int SalOp::replyMessage(SalReason reason) {
return -1;
}
void SalOp::addMessageAccept(belle_sip_message_t *msg) {
bctbx_list_t *item;
const char *str;
char *old;
char *header = ms_strdup("xml/cipher, application/cipher.vnd.gsma.rcs-ft-http+xml");
for (item = mRoot->mSupportedContentTypes; item != NULL; item = bctbx_list_next(item)) {
str = (const char *)bctbx_list_get_data(item);
old = header;
header = ms_strdup_printf("%s, %s", old, str);
ms_free(old);
}
belle_sip_message_add_header(msg, belle_sip_header_create("Accept", header));
ms_free(header);
void SalOp::addMessageAccept (belle_sip_message_t *message) {
stringstream ss;
ss << "xml/cipher, application/cipher.vnd.gsma.rcs-ft-http+xml";
for (const auto &supportedContentType : mRoot->mSupportedContentTypes)
ss << ", " << supportedContentType;
string headerValue = ss.str();
belle_sip_message_add_header(message, belle_sip_header_create("Accept", headerValue.c_str()));
}
void SalOp::setServiceRoute(const SalAddress* service_route) {

View file

@ -44,25 +44,25 @@ public:
void setUserPointer (void *value) { mUserPointer = value; }
void *getUserPointer () const { return mUserPointer; }
void setSubject (const char *value);
const char *getSubject () const { return mSubject; }
void setSubject (const std::string &value) { mSubject = value; }
const std::string &getSubject () const { return mSubject; }
void setFrom (const char *value);
void setFrom (const std::string &value);
void setFromAddress (const SalAddress *value);
const char *getFrom () const { return mFrom; }
const std::string &getFrom () const { return mFrom; }
const SalAddress *getFromAddress () const { return mFromAddress; }
void setTo (const char *value);
void setTo (const std::string &value);
void setToAddress (const SalAddress *value);
const char *getTo () const { return mTo; }
const std::string &getTo () const { return mTo; }
const SalAddress *getToAddress () const { return mToAddress; }
void setContactAddress (const SalAddress* value);
const SalAddress *getContactAddress() const { return mContactAddress; }
void setRoute (const char *value);
void setRoute (const std::string &value);
void setRouteAddress (const SalAddress *value);
const bctbx_list_t *getRouteAddresses () const { return mRouteAddresses; }
const std::list<SalAddress *> &getRouteAddresses () const { return mRouteAddresses; }
void addRouteAddress (const SalAddress *address);
void setDiversionAddress (const SalAddress *value);
@ -73,30 +73,30 @@ public:
void setManualRefresherMode (bool value) { mManualRefresher = value; }
void setEntityTag (const char *value);
const char *getEntityTag() const { return mEntityTag; }
void setEntityTag (const std::string &value) { mEntityTag = value; }
const std::string &getEntityTag() const { return mEntityTag; }
void setEvent (const char *eventName);
void setEvent (const std::string &eventName);
void setPrivacy (SalPrivacyMask value) { mPrivacy = value; }
SalPrivacyMask getPrivacy() const { return mPrivacy; }
void setRealm (const char *value);
void setRealm (const std::string &value) { mRealm = value; }
void setSentCustomHeaders (SalCustomHeader *ch);
void enableCnxIpTo0000IfSendOnly (bool value) { mCnxIpTo0000IfSendOnlyEnabled = value; }
bool cnxIpTo0000IfSendOnlyEnabled () const { return mCnxIpTo0000IfSendOnlyEnabled; }
const char *getProxy () const { return mRoute; }
const char *getNetworkOrigin () const { return mOrigin; }
const char *getCallId () const { return mCallId; }
char *getDialogId () const;
const std::string &getProxy () const { return mRoute; }
const std::string &getNetworkOrigin () const { return mOrigin; }
const std::string &getCallId () const { return mCallId; }
std::string getDialogId () const;
int getAddressFamily () const;
const SalCustomHeader *getRecvCustomHeaders () const { return mRecvCustomHeaders; }
const char *getRemoteContact () const { return mRemoteContact; }
const std::string &getRemoteContact () const { return mRemoteContact; }
const SalAddress *getRemoteContactAddress () const { return mRemoteContactAddress; }
const char *getRemoteUserAgent () const { return mRemoteUserAgent; }
const std::string &getRemoteUserAgent () const { return mRemoteUserAgent; }
const char *getPublicAddress (int *port) {
return mRefresher ? belle_sip_refresher_get_public_address(mRefresher, port) : nullptr;
@ -109,7 +109,7 @@ public:
const SalErrorInfo *getReasonErrorInfo () const { return &mReasonErrorInfo; }
bool isForkedOf (const SalOp *op) const {
return mCallId && op->mCallId && strcmp(mCallId, op->mCallId) == 0;
return !mCallId.empty() && !op->mCallId.empty() && (mCallId == op->mCallId);
}
bool isIdle () const;
@ -126,8 +126,8 @@ public:
void cancelAuthentication () { lFatal() << "SalOp::cancelAuthentication not implemented yet"; }
SalAuthInfo *getAuthRequested () { return mAuthInfo; }
int ping (const char *from, const char *to);
int sendInfo (const char *from, const char *to, const SalBodyHandler *bodyHandler);
int ping (const std::string &from, const std::string &to);
int sendInfo (const SalBodyHandler *bodyHandler);
protected:
enum class State {
@ -137,7 +137,7 @@ protected:
Terminated
};
static const char *toString (const State value);
static std::string toString (const State value);
enum class Dir {
Incoming = 0,
@ -155,7 +155,7 @@ protected:
Refer // For out of dialog refer only
};
static const char *toString (const Type type);
static std::string toString (const Type type);
using ReleaseCb = void (*) (SalOp *op);
@ -164,7 +164,7 @@ protected:
void processAuthentication ();
int processRedirect ();
belle_sip_request_t *buildRequest (const char *method);
belle_sip_request_t *buildRequest (const std::string &method);
int sendRequest (belle_sip_request_t *request);
int sendRequestWithContact (belle_sip_request_t *request, bool addContact);
int sendRequestWithExpires (belle_sip_request_t *request, int expires);
@ -177,8 +177,8 @@ protected:
void setReferredBy (belle_sip_header_referred_by_t *referredByHeader);
void setReplaces (belle_sip_header_replaces_t *replacesHeader);
void setRemoteContact (const char *value);
void setNetworkOrigin (const char *value);
void setRemoteContact (const std::string &value);
void setNetworkOrigin (const std::string &value);
void setNetworkOriginAddress (SalAddress *value);
void setPrivacyFromMessage (belle_sip_message_t *message);
void setRemoteUserAgent (belle_sip_message_t *message);
@ -207,33 +207,32 @@ protected:
static bool isExternalBody (belle_sip_header_content_type_t* contentType);
static void assignAddress (SalAddress **address, const char *value);
static void assignString (char **str, const char *arg);
static void addInitialRouteSet (belle_sip_request_t *request, const MSList *list);
static void assignAddress (SalAddress **address, const std::string &value);
static void addInitialRouteSet (belle_sip_request_t *request, const std::list<SalAddress *> &routeAddresses);
// SalOpBase
Sal *mRoot = nullptr;
char *mRoute = nullptr; // Or request-uri for REGISTER
MSList *mRouteAddresses = nullptr; // List of SalAddress *
std::string mRoute; // Or request-uri for REGISTER
std::list<SalAddress *> mRouteAddresses;
SalAddress *mContactAddress = nullptr;
char *mSubject = nullptr;
char *mFrom = nullptr;
std::string mSubject;
std::string mFrom;
SalAddress* mFromAddress = nullptr;
char *mTo = nullptr;
std::string mTo;
SalAddress *mToAddress = nullptr;
char *mOrigin = nullptr;
std::string mOrigin;
SalAddress *mOriginAddress = nullptr;
SalAddress *mDiversionAddress = nullptr;
char *mRemoteUserAgent = nullptr;
std::string mRemoteUserAgent;
SalAddress *mRemoteContactAddress = nullptr;
char *mRemoteContact = nullptr;
std::string mRemoteContact;
void *mUserPointer = nullptr;
char *mCallId = nullptr;
char *mRealm = nullptr;
std::string mCallId;
std::string mRealm;
SalAddress *mServiceRoute = nullptr; // As defined by rfc3608, might be a list
SalCustomHeader *mSentCustomHeaders = nullptr;
SalCustomHeader *mRecvCustomHeaders = nullptr;
char *mEntityTag = nullptr; // As defined by rfc3903 (I.E publih)
std::string mEntityTag; // As defined by rfc3903 (I.E publih)
ReleaseCb mReleaseCb = nullptr;
const belle_sip_listener_callbacks_t *mCallbacks = nullptr;

View file

@ -17,6 +17,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "c-wrapper/internal/c-tools.h"
#include "sal/presence-op.h"
using namespace std;
@ -42,7 +43,7 @@ void SalPresenceOp::presenceProcessIoErrorCb(void *user_ctx, const belle_sip_io_
ms_warning("presence_process_io_error() refresher is present, should not happen");
return;
}
ms_message("subscription to [%s] io error",op->getTo());
ms_message("subscription to [%s] io error",op->getTo().c_str());
if (!op->mOpReleased){
op->mRoot->mCallbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/
}
@ -90,7 +91,7 @@ void SalPresenceOp::presenceResponseEventCb(void *op_base, const belle_sip_respo
if (code>=300) {
if (strcmp("SUBSCRIBE",belle_sip_request_get_method(request))==0){
ms_message("subscription to [%s] rejected",op->getTo());
ms_message("subscription to [%s] rejected",op->getTo().c_str());
if (!op->mOpReleased){
op->mRoot->mCallbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/
}
@ -121,7 +122,7 @@ void SalPresenceOp::presenceResponseEventCb(void *op_base, const belle_sip_respo
if ((expires != NULL) && (belle_sip_header_expires_get_expires(expires) > 0)) {
op->mRefresher=belle_sip_client_transaction_create_refresher(client_transaction);
belle_sip_refresher_set_listener(op->mRefresher,presenceRefresherListenerCb,op);
belle_sip_refresher_set_realm(op->mRefresher,op->mRealm);
belle_sip_refresher_set_realm(op->mRefresher,L_STRING_TO_C(op->mRealm));
}
}
break;
@ -143,7 +144,7 @@ void SalPresenceOp::presenceProcessTimeoutCb(void *user_ctx, const belle_sip_tim
request = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction));
if (strcmp("SUBSCRIBE",belle_sip_request_get_method(request))==0){
ms_message("subscription to [%s] timeout",op->getTo());
ms_message("subscription to [%s] timeout",op->getTo().c_str());
if (!op->mOpReleased){
op->mRoot->mCallbacks.notify_presence(op,SalSubscribeTerminated, NULL,NULL); /*NULL = offline*/
}
@ -192,7 +193,7 @@ void SalPresenceOp::handleNotify(belle_sip_request_t *req, belle_sip_dialog_t *d
}
if (!subscription_state_header || strcasecmp(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,belle_sip_header_subscription_state_get_state(subscription_state_header)) ==0) {
sub_state=SalSubscribeTerminated;
ms_message("Outgoing subscription terminated by remote [%s]",getTo());
ms_message("Outgoing subscription terminated by remote [%s]",getTo().c_str());
} else {
sub_state=getSubscriptionState(BELLE_SIP_MESSAGE(req));
}
@ -249,7 +250,7 @@ void SalPresenceOp::presenceProcessRequestEventCb(void *op_base, const belle_sip
return;
}
op->setOrUpdateDialog(dialog);
ms_message("new incoming subscription from [%s] to [%s]",op->getFrom(),op->getTo());
ms_message("new incoming subscription from [%s] to [%s]",op->getFrom().c_str(),op->getTo().c_str());
}else if (strcmp(method,"NOTIFY")==0 && belle_sip_request_event_get_dialog(event)) {
/*special case of dialog created by notify matching subscribe*/
op->setOrUpdateDialog(belle_sip_request_event_get_dialog(event));
@ -265,7 +266,7 @@ void SalPresenceOp::presenceProcessRequestEventCb(void *op_base, const belle_sip
if (strcmp("NOTIFY",method)==0) {
op->handleNotify(req, belle_sip_request_event_get_dialog(event));
} else if (strcmp("SUBSCRIBE",method)==0) {
op->mRoot->mCallbacks.subscribe_presence_received(op,op->getFrom());
op->mRoot->mCallbacks.subscribe_presence_received(op,op->getFrom().c_str());
}
break;
}
@ -293,9 +294,9 @@ void SalPresenceOp::presenceProcessRequestEventCb(void *op_base, const belle_sip
void SalPresenceOp::presenceProcessDialogTerminatedCb(void *ctx, const belle_sip_dialog_terminated_event_t *event) {
SalPresenceOp * op= (SalPresenceOp *)ctx;
if (op->mDialog && belle_sip_dialog_is_server(op->mDialog)) {
ms_message("Incoming subscribtion from [%s] terminated",op->getFrom());
ms_message("Incoming subscribtion from [%s] terminated",op->getFrom().c_str());
if (!op->mOpReleased){
op->mRoot->mCallbacks.subscribe_presence_closed(op, op->getFrom());
op->mRoot->mCallbacks.subscribe_presence_closed(op, op->getFrom().c_str());
}
op->setOrUpdateDialog(NULL);
}/* else client dialog is managed by refresher*/

View file

@ -68,7 +68,7 @@ int SalRegisterOp::sendRegister(const char *proxy, const char *from, int expires
void SalRegisterOp::registerRefresherListener(belle_sip_refresher_t* refresher, void* user_pointer, unsigned int status_code, const char* reason_phrase, int will_retry) {
SalRegisterOp * op = (SalRegisterOp *)user_pointer;
belle_sip_response_t* response=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(belle_sip_refresher_get_transaction(refresher)));
ms_message("Register refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase,op->getProxy());
ms_message("Register refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase,op->getProxy().c_str());
if (belle_sip_refresher_get_auth_events(refresher)) {
if (op->mAuthInfo) sal_auth_info_delete(op->mAuthInfo);

View file

@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <algorithm>
#include "sal/sal.h"
#include "sal/call-op.h"
#include "sal/presence-op.h"
@ -27,6 +29,8 @@
#include "tester_utils.h"
#include "private.h"
#include "c-wrapper/internal/c-tools.h"
using namespace std;
LINPHONE_BEGIN_NAMESPACE
@ -205,19 +209,21 @@ void Sal::processRequestEventCb (void *ud, const belle_sip_request_event_t *even
}
}
if (!op->mOrigin) {
if (op->mOrigin.empty()) {
/*set origin uri*/
origin_address=belle_sip_header_address_create(NULL,belle_sip_request_extract_origin(req));
op->setNetworkOriginAddress((SalAddress*)origin_address);
belle_sip_object_unref(origin_address);
}
if (!op->mRemoteUserAgent) {
if (op->mRemoteUserAgent.empty())
op->setRemoteUserAgent(BELLE_SIP_MESSAGE(req));
if (op->mCallId.empty()) {
op->mCallId = belle_sip_header_call_id_get_call_id(
BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req), belle_sip_header_call_id_t))
);
}
if (!op->mCallId) {
op->mCallId=ms_strdup(belle_sip_header_call_id_get_call_id(BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req), belle_sip_header_call_id_t))));
}
/*It is worth noting that proxies can (and will) remove this header field*/
op->setPrivacyFromMessage((belle_sip_message_t*)req);
@ -258,8 +264,10 @@ void Sal::processResponseEventCb(void *user_ctx, const belle_sip_response_event_
op->setRemoteContact(belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(remote_contact)));
}
if (!op->mCallId) {
op->mCallId=ms_strdup(belle_sip_header_call_id_get_call_id(BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(response), belle_sip_header_call_id_t))));
if (op->mCallId.empty()) {
op->mCallId = belle_sip_header_call_id_get_call_id(
BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(response), belle_sip_header_call_id_t))
);
}
op->assignRecvHeaders((belle_sip_message_t*)response);
@ -280,8 +288,8 @@ void Sal::processResponseEventCb(void *user_ctx, const belle_sip_response_event_
op->mPendingAuthTransaction=NULL;
}
if (++op->mAuthRequests > 2) {
ms_warning("Auth info cannot be found for op [%s/%s] after 2 attempts, giving up",op->getFrom()
,op->getTo());
ms_warning("Auth info cannot be found for op [%s/%s] after 2 attempts, giving up",op->getFrom().c_str()
,op->getTo().c_str());
op->mRoot->mCallbacks.auth_failure(op,op->mAuthInfo);
op->mRoot->removePendingAuth(op);
} else {
@ -363,14 +371,14 @@ Sal::Sal(MSFactory *factory){
/*first create the stack, which initializes the belle-sip object's pool for this thread*/
mStack = belle_sip_stack_new(NULL);
mUserAgent=belle_sip_header_user_agent_new();
mUserAgentHeader=belle_sip_header_user_agent_new();
#if defined(PACKAGE_NAME) && defined(LIBLINPHONE_VERSION)
belle_sip_header_user_agent_add_product(user_agent, PACKAGE_NAME "/" LIBLINPHONE_VERSION);
#else
belle_sip_header_user_agent_add_product(mUserAgent, "Unknown");
belle_sip_header_user_agent_add_product(mUserAgentHeader, "Unknown");
#endif
appendStackStringToUserAgent();
belle_sip_object_ref(mUserAgent);
belle_sip_object_ref(mUserAgentHeader);
mProvider = belle_sip_stack_create_provider(mStack,NULL);
enableNatHelper(TRUE);
@ -387,17 +395,12 @@ Sal::Sal(MSFactory *factory){
}
Sal::~Sal() {
belle_sip_object_unref(mUserAgent);
belle_sip_object_unref(mUserAgentHeader);
belle_sip_object_unref(mProvider);
belle_sip_object_unref(mStack);
belle_sip_object_unref(mListener);
if (mSupported) belle_sip_object_unref(mSupported);
bctbx_list_free_with_data(mSupportedTags,ms_free);
bctbx_list_free_with_data(mSupportedContentTypes, ms_free);
if (mUuid) ms_free(mUuid);
if (mRootCa) ms_free(mRootCa);
if (mRootCaData) ms_free(mRootCaData);
if (mLinphoneSpecs) ms_free(mLinphoneSpecs);
if (mSupportedHeader)
belle_sip_object_unref(mSupportedHeader);
}
void Sal::setCallbacks(const Callbacks *cbs) {
@ -461,8 +464,10 @@ void Sal::setTlsProperties(){
if (!mTlsVerify) verify_exceptions = BELLE_TLS_VERIFY_ANY_REASON;
else if (!mTlsVerifyCn) verify_exceptions = BELLE_TLS_VERIFY_CN_MISMATCH;
belle_tls_crypto_config_set_verify_exceptions(crypto_config, verify_exceptions);
if (mRootCa != NULL) belle_tls_crypto_config_set_root_ca(crypto_config, mRootCa);
if (mRootCaData != NULL) belle_tls_crypto_config_set_root_ca_data(crypto_config, mRootCaData);
if (!mRootCa.empty())
belle_tls_crypto_config_set_root_ca(crypto_config, mRootCa.c_str());
if (!mRootCaData.empty())
belle_tls_crypto_config_set_root_ca_data(crypto_config, mRootCaData.c_str());
if (mSslConfig != NULL) belle_tls_crypto_config_set_ssl_config(crypto_config, mSslConfig);
belle_sip_tls_listening_point_set_crypto_config(tlp, crypto_config);
belle_sip_object_unref(crypto_config);
@ -505,14 +510,13 @@ int Sal::addListenPort(SalAddress* addr, bool is_tunneled) {
return result;
}
int Sal::setListenPort(const char *addr, int port, SalTransport tr, bool is_tunneled) {
SalAddress* sal_addr = sal_address_new(NULL);
int result;
sal_address_set_domain(sal_addr,addr);
sal_address_set_port(sal_addr,port);
sal_address_set_transport(sal_addr,tr);
result = addListenPort(sal_addr, is_tunneled);
sal_address_destroy(sal_addr);
int Sal::setListenPort (const string &addr, int port, SalTransport tr, bool isTunneled) {
SalAddress *salAddr = sal_address_new(nullptr);
sal_address_set_domain(salAddr, L_STRING_TO_C(addr));
sal_address_set_port(salAddr, port);
sal_address_set_transport(salAddr, tr);
int result = addListenPort(salAddr, isTunneled);
sal_address_destroy(salAddr);
return result;
}
@ -547,62 +551,48 @@ int Sal::isTransportAvailable(SalTransport t) {
return FALSE;
}
void Sal::makeSupportedHeader(){
bctbx_list_t *it;
char *alltags=NULL;
size_t buflen=64;
size_t written=0;
void Sal::makeSupportedHeader () {
if (mSupportedHeader) {
belle_sip_object_unref(mSupportedHeader);
mSupportedHeader = nullptr;
}
string tags = Utils::join(mSupportedTags, ", ");
if (tags.empty())
return;
mSupportedHeader = belle_sip_header_create("Supported", tags.c_str());
if (mSupportedHeader)
belle_sip_object_ref(mSupportedHeader);
}
if (mSupported){
belle_sip_object_unref(mSupported);
mSupported=NULL;
}
for(it=mSupportedTags;it!=NULL;it=it->next){
const char *tag=(const char*)it->data;
size_t taglen=strlen(tag);
if (alltags==NULL || (written+taglen+1>=buflen)) alltags=reinterpret_cast<char *>(ms_realloc(alltags,(buflen=buflen*2)));
written+=(size_t)snprintf(alltags+written,buflen-written,it->next ? "%s, " : "%s",tag);
}
if (alltags){
mSupported=belle_sip_header_create("Supported",alltags);
if (mSupported){
belle_sip_object_ref(mSupported);
}
ms_free(alltags);
void Sal::setSupportedTags (const string &tags) {
vector<string> splittedTags = Utils::split(tags, ",");
mSupportedTags.clear();
for (const auto &tag : splittedTags)
mSupportedTags.push_back(Utils::trim(tag));
makeSupportedHeader();
}
const string &Sal::getSupportedTags () const {
if (mSupportedHeader)
mSupported = belle_sip_header_get_unparsed_value(mSupportedHeader);
else
mSupported.clear();
return mSupported;
}
void Sal::addSupportedTag (const string &tag) {
auto it = find(mSupportedTags.cbegin(), mSupportedTags.cend(), tag);
if (it == mSupportedTags.cend()) {
mSupportedTags.push_back(tag);
makeSupportedHeader();
}
}
void Sal::setSupportedTags(const char* tags){
mSupportedTags=bctbx_list_free_with_data(mSupportedTags,ms_free);
if (tags){
char *iter;
char *buffer=ms_strdup(tags);
char *tag;
char *context=NULL;
iter=buffer;
while((tag=strtok_r(iter,", ",&context))!=NULL){
iter=NULL;
mSupportedTags=bctbx_list_append(mSupportedTags,ms_strdup(tag));
}
ms_free(buffer);
}
makeSupportedHeader();
}
void Sal::addSupportedTag(const char* tag){
bctbx_list_t *elem=bctbx_list_find_custom(mSupportedTags,(bctbx_compare_func)strcasecmp,tag);
if (!elem){
mSupportedTags=bctbx_list_append(mSupportedTags,ms_strdup(tag));
makeSupportedHeader();
}
}
void Sal::removeSupportedTag(const char* tag){
bctbx_list_t *elem=bctbx_list_find_custom(mSupportedTags,(bctbx_compare_func)strcasecmp,tag);
if (elem){
ms_free(elem->data);
mSupportedTags=bctbx_list_erase_link(mSupportedTags,elem);
makeSupportedHeader();
void Sal::removeSupportedTag (const string &tag) {
auto it = find(mSupportedTags.cbegin(), mSupportedTags.cend(), tag);
if (it != mSupportedTags.cend()) {
mSupportedTags.erase(it);
makeSupportedHeader();
}
}
@ -617,21 +607,23 @@ ortp_socket_t Sal::getSocket() const {
return -1;
}
void Sal::setUserAgent(const char *user_agent) {
belle_sip_header_user_agent_set_products(mUserAgent,NULL);
belle_sip_header_user_agent_add_product(mUserAgent,user_agent);
void Sal::setUserAgent (const string &value) {
belle_sip_header_user_agent_set_products(mUserAgentHeader, nullptr);
belle_sip_header_user_agent_add_product(mUserAgentHeader, L_STRING_TO_C(value));
}
const char* Sal::getUserAgent() const {
static char user_agent[255];
belle_sip_header_user_agent_get_products_as_string(mUserAgent, user_agent, 254);
return user_agent;
const string &Sal::getUserAgent () const {
char userAgent[256];
belle_sip_header_user_agent_get_products_as_string(mUserAgentHeader, userAgent, sizeof(userAgent) - 1);
mUserAgent = userAgent;
return mUserAgent;
}
void Sal::appendStackStringToUserAgent() {
char stack_string[64];
snprintf(stack_string, sizeof(stack_string) - 1, "(belle-sip/%s)", belle_sip_version_to_string());
belle_sip_header_user_agent_add_product(mUserAgent, stack_string);
void Sal::appendStackStringToUserAgent () {
stringstream ss;
ss << "(belle-sip/" << belle_sip_version_to_string() << ")";
string stackStr = ss.str();
belle_sip_header_user_agent_add_product(mUserAgentHeader, stackStr.c_str());
}
void Sal::setKeepAlivePeriod(unsigned int value) {
@ -655,26 +647,34 @@ int Sal::setTunnel(void *tunnelclient) {
#endif
}
bool Sal::isContentTypeSupported(const char *content_type) const {
bctbx_list_t *item;
for (item = mSupportedContentTypes; item != NULL; item = bctbx_list_next(item)) {
const char *item_content_type = (const char *)bctbx_list_get_data(item);
if (strcmp(item_content_type, content_type) == 0) return true;
}
return false;
void Sal::setHttpProxyHost (const string &value) {
belle_sip_stack_set_http_proxy_host(mStack, L_STRING_TO_C(value));
}
void Sal::addContentTypeSupport(const char *content_type) {
if (content_type && !isContentTypeSupported(content_type))
mSupportedContentTypes = bctbx_list_append(mSupportedContentTypes, ms_strdup(content_type));
const string &Sal::getHttpProxyHost () const {
mHttpProxyHost = belle_sip_stack_get_http_proxy_host(mStack);
return mHttpProxyHost;
}
void Sal::removeContentTypeSupport(const char *content_type) {
if (content_type != NULL) {
if (bctbx_list_find(mSupportedContentTypes, content_type)) {
mSupportedContentTypes = bctbx_list_remove(mSupportedContentTypes, (char *)content_type);
}
}
bool Sal::isContentEncodingAvailable (const string &contentEncoding) const {
return belle_sip_stack_content_encoding_available(mStack, L_STRING_TO_C(contentEncoding));
}
bool Sal::isContentTypeSupported (const string &contentType) const {
auto it = find_if(mSupportedContentTypes.cbegin(), mSupportedContentTypes.cend(),
[contentType](string supportedContentType) { return contentType == supportedContentType; });
return it != mSupportedContentTypes.cend();
}
void Sal::addContentTypeSupport (const string &contentType) {
if (!contentType.empty() && !isContentTypeSupported(contentType))
mSupportedContentTypes.push_back(contentType);
}
void Sal::removeContentTypeSupport (const string &contentType) {
auto it = find(mSupportedContentTypes.begin(), mSupportedContentTypes.end(), contentType);
if (it != mSupportedContentTypes.end())
mSupportedContentTypes.erase(it);
}
void Sal::useRport(bool use_rports) {
@ -682,33 +682,13 @@ void Sal::useRport(bool use_rports) {
ms_message("Sal use rport [%s]", use_rports ? "enabled" : "disabled");
}
void Sal::setContactLinphoneSpecs(const char *specs) {
if (mLinphoneSpecs) {
ms_free(mLinphoneSpecs);
mLinphoneSpecs = NULL;
}
if (specs) {
mLinphoneSpecs = ms_strdup(specs);
}
}
void Sal::setRootCa(const char* rootCa) {
if (mRootCa) {
ms_free(mRootCa);
mRootCa = NULL;
}
if (rootCa)
mRootCa = ms_strdup(rootCa);
void Sal::setRootCa (const string &value) {
mRootCa = value;
setTlsProperties();
}
void Sal::setRootCaData(const char* data) {
if (mRootCaData) {
ms_free(mRootCaData);
mRootCaData = NULL;
}
if (data)
mRootCaData = ms_strdup(data);
void Sal::setRootCaData (const string &value) {
mRootCaData = value;
setTlsProperties();
}
@ -727,15 +707,6 @@ void Sal::setSslConfig(void *ssl_config) {
setTlsProperties();
}
void Sal::setUuid(const char *uuid){
if (mUuid){
ms_free(mUuid);
mUuid=NULL;
}
if (uuid)
mUuid=ms_strdup(uuid);
}
int Sal::createUuid(char *uuid, size_t len) {
if (generateUuid(uuid, len) == 0) {
setUuid(uuid);
@ -770,19 +741,18 @@ int Sal::generateUuid(char *uuid, size_t len) {
return 0;
}
void Sal::addPendingAuth(SalOp *op){
if (bctbx_list_find(mPendingAuths,op)==NULL){
mPendingAuths=bctbx_list_append(mPendingAuths,op);
op->mHasAuthPending=TRUE;
void Sal::addPendingAuth (SalOp *op) {
auto it = find(mPendingAuths.cbegin(), mPendingAuths.cend(), op);
if (it == mPendingAuths.cend()) {
mPendingAuths.push_back(op);
op->mHasAuthPending = true;
}
}
void Sal::removePendingAuth(SalOp *op){
if (op->mHasAuthPending){
op->mHasAuthPending=FALSE;
if (bctbx_list_find(mPendingAuths,op)){
mPendingAuths=bctbx_list_remove(mPendingAuths,op);
}
void Sal::removePendingAuth (SalOp *op) {
if (op->mHasAuthPending) {
op->mHasAuthPending = false;
mPendingAuths.remove(op);
}
}
@ -813,9 +783,26 @@ void Sal::setDnsServers(const bctbx_list_t *servers){
belle_sip_list_free(l);
}
belle_sip_source_t *Sal::createTimer(belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms, const char* timer_name) {
void Sal::setDnsUserHostsFile (const string &value) {
belle_sip_stack_set_dns_user_hosts_file(mStack, value.c_str());
}
const string &Sal::getDnsUserHostsFile () const {
mDnsUserHostsFile = belle_sip_stack_get_dns_user_hosts_file(mStack);
return mDnsUserHostsFile;
}
belle_sip_resolver_context_t *Sal::resolveA (const string &name, int port, int family, belle_sip_resolver_callback_t cb, void *data) {
return belle_sip_stack_resolve_a(mStack, L_STRING_TO_C(name), port, family, cb, data);
}
belle_sip_resolver_context_t *Sal::resolve (const string &service, const string &transport, const string &name, int port, int family, belle_sip_resolver_callback_t cb, void *data) {
return belle_sip_stack_resolve(mStack, L_STRING_TO_C(service), L_STRING_TO_C(transport), L_STRING_TO_C(name), port, family, cb, data);
}
belle_sip_source_t *Sal::createTimer (belle_sip_source_func_t func, void *data, unsigned int timeoutValueMs, const string &timerName) {
belle_sip_main_loop_t *ml = belle_sip_stack_get_main_loop(mStack);
return belle_sip_main_loop_create_timeout(ml, func, data, timeout_value_ms, timer_name);
return belle_sip_main_loop_create_timeout(ml, func, data, timeoutValueMs, L_STRING_TO_C(timerName));
}
void Sal::cancelTimer(belle_sip_source_t *timer) {
@ -825,8 +812,8 @@ void Sal::cancelTimer(belle_sip_source_t *timer) {
belle_sip_response_t* Sal::createResponseFromRequest (belle_sip_request_t* req, int code ) {
belle_sip_response_t *resp=belle_sip_response_create_from_request(req,code);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(mUserAgent));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp), mSupported);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(mUserAgentHeader));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp), mSupportedHeader);
return resp;
}
@ -951,7 +938,7 @@ int sal_create_uuid(Sal *ctx, char *uuid, size_t len) {
}
void sal_set_uuid(Sal *ctx, const char *uuid) {
ctx->setUuid(uuid);
ctx->setUuid(L_C_TO_STRING(uuid));
}
void sal_default_set_sdp_handling(Sal* h, SalOpSDPHandling handling_method) {

View file

@ -20,6 +20,9 @@
#ifndef _L_SAL_H_
#define _L_SAL_H_
#include <list>
#include <vector>
#include "linphone/utils/general.h"
#include "c-wrapper/internal/c-sal.h"
@ -134,27 +137,23 @@ public:
// ---------------------------------------------------------------------------
// SIP parameters
// ---------------------------------------------------------------------------
void setSupportedTags (const char *tags);
const char *getSupportedTags () const {
return mSupported ? belle_sip_header_get_unparsed_value(mSupported) : nullptr;
}
void addSupportedTag (const char *tag);
void removeSupportedTag (const char *tag);
void setSupportedTags (const std::string &tags);
const std::string &getSupportedTags () const;
void addSupportedTag (const std::string &tag);
void removeSupportedTag (const std::string &tag);
void setUserAgent (const char *userAgent);
const char *getUserAgent() const;
void setUserAgent (const std::string &value);
const std::string &getUserAgent () const;
void appendStackStringToUserAgent ();
bool isContentEncodingAvailable (const char *contentEncoding) {
return belle_sip_stack_content_encoding_available(mStack, contentEncoding);
}
bool isContentTypeSupported (const char *contentType) const;
void addContentTypeSupport (const char *contentType);
void removeContentTypeSupport (const char *contentType);
bool isContentEncodingAvailable (const std::string &contentEncoding) const;
bool isContentTypeSupported (const std::string &contentType) const;
void addContentTypeSupport (const std::string &contentType);
void removeContentTypeSupport (const std::string &contentType);
void setDefaultSdpHandling (SalOpSDPHandling sdpHandlingMethod);
void setUuid (const char *uuid);
void setUuid (const std::string &value) { mUuid = value; }
int createUuid (char *uuid, size_t len);
static int generateUuid (char *uuid, size_t len);
@ -178,15 +177,15 @@ public:
void enableUnconditionalAnswer (int value) { belle_sip_provider_enable_unconditional_answer(mProvider, value); }
void enableReconnectToPrimaryAsap (bool value) { belle_sip_stack_enable_reconnect_to_primary_asap(mStack, value); }
bctbx_list_t *getPendingAuths () const { return bctbx_list_copy(mPendingAuths); }
const std::list<SalOp *> &getPendingAuths () const { return mPendingAuths; }
void setContactLinphoneSpecs (const char *specs);
void setContactLinphoneSpecs (const std::string &value) { mLinphoneSpecs = value; }
// ---------------------------------------------------------------------------
// Network parameters
// ---------------------------------------------------------------------------
int setListenPort (const char *addr, int port, SalTransport tr, bool isTunneled);
int setListenPort (const std::string &addr, int port, SalTransport tr, bool isTunneled);
int getListeningPort (SalTransport tr);
int isTransportAvailable (SalTransport t);
@ -203,8 +202,8 @@ public:
int setTunnel (void *tunnelClient);
void setHttpProxyHost (const char *value) { belle_sip_stack_set_http_proxy_host(mStack, value); }
const char *getHttpProxyHost () const { return belle_sip_stack_get_http_proxy_host(mStack); }
void setHttpProxyHost (const std::string &value);
const std::string &getHttpProxyHost () const;
void setHttpProxyPort (int value) { belle_sip_stack_set_http_proxy_port(mStack, value); }
int getHttpProxyPort () const { return belle_sip_stack_get_http_proxy_port(mStack); }
@ -219,9 +218,9 @@ public:
// TLS parameters
// ---------------------------------------------------------------------------
void setSslConfig (void *sslConfig);
void setRootCa (const char *value);
void setRootCaData (const char *data);
const char *getRootCa () const { return mRootCa; }
void setRootCa (const std::string &value);
void setRootCaData (const std::string &value);
const std::string &getRootCa () const { return mRootCa; }
void verifyServerCertificates (bool value);
void verifyServerCn (bool value);
@ -241,21 +240,17 @@ public:
void enableDnsSrv (bool value) { belle_sip_stack_enable_dns_srv(mStack, (unsigned char)value); }
bool dnsSrvEnabled () const { return belle_sip_stack_dns_srv_enabled(mStack); }
void setDnsUserHostsFile (const char *value) { belle_sip_stack_set_dns_user_hosts_file(mStack, value); }
const char *getDnsUserHostsFile () const { return belle_sip_stack_get_dns_user_hosts_file(mStack); }
void setDnsUserHostsFile (const std::string &value);
const std::string &getDnsUserHostsFile () const;
belle_sip_resolver_context_t *resolveA (const char *name, int port, int family, belle_sip_resolver_callback_t cb, void *data) {
return belle_sip_stack_resolve_a(mStack, name, port, family, cb, data);
}
belle_sip_resolver_context_t *resolve (const char *service, const char *transport, const char *name, int port, int family, belle_sip_resolver_callback_t cb, void *data) {
return belle_sip_stack_resolve(mStack, service, transport, name, port, family, cb, data);
}
belle_sip_resolver_context_t *resolveA (const std::string &name, int port, int family, belle_sip_resolver_callback_t cb, void *data);
belle_sip_resolver_context_t *resolve (const std::string &service, const std::string &transport, const std::string &name, int port, int family, belle_sip_resolver_callback_t cb, void *data);
// ---------------------------------------------------------------------------
// Timers
// ---------------------------------------------------------------------------
belle_sip_source_t *createTimer (belle_sip_source_func_t func, void *data, unsigned int timeoutValueMs, const char *timerName);
belle_sip_source_t *createTimer (belle_sip_source_func_t func, void *data, unsigned int timeoutValueMs, const std::string &timerName);
void cancelTimer (belle_sip_source_t *timer);
@ -292,21 +287,21 @@ private:
MSFactory *mFactory = nullptr;
Callbacks mCallbacks = { 0 };
MSList *mPendingAuths = nullptr; // List of SalOp
std::list<SalOp *> mPendingAuths;
belle_sip_stack_t *mStack = nullptr;
belle_sip_provider_t *mProvider = nullptr;
belle_sip_header_user_agent_t *mUserAgent = nullptr;
belle_sip_header_user_agent_t *mUserAgentHeader = nullptr;
belle_sip_listener_t *mListener = nullptr;
void *mTunnelClient = nullptr;
void *mUserPointer = nullptr; // User pointer
int mSessionExpires = 0;
unsigned int mKeepAlive = 0;
char *mRootCa = nullptr;
char *mRootCaData = nullptr;
char *mUuid = nullptr;
std::string mRootCa;
std::string mRootCaData;
std::string mUuid;
int mRefresherRetryAfter = 60000; // Retry after value for refresher
MSList *mSupportedTags = nullptr; // List of char *
belle_sip_header_t *mSupported = nullptr;
std::vector<std::string> mSupportedTags;
belle_sip_header_t *mSupportedHeader = nullptr;
bool mOneMatchingCodec = false;
bool mUseTcpTlsKeepAlive = false;
bool mNatHelperEnabled = false;
@ -320,8 +315,14 @@ private:
SalOpSDPHandling mDefaultSdpHandling = SalOpSDPNormal;
bool mPendingTransactionChecking = true; // For testing purposes
void *mSslConfig = nullptr;
bctbx_list_t *mSupportedContentTypes = nullptr; // List of char *
char *mLinphoneSpecs = nullptr;
std::vector<std::string> mSupportedContentTypes;
std::string mLinphoneSpecs;
// Cache values
mutable std::string mDnsUserHostsFile;
mutable std::string mHttpProxyHost;
mutable std::string mSupported;
mutable std::string mUserAgent;
friend class SalOp;
friend class SalCallOp;