                     searchType: req.headers.st, address: rinfo.address, port: rinfo.port
                     dev, httpServer
                 )
+    socket.addMembership config.ssdp.address
     socket.bind config.ssdp.port
 
-# send 3 messages about the device, and then one for each service
 advertise = (dev, httpServer) ->
-    # messages only have different notification types
-    messages = for nt in makeNotificationHeaders(dev)
+    sendMessages(
         makeMessage(
             'notify'
+            [ 'host', 'cache-control', 'location', 'nt', 'nts', 'server', 'usn' ]
             nt: nt, nts: 'ssdp:alive'
             dev, httpServer
-        )
-    sendMessages messages
+        ) for nt in makeNotificationHeaders(dev)
+    )
 
 answer = (req, dev, httpServer) ->
-    messages =
-        if req.searchType is 'ssdp:all'
-            for st in makeNotificationHeaders(dev)
-                makeMessage(
-                    'notify'
-                    st: st, ext: '', nts: 'ssdp:alive'
-                    dev, httpServer
-                )
-        # respond with the same search type as request's
-        else
-            [ makeMessage(
-                'notify'
-                st: req.searchType, ext: ''
-                dev, httpServer
-            ) ]
-        sendMessages messages, req.address, req.port
+    # unless ssdp:all, respond once with same search type as request's
+    sendMessages(
+        makeMessage(
+            'ok'
+            [ 'cache-control', 'ext', 'location', 'server', 'st', 'usn' ]
+            st: st
+            dev, httpServer
+        ) for st in (if req.searchType is 'ssdp:all' then makeNotificationHeaders(dev) else [ req.searchType ])
+        req.address
+        req.port
+    )
 
+# send 3 messages about the device, and then one for each service
 makeNotificationHeaders = (dev) ->
     arr = [ 'upnp:rootdevice', config.uuid, device.makeDeviceType(dev.type) ]
     for serviceType in config.devices[dev.type].services


# create a UDP socket, send messages, then close socket
sendMessages = (messages, address, port) ->
    address ?= config.ssdp.address
    port ?= config.ssdp.port
    socket = dgram.createSocket 'udp4'
    socket.setMulticastTTL 4
    socket.bind()
    done = messages.length
    for msg in messages
        socket.send msg, 0, msg.length, port, address, ->
            if done-- is 1
                socket.close()

# generate SSDP (HTTPU/HTTPMU) headers suiting the message type
makeMessage = (reqType, customHeaders, dev, httpServer) ->
    # headers with static values
    headers =
        host: "#{config.ssdp.address}:#{config.ssdp.port}"
        'cache-control': "max-age=#{config.ssdp.timeout}"
        location: makeDescriptionUrl httpServer
        server: makeServerString dev
        usn: config.uuid

    # append NT to USN, except for requests with only uuid as NT
    if customHeaders.nt and customHeaders.nt isnt config.uuid
        headers.usn += '::' + customHeaders.nt
    else if customHeaders.st and customHeaders.st isnt config.uuid
        headers.usn += '::' + customHeaders.st
    headers = extend(headers, customHeaders)
    
    # build message string
    message = [ "#{reqType.toUpperCase()} * HTTP/1.1" ]
    for header, value of headers
        message.push "#{header.toUpperCase()}: #{value}"
    # add carriage returns and new lines as required by HTTP spec
    message.push '\r\n'
    new Buffer message.join '\r\n'

makeServerString = (dev) ->

    )

listen = exports.listen = (dev, httpServer) ->
    socket = dgram.createSocket 'udp4', (msg, rinfo) ->
        parseHeaders msg, (err, req) ->
            # these are the ST (search type) values we should respond to
            respondTo = [ 'ssdp:all', 'upnp:rootdevice', config.uuid ]
