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