From cbbf4601211669ededac8d41d6adaec277af3e3b Mon Sep 17 00:00:00 2001 From: erin_yueh Date: Mon, 17 Dec 2007 09:31:02 +0000 Subject: gsmd: conference call support (Sean Chiang) git-svn-id: http://svn.openmoko.org/trunk/src/target/gsm@3657 99fdad57-331a-0410-800a-d7fa5415bdb3 --- src/gsmd/ext_response.c | 18 +++++++++----- src/gsmd/gsmd.c | 2 ++ src/gsmd/unsolicited.c | 64 +++++++++++++++++++++++++++++++++---------------- src/gsmd/usock.c | 56 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 114 insertions(+), 26 deletions(-) (limited to 'src/gsmd') diff --git a/src/gsmd/ext_response.c b/src/gsmd/ext_response.c index 37edf59..f2a94a7 100644 --- a/src/gsmd/ext_response.c +++ b/src/gsmd/ext_response.c @@ -109,16 +109,16 @@ struct gsm_extrsp *extrsp_parse(const void *ctx, const char *input) } break; case TOKEN_NUMERIC: - if (isdigit(*cur)) { - *cur_buf = *cur; - cur_buf++; - } - - if (*cur == ',' || *(cur+1) == '\0') { + if (*cur == ',') { /* end of number */ cur_token->u.numeric = atoi(buf); er->num_tokens++; state = IDLE; + } else if (isdigit(*cur)) { + *cur_buf = *cur; + cur_buf++; + } else { + /* ERORR */ } break; case TOKEN_STRING: @@ -170,6 +170,12 @@ struct gsm_extrsp *extrsp_parse(const void *ctx, const char *input) cur++; } + if (state == TOKEN_NUMERIC) { + /* end of number */ + cur_token->u.numeric = atoi(buf); + er->num_tokens++; + } + //extrsp_dump(er); return er; } diff --git a/src/gsmd/gsmd.c b/src/gsmd/gsmd.c index ce8ec7e..53b43a8 100644 --- a/src/gsmd/gsmd.c +++ b/src/gsmd/gsmd.c @@ -171,6 +171,8 @@ static int gsmd_initsettings2(struct gsmd *gsmd) rc |= gsmd_simplecmd(gsmd, "AT+CLIP=1"); /* use +COLP: to indicate COLP */ rc |= gsmd_simplecmd(gsmd, "AT+COLP=1"); + /* use +CCWA: to indicate waiting call */ + rc |= gsmd_simplecmd(gsmd, "AT+CCWA=1,1"); /* configure message format as PDU mode*/ /* FIXME: TEXT mode support!! */ rc |= gsmd_simplecmd(gsmd, "AT+CMGF=0"); diff --git a/src/gsmd/unsolicited.c b/src/gsmd/unsolicited.c index 6e96b35..8c99183 100644 --- a/src/gsmd/unsolicited.c +++ b/src/gsmd/unsolicited.c @@ -253,33 +253,57 @@ static int creg_parse(char *buf, int len, const char *param, static int ccwa_parse(char *buf, int len, const char *param, struct gsmd *gsmd) { - const char *token; - unsigned int type; + struct gsmd_evt_auxdata *aux; + struct gsm_extrsp *er; struct gsmd_ucmd *ucmd = usock_build_event(GSMD_MSG_EVENT, GSMD_EVT_CALL_WAIT, - sizeof(struct gsmd_addr)); - struct gsmd_addr *gaddr; - + sizeof(struct gsmd_evt_auxdata)); + if (!ucmd) return -ENOMEM; - gaddr = (struct gsmd_addr *) ucmd->buf; - memset(gaddr, 0, sizeof(*gaddr)); + aux = (struct gsmd_evt_auxdata *) ucmd->buf; + + er = extrsp_parse(gsmd_tallocs, param); - /* parse address (phone number) */ - token = strtok(buf, ","); - if (!token) - return -EINVAL; - strncpy(gaddr->number, token, GSMD_ADDR_MAXLEN); + if ( !er ) + return -ENOMEM; - /* parse type */ - token = strtok(NULL, ","); - if (!token) + if ( er->num_tokens == 5 && + er->tokens[0].type == GSMD_ECMD_RTT_STRING && + er->tokens[1].type == GSMD_ECMD_RTT_NUMERIC && + er->tokens[2].type == GSMD_ECMD_RTT_NUMERIC && + er->tokens[3].type == GSMD_ECMD_RTT_EMPTY && + er->tokens[4].type == GSMD_ECMD_RTT_NUMERIC ) { + /* + * ,,,[][,] + */ + + strcpy(aux->u.ccwa.addr.number, er->tokens[0].u.string); + aux->u.ccwa.addr.type = er->tokens[1].u.numeric; + aux->u.ccwa.classx = er->tokens[2].u.numeric; + aux->u.ccwa.alpha[0] = '\0'; + aux->u.ccwa.cli = er->tokens[4].u.numeric; + } + else if ( er->num_tokens == 5 && + er->tokens[0].type == GSMD_ECMD_RTT_STRING && + er->tokens[1].type == GSMD_ECMD_RTT_NUMERIC && + er->tokens[2].type == GSMD_ECMD_RTT_NUMERIC && + er->tokens[3].type == GSMD_ECMD_RTT_STRING && + er->tokens[4].type == GSMD_ECMD_RTT_NUMERIC ) { + /* + * ,,,[][,] + */ + + strcpy(aux->u.ccwa.addr.number, er->tokens[0].u.string); + aux->u.ccwa.addr.type = er->tokens[1].u.numeric; + aux->u.ccwa.classx = er->tokens[2].u.numeric; + strcpy(aux->u.ccwa.alpha, er->tokens[3].u.string); + aux->u.ccwa.cli = er->tokens[4].u.numeric; + } + else { + DEBUGP("Invalid Input : Parse error\n"); return -EINVAL; - type = atoi(token) & 0xff; - gaddr->type = type; - - /* FIXME: parse class */ - token = strtok(NULL, ","); + } return usock_evt_send(gsmd, ucmd, GSMD_EVT_CALL_WAIT); } diff --git a/src/gsmd/usock.c b/src/gsmd/usock.c index 0a4acd7..80f2e01 100644 --- a/src/gsmd/usock.c +++ b/src/gsmd/usock.c @@ -200,6 +200,23 @@ static int voicecall_get_stat_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) cmd->id, sizeof(gcs), &gcs); } +static int voicecall_ctrl_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) +{ + struct gsmd_user *gu = ctx; + int ret = 0; + + DEBUGP("resp: %s\n", resp); + + if ( !strncmp(resp, "+CME", 4) ) { + /* +CME ERROR: */ + DEBUGP("+CME error\n"); + ret = atoi(strpbrk(resp, "0123456789")); + } + + return gsmd_ucmd_submit(gu, GSMD_MSG_VOICECALL, GSMD_VOICECALL_CTRL, + cmd->id, sizeof(ret), &ret); +} + static int usock_ringing_cb(struct gsmd_atcmd *cmd, void *ctx, char *resp) { struct gsmd_user *gu = ctx; @@ -217,6 +234,7 @@ static int usock_rcv_voicecall(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, struct gsmd_atcmd *cmd = NULL; struct gsmd_addr *ga; struct gsmd_dtmf *gd; + struct gsmd_call_ctrl *gcc; int atcmd_len; switch (gph->msg_subtype) { @@ -274,6 +292,44 @@ static int usock_rcv_voicecall(struct gsmd_user *gu, struct gsmd_msg_hdr *gph, if (!cmd) return -ENOMEM; break; + case GSMD_VOICECALL_CTRL: + if (len < sizeof(*gph) + sizeof(*gcc)) + return -EINVAL; + + gcc = (struct gsmd_call_ctrl *) ((void *)gph + sizeof(*gph)); + + atcmd_len = 1 + strlen("AT+CHLD=") + 2; + cmd = atcmd_fill("AT+CHLD=", atcmd_len, &voicecall_ctrl_cb, + gu, gph->id, NULL); + if (!cmd) + return -ENOMEM; + + switch (gcc->proc) { + case GSMD_CALL_CTRL_R_HLDS: + case GSMD_CALL_CTRL_UDUB: + sprintf(cmd->buf, "AT+CHLD=%d", 0); + break; + case GSMD_CALL_CTRL_R_ACTS_A_HLD_WAIT: + sprintf(cmd->buf, "AT+CHLD=%d", 1); + break; + case GSMD_CALL_CTRL_R_ACT_X: + sprintf(cmd->buf, "AT+CHLD=%d%d", 1, gcc->idx); + break; + case GSMD_CALL_CTRL_H_ACTS_A_HLD_WAIT: + sprintf(cmd->buf, "AT+CHLD=%d", 2); + break; + case GSMD_CALL_CTRL_H_ACTS_EXCEPT_X: + sprintf(cmd->buf, "AT+CHLD=%d%d", 2, gcc->idx); + break; + case GSMD_CALL_CTRL_M_HELD: + sprintf(cmd->buf, "AT+CHLD=%d", 3); + break; + default: + return -EINVAL; + } + + break; + default: return -EINVAL; } -- cgit v1.2.3