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

    if (_errorRequestBufferLength(requestBuffer)) {
        return;
    }

    // build answer
    var dataBytes = parseInt((length - 1) / 8 + 1);
    var responseBuffer = Buffer.alloc(3 + dataBytes + 2);
    try {
        responseBuffer.writeUInt8(dataBytes, 2);
    }
    catch (err) {
        callback(err);
        return;
    }

    var vectorCB;
    if(fc === 1)
        vectorCB = vector.getCoil;
    else if (fc === 2)
        vectorCB = vector.getDiscreteInput;

    // read coils
    if (vectorCB) {
        var callbackInvoked = false;
        var cbCount = 0;
        var buildCb = function(i) {
            return function(err, value) {
                if (err) {
                    if (!callbackInvoked) {
                        callbackInvoked = true;
                        callback(err);
                    }

                    return;
                }

                cbCount = cbCount + 1;

                responseBuffer.writeBit(value, i % 8, 3 + parseInt(i / 8));

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

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

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

        for (var i = 0; i < length; i++) {
            var cb = buildCb(i);
            try {
                if (vectorCB.length === 3) {
                    vectorCB(address + i, unitID, cb);
                }
                else {
                    var promiseOrValue = vectorCB(address + i, unitID);
                    _handlePromiseOrValue(promiseOrValue, cb);
                }
            }
            catch(err) {
                cb(err);
            }
        }
    }
}
function _handleReadCoilsOrInputDiscretes(requestBuffer, vector, unitID, callback, fc) {
    var address = requestBuffer.readUInt16BE(2);
    var length = requestBuffer.readUInt16BE(4);

    if (_errorRequestBufferLength(requestBuffer)) {
        return;
    }

    // build answer
    var dataBytes = parseInt((length - 1) / 8 + 1);
    var responseBuffer = Buffer.alloc(3 + dataBytes + 2);
    try {
        responseBuffer.writeUInt8(dataBytes, 2);
    }
    catch (err) {
        callback(err);
        return;
    }

    var vectorCB;
    if(fc === 1)
        vectorCB = vector.getCoil;
    else if (fc === 2)
        vectorCB = vector.getDiscreteInput;

    // read coils
    if (vectorCB) {
        var callbackInvoked = false;
        var cbCount = 0;
        var buildCb = function(i) {
            return function(err, value) {
                if (err) {
                    if (!callbackInvoked) {
                        callbackInvoked = true;
                        callback(err);
                    }

                    return;
                }

                cbCount = cbCount + 1;

                responseBuffer.writeBit(value, i % 8, 3 + parseInt(i / 8));

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

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

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

        for (var i = 0; i < length; i++) {
            var cb = buildCb(i);
            try {
                if (vectorCB.length === 3) {
                    vectorCB(address + i, unitID, cb);
                }
                else {
                    var promiseOrValue = vectorCB(address + i, unitID);
                    _handlePromiseOrValue(promiseOrValue, cb);
                }
            }
            catch(err) {
                cb(err);
            }
        }
    }
}
function _handleReadCoilsOrInputDiscretes ( requestBuffer , vector , unitID , callback , fc ) { var address = requestBuffer . readUInt16BE ( 2 ) ; var length = requestBuffer . readUInt16BE ( 4 ) ; if ( _errorRequestBufferLength ( requestBuffer ) ) { return ; } // build answer var dataBytes = parseInt ( ( length - 1 ) / 8 + 1 ) ; var responseBuffer = Buffer . alloc ( 3 + dataBytes + 2 ) ; try { responseBuffer . writeUInt8 ( dataBytes , 2 ) ; } catch ( err ) { callback ( err ) ; return ; } var vectorCB ; if ( fc === 1 ) vectorCB = vector . getCoil ; else if ( fc === 2 ) vectorCB = vector . getDiscreteInput ; // read coils if ( vectorCB ) { var callbackInvoked = false ; var cbCount = 0 ; var buildCb = function ( i ) { return function ( err , value ) { if ( err ) { if ( ! callbackInvoked ) { callbackInvoked = true ; callback ( err ) ; } return ; } cbCount = cbCount + 1 ; responseBuffer . writeBit ( value , i % 8 , 3 + parseInt ( i / 8 ) ) ; if ( cbCount === length && ! callbackInvoked ) { modbusSerialDebug ( { action : "FC" + fc + " response" , responseBuffer : responseBuffer } ) ; callbackInvoked = true ; callback ( null , responseBuffer ) ; } } ; } ; if ( length === 0 ) callback ( { modbusErrorCode : 0x02 , // Illegal address msg : "Invalid length" } ) ; for ( var i = 0 ; i < length ; i ++ ) { var cb = buildCb ( i ) ; try { if ( vectorCB . length === 3 ) { vectorCB ( address + i , unitID , cb ) ; } else { var promiseOrValue = vectorCB ( address + i , unitID ) ; _handlePromiseOrValue ( promiseOrValue , cb ) ; } } catch ( err ) { cb ( err ) ; } } } }
Function to handle FC1 or FC2 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 FC1 or FC2 request .