diff --git a/acs.coffee b/acs.coffee index 4b66085..19ec12b 100644 --- a/acs.coffee +++ b/acs.coffee @@ -102,6 +102,13 @@ updateDevice = (currentRequest, actions, callback) -> updates["#{path}_writable"] = p[1] if p[1]? updates["#{path}_timestamp"] = now + if actions.customCommands? + for p in actions.customCommands + commandName = p[0] + updates["_customCommands.#{commandName}._value"] = p[1] + updates["_customCommands.#{commandName}._timestamp"] = now + updates["_customCommands.#{commandName}._commands"] = p[2] if p[2]? + if Object.keys(updates).length > 0 or Object.keys(deletes).length > 0 db.devicesCollection.update({'_id' : currentRequest.deviceId}, {'$set' : updates, '$unset' : deletes}, {}, (err, count) -> if (err) diff --git a/config.coffee b/config.coffee index 5c9e453..4b2781c 100644 --- a/config.coffee +++ b/config.coffee @@ -49,3 +49,5 @@ exports.ALIASES = aliases # load authentication scripts exports.auth = require('./config/auth') + +exports.CUSTOM_COMMANDS = require('./config/custom_commands') diff --git a/config/custom_commands-sample.json b/config/custom_commands-sample.json new file mode 100644 index 0000000..b9200a0 --- /dev/null +++ b/config/custom_commands-sample.json @@ -0,0 +1,3 @@ +{ + "seowon_frequencies" : "/^[0-9]+\\-SWU\\%2D9200\\-[0-9A-Z]+$/" +} diff --git a/customCommands.coffee b/customCommands.coffee new file mode 100644 index 0000000..6f7f3b3 --- /dev/null +++ b/customCommands.coffee @@ -0,0 +1,17 @@ +common = require './common' + +exports.execute = (deviceId, command, callback) -> + args = command.split(/\s+/) + f = args.shift() + c = args.shift() + + file = require "./config/custom_commands/#{f}" + file[c](deviceId, args.join(' '), callback) + + +exports.getCommands = (filename) -> + commands = [] + f = require("./config/custom_commands/#{filename}") + for k,v of f + commands.push(k) + return commands diff --git a/tasks.coffee b/tasks.coffee index 8f7f1a5..e833295 100644 --- a/tasks.coffee +++ b/tasks.coffee @@ -2,6 +2,7 @@ config = require './config' common = require './common' db = require './db' mongodb = require 'mongodb' +customCommands = require './customCommands' BATCH_SIZE = 16 exports.STATUS_QUEUED = STATUS_QUEUED = 0 @@ -11,12 +12,25 @@ exports.STATUS_FAULT = STATUS_FAULT = 3 exports.STATUS_FINISHED = STATUS_FINISHED = 4 +initCustomCommands = (deviceId, callback) -> + updates = {customCommands : []} + counter = 0 + for k,v of config.CUSTOM_COMMANDS + if eval(v).test(deviceId) + ++counter + customCommands.execute(deviceId, "#{k} init", (err, value) -> + updates.customCommands.push([k, value, customCommands.getCommands(k)]) + callback(updates) if --counter <= 0 + ) + callback(updates) if counter <= 0 + + this.init = (task, methodResponse, callback) -> if not task.subtask? task.subtask = {device : task.device, name : 'getParameterNames', parameterPath : '', nextLevel : false} if task.subtask.name == 'getParameterNames' - if methodResponse.faultcode? + if methodResponse.faultcode? task.fault = methodResponse callback(null, STATUS_FAULT) return @@ -42,7 +56,13 @@ this.init = (task, methodResponse, callback) -> # Ignore GetParameterValues errors. A workaround for the crappy Seewon devices. methodResponse = {parameterList : {}} this.getParameterValues(task.subtask, methodResponse, (err, status, cwmpResponse, deviceUpdates) -> - callback(err, status, cwmpResponse, deviceUpdates) + if status is STATUS_FINISHED + initCustomCommands(task.device, (updates) -> + common.extend(deviceUpdates, updates) + callback(err, status, cwmpResponse, deviceUpdates) + ) + else + callback(err, status, cwmpResponse, deviceUpdates) ) else throw Error('Unexpected subtask name') @@ -335,5 +355,17 @@ this.download = (task, methodResponse, callback) -> callback(null, STATUS_FINISHED) +this.customCommand = (task, methodResponse, callback) -> + # TODO implement timeout + customCommands.execute(task.device, task.command, (err, value) -> + if err? + task.fault = err + callback(null, STATUS_FAULT) + else + commandName = task.command.split(' ', 2)[0] + callback(null, STATUS_FINISHED, null, {customCommands : [[commandName, value]]}) + ) + + exports.task = (task, methodResponse, callback) -> this[task.name](task, methodResponse, callback)