예제 #1
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);
        }