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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
/* 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
/* 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; }
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; }
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; }