MqttNode.prototype.initResrc = function (oid, iid, resrcs) { var self = this, okey; if (!_.isPlainObject(resrcs)) throw new TypeError('resrcs should be an object.'); okey = mutils.oidKey(oid); this.so[okey] = this.so[okey] || {}; this.so[okey][iid] = this.so[okey][iid] || {}; _.forEach(resrcs, function (r, rid) { var rkey; if (_.isFunction(r)) throw new TypeError('resource cannot be a function.'); rkey = mutils.ridKey(oid, rid); if (_.isObject(r)) r._isCb = _.isFunction(r.read) || _.isFunction(r.write) || _.isFunction(r.exec); self.so[okey][iid][rkey] = r; }); return this; };
MqttNode.prototype._getAttrs = function (oid, iid, rid) { var trg = this._target(oid, iid, rid), key, defaultAttrs; if (!trg.exist) return undefined; key = mutils.oidKey(oid); defaultAttrs = { pmin: this.so.lwm2mServer[0].defaultMinPeriod, pmax: this.so.lwm2mServer[0].defaultMaxPeriod, mute: true, cancel: true, lastRpVal: null }; if (trg.type === TTYPE.inst) key = key + ':' + iid; else if (trg.type === TTYPE.rsc) key = key + ':' + iid + ':' + mutils.ridKey(oid, rid); this._repAttrs[key] = this._repAttrs[key] || defaultAttrs; return this._repAttrs[key]; };
MqttNode.prototype._target = function (oid, iid, rid) { var okey = mutils.oidKey(oid), trg = { type: null, exist: this._has(oid, iid, rid), value: null }, rkey; if (!_.isNil(oid)) { trg.type = (oid === '') ? TTYPE.root : TTYPE.obj; if (!_.isNil(iid)) { trg.type = TTYPE.inst; if (!_.isNil(rid)) { trg.type = TTYPE.rsc; rkey = mutils.ridKey(oid, rid); } } } if (trg.exist) { if (trg.type === TTYPE.obj) trg.value = this.so[okey]; else if (trg.type === TTYPE.inst) trg.value = this.so[okey][iid]; else if (trg.type === TTYPE.rsc) trg.value = this.so[okey][iid][rkey]; } return trg; };
MqttNode.prototype._dumpObj = function (oid, iid, callback) { var self = this, okey = mutils.oidKey(oid), dump = {}, obj = this.so[okey], count = 0; if (_.isFunction(iid)) { callback = iid; iid = undefined; } if (_.isNil(obj)) { dump = null; callback(null, dump); } else if (_.isUndefined(iid)) { // dump object count = 0; _.forEach(obj, function (inst, ii) { dump[ii] = {}; _.forEach(inst, function (r, rid) { count += 1; }); }); _.forEach(obj, function (inst, ii) { _.forEach(inst, function (r, rid) { self._readResrc(oid, ii, rid, function (err, val) { dump[ii][mutils.ridNum(oid, rid)] = val; count -= 1; if (count === 0 && _.isFunction(callback)) callback(null, dump); }); }); }); } else { // dump instance count = 0; obj = this.so[okey][iid]; if (_.isNil(obj)) { dump = null; } else { _.forEach(obj, function (r, rid) { count += 1; }); _.forEach(obj, function (r, rid) { self._readResrc(oid, iid, rid, function (err, val) { dump[mutils.ridNum(oid, rid)] = val; count -= 1; if (count === 0 && _.isFunction(callback)) callback(null, dump); }); }); } } };
MqttNode.prototype._has = function (oid, iid, rid) { var okey = mutils.oidKey(oid), has = false, rkey; if (!_.isUndefined(oid)) { has = !_.isUndefined(this.so[okey]); if (has && !_.isUndefined(iid)) { has = !_.isUndefined(this.so[okey][iid]); if (has && !_.isUndefined(rid)) { rkey = mutils.ridKey(oid, rid); has = !_.isUndefined(this.so[okey][iid][rkey]); } } } return has; };
MqttNode.prototype.disableReport = function (oid, iid, rid) { var trg = this._target(oid, iid, rid), rAttrs = this._getAttrs(oid, iid, rid), okey = mutils.oidKey(oid), rpid, rRpt; if (!trg.exist) return false; if (trg.type === TTYPE.obj) rpid = okey; else if (trg.type === TTYPE.inst) rpid = okey + ':' + iid; else if (trg.type === TTYPE.rsc) rpid = okey + ':' + iid + ':' + mutils.ridKey(oid, rid); rRpt = this._reporters[rpid]; if (_.isNull(rAttrs)) return false; if (_.isUndefined(rRpt)) return true; rAttrs.cancel = true; rAttrs.mute = true; clearTimeout(rRpt.min); clearInterval(rRpt.max); clearInterval(rRpt.poller); rRpt.min = null; rRpt.max = null; rRpt.poller = null; rRpt = null; delete this._reporters[rpid]; return true; };
MqttNode.prototype._setAttrs = function (oid, iid, rid, attrs) { var okey = mutils.oidKey(oid), rkey, key, trg; if (arguments.length === 4) { rkey = mutils.ridKey(oid, rid); key = okey + ':' + iid + ':' + rkey; } else if (arguments.length === 3) { attrs = rid; rid = undefined; key = okey + ':' + iid; } else if (arguments.length === 2) { attrs = iid; iid = undefined; } if (!_.isPlainObject(attrs)) throw new TypeError('attrs should be given as an object.'); trg = this._target(oid, iid, rid); if (!trg.exist) return false; // attrs with default settings attrs.pmin = _.isNumber(attrs.pmin) ? attrs.pmin : this.so.lwm2mServer[0].defaultMinPeriod; attrs.pmax = _.isNumber(attrs.pmax) ? attrs.pmax : this.so.lwm2mServer[0].defaultMaxPeriod; attrs.mute = _.isBoolean(attrs.mute) ? attrs.mute : true; attrs.cancel = _.isBoolean(attrs.cancel) ? attrs.cancel : true; this._repAttrs[key] = attrs; return true; };
MqttNode.prototype.enableReport = function (oid, iid, rid) { var self = this, trg = this._target(oid, iid, rid), rAttrs = this._getAttrs(oid, iid, rid), okey = mutils.oidKey(oid), rkey, rpid, pmin, pmax, rRpt, dumper, notify; if (!trg.exist) return false; if (trg.type === TTYPE.obj) { rpid = okey; dumper = function (cb) { self._dumpObj(oid, cb); }; notify = { oid: mutils.oidNum(oid), data: null }; } else if (trg.type === TTYPE.inst) { rpid = okey + ':' + iid; dumper = function (cb) { self._dumpObj(oid, iid, cb); }; notify = { oid: mutils.oidNum(oid), iid: iid, data: null }; } else if (trg.type === TTYPE.rsc) { rkey = mutils.ridKey(oid, rid); rpid = okey + ':' + iid + ':' + rkey; dumper = function (cb) { self._readResrc(oid, iid, rid, cb); }; notify = { oid: mutils.oidNum(oid), iid: iid, rid: mutils.ridNum(rid), data: null }; } pmin = rAttrs.pmin * 1000; pmax = rAttrs.pmax * 1000; rAttrs.cancel = false; rAttrs.mute = true; this._reporters[rpid] = { min: null, max: null, poller: null }; rRpt = this._reporters[rpid]; // WE DONT USE POLLER AT THIS MOMENT, BUT KEEP THIS SNIPPET HERE // if (trg.type === TTYPE.rsc) { // rRpt.poller = setInterval(function () { // self._readResrc(oid, iid, rid); // just read it, helper._checkAndReportResrc() will be invoked // }, rAttrs.pintvl || 500); // } rRpt.min = setTimeout(function () { if (pmin === 0) { // if no pmin, just report at pmax triggered rAttrs.mute = false; } else { dumper(function (err, val) { rAttrs.mute = false; notify.data = val; self.pubNotify(notify); }); } }, pmin); rRpt.max = setInterval(function () { rAttrs.mute = true; dumper(function (err, val) { rAttrs.mute = false; notify.data = val; self.pubNotify(notify); }); if (!_.isNil(rRpt.min)) clearTimeout(rRpt.min); rRpt.min = null; rRpt.min = setTimeout(function () { if (pmin === 0) { rAttrs.mute = false; } else { dumper(function (err, val) { rAttrs.mute = false; notify.data = val; self.pubNotify(notify); }); } }, pmin); }, pmax); return true; };