예제 #1
0
static char *bta_hf_client_parse_cind_list(char *buffer)
{
    int offset;
    char *name = osi_malloc(129);
    UINT32 min, max;
    UINT32 index = 0;
    int res;

    if (name == NULL) {
        APPL_TRACE_ERROR("No mem %s", __FUNCTION__);
        return NULL;
    }

    while ((res = sscanf(buffer, "(\"%128[^\"]\",(%u%*[-,]%u))%n", name, &min, &max, &offset)) > 2) {
        bta_hf_client_handle_cind_list_item(name, min, max, index);
        buffer += offset;
        index++;

        if (*buffer != ',') {
            break;
        }

        buffer++;
    }

    osi_free(name);

    if (res > 2) {
        AT_CHECK_RN(buffer);
        return buffer;
    }

    return NULL;
}
예제 #2
0
static char *bta_hf_client_parse_cops(char *buffer)
{
    UINT8 mode;
    /* spec forces 16 chars max, plus \0 here */
    char opstr[17];
    int res;
    int offset;

    AT_CHECK_EVENT(buffer, "+COPS:");

    /* TODO: Not sure if operator string actually can contain escaped " char inside */
    res = sscanf(buffer, "%hhi,0,\"%16[^\"]\"%n", &mode, opstr, &offset);
    if (res < 2) {
        return NULL;
    }

    buffer += offset;

    AT_SKIP_REST(buffer);

    AT_CHECK_RN(buffer);

    bta_hf_client_handle_cops(opstr, mode);
    return buffer;
}
예제 #3
0
static char *bta_hf_client_parse_cind_values(char *buffer)
{
    /* value and its position */
    UINT16 index = 0;
    UINT32 value = 0;

    int offset;
    int res;

    while ((res = sscanf(buffer, "%u%n", &value, &offset)) > 0) {
        /* decides if its valid index and value, if yes stores it */
        bta_hf_client_handle_cind_value(index, value);

        buffer += offset;

        /* check if more values are present */
        if (*buffer != ',') {
            break;
        }

        index++;
        buffer++;
    }

    if (res > 0) {
        AT_CHECK_RN(buffer);
        return buffer;
    }

    return NULL;
}
예제 #4
0
static char *bta_hf_client_parse_ciev(char *buffer)
{
    UINT32 index, value;
    int res;
    int offset = 0;

    AT_CHECK_EVENT(buffer, "+CIEV:");

    res = sscanf(buffer, "%lu,%lu%n", &index, &value, &offset);
    if(res < 2)
    {
        return NULL;
    }

    if (offset == 0)
    {
        APPL_TRACE_ERROR1("bta_hf_client_parse_ciev : Format Error %s", buffer);
        return NULL;
    }
    buffer += offset;

    AT_CHECK_RN(buffer);

    bta_hf_client_handle_ciev(index, value);
    return buffer;
}
예제 #5
0
static char *bta_hf_client_parse_cind_list(char *buffer)
{
    int offset;
    char name[129];
    UINT32 min, max;
    UINT32 index = 0;
    int res;

    while ((res = sscanf(buffer, "(\"%128[^\"]\",(%u%*[-,]%u))%n", name, &min, &max, &offset)) > 2)
    {
        bta_hf_client_handle_cind_list_item(name, min, max, index);
        buffer += offset;
        index++;

        if (*buffer != ',')
        {
            break;
        }

        buffer++;
    }

    if (res > 2)
    {
        AT_CHECK_RN(buffer);
        return buffer;
    }

    return NULL;
}
예제 #6
0
static char *bta_hf_client_parse_binp(char *buffer)
{
    /* HFP only supports phone number as BINP data */
    /* phone number is 32 chars plus one for \0*/
    char numstr[33];
    int res;
    int offset;

    AT_CHECK_EVENT(buffer, "+BINP:");

    res = sscanf(buffer, "\"%32[^\"]\"\r\n%n", numstr, &offset);
    if (res < 1) {
        return NULL;
    }

    buffer += offset;

    /* some phones might sent type as well, just skip it */
    AT_SKIP_REST(buffer);

    AT_CHECK_RN(buffer);

    bta_hf_client_handle_binp(numstr);
    return buffer;
}
예제 #7
0
static char *bta_hf_client_parse_binp(char *buffer)
{
    /* HFP only supports phone number as BINP data */
    /* phone number is 32 chars plus one for \0*/
    char numstr[33];
    int res;
    int offset = 0;

    AT_CHECK_EVENT(buffer, "+BINP:");

    res = sscanf(buffer, "\"%32[^\"]\"\r\n%n", numstr, &offset);
    if(res < 1)
    {
        return NULL;
    }

    /* Abort in case offset not set because of format error */
    if (offset == 0)
    {
        APPL_TRACE_ERROR1("bta_hf_client_parse_binp: Format Error %s", buffer);
        return NULL;
    }
    buffer += offset;

    /* some phones might sent type as well, just skip it */
    AT_SKIP_REST(buffer);

    AT_CHECK_RN(buffer);

    bta_hf_client_handle_binp(numstr);
    return buffer;
}
예제 #8
0
static char *bta_hf_client_parse_cops(char *buffer)
{
    UINT8 mode;
    /* spec forces 16 chars max, plus \0 here */
    char opstr[17];
    int res;
    int offset = 0;

    AT_CHECK_EVENT(buffer, "+COPS:");

    /* TODO: Not sure if operator string actually can contain escaped " char inside */
    res = sscanf(buffer, "%hhi,0,\"%16[^\"]\"%n", &mode, opstr, &offset);
    if(res < 2)
    {
        return NULL;
    }
    /* Abort in case offset not set because of format error */
    if (offset == 0)
    {
        APPL_TRACE_ERROR1("bta_hf_client_parse_cops: Format Error %s", buffer);
        return NULL;
    }
    buffer += offset;

    AT_SKIP_REST(buffer);

    AT_CHECK_RN(buffer);

    bta_hf_client_handle_cops(opstr, mode);
    return buffer;
}
예제 #9
0
static char *bta_hf_client_parse_clip(char *buffer)
{
    /* spec forces 32 chars, plus \0 here */
    char number[33];
    UINT32 type = 0;
    int res;
    int offset = 0;

    AT_CHECK_EVENT(buffer, "+CLIP:");

    /* there might be something more after %lu but HFP doesn't care */
    res = sscanf(buffer, "\"%32[^\"]\",%lu%n", number, &type, &offset);
    if(res < 2)
    {
        return NULL;
    }

    if (offset == 0)
    {
        APPL_TRACE_ERROR1("bta_hf_client_parse_clip: Format Error %s", buffer);
        return NULL;
    }
    buffer += offset;

    AT_SKIP_REST(buffer);

    AT_CHECK_RN(buffer);

    bta_hf_client_handle_clip(number, type);
    return buffer;
}
예제 #10
0
/* in HFP context there is no difference between ccwa and clip */
static char *bta_hf_client_parse_ccwa(char *buffer)
{
    /* ac to spec 32 chars max, plus \0 here */
    char number[33];
    UINT32 type = 0;
    int res ;
    int offset;

    AT_CHECK_EVENT(buffer, "+CCWA:");

    /* there might be something more after %lu but HFP doesn't care */
    res = sscanf(buffer, "\"%32[^\"]\",%u%n", number, &type, &offset);
    if (res < 2) {
        return NULL;
    }

    buffer += offset;

    AT_SKIP_REST(buffer);

    AT_CHECK_RN(buffer);

    bta_hf_client_handle_ccwa(number, type);
    return buffer;
}
예제 #11
0
static char *bta_hf_client_parse_cnum(char *buffer)
{
    char numstr[33];     /* spec forces 32 chars, plus one for \0*/
    UINT16 type;
    UINT16 service = 0; /* 0 in case this optional parameter is not being sent */
    int res;
    int offset = 0;

    AT_CHECK_EVENT(buffer, "+CNUM:");

    res = sscanf(buffer, ",\"%32[^\"]\",%hu,,%hu%n", numstr, &type, &service, &offset);
    if(res < 0)
    {
        return NULL;
    }

    if (res == 0)
    {
        res = sscanf(buffer, ",\"\",%hu,,%hu%n", &type, &service, &offset);
        if (res < 0)
        {
            return NULL;
        }

        /* numstr is not matched in second attempt, correct this */
        res++;
        numstr[0] = '\0';
    }

    if (res < 3)
    {
        return NULL;
    }

    /* Abort in case offset not set because of format error */
    if (offset == 0)
    {
        APPL_TRACE_ERROR1("bta_hf_client_parse_cnum: Format Error %s", buffer);
        return NULL;
    }

    buffer += offset;

    AT_CHECK_RN(buffer);

    /* service is optional */
    if(res == 2)
    {
        bta_hf_client_handle_cnum(numstr, type, service);
        return buffer;
    }

    if (service != 4 && service != 5)
    {
        return NULL;
    }

    bta_hf_client_handle_cnum(numstr, type, service);
    return buffer;
}
예제 #12
0
static char *bta_hf_client_parse_ring(char *buffer)
{
    AT_CHECK_EVENT(buffer, "RING");
    AT_CHECK_RN(buffer);

    bta_hf_client_handle_ring();

    return buffer;
}
예제 #13
0
static char *bta_hf_client_parse_ok(char *buffer)
{
    AT_CHECK_EVENT(buffer, "OK");
    AT_CHECK_RN(buffer);

    bta_hf_client_handle_ok();

    return buffer;
}
예제 #14
0
static char *bta_hf_client_parse_blacklisted(char *buffer)
{
    AT_CHECK_EVENT(buffer, "BLACKLISTED");
    AT_CHECK_RN(buffer);

    bta_hf_client_handle_error(BTA_HF_CLIENT_AT_RESULT_BLACKLISTED, 0);

    return buffer;
}
예제 #15
0
static char *bta_hf_client_parse_no_answer(char *buffer)
{
    AT_CHECK_EVENT(buffer, "NO ANSWER");
    AT_CHECK_RN(buffer);

    bta_hf_client_handle_error(BTA_HF_CLIENT_AT_RESULT_NO_ANSWER, 0);

    return buffer;
}
예제 #16
0
static char *bta_hf_client_parse_delayed(char *buffer)
{
    AT_CHECK_EVENT(buffer, "DELAYED");
    AT_CHECK_RN(buffer);

    bta_hf_client_handle_error(BTA_HF_CLIENT_AT_RESULT_DELAY, 0);

    return buffer;
}
예제 #17
0
static char *bta_hf_client_parse_clcc(char *buffer)
{
    UINT16 idx, dir, status, mode, mpty;
    char numstr[33];     /* spec forces 32 chars, plus one for \0*/
    UINT16 type;
    int res;
    int offset;
    AT_CHECK_EVENT(buffer, "+CLCC:");

    res = sscanf(buffer, "%hu,%hu,%hu,%hu,%hu%n",
                 &idx, &dir, &status, &mode, &mpty, &offset);
    if (res < 5) {
        return NULL;
    }

    buffer += offset;

    /* check optional part */
    if (*buffer == ',') {
        int res2;

        res2 = sscanf(buffer, ",\"%32[^\"]\",%hu%n", numstr, &type, &offset);
        if (res2 < 0) {
            return NULL;
        }

        if (res2 == 0) {
            res2 = sscanf(buffer, ",\"\",%hu%n", &type, &offset);
            if (res < 0) {
                return NULL;
            }

            /* numstr is not matched in second attempt, correct this */
            res2++;
            numstr[0] = '\0';
        }

        if (res2 < 2) {
            return NULL;
        }

        res += res2;
        buffer += offset;
    }

    AT_CHECK_RN(buffer);

    if (res > 6) {
        /* we also have last two optional parameters */
        bta_hf_client_handle_clcc(idx, dir, status, mode, mpty, numstr, type);
    } else {
        /* we didn't get the last two parameters */
        bta_hf_client_handle_clcc(idx, dir, status, mode, mpty, NULL, 0);
    }

    return buffer;
}
예제 #18
0
static char *bta_hf_client_parse_error(char *buffer)
{
    AT_CHECK_EVENT(buffer, "ERROR");
    AT_CHECK_RN(buffer);

    bta_hf_client_handle_error(BTA_HF_CLIENT_AT_RESULT_ERROR, 0);

    return buffer;
}
예제 #19
0
static char *bta_hf_client_parse_chld(char *buffer)
{
    AT_CHECK_EVENT(buffer, "+CHLD:");

    if (*buffer != '(') {
        return NULL;
    }

    buffer++;

    while (*buffer != '\0') {
        if (strncmp("0", buffer, 1) == 0) {
            bta_hf_client_handle_chld(BTA_HF_CLIENT_CHLD_REL);
            buffer++;
        } else if (strncmp("1x", buffer, 2) == 0) {
            bta_hf_client_handle_chld(BTA_HF_CLIENT_CHLD_REL_X);
            buffer += 2;
        } else if (strncmp("1", buffer, 1) == 0) {
            bta_hf_client_handle_chld(BTA_HF_CLIENT_CHLD_REL_ACC);
            buffer++;
        } else if (strncmp("2x", buffer, 2) == 0) {
            bta_hf_client_handle_chld(BTA_HF_CLIENT_CHLD_PRIV_X);
            buffer += 2;
        } else if (strncmp("2", buffer, 1) == 0) {
            bta_hf_client_handle_chld(BTA_HF_CLIENT_CHLD_HOLD_ACC);
            buffer++;
        } else if (strncmp("3", buffer, 1) == 0) {
            bta_hf_client_handle_chld(BTA_HF_CLIENT_CHLD_MERGE);
            buffer++;
        } else if (strncmp("4", buffer, 1) == 0) {
            bta_hf_client_handle_chld(BTA_HF_CLIENT_CHLD_MERGE_DETACH);
            buffer++;
        } else {
            return NULL;
        }

        if (*buffer == ',') {
            buffer++;
            continue;
        }

        if (*buffer == ')') {
            buffer++;
            break;
        }

        return NULL;
    }

    AT_CHECK_RN(buffer);

    return buffer;
}
예제 #20
0
/* generic uint32 parser */
static char *bta_hf_client_parse_uint32(char *buffer, void (*handler_callback)(UINT32))
{
    UINT32 value;
    int res;
    int offset;

    res = sscanf(buffer, "%u%n", &value, &offset);
    if (res < 1) {
        return NULL;
    }

    buffer += offset;

    AT_CHECK_RN(buffer);

    handler_callback(value);
    return buffer;
}
예제 #21
0
static char *bta_hf_client_parse_btrh(char *buffer)
{
    UINT16 code = 0;
    int res;
    int offset;

    AT_CHECK_EVENT(buffer, "+BTRH:");

    res = sscanf(buffer, "%hu%n", &code, &offset);
    if (res < 1) {
        return NULL;
    }

    buffer += offset;

    AT_CHECK_RN(buffer);

    bta_hf_client_handle_btrh(code);
    return buffer;
}
예제 #22
0
static char *bta_hf_client_parse_ciev(char *buffer)
{
    UINT32 index, value;
    int res;
    int offset;

    AT_CHECK_EVENT(buffer, "+CIEV:");

    res = sscanf(buffer, "%u,%u%n", &index, &value, &offset);
    if (res < 2) {
        return NULL;
    }

    buffer += offset;

    AT_CHECK_RN(buffer);

    bta_hf_client_handle_ciev(index, value);
    return buffer;
}