FreeCalypso > hg > fc-sim-tools
view simtool/pnnprog.c @ 53:fbedb67d234f
serial: fix parity for inverse coding convention
Important note: it is my (Mother Mychaela's) understanding that
SIM cards with inverse coding convention are extremely rare,
and I have never seen such a card. Therefore, our support for
the inverse coding convention will likely remain forever untested.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 21 Mar 2021 20:46:09 +0000 |
parents | ddd767f6e15b |
children |
line wrap: on
line source
/* * This module implements functions for admin programming of EF_PNN. */ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include "curfile.h" static u_char * add_field(dp, bytes_avail, namearg, type) u_char *dp; char *namearg; unsigned bytes_avail, type; { u_char gsm7_buf[289]; unsigned nsept, noct; int rc; if (bytes_avail < 4) { fprintf(stderr, "error: PNN record is too short for name element\n"); return(0); } rc = qstring_arg_to_gsm7(namearg, gsm7_buf, (bytes_avail-3) * 8 / 7); if (rc < 0) return(0); nsept = rc; gsm7_buf[nsept] = 0; noct = (nsept * 7 + 7) / 8; *dp++ = type; *dp++ = noct + 1; *dp++ = 0x80 | (nsept & 7); gsm7_pack(gsm7_buf, dp, noct); dp += noct; return dp; } cmd_pnn_write(argc, argv) char **argv; { int rc; unsigned recno; u_char record[255], *dp, *endp; rc = select_ef_pnn(); if (rc < 0) return(rc); recno = strtoul(argv[1], 0, 0); if (recno < 1 || recno > curfile_record_count) { fprintf(stderr, "error: specified record number is invalid\n"); return(-1); } dp = record; endp = record + curfile_record_len; dp = add_field(dp, endp - dp, argv[2], 0x43); if (!dp) return(-1); if (argv[3]) { dp = add_field(dp, endp - dp, argv[3], 0x45); if (!dp) return(-1); } while (dp < endp) *dp++ = 0xFF; return update_rec_op(recno, 0x04, record, curfile_record_len); } cmd_pnn_erase(argc, argv) char **argv; { int rc; unsigned recno, startrec, endrec; u_char record[255]; rc = select_ef_pnn(); if (rc < 0) return(rc); startrec = strtoul(argv[1], 0, 0); if (startrec < 1 || startrec > curfile_record_count) { fprintf(stderr, "error: specified starting record number is invalid\n"); return(-1); } if (!argv[2]) endrec = startrec; else if (!strcmp(argv[2], "end")) endrec = curfile_record_count; else { endrec = strtoul(argv[2], 0, 0); if (endrec < 1 || endrec > curfile_record_count) { fprintf(stderr, "error: specified final record number is invalid\n"); return(-1); } if (startrec > endrec) { fprintf(stderr, "error: reverse record range specified\n"); return(-1); } } memset(record, 0xFF, curfile_record_len); for (recno = startrec; recno <= endrec; recno++) { rc = update_rec_op(recno, 0x04, record, curfile_record_len); if (rc < 0) return(rc); } return(0); }