static int simIOGetLogicalChannel(void) { ATResponse *atresponse = NULL; static int g_lc = 0; int err; if (g_lc == 0) { struct tlv tlvApp, tlvAppId; char *line; char *resp; err = at_send_command_singleline("AT+CUAD", "+CUAD:", &atresponse); if (err != AT_NOERROR) return g_lc; line = atresponse->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto finally; err = at_tok_nextstr(&line, &resp); if (err < 0) goto finally; err = parseTlv(resp, &resp[strlen(resp)], &tlvApp); if (err < 0) goto finally; if (tlvApp.tag != 0x61) { /* Application */ err = -EINVAL; goto finally; } err = parseTlv(tlvApp.data, tlvApp.end, &tlvAppId); if (err < 0) goto finally; if (tlvAppId.tag != 0x4F) { /* Application ID */ err = -EINVAL; goto finally; } at_response_free(atresponse); err = at_send_command_singleline("AT+CCHO=\"%.*s\"", "+CCHO:", &atresponse, tlvAppId.end - tlvAppId.data, tlvAppId.data); if (err != AT_NOERROR) return g_lc; line = atresponse->p_intermediates->line; err = at_tok_start(&line); if (err < 0) goto finally; err = at_tok_nextint(&line, &g_lc); if (err < 0) goto finally; } finally: at_response_free(atresponse); return g_lc; }
int fcp_to_ts_51011(/*in*/ const char *stream, /*in*/ size_t len, /*out*/ struct ts_51011_921_resp *out) { const char *end = &stream[len]; struct tlv fcp; int ret = parseTlv(stream, end, &fcp); const char *what = NULL; #define FCP_CVT_THROW(_ret, _what) \ do { \ ret = _ret; \ what = _what; \ goto except; \ } while (0) if (ret < 0) FCP_CVT_THROW(ret, "ETSI TS 102 221, 11.1.1.3: FCP template TLV structure"); if (fcp.tag != 0x62) FCP_CVT_THROW(-EINVAL, "ETSI TS 102 221, 11.1.1.3: FCP template tag"); /* * NOTE: Following fields do not exist in FCP template: * - file_acc * - file_status */ memset(out, 0, sizeof(*out)); while (fcp.data < fcp.end) { unsigned char fdbyte; size_t property_size; struct tlv tlv; ret = parseTlv(fcp.data, end, &tlv); if (ret < 0) FCP_CVT_THROW(ret, "ETSI TS 102 221, 11.1.1.3: FCP property TLV structure"); property_size = (tlv.end - tlv.data) / 2; switch (tlv.tag) { case 0x80: /* File size, ETSI TS 102 221, 11.1.1.4.1 */ /* File size > 0xFFFF is not supported by ts_51011 */ if (property_size != 2) FCP_CVT_THROW(-ENOTSUP, "3GPP TS 51 011, 9.2.1: Unsupported file size"); /* be16 on both sides */ ((char*)&out->file_size)[0] = TLV_DATA(tlv, 0); ((char*)&out->file_size)[1] = TLV_DATA(tlv, 1); break; case 0x83: /* File identifier, ETSI TS 102 221, 11.1.1.4.4 */ /* Sanity check */ if (property_size != 2) FCP_CVT_THROW(-EINVAL, "ETSI TS 102 221, 11.1.1.4.4: Invalid file identifier"); /* be16 on both sides */ ((char*)&out->file_id)[0] = TLV_DATA(tlv, 0); ((char*)&out->file_id)[1] = TLV_DATA(tlv, 1); break; case 0x82: /* File descriptior, ETSI TS 102 221, 11.1.1.4.3 */ /* Sanity check */ if (property_size < 2) FCP_CVT_THROW(-EINVAL, "ETSI TS 102 221, 11.1.1.4.3: Invalid file descriptor"); fdbyte = TLV_DATA(tlv, 0); /* ETSI TS 102 221, Table 11.5 for FCP fields */ /* 3GPP TS 51 011, 9.2.1 and 9.3 for 'out' fields */ if ((fdbyte & 0xBF) == 0x38) { out->file_type = 2; /* DF of ADF */ } else if ((fdbyte & 0xB0) == 0x00) { out->file_type = 4; /* EF */ out->file_status = 1; /* Not invalidated */ ++out->data_size; /* file_structure field is valid */ if ((fdbyte & 0x07) == 0x01) { out->file_structure = 0; /* Transparent */ } else { if (property_size < 5) FCP_CVT_THROW(-EINVAL, "ETSI TS 102 221, 11.1.1.4.3: Invalid non-transparent file descriptor"); ++out->data_size; /* record_size field is valid */ out->record_size = TLV_DATA(tlv, 3); if ((fdbyte & 0x07) == 0x06) { out->file_structure = 3; /* Cyclic */ } else if ((fdbyte & 0x07) == 0x02) { out->file_structure = 1; /* Linear fixed */ } else { FCP_CVT_THROW(-EINVAL, "ETSI TS 102 221, 11.1.1.4.3: Invalid file structure"); } } } else { out->file_type = 0; /* RFU */ } break; } fcp.data = tlv.end; } finally: return ret; except: #undef FCP_CVT_THROW ALOGE("FCP to TS 510 11: Specification violation: %s.", what); goto finally; }