Skip to content

Commit

Permalink
- Added test for chopped tcp data on the tcp client.
Browse files Browse the repository at this point in the history
- Refactored modbus-tcp-client, this module now
  server the tcp client logic while the client core and
  tcp client get composed in the modbus.js file.
  • Loading branch information
stefanpoeter committed Nov 25, 2016
1 parent 164ac85 commit 962c273
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 24 deletions.
35 changes: 19 additions & 16 deletions src/modbus-tcp-client.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
'use strict'

var stampit = require('stampit')
var Net = require('net')
var ModbusCore = require('./modbus-client-core.js')

module.exports = stampit()
.compose(ModbusCore)
.init(function () {
var reqId = 0
var currentRequestId = reqId
var closedOnPurpose = false
var reconnect = false
var trashRequestId
var buffer = Buffer.alloc(0)
var socket

var init = function () {
Expand All @@ -35,8 +33,13 @@ module.exports = stampit()
this.setState('connect')

if (!socket) {
socket = new Net.Socket()

/* for testing you are able to inject a mocking object
* a simple event object should do the trick */
if (this.injectedSocket) {
socket = this.injectedSocket
} else {
socket = require('net').Socket()
}
socket.on('connect', onSocketConnect)
socket.on('close', onSocketClose)
socket.on('error', onSocketError)
Expand Down Expand Up @@ -76,37 +79,37 @@ module.exports = stampit()
var onSocketData = function (data) {
this.log.debug('received data')

var cnt = 0
buffer = Buffer.concat([buffer, data])

while (cnt < data.length) {
while (buffer.length > 7) {
// 1. extract mbap

var mbap = data.slice(cnt, cnt + 7)
var id = mbap.readUInt16BE(0)
var len = mbap.readUInt16BE(4)
var id = buffer.readUInt16BE(0)
var len = buffer.readUInt16BE(4)

if (id === trashRequestId) {
this.log.debug('current mbap contains trashed request id.')

return
}

cnt += 7

this.log.debug('MBAP extracted')
/* Not all data received yet. */
if (buffer.length < 7 + len - 1) {
break
}

// 2. extract pdu

var pdu = data.slice(cnt, cnt + len - 1)

cnt += pdu.length
var pdu = buffer.slice(7, 7 + len - 1)

this.log.debug('PDU extracted')

// emit data event and let the
// listener handle the pdu

this.emit('data', pdu)

buffer = buffer.slice(pdu.length + 7, buffer.length)
}
}.bind(this)

Expand Down
10 changes: 5 additions & 5 deletions src/modbus-tcp-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@ module.exports = stampit()
var initiateSocket = function (socket) {
let socketId = socketList.length

let requestHandler = function (req) {
var requestHandler = function (req) {
fifo.push(req)
flush()
}

let removeHandler = function () {
var removeHandler = function () {
socketList[socketId] = undefined
/* remove undefined on the end of the array */
for (let i = socketList.length - 1; i >= 0; i -= 1) {
Expand All @@ -97,8 +97,8 @@ module.exports = stampit()

socketList.splice(i, 1)
}
console.log(socketList)
}
this.log.debug('Client connection closed, remaining clients. ', socketList.length)
}.bind(this)

let clientSocket = ClientSocket({
socket: socket,
Expand All @@ -108,7 +108,7 @@ module.exports = stampit()
})

socketList.push(clientSocket)
}
}.bind(this)

this.close = function (cb) {
for (var c in clients) {
Expand Down
6 changes: 4 additions & 2 deletions src/modbus.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

var fs = require('fs')
var path = require('path')
var ModbusCore = require('./modbus-client-core.js')
var ModbusTcpClient = require('./modbus-tcp-client.js')

exports.client = {
tcp: {
core: require('./modbus-tcp-client.js'),
complete: require('./modbus-tcp-client.js')
core: ModbusCore.compose(ModbusTcpClient),
complete: ModbusCore.compose(ModbusTcpClient)
},
serial: {
core: require('./modbus-serial-client.js'),
Expand Down
44 changes: 43 additions & 1 deletion test/modbus-tcp.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ var assert = require('assert')
var EventEmitter = require('events')

describe('Modbus TCP Tests.', function () {
describe('Chopped Data Tests (Server Side).', function () {
describe('Server Tests.', function () {
/* We are using the read coils request for the chopped data tests. */

let ClientSocket = require('../src/modbus-tcp-server-client.js')
Expand Down Expand Up @@ -47,4 +47,46 @@ describe('Modbus TCP Tests.', function () {
})
})
})

describe('Client Tests.', function () {
var stampit = require('stampit')
var StateMachine = require('stampit-state-machine')
var Logger = require('stampit-log')

it('should handle a chopped data request fine.', function (done) {
var ModbusTcpClient = require('../src/modbus-tcp-client.js')
var injectedSocket = new EventEmitter()
var exResponse = Buffer.from([0x01, 0x02, 0x055, 0x01])

/* dummy method */
injectedSocket.connect = function () { }

/* create the client by composing
* logger, state machine and the tcp client,
* normally the logger and the state machine
* come with the modbus client core. */
var client = stampit()
.compose(Logger)
.compose(StateMachine)
.compose(ModbusTcpClient)({
injectedSocket: injectedSocket
})

/* connect to whatever and confirm */
client.connect()

injectedSocket.emit('connect')

/* fetch send data and compare */
client.on('data', function (data) {
assert.equal(data.compare(exResponse), 0)
done()
})

/* Send header data */
injectedSocket.emit('data', Buffer.from([0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x01]))
/* emitting a read coils request (start = 0, count = 10) */
injectedSocket.emit('data', Buffer.from([0x01, 0x02, 0x55, 0x01]))
})
})
})

0 comments on commit 962c273

Please sign in to comment.