An access controller for man doors at our facility. It receives Wiegand signals from a keypad/card reader and activates a relay to open the door. Access codes are stored in EEPROM. The active code list is updated from TFTP on a local server.
Dependencies: 24LCxx_I2C CardReader USBHOST
CodeMemory.cpp
- Committer:
- acesrobertm
- Date:
- 2017-09-25
- Revision:
- 0:a56239ae90c2
File content as of revision 0:a56239ae90c2:
#include "CodeMemory.h" void CodeMemory::EEPROMClear() { for (int i = 0 ; i < EEPROM_LENGTH ; i += 4) { _eeprom->Write(i, (int)0, C24LCXX_I2C::LittleEndian); } } unsigned short CodeMemory::ReadAccessCode(unsigned short address) { // Read two bytes at the specified address short code; _eeprom->Read((short)address, &code, C24LCXX_I2C::LittleEndian); return code; } void CodeMemory::WriteAccessCode(unsigned short address, unsigned short value) { //Write the bytes into the eeprom memory. _eeprom->Write(address, (short)value, C24LCXX_I2C::LittleEndian); return; } unsigned int CodeMemory::ReadEEPROMULong(unsigned short address) { // Read four bytes at the specified address. int value; _eeprom->Read((short)address, &value, C24LCXX_I2C::LittleEndian); return value; } void CodeMemory::WriteEEPROMULong(unsigned short address, unsigned int value) { _eeprom->Write((short)address, (int)value, C24LCXX_I2C::LittleEndian); return; } // Find the address of the specified code int CodeMemory::FindAccessCode(unsigned short code) { return FindAccessCode(code, 0, CODE_TABLE_SIZE); } int CodeMemory::FindAccessCode(unsigned short code, unsigned short startAddress, unsigned short stopAddress) { int address = startAddress; while ((address < stopAddress) && (ReadAccessCode(address) != code)) { address += 2; } if (address >= stopAddress) { address = -1; } return address; } // ************************************************** // EEPROM Access Code Functions // ************************************************** int CodeMemory::ActivateAccessCode(unsigned short value) { int address = FindAccessCode(value); if (address >= 0) { return -1; // The code already exists in the list. } // Find the address of the next available 16 bit code slot (zero valued) address = FindAccessCode(0); if (address >= 0) { WriteAccessCode(address, value); } else // Memory Full { address = -2; } return address; } int CodeMemory::DeactivateAccessCode(unsigned short value) { int address = FindAccessCode(value); if (address < 0) { return -1; // The code was not found } else { // Erase the two bytes of data from eeprom _eeprom->Write(address, (short)0, C24LCXX_I2C::LittleEndian); } return address; } void CodeMemory::PrintAllAccessCodes() { int address = 0; while (address < CODE_TABLE_SIZE + SPECIAL_CODE_TABLE_SIZE) { unsigned int code = ReadAccessCode(address); if (code > 0) { printf("%d - %d\n", address, code); } address += 2; } return; } void CodeMemory::SyncAccessCodes(unsigned short* codeList, unsigned short codeCount) { // Deactivate codes that don't exist in the new set. for (int address = 0; address < CODE_TABLE_SIZE; address += 2) { unsigned short code = ReadAccessCode(address); if (code > 0) { // Search the new code list for this code. unsigned short* codePtr = std::find(codeList, codeList + codeCount, code); if (codePtr == codeList + codeCount) { // Code not found. WriteAccessCode(address, 0); } } } // Activate all codes in the code list. Duplicates will be ignored. for (int codeIndex = 0; codeIndex < codeCount; codeIndex++) { ActivateAccessCode(codeList[codeIndex]); } return; } // ************************************************** // EEPROM Special Command Code Functions // ************************************************** bool CodeMemory::IsSpecialCode(unsigned short specialCodeIndex, unsigned short code, unsigned short defaultCode) { // Check for code index out of range if (specialCodeIndex >= (SPECIAL_CODE_TABLE_SIZE / 2)) { return false; } // Check test code value against the default code or eeprom custom code else { unsigned short eepromValue = ReadAccessCode(CODE_TABLE_SIZE + (specialCodeIndex * 2)); return ((eepromValue == 0) && (code == defaultCode)) || (code == eepromValue); } } bool CodeMemory::SetSpecialCode(unsigned short specialCodeIndex, unsigned short code) { // Don't allow duplicate codes if (FindAccessCode(code, CODE_TABLE_SIZE, CODE_TABLE_SIZE + SPECIAL_CODE_TABLE_SIZE) < 0) { printf("Changing special code at index %d to %d\n", specialCodeIndex, code); WriteAccessCode(CODE_TABLE_SIZE + (specialCodeIndex * 2), code); return true; } else { printf("Failed to change special code: Code Exists\n"); return false; // Code already exists in the special code table } } // ************************************************** // EEPROM Event Log // ************************************************** int CodeMemory::LogPointerAddress() { return CODE_TABLE_SIZE + SPECIAL_CODE_TABLE_SIZE; } int CodeMemory::FirstEventLogAddress() { return LogPointerAddress() + EVENT_LOG_POINTER_SIZE + EVENT_LOG_TIME_BASE_SIZE; } int CodeMemory::EventLogEndAddress() { return EEPROM_LENGTH; } void CodeMemory::PrintEvent(unsigned short eventAddress) { unsigned char memByte; _eeprom->Read((short)eventAddress, &memByte); printf("%u:%u:%u\n", ReadEEPROMULong(eventAddress + 3), memByte, ReadAccessCode(eventAddress + 1)); return; } int CodeMemory::GetLatestEventAddress() { return ReadAccessCode(LogPointerAddress()); // Get the location of the last event } int CodeMemory::GetNextEventAddress() { return GetNextEventAddress(GetLatestEventAddress()); } int CodeMemory::GetNextEventAddress(unsigned short startAddress) { int address = startAddress; if (address < FirstEventLogAddress()) { // Empty log, so point to the first slot address = FirstEventLogAddress(); } else if ((address + EVENT_SIZE + (EVENT_SIZE - 1)) < EventLogEndAddress()) { // No wrap necessary address += EVENT_SIZE; } else { // Wrap to the beginning of the log address = FirstEventLogAddress(); } return address; } int CodeMemory::GetPreviousEventAddress(unsigned short startAddress) { int address = startAddress; if ((address - EVENT_SIZE) >= FirstEventLogAddress()) { // No wrap necessary address -= EVENT_SIZE; } else // Wrap to the end of the log { int eventLogLength = ((EventLogEndAddress() - FirstEventLogAddress()) / EVENT_SIZE); address = FirstEventLogAddress() + ((eventLogLength * EVENT_SIZE) - EVENT_SIZE); // Last event address } return address; } void CodeMemory::WriteEvent(unsigned char eventType, unsigned short eventValue) { unsigned int currentTime = time(NULL); // Determine the location of the next event int eventAddress = GetNextEventAddress(); WriteAccessCode(LogPointerAddress(), eventAddress); // Write the event type byte _eeprom->Write(eventAddress, eventType); // Write the event value integer WriteAccessCode(eventAddress + 1, eventValue); // Write the timestamp WriteEEPROMULong(eventAddress + 3, currentTime); // Send the event code to the supervisor for SQL storage printf("Evt:%lu:%u:%u\n", currentTime, eventType, eventValue); return; } void CodeMemory::PrintEventLog() { int oldestEventAddress = GetNextEventAddress(); int eventAddress = oldestEventAddress; // Print all of the events, oldest to newest do { PrintEvent(eventAddress); // Increment to the next event in the log eventAddress = GetNextEventAddress(eventAddress); } while (eventAddress != oldestEventAddress); return; } void CodeMemory::PrintRecentEvents() { PrintRecentEvents(10); return; } void CodeMemory::PrintRecentEvents(unsigned short numEvents) { int eventAddress = GetLatestEventAddress(); for (int eventIndex = 0; eventIndex < numEvents; eventIndex++) { PrintEvent(eventAddress); eventAddress = GetPreviousEventAddress(eventAddress); } return; }