// File: brunokeymolen[P]ssdp/src/ssdpnotifyalive.cpp
// Function: SSDPNotifyAlive::Process(sockaddr*, std::vector<SSDP_HTTP_HEADER*, std::allocator<SSDP_HTTP_HEADER*>>)
int SSDPNotifyAlive::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;//Unknown format
    }


    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 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();


    //printf("SSDPNotifyAlive\n");
    return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x180, %rsp            # imm = 0x180
movq %rdx, -0x168(%rbp)
movq %rsi, %rax
movq -0x168(%rbp), %rsi
movq %rsi, -0x160(%rbp)
movq %rdi, -0x10(%rbp)
movq %rax, -0x18(%rbp)
movq %rsi, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x158(%rbp)
leaq -0xb0(%rbp), %rdi
movq %rdi, -0x150(%rbp)
callq 0xa860
movq -0x150(%rbp), %rdi
leaq 0x4a38(%rip), %rsi      # 0x104e3
movl $0x3, %edx
leaq -0x28(%rbp), %rcx
leaq -0x2c(%rbp), %r8
callq 0xe230
movl %eax, -0x144(%rbp)
jmp 0xbac5
movl -0x144(%rbp), %eax
movl %eax, -0x30(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0xa800
cmpl $0x0, -0x30(%rbp)
jne 0xbae6
cmpl $0x0, -0x2c(%rbp)
jg 0xbb1b
movl $0xffffffff, -0x30(%rbp) # imm = 0xFFFFFFFF
movl -0x30(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xbed9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0xa800
jmp 0xbee5
movq -0x28(%rbp), %rdi
movl -0x2c(%rbp), %esi
leaq -0x98(%rbp), %rdx
callq 0xe350
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jge 0xbb42
movl -0x30(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xbed9
movq -0x158(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x6f40
movq -0x158(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x28(%rbp), %rsi
movl -0x2c(%rbp), %edx
callq 0x7360
movq -0x160(%rbp), %rsi
movq %rax, -0x48(%rbp)
leaq -0xd8(%rbp), %rdi
movq %rdi, -0x170(%rbp)
callq 0xa860
movq -0x170(%rbp), %rdi
leaq 0x491e(%rip), %rsi      # 0x104b3
movl $0xd, %edx
leaq -0x38(%rbp), %rcx
leaq -0x3c(%rbp), %r8
callq 0xe230
jmp 0xbba9
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 0xbe96
cmpl $0x0, -0x40(%rbp)
jl 0xbe96
movq -0x158(%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 0xbce9
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 0xbce9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0xa800
jmp 0xbee5
movq -0x160(%rbp), %rsi
leaq -0xf0(%rbp), %rdi
movq %rdi, -0x178(%rbp)
callq 0xa860
movq -0x178(%rbp), %rdi
leaq 0x479d(%rip), %rsi      # 0x104ae
movl $0x4, %edx
leaq -0x38(%rbp), %rcx
leaq -0x3c(%rbp), %r8
callq 0xe230
jmp 0xbd25
leaq -0xf0(%rbp), %rdi
callq 0xa800
movq -0x48(%rbp), %rdi
addq $0xf8, %rdi
movq -0x38(%rbp), %rsi
movslq -0x3c(%rbp), %rdx
callq 0x33c0
movq -0x160(%rbp), %rsi
leaq -0x108(%rbp), %rdi
movq %rdi, -0x180(%rbp)
callq 0xa860
movq -0x180(%rbp), %rdi
leaq 0x4750(%rip), %rsi      # 0x104c1
movl $0x8, %edx
leaq -0x38(%rbp), %rcx
leaq -0x3c(%rbp), %r8
callq 0xe230
jmp 0xbd85
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 $0x28, %rdi
leaq 0x472f(%rip), %rsi      # 0x104e7
xorl %eax, %eax
movl %eax, %edx
callq 0x3530
movq %rax, -0x110(%rbp)
cmpq $-0x1, -0x110(%rbp)
je 0xbe56
leaq -0x140(%rbp), %rdi
leaq 0x473c(%rip), %rsi      # 0x10520
movl $0x2c, %edx
callq 0x3230
movq -0x48(%rbp), %rdi
addq $0x28, %rdi
movq -0x110(%rbp), %rsi
leaq -0x140(%rbp), %rcx
movl $0x2c, %edx
callq 0x3180
jmp 0xbe56
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0xa800
jmp 0xbee5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb8(%rbp)
movl %eax, -0xbc(%rbp)
leaq -0x108(%rbp), %rdi
callq 0xa800
jmp 0xbee5
cmpb $0x0, -0x6c(%rbp)
jne 0xbe62
cmpb $0x0, -0x6b(%rbp)
je 0xbe78
movq -0x158(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x48(%rbp), %rsi
callq 0x7170
jmp 0xbe94
cmpb $0x0, -0x6a(%rbp)
je 0xbe92
movq -0x158(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x48(%rbp), %rsi
callq 0x76a0
jmp 0xbe94
jmp 0xbe96
cmpq $0x0, -0x48(%rbp)
je 0xbec3
cmpl $0x0, -0x40(%rbp)
jl 0xbec3
movq -0x158(%rbp), %rax
movq 0x20(%rax), %rdi
movq -0x98(%rbp), %rsi
movl -0x90(%rbp), %edx
movl -0x40(%rbp), %ecx
callq 0x7740
movq -0x158(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x6f60
movl -0x30(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x180, %rsp            # imm = 0x180
popq %rbp
retq
movq -0xb8(%rbp), %rdi
callq 0x34b0
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)