async forwardOpen() {
        const { FORWARD_OPEN } = CIP.MessageRouter.services;
        const { LOGICAL } = CIP.EPATH.segments;
        const { owner, connectionType, fixedVar, priority} = CIP.ConnectionManager;

        // Build Connection Manager Object Logical Path Buffer
        const cmPath = Buffer.concat([
            LOGICAL.build(LOGICAL.types.ClassID, 0x06), // Connection Manager Object (0x01)
            LOGICAL.build(LOGICAL.types.InstanceID, 0x01) // Instance ID (0x01)
        ]);

        // Message Router to Embed in UCMM
        const MR = CIP.MessageRouter.build(FORWARD_OPEN, cmPath, []);

        // Create connection parameters
        const paramsOT = CIP.ConnectionManager.build_connectionParameters(owner.Exclusive, connectionType.PointToPoint, priority.Scheduled, fixedVar.Fixed, 6 + this.outputInstance.size);
        const paramsTO = CIP.ConnectionManager.build_connectionParameters(owner.Exclusive, connectionType.PointToPoint, priority.Scheduled, fixedVar.Fixed, 2 + this.inputInstance.size);
        

        this.state.fwd_open_serial = getRandomInt(32767);
        const forwardOpenData = CIP.ConnectionManager.build_forwardOpen(this.state.rpi * 1000, paramsOT, 1000 , 32, this.state.fwd_open_serial);

        // Build MR Path in order to send the message to the CPU
        const mrPath = Buffer.concat([
            LOGICAL.build(LOGICAL.types.ClassID, 0x02), // Message Router Object (0x02)
            LOGICAL.build(LOGICAL.types.InstanceID, 0x01) // Instance ID (0x01)
        ]);

        const ioPath = this._ioPath();
        
        // This is the Connection Path data unit (Vol.1 Table 3-5.21)
        const connectionPath = Buffer.concat([
            Buffer.from([Math.ceil(ioPath.length/2)]), //Path size in WORDS
            ioPath
        ]);

        // Next 2 lines change the result of CIP.ConnectionManager.build_forwardOpen
        forwardOpenData.writeUInt8(1, 34);  // Change to Class 1 
        forwardOpenData.writeUInt16LE(paramsTO, 32); // Change T=>O connection parameters

        const forwardOpenPacket = Buffer.concat([
            MR,
            forwardOpenData,
            connectionPath
        ]);

        super.establishing_conn = true;
        super.established_conn = false;

        super.write_cip(forwardOpenPacket); // We need to bypass unconnected send for now

        const readPropsErr = new Error("TIMEOUT occurred while trying forwardOpen Request.");
        
        // Wait for Response
        const data = await promiseTimeout(
            new Promise((resolve, reject) => {
                this.on("Forward Open", (err, data) => {
                    if (err) reject(err);
                    resolve(data);
                });
            }),
            this.state.timeout_sp,
            readPropsErr
        );

        this.removeAllListeners("Forward Open");
        
        const OTconnID = data.readUInt32LE(0); // first 4 Bytes are O->T connection ID 
        
        super.id_conn = OTconnID;
        super.established_conn = true;
        super.establishing_conn = false;
        this.TOconnectionID = forwardOpenData.readUInt32LE(6);
        this.OTconnectionID = OTconnID;
        return OTconnID;       
    }
/**
     * Writes a forwardOpen Request and retrieves the connection ID used for
     * connected messages.
     * @memberof Controller
     * @returns {Promise}
     */
Writes a forwardOpen Request and retrieves the connection ID used for
connected messages.
@memberof Controller
@returns {Promise}
Writes a forwardOpen Request and retrieves the connection ID used for connected messages . @memberof Controller @returns { Promise }
async forwardOpen() {
        const { FORWARD_OPEN } = CIP.MessageRouter.services;
        const { LOGICAL } = CIP.EPATH.segments;
        const { owner, connectionType, fixedVar, priority} = CIP.ConnectionManager;
        const cmPath = Buffer.concat([
            LOGICAL.build(LOGICAL.types.ClassID, 0x06), 
            LOGICAL.build(LOGICAL.types.InstanceID, 0x01) 
        ]);
        const MR = CIP.MessageRouter.build(FORWARD_OPEN, cmPath, []);
        const paramsOT = CIP.ConnectionManager.build_connectionParameters(owner.Exclusive, connectionType.PointToPoint, priority.Scheduled, fixedVar.Fixed, 6 + this.outputInstance.size);
        const paramsTO = CIP.ConnectionManager.build_connectionParameters(owner.Exclusive, connectionType.PointToPoint, priority.Scheduled, fixedVar.Fixed, 2 + this.inputInstance.size);
        this.state.fwd_open_serial = getRandomInt(32767);
        const forwardOpenData = CIP.ConnectionManager.build_forwardOpen(this.state.rpi * 1000, paramsOT, 1000 , 32, this.state.fwd_open_serial);
        const mrPath = Buffer.concat([
            LOGICAL.build(LOGICAL.types.ClassID, 0x02), 
            LOGICAL.build(LOGICAL.types.InstanceID, 0x01) 
        ]);
        const ioPath = this._ioPath();
        const connectionPath = Buffer.concat([
            Buffer.from([Math.ceil(ioPath.length/2)]), 
            ioPath
        ]);
        forwardOpenData.writeUInt8(1, 34);  
        forwardOpenData.writeUInt16LE(paramsTO, 32); 
        const forwardOpenPacket = Buffer.concat([
            MR,
            forwardOpenData,
            connectionPath
        ]);
        super.establishing_conn = true;
        super.established_conn = false;
        super.write_cip(forwardOpenPacket); 
        const readPropsErr = new Error("TIMEOUT occurred while trying forwardOpen Request.");
        const data = await promiseTimeout(
            new Promise((resolve, reject) => {
                this.on("Forward Open", (err, data) => {
                    if (err) reject(err);
                    resolve(data);
                });
            }),
            this.state.timeout_sp,
            readPropsErr
        );
        this.removeAllListeners("Forward Open");
        const OTconnID = data.readUInt32LE(0); 
        super.id_conn = OTconnID;
        super.established_conn = true;
        super.establishing_conn = false;
        this.TOconnectionID = forwardOpenData.readUInt32LE(6);
        this.OTconnectionID = OTconnID;
        return OTconnID;       
    }
async forwardOpen ( ) { const { FORWARD_OPEN } = CIP . MessageRouter . services ; const { LOGICAL } = CIP . EPATH . segments ; const { owner , connectionType , fixedVar , priority } = CIP . ConnectionManager ; const cmPath = Buffer . concat ( [ LOGICAL . build ( LOGICAL . types . ClassID , 0x06 ) , LOGICAL . build ( LOGICAL . types . InstanceID , 0x01 ) ] ) ; const MR = CIP . MessageRouter . build ( FORWARD_OPEN , cmPath , [ ] ) ; const paramsOT = CIP . ConnectionManager . build_connectionParameters ( owner . Exclusive , connectionType . PointToPoint , priority . Scheduled , fixedVar . Fixed , 6 + this . outputInstance . size ) ; const paramsTO = CIP . ConnectionManager . build_connectionParameters ( owner . Exclusive , connectionType . PointToPoint , priority . Scheduled , fixedVar . Fixed , 2 + this . inputInstance . size ) ; this . state . fwd_open_serial = getRandomInt ( 32767 ) ; const forwardOpenData = CIP . ConnectionManager . build_forwardOpen ( this . state . rpi * 1000 , paramsOT , 1000 , 32 , this . state . fwd_open_serial ) ; const mrPath = Buffer . concat ( [ LOGICAL . build ( LOGICAL . types . ClassID , 0x02 ) , LOGICAL . build ( LOGICAL . types . InstanceID , 0x01 ) ] ) ; const ioPath = this . _ioPath ( ) ; const connectionPath = Buffer . concat ( [ Buffer . from ( [ Math . ceil ( ioPath . length / 2 ) ] ) , ioPath ] ) ; forwardOpenData . writeUInt8 ( 1 , 34 ) ; forwardOpenData . writeUInt16LE ( paramsTO , 32 ) ; const forwardOpenPacket = Buffer . concat ( [ MR , forwardOpenData , connectionPath ] ) ; super . establishing_conn = true ; super . established_conn = false ; super . write_cip ( forwardOpenPacket ) ; const readPropsErr = new Error ( "TIMEOUT occurred while trying forwardOpen Request." ) ; const data = await promiseTimeout ( new Promise ( ( resolve , reject ) => { this . on ( "Forward Open" , ( err , data ) => { if ( err ) reject ( err ) ; resolve ( data ) ; } ) ; } ) , this . state . timeout_sp , readPropsErr ) ; this . removeAllListeners ( "Forward Open" ) ; const OTconnID = data . readUInt32LE ( 0 ) ; super . id_conn = OTconnID ; super . established_conn = true ; super . establishing_conn = false ; this . TOconnectionID = forwardOpenData . readUInt32LE ( 6 ) ; this . OTconnectionID = OTconnID ; return OTconnID ; }
Writes a forwardOpen Request and retrieves the connection ID used for
 connected messages.
Writes a forwardOpen Request and retrieves the connection ID used for connected messages .
// Build Connection Manager Object Logical Path Buffer // Connection Manager Object (0x01) // Instance ID (0x01) // Message Router to Embed in UCMM // Create connection parameters // Build MR Path in order to send the message to the CPU // Message Router Object (0x02) // Instance ID (0x01) // This is the Connection Path data unit (Vol.1 Table 3-5.21) //Path size in WORDS // Next 2 lines change the result of CIP.ConnectionManager.build_forwardOpen // Change to Class 1  // Change T=>O connection parameters // We need to bypass unconnected send for now // Wait for Response // first 4 Bytes are O->T connection ID 