// File: /workspace/github_cpp_makefile_star2_O2/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 $0x1e8, %rsp            # imm = 0x1E8
movq %rdx, %r15
movq %rsi, %r14
movq %rdi, %r12
leaq 0xc8(%rsp), %rbx
movq %rbx, %rdi
movq %rdx, %rsi
callq 0x58e0
leaq 0x1b8b(%rip), %rsi      # 0x84db
pushq $0x3
popq %rdx
leaq 0x20(%rsp), %rcx
leaq 0x14(%rsp), %r8
movq %rbx, %rdi
callq 0x6cfc
movl %eax, %ebp
leaq 0xc8(%rsp), %rdi
callq 0x594c
testl %ebp, %ebp
setne %al
movl 0x14(%rsp), %esi
testl %esi, %esi
setle %cl
orb %al, %cl
je 0x698e
pushq $-0x1
popq %rbp
jmp 0x6c9c
movq 0x20(%rsp), %rdi
leaq 0x30(%rsp), %rdx
callq 0x6d76
movl %eax, %ebp
testl %eax, %eax
js 0x6c9c
movq 0x20(%r12), %rdi
callq 0x4b86
movq 0x20(%r12), %rdi
movq 0x20(%rsp), %rsi
movl 0x14(%rsp), %edx
callq 0x4e0c
movq %rax, %r13
leaq 0xb0(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x58e0
leaq 0x1aca(%rip), %rsi      # 0x84ab
pushq $0xd
popq %rdx
leaq 0x18(%rsp), %rcx
leaq 0xc(%rsp), %r8
movq %rbx, %rdi
callq 0x6cfc
leaq 0xb0(%rsp), %rdi
callq 0x594c
movq 0x18(%rsp), %rdi
movl 0xc(%rsp), %esi
callq 0x70fe
testq %r13, %r13
setne %dl
testl %eax, %eax
sets %cl
orb %dl, %cl
jne 0x6c74
movl %eax, 0x10(%rsp)
movq %r12, 0x28(%rsp)
movq 0x20(%r12), %rdi
movq 0x20(%rsp), %rsi
movl 0x14(%rsp), %edx
callq 0x4b9a
movq %rax, %r12
movl 0x4(%r14), %eax
movl %eax, 0x138(%r12)
movzwl 0x2(%r14), %eax
rolw $0x8, %ax
movw %ax, 0x13c(%r12)
leaq 0x8(%r12), %rdi
movq 0x30(%rsp), %rsi
movl 0x38(%rsp), %edx
callq 0x3300
movb 0x5d(%rsp), %al
movb %al, 0x1(%r12)
movb 0x5c(%rsp), %al
movb %al, (%r12)
movb 0x5e(%rsp), %al
movb %al, 0x2(%r12)
leaq 0xb8(%r12), %rdi
movq 0x60(%rsp), %rsi
movl 0x68(%rsp), %edx
callq 0x3300
cmpb $0x0, 0x1(%r12)
jne 0x6ad5
leaq 0x28(%r12), %rdi
movq 0x40(%rsp), %rsi
movl 0x48(%rsp), %edx
callq 0x3300
leaq 0xd8(%r12), %rdi
movq 0x70(%rsp), %rsi
movl 0x78(%rsp), %edx
callq 0x3300
leaq 0x98(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x58e0
leaq 0x19b7(%rip), %rsi      # 0x84a6
pushq $0x4
popq %rdx
leaq 0x18(%rsp), %rcx
leaq 0xc(%rsp), %r8
movq %rbx, %rdi
callq 0x6cfc
leaq 0x98(%rsp), %rdi
callq 0x594c
leaq 0xf8(%r12), %rdi
leaq 0x18(%rsp), %r14
movq (%r14), %rsi
leaq 0xc(%rsp), %r13
movslq (%r13), %rdx
callq 0x3300
leaq 0x80(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x58e0
leaq 0x1970(%rip), %rsi      # 0x84b9
pushq $0x8
popq %rdx
movq %rbx, %rdi
movq %r14, %rcx
movq %r13, %r8
callq 0x6cfc
movq %r12, %r13
leaq 0x80(%rsp), %rdi
callq 0x594c
leaq 0x118(%r12), %rbx
movq 0x18(%rsp), %rsi
movslq 0xc(%rsp), %rdx
movq %rbx, %rdi
callq 0x3300
leaq 0x1a5a(%rip), %rsi      # 0x85e5
movq %rbx, %rdi
xorl %edx, %edx
callq 0x3430
cmpq $-0x1, %rax
je 0x6be8
movq %rax, %r14
movzbl 0x138(%r13), %edx
movzbl 0x139(%r13), %ecx
movzbl 0x13a(%r13), %r8d
movzbl 0x13b(%r13), %r9d
leaq 0x1a2d(%rip), %rsi      # 0x85f2
leaq 0xe0(%rsp), %r15
movq %r15, %rdi
xorl %eax, %eax
callq 0x3080
pushq $0xc
popq %rdx
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rcx
callq 0x3150
addq $0x28, %r12
leaq 0x18ec(%rip), %rsi      # 0x84df
movq %r12, %rdi
xorl %edx, %edx
callq 0x3430
cmpq $-0x1, %rax
je 0x6c39
movups 0x1922(%rip), %xmm0     # 0x852c
leaq 0xe0(%rsp), %rcx
movups %xmm0, 0x1c(%rcx)
movaps 0x1903(%rip), %xmm0     # 0x8520
movaps %xmm0, 0x10(%rcx)
movaps 0x18e8(%rip), %xmm0     # 0x8510
movaps %xmm0, (%rcx)
pushq $0x2c
popq %rdx
movq %r12, %rdi
movq %rax, %rsi
callq 0x3150
movb 0x5d(%rsp), %al
orb 0x5c(%rsp), %al
je 0x6c57
movq 0x28(%rsp), %r12
movq 0x20(%r12), %rdi
movq %r13, %rsi
callq 0x4cfa
jmp 0x6c70
cmpb $0x0, 0x5e(%rsp)
movq 0x28(%rsp), %r12
je 0x6c70
movq 0x20(%r12), %rdi
movq %r13, %rsi
callq 0x4f30
movl 0x10(%rsp), %eax
testl %eax, %eax
js 0x6c92
testq %r13, %r13
je 0x6c92
movq 0x20(%r12), %rdi
movq 0x30(%rsp), %rsi
movl 0x38(%rsp), %edx
movl %eax, %ecx
callq 0x4f6e
movq 0x20(%r12), %rdi
callq 0x4b90
movl %ebp, %eax
addq $0x1e8, %rsp            # imm = 0x1E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x6cb6
jmp 0x6cb6
jmp 0x6cb6
movq %rax, %r14
movq %rbx, %rdi
callq 0x594c
movq %r14, %rdi
callq 0x33d0
nop