// File: /workspace/github_cpp_makefile_star2_O2/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 $0x1458, %rsp           # imm = 0x1458
movq %rsi, -0x40(%rbp)
movl %edi, -0x30(%rbp)
leaq 0x8561(%rip), %rsi      # 0x10040
leaq -0x1480(%rbp), %rdi
movl $0x1001, %edx           # imm = 0x1001
callq 0x21e0
leaq -0x170(%rbp), %rdi
callq 0xa610
movb 0x11946(%rip), %al      # 0x19448
testb %al, %al
je 0x7d29
movb $0x1, %bl
leaq 0xb87f(%rip), %r13      # 0x13392
leaq 0x11746(%rip), %r15     # 0x19260
leaq -0x470(%rbp), %r12
leaq 0x84e8(%rip), %r14      # 0x10010
testb $0x1, %bl
je 0x7c25
andl $0x0, -0x470(%rbp)
movl -0x30(%rbp), %edi
movq -0x40(%rbp), %rsi
movq %r13, %rdx
movq %r15, %rcx
movq %r12, %r8
callq 0x2070
cmpl $-0x1, %eax
je 0x7c25
testl %eax, %eax
setg -0x170(%rbp)
cmpl $0xb, %eax
ja 0x7c0e
movl %eax, %eax
movslq (%r14,%rax,4), %rax
addq %r14, %rax
leaq -0x168(%rbp), %rdi
jmpq *%rax
movq 0x11437(%rip), %rax     # 0x18fb8
movq (%rax), %rsi
movl $0x1000, %edx           # imm = 0x1000
leaq -0x1480(%rbp), %rdi
callq 0x2140
jmp 0x7b28
leaq -0x68(%rbp), %rdi
jmp 0x7bda
leaq -0x108(%rbp), %rdi
jmp 0x7bda
leaq -0xe8(%rbp), %rdi
jmp 0x7bda
leaq -0x148(%rbp), %rdi
jmp 0x7bda
leaq -0x128(%rbp), %rdi
jmp 0x7bda
leaq -0x88(%rbp), %rdi
jmp 0x7bda
leaq -0xc8(%rbp), %rdi
jmp 0x7bda
leaq -0xa8(%rbp), %rdi
movq 0x113d7(%rip), %rax     # 0x18fb8
movq (%rax), %rsi
callq 0x2450
jmp 0x7b28
movb $0x1, -0x44(%rbp)
jmp 0x7b28
movq 0x113ba(%rip), %rax     # 0x18fb8
movq (%rax), %rdi
callq 0x23d0
movl %eax, -0x48(%rbp)
jmp 0x7b28
xorl %ebx, %ebx
leaq 0xb762(%rip), %rdi      # 0x13379
movl %eax, %esi
xorl %eax, %eax
callq 0x2050
jmp 0x7b28
movq 0x113ac(%rip), %r14     # 0x18fd8
testb $0x1, %bl
je 0x7f01
movl -0x30(%rbp), %eax
cmpl %eax, (%r14)
jl 0x7f01
leaq 0xc312(%rip), %rdi      # 0x13f5a
callq 0x23c0
leaq 0xb73e(%rip), %rsi      # 0x13392
leaq -0xe8(%rbp), %rdi
callq 0x83a1
testb %al, %al
je 0x7c85
leaq -0x170(%rbp), %rdi
callq 0x6f5a
movq -0x108(%rbp), %rsi
leaq 0xb73e(%rip), %rdi      # 0x133bc
xorl %eax, %eax
callq 0x2050
cmpb $0x1, -0x170(%rbp)
jne 0x7cf0
cmpq $0x8, -0x160(%rbp)
jne 0x7ce4
leaq 0xc2d3(%rip), %rdi      # 0x13f72
callq 0x23c0
leaq -0x1480(%rbp), %rdi
leaq -0x170(%rbp), %rsi
callq 0x373d
leaq -0x1480(%rbp), %rdi
leaq -0x170(%rbp), %rsi
callq 0x4f4f
leaq 0xc2b4(%rip), %rdi      # 0x13f85
callq 0x23c0
leaq -0x1480(%rbp), %rdi
callq 0x2ff5
jmp 0x7cf0
leaq 0xc2b2(%rip), %rdi      # 0x13f9d
callq 0x23c0
cmpb $0x1, -0x44(%rbp)
jne 0x7d09
leaq -0x1480(%rbp), %rdi
leaq -0x170(%rbp), %rsi
callq 0x7207
leaq -0x170(%rbp), %rdi
callq 0xabc6
xorl %eax, %eax
addq $0x1458, %rsp           # imm = 0x1458
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x11718(%rip), %rdi     # 0x19448
callq 0x2430
testl %eax, %eax
je 0x7b0a
leaq 0xb350(%rip), %rsi      # 0x13094
leaq 0xb37d(%rip), %rdx      # 0x130c8
leaq -0x470(%rbp), %r15
movq %r15, %rdi
callq 0xa7a2
leaq -0x430(%rbp), %r12
leaq 0xb331(%rip), %rsi      # 0x13099
leaq 0xb38d(%rip), %rdx      # 0x130fc
movq %r12, %rdi
callq 0xa7e8
leaq -0x3f0(%rbp), %r12
leaq 0xb318(%rip), %rsi      # 0x1309d
leaq 0xb39f(%rip), %rdx      # 0x1312b
movq %r12, %rdi
callq 0xa82e
leaq -0x3b0(%rbp), %r12
leaq 0xb301(%rip), %rsi      # 0x130a3
leaq 0xb395(%rip), %rdx      # 0x1313e
movq %r12, %rdi
callq 0xa874
leaq -0x370(%rbp), %r12
leaq 0xb2e9(%rip), %rsi      # 0x130a8
leaq 0xb3c6(%rip), %rdx      # 0x1318c
movq %r12, %rdi
callq 0xa8ba
leaq -0x330(%rbp), %r12
leaq 0xb2d0(%rip), %rsi      # 0x130ac
leaq 0xb3ee(%rip), %rdx      # 0x131d1
movq %r12, %rdi
callq 0xa900
leaq -0x2f0(%rbp), %r12
leaq 0xb2b8(%rip), %rsi      # 0x130b1
leaq 0xb401(%rip), %rdx      # 0x13201
movq %r12, %rdi
callq 0xa946
leaq -0x2b0(%rbp), %r12
leaq 0xb29f(%rip), %rsi      # 0x130b5
leaq 0xb406(%rip), %rdx      # 0x13223
movq %r12, %rdi
callq 0xa98c
leaq -0x270(%rbp), %r12
leaq 0xb286(%rip), %rsi      # 0x130b9
leaq 0xb439(%rip), %rdx      # 0x13273
movq %r12, %rdi
callq 0xa9d2
leaq -0x230(%rbp), %r12
leaq 0xb271(%rip), %rsi      # 0x130c1
leaq 0xb44e(%rip), %rdx      # 0x132a5
movq %r12, %rdi
callq 0xaa18
leaq -0x1f0(%rbp), %r12
leaq 0xb257(%rip), %rsi      # 0x130c4
leaq 0xb478(%rip), %rdx      # 0x132ec
movq %r12, %rdi
callq 0xaa5e
leaq -0x1b0(%rbp), %r12
leaq 0xb0d7(%rip), %rsi      # 0x12f61
leaq 0xb49e(%rip), %rdx      # 0x1332f
movq %r12, %rdi
callq 0xaaa4
leaq 0x11578(%rip), %rdi     # 0x19418
leaq -0x470(%rbp), %rsi
pushq $0xc
popq %rdx
leaq -0x29(%rbp), %rcx
leaq -0x31(%rbp), %r8
callq 0xab0a
movl $0x2c0, %ebx            # imm = 0x2C0
leaq (%rbx,%rbp), %rdi
addq $-0x470, %rdi           # imm = 0xFB90
callq 0xaaea
addq $-0x40, %rbx
cmpq $-0x40, %rbx
jne 0x7ebc
leaq 0x2c75(%rip), %rdi      # 0xab52
leaq 0x11534(%rip), %rsi     # 0x19418
leaq 0x1136d(%rip), %rdx     # 0x19258
callq 0x2200
leaq 0x11551(%rip), %rdi     # 0x19448
callq 0x2180
jmp 0x7b0a
leaq 0xb48b(%rip), %rdi      # 0x13393
xorl %eax, %eax
callq 0x2050
leaq 0xb9ba(%rip), %r12      # 0x138d0
movslq (%r14), %rax
cmpl -0x30(%rbp), %eax
jge 0x7f38
leal 0x1(%rax), %ecx
movl %ecx, (%r14)
movq -0x40(%rbp), %rcx
movq (%rcx,%rax,8), %rsi
movq %r12, %rdi
xorl %eax, %eax
callq 0x2050
jmp 0x7f16
leaq 0xc08f(%rip), %rdi      # 0x13fce
callq 0x23c0
leaq -0x470(%rbp), %rbx
leaq 0x114c6(%rip), %r12     # 0x19418
leaq 0xb455(%rip), %r13      # 0x133ae
movq (%r15), %r14
testq %r14, %r14
je 0x7f99
movq %rbx, %rdi
movq %r14, %rsi
leaq -0x29(%rbp), %rdx
callq 0x20f0
movq %r12, %rdi
movq %rbx, %rsi
callq 0xab5c
movq (%rax), %rdx
movq %r13, %rdi
movq %r14, %rsi
xorl %eax, %eax
callq 0x2050
movq %rbx, %rdi
callq 0x2120
addq $0x20, %r15
jmp 0x7f59
pushq $0xa
popq %rdi
callq 0x2340
pushq $0x1
popq %rdi
callq 0x22e0
movq %rax, %rbx
movl $0x2c0, %r14d           # imm = 0x2C0
leaq (%r14,%rbp), %rdi
addq $-0x470, %rdi           # imm = 0xFB90
callq 0xaaea
addq $-0x40, %r14
cmpq $-0x40, %r14
jne 0x7fb2
jmp 0x7fe7
movq %rax, %rbx
jmp 0x7fe7
movq %rax, %rbx
addq $-0x40, %r12
movq %r12, %rdi
callq 0xaaea
cmpq %r15, %r12
jne 0x7fd6
leaq 0x1145a(%rip), %rdi     # 0x19448
callq 0x2170
jmp 0x800d
movq %rax, %rbx
leaq -0x470(%rbp), %rdi
callq 0x2120
jmp 0x800d
jmp 0x800a
jmp 0x800a
movq %rax, %rbx
leaq -0x170(%rbp), %rdi
callq 0xabc6
movq %rbx, %rdi
callq 0x2400