// File: /workspace/github_cpp_makefile_star2_O3/FFY00[P]uicc/src/program_uicc.c
// Function: main
int main(int argc, char **argv) {
    char portName[FILENAME_MAX+1] = "/dev/ttyUSB0";
    struct uicc_vals new_vals;
    static struct option long_options[] = {
        {"port",  required_argument, 0, 0},
        {"adm",   required_argument, 0, 1},
        {"iccid", required_argument, 0, 2},
        {"imsi",  required_argument, 0, 3},
        {"opc",   required_argument, 0, 4},
        {"isdn",  required_argument, 0, 5},
        {"acc",   required_argument, 0, 6},
        {"key",   required_argument, 0, 7},
        {"MNCsize", required_argument, 0, 8},
        {"xx",    required_argument, 0, 9},
        {"authenticate",  no_argument, 0, 10},
        {"spn", required_argument, 0, 11},
        {0,       0,                 0, 0}
    };
    static map<string,string> help_text= {
        {"port",  "Linux port to access the card reader (/dev/ttyUSB0)"},
        {"adm",   "The ADM code of the card (the master password)"},
        {"iccid", "the UICC id to set"},
        {"imsi",  "The imsi to set, we automatically set complementary files such as \"home PLMN\""},
        {"opc",   "OPc field: OPerator code: must be also set in HSS (exlusive with OP)"},
        {"isdn",  "The mobile phone number (not used in simple 4G)"},
        {"acc",   "One of the defined security codes"},
        {"key",   "The authentication key (called Ki in 3G/4G, Kc in GSM), must be the same in HSS"},
        {"MNCsize","Mobile network code size in digits (default to 2)"},
        {"xx",    "OP  field: OPerator code: must be also set in HSS (exclusive with OPc)"},
        {"spn",   "service provider name: the name that the UE will show as 'network'"},
        {"authenticate",  "Test the milenage authentication and discover the current sequence number"},
    };
    int c;
    bool correctOpt=true;

    while (correctOpt) {
        int option_index = 0;
        c = getopt_long_only(argc, argv, "",
                             long_options, &option_index);

        if (c == -1)
            break;

        new_vals.setIt= c > 0;

        switch (c) {
        case 0:
            strncpy(portName, optarg, FILENAME_MAX);
            break;

        case 1:
            new_vals.adm=optarg;
            break;

        case 2:
            new_vals.iccid=optarg;
            break;

        case 3:
            new_vals.imsi=optarg;
            break;

        case 4:
            new_vals.opc=optarg;
            break;

        case 5:
            new_vals.isdn=optarg;
            break;

        case 6:
            new_vals.acc=optarg;
            break;

        case 7:
            new_vals.key=optarg;
            break;

        case 8:
            new_vals.mncLen=atoi(optarg);
            break;

        case 9:
            new_vals.op=optarg;
            break;

        case 10:
            new_vals.authenticate=true;
            break;

        case 11:
            new_vals.spn=optarg;
            break;

        default:
            printf("unrecognized option: %d \n", c);
            correctOpt=false;
        };
    }

    if (optind < argc ||  correctOpt==false) {
        printf("non-option ARGV-elements: ");

        while (optind < argc)
            printf("%s ", argv[optind++]);

        printf("Possible options are:\n");

        for (int i=0; long_options[i].name!=NULL; i++)
            printf("  --%-10s %s\n",long_options[i].name, help_text[long_options[i].name].c_str());

        printf("\n");
        exit(1);
    }

    printf ("Existing values in USIM\n");
    //Assert(readUSIMvalues(portName), "failed to read UICC");

    if ( new_vals.op != "") {
        setOPc(new_vals);
        printf("Computed OPc from OP and Ki as: %s\n", new_vals.opc.c_str());
    }

    if (new_vals.setIt) {
        if ( new_vals.adm.size() != 8 )
            printf ("No ADM code of 8 figures, can't program the UICC\n");
        else {
            printf("Setting new values\n");
            writeSIMvalues(portName, new_vals);
            writeUSIMvalues(portName, new_vals);
            printf ("Read new values in UICC\n");
            readUSIMvalues(portName);
        }
    }

    if ( new_vals.authenticate)
        authenticate(portName, new_vals);

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1448, %rsp           # imm = 0x1448
movq %rsi, %r13
movl %edi, %r14d
leaq 0xae79(%rip), %rsi      # 0x15060
leaq -0x1470(%rbp), %rdi
movl $0x1001, %edx           # imm = 0x1001
callq 0x21f0
leaq -0x168(%rbp), %rdi
callq 0xd78e
movb 0x1522e(%rip), %al      # 0x1f438
testb %al, %al
movq %r13, -0x38(%rbp)
movl %r14d, -0x30(%rbp)
je 0xa574
leaq -0x468(%rbp), %r8
movl $0x0, (%r8)
leaq 0xe183(%rip), %rdx      # 0x183b2
leaq 0x1501a(%rip), %rcx     # 0x1f250
movl %r14d, %edi
movq %r13, %rsi
callq 0x2080
cmpl $-0x1, %eax
je 0xa390
leaq 0xaddf(%rip), %r12      # 0x15030
leaq -0x468(%rbp), %r15
testl %eax, %eax
setg -0x168(%rbp)
cmpl $0xb, %eax
ja 0xa488
movl %eax, %eax
movslq (%r12,%rax,4), %rcx
addq %r12, %rcx
leaq -0x158(%rbp), %rax
leaq -0x160(%rbp), %rbx
jmpq *%rcx
movq 0x14d2e(%rip), %rax     # 0x1efb8
movq (%rax), %rsi
movl $0x1000, %edx           # imm = 0x1000
leaq -0x1470(%rbp), %rdi
callq 0x2140
jmp 0xa345
leaq -0x58(%rbp), %rax
leaq -0x60(%rbp), %rbx
jmp 0xa315
leaq -0xf8(%rbp), %rax
leaq -0x100(%rbp), %rbx
jmp 0xa315
leaq -0xd8(%rbp), %rax
leaq -0xe0(%rbp), %rbx
jmp 0xa315
leaq -0x138(%rbp), %rax
leaq -0x140(%rbp), %rbx
jmp 0xa315
leaq -0x118(%rbp), %rax
leaq -0x120(%rbp), %rbx
jmp 0xa315
leaq -0x78(%rbp), %rax
leaq -0x80(%rbp), %rbx
jmp 0xa315
leaq -0xb8(%rbp), %rax
leaq -0xc0(%rbp), %rbx
jmp 0xa315
leaq -0x98(%rbp), %rax
leaq -0xa0(%rbp), %rbx
movq 0x14c9c(%rip), %rcx     # 0x1efb8
movq (%rcx), %r14
movq (%rax), %r13
movq %r14, %rdi
callq 0x2130
movq %rbx, %rdi
xorl %esi, %esi
movq %r13, %rdx
movq -0x38(%rbp), %r13
movq %r14, %rcx
movl -0x30(%rbp), %r14d
movq %rax, %r8
callq 0x23d0
movl $0x0, -0x468(%rbp)
movl %r14d, %edi
movq %r13, %rsi
leaq 0xe056(%rip), %rdx      # 0x183b2
leaq 0x14eed(%rip), %rcx     # 0x1f250
movq %r15, %r8
callq 0x2080
cmpl $-0x1, %eax
jne 0xa258
jmp 0xa390
movb $0x1, -0x3c(%rbp)
jmp 0xa345
movq 0x14c35(%rip), %rax     # 0x1efb8
movq (%rax), %rdi
callq 0x23e0
movl %eax, -0x40(%rbp)
jmp 0xa345
movq 0x14c41(%rip), %rax     # 0x1efd8
cmpl %r14d, (%rax)
jl 0xa498
leaq 0xebd3(%rip), %rdi      # 0x18f7a
callq 0x23c0
leaq 0xdfff(%rip), %rsi      # 0x183b2
leaq -0xe0(%rbp), %rdi
callq 0x20b0
testl %eax, %eax
je 0xa3e4
leaq -0x168(%rbp), %rdi
callq 0x90e6
movq -0x100(%rbp), %rsi
leaq 0xdfff(%rip), %rdi      # 0x183dc
xorl %eax, %eax
callq 0x2060
cmpb $0x1, -0x168(%rbp)
jne 0xa44f
cmpq $0x8, -0x158(%rbp)
jne 0xa443
leaq 0xeb94(%rip), %rdi      # 0x18f92
callq 0x23c0
leaq -0x1470(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x54e1
leaq -0x1470(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x6ef9
leaq 0xeb75(%rip), %rdi      # 0x18fa5
callq 0x23c0
leaq -0x1470(%rbp), %rdi
callq 0x4af1
jmp 0xa44f
leaq 0xeb73(%rip), %rdi      # 0x18fbd
callq 0x23c0
cmpb $0x1, -0x3c(%rbp)
jne 0xa468
leaq -0x1470(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x947e
leaq -0x168(%rbp), %rdi
callq 0xe0ac
xorl %eax, %eax
addq $0x1448, %rsp           # imm = 0x1448
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xdf0a(%rip), %rdi      # 0x18399
movl %eax, %esi
xorl %eax, %eax
callq 0x2060
leaq 0xdf14(%rip), %rdi      # 0x183b3
xorl %eax, %eax
callq 0x2060
movl %r14d, %r15d
movq 0x14b28(%rip), %r14     # 0x1efd8
movl (%r14), %eax
cmpl %r15d, %eax
jge 0xa4de
leaq 0xe431(%rip), %rbx      # 0x188f0
leal 0x1(%rax), %ecx
movl %ecx, (%r14)
cltq
movq (%r13,%rax,8), %rsi
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2060
movl (%r14), %eax
cmpl %r15d, %eax
jl 0xa4bf
leaq 0xeb09(%rip), %rdi      # 0x18fee
callq 0x23c0
movq 0x14d5f(%rip), %r13     # 0x1f250
testq %r13, %r13
je 0xa560
leaq 0x14d73(%rip), %r14     # 0x1f270
leaq -0x468(%rbp), %rbx
leaq 0x14efd(%rip), %r15     # 0x1f408
leaq 0xdebc(%rip), %r12      # 0x183ce
movq %rbx, %rdi
movq %r13, %rsi
leaq -0x29(%rbp), %rdx
callq 0x2110
movq %r15, %rdi
movq %rbx, %rsi
callq 0xe02c
movq (%rax), %rdx
movq %r12, %rdi
movq %r13, %rsi
xorl %eax, %eax
callq 0x2060
movq -0x468(%rbp), %rdi
leaq -0x458(%rbp), %rax
cmpq %rax, %rdi
je 0xa554
callq 0x2220
movq (%r14), %r13
addq $0x20, %r14
testq %r13, %r13
jne 0xa512
movl $0xa, %edi
callq 0x2340
movl $0x1, %edi
callq 0x2300
leaq 0x14ebd(%rip), %rdi     # 0x1f438
callq 0x2430
testl %eax, %eax
je 0xa21a
leaq 0xdb25(%rip), %rsi      # 0x180b4
leaq 0xdb52(%rip), %rdx      # 0x180e8
leaq -0x468(%rbp), %r15
movq %r15, %rdi
callq 0xd9e2
leaq -0x428(%rbp), %r12
leaq 0xdb06(%rip), %rsi      # 0x180b9
leaq 0xdb62(%rip), %rdx      # 0x1811c
movq %r12, %rdi
callq 0xda58
leaq -0x3e8(%rbp), %r12
leaq 0xdaed(%rip), %rsi      # 0x180bd
leaq 0xdb74(%rip), %rdx      # 0x1814b
movq %r12, %rdi
callq 0xdace
leaq -0x3a8(%rbp), %r12
leaq 0xdad6(%rip), %rsi      # 0x180c3
leaq 0xdb6a(%rip), %rdx      # 0x1815e
movq %r12, %rdi
callq 0xdb44
leaq -0x368(%rbp), %r12
leaq 0xdabe(%rip), %rsi      # 0x180c8
leaq 0xdb9b(%rip), %rdx      # 0x181ac
movq %r12, %rdi
callq 0xdbba
leaq -0x328(%rbp), %r12
leaq 0xdaa5(%rip), %rsi      # 0x180cc
leaq 0xdbc3(%rip), %rdx      # 0x181f1
movq %r12, %rdi
callq 0xdc30
leaq -0x2e8(%rbp), %r12
leaq 0xda8d(%rip), %rsi      # 0x180d1
leaq 0xdbd6(%rip), %rdx      # 0x18221
movq %r12, %rdi
callq 0xdca6
leaq -0x2a8(%rbp), %r12
leaq 0xda74(%rip), %rsi      # 0x180d5
leaq 0xdbdb(%rip), %rdx      # 0x18243
movq %r12, %rdi
callq 0xdd1c
leaq -0x268(%rbp), %r12
leaq 0xda5b(%rip), %rsi      # 0x180d9
leaq 0xdc0e(%rip), %rdx      # 0x18293
movq %r12, %rdi
callq 0xdd92
leaq -0x228(%rbp), %r12
leaq 0xda46(%rip), %rsi      # 0x180e1
leaq 0xdc23(%rip), %rdx      # 0x182c5
movq %r12, %rdi
callq 0xde08
leaq -0x1e8(%rbp), %r12
leaq 0xda2c(%rip), %rsi      # 0x180e4
leaq 0xdc4d(%rip), %rdx      # 0x1830c
movq %r12, %rdi
callq 0xde7e
leaq -0x1a8(%rbp), %r12
leaq 0xd8ac(%rip), %rsi      # 0x17f81
leaq 0xdc73(%rip), %rdx      # 0x1834f
movq %r12, %rdi
callq 0xdef4
leaq 0x14d1d(%rip), %rdi     # 0x1f408
leaq -0x468(%rbp), %rsi
leaq -0x29(%rbp), %rcx
leaq -0x2a(%rbp), %r8
movl $0xc, %edx
callq 0xdfa0
movl $0x2c0, %ebx            # imm = 0x2C0
leaq (%rbx,%rbp), %rdi
addq $-0x468, %rdi           # imm = 0xFB98
callq 0xdf6a
addq $-0x40, %rbx
cmpq $-0x40, %rbx
jne 0xa709
leaq 0x38f8(%rip), %rdi      # 0xe022
leaq 0x14cd7(%rip), %rsi     # 0x1f408
leaq 0x14b10(%rip), %rdx     # 0x1f248
callq 0x2210
leaq 0x14cf4(%rip), %rdi     # 0x1f438
callq 0x2180
movq -0x38(%rbp), %r13
movl -0x30(%rbp), %r14d
jmp 0xa21a
movq %rax, %rbx
movl $0x2c0, %r14d           # imm = 0x2C0
leaq (%r14,%rbp), %rdi
addq $-0x468, %rdi           # imm = 0xFB98
callq 0xdf6a
addq $-0x40, %r14
cmpq $-0x40, %r14
jne 0xa75f
jmp 0xa794
movq %rax, %rbx
jmp 0xa794
movq %rax, %rbx
addq $-0x40, %r12
movq %r12, %rdi
callq 0xdf6a
cmpq %r15, %r12
jne 0xa783
leaq 0x14c9d(%rip), %rdi     # 0x1f438
callq 0x2170
jmp 0xa7c6
movq %rax, %rbx
movq -0x468(%rbp), %rdi
leaq -0x458(%rbp), %rax
cmpq %rax, %rdi
je 0xa7c6
callq 0x2220
jmp 0xa7c6
jmp 0xa7c3
jmp 0xa7c3
movq %rax, %rbx
leaq -0x168(%rbp), %rdi
callq 0xe0ac
movq %rbx, %rdi
callq 0x2400