Skip to content

Commit ef79a60

Browse files
authored
Merge pull request #147 from kmatzen/fix/issue-95-dtmf-during-call
feat(#95): Send DTMF to Baresip during active call
2 parents 5a726c8 + 5901016 commit ef79a60

File tree

9 files changed

+54
-5
lines changed

9 files changed

+54
-5
lines changed

host/baresip_interface.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ struct ua *baresip_call_get_ua(struct call *call) {
127127
return call_get_ua(call);
128128
}
129129

130+
int baresip_call_send_digit(struct call *call, char key) {
131+
return call_send_digit(call, key);
132+
}
133+
130134
/* Event functions - thunk to bridge enum baresip_ua_event <-> enum ua_event */
131135
static baresip_ua_event_handler_t g_bevent_handler;
132136
static void *g_bevent_arg;

host/baresip_interface.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ int baresip_account_uri_complete_strdup(struct account *account, char **uri, con
102102

103103
/* Call functions */
104104
struct ua *baresip_call_get_ua(struct call *call);
105+
int baresip_call_send_digit(struct call *call, char key);
105106

106107
/* Event functions */
107108
void baresip_bevent_register(baresip_ua_event_handler_t handler, void *arg);

host/daemon.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,9 @@ void handle_keypad_event(keypad_event_t *keypad_event) {
447447
VALIDATE_BASICS();
448448

449449
char key = keypad_event_get_key(keypad_event);
450+
int in_call = (daemon_state->current_state == DAEMON_STATE_CALL_ACTIVE ||
451+
daemon_state->current_state == DAEMON_STATE_CALL_INCOMING);
452+
450453
if (isdigit(key)) {
451454
pthread_mutex_lock(&daemon_state_mutex);
452455

@@ -462,10 +465,12 @@ void handle_keypad_event(keypad_event_t *keypad_event) {
462465
}
463466
pthread_mutex_unlock(&daemon_state_mutex);
464467

465-
/* Let active plugin handle the keypad event */
466-
if (isdigit(key)) {
467-
plugins_handle_keypad(key);
468-
}
468+
plugins_handle_keypad(key);
469+
daemon_broadcast_state("keypad");
470+
} else if (in_call && (key == '*' || key == '#')) {
471+
/* #95: Pass * and # to plugin for DTMF during call */
472+
metrics_increment_counter("keypad_presses", 1);
473+
plugins_handle_keypad(key);
469474
daemon_broadcast_state("keypad");
470475
}
471476
}

host/millennium_sdk.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,13 @@ void millennium_client_hangup(struct millennium_client *client) {
519519
logger_info_with_category("SDK", "Call terminated.");
520520
}
521521

522+
int millennium_client_send_dtmf(struct millennium_client *client, char key) {
523+
if (!client || !client->ua) return -1;
524+
struct call *call = baresip_ua_call((struct ua *)client->ua);
525+
if (!call) return -1;
526+
return baresip_call_send_digit(call, key);
527+
}
528+
522529
void millennium_client_serial_activity(struct millennium_client *client) {
523530
if (!client) return;
524531
clock_gettime(CLOCK_MONOTONIC, &client->last_serial_activity);

host/millennium_sdk.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ void *millennium_client_next_event(struct millennium_client *client);
8484
void millennium_client_call(struct millennium_client *client, const char *number);
8585
void millennium_client_answer_call(struct millennium_client *client);
8686
void millennium_client_hangup(struct millennium_client *client);
87+
int millennium_client_send_dtmf(struct millennium_client *client, char key);
8788
void millennium_client_set_ua(struct millennium_client *client, void *ua);
8889

8990
/* Internal functions */

host/plugins/classic_phone.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,12 @@ static int classic_phone_handle_coin(int coin_value, const char *coin_code) {
7272

7373
static int classic_phone_handle_keypad(char key) {
7474
if (classic_phone_data.is_in_call) {
75-
/* In call - could handle DTMF here */
75+
/* #95: Send DTMF to Baresip for IVR/voicemail navigation */
76+
if (client && (isdigit((unsigned char)key) || key == '*' || key == '#')) {
77+
if (millennium_client_send_dtmf(client, key) == 0) {
78+
audio_tones_play_dtmf(key); /* Local feedback */
79+
}
80+
}
7681
return 0;
7782
}
7883

host/simulator.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,12 @@ void millennium_client_hangup(millennium_client_t *c) {
191191
sim_hangup_called = 1;
192192
}
193193

194+
int millennium_client_send_dtmf(millennium_client_t *c, char key) {
195+
(void)c;
196+
if (sim_call_active) fprintf(stderr, "[DTMF] %c\n", key);
197+
return sim_call_active ? 0 : -1;
198+
}
199+
194200
void millennium_client_set_ua(millennium_client_t *c, void *ua) {
195201
(void)c; (void)ua;
196202
}
@@ -327,8 +333,11 @@ static void sim_handle_hook(hook_state_change_event_t *ev) {
327333

328334
static void sim_handle_keypad(keypad_event_t *ev) {
329335
char key;
336+
int in_call;
330337
if (!ev || !daemon_state) return;
331338
key = keypad_event_get_key(ev);
339+
in_call = (daemon_state->current_state == DAEMON_STATE_CALL_ACTIVE ||
340+
daemon_state->current_state == DAEMON_STATE_CALL_INCOMING);
332341

333342
if (isdigit(key) &&
334343
daemon_state->current_state == DAEMON_STATE_IDLE_UP &&
@@ -337,6 +346,9 @@ static void sim_handle_keypad(keypad_event_t *ev) {
337346
daemon_state_add_key(daemon_state, key);
338347
daemon_state_update_activity(daemon_state);
339348
plugins_handle_keypad(key);
349+
} else if (in_call && (isdigit(key) || key == '*' || key == '#')) {
350+
/* #95: Pass keys to plugin for DTMF during call */
351+
plugins_handle_keypad(key);
340352
}
341353
}
342354

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Test: #95 DTMF during call - keys sent to Baresip for IVR/voicemail
2+
# When in CALL_ACTIVE, keypresses should send DTMF (simulator logs [DTMF] X)
3+
4+
hook_up
5+
coin 25
6+
coin 25
7+
keys 5551234567
8+
call_active
9+
10+
# Press keys during call - should trigger DTMF (no assertion; stderr shows [DTMF] 1, [DTMF] 2)
11+
keys 12
12+
13+
hook_down

host/tests/unit_tests.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ void millennium_client_set_display(millennium_client_t *c, const char *m) { (voi
2424
void millennium_client_call(millennium_client_t *c, const char *n) { (void)c; (void)n; }
2525
void millennium_client_answer_call(millennium_client_t *c) { (void)c; }
2626
void millennium_client_hangup(millennium_client_t *c) { (void)c; }
27+
int millennium_client_send_dtmf(millennium_client_t *c, char key) { (void)c; (void)key; return 0; }
2728
void millennium_client_update(millennium_client_t *c) { (void)c; }
2829
void *millennium_client_next_event(millennium_client_t *c) { (void)c; return NULL; }
2930
void millennium_client_write_to_display(millennium_client_t *c, const char *m) { (void)c; (void)m; }

0 commit comments

Comments
 (0)