From: Michal Kubecek <mkubecek@suse.cz>
Date: Fri, 20 May 2016 09:48:18 +0200
Subject: DTMF event type cleanup
Patch-mainline: Not yet, going to submit

DTMF event constants handling is a bit messy as three different types
are used in different source files, triggering various compiler
warnings. Introduce t_dtmf_ev type and use it everywhere, also replace
helper macros by inline functions.
---
 src/audio/audio_rx.cpp            |  2 +-
 src/audio/audio_rx.h              |  4 ++--
 src/audio/dtmf_player.cpp         |  6 +++---
 src/audio/dtmf_player.h           |  8 ++++----
 src/audio/freq_gen.cpp            |  3 ++-
 src/audio/freq_gen.h              |  4 +++-
 src/audio/rtp_telephone_event.cpp |  8 ++++++--
 src/audio/rtp_telephone_event.h   | 25 ++++++++++++++++++++-----
 src/dialog.cpp                    |  2 +-
 src/events.cpp                    |  2 +-
 src/events.h                      |  5 +++--
 src/gui/gui.cpp                   | 10 +++++-----
 src/gui/gui.h                     |  4 ++--
 src/parser/sip_body.cpp           |  2 +-
 src/userintf.cpp                  | 14 +++++++-------
 src/userintf.h                    |  8 ++++----
 16 files changed, 65 insertions(+), 42 deletions(-)

diff --git a/src/audio/audio_rx.cpp b/src/audio/audio_rx.cpp
index 9435ac4447f2..e605fcfcc31f 100644
--- a/src/audio/audio_rx.cpp
+++ b/src/audio/audio_rx.cpp
@@ -657,7 +657,7 @@ void t_audio_rx::set_pt_telephone_event(int pt) {
 
 void t_audio_rx::push_dtmf(char digit, bool inband) {
 	// Ignore invalid DTMF digits
-	if (!VALID_DTMF_SYM(digit)) return;
+	if (!is_valid_dtmf_sym(digit)) return;
 
 	// Ignore DTMF tones in a 3-way conference
 	if (is_3way) return;
diff --git a/src/audio/audio_rx.h b/src/audio/audio_rx.h
index 5db87627a6db..88d8884bff0a 100644
--- a/src/audio/audio_rx.h
+++ b/src/audio/audio_rx.h
@@ -109,8 +109,8 @@ private:
 
 	// Queue of DTMF tones to be sent
 	struct t_dtmf_event {
-		uint8	dtmf_tone;
-		bool	inband;
+		t_dtmf_ev	dtmf_tone;
+		bool		inband;
 	};
 	
 	queue<t_dtmf_event>	dtmf_queue;
diff --git a/src/audio/dtmf_player.cpp b/src/audio/dtmf_player.cpp
index d3d5909cb6c8..54c2580d01cc 100644
--- a/src/audio/dtmf_player.cpp
+++ b/src/audio/dtmf_player.cpp
@@ -30,7 +30,7 @@
 /////////////////////////////////////////
 
 t_dtmf_player::t_dtmf_player(t_audio_rx *audio_rx, t_audio_encoder *audio_encoder, 
-			t_user *user_config, uint8 dtmf_tone, uint32 dtmf_timestamp,
+			t_user *user_config, t_dtmf_ev dtmf_tone, uint32 dtmf_timestamp,
 			uint16 nsamples) :
 	_audio_rx(audio_rx),
 	_user_config(user_config),
@@ -57,7 +57,7 @@ bool t_dtmf_player::finished(void) {
 
 t_rtp_event_dtmf_player::t_rtp_event_dtmf_player(t_audio_rx *audio_rx, 
 			t_audio_encoder *audio_encoder, t_user *user_config,
-			uint8 dtmf_tone, uint32 dtmf_timestamp,
+			t_dtmf_ev dtmf_tone, uint32 dtmf_timestamp,
 			uint16 nsamples) : 
 	t_dtmf_player(audio_rx, audio_encoder, user_config, dtmf_tone, dtmf_timestamp, 
 			nsamples)
@@ -125,7 +125,7 @@ uint16 t_rtp_event_dtmf_player::get_payload(uint8 *payload,
 
 t_inband_dtmf_player::t_inband_dtmf_player(t_audio_rx *audio_rx, 
 		t_audio_encoder *audio_encoder, t_user *user_config,
-		uint8 dtmf_tone, uint32 dtmf_timestamp,
+		t_dtmf_ev dtmf_tone, uint32 dtmf_timestamp,
 		uint16 nsamples) :
 	t_dtmf_player(audio_rx, audio_encoder, user_config, dtmf_tone, dtmf_timestamp, 
 			nsamples),
diff --git a/src/audio/dtmf_player.h b/src/audio/dtmf_player.h
index 01452897a2a4..de10bb13bed4 100644
--- a/src/audio/dtmf_player.h
+++ b/src/audio/dtmf_player.h
@@ -41,14 +41,14 @@ protected:
 	// Settings for current DTMF tone
 	bool		_dtmf_pause;      // indicates if playing is in the pause phase
 	bool		_dtmf_stop;	  // indicates if DTMF should be stopped
-	uint8		_dtmf_current;    // Currently played DTMF tone
+	t_dtmf_ev	_dtmf_current;    // Currently played DTMF tone
 	uint32		_dtmf_timestamp;  // RTP timestamp (start of tone)
 	uint16		_dtmf_duration;   // Duration of the tone currently played
 	uint16		_nsamples; 	  // number of samples taken per packet
 	
 public:
 	t_dtmf_player(t_audio_rx *audio_rx, t_audio_encoder *audio_encoder,
-		t_user *user_config, uint8 dtmf_tone, uint32 dtmf_timestamp,
+		t_user *user_config, t_dtmf_ev dtmf_tone, uint32 dtmf_timestamp,
 		uint16 nsamples);
 		
 	virtual ~t_dtmf_player() {};
@@ -71,7 +71,7 @@ public:
 class t_rtp_event_dtmf_player : public t_dtmf_player {
 public:
 	t_rtp_event_dtmf_player(t_audio_rx *audio_rx, t_audio_encoder *audio_encoder,
-		t_user *user_config, uint8 dtmf_tone, uint32 dtmf_timestamp,
+		t_user *user_config,  t_dtmf_ev dtmf_tone, uint32 dtmf_timestamp,
 		uint16 nsamples);
 	
 	virtual uint16 get_payload(uint8 *payload, uint16 payload_size,
@@ -87,7 +87,7 @@ private:
 	
 public:
 	t_inband_dtmf_player(t_audio_rx *audio_rx, t_audio_encoder *audio_encoder,
-		t_user *user_config, uint8 dtmf_tone, uint32 dtmf_timestamp,
+		t_user *user_config, t_dtmf_ev dtmf_tone, uint32 dtmf_timestamp,
 		uint16 nsamples);
 	
 	virtual uint16 get_payload(uint8 *payload, uint16 payload_size,
diff --git a/src/audio/freq_gen.cpp b/src/audio/freq_gen.cpp
index 5aad228e89a5..0ba669ee0cdb 100644
--- a/src/audio/freq_gen.cpp
+++ b/src/audio/freq_gen.cpp
@@ -35,7 +35,7 @@ t_freq_gen::t_freq_gen(vector<uint16> frequencies, int8 db_level) {
 	_amplitude = int16(pow(10.0, db_level / 20.0) * 32767 / _frequencies.size());
 }
 
-t_freq_gen::t_freq_gen(uint8 dtmf, int8 db_level) : _frequencies(2)
+t_freq_gen::t_freq_gen(t_dtmf_ev dtmf, int8 db_level) : _frequencies(2)
 {
 	assert(db_level <= 0);
 	
@@ -106,6 +106,7 @@ t_freq_gen::t_freq_gen(uint8 dtmf, int8 db_level) : _frequencies(2)
 		break;
 	default:
 		assert(false);
+		_frequencies.clear();
 	}
 		
 	// dB = 20 * log(amplitude / 32768)
diff --git a/src/audio/freq_gen.h b/src/audio/freq_gen.h
index 6817baa2f7d5..40818fab5702 100644
--- a/src/audio/freq_gen.h
+++ b/src/audio/freq_gen.h
@@ -28,6 +28,8 @@
 #include <vector>
 #include <commoncpp/config.h>
 
+#include "rtp_telephone_event.h"
+
 using namespace std;
 
 class t_freq_gen {
@@ -37,7 +39,7 @@ private:
 	
 public:
 	t_freq_gen(vector<uint16> frequencies, int8 db_level);
-	t_freq_gen(uint8 dtmf, int8 db_level);
+	t_freq_gen(t_dtmf_ev dtmf, int8 db_level);
 	
 	// Get sound sample on a particular timestamp in us.
 	int16 get_sample(uint32 ts_usec) const;
diff --git a/src/audio/rtp_telephone_event.cpp b/src/audio/rtp_telephone_event.cpp
index a076531701d7..b4f4c00ab624 100644
--- a/src/audio/rtp_telephone_event.cpp
+++ b/src/audio/rtp_telephone_event.cpp
@@ -60,16 +60,18 @@ unsigned short t_rtp_telephone_event::get_duration(void) const {
 	return ntohs(duration);
 }
 
-unsigned char char2dtmf_ev(char sym) {
+t_dtmf_ev char2dtmf_ev(char sym) {
 	if (sym >= '0' && sym <= '9') return (sym - '0' + TEL_EV_DTMF_0);
 	if (sym >= 'A' && sym <= 'D') return (sym - 'A' + TEL_EV_DTMF_A);
 	if (sym >= 'a' && sym <= 'd') return (sym-  'a' + TEL_EV_DTMF_A);
 	if (sym == '*') return TEL_EV_DTMF_STAR;
 	if (sym == '#') return TEL_EV_DTMF_POUND;
+
 	assert(false);
+	return TEL_EV_DTMF_INVALID;
 }
 
-char dtmf_ev2char(unsigned char ev) {
+char dtmf_ev2char(t_dtmf_ev ev) {
 	if (ev <= TEL_EV_DTMF_9) {
 		return ev + '0' - TEL_EV_DTMF_0;
 	}
@@ -78,6 +80,8 @@ char dtmf_ev2char(unsigned char ev) {
 	}
 	if (ev == TEL_EV_DTMF_STAR) return '*';
 	if (ev == TEL_EV_DTMF_POUND) return '#';
+
 	assert(false);
+	return '?';
 }
 
diff --git a/src/audio/rtp_telephone_event.h b/src/audio/rtp_telephone_event.h
index 372504cd4edc..5f8d0053f3f1 100644
--- a/src/audio/rtp_telephone_event.h
+++ b/src/audio/rtp_telephone_event.h
@@ -25,6 +25,8 @@
 
 // RFC 2833 3.10
 // DTMF events
+typedef unsigned char t_dtmf_ev;
+
 #define	TEL_EV_DTMF_0		0
 #define	TEL_EV_DTMF_1		1
 #define	TEL_EV_DTMF_2		2
@@ -41,12 +43,25 @@
 #define	TEL_EV_DTMF_B		13
 #define	TEL_EV_DTMF_C		14
 #define	TEL_EV_DTMF_D		15
+#define	TEL_EV_DTMF_INVALID	((t_dtmf_ev) 0xff)
+
+static inline bool is_valid_dtmf_ev(t_dtmf_ev ev)
+{
+	return (ev <= TEL_EV_DTMF_D);
+}
 
-#define VALID_DTMF_EV(ev)	( (ev) <= TEL_EV_DTMF_D )
-#define VALID_DTMF_SYM(s)	( ((s) >= '0' && (s) <= '9') || \
-				  ((s) >= 'a' && (s) <= 'd') || \
-				  ((s) >= 'A' && (s) <= 'D') || \
-				  (s) == '*' || (s) == '#' )
+static inline bool is_valid_dtmf_sym(char s)
+{
+	if (s >= '0' && s <= '9')
+		return true;
+	if (s >= 'a' && s <= 'd')
+		return true;
+	if (s >= 'A' && s <= 'D')
+		return true;
+	if (s == '*' || s == '#')
+		return true;
+	return false;
+}
 
 // RFC 2833 3.5
 // Payload format (in network order!!)
diff --git a/src/dialog.cpp b/src/dialog.cpp
index f6e1790d1c4d..b6e58f59acc5 100644
--- a/src/dialog.cpp
+++ b/src/dialog.cpp
@@ -1268,7 +1268,7 @@ void t_dialog::process_info(t_request *r, t_tuid tuid, t_tid tid) {
 	}
 	
 	char dtmf_signal = ((t_sip_body_dtmf_relay *)r->body)->signal;
-	if (!VALID_DTMF_SYM(dtmf_signal)) {
+	if (!is_valid_dtmf_sym(dtmf_signal)) {
 		resp = r->create_response(R_400_BAD_REQUEST, "Invalid DTMF signal");
 		line->send_response(resp, tuid, tid);
 		MEMMAN_DELETE(resp);
diff --git a/src/events.cpp b/src/events.cpp
index dcd30d881a97..a773a73783fd 100644
--- a/src/events.cpp
+++ b/src/events.cpp
@@ -385,7 +385,7 @@ void t_event_ui::set_codec(t_audio_codec _codec) {
 	codec = _codec;
 }
 
-void t_event_ui::set_dtmf_event(char _dtmf_event) {
+void t_event_ui::set_dtmf_event(t_dtmf_ev _dtmf_event) {
 	dtmf_event = _dtmf_event;
 }
 
diff --git a/src/events.h b/src/events.h
index 460ae9549169..a2308527ddba 100644
--- a/src/events.h
+++ b/src/events.h
@@ -29,6 +29,7 @@
 #include "timekeeper.h"
 #include "stun/stun.h"
 #include "audio/audio_codecs.h"
+#include "audio/rtp_telephone_event.h"
 #include "parser/sip_message.h"
 #include "sockets/socket.h"
 #include "sockets/url.h"
@@ -497,7 +498,7 @@ private:
 	//@{
 	int		line;		/**< Line number. */
 	t_audio_codec	codec;		/**< Audio codec. */
-	char		dtmf_event;	/**< DTMF event. */
+	t_dtmf_ev	dtmf_event;	/**< DTMF event. */
 	bool		encrypted;	/**< Encryption indication. */
 	string		cipher_mode;	/**< Cipher mode (algorithm name). */
 	string		zrtp_sas;	/**< ZRTP SAS/ */
@@ -518,7 +519,7 @@ public:
 	//@{
 	void set_line(int _line);
 	void set_codec(t_audio_codec _codec);
-	void set_dtmf_event(char _dtmf_event);
+	void set_dtmf_event(t_dtmf_ev _dtmf_event);
 	void set_encrypted(bool on);
 	void set_cipher_mode(const string &_cipher_mode);
 	void set_zrtp_sas(const string &sas);
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index 752ae966b606..160f982d915c 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -1822,7 +1822,7 @@ void t_gui::cb_stop_call_notification(int line) {
 	unlock();
 }
 
-void t_gui::cb_dtmf_detected(int line, char dtmf_event) {
+void t_gui::cb_dtmf_detected(int line, t_dtmf_ev dtmf_event) {
 	if (line >= NUM_USER_LINES) return;
 	
 	lock();
@@ -1831,7 +1831,7 @@ void t_gui::cb_dtmf_detected(int line, char dtmf_event) {
 	emit mw_display_header();
 	s = qApp->translate("GUI", "Line %1: DTMF detected:").arg(line + 1).append(" ");
 	
-	if (VALID_DTMF_EV(dtmf_event)) {
+	if (is_valid_dtmf_ev(dtmf_event)) {
 		s.append(dtmf_ev2char(dtmf_event));
 	} else {
 		s.append(qApp->translate("GUI", "invalid DTMF telephone event (%1)").arg(
@@ -1843,13 +1843,13 @@ void t_gui::cb_dtmf_detected(int line, char dtmf_event) {
 	unlock();
 }
 
-void t_gui::cb_send_dtmf(int line, char dtmf_event) {
+void t_gui::cb_send_dtmf(int line, t_dtmf_ev dtmf_event) {
 	if (line >= NUM_USER_LINES) return;
 	
 	lock();
 	QString s;
 	
-	if (!VALID_DTMF_EV(dtmf_event)) return;
+	if (!is_valid_dtmf_ev(dtmf_event)) return;
 	
 	emit mw_display_header();
 	s = qApp->translate("GUI", "Line %1: send DTMF %2").arg(line + 1).arg(
@@ -2988,7 +2988,7 @@ void t_gui::action_dtmf(const string &digits) {
 	if (!call_info.dtmf_supported) return;
 	
 	for (string::const_iterator i = digits.begin(); i != digits.end(); i++) {
-		if (VALID_DTMF_SYM(*i)) {
+		if (is_valid_dtmf_sym(*i)) {
 			phone->pub_send_dtmf(*i, call_info.dtmf_inband, call_info.dtmf_info);
 		}
 	}
diff --git a/src/gui/gui.h b/src/gui/gui.h
index 10f5ea270b4d..db27ad03f19d 100644
--- a/src/gui/gui.h
+++ b/src/gui/gui.h
@@ -242,8 +242,8 @@ public:
 	void cb_notify_call(int line, const QString &from_party, const QString &organization,
 			   const QImage &photo, const QString &subject, QString &referred_by_party);
 	void cb_stop_call_notification(int line);
-	void cb_dtmf_detected(int line, char dtmf_event);
-	void cb_send_dtmf(int line, char dtmf_event);
+	void cb_dtmf_detected(int line, t_dtmf_ev dtmf_event);
+	void cb_send_dtmf(int line, t_dtmf_ev dtmf_event);
 	void cb_dtmf_not_supported(int line);
 	void cb_dtmf_supported(int line);
 	void cb_line_state_changed(void);
diff --git a/src/parser/sip_body.cpp b/src/parser/sip_body.cpp
index cc95f8575cc3..2ee455b92dc9 100644
--- a/src/parser/sip_body.cpp
+++ b/src/parser/sip_body.cpp
@@ -247,7 +247,7 @@ bool t_sip_body_dtmf_relay::parse(const string &s) {
 		if (value.empty()) continue;
 		
 		if (parameter == "signal") {
-			if (!VALID_DTMF_SYM(value[0])) return false;
+			if (!is_valid_dtmf_sym(value[0])) return false;
 			signal = value[0];
 			valid = true;
 		} else if (parameter == "duration") {
diff --git a/src/userintf.cpp b/src/userintf.cpp
index a019d9813b6e..6327ed846797 100644
--- a/src/userintf.cpp
+++ b/src/userintf.cpp
@@ -1001,7 +1001,7 @@ void t_userintf::do_dtmf(const string &digits) {
 	if (!call_info.dtmf_supported) return;
 	
 	for (string::const_iterator i = digits.begin(); i != digits.end(); i++) {
-		if (VALID_DTMF_SYM(*i)) {
+		if (is_valid_dtmf_sym(*i)) {
 			phone->pub_send_dtmf(*i, call_info.dtmf_inband, call_info.dtmf_info);
 		}
 	}
@@ -2939,13 +2939,13 @@ void t_userintf::cb_stop_call_notification(int line) {
 	cb_stop_tone(line);
 }
 
-void t_userintf::cb_dtmf_detected(int line, char dtmf_event) {
+void t_userintf::cb_dtmf_detected(int line, t_dtmf_ev dtmf_event) {
 	if (line >= NUM_USER_LINES) return;
 	
 	cout << endl;
 	cout << "Line " << line + 1 << ": DTMF detected: ";
 
-	if (VALID_DTMF_EV(dtmf_event)) {
+	if (is_valid_dtmf_ev(dtmf_event)) {
 		cout << dtmf_ev2char(dtmf_event) << endl;
 	} else {
 		cout << "invalid DTMF telephone event (" << (int)dtmf_event << endl;
@@ -2955,22 +2955,22 @@ void t_userintf::cb_dtmf_detected(int line, char dtmf_event) {
 	cout.flush();
 }
 
-void t_userintf::cb_async_dtmf_detected(int line, char dtmf_event) {
+void t_userintf::cb_async_dtmf_detected(int line, t_dtmf_ev dtmf_event) {
 	if (line >= NUM_USER_LINES) return;
 	
 	t_event_ui *event = new t_event_ui(TYPE_UI_CB_DTMF_DETECTED);
 	MEMMAN_NEW(event);
 	
 	event->set_line(line);
-	event->set_dtmf_event(dtmf_event);	
+	event->set_dtmf_event(dtmf_event);
 	evq_ui_events.push(event);
 }
 
-void t_userintf::cb_send_dtmf(int line, char dtmf_event) {
+void t_userintf::cb_send_dtmf(int line, t_dtmf_ev dtmf_event) {
 	// No feed back in CLI
 }
 
-void t_userintf::cb_async_send_dtmf(int line, char dtmf_event) {
+void t_userintf::cb_async_send_dtmf(int line, t_dtmf_ev dtmf_event) {
 	t_event_ui *event = new t_event_ui(TYPE_UI_CB_SEND_DTMF);
 	MEMMAN_NEW(event);
 	
diff --git a/src/userintf.h b/src/userintf.h
index e9b560605785..9bb5b8032aae 100644
--- a/src/userintf.h
+++ b/src/userintf.h
@@ -270,10 +270,10 @@ public:
         virtual void cb_stop_tone(int line);
         virtual void cb_notify_call(int line, string from_party);
         virtual void cb_stop_call_notification(int line);
-	virtual void cb_dtmf_detected(int line, char dtmf_event);
-	virtual void cb_async_dtmf_detected(int line, char dtmf_event);
-	virtual void cb_send_dtmf(int line, char dtmf_event);
-	virtual void cb_async_send_dtmf(int line, char dtmf_event);
+	virtual void cb_dtmf_detected(int line, t_dtmf_ev dtmf_event);
+	virtual void cb_async_dtmf_detected(int line, t_dtmf_ev dtmf_event);
+	virtual void cb_send_dtmf(int line, t_dtmf_ev dtmf_event);
+	virtual void cb_async_send_dtmf(int line, t_dtmf_ev dtmf_event);
 	virtual void cb_dtmf_not_supported(int line);
 	virtual void cb_dtmf_supported(int line);
 	virtual void cb_line_state_changed(void);
-- 
2.8.2

