Last active
August 26, 2016 02:56
-
-
Save moleike/48fc4facc329ec428de44cdbaa3eb894 to your computer and use it in GitHub Desktop.
an http api for mqtt-shepherd
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// reverse proxy (HTTP(s) to LWM2M over MQTT) | |
// this should be mounted on an Express app | |
const router = require('express').Router() | |
const shepherd = require('lib/shepherd'); | |
const ch = require('lib/status'); // coap to http status | |
const herrero = require('herrero'); | |
const bodyParser = require('body-parser') | |
const { NotFoundError } = herrero; | |
// load the router on e.g /device/:id | |
module.exports = router | |
// read returns object representations | |
// discover returns object links | |
// TODO add support for these media types: | |
// | |
// * application/senml+json for object representations | |
// * application/link-format+json for object links | |
// | |
router.use(bodyParser.json({ type: 'application/*+json' })) | |
router.param('oid', (req, res, next, id) => { | |
const qnode = shepherd.find(req.id); // assumes the device id is stored on req object | |
if (!qnode) | |
next(new NotFoundError(`not found`)) | |
req.qnode = qnode; | |
next(); | |
}); | |
router.route('/:oid') | |
.get((req, res, next) => { | |
req.qnode.readReq(req.path, (err, rsp) => { | |
if (err) return next(err); | |
const { status, data } = rsp; | |
res.status(ch(status)).json(data); | |
}); | |
}) | |
router.route('/:oid/attributes') | |
.get((req, res, next) => { | |
console.log('req.param.oid ' + req.param.oid) | |
req.qnode.discoverReq(req.params.oid, (err, rsp) => { | |
if (err) return next(err); | |
const { status, data } = rsp; | |
res.status(ch(status)).json(data); | |
}); | |
}) | |
.put((req, res, next) => { | |
const { pmin, pmax, gt, lt, stp } = req.query; | |
req.qnode.writeAttrsReq(req.params.oid, { | |
pmin, pmax, gt, lt, stp | |
}, (err, rsp) => { | |
if (err) return next(err); | |
const { status, data } = rsp; | |
res.status(ch(status)).json(data); | |
}); | |
}); | |
router.route('/:oid/:iid') | |
.get((req, res, next) => { | |
req.qnode.readReq(req.path, (err, rsp) => { | |
if (err) return next(err); | |
const { status, data } = rsp; | |
res.status(ch(status)).json(data); | |
}); | |
}) | |
.put((req, res, next) => { | |
const { oid, iid } = req.params; | |
const { id : rid , value } = req.body.resource; // { resource: { id: 0, value: 'foo' } } | |
if (rid === undefined || value === undefined) | |
return next(new BadRequestError()); | |
req.qnode.writeReq(`${oid}/${iid}/${rid}`, value, (err, rsp) => { | |
if (err) return next(err); | |
const { status, data } = rsp; | |
res.status(ch(status)).json(data); | |
}); | |
}) | |
router.route('/:oid/:iid/attributes') | |
.get((req, res, next) => { | |
const { oid, iid } = req.params; | |
req.qnode.discoverReq(`${oid}/${iid}`, (err, rsp) => { | |
if (err) return next(err); | |
const { status, data } = rsp; | |
res.status(ch(status)).json(data); | |
}); | |
}) | |
.put((req, res, next) => { | |
const { oid, iid } = req.params; | |
const { pmin, pmax, gt, lt, stp } = req.query; | |
req.qnode.writeAttrsReq(`${oid}/${iid}`, { | |
pmin, pmax, gt, lt, stp | |
}, (err, rsp) => { | |
if (err) return next(err); | |
const { status, data } = rsp; | |
res.status(ch(status)).json(data); | |
}); | |
}); | |
router.route('/:oid/:iid/:rid') | |
.get((req, res, next) => { | |
req.qnode.readReq(req.path, (err, rsp) => { | |
if (err) return next(err); | |
const { status, data } = rsp; | |
res.set('Content-Type', 'text/plain'); | |
res.status(ch(status)).json(data); | |
}); | |
}) | |
router.route('/:oid/:iid/:rid/exec') | |
.post((req, res, next) => { | |
if (!Array.isArray(req.body.args)) // { 'args': [0, 'myString', false] } | |
return next(new BadRequestError('array of arguments was expected')); | |
req.qnode.executeReq(req.path, req.body ,(err, rsp) => { | |
if (err) return next(err); | |
const { status, data } = rsp; | |
res.status(ch(status)).json(data); | |
}); | |
}); | |
router.route('/:oid/:iid/:rid/attributes') | |
.get((req, res, next) => { | |
const { oid, iid, rid } = req.params; | |
req.qnode.discoverReq(`${oid}/${iid}/${rid}`, (err, rsp) => { | |
if (err) return next(err); | |
const { status, data } = rsp; | |
res.status(ch(status)).json(data); | |
}); | |
}) | |
.put((req, res, next) => { | |
const { oid, iid, rid } = req.params; | |
const { pmin, pmax, gt, lt, stp } = req.query; | |
req.qnode.writeAttrsReq(`${oid}/${iid}/${rid}`, { | |
pmin, pmax, gt, lt, stp | |
}, (err, rsp) => { | |
if (err) return next(err); | |
const { status, data } = rsp; | |
res.status(ch(status)).json(data); | |
}); | |
}) | |
// as in https://developer.github.com/v3/gists/#star-a-gist | |
router.route('/:oid/:iid/:rid/observe') | |
.put((req, res, next) => { | |
const { oid, iid, rid } = req.params; | |
req.qnode.observeReq(`${oid}/${iid}/${rid}`, (err, rsp) => { | |
if (err) return next(err); | |
const { status, data } = rsp; | |
res.status(ch(status)).json(data); | |
}); | |
}) | |
.delete((req, res, next) => { | |
const { oid, iid, rid } = req.params; | |
req.qnode.writeAttrsReq(`${oid}/${iid}/${rid}`, { | |
cancel: true | |
}, (err, rsp) => { | |
if (err) return next(err); | |
const { status, data } = rsp; | |
res.status(ch(status)).json(data); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const MqttShepherd = require('mqtt-shepherd'); | |
const debug = require('debug')('dm:lwm2m'); | |
const qserver = new MqttShepherd('device_manager', { | |
port: 1883 | |
}); | |
qserver.on('ready', function () { | |
debug('MQTT server ready.'); | |
qserver.permitJoin(180); | |
}); | |
qserver.on('message', function (topic, message, packet) { | |
debug(topic, message); | |
}); | |
module.exports = qserver; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// TODO https://tools.ietf.org/html/draft-ietf-core-http-mapping-13#section-7 | |
module.exports = code => coap_http[code]; | |
const coap_http = { | |
201: 201, // Created | |
202: 200, // OK | |
203: 304, // Not Modified | |
204: 200, // OK | |
205: 200, // OK | |
400: 400, // Bad Request | |
401: 403, // Forbidden | |
402: 400, // Bad Request | |
403: 403, // Forbidden | |
404: 404, // Not Found | |
405: 400, // Bad Request | |
406: 406, // Not Acceptable | |
412: 412, // Precondition Failed | |
413: 413, // Request Repr. Too Large | |
415: 415, // Unsupported Media Type | |
500: 500, // Internal Server Error | |
501: 501, // Not Implemented | |
502: 502, // Bad Gateway | |
503: 503, // Service Unavailable | |
504: 504, // Gateway Timeout | |
505: 502 // Bad Gateway | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment