// File: /workspace/github_cpp_makefile_star2_O1/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, %r15
movl %edi, %r12d
leaq 0xb15d(%rip), %rsi      # 0x15060
leaq -0x1470(%rbp), %rdi
movl $0x1001, %edx           # imm = 0x1001
callq 0x21f0
leaq -0x168(%rbp), %rdi
callq 0xd48c
movb 0x15512(%rip), %al      # 0x1f438
testb %al, %al
movq %r15, -0x38(%rbp)
movl %r12d, -0x30(%rbp)
je 0xa1a8
movb $0x1, %r13b
testb $0x1, %r13b
je 0xa0a6
movl $0x0, -0x468(%rbp)
movl %r12d, %edi
movq %r15, %rsi
leaq 0xe458(%rip), %rdx      # 0x183b2
leaq 0x152ef(%rip), %rcx     # 0x1f250
leaq -0x468(%rbp), %r8
callq 0x2080
movl %eax, %ebx
cmpl $-0x1, %eax
je 0xa06c
testl %ebx, %ebx
setg -0x168(%rbp)
cmpl $0xb, %ebx
ja 0xa091
movl %ebx, %eax
leaq 0xb09d(%rip), %rdx      # 0x15030
movslq (%rdx,%rax,4), %rcx
addq %rdx, %rcx
leaq -0x158(%rbp), %rax
leaq -0x160(%rbp), %r14
jmpq *%rcx
movq 0x15007(%rip), %rax     # 0x1efb8
movq (%rax), %rsi
movl $0x1000, %edx           # imm = 0x1000
leaq -0x1470(%rbp), %rdi
callq 0x2140
jmp 0xa06c
leaq -0x58(%rbp), %rax
leaq -0x60(%rbp), %r14
jmp 0xa03c
leaq -0xf8(%rbp), %rax
leaq -0x100(%rbp), %r14
jmp 0xa03c
leaq -0xd8(%rbp), %rax
leaq -0xe0(%rbp), %r14
jmp 0xa03c
leaq -0x138(%rbp), %rax
leaq -0x140(%rbp), %r14
jmp 0xa03c
leaq -0x118(%rbp), %rax
leaq -0x120(%rbp), %r14
jmp 0xa03c
leaq -0x78(%rbp), %rax
leaq -0x80(%rbp), %r14
jmp 0xa03c
leaq -0xb8(%rbp), %rax
leaq -0xc0(%rbp), %r14
jmp 0xa03c
leaq -0x98(%rbp), %rax
leaq -0xa0(%rbp), %r14
movq 0x14f75(%rip), %rcx     # 0x1efb8
movq (%rcx), %r15
movq (%rax), %r12
movq %r15, %rdi
callq 0x2130
movq %r14, %rdi
xorl %esi, %esi
movq %r12, %rdx
movl -0x30(%rbp), %r12d
movq %r15, %rcx
movq -0x38(%rbp), %r15
movq %rax, %r8
callq 0x23d0
cmpl $-0x1, %ebx
jne 0x9f39
jmp 0xa0a6
movb $0x1, -0x3c(%rbp)
jmp 0xa06c
movq 0x14f34(%rip), %rax     # 0x1efb8
movq (%rax), %rdi
callq 0x23e0
movl %eax, -0x40(%rbp)
jmp 0xa06c
xorl %r13d, %r13d
leaq 0xe2fe(%rip), %rdi      # 0x18399
movl %ebx, %esi
xorl %eax, %eax
callq 0x2060
jmp 0xa06c
movq 0x14f2b(%rip), %r14     # 0x1efd8
cmpl %r12d, (%r14)
jl 0xa38d
andb $0x1, %r13b
je 0xa38d
leaq 0xeeb3(%rip), %rdi      # 0x18f7a
callq 0x23c0
leaq -0xe0(%rbp), %rdi
leaq 0xe2d8(%rip), %rsi      # 0x183b2
callq 0x20b0
testl %eax, %eax
je 0xa104
leaq -0x168(%rbp), %rdi
callq 0x906c
movq -0x100(%rbp), %rsi
leaq 0xe2df(%rip), %rdi      # 0x183dc
xorl %eax, %eax
callq 0x2060
cmpb $0x1, -0x168(%rbp)
jne 0xa16f
cmpq $0x8, -0x158(%rbp)
jne 0xa163
leaq 0xee74(%rip), %rdi      # 0x18f92
callq 0x23c0
leaq -0x1470(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x54d4
leaq -0x1470(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x6eb7
leaq 0xee55(%rip), %rdi      # 0x18fa5
callq 0x23c0
leaq -0x1470(%rbp), %rdi
callq 0x4af2
jmp 0xa16f
leaq 0xee53(%rip), %rdi      # 0x18fbd
callq 0x23c0
cmpb $0x1, -0x3c(%rbp)
jne 0xa188
leaq -0x1470(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x934f
leaq -0x168(%rbp), %rdi
callq 0xddaa
xorl %eax, %eax
addq $0x1448, %rsp           # imm = 0x1448
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x15289(%rip), %rdi     # 0x1f438
callq 0x2430
testl %eax, %eax
je 0x9f36
leaq -0x468(%rbp), %r15
leaq 0xdeea(%rip), %rsi      # 0x180b4
leaq 0xdf17(%rip), %rdx      # 0x180e8
movq %r15, %r12
movq %r15, %rdi
callq 0xd6e0
leaq -0x428(%rbp), %r12
leaq 0xdecf(%rip), %rsi      # 0x180b9
leaq 0xdf2b(%rip), %rdx      # 0x1811c
movq %r12, %rdi
callq 0xd756
leaq -0x3e8(%rbp), %r12
leaq 0xdeb6(%rip), %rsi      # 0x180bd
leaq 0xdf3d(%rip), %rdx      # 0x1814b
movq %r12, %rdi
callq 0xd7cc
leaq -0x3a8(%rbp), %r12
leaq 0xde9f(%rip), %rsi      # 0x180c3
leaq 0xdf33(%rip), %rdx      # 0x1815e
movq %r12, %rdi
callq 0xd842
leaq -0x368(%rbp), %r12
leaq 0xde87(%rip), %rsi      # 0x180c8
leaq 0xdf64(%rip), %rdx      # 0x181ac
movq %r12, %rdi
callq 0xd8b8
leaq -0x328(%rbp), %r12
leaq 0xde6e(%rip), %rsi      # 0x180cc
leaq 0xdf8c(%rip), %rdx      # 0x181f1
movq %r12, %rdi
callq 0xd92e
leaq -0x2e8(%rbp), %r12
leaq 0xde56(%rip), %rsi      # 0x180d1
leaq 0xdf9f(%rip), %rdx      # 0x18221
movq %r12, %rdi
callq 0xd9a4
leaq -0x2a8(%rbp), %r12
leaq 0xde3d(%rip), %rsi      # 0x180d5
leaq 0xdfa4(%rip), %rdx      # 0x18243
movq %r12, %rdi
callq 0xda1a
leaq -0x268(%rbp), %r12
leaq 0xde24(%rip), %rsi      # 0x180d9
leaq 0xdfd7(%rip), %rdx      # 0x18293
movq %r12, %rdi
callq 0xda90
leaq -0x228(%rbp), %r12
leaq 0xde0f(%rip), %rsi      # 0x180e1
leaq 0xdfec(%rip), %rdx      # 0x182c5
movq %r12, %rdi
callq 0xdb06
leaq -0x1e8(%rbp), %r12
leaq 0xddf5(%rip), %rsi      # 0x180e4
leaq 0xe016(%rip), %rdx      # 0x1830c
movq %r12, %rdi
callq 0xdb7c
leaq -0x1a8(%rbp), %r12
leaq 0xdc75(%rip), %rsi      # 0x17f81
leaq 0xe03c(%rip), %rdx      # 0x1834f
movq %r12, %rdi
callq 0xdbf2
leaq 0x150e6(%rip), %rdi     # 0x1f408
leaq -0x468(%rbp), %rsi
leaq -0x29(%rbp), %rcx
leaq -0x2a(%rbp), %r8
movl $0xc, %edx
callq 0xdc9e
movl $0x2c0, %ebx            # imm = 0x2C0
leaq (%rbx,%rbp), %rdi
addq $-0x468, %rdi           # imm = 0xFB98
callq 0xdc68
addq $-0x40, %rbx
cmpq $-0x40, %rbx
jne 0xa340
leaq 0x39bf(%rip), %rdi      # 0xdd20
leaq 0x150a0(%rip), %rsi     # 0x1f408
leaq 0x14ed9(%rip), %rdx     # 0x1f248
callq 0x2210
leaq 0x150bd(%rip), %rdi     # 0x1f438
callq 0x2180
movq -0x38(%rbp), %r15
movl -0x30(%rbp), %r12d
jmp 0x9f36
leaq 0xe01f(%rip), %rdi      # 0x183b3
xorl %eax, %eax
callq 0x2060
movl (%r14), %eax
cmpl %r12d, %eax
jge 0xa3c8
leaq 0xe546(%rip), %rbx      # 0x188f0
leal 0x1(%rax), %ecx
movl %ecx, (%r14)
cltq
movq (%r15,%rax,8), %rsi
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2060
movl (%r14), %eax
cmpl %r12d, %eax
jl 0xa3aa
leaq 0xec1f(%rip), %rdi      # 0x18fee
callq 0x23c0
movq 0x14e75(%rip), %r13     # 0x1f250
testq %r13, %r13
je 0xa44a
leaq 0x14e89(%rip), %r14     # 0x1f270
leaq -0x468(%rbp), %rbx
leaq 0x15013(%rip), %r15     # 0x1f408
leaq 0xdfd2(%rip), %r12      # 0x183ce
movq %rbx, %rdi
movq %r13, %rsi
leaq -0x29(%rbp), %rdx
callq 0x2110
movq %r15, %rdi
movq %rbx, %rsi
callq 0xdd2a
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 0xa43e
callq 0x2220
movq (%r14), %r13
addq $0x20, %r14
testq %r13, %r13
jne 0xa3fc
movl $0xa, %edi
callq 0x2340
movl $0x1, %edi
callq 0x2300
movq %rax, %rbx
movl $0x2c0, %r14d           # imm = 0x2C0
leaq (%r14,%rbp), %rdi
addq $-0x468, %rdi           # imm = 0xFB98
callq 0xdc68
addq $-0x40, %r14
cmpq $-0x40, %r14
jne 0xa467
jmp 0xa4a3
movq %rax, %rbx
cmpq %r12, %r15
je 0xa4a3
leaq -0x468(%rbp), %r14
addq $-0x40, %r12
movq %r12, %rdi
callq 0xdc68
cmpq %r14, %r12
jne 0xa492
leaq 0x14f8e(%rip), %rdi     # 0x1f438
callq 0x2170
jmp 0xa4d5
movq %rax, %rbx
movq -0x468(%rbp), %rdi
leaq -0x458(%rbp), %rax
cmpq %rax, %rdi
je 0xa4d5
callq 0x2220
jmp 0xa4d5
jmp 0xa4d2
jmp 0xa4d2
movq %rax, %rbx
leaq -0x168(%rbp), %rdi
callq 0xddaa
movq %rbx, %rdi
callq 0x2400