// File: /workspace/github_cpp_makefile_star2_O3/brunokeymolen[P]ssdp/src/ssdpsearchresp.cpp
// Function: SSDPSearchResp::Process(sockaddr*, std::vector<SSDP_HTTP_HEADER*, std::allocator<SSDP_HTTP_HEADER*>>)
int SSDPSearchResp::Process(struct sockaddr* sender, std::vector<SSDP_HTTP_HEADER*> msgheaders){
    u8* usn;
    int usnlen;
    int ret;
    u8* val;
    int vallen;
    int cache;
    SSDPDBDevice *device;
    //SSDPDBService *service;
    ssdpuuid uuid;



    //Get the Device USN (Unique Service Name)
    ret=GetHeaderValueFromCollection(msgheaders, (u8*)"USN", 3, &usn, &usnlen);
    if(ret != 0 || usnlen<=0){
        ret = -1;
        return ret;
    }

    ret = ParseUSN(usn, usnlen, &uuid);
    if(ret < 0){
        return ret;
    }

    mDB->Lock();


    //Device or service update

    //Is the device already registered ?
    device = mDB->GetDevice(usn, usnlen);

    GetHeaderValueFromCollection(msgheaders, (u8*)"CACHE-CONTROL", 13, &val, &vallen);
    cache = cachecontroltoi(val, vallen);

    if(device == NULL && cache >= 0){ //cachecontrol is mandatory, if not formatted well we ignore all to avoid conflicts with the db cleanup
        device = mDB->InsertDevice(usn, usnlen);
        memcpy(&(device->ip), (u8*)sender->sa_data+2, 4);
        memcpy(&(device->port), sender->sa_data, 2);
        device->port = ntohs(device->port);

        //uuid
        device->uuid.assign((const char*)uuid.uuid, uuid.uuidlen);
        device->isroot = uuid.isrootdevice;
        device->isdevice = uuid.isdevice;
        device->isservice = uuid.isservice;
        device->type.assign((const char*)uuid.type, uuid.typelen);
        if(!device->isroot){
            device->urn.assign((const char*)uuid.fullurn, uuid.fullurnlen);
            device->version.assign((const char*)uuid.version, uuid.versionlen);
        }
        //host
        GetHeaderValueFromCollection(msgheaders, (u8*)"HOST", 4, &val, &vallen);
        device->host.assign((const char*)val, vallen);
        //Location
        GetHeaderValueFromCollection(msgheaders, (u8*)"LOCATION", 8, &val, &vallen);
        device->location.assign((const char*)val, vallen);


        //Workaround for MusicPal bug
        size_t wrongloc = device->location.find("://127.0.0.1");
        if(wrongloc != std::string::npos){
            //replace 127.0.0.1 with source ip address
            char ipbuf[255];
            sprintf(ipbuf, "://%d.%d.%d.%d", (unsigned char)((char*)&(device->ip))[0], (unsigned char)((char*)&(device->ip))[1], (unsigned char)((char*)&(device->ip))[2], (unsigned char)((char*)&(device->ip))[3] );
            device->location.replace(wrongloc, 12, ipbuf);
        }
        //end workaround

        //Workaround for another MusicPal bug
        size_t wrongdev = device->urn.find("schemas-upnp-org:device:RenderingControl:1");
        if(wrongdev != std::string::npos){
            //replace schemas-upnp-org:device:RenderingControl:1 with schemas-upnp-org:service:RenderingControl:1
            char buf[] = "schemas-upnp-org:service:RenderingControl:1";
            device->urn.replace(wrongdev, sizeof(buf), buf);
        }
        //end workaround


        //Inform the observers
        if(uuid.isdevice || uuid.isrootdevice){
            mDB->DeviceUpdate(device);
        }else if(uuid.isservice){
            mDB->ServiceUpdate(device);
        }

    }

    //always update cache control
    if(device != NULL && cache >= 0){
        mDB->UpdateCacheControl(uuid.uuid, uuid.uuidlen, cache);
    }

    //printf("%s\n", device->uuid.c_str());

    mDB->Unlock();

    return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1d8, %rsp            # imm = 0x1D8
movq %rdx, %r12
movq %rsi, %r15
movq %rdi, %rbx
leaq 0xb8(%rsp), %r14
movq %r14, %rdi
movq %rdx, %rsi
callq 0x5eba
leaq 0x13bf(%rip), %rsi      # 0x84db
leaq 0x18(%rsp), %rcx
leaq 0xc(%rsp), %r8
movq %r14, %rdi
movl $0x3, %edx
callq 0x7590
movl %eax, %ebp
movq 0xb8(%rsp), %rdi
testq %rdi, %rdi
je 0x7152
movq 0xc8(%rsp), %rsi
subq %rdi, %rsi
callq 0x3280
testl %ebp, %ebp
setne %al
movl 0xc(%rsp), %esi
testl %esi, %esi
setle %cl
orb %al, %cl
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
jne 0x74f8
movq 0x18(%rsp), %rdi
leaq 0x20(%rsp), %rdx
callq 0x760e
movl %eax, %ebp
testl %eax, %eax
js 0x74f8
movq 0x20(%rbx), %rdi
callq 0x4f34
movq 0x20(%rbx), %rdi
movq 0x18(%rsp), %rsi
movl 0xc(%rsp), %edx
callq 0x527c
movq %rax, %r14
leaq 0xa0(%rsp), %r13
movq %r13, %rdi
movq %r12, %rsi
callq 0x5eba
leaq 0x12ed(%rip), %rsi      # 0x84ab
leaq 0x10(%rsp), %rcx
leaq 0x4(%rsp), %r8
movq %r13, %rdi
movl $0xd, %edx
callq 0x7590
movq 0xa0(%rsp), %rdi
testq %rdi, %rdi
je 0x71f2
movq 0xb0(%rsp), %rsi
subq %rdi, %rsi
callq 0x3280
movq 0x10(%rsp), %rdi
movl 0x4(%rsp), %esi
callq 0x797b
testq %r14, %r14
setne %dl
testl %eax, %eax
sets %cl
orb %dl, %cl
jne 0x74d2
movl %eax, 0x8(%rsp)
movq 0x20(%rbx), %rdi
movq 0x18(%rsp), %rsi
movl 0xc(%rsp), %edx
callq 0x4f48
movq %rax, %r13
movq %rax, %r14
movl 0x4(%r15), %eax
movl %eax, 0x138(%r13)
movzwl 0x2(%r15), %eax
rolw $0x8, %ax
movw %ax, 0x13c(%r13)
leaq 0x8(%r13), %rdi
movq 0x20(%rsp), %rcx
movl 0x28(%rsp), %r8d
movq 0x10(%r13), %rdx
xorl %esi, %esi
callq 0x3390
movb 0x4d(%rsp), %al
movb %al, 0x1(%r13)
movb 0x4c(%rsp), %al
movb %al, (%r13)
movb 0x4e(%rsp), %al
movb %al, 0x2(%r13)
leaq 0xb8(%r13), %rdi
movq 0x50(%rsp), %rcx
movl 0x58(%rsp), %r8d
movq 0xc0(%r13), %rdx
xorl %esi, %esi
callq 0x3390
cmpb $0x0, 0x1(%r13)
jne 0x72da
leaq 0x28(%r13), %rdi
movq 0x30(%rsp), %rcx
movl 0x38(%rsp), %r8d
movq 0x30(%r14), %rdx
xorl %esi, %esi
callq 0x3390
leaq 0xd8(%r13), %rdi
movq 0x60(%rsp), %rcx
movl 0x68(%rsp), %r8d
movq 0xe0(%r14), %rdx
xorl %esi, %esi
callq 0x3390
leaq 0x88(%rsp), %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0x5eba
leaq 0x11b2(%rip), %rsi      # 0x84a6
leaq 0x10(%rsp), %rcx
leaq 0x4(%rsp), %r8
movq %r15, %rdi
movl $0x4, %edx
callq 0x7590
movq 0x88(%rsp), %rdi
testq %rdi, %rdi
je 0x7328
movq 0x98(%rsp), %rsi
subq %rdi, %rsi
callq 0x3280
leaq 0xf8(%r13), %rdi
leaq 0x10(%rsp), %rax
movq (%rax), %rcx
leaq 0x4(%rsp), %rax
movslq (%rax), %r8
movq 0x100(%r14), %rdx
xorl %esi, %esi
callq 0x3390
leaq 0x70(%rsp), %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0x5eba
leaq 0x1155(%rip), %rsi      # 0x84b9
movq %r15, %rdi
movl $0x8, %edx
leaq 0x10(%rsp), %rcx
leaq 0x4(%rsp), %r8
callq 0x7590
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x7395
movq 0x80(%rsp), %rsi
subq %rdi, %rsi
callq 0x3280
leaq 0x118(%r13), %r15
movq 0x10(%rsp), %rcx
movslq 0x4(%rsp), %r8
movq 0x120(%r14), %rdx
movq %r15, %rdi
xorl %esi, %esi
callq 0x3390
leaq 0x126e(%rip), %rsi      # 0x862c
movl $0xc, %ecx
movq %r15, %rdi
xorl %edx, %edx
callq 0x3400
cmpq $-0x1, %rax
je 0x7434
movq %rax, %r12
movzbl 0x138(%r14), %edx
movzbl 0x139(%r14), %ecx
movzbl 0x13a(%r14), %r8d
movzbl 0x13b(%r14), %r9d
leaq 0x123c(%rip), %rsi      # 0x8639
leaq 0xd0(%rsp), %rdi
xorl %eax, %eax
callq 0x3090
leaq 0xd0(%rsp), %rdi
callq 0x3100
movl $0xc, %edx
movq %r15, %rdi
movq %r12, %rsi
leaq 0xd0(%rsp), %rcx
movq %rax, %r8
callq 0x32a0
addq $0x28, %r13
leaq 0x10a0(%rip), %rsi      # 0x84df
movl $0x2a, %ecx
movq %r13, %rdi
xorl %edx, %edx
callq 0x3400
cmpq $-0x1, %rax
je 0x74a3
movq %rax, %r15
movups 0x10ce(%rip), %xmm0     # 0x852c
leaq 0xd0(%rsp), %r12
movups %xmm0, 0x1c(%r12)
movaps 0x10ad(%rip), %xmm0     # 0x8520
movaps %xmm0, 0x10(%r12)
movaps 0x1090(%rip), %xmm0     # 0x8510
movaps %xmm0, (%r12)
movq %r12, %rdi
callq 0x3100
movl $0x2c, %edx
movq %r13, %rdi
movq %r15, %rsi
movq %r12, %rcx
movq %rax, %r8
callq 0x32a0
movb 0x4d(%rsp), %al
orb 0x4c(%rsp), %al
je 0x74bb
movq 0x20(%rbx), %rdi
movq %r14, %rsi
callq 0x510e
jmp 0x74ce
cmpb $0x0, 0x4e(%rsp)
je 0x74ce
movq 0x20(%rbx), %rdi
movq %r14, %rsi
callq 0x541a
movl 0x8(%rsp), %eax
testl %eax, %eax
js 0x74ef
testq %r14, %r14
je 0x74ef
movq 0x20(%rbx), %rdi
movq 0x20(%rsp), %rsi
movl 0x28(%rsp), %edx
movl %eax, %ecx
callq 0x545c
movq 0x20(%rbx), %rdi
callq 0x4f3e
movl %ebp, %eax
addq $0x1d8, %rsp            # imm = 0x1D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x80(%rsp), %rcx
movq %rax, %rbx
movq 0x70(%rsp), %rdi
jmp 0x7546
leaq 0x98(%rsp), %rcx
movq %rax, %rbx
movq 0x88(%rsp), %rdi
jmp 0x7546
leaq 0xb0(%rsp), %rcx
movq %rax, %rbx
movq 0xa0(%rsp), %rdi
testq %rdi, %rdi
jne 0x7565
jmp 0x7570
movq %rax, %rbx
movq 0xb8(%rsp), %rdi
testq %rdi, %rdi
je 0x7570
leaq 0xc8(%rsp), %rcx
movq (%rcx), %rsi
subq %rdi, %rsi
callq 0x3280
movq %rbx, %rdi
callq 0x3410