public PanelCommandHandle EnqueueCommand(PanelCommand expcmd) { PanelCommandHandle cmdhdl = new PanelCommandHandle(new AutoResetEvent(false), expcmd); Task.Run(() => { lock (pending_command_queue_lock) pending_command_queue.Enqueue(cmdhdl); }); return(cmdhdl); }
public PanelCommandHandle[] EnqueueCommands(PanelCommand[] expcmds) { PanelCommandHandle[] cmdhdls = new PanelCommandHandle[expcmds.Length]; for (int index_counter = 0; index_counter < expcmds.Length; index_counter++) { cmdhdls[index_counter] = new PanelCommandHandle(new AutoResetEvent(false), expcmds[index_counter]); } Task.Run(() => { lock (pending_command_queue_lock) for (int index_counter = 0; index_counter < expcmds.Length; index_counter++) { pending_command_queue.Enqueue(cmdhdls[index_counter]); } }); return(cmdhdls); }
void commLoop() { long total_errors = 0; comm_running = true; BlockingConnectionReset(); while (comm_running) { int transmit_queue_size = 0; lock (pending_command_queue_lock) transmit_queue_size = pending_command_queue.Count; if (transmit_queue_size > 0) { comm_busy = true; Queue <PanelCommandHandle> current_commands = new Queue <PanelCommandHandle>(); lock (pending_command_queue_lock) for (int object_counter = 0; object_counter < cur_command_buf_size && (transmit_queue_size - object_counter) > 0; object_counter++) { current_commands.Enqueue(pending_command_queue.Dequeue()); } int rep_counter = 0; BlockingConnectionReset(); Action process_command = delegate { while (comm_running) { while (comm_running) { try { for (int object_counter = 0; object_counter < current_commands.Count; object_counter++) { netStream.Write(current_commands.ElementAt(object_counter).Command.TxPacket, 0, current_commands.ElementAt(object_counter).Command.TxPacket.Length); //write current commands } int success_counter = 0; for (int object_counter = 0; object_counter < current_commands.Count; object_counter++) { byte[] resp_buffer = new byte[3]; netStream.Read(resp_buffer, 0, 3); //read ack if (ack.SequenceEqual(resp_buffer)) { if (current_commands.ElementAt(object_counter).Command.ResponseExpected) { resp_buffer = new byte[current_commands.ElementAt(object_counter).Command.ResponseLength]; netStream.Read(resp_buffer, 0, current_commands.ElementAt(object_counter).Command.ResponseLength); if (Utilities.CRC8(resp_buffer, current_commands.ElementAt(object_counter).Command.ResponseLength - 1) == resp_buffer[current_commands.ElementAt(object_counter).Command.ResponseLength - 1]) { current_commands.ElementAt(object_counter).Command.RxPacket = resp_buffer; //return; success_counter++; } else { Console.WriteLine("Failed CRC Check."); break; //failure. restart loop } } else { success_counter++; //return; } } else { Console.WriteLine("expected ack. not received."); break; //failure. restart loop } } if (success_counter == current_commands.Count) { return; } } catch (Exception ex) { Console.WriteLine("Process Command Failure "); //rep_counter++; break; } } //if this code has been reached then an error has occured Thread.Sleep((cur_command_buf_size + 1) * DELAY_PER_FAILURE); cur_command_buf_size = MIN_COMMAND_BUF_SIZE; //set the buffer size to 1 //dequeue all but one command. there will always be at least one command in the current commands queue if (current_commands.Count > 1) { lock (pending_command_queue_lock) while (current_commands.Count != MIN_COMMAND_BUF_SIZE) { //if (pending_command_queue.Count > 0) //{ PanelCommandHandle[] pending_holding = pending_command_queue.ToArray(); PanelCommandHandle[] current_holding = current_commands.ToArray(); PanelCommandHandle[] merged_array = new PanelCommandHandle[pending_holding.Length + current_holding.Length]; Array.Copy(current_holding, merged_array, current_holding.Length); Array.Copy(pending_holding, 0, merged_array, current_holding.Length, pending_holding.Length); pending_command_queue = new Queue <PanelCommandHandle>(merged_array); current_commands = new Queue <PanelCommandHandle>(); current_commands.Enqueue(pending_command_queue.Dequeue()); //} } } rep_counter++; //netStream.Flush(); BlockingConnectionReset(); } }; process_command(); //Console.WriteLine("Panel queue size:" + cur_command_buf_size); if (rep_counter == 0) { if (cur_command_buf_size < MAX_COMMAND_BUF_SIZE) { cur_command_buf_size += BUFF_SIZE_INCREASE_RATE; } } else { total_errors++; } //Console.WriteLine(cur_command_buf_size); foreach (PanelCommandHandle cmdhdl in current_commands) { cmdhdl.Handle.Set(); } } else { comm_busy = false; } } }
private Task Refresh() { return(Task.Run(delegate() { UInt64 uid, uptime; DateTime uid_read_timestamp; PanelCommandHandle pch = connection.EnqueueCommand(new PanelCommand(PanelCommand.POLL_CARD_PRESENCE)); pch.Handle.WaitOne(); //uid will be waiting uid_read_timestamp = DateTime.Now; byte[] conversion_buffer = new byte[8]; Array.Copy(pch.Command.RxPacket, 1, conversion_buffer, 1, 7); Array.Reverse(conversion_buffer); uid = BitConverter.ToUInt64(conversion_buffer, 0); if (uid != 0) { connection.EnqueueCommand(new PanelCommand(PanelCommand.CLEAR_CARD)).Handle.WaitOne(); } pch = connection.EnqueueCommand(new PanelCommand(PanelCommand.GET_UPTIME)); pch.Handle.WaitOne(); //uid will be waiting uptime = BitConverter.ToUInt64(pch.Command.RxPacket, 1); PanelState stcpy = null; lock (state_lock) if (state != null) { stcpy = new PanelState(state); } else { state = new PanelState(new AccessControlCard(uid, AccessControlCard.MIFARE_CLASSIC, uid_read_timestamp), uptime, uid_read_timestamp); } if (stcpy != null) { AccessControlCard accessctlcd = stcpy.Card; //if this is a different card then continue if (accessctlcd.UID != uid) { accessctlcd = new AccessControlCard(uid, AccessControlCard.MIFARE_CLASSIC, uid_read_timestamp); if (uid != 0) { if (presented != null) { presented(this, new PanelEventArgs(new PanelState(accessctlcd, uptime, uid_read_timestamp))); } } } lock (state_lock) state = new PanelState(accessctlcd, uptime, uid_read_timestamp); if (newstate != null) { newstate(this, new PanelEventArgs(new PanelState(accessctlcd, uptime, uid_read_timestamp))); } } })); }