Skip to content

Instantly share code, notes, and snippets.

@guillaumewuip
Last active October 29, 2018 15:24
Show Gist options
  • Save guillaumewuip/dec66c1e130bffee7fbe to your computer and use it in GitHub Desktop.
Save guillaumewuip/dec66c1e130bffee7fbe to your computer and use it in GitHub Desktop.
Mock an UPnP Sony Camera
/**
* Mock the Sony QX1 SSDP discovery proces
*/
var dgram = require('dgram'),
parse = require('./parse'), //helper
client = dgram.createSocket('udp4');
var UPNP_PORT = 1900;
HTTP_PORT = 8080;
HOST = '192.168.0.26';
//Listening for broadcast event
client.on('listening', function () {
var address = client.address();
client.setMulticastTTL(128);
client.addMembership('239.255.255.250', HOST);
console.log('UDP Client listening on ' + address.address + ":" + address.port);
});
//on UPnP message
client.on('message', function (buf, remote) {
var message = buf.toString('utf8').split("\n");
parse.isRequest(message, function (res) {
console.log('UPnP Request received.');
console.log('From: ' + remote.address + ':' + remote.port);
if (res) {
sendResponse();
}
});
});
var sendResponse = function () {
//response message
//note the LOCATION header
var message = new Buffer(
"HTTP/1.1 200 OK\r\n" +
"LOCATION: http://" + HOST + ":" + HTTP_PORT + "/dd.xml\r\n" +
"CACHE-CONTROL: max-age=1800\r\n" +
"EXT:\r\n" +
"SERVER: OS/version UPnP/1.0 product/version\r\n" +
"ST: urn:schemas-sony-com:service:ScalarWebAPI:1\r\n" +
"\r\n"
);
var client = dgram.createSocket("udp4");
client.send(message, 0, message.length, 1900, "239.255.255.250", function(err, bytes) {
if (err) {
console.log("ERR: " + err);
}
console.log("Message broadcasted");
client.close();
});
};
client.bind(UPNP_PORT);
/**
* UPnP client that try to find a Sony Camera via SSDP
*/
var dgram = require('dgram'),
parse = require('./parse'), //helper
client = dgram.createSocket('udp4');
var UPNP_PORT = 1900;
HOST = process.argv[2] || "192.168.0.26";
//on UPnP message
client.on('message', function (buf, remote) {
var message = buf.toString('utf8').split("\n");
parse.isResponse(message, function (res) {
if (res) {
console.log("Got response");
console.log(res);
client.close();
}
});
});
client.bind(UPNP_PORT, function () {
var message = new Buffer(
"M-SEARCH * HTTP/1.1\r\n" +
"HOST:239.255.255.250:1900\r\n" +
"ST: urn:schemas-sony-com:service:ScalarWebAPI:1\r\n" + //note this target
"MAN:\"ssdp:discover\"\r\n" +
"MX:5\r\n" + // 5 second to respond (but they all respond immediately?)
"\r\n"
);
client.send(message, 0, message.length, 1900, "239.255.255.250", function(err, bytes) {
console.log("message send");
if (err) {
console.log("ERR: " + err);
}
});
var address = client.address();
client.addMembership('239.255.255.250', HOST);
console.log('UDP Client listening on ' + address.address + ":" + address.port);
});
var handleMessage = function (message, callback) {
targetSony = message.filter(function (elem) {
if (elem.toLowerCase().indexOf("st: urn:schemas-sony-com:service:scalarwebapi:1") > -1) {
return true;
}
return false;
});
if (targetSony.length > 0) {
callback(true);
}
callback(false);
};
module.exports = {
isRequest : function (message, callback) {
handleMessage(message, function (res) {
if (res) {
var host = message.filter(function (elem) {
if (elem.toLowerCase().indexOf("host") > -1) {
return true;
}
return false;
});
if (host.length > 0) {
callback(true);
} else {
callback(false);
};
}
});
},
isResponse : function (message, callback) {
handleMessage(message, function (res) {
if (res) {
var location = message.filter(function (elem) {
if (elem.toLowerCase().indexOf("location:") > -1) {
return true;
}
return false;
});
if (location.length > 0) {
callback(location[0].replace('LOCATION: ', ''));
} else {
callback(false);
}
}
});
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment