static byte[] get_response(byte cmd_code, int reply_data_len, int timeout) { if (!response_event.WaitOne(timeout)) { throw new Exception("Command timed out"); } response_lock.WaitOne(); if (response_queue.Count < 0) { throw new Exception("reponse_queue.Count < 0"); } caPacket pack = (caPacket)response_queue.Dequeue(); if (response_queue.Count < 1) { // put threads on hold until new responses appear response_event.Reset(); } response_lock.ReleaseMutex(); // check packet contents if (pack.cmd_code != cmd_code) { // response queue messed up due to packet loss or logic fault throw new Exception("Unexpected response"); } if (pack.term != term_ack) { // adapter reported command failure due to parametre error in // last command or execution failed throw new Exception("Command failed"); } if (pack.data_len != reply_data_len) { // faulty program logic; packet damage not likely, ince command // code and terminator were in place throw new Exception("Unexpected response data length"); } return(pack.data_len > 0 ? pack.data : null); }
protected override void process_usb() { int byte_i; while (usb_queue.Count >= caPacket.min_size) { if (!pack_incomplete) { // read packet header in_pack.cmd_code = (byte)usb_queue.Dequeue(); in_pack.data_len = (ushort)(((byte)usb_queue.Dequeue() << 8) | (byte)usb_queue.Dequeue()); } if (usb_queue.Count <= in_pack.data_len) { // incomplete packet pack_incomplete = true; return; } if (in_pack.data_len > 0) { // read data block in_pack.data = new byte[in_pack.data_len]; Debug.Assert(in_pack.data != null); for (byte_i = 0; byte_i < in_pack.data_len; ++byte_i) { in_pack.data[byte_i] = (byte)usb_queue.Dequeue(); } } // teminator in_pack.term = (byte)usb_queue.Dequeue(); pack_incomplete = false; // got CAN frame if (in_pack.cmd_code == cmd_can_frame) { if (in_pack.data_len == 15) { // fill frame structure caCANFrame can_frame = new caCANFrame(); can_frame.id = (uint)BitConverter.ToInt32(in_pack.data, 0); can_frame.data = (ulong)BitConverter.ToInt64(in_pack.data, 4); can_frame.length = in_pack.data[12]; can_frame.is_extended = in_pack.data[13]; can_frame.is_remote = in_pack.data[14]; frame_lock.WaitOne(); // store frame in queue and notify waiting threads frame_queue.Enqueue(can_frame); frame_event.Set(); frame_lock.ReleaseMutex(); } } // got command response else { response_lock.WaitOne(); // save response packet and notify waiting threads caPacket new_pack = new caPacket(); new_pack.cmd_code = in_pack.cmd_code; new_pack.data = in_pack.data_len != 0 ? (byte[])in_pack.data.Clone() : null; new_pack.data_len = in_pack.data_len; new_pack.term = in_pack.term; response_queue.Enqueue(new_pack); response_event.Set(); response_lock.ReleaseMutex(); } } }
protected override void process_usb() { int byte_i; while (usb_queue.Count >= caPacket.min_size) { if (!pack_incomplete) { // read packet header in_pack.cmd_code = (byte)usb_queue.Dequeue(); in_pack.data_len = (ushort)(((byte)usb_queue.Dequeue() << 8) | (byte)usb_queue.Dequeue()); } if (usb_queue.Count <= in_pack.data_len) { // incomplete packet pack_incomplete = true; return; } if (in_pack.data_len > 0) { // read data block in_pack.data = new byte[in_pack.data_len]; Debug.Assert(in_pack.data != null); for (byte_i = 0; byte_i < in_pack.data_len; ++byte_i) { in_pack.data[byte_i] = (byte)usb_queue.Dequeue(); } } // teminator in_pack.term = (byte)usb_queue.Dequeue(); pack_incomplete = false; // got CAN frame if(in_pack.cmd_code == cmd_can_frame) { if(in_pack.data_len == 15) { // fill frame structure caCANFrame can_frame = new caCANFrame(); can_frame.id = (uint)BitConverter.ToInt32(in_pack.data, 0); can_frame.data = (ulong)BitConverter.ToInt64(in_pack.data, 4); can_frame.length = in_pack.data[12]; can_frame.is_extended = in_pack.data[13]; can_frame.is_remote = in_pack.data[14]; frame_lock.WaitOne(); // store frame in queue and notify waiting threads frame_queue.Enqueue(can_frame); frame_event.Set(); frame_lock.ReleaseMutex(); } } // got command response else { response_lock.WaitOne(); // save response packet and notify waiting threads caPacket new_pack = new caPacket(); new_pack.cmd_code = in_pack.cmd_code; new_pack.data = in_pack.data_len != 0 ? (byte[])in_pack.data.Clone() : null; new_pack.data_len = in_pack.data_len; new_pack.term = in_pack.term; response_queue.Enqueue(new_pack); response_event.Set(); response_lock.ReleaseMutex(); } } }