mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-18 03:28:07 +00:00
* implement reporting of dtmf received via SIP info
* dtmf can be typed on keyboard with gtk app.
This commit is contained in:
parent
41f0390f93
commit
a8d304fd8f
8 changed files with 116 additions and 6 deletions
|
|
@ -895,3 +895,5 @@ unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size){
|
|||
return belle_sip_random_bytes(ret,size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -362,7 +362,6 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
|
|||
}
|
||||
dialog_state=belle_sip_dialog_get_state(op->dialog);
|
||||
switch(dialog_state) {
|
||||
|
||||
case BELLE_SIP_DIALOG_NULL: {
|
||||
if (strcmp("INVITE",belle_sip_request_get_method(req))==0) {
|
||||
if (!op->replaces && (op->replaces=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_replaces_t))) {
|
||||
|
|
@ -461,7 +460,13 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
|
|||
}else{
|
||||
SalBody salbody;
|
||||
if (sal_op_get_body(op,(belle_sip_message_t*)req,&salbody)) {
|
||||
op->base.root->callbacks.info_received(op,&salbody);
|
||||
if (sal_body_has_type(&salbody,"application","dtmf-relay")){
|
||||
char tmp[10];
|
||||
if (sal_lines_get_value(salbody.data, "Signal",tmp, sizeof(tmp))){
|
||||
op->base.root->callbacks.dtmf_received(op,tmp[0]);
|
||||
}
|
||||
}else
|
||||
op->base.root->callbacks.info_received(op,&salbody);
|
||||
} else {
|
||||
op->base.root->callbacks.info_received(op,NULL);
|
||||
}
|
||||
|
|
@ -485,10 +490,9 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
|
|||
unsupported_method(server_transaction,req);
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
default:
|
||||
ms_error("unexpected dialog state [%s]",belle_sip_dialog_state_to_string(dialog_state));
|
||||
}
|
||||
/* no break */
|
||||
break;
|
||||
}
|
||||
|
||||
if (server_transaction) belle_sip_object_unref(server_transaction);
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ void linphone_core_update_streams_destinations(LinphoneCore *lc, LinphoneCall *c
|
|||
ms_message("Change video stream destination: RTP=%s:%d RTCP=%s:%d", rtp_addr, new_videodesc->rtp_port, rtcp_addr, new_videodesc->rtcp_port);
|
||||
rtp_session_set_remote_addr_full(call->videostream->ms.session, rtp_addr, new_videodesc->rtp_port, rtcp_addr, new_videodesc->rtcp_port);
|
||||
}
|
||||
#else
|
||||
(void)new_videodesc;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "config.h"
|
||||
#endif
|
||||
#include "sal/sal.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
const char* sal_transport_to_string(SalTransport transport) {
|
||||
switch (transport) {
|
||||
case SalTransportUDP:return "udp";
|
||||
|
|
@ -572,3 +575,55 @@ const char* sal_privacy_to_string(SalPrivacy privacy) {
|
|||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void remove_trailing_spaces(char *line){
|
||||
int i;
|
||||
for(i=strlen(line)-1;i>=0;--i){
|
||||
if (isspace(line[i])) line[i]='\0';
|
||||
else break;
|
||||
}
|
||||
}
|
||||
|
||||
static int line_get_value(const char *input, const char *key, char *value, size_t value_size, int *read){
|
||||
const char *end=strchr(input,'\n');
|
||||
char line[256]={0};
|
||||
char key_candidate[256];
|
||||
char *equal;
|
||||
size_t len;
|
||||
if (!end) len=strlen(input);
|
||||
else len=end +1 -input;
|
||||
*read=len;
|
||||
strncpy(line,input,MIN(len,sizeof(line)));
|
||||
equal=strchr(line,'=');
|
||||
if (!equal) return FALSE;
|
||||
*equal='\0';
|
||||
if (sscanf(line,"%s",key_candidate)!=1) return FALSE;
|
||||
if (strcasecmp(key,key_candidate)==0){
|
||||
equal++;
|
||||
remove_trailing_spaces(equal);
|
||||
strncpy(value,equal,value_size-1);
|
||||
value[value_size-1]='\0';
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size){
|
||||
int read=0;
|
||||
|
||||
do{
|
||||
if (line_get_value(data,key,value,value_size,&read))
|
||||
return TRUE;
|
||||
data+=read;
|
||||
}while(read!=0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int sal_body_has_type(const SalBody *body, const char *type, const char *subtype){
|
||||
return body->type && body->subtype
|
||||
&& strcmp(body->type,type)==0
|
||||
&& strcmp(body->subtype,subtype)==0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,11 @@
|
|||
<object class="GtkFrame" id="frame3">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="events">GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>
|
||||
<property name="label_xalign">0.5</property>
|
||||
<property name="shadow_type">none</property>
|
||||
<signal name="key-release-event" handler="linphone_gtk_keypad_key_released" swapped="no"/>
|
||||
<signal name="key-press-event" handler="linphone_gtk_keypad_key_pressed" swapped="no"/>
|
||||
<child>
|
||||
<object class="GtkAspectFrame" id="aspectframe1">
|
||||
<property name="visible">True</property>
|
||||
|
|
|
|||
40
gtk/main.c
40
gtk/main.c
|
|
@ -64,6 +64,7 @@ static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl)
|
|||
static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cs, const char *msg);
|
||||
static void linphone_gtk_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t enabled, const char *token);
|
||||
static void linphone_gtk_transfer_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate);
|
||||
static void linphone_gtk_dtmf_received(LinphoneCore *lc, LinphoneCall *call, int dtmf);
|
||||
void linphone_gtk_save_main_window_position(GtkWindow* mw, GdkEvent *event, gpointer data);
|
||||
static gboolean linphone_gtk_auto_answer(LinphoneCall *call);
|
||||
void linphone_gtk_status_icon_set_blinking(gboolean val);
|
||||
|
|
@ -251,6 +252,7 @@ static void linphone_gtk_init_liblinphone(const char *config_file,
|
|||
vtable.buddy_info_updated=linphone_gtk_buddy_info_updated;
|
||||
vtable.call_encryption_changed=linphone_gtk_call_encryption_changed;
|
||||
vtable.transfer_state_changed=linphone_gtk_transfer_state_changed;
|
||||
vtable.dtmf_received=linphone_gtk_dtmf_received;
|
||||
|
||||
the_core=linphone_core_new(&vtable,config_file,factory_config_file,NULL);
|
||||
//lp_config_set_int(linphone_core_get_config(the_core), "sip", "store_auth_info", 0);
|
||||
|
|
@ -1049,6 +1051,10 @@ static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm
|
|||
auth_timeout_new(w);
|
||||
}
|
||||
|
||||
static void linphone_gtk_dtmf_received(LinphoneCore *lc, LinphoneCall *call, int dtmf){
|
||||
ms_message("Dtmf %c received.",dtmf);
|
||||
}
|
||||
|
||||
static void linphone_gtk_display_status(LinphoneCore *lc, const char *status){
|
||||
GtkWidget *w=linphone_gtk_get_main_window();
|
||||
GtkWidget *status_bar=linphone_gtk_get_widget(w,"status_bar");
|
||||
|
|
@ -1715,6 +1721,40 @@ void linphone_gtk_init_dtmf_table(GtkWidget *mw){
|
|||
g_object_set_data(G_OBJECT(linphone_gtk_get_widget(mw,"dtmf_*")),"label","*");
|
||||
}
|
||||
|
||||
static gboolean key_allowed(guint32 code){
|
||||
static const char *allowed="1234567890#*ABCD";
|
||||
return code!=0 && strchr(allowed,(char)code)!=NULL;
|
||||
}
|
||||
|
||||
static GtkButton *get_button_from_key(GtkWidget *w, GdkEvent *event){
|
||||
guint keyval=event->key.keyval;
|
||||
guint32 code=gdk_keyval_to_unicode(keyval);
|
||||
code=g_unichar_toupper(code);
|
||||
if (key_allowed(code)){
|
||||
char widgetname[16];
|
||||
w=gtk_widget_get_toplevel(w);
|
||||
snprintf(widgetname,sizeof(widgetname),"dtmf_%c",code);
|
||||
return GTK_BUTTON(linphone_gtk_get_widget(w,widgetname));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_gtk_keypad_key_pressed(GtkWidget *w, GdkEvent *event, gpointer userdata){
|
||||
GtkButton *button=get_button_from_key(w,event);
|
||||
if (button) {
|
||||
linphone_gtk_dtmf_pressed(button);
|
||||
/*g_signal_emit_by_name(button, "button-press-event");*/
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_keypad_key_released(GtkWidget *w, GdkEvent *event, gpointer userdata){
|
||||
GtkButton *button=get_button_from_key(w,event);
|
||||
if (button) {
|
||||
linphone_gtk_dtmf_released(button);
|
||||
/*g_signal_emit_by_name(button, "button-release-event");*/
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_gtk_create_keypad(GtkWidget *button){
|
||||
GtkWidget *mw=linphone_gtk_get_main_window();
|
||||
GtkWidget *k=(GtkWidget *)g_object_get_data(G_OBJECT(mw),"keypad");
|
||||
|
|
|
|||
|
|
@ -691,4 +691,8 @@ LINPHONE_PUBLIC void sal_set_dns_user_hosts_file(Sal *sal, const char *hosts_fil
|
|||
LINPHONE_PUBLIC const char *sal_get_dns_user_hosts_file(const Sal *sal);
|
||||
unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size);
|
||||
|
||||
int sal_body_has_type(const SalBody *body, const char *type, const char *subtype);
|
||||
/*this function parses a document with key=value pairs separated by new lines, and extracts the value for a given key*/
|
||||
int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit f8cba968622ce3400d2c67bfb8a248ef48363627
|
||||
Subproject commit 25d5fc4a3383c3eeb79193bb31f1d2f123246dfd
|
||||
Loading…
Add table
Reference in a new issue