<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/17553">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">osmo-sim-test: Optionally dump card files to host filesystem<br><br>Using the new '--output-dir' command line argument, the user can<br>instruct osmo-sim-test to dump the file content to a local directory.<br><br>osmo-sim-test will create one sub-directory per DF, and create a<br>text file for each EF.  The contents of the text files are a hexdump<br>of the contents.  Transparent EF are dumped as one line of hex,<br>while linear fixed EF are dumped as one record per line, i.e. the<br>number of lines corresponds to the number of records.<br><br>Change-Id: I35176f4a13c3537eaa8de550e231818a22b4c07c<br>---<br>M utils/osmo-sim-test.c<br>1 file changed, 97 insertions(+), 11 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/utils/osmo-sim-test.c b/utils/osmo-sim-test.c</span><br><span>index 4c704f6..a9ab0d0 100644</span><br><span>--- a/utils/osmo-sim-test.c</span><br><span>+++ b/utils/osmo-sim-test.c</span><br><span>@@ -1,5 +1,5 @@</span><br><span> /* libosmosim test application - currently simply dumps a USIM */</span><br><span style="color: hsl(0, 100%, 40%);">-/* (C) 2012 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+/* (C) 2012-2020 by Harald Welte <laforge@gnumonks.org></span><br><span>  * All Rights Reserved</span><br><span>  *</span><br><span>  * This program is free software; you can redistribute it and/or modify</span><br><span>@@ -25,6 +25,12 @@</span><br><span> #include <getopt.h></span><br><span> #include <arpa/inet.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <unistd.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sys/stat.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sys/types.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <fcntl.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <limits.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #include <osmocom/core/msgb.h></span><br><span> #include <osmocom/core/talloc.h></span><br><span> #include <osmocom/sim/sim.h></span><br><span>@@ -34,6 +40,7 @@</span><br><span> /* FIXME: this needs to be moved to card_fs_uicc.c */</span><br><span> </span><br><span> static uint8_t g_class = 0x00; /* UICC/USIM */</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *g_output_dir;</span><br><span> </span><br><span> /* 11.1.1 */</span><br><span> static struct msgb *_select_file(struct osim_chan_hdl *st, uint8_t p1, uint8_t p2,</span><br><span>@@ -317,13 +324,15 @@</span><br><span>   return NULL;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int dump_file(struct osim_chan_hdl *chan, uint16_t fid)</span><br><span style="color: hsl(120, 100%, 40%);">+static int dump_file(struct osim_chan_hdl *chan, const char *short_name, uint16_t fid)</span><br><span> {</span><br><span>     struct tlv_parsed tp;</span><br><span>        struct osim_fcp_fd_decoded ffdd;</span><br><span>     struct msgb *msg, *rmsg;</span><br><span>     int rc, i, offset;</span><br><span style="color: hsl(120, 100%, 40%);">+    FILE *f_data = NULL;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+      /* Select the file */</span><br><span>        msg = select_file(chan, fid);</span><br><span>        if (!msg) {</span><br><span>          fprintf(stderr, "Unable to select file\n");</span><br><span>@@ -363,23 +372,41 @@</span><br><span>                goto out;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (g_output_dir) {</span><br><span style="color: hsl(120, 100%, 40%);">+           f_data = fopen(short_name, "w");</span><br><span style="color: hsl(120, 100%, 40%);">+            if (!f_data) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        fprintf(stderr, "Couldn't create '%s': %s\n", short_name, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                     goto out;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  printf("EF type: %u\n", ffdd.ef_type);</span><br><span> </span><br><span>         switch (ffdd.ef_type) {</span><br><span>      case EF_TYPE_RECORD_FIXED:</span><br><span>           for (i = 0; i < ffdd.num_rec; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       const char *hex;</span><br><span>                     rmsg = read_record_nr(chan, i+1, ffdd.rec_len);</span><br><span style="color: hsl(0, 100%, 40%);">-                 if (!rmsg)</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (!rmsg) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (f_data)</span><br><span style="color: hsl(120, 100%, 40%);">+                                   fclose(f_data);</span><br><span>                              return -EIO;</span><br><span style="color: hsl(120, 100%, 40%);">+                  }</span><br><span>                    printf("SW: %s\n", osim_print_sw(chan->card, msgb_apdu_sw(msg)));</span><br><span style="color: hsl(0, 100%, 40%);">-                  printf("Rec %03u: %s\n", i+1,</span><br><span style="color: hsl(0, 100%, 40%);">-                         osmo_hexdump(msgb_apdu_de(rmsg), msgb_apdu_le(rmsg)));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                      hex = osmo_hexdump_nospc(msgb_apdu_de(rmsg), msgb_apdu_le(rmsg));</span><br><span style="color: hsl(120, 100%, 40%);">+                     printf("Rec %03u: %s\n", i+1, hex);</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (f_data)</span><br><span style="color: hsl(120, 100%, 40%);">+                           fprintf(f_data, "%s\n", hex);</span><br><span>              }</span><br><span>            break;</span><br><span>       case EF_TYPE_TRANSP:</span><br><span>                 if (g_class != 0xA0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                  if (!TLVP_PRESENT(&tp, UICC_FCP_T_FILE_SIZE))</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (!TLVP_PRESENT(&tp, UICC_FCP_T_FILE_SIZE)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           if (f_data)</span><br><span style="color: hsl(120, 100%, 40%);">+                                   fclose(f_data);</span><br><span>                              goto out;</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span>                    i = ntohs(*(uint16_t *)TLVP_VAL(&tp, UICC_FCP_T_FILE_SIZE));</span><br><span>                     printf("File size: %d bytes\n", i);</span><br><span>                } else {</span><br><span>@@ -389,12 +416,18 @@</span><br><span>             for (offset = 0; offset < i-1; ) {</span><br><span>                        uint16_t remain_len = i - offset;</span><br><span>                    uint16_t read_len = OSMO_MIN(remain_len, 256);</span><br><span style="color: hsl(120, 100%, 40%);">+                        const char *hex;</span><br><span>                     rmsg = read_binary(chan, offset, read_len);</span><br><span style="color: hsl(0, 100%, 40%);">-                     if (!rmsg)</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (!rmsg) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (f_data)</span><br><span style="color: hsl(120, 100%, 40%);">+                                   fclose(f_data);</span><br><span>                              return -EIO;</span><br><span style="color: hsl(120, 100%, 40%);">+                  }</span><br><span>                    offset += read_len;</span><br><span style="color: hsl(0, 100%, 40%);">-                     printf("Content: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                               osmo_hexdump(msgb_apdu_de(rmsg), msgb_apdu_le(rmsg)));</span><br><span style="color: hsl(120, 100%, 40%);">+                        hex = osmo_hexdump_nospc(msgb_apdu_de(rmsg), msgb_apdu_le(rmsg));</span><br><span style="color: hsl(120, 100%, 40%);">+                     printf("Content: %s\n", hex);</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (f_data)</span><br><span style="color: hsl(120, 100%, 40%);">+                           fprintf(f_data, "%s", hex);</span><br><span>                }</span><br><span>            break;</span><br><span>       default:</span><br><span>@@ -402,8 +435,11 @@</span><br><span>      }</span><br><span> </span><br><span> out:</span><br><span style="color: hsl(120, 100%, 40%);">+ if (f_data)</span><br><span style="color: hsl(120, 100%, 40%);">+           fclose(f_data);</span><br><span>      msgb_free(msg);</span><br><span>      return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> }</span><br><span> </span><br><span> static void print_help(void)</span><br><span>@@ -411,6 +447,7 @@</span><br><span>     printf( "osmo-sim-test Usage:\n"</span><br><span>           " -h  --help               This message\n"</span><br><span>                 " -n  --reader-num NR      Open reader number NR\n"</span><br><span style="color: hsl(120, 100%, 40%);">+         " -o  --output-dir DIR     To-be-created output directory for filesystem dump\n"</span><br><span>         );</span><br><span> }</span><br><span> </span><br><span>@@ -423,10 +460,11 @@</span><br><span>            const struct option long_options[] = {</span><br><span>                       { "help", 0, 0, 'h' },</span><br><span>                     { "reader-num", 1, 0, 'n' },</span><br><span style="color: hsl(120, 100%, 40%);">+                        { "output-dir", 1, 0, 'o' },</span><br><span>                       {0,0,0,0}</span><br><span>            };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-          c = getopt_long(argc, argv, "hn:",</span><br><span style="color: hsl(120, 100%, 40%);">+          c = getopt_long(argc, argv, "hn:o:",</span><br><span>                               long_options, &option_index);</span><br><span>            if (c == -1)</span><br><span>                         break;</span><br><span>@@ -439,6 +477,9 @@</span><br><span>                 case 'n':</span><br><span>                    readernum = atoi(optarg);</span><br><span>                    break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case 'o':</span><br><span style="color: hsl(120, 100%, 40%);">+                     g_output_dir = optarg;</span><br><span style="color: hsl(120, 100%, 40%);">+                        break;</span><br><span>               default:</span><br><span>                     exit(2);</span><br><span>                     break;</span><br><span>@@ -452,6 +493,22 @@</span><br><span> }</span><br><span> </span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void mkdir_and_chdir(const char *name, mode_t mode)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       rc = mkdir(name, mode);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              fprintf(stderr, "Cannot create '%s': %s\n", name, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+         exit(24);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = chdir(name);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              fprintf(stderr, "Cannot change to just-created '%s': %s\n", name, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+         exit(24);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void iterate_fs(struct osim_chan_hdl *chan)</span><br><span> {</span><br><span>  const struct osim_file_desc *prev_cwd;</span><br><span>@@ -460,6 +517,8 @@</span><br><span>         /* iterate over all files in current working directory */</span><br><span>    llist_for_each_entry(ofd, &chan->cwd->child_list, list) {</span><br><span>          struct msgb *m;</span><br><span style="color: hsl(120, 100%, 40%);">+               char prev_dir[PATH_MAX];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>           printf("\n\n================ %s (%s) ==================\n",</span><br><span>                        ofd->short_name, ofd->long_name);</span><br><span> </span><br><span>@@ -477,12 +536,22 @@</span><br><span>                  /* the select above has just changed into this directory */</span><br><span>                  prev_cwd = chan->cwd;</span><br><span>                     chan->cwd = ofd;</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (g_output_dir) {</span><br><span style="color: hsl(120, 100%, 40%);">+                           if (!getcwd(prev_dir, sizeof(prev_dir))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                    fprintf(stderr, "Cannot determine cwd: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                                     exit(23);</span><br><span style="color: hsl(120, 100%, 40%);">+                                     continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                             }</span><br><span style="color: hsl(120, 100%, 40%);">+                             mkdir_and_chdir(ofd->short_name, 0750);</span><br><span style="color: hsl(120, 100%, 40%);">+                    }</span><br><span>                    iterate_fs(chan);</span><br><span>                    /* "pop" the directory from the stack */</span><br><span>                   chan->cwd = prev_cwd;</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (g_output_dir)</span><br><span style="color: hsl(120, 100%, 40%);">+                             OSMO_ASSERT(chdir("..") == 0);</span><br><span>                     break;</span><br><span>               default:</span><br><span style="color: hsl(0, 100%, 40%);">-                        dump_file(chan, ofd->fid);</span><br><span style="color: hsl(120, 100%, 40%);">+                 dump_file(chan, ofd->short_name, ofd->fid);</span><br><span>                    break;</span><br><span>               }</span><br><span>    }</span><br><span>@@ -498,6 +567,22 @@</span><br><span> </span><br><span>         handle_options(argc, argv);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       if (g_output_dir) {</span><br><span style="color: hsl(120, 100%, 40%);">+           int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+               rc = mkdir(g_output_dir, 0750);</span><br><span style="color: hsl(120, 100%, 40%);">+               if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      fprintf(stderr, "Cannot create directory '%s': %s\n", g_output_dir,</span><br><span style="color: hsl(120, 100%, 40%);">+                         strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                     exit(5);</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+             rc = chdir(g_output_dir);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      fprintf(stderr, "Cannot change to just-created directory '%s': %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                               g_output_dir, strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                       exit(5);</span><br><span style="color: hsl(120, 100%, 40%);">+              }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  reader = osim_reader_open(OSIM_READER_DRV_PCSC, readernum, "", NULL);</span><br><span>      if (!reader)</span><br><span>                 exit(1);</span><br><span>@@ -521,6 +606,7 @@</span><br><span>               /* normal file */</span><br><span>            dump_fcp_template_msg(msg);</span><br><span>          msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+               mkdir_and_chdir("ADF_USIM", 0750);</span><br><span>         }</span><br><span> </span><br><span>        msg = select_file(chan, 0x6fc5);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/17553">change 17553</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/c/libosmocore/+/17553"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I35176f4a13c3537eaa8de550e231818a22b4c07c </div>
<div style="display:none"> Gerrit-Change-Number: 17553 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>