network/websocket_cmd_stream/resources/src/js/gos_ws_cmd_api.js

var GosWsCmdApi = function () {
var context = {}
/** -----------------------------
* Private variables
*/
var ws = WebsocketMsgPack()
var STATUS_CODE = {
SUCCESS: 0,
FAILED: 1,
PARSE_ERROR: 2,
UNKNOWN: 3,
TOO_FEW_ARGS: 4,
TOO_MANY_ARGS: 5,
UNKNOWN_OPTION: 6,
BAD_ARGS: 7,
BUFFER_OVERFLOW: 8,
BOUNDS_ERROR: 9
}
var nextRequestId = 0
var pendingRequests = {}
var logger = Logger('[WSCMD] ')
/** -----------------------------
* Public variables
*/
context.onConnected = null
context.onDisconnected = null
/** -----------------------------
* Public methods
*/
/**
*
*/
context.isConnected = function() {
return ws.isConnected()
}
/**
* Open connection
*/
context.open = function(host) {
if(!ws.isConnected()) {
logger.info('Opening connection to ' + host + ' ...')
ws.open(host + '/cmdstream')
}
}
/**
* Close connection
*/
context.close = function() {
logger.info('Closing connection ...')
ws.close()
}
/**
* Issue a command to the device
*
* The `config` is optional and has the following params:
* config.timeout - time in milliseconds to wait for response (default 7000)
* config.data - optional binary data (e.g.: used for writing file data)
* config.bin_response - return the response data as ByteArray, otherwise a string is returned
*/
context.issue = function(cmd, handler, config) {
sendCommand(cmd, handler, config)
}
/**
* Set the websocket reconnect period in milliseconds
*/
context.setReconnectPeriod = function(periodMs) {
ws.reconnectPeriod = periodMs
}
/**
* Set the logger
*/
context.setLogger = function(l) {
logger.setLogger(l)
}
/**
* Set the logger
*/
context.setMsgpackLogger = function(l) {
ws.setLogger(l)
}
/** -----------------------------
* Private methods
*/
/**
*
*/
var sendCommand = function(cmd, handler, config) {
config = config || {}
if(config.timeout === undefined || config.timeout === null) {
config.timeout = 7000
}
var request = {
id: getNextRequestId(),
command: cmd
}
if(config.data) {
request.data = config.data
}
logger.debug('TX request: ' + JSON.stringify(request))
try {
ws.send(request)
addPendingRequest(request, handler, config)
} catch(e) {
handler(false, new Error('Failed to send request, err: ' + e.message))
}
}
/**
*
*/
var getNextRequestId = function() {
var retval = nextRequestId
nextRequestId++
return retval
}
/**
*
*/
var addPendingRequest = function(request, handler, config) {
var onPendingRequestTimeout = function() {
popPendingRequest(request.id)
handler(false, new Error('Timed-out waiting for response from device'))
}
request.timer = setTimeout(onPendingRequestTimeout, config.timeout)
request.handler = handler
request.bin_response = config.bin_response
pendingRequests[request.id] = request
}
/**
*
*/
var popPendingRequest = function(msgId) {
var request = null
if(msgId in pendingRequests) {
request = pendingRequests[msgId]
delete pendingRequests[msgId]
if(request.timer) {
clearTimeout(request.timer)
request.timer = null
}
}
return request
}
/**
*
*/
ws.onMessage = function(msg) {
request = popPendingRequest(msg.id)
if(request) {
if(msg.code === STATUS_CODE.SUCCESS) {
var data
if(!request.bin_response) {
data = String.fromCharCode.apply(null, msg.response);
} else {
data = msg.response
}
request.handler(true, data)
} else {
var msg
if(msg.code === STATUS_CODE.FAILED) {
msg = ' The command failed'
} else if(msg.code === STATUS_CODE.PARSE_ERROR) {
msg = 'Failed to parse the command'
} else if(msg.code === STATUS_CODE.UNKNOWN) {
msg = 'Unknown command'
} else if(msg.code === STATUS_CODE.TOO_FEW_ARGS) {
msg = 'Not enough command arguments'
} else if(msg.code === STATUS_CODE.TOO_MANY_ARGS) {
msg = 'Too many command arguments'
} else if(msg.code === STATUS_CODE.UNKNOWN_OPTION) {
msg = 'Unknown option'
} else if(msg.code === STATUS_CODE.BAD_ARGS) {
msg = 'Invalid command arguments'
} else if(msg.code === STATUS_CODE.BUFFER_OVERFLOW) {
msg = 'Command buffer overflow'
} else if(msg.code === STATUS_CODE.BOUNDS_ERROR) {
msg = 'Command specific, the parameters of the command were exceeded'
} else {
msg = 'Unknown error while processing request'
}
request.handler(false, new Error(msg))
}
} else {
logger.debug('No pending request found for received response')
}
}
/**
*
*/
ws.onConnected = function() {
logger.info('Connected')
if(context.onConnected) {
context.onConnected()
}
}
/**
*
*/
ws.onDisconnected = function() {
logger.info('Disconnected')
while(Object.keys(pendingRequests).length > 0) {
var msgId = Object.keys(pendingRequests)[0]
var request = popPendingRequest(msgId)
request.handler(false, new Error('Connection closed, dropping request'))
}
if(context.onDisconnected) {
context.onDisconnected()
}
}
return context
}