转换CRSM返回值到ril上层可处理字串的方法

来源:互联网 发布:php导出数据到excel 编辑:程序博客网 时间:2024/06/07 20:23
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>

struct ts_51011_921_resp {
    uint8_t   rfu_1[2];
    uint16_t  file_size; /* be16 */
    uint16_t  file_id;   /* be16 */
    uint8_t   file_type;
    uint8_t   rfu_2;
    uint8_t   file_acc[3];
    uint8_t   file_status;
    uint8_t   data_size;
    uint8_t   file_structure;
    uint8_t   record_size;
} __attribute__((packed));

#define TLV_DATA(tlv, pos) (((unsigned)char2nib(tlv.data[(pos) * 2 + 0]) << 4) | \
                            ((unsigned)char2nib(tlv.data[(pos) * 2 + 1]) << 0))

#define NUM_ELEMS(x) (sizeof(x) / sizeof(x[0]))

struct tlv {
    unsigned    tag;
    const char *data;
    const char *end;
};
char char2nib(char c)
{
    if (c >= 0x30 && c <= 0x39)
        return c - 0x30;

    if (c >= 0x41 && c <= 0x46)
        return c - 0x41 + 0xA;

    if (c >= 0x61 && c <= 0x66)
        return c - 0x61 + 0xA;

    return 0;
}

int parseTlv(/*in*/ const char *stream,
             /*in*/ const char *end,
             /*out*/ struct tlv *tlv)
{
#define TLV_STREAM_GET(stream, end, p)  \
    do {                                \
        if (stream + 1 >= end)          \
            goto underflow;             \
        p = ((unsigned)char2nib(stream[0]) << 4)  \
          | ((unsigned)char2nib(stream[1]) << 0); \
        stream += 2;                    \
    } while (0)

    size_t size;

    TLV_STREAM_GET(stream, end, tlv->tag);
    TLV_STREAM_GET(stream, end, size);
    if (stream + size * 2 > end)
        goto underflow;
    tlv->data = &stream[0];
    tlv->end  = &stream[size * 2];
    return 0;

underflow:
    return -1;
#undef TLV_STREAM_GET
}

//telink sim i/o
static 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(-1, "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(-2, "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(-1, "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(-1, "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(-1, "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(-1, "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
     printf("%s() FCP to TS 510 11: Specification violation: %s.", __func__, what);
     goto finally;
 }

int binaryToString(/*in*/ const unsigned char *binary,
                   /*in*/ size_t len,
                   /*out*/ char *string)
{
    int pos;
    const unsigned char *it;
    const unsigned char *end = &binary[len];
    static const char nibbles[] =
        {'0', '1', '2', '3', '4', '5', '6', '7',
         '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

    if (end < binary)
        return -1;

    for (pos = 0, it = binary; it != end; ++it, pos += 2) {
        string[pos + 0] = nibbles[*it >> 4];
        string[pos + 1] = nibbles[*it & 0x0f];
    }
    string[pos] = 0;
    return 0;
}

int main()
{
   char * p = "此处加入CRSM执行192返回的字串";
如:“621F82054221001CFA83024F39A5038001718A01058B036F060380021B58880108”
   int n = strlen(p);
    int err;
    /* size_t pos; */
    struct ts_51011_921_resp resp;
    void *cvt_buf = NULL;

    fcp_to_ts_51011(p, n, &resp);

    cvt_buf = malloc(sizeof(resp) * 2 + 1);
    if (!cvt_buf) {
        err = -1;
        printf("malloc error!!!");
        goto error;
    }

    err = binaryToString((unsigned char*)(&resp),
                   sizeof(resp), cvt_buf);
    if (err < 0)
    {
        printf(" binaryToString error!!!");
        goto error;
    }

    printf("\ncvt_buff = %s\n", (char *)cvt_buf);

error:

    return 0;
}


阅读全文
0 0
原创粉丝点击