// returns the message for the Arduino
        private static string ProcessCardScan(CardScan cardScan)
        {
            CardScanResult result = GetCardScanResult(cardScan);

            if (result.Status == "valid")
            {
                return(CommandHandler.MSG_VEND_INPUT_READY);
            }

            return(CommandHandler.MSG_ERROR_INVALID_CARD);
        }
Exemple #2
0
        public JObject ScanCards()
        {
            //Reset The Stopwatch
            lock (scanIdle)
            {
                if (scanIdle == null)
                {
                    scanIdle = new Stopwatch();
                }

                scanIdle.Restart();
            }

            //Startup the watch thread
            if (!watchActive)
            {
                watchActive = true;
                scanValid   = false;
                scanStart.Restart();

                Task t = new Task(() => {
                    //Get Controllers

                    String ErrorMsg;
                    List <KeyDbManager.ControllerInfo> dbControllers = KeyDbManager.ListControllers(out ErrorMsg);

                    //Scan Net For Active Controllers
                    List <WGToolKit.WGController> netControllers = WGToolKit.WGController.ScanNet(FreesideKeyService.Properties.Settings.Default.controllerPort);

                    //Start Watch
                    foreach (WGToolKit.WGController nc in netControllers)
                    {
                        nc.startWatch((Object sender, WGToolKit.ControllerRecord recvRecord) =>
                        {
                            Int32 cardID           = (Int32)recvRecord.cardID;
                            Int32 controllerSerial = ((WGToolKit.WGController)sender).Connection.ID;
                            Int32 doorIndex        = WGToolKit.WGTools.getDoorFromRecordStatus(recvRecord.cardID, recvRecord.statusByte);

                            String doorName  = KeyDbManager.LookupDoorName(controllerSerial, doorIndex, out ErrorMsg);
                            CardScanResult c = new CardScanResult(cardID, controllerSerial, doorIndex, doorName);

                            lock (scanResults)
                            {
                                if (!scanResults.Contains(c) && scanValid)
                                {
                                    scanResults.Add(c);
                                }
                            }
                        });
                    }



                    //Watch Started. Now Just Wait FOr Idle Timer TO expire and cleanup
                    while (true)
                    {
                        //Timer to burn first two seconds of entries (Stale).
                        if (!scanValid)
                        {
                            lock (scanStart)
                            {
                                if (scanStart.ElapsedMilliseconds > 2000)
                                {
                                    scanValid = true;
                                }
                            }
                        }

                        lock (scanIdle)
                        {
                            if (scanIdle.ElapsedMilliseconds > 10000)
                            {
                                //Stop Watch
                                foreach (WGToolKit.WGController nc in netControllers)
                                {
                                    nc.stopWatch();
                                }

                                //Clear Lists;
                                watchActive = false;
                                scanResults.Clear();
                            }
                        }

                        Thread.Sleep(10);
                    }
                });

                t.Start();
            }

            //Reset the scan Timer
            lock (scanIdle)
            {
                scanIdle.Restart();
            }

            //Return List Of collected REsults
            JObject result = new JObject();

            lock (scanResults)
            {
                result["scanResults"] = JToken.FromObject(scanResults);
                result["message"]     = $"Scan Results Found: {scanResults.Count}";
            }


            return(result);
        }
Exemple #3
0
        // Called when the user has pushed some coordinates
        private static string RequestItem(string coordinateString)
        {
            // Get the last card scan
            CardScan scan = CardScan.LastCardScan();

            if (scan == null)
            {
                return(MSG_ERROR_NO_CARD);
            }

            VendingRequest lastRequest = VendingRequest.LastOutstandingRequest();

            string error          = null;
            string successMessage = MSG_VEND_ITEM;
            int    x             = -1;
            int    y             = -1;
            string requestStatus = null;

            using (klick_vending_machineEntities context = new klick_vending_machineEntities())
            {
                CardScanResult scanResult = scan.CardScanResult;

                // create a new vending request
                VendingRequest request = new VendingRequest()
                {
                    CardScanResultID = scanResult.CardScanResultID,
                    Status           = STATUS_PROCESSING,
                    RequestDate      = DateTime.Now,
                    Coordinates      = coordinateString
                };

                context.VendingRequests.Add(request);
                context.SaveChanges();

                try
                {
                    // Error checking block
                    if (lastRequest != null)
                    {
                        // We found a vending request with that is either processing or vending within a timeout interval
                        // Cannot vend again at this point
                        error = MSG_ERROR_VENDING_IN_PROGRESS;
                    }
                    else if (scan.HasTimedOut)
                    {
                        // We've timed out
                        if (DateTime.Now.Subtract(scan.ScanDate).TotalMinutes > 5)
                        {
                            // Last scan was a while ago - just tell the user to scan first, so they don't get confused
                            error = MSG_ERROR_NO_CARD;
                        }
                        else
                        {
                            // Display timeout error message
                            error = MSG_ERROR_CARD_TIMEOUT;
                        }
                    }
                    else if (scanResult.Status != "valid")
                    {
                        // Invalid card!
                        error = MSG_ERROR_INVALID_CARD;
                    }
                    else if (scan.HasVended(request.VendingRequestID))
                    {
                        // We've already vended an item for this card scan. Sneaky!
                        error = MSG_ERROR_ALREADY_VENDED;
                    }
                    else if (coordinateString == "TIMEOUT")
                    {
                        // Timed out before anything was vended
                        string DefaultTimeoutPath = "smb_warning.wav";
                        PlaySound(GetConfigPath("timeout", DefaultTimeoutPath));
                        error = MSG_ERROR_CARD_TIMEOUT;
                    }
                    else if (!GetCoordinates(coordinateString, out x, out y))
                    {
                        // Unable to parse coordinates
                        error = MSG_ERROR_INVALID_COORDS;
                    }
                    else
                    {
                        requestStatus = GetItemStatusType(x, y);
                        if (requestStatus == null)
                        {
                            error = MSG_ERROR_INVALID_ITEM;
                        }
                    }

                    request.X = x;
                    request.Y = y;
                }
                catch (Exception e)
                {
                    error = MSG_ERROR_SYSTEM_FAIL;
                    Error.CreateError(e);
                }

                if (error == null)
                {
                    // TODO: consider what happens if the message to the Arduino fails?
                    request.Status        = requestStatus;
                    request.VendStartDate = DateTime.Now;

                    // Adjust the success message if necessary
                    if (requestStatus == STATUS_TAKING_PHOTO)
                    {
                        successMessage = MSG_TAKING_PHOTO;
                    }
                    else if (requestStatus == STATUS_PLAYING_SOUND)
                    {
                        successMessage = MSG_PLAYING_SOUND;
                    }
                }
                else
                {
                    request.Status       = "failed";
                    request.ErrorMessage = error;
                }

                context.SaveChanges();
            }

            Logger.WriteLine("Returning! " + (error == null ? MSG_VEND_ITEM : error));

            // Finally, success! Vend it. Or display the error instead if there is one.
            return(error == null ? successMessage : error);
        }
        private static CardScanResult GetCardScanResult(CardScan cardScan)
        {
            // now we have to create a result, and validate against the keyscan database
            using (klick_vending_machineEntities context = new klick_vending_machineEntities()) {
                CardScanResult result = new CardScanResult()
                {
                    CardScanID = cardScan.CardScanID,
                    ResultDate = DateTime.Now,
                    Status     = "invalid"
                };

                context.CardScanResults.Add(result);

                try {
                    string hexID = cardScan.CardID.Replace(" ", ""); // strip out extra spaces

                    // assert correct length
                    if (hexID.Length == 16)
                    {
                        // take the last 4 octets only (this is a 16-digit string)
                        hexID = hexID.Substring(8);

                        string binaryID = String.Join(String.Empty,
                                                      hexID.Select(
                                                          c => Convert.ToString(Convert.ToInt32(c.ToString(), 16), 2).PadLeft(4, '0')
                                                          )
                                                      );

                        // card batch = 8 digits, starting at digit 7
                        // card id = 15 digits, starting at digit 16
                        string binaryCardBatch  = binaryID.Substring(7, 8);
                        string binaryCardNumber = binaryID.Substring(16, 15);

                        // convert to decimal, then padded string (3-digit batch, 5-digit number)
                        result.CardBatch  = Convert.ToInt64(binaryCardBatch, 2).ToString().PadLeft(3, '0');
                        result.CardNumber = Convert.ToInt64(binaryCardNumber, 2).ToString().PadLeft(5, '0');

                        // lookup card in keyscan database and validate, and grab first and lastname

                        SqlConnection o_sqlConnection = new SqlConnection();
                        o_sqlConnection.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["keyscandb"].ConnectionString;
                        o_sqlConnection.Open();
                        SqlCommand o_sqlCommand = new SqlCommand();
                        o_sqlCommand.CommandText = "Select * from CARD where CARD_BATCH = " + result.CardBatch + " and CARD_NUMBER = " + result.CardNumber + " and isnull([CARD_VALIDFROM], getdate()-1) < Getdate() and isnull([CARD_VALIDTO], getdate() + 1) > getdate() and isnull([CARD_ARCHIVED],0) = 0 and isnull([CARD_LIMITED],0) = 0 and [CARD_DELETED] = 0";
                        o_sqlCommand.Connection  = o_sqlConnection;
                        SqlDataReader o_sqlDataReader;
                        o_sqlDataReader = o_sqlCommand.ExecuteReader();
                        if (o_sqlDataReader.Read())
                        {
                            result.CardFirstName = o_sqlDataReader["CARD_FIRSTNAME"].ToString();
                            result.CardLastName  = o_sqlDataReader["CARD_LASTNAME"].ToString();
                            result.Status        = "valid";
                        }
                        else
                        {
                            result.Status = "invalid";
                        }
                        o_sqlDataReader.Close();
                        o_sqlConnection.Close();
                    }
                }
                catch (Exception e)
                {
                    Logger.WriteException(e);
                    result.Status = "failed";
                    // Error.CreateError(e);
                }

                context.SaveChanges();

                return(result);
            }
        }