Implement last number dialed (AT+BLDN) support

This commit is contained in:
Johan Hedberg 2008-09-05 11:38:07 +03:00
parent a3634219a1
commit 1b971b060b
3 changed files with 111 additions and 2 deletions

View File

@ -62,6 +62,9 @@
#define RING_INTERVAL 3000
/* Number of indicator events that can be queued */
#define EV_BUF_SIZE 4
#define BUF_SIZE 1024
#define HEADSET_GAIN_SPEAKER 'S'
@ -74,12 +77,19 @@ static struct {
int er_mode; /* Event reporting mode */
int er_ind; /* Event reporting for indicators */
int rh; /* Response and Hold state */
gboolean ev_buf_active; /* Buffer indicator events */
struct {
int index; /* HFP indicator index */
int val; /* new indicator value */
} ev_buf[EV_BUF_SIZE]; /* Indicator event buffer */
} ag = {
.telephony_ready = FALSE,
.features = 0,
.er_mode = 3,
.er_ind = 0,
.rh = -1,
.ev_buf_active = FALSE,
.ev_buf = { { 0, 0 } },
};
static gboolean sco_hci = TRUE;
@ -204,6 +214,49 @@ static int headset_send(struct headset *hs, char *format, ...)
return 0;
}
static int buffer_event(int index)
{
int i;
for (i = 0; i < EV_BUF_SIZE; i++) {
if (ag.ev_buf[i].index == 0) {
ag.ev_buf[i].index = index + 1;
ag.ev_buf[i].val = ag.indicators[index].val;
return 0;
}
}
error("No space in event buffer");
return -ENOSPC;
}
static int flush_events(void)
{
int i;
struct headset *hs;
if (!active_telephony_device)
return -ENODEV;
hs = active_telephony_device->headset;
for (i = 0; i < EV_BUF_SIZE; i++) {
int ret;
if (ag.ev_buf[i].index == 0)
break;
ret = headset_send(hs, "\r\n+CIEV:%d,%d\r\n",
ag.ev_buf[i].index, ag.ev_buf[i].val);
if (ret < 0)
return ret;
ag.ev_buf[i].index = 0;
}
return 0;
}
static int supported_features(struct audio_device *device, const char *buf)
{
struct headset *hs = device->headset;
@ -622,6 +675,23 @@ static int response_and_hold(struct audio_device *device, const char *buf)
return headset_send(hs, "\r\nOK\n\r", ag.rh);
}
static int last_dialed_number(struct audio_device *device, const char *buf)
{
struct headset *hs = device->headset;
ag.ev_buf_active = TRUE;
if (telephony_last_dialed_number() < 0) {
headset_send(hs, "\r\nERROR\r\n");
return 0;
}
flush_events();
ag.ev_buf_active = FALSE;
return headset_send(hs, "\r\nOK\n\r", ag.rh);
}
static int signal_gain_setting(struct audio_device *device, const char *buf)
{
struct headset *hs = device->headset;
@ -678,6 +748,7 @@ static struct event event_callbacks[] = {
{ "AT+CKPD", answer_call },
{ "AT+CLIP", cli_notification },
{ "AT+BTRH", response_and_hold },
{ "AT+BLDN", last_dialed_number },
{ 0 }
};
@ -2013,6 +2084,9 @@ int telephony_event_ind(int index)
return -EINVAL;
}
if (ag.ev_buf_active)
return buffer_event(index);
return headset_send(hs, "\r\n+CIEV:%d,%d\r\n", index + 1,
ag.indicators[index].val);
}

View File

@ -43,7 +43,7 @@ static gboolean events_enabled = FALSE;
*/
static int response_and_hold = -1;
static struct indicator indicators[] =
static struct indicator dummy_indicators[] =
{
{ "battchg", "0-5", 5 },
{ "signal", "0-5", 5 },
@ -71,11 +71,19 @@ int telephony_response_and_hold_req(int rh)
return 0;
}
int telephony_last_dialed_number(void)
{
/* Notify outgoing call set-up successfully initiated */
telephony_update_indicator(dummy_indicators, "callsetup", 2);
return 0;
}
int telephony_init(void)
{
uint32_t features = 0;
telephony_ready(features, indicators, response_and_hold);
telephony_ready(features, dummy_indicators, response_and_hold);
return 0;
}

View File

@ -23,6 +23,8 @@
*/
#include <stdint.h>
#include <errno.h>
#include <glib.h>
#define AG_FEATURE_THREE_WAY_CALLING 0x0001
#define AG_FEATURE_EC_ANDOR_NR 0x0002
@ -48,7 +50,32 @@ int telephony_response_and_hold_req(int rh);
int telephony_response_and_hold_ind(int rh);
int telephony_last_dialed_number(void);
int telephony_ready(uint32_t features, struct indicator *indicators, int rh);
/* Helper function for quick indicator updates */
static inline int telephony_update_indicator(struct indicator *indicators,
const char *desc,
int new_val)
{
int i;
struct indicator *ind = NULL;
for (i = 0; indicators[i].desc != NULL; i++) {
if (g_str_equal(indicators[i].desc, desc)) {
ind = &indicators[i];
break;
}
}
if (!ind)
return -ENOENT;
ind->val = new_val;
return telephony_event_ind(i);
}
int telephony_init(void);
void telephony_exit(void);