servers/servertcp_handler.js
function _handleWriteMultipleRegisters(requestBuffer, vector, unitID, callback) {
    var address = requestBuffer.readUInt16BE(2);
    var length = requestBuffer.readUInt16BE(4);

    // if length is bad, ignore message
    if (requestBuffer.length !== (7 + length * 2 + 2)) {
        return;
    }

    // build answer
    var responseBuffer = Buffer.alloc(8);
    responseBuffer.writeUInt16BE(address, 2);
    responseBuffer.writeUInt16BE(length, 4);

    // write registers
    var callbackInvoked = false;
    var cbCount = 0;
    var buildCb = function(/* i - not used at the moment */) {
        return function(err) {
            if (err) {
                if (!callbackInvoked) {
                    callbackInvoked = true;
                    callback(err);
                }

                return;
            }

            cbCount = cbCount + 1;

            if (cbCount === length && !callbackInvoked) {
                modbusSerialDebug({ action: "FC16 response", responseBuffer: responseBuffer });

                callbackInvoked = true;
                callback(null, responseBuffer);
            }
        };
    };

    if (length === 0)
        callback({
            modbusErrorCode: 0x02, // Illegal address
            msg: "Invalid length"
        });

    if (vector.setRegister) {
        var value;

        for (var i = 0; i < length; i++) {
            var cb = buildCb(i);
            value = requestBuffer.readUInt16BE(7 + i * 2);

            try {
                if (vector.setRegister.length === 4) {
                    vector.setRegister(address + i, value, unitID, cb);
                }
                else {
                    var promiseOrValue = vector.setRegister(address + i, value, unitID);
                    _handlePromiseOrValue(promiseOrValue, cb);
                }
            }
            catch(err) {
                cb(err);
            }
        }
    } else if (vector.setRegisterArray) {
        value = [];

        for (i = 0; i < length; i++) {
            cb = buildCb(i);

            value.push(requestBuffer.readUInt16BE(7 + i * 2));
            _handlePromiseOrValue(value, cb);
        }

        try {
            if (vector.setRegisterArray.length === 6) {
                vector.setRegisterArray(address, value, unitID, cb);
            }
            else {
                vector.setRegisterArray(address, value, unitID);
            }
        }
        catch (err) {
            cb(err);
        }
    }
}
function _handleWriteMultipleRegisters(requestBuffer, vector, unitID, callback) {
    var address = requestBuffer.readUInt16BE(2);
    var length = requestBuffer.readUInt16BE(4);

    // if length is bad, ignore message
    if (requestBuffer.length !== (7 + length * 2 + 2)) {
        return;
    }

    // build answer
    var responseBuffer = Buffer.alloc(8);
    responseBuffer.writeUInt16BE(address, 2);
    responseBuffer.writeUInt16BE(length, 4);

    // write registers
    var callbackInvoked = false;
    var cbCount = 0;
    var buildCb = function(/* i - not used at the moment */) {
        return function(err) {
            if (err) {
                if (!callbackInvoked) {
                    callbackInvoked = true;
                    callback(err);
                }

                return;
            }

            cbCount = cbCount + 1;

            if (cbCount === length && !callbackInvoked) {
                modbusSerialDebug({ action: "FC16 response", responseBuffer: responseBuffer });

                callbackInvoked = true;
                callback(null, responseBuffer);
            }
        };
    };

    if (length === 0)
        callback({
            modbusErrorCode: 0x02, // Illegal address
            msg: "Invalid length"
        });

    if (vector.setRegister) {
        var value;

        for (var i = 0; i < length; i++) {
            var cb = buildCb(i);
            value = requestBuffer.readUInt16BE(7 + i * 2);

            try {
                if (vector.setRegister.length === 4) {
                    vector.setRegister(address + i, value, unitID, cb);
                }
                else {
                    var promiseOrValue = vector.setRegister(address + i, value, unitID);
                    _handlePromiseOrValue(promiseOrValue, cb);
                }
            }
            catch(err) {
                cb(err);
            }
        }
    } else if (vector.setRegisterArray) {
        value = [];

        for (i = 0; i < length; i++) {
            cb = buildCb(i);

            value.push(requestBuffer.readUInt16BE(7 + i * 2));
            _handlePromiseOrValue(value, cb);
        }

        try {
            if (vector.setRegisterArray.length === 6) {
                vector.setRegisterArray(address, value, unitID, cb);
            }
            else {
                vector.setRegisterArray(address, value, unitID);
            }
        }
        catch (err) {
            cb(err);
        }
    }
}
function _handleWriteMultipleRegisters ( requestBuffer , vector , unitID , callback ) { var address = requestBuffer . readUInt16BE ( 2 ) ; var length = requestBuffer . readUInt16BE ( 4 ) ; // if length is bad, ignore message if ( requestBuffer . length !== ( 7 + length * 2 + 2 ) ) { return ; } // build answer var responseBuffer = Buffer . alloc ( 8 ) ; responseBuffer . writeUInt16BE ( address , 2 ) ; responseBuffer . writeUInt16BE ( length , 4 ) ; // write registers var callbackInvoked = false ; var cbCount = 0 ; var buildCb = function ( /* i - not used at the moment */ ) { return function ( err ) { if ( err ) { if ( ! callbackInvoked ) { callbackInvoked = true ; callback ( err ) ; } return ; } cbCount = cbCount + 1 ; if ( cbCount === length && ! callbackInvoked ) { modbusSerialDebug ( { action : "FC16 response" , responseBuffer : responseBuffer } ) ; callbackInvoked = true ; callback ( null , responseBuffer ) ; } } ; } ; if ( length === 0 ) callback ( { modbusErrorCode : 0x02 , // Illegal address msg : "Invalid length" } ) ; if ( vector . setRegister ) { var value ; for ( var i = 0 ; i < length ; i ++ ) { var cb = buildCb ( i ) ; value = requestBuffer . readUInt16BE ( 7 + i * 2 ) ; try { if ( vector . setRegister . length === 4 ) { vector . setRegister ( address + i , value , unitID , cb ) ; } else { var promiseOrValue = vector . setRegister ( address + i , value , unitID ) ; _handlePromiseOrValue ( promiseOrValue , cb ) ; } } catch ( err ) { cb ( err ) ; } } } else if ( vector . setRegisterArray ) { value = [ ] ; for ( i = 0 ; i < length ; i ++ ) { cb = buildCb ( i ) ; value . push ( requestBuffer . readUInt16BE ( 7 + i * 2 ) ) ; _handlePromiseOrValue ( value , cb ) ; } try { if ( vector . setRegisterArray . length === 6 ) { vector . setRegisterArray ( address , value , unitID , cb ) ; } else { vector . setRegisterArray ( address , value , unitID ) ; } } catch ( err ) { cb ( err ) ; } } }
Function to handle FC16 request.

@param requestBuffer - request Buffer from client
@param vector - vector of functions for read and write
@param unitID - Id of the requesting unit
@param {function} callback - callback to be invoked passing {Buffer} response
@returns undefined
@private
Function to handle FC16 request .