// File: 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
movq %rsp, %rbp
subq $0x290, %rsp            # imm = 0x290
movq %rdx, -0x278(%rbp)
movq %rsi, %rax
movq -0x278(%rbp), %rsi
movq %rsi, -0x270(%rbp)
movq %rdi, -0x10(%rbp)
movq %rax, -0x18(%rbp)
movq %rsi, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x268(%rbp)
leaq -0xb0(%rbp), %rdi
movq %rdi, -0x260(%rbp)
callq 0xa860
movq -0x260(%rbp), %rdi
leaq 0x2828(%rip), %rsi      # 0x104e3
movl $0x3, %edx
leaq -0x28(%rbp), %rcx
leaq -0x2c(%rbp), %r8
callq 0xe230
movl %eax, -0x254(%rbp)
jmp 0xdcd5
movl -0x254(%rbp), %eax
movl %eax, -0x30(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0xa800
cmpl $0x0, -0x30(%rbp)
jne 0xdcf6
cmpl $0x0, -0x2c(%rbp)
jg 0xdd2b
movl $0xffffffff, -0x30(%rbp) # imm = 0xFFFFFFFF
movl -0x30(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xe17b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0xa800
jmp 0xe187
movq -0x28(%rbp), %rdi
movl -0x2c(%rbp), %esi
leaq -0x98(%rbp), %rdx
callq 0xe350
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jge 0xdd52
movl -0x30(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xe17b
movq -0x268(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x6f40
movq -0x268(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x28(%rbp), %rsi
movl -0x2c(%rbp), %edx
callq 0x7360
movq -0x270(%rbp), %rsi
movq %rax, -0x48(%rbp)
leaq -0xd8(%rbp), %rdi
movq %rdi, -0x280(%rbp)
callq 0xa860
movq -0x280(%rbp), %rdi
leaq 0x270e(%rip), %rsi      # 0x104b3
movl $0xd, %edx
leaq -0x38(%rbp), %rcx
leaq -0x3c(%rbp), %r8
callq 0xe230
jmp 0xddb9
leaq -0xd8(%rbp), %rdi
callq 0xa800
movq -0x38(%rbp), %rdi
movl -0x3c(%rbp), %esi
callq 0xe850
movl %eax, -0x40(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0xe138
cmpl $0x0, -0x40(%rbp)
jl 0xe138
movq -0x268(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x28(%rbp), %rsi
movl -0x2c(%rbp), %edx
callq 0x6f80
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movq -0x18(%rbp), %rcx
movl 0x4(%rcx), %ecx
movl %ecx, 0x138(%rax)
movq -0x48(%rbp), %rax
movq -0x18(%rbp), %rcx
movw 0x2(%rcx), %cx
movw %cx, 0x13c(%rax)
movq -0x48(%rbp), %rax
movzwl 0x13c(%rax), %edi
callq 0x3500
movw %ax, %cx
movq -0x48(%rbp), %rax
movw %cx, 0x13c(%rax)
movq -0x48(%rbp), %rdi
addq $0x8, %rdi
movq -0x98(%rbp), %rsi
movl -0x90(%rbp), %eax
movl %eax, %edx
callq 0x33c0
movb -0x6b(%rbp), %cl
movq -0x48(%rbp), %rax
movb %cl, 0x1(%rax)
movb -0x6c(%rbp), %cl
movq -0x48(%rbp), %rax
movb %cl, (%rax)
movb -0x6a(%rbp), %cl
movq -0x48(%rbp), %rax
movb %cl, 0x2(%rax)
movq -0x48(%rbp), %rdi
addq $0xb8, %rdi
movq -0x68(%rbp), %rsi
movl -0x60(%rbp), %eax
movl %eax, %edx
callq 0x33c0
movq -0x48(%rbp), %rax
cmpb $0x0, 0x1(%rax)
jne 0xdef9
movq -0x48(%rbp), %rdi
addq $0x28, %rdi
movq -0x88(%rbp), %rsi
movl -0x80(%rbp), %eax
movl %eax, %edx
callq 0x33c0
movq -0x48(%rbp), %rdi
addq $0xd8, %rdi
movq -0x58(%rbp), %rsi
movl -0x50(%rbp), %eax
movl %eax, %edx
callq 0x33c0
jmp 0xdef9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0xa800
jmp 0xe187
movq -0x270(%rbp), %rsi
leaq -0xf0(%rbp), %rdi
movq %rdi, -0x288(%rbp)
callq 0xa860
movq -0x288(%rbp), %rdi
leaq 0x258d(%rip), %rsi      # 0x104ae
movl $0x4, %edx
leaq -0x38(%rbp), %rcx
leaq -0x3c(%rbp), %r8
callq 0xe230
jmp 0xdf35
leaq -0xf0(%rbp), %rdi
callq 0xa800
movq -0x48(%rbp), %rdi
addq $0xf8, %rdi
movq -0x38(%rbp), %rsi
movslq -0x3c(%rbp), %rdx
callq 0x33c0
movq -0x270(%rbp), %rsi
leaq -0x108(%rbp), %rdi
movq %rdi, -0x290(%rbp)
callq 0xa860
movq -0x290(%rbp), %rdi
leaq 0x2540(%rip), %rsi      # 0x104c1
movl $0x8, %edx
leaq -0x38(%rbp), %rcx
leaq -0x3c(%rbp), %r8
callq 0xe230
jmp 0xdf95
leaq -0x108(%rbp), %rdi
callq 0xa800
movq -0x48(%rbp), %rdi
addq $0x118, %rdi            # imm = 0x118
movq -0x38(%rbp), %rsi
movslq -0x3c(%rbp), %rdx
callq 0x33c0
movq -0x48(%rbp), %rdi
addq $0x118, %rdi            # imm = 0x118
leaq 0x262a(%rip), %rsi      # 0x105f5
xorl %eax, %eax
movl %eax, %edx
callq 0x3530
movq %rax, -0x110(%rbp)
cmpq $-0x1, -0x110(%rbp)
je 0xe097
leaq -0x210(%rbp), %rdi
movq -0x48(%rbp), %rax
movzbl 0x138(%rax), %edx
movq -0x48(%rbp), %rax
movzbl 0x139(%rax), %ecx
movq -0x48(%rbp), %rax
movzbl 0x13a(%rax), %r8d
movq -0x48(%rbp), %rax
movzbl 0x13b(%rax), %r9d
leaq 0x25dd(%rip), %rsi      # 0x10602
movb $0x0, %al
callq 0x30a0
movq -0x48(%rbp), %rdi
addq $0x118, %rdi            # imm = 0x118
movq -0x110(%rbp), %rsi
leaq -0x210(%rbp), %rcx
movl $0xc, %edx
callq 0x3180
jmp 0xe097
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0xa800
jmp 0xe187
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
leaq -0x108(%rbp), %rdi
callq 0xa800
jmp 0xe187
movq -0x48(%rbp), %rdi
addq $0x28, %rdi
leaq 0x2441(%rip), %rsi      # 0x104e7
xorl %eax, %eax
movl %eax, %edx
callq 0x3530
movq %rax, -0x218(%rbp)
cmpq $-0x1, -0x218(%rbp)
je 0xe0f8
leaq -0x250(%rbp), %rdi
leaq 0x2452(%rip), %rsi      # 0x10520
movl $0x2c, %edx
callq 0x3230
movq -0x48(%rbp), %rdi
addq $0x28, %rdi
movq -0x218(%rbp), %rsi
leaq -0x250(%rbp), %rcx
movl $0x2c, %edx
callq 0x3180
cmpb $0x0, -0x6c(%rbp)
jne 0xe104
cmpb $0x0, -0x6b(%rbp)
je 0xe11a
movq -0x268(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x48(%rbp), %rsi
callq 0x7170
jmp 0xe136
cmpb $0x0, -0x6a(%rbp)
je 0xe134
movq -0x268(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x48(%rbp), %rsi
callq 0x76a0
jmp 0xe136
jmp 0xe138
cmpq $0x0, -0x48(%rbp)
je 0xe165
cmpl $0x0, -0x40(%rbp)
jl 0xe165
movq -0x268(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x98(%rbp), %rsi
movl -0x90(%rbp), %edx
movl -0x40(%rbp), %ecx
callq 0x7740
movq -0x268(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x6f60
movl -0x30(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x290, %rsp            # imm = 0x290
popq %rbp
retq
movq -0xb8(%rbp), %rdi
callq 0x34b0
nopw %cs:(%rax,%rax)
nopl (%rax)