/// <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); }