Exemple #1
0
        /// <summary>
        /// Connect to Lego RCX brick.
        /// </summary>
        ///
        /// <param name="towerType">Type of IR tower to use for communication with RCX brick.</param>
        ///
        /// <returns>Returns <b>true</b> on successful connection or <b>false</b>
        /// otherwise.</returns>
        ///
        /// <remarks>If connection to RCX brick was established before the call, existing connection will be reused.
        /// If it is required to force reconnection, then <see cref="Disconnect"/> method should be called before.
        /// </remarks>
        ///
        public bool Connect(IRTowerType towerType)
        {
            lock ( sync )
            {
                // check if we are already connected
                if (stack != IntPtr.Zero)
                {
                    return(true);
                }

                uint status;

                // create stack
                status = GhostAPI.GhCreateStack(
                    (towerType == IRTowerType.USB) ? "LEGO.Pbk.CommStack.Port.USB" : "LEGO.Pbk.CommStack.Port.RS232",
                    "LEGO.Pbk.CommStack.Protocol.IR",
                    "LEGO.Pbk.CommStack.Session",
                    out stack);

                if (!GhostAPI.PBK_SUCCEEDED(status))
                {
                    return(false);
                }

                // select first available device
                StringBuilder sb = new StringBuilder(200);
                status = GhostAPI.GhSelectFirstDevice(stack, sb, sb.Length);

                if (!GhostAPI.PBK_SUCCEEDED(status))
                {
                    Disconnect( );
                    return(false);
                }

                // open stack, set interleave, set wait mode and check if the brick is alive
                if (
                    !GhostAPI.PBK_SUCCEEDED(GhostAPI.GhOpen(stack)) ||
                    !GhostAPI.PBK_SUCCEEDED(GhostAPI.GhSetWaitMode(stack, IntPtr.Zero)) ||
                    !GhostAPI.PBK_SUCCEEDED(GhostAPI.GhSetInterleave(stack, 1, 0)) ||
                    !IsAlive( )
                    )
                {
                    Disconnect( );
                    return(false);
                }
            }

            return(true);
        }
Exemple #2
0
        /// <summary>
        /// Send command to Lego RCX brick and read reply.
        /// </summary>
        ///
        /// <param name="command">Command to send.</param>
        /// <param name="reply">Buffer to receive reply into.</param>
        /// <param name="expectedReplyLen">Expected reply length.</param>
        ///
        /// <returns>Returns <b>true</b> if the command was sent successfully and reply was
        /// received, otherwise <b>false</b>.</returns>
        ///
        /// <exception cref="NullReferenceException">Communication can not be performed, because connection with
        /// RCX brick was not established yet.</exception>
        /// <exception cref="ArgumentException">Reply buffer size is smaller than the reply data size.</exception>
        /// <exception cref="ApplicationException">Reply does not correspond to command (first byte of reply
        /// should be complement (bitwise NOT) to the first byte of command orred with 0x08).</exception>
        ///
        protected bool SendCommand(byte[] command, byte[] reply, int expectedReplyLen)
        {
            bool   result = false;
            uint   status;
            IntPtr queue;

            lock ( sync )
            {
                // check if GhostAPI stack was created (if device is connected)
                if (stack == IntPtr.Zero)
                {
                    throw new NullReferenceException("Not connected to RCX brick");
                }

                // create command queue
                status = GhostAPI.GhCreateCommandQueue(out queue);

                if (!GhostAPI.PBK_SUCCEEDED(status))
                {
                    return(false);
                }

                // append command to the queue
                status = GhostAPI.GhAppendCommand(queue, command, command.Length, expectedReplyLen);

                if (GhostAPI.PBK_SUCCEEDED(status))
                {
                    // execute command
                    status = GhostAPI.GhExecute(stack, queue);

                    if (GhostAPI.PBK_SUCCEEDED(status))
                    {
                        IntPtr commandHandle;
                        uint   replyLen;

                        // get first command and its reply data lenght
                        if (
                            (GhostAPI.PBK_SUCCEEDED(GhostAPI.GhGetFirstCommand(queue, out commandHandle))) &&
                            (GhostAPI.PBK_SUCCEEDED(GhostAPI.GhGetCommandReplyLen(commandHandle, out replyLen)))
                            )
                        {
                            // check provided reply buffer size
                            if (reply.Length < replyLen)
                            {
                                throw new ArgumentException("Reply buffer is too small");
                            }

                            // get reply data
                            status = GhostAPI.GhGetCommandReply(commandHandle, reply, replyLen);

                            if (GhostAPI.PBK_SUCCEEDED(status))
                            {
                                // check that reply corresponds to command
                                if ((command[0] | 0x08) != (byte)~reply[0])
                                {
                                    throw new ApplicationException("Reply does not correspond to command");
                                }

                                result = true;
                            }
                        }
                    }
                }

                // destroy command queue
                GhostAPI.GhDestroyCommandQueue(queue);
            }

            return(result);
        }