static void linphonec_text_received(LinphoneCore *lc, LinphoneChatRoom *cr,
const char *from, const char *msg);
static void linphonec_display_status (LinphoneCore * lc, const char *something);
-static void linphonec_general_state (LinphoneCore * lc, LinphoneGeneralState *gstate);
+static void linphonec_general_state (LinphoneCore * lc, LinphoneGeneralState *gstate, LinphoneGeneralStateContext gctx);
static void linphonec_dtmf_received(LinphoneCore *lc, int dtmf);
static void print_prompt(LinphoneCore *opm);
void linphonec_out(const char *fmt,...);
}
static void
-linphonec_general_state (LinphoneCore * lc, LinphoneGeneralState *gstate)
+linphonec_general_state (LinphoneCore * lc, LinphoneGeneralState *gstate, LinphoneGeneralStateContext gctx)
{
if (show_general_state) {
switch(gstate->new_state) {
const char *from,*to;
char *tmp;
LinphoneAddress *from_parsed;
+ LinphoneGeneralStateContext gctx;
/* first check if we can answer successfully to this invite */
if (lc->presence_mode!=LINPHONE_STATUS_ONLINE){
linphone_address_clean(from_parsed);
tmp=linphone_address_as_string(from_parsed);
linphone_address_destroy(from_parsed);
- gstate_new_state(lc, GSTATE_CALL_IN_INVITE, tmp);
+ gctx.call=call;
+ gstate_new_state(lc, GSTATE_CALL_IN_INVITE, gctx, tmp);
barmesg=ortp_strdup_printf("%s %s%s",tmp,_("is contacting you"),
(sal_call_autoanswer_asked(h)) ?_(" and asked autoanswer."):_("."));
if (lc->vtable.show) lc->vtable.show(lc);
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h));
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(h);
SalMediaDescription *md;
+ LinphoneGeneralStateContext gctx;
+
if (call==NULL) return;
+ gctx.call=call;
+
if (lc->vtable.display_status)
lc->vtable.display_status(lc,_("Remote ringing."));
if (lc->vtable.ringing_recv)
MSSndCard *ringcard=lc->sound_conf.lsd_card ? lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard;
ms_message("Remote ringing...");
lc->ringstream=ring_start(lc->sound_conf.remote_ring,2000,ringcard);
- gstate_new_state(lc, GSTATE_CALL_OUT_RINGING, NULL);
+
+ gstate_new_state(lc, GSTATE_CALL_OUT_RINGING, gctx, NULL);
}
}else{
/*accept early media */
if (lc->vtable.show) lc->vtable.show(lc);
if (lc->vtable.display_status)
lc->vtable.display_status(lc,_("Early media."));
- gstate_new_state(lc, GSTATE_CALL_OUT_RINGING, NULL);
+ gstate_new_state(lc, GSTATE_CALL_OUT_RINGING, gctx, NULL);
if (lc->ringstream!=NULL){
ring_stop(lc->ringstream);
lc->ringstream=NULL;
static void call_accepted(SalOp *op){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
+ LinphoneGeneralStateContext gctx;
if (call==NULL){
ms_warning("No call to accept.");
return ;
}
+ gctx.call=call;
if (call->state==LinphoneCallAVRunning){
ms_message("GET ACK of resume\n");
if(lc->vtable.ack_resumed_recv)
else
{
linphone_core_set_as_current_call (lc,call);
- gstate_new_state(lc, GSTATE_CALL_OUT_CONNECTED, NULL);
+ gstate_new_state(lc, GSTATE_CALL_OUT_CONNECTED, gctx, NULL);
linphone_connect_incoming(lc,call);
}
}else{
static void call_ack(SalOp *op){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
+ LinphoneGeneralStateContext gctx;
if (call==NULL){
ms_warning("No call to be ACK'd");
return ;
}
+ gctx.call=call;
if (call->media_pending){
if (lc->audiostream->ticker!=NULL){
/*case where we accepted early media */
if (call->resultdesc)
sal_media_description_ref(call->resultdesc);
if (call->resultdesc && !sal_media_description_empty(call->resultdesc)){
- gstate_new_state(lc, GSTATE_CALL_IN_CONNECTED, NULL);
+ gstate_new_state(lc, GSTATE_CALL_IN_CONNECTED, gctx, NULL);
linphone_connect_incoming(lc,call);
}else{
/*send a bye*/
static void call_terminated(SalOp *op, const char *from){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
+ LinphoneGeneralStateContext gctx;
+ gctx.call=call;
if (linphone_call_get_state(call)==LinphoneCallTerminated){
ms_warning("call_terminated: ignoring.");
return;
if (lc->vtable.display_status!=NULL)
lc->vtable.display_status(lc,_("Call terminated."));
call->state=LinphoneCallTerminated;
- gstate_new_state(lc, GSTATE_CALL_END, NULL);
+ gstate_new_state(lc, GSTATE_CALL_END, gctx, NULL);
if (lc->vtable.bye_recv!=NULL){
LinphoneAddress *addr=linphone_address_new(from);
char *tmp;
char *msg603=_("Call declined.");
char *msg=(char*)details;
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
+ LinphoneGeneralStateContext gctx;
+ gctx.call=call;
if (lc->vtable.show) lc->vtable.show(lc);
if (error==SalErrorNoResponse){
if(call == linphone_core_get_current_call(lc))
linphone_core_stop_media_streams(lc,call);
if (call!=NULL) {
- if (sr!=SalReasonDeclined) gstate_new_state(lc, GSTATE_CALL_ERROR, msg);
- else gstate_new_state(lc, GSTATE_CALL_END, NULL);
+ if (sr!=SalReasonDeclined) gstate_new_state(lc, GSTATE_CALL_ERROR, gctx, msg);
+ else gstate_new_state(lc, GSTATE_CALL_END, gctx, NULL);
linphone_call_set_terminated(call);
}
}
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)sal_op_get_user_pointer(op);
char *msg;
+ LinphoneGeneralStateContext gctx;
+ gctx.proxy=cfg;
cfg->registered=registered;
- gstate_new_state(lc, GSTATE_REG_OK, NULL);
+ gstate_new_state(lc, GSTATE_REG_OK,gctx, NULL);
if (cfg->registered) msg=ms_strdup_printf(_("Registration on %s successful."),sal_op_get_proxy(op));
else msg=ms_strdup_printf(_("Unregistration on %s done."),sal_op_get_proxy(op));
if (lc->vtable.display_status)
static void register_failure(SalOp *op, SalError error, SalReason reason, const char *details){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
+ LinphoneGeneralStateContext gctx;
char *msg=ortp_strdup_printf(_("Registration on %s failed: %s"),sal_op_get_proxy(op),(details!=NULL) ? details : _("no response timeout"));
if (lc->vtable.display_status) lc->vtable.display_status(lc,msg);
- gstate_new_state(lc, GSTATE_REG_FAILED, msg);
+ gctx.proxy=(LinphoneProxyConfig*)sal_op_get_user_pointer (op);
+ gstate_new_state(lc, GSTATE_REG_FAILED, gctx, msg);
ms_free(msg);
}
void gstate_new_state(struct _LinphoneCore *lc,
gstate_t new_state,
+ LinphoneGeneralStateContext gctx,
const char *message) {
- LinphoneGeneralState states_arg;
-
- /* determine the affected group */
- if (new_state < GSTATE_REG_NONE)
- states_arg.group = GSTATE_GROUP_POWER;
- else if (new_state < GSTATE_CALL_IDLE)
- states_arg.group = GSTATE_GROUP_REG;
- else
- states_arg.group = GSTATE_GROUP_CALL;
-
- /* store the new state while remembering the old one */
- states_arg.new_state = new_state;
- states_arg.old_state = linphone_core_get_state(lc,states_arg.group);
- linphone_core_set_state(lc, states_arg.group,new_state);
- states_arg.message = message;
-
- /*printf("gstate_new_state: %s\t-> %s\t(%s)\n",
- _gstates_text[states_arg.old_state],
- _gstates_text[states_arg.new_state],
- message);*/
+ LinphoneGeneralState states_arg;
- /* call the virtual method */
- if (lc->vtable.general_state)
- lc->vtable.general_state(lc, &states_arg);
-
- /* immediately proceed to idle state */
- if (new_state == GSTATE_CALL_END ||
- new_state == GSTATE_CALL_ERROR)
- gstate_new_state(lc, GSTATE_CALL_IDLE, NULL);
+ /* determine the affected group */
+ if (new_state < GSTATE_REG_NONE)
+ states_arg.group = GSTATE_GROUP_POWER;
+ else if (new_state < GSTATE_CALL_IDLE)
+ states_arg.group = GSTATE_GROUP_REG;
+ else
+ states_arg.group = GSTATE_GROUP_CALL;
+
+ /* store the new state while remembering the old one */
+ states_arg.new_state = new_state;
+ states_arg.old_state = linphone_core_get_state(lc,states_arg.group);
+ linphone_core_set_state(lc, states_arg.group,new_state);
+ states_arg.message = message;
+
+ /*printf("gstate_new_state: %s\t-> %s\t(%s)\n",
+ _gstates_text[states_arg.old_state],
+ _gstates_text[states_arg.new_state],
+ message);*/
+
+ /* call the virtual method */
+ if (lc->vtable.general_state)
+ lc->vtable.general_state(lc, &states_arg, gctx);
+
+ /* immediately proceed to idle state */
+ if (new_state == GSTATE_CALL_END ||
+ new_state == GSTATE_CALL_ERROR)
+ gstate_new_state(lc, GSTATE_CALL_IDLE, gctx, NULL);
}
linphone_core_notify_all_friends(lc,lc->prev_mode);
linphone_core_update_allocated_audio_bandwidth(lc);
- if (call->state==LinphoneCallAVRunning){
+ if (call->state==LinphoneCallAVRunning || call->state==LinphoneCallPaused){
status=LinphoneCallSuccess;
}
call->user_pointer = user_pointer;
}
+/**
+ * Returns the call log associated to this call.
+**/
+LinphoneCallLog *linphone_call_get_call_log(const LinphoneCall *call){
+ return call->log;
+}
+
+
/**
* @}
**/
static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vtable, const char *config_path,
const char *factory_config_path, void * userdata)
{
+ LinphoneGeneralStateContext gctx={0};
memset (lc, 0, sizeof (LinphoneCore));
lc->data=userdata;
memcpy(&lc->vtable,vtable,sizeof(LinphoneCoreVTable));
gstate_initialize(lc);
- gstate_new_state(lc, GSTATE_POWER_STARTUP, NULL);
+ gstate_new_state(lc, GSTATE_POWER_STARTUP, gctx, NULL);
ortp_init();
linphone_core_assign_payload_type(&payload_type_pcmu8000,0,NULL);
ui_config_read(lc);
if (lc->vtable.display_status)
lc->vtable.display_status(lc,_("Ready"));
- gstate_new_state(lc, GSTATE_POWER_ON, NULL);
+ gstate_new_state(lc, GSTATE_POWER_ON, gctx, NULL);
lc->auto_net_state_mon=lc->sip_conf.auto_net_state_mon;
lc->ready=TRUE;
char *contact;
char *real_url,*barmsg;
char *from;
+ LinphoneGeneralStateContext gctx;
/*try to be best-effort in giving real local or routable contact address */
contact=get_fixed_contact(lc,call,dest_proxy);
if (contact){
if(call == linphone_core_get_current_call(lc))
linphone_core_stop_media_streams(lc,call);
linphone_call_set_terminated (call);
- }else gstate_new_state(lc, GSTATE_CALL_OUT_INVITE, real_url);
+ }else {
+ gctx.call=call;
+ gstate_new_state(lc, GSTATE_CALL_OUT_INVITE, gctx, real_url);
+ }
ms_free(real_url);
ms_free(from);
return err;
{
LinphoneProxyConfig *cfg=NULL;
const char *contact=NULL;
+ LinphoneGeneralStateContext gctx;
if (call==NULL){
//if just one call is present answer the only one ...
sal_call_accept(call->op);
if (lc->vtable.display_status!=NULL)
lc->vtable.display_status(lc,_("Connected."));
- gstate_new_state(lc, GSTATE_CALL_IN_CONNECTED, NULL);
+ gctx.call=call;
+ gstate_new_state(lc, GSTATE_CALL_IN_CONNECTED, gctx, NULL);
call->resultdesc=sal_call_get_final_media_description(call->op);
if (call->resultdesc){
sal_media_description_ref(call->resultdesc);
int linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *the_call)
{
LinphoneCall *call;
+ LinphoneGeneralStateContext gctx;
if (the_call == NULL){
call = linphone_core_get_current_call(lc);
if(call == NULL){
linphone_core_stop_media_streams(lc,call);
if (lc->vtable.display_status!=NULL)
lc->vtable.display_status(lc,_("Call ended") );
- gstate_new_state(lc, GSTATE_CALL_END, NULL);
+ gctx.call=call;
+ gstate_new_state(lc, GSTATE_CALL_END, gctx, NULL);
linphone_call_set_terminated(call);
return 0;
}
static void linphone_core_uninit(LinphoneCore *lc)
{
+ LinphoneGeneralStateContext gctx;
while(lc->calls)
{
LinphoneCall *the_call = lc->calls->data;
if (lc->friends)
ms_list_for_each(lc->friends,(void (*)(void *))linphone_friend_close_subscriptions);
- gstate_new_state(lc, GSTATE_POWER_SHUTDOWN, NULL);
+ gctx.call=NULL;
+ gstate_new_state(lc, GSTATE_POWER_SHUTDOWN, gctx, NULL);
#ifdef VIDEO_ENABLED
if (lc->previewstream!=NULL){
video_preview_stop(lc->previewstream);
linphone_core_free_payload_types();
ortp_exit();
- gstate_new_state(lc, GSTATE_POWER_OFF, NULL);
+ gstate_new_state(lc, GSTATE_POWER_OFF, gctx, NULL);
}
static void set_network_reachable(LinphoneCore* lc,bool_t isReachable){
struct _SipSetupContext;
-/**
- * The LinphoneCall object represents a call issued or received by the LinphoneCore
-**/
-struct _LinphoneCall;
-typedef struct _LinphoneCall LinphoneCall;
-
-typedef enum _LinphoneCallState{
- LinphoneCallInit,
- LinphoneCallPreEstablishing,
- LinphoneCallRinging,
- LinphoneCallAVRunning,
- LinphoneCallPaused,
- LinphoneCallTerminated
-}LinphoneCallState;
-
-LinphoneCallState linphone_call_get_state(const LinphoneCall *call);
-bool_t linphone_call_asked_to_autoanswer(LinphoneCall *call);
-bool_t linphone_call_paused(LinphoneCall *call);
-const LinphoneAddress * linphone_core_get_current_call_remote_address(struct _LinphoneCore *lc);
-const LinphoneAddress * linphone_call_get_remote_address(const LinphoneCall *call);
-char *linphone_call_get_remote_address_as_string(const LinphoneCall *call);
-void linphone_call_ref(LinphoneCall *call);
-void linphone_call_unref(LinphoneCall *call);
-
/**
* Enum representing the direction of a call.
const rtp_stats_t *linphone_call_log_get_remote_stats(const LinphoneCallLog *cl);
char * linphone_call_log_to_str(LinphoneCallLog *cl);
+
+/**
+ * The LinphoneCall object represents a call issued or received by the LinphoneCore
+**/
+struct _LinphoneCall;
+typedef struct _LinphoneCall LinphoneCall;
+
+typedef enum _LinphoneCallState{
+ LinphoneCallInit,
+ LinphoneCallPreEstablishing,
+ LinphoneCallRinging,
+ LinphoneCallAVRunning,
+ LinphoneCallPaused,
+ LinphoneCallTerminated
+}LinphoneCallState;
+
+LinphoneCallState linphone_call_get_state(const LinphoneCall *call);
+bool_t linphone_call_asked_to_autoanswer(LinphoneCall *call);
+bool_t linphone_call_paused(LinphoneCall *call);
+const LinphoneAddress * linphone_core_get_current_call_remote_address(struct _LinphoneCore *lc);
+const LinphoneAddress * linphone_call_get_remote_address(const LinphoneCall *call);
+char *linphone_call_get_remote_address_as_string(const LinphoneCall *call);
+void linphone_call_ref(LinphoneCall *call);
+void linphone_call_unref(LinphoneCall *call);
+LinphoneCallLog *linphone_call_get_call_log(const LinphoneCall *call);
+
+
typedef enum{
LinphoneSPWait,
LinphoneSPDeny,
};
typedef struct _LinphoneGeneralState LinphoneGeneralState;
-/* private: set a new state */
-void gstate_new_state(struct _LinphoneCore *lc, gstate_t new_state, const char *message);
-/*private*/
-void gstate_initialize(struct _LinphoneCore *lc) ;
+
+typedef union _LinphoneGeneralStateContext{
+ LinphoneCall *call;
+ LinphoneProxyConfig *proxy;
+}LinphoneGeneralStateContext;
/**
* @addtogroup initializing
/** Callback prototype */
typedef void (*TextMessageReceived)(struct _LinphoneCore *lc, LinphoneChatRoom *room, const char *from, const char *message);
/** Callback prototype */
-typedef void (*GeneralStateChange)(struct _LinphoneCore *lc, LinphoneGeneralState *gstate);
+typedef void (*GeneralStateChange)(struct _LinphoneCore *lc, LinphoneGeneralState *gstate, LinphoneGeneralStateContext ctx);
/** Callback prototype */
typedef void (*DtmfReceived)(struct _LinphoneCore* lc, int dtmf);
/** Callback prototype */
#endif
-
+/* private: set a new state */
+void gstate_new_state(struct _LinphoneCore *lc, gstate_t new_state, LinphoneGeneralStateContext context, const char *message);
+/*private*/
+void gstate_initialize(struct _LinphoneCore *lc);
struct _LinphoneCall
{
}
static void linphone_proxy_config_register(LinphoneProxyConfig *obj){
+ LinphoneGeneralStateContext gctx;
const char *id_str;
+
+ gctx.proxy=obj;
if (obj->reg_identity!=NULL) id_str=obj->reg_identity;
else id_str=linphone_core_get_primary_contact(obj->lc);
if (obj->reg_sendregister){
ms_free(contact);
sal_op_set_user_pointer(obj->op,obj);
if (!sal_register(obj->op,obj->reg_proxy,obj->reg_identity,obj->expires)) {
- gstate_new_state(obj->lc,GSTATE_REG_PENDING,NULL);
+ gstate_new_state(obj->lc,GSTATE_REG_PENDING, gctx, NULL);
} else {
- gstate_new_state(obj->lc,GSTATE_REG_FAILED,NULL);
+ gstate_new_state(obj->lc,GSTATE_REG_FAILED, gctx, NULL);
}
}
}
static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const char *url);
static void linphone_gtk_display_question(LinphoneCore *lc, const char *question);
static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl);
-static void linphone_gtk_general_state(LinphoneCore *lc, LinphoneGeneralState *gstate);
+static void linphone_gtk_general_state(LinphoneCore *lc, LinphoneGeneralState *gstate, LinphoneGeneralStateContext gctx);
static void linphone_gtk_refer_received(LinphoneCore *lc, LinphoneCall *call, const char *refer_to);
static gboolean linphone_gtk_auto_answer(GtkWidget *incall_window);
if (w) linphone_gtk_call_log_update(w);
}
-static void linphone_gtk_general_state(LinphoneCore *lc, LinphoneGeneralState *gstate){
+static void linphone_gtk_general_state(LinphoneCore *lc, LinphoneGeneralState *gstate, LinphoneGeneralStateContext gctx){
switch(gstate->new_state){
case GSTATE_CALL_OUT_CONNECTED:
case GSTATE_CALL_IN_CONNECTED:
-Subproject commit 17e879de84d894df6a1875665594567c1cf43617
+Subproject commit 55e0624b53e984eecc6b5a4eedef467456968886