Commit a8d304fd authored by Simon Morlat's avatar Simon Morlat

* implement reporting of dtmf received via SIP info

* dtmf can be typed on keyboard with gtk app.
parent 41f0390f
......@@ -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>
......
......@@ -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
mediastreamer2 @ 25d5fc4a
Subproject commit f8cba968622ce3400d2c67bfb8a248ef48363627
Subproject commit 25d5fc4a3383c3eeb79193bb31f1d2f123246dfd
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment