Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <SoftwareSerial.h>
- #include <OneWire.h>
- #include <string.h>
- #define pin 10 // Pin 10 on Arduino
- #define port_speed 9600 // Port speed (bit / sec)
- #define led_delay_time 1000 // Delay time using for led blinking
- #define _waiting_time 20000 // Default waiting time for the key applying
- #define _delay_time 1000 // Default delay time between waiting the key
- const int STORAGE_SIZE = 5;
- struct KeysStorage{
- byte key_for_writing[8], last_key[8];
- byte storage[STORAGE_SIZE][8];
- String titles[8];
- KeysStorage(){
- clear_storage();
- };
- bool set(short n, byte key[], String title){
- if (n >= 0 && n < STORAGE_SIZE){
- for (short i = 0; i < 8; i++){
- storage[n][i] = key[i];
- }
- titles[n] = title;
- return true;
- }
- return false;
- };
- String get_key_string(short n){
- if (n >= 0 && n < STORAGE_SIZE){
- return "<" + titles[n] + "> (" + key_as_string(storage[n]) + ")";
- }
- return "Error: incorrect number of the key";
- }
- void clear_storage(){
- for (short i = 0; i < STORAGE_SIZE; i++){
- for (short j = 0; j < 8; j++){
- storage[i][j] = 0;
- }
- titles[i] = "Unknown";
- }
- }
- String str_key = "";
- String key_as_string(byte key[]){
- str_key = "";
- // Building key as String
- for (int i = 0; i < 8; i++){
- str_key += String(key[i], HEX) + (i == 7 ? "": ":");
- }
- return str_key;
- }
- String build_key_string(byte key[]){
- String key_title = "Unknown";
- bool is_key_storing;
- for (int i = 0; i < STORAGE_SIZE; i++){
- is_key_storing = true;
- for (int j = 0; j < 8; j++){
- if (storage[i][j] != key[j])
- is_key_storing = false;
- }
- if (is_key_storing){
- key_title = titles[i];
- break;
- }
- }
- return "<" + key_title + "> (" + key_as_string(key) + ")";
- }
- String get_storage_content(){
- String result = "";
- for (int i = 0; i < STORAGE_SIZE; i++){
- result += ("<" + titles[i] + "> (" + key_as_string(storage[i]) + ")\n");
- }
- return result;// "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; 200/37
- }
- bool set_for_writing(short n){
- if (!is_empty(n)){
- for (short i = 0; i < 8; i++){
- key_for_writing[i] = storage[n][i];
- }
- return true;
- }
- return false;
- }
- bool is_empty(short n){
- if (n >= 0 && n < STORAGE_SIZE){
- for (short i = 0; i < 8; i++){
- if (storage[n][i] != 0){
- return false;
- }
- }
- }
- return true;
- }
- bool is_last_key_in_writing_buffer(){
- for (short i = 0; i < 8; i++){
- if (key_for_writing[i] != last_key[i]) return false;
- }
- return true;
- }
- void save_last_to_writing_buffer(){
- for (short i = 0; i < 8; i++){
- key_for_writing[i] = last_key[i];
- }
- }
- };
- enum State {
- BASE,
- COPY,
- SET,
- WRITE
- };
- // State
- State state = BASE;
- // Keys
- OneWire ibutton (pin);
- KeysStorage keys_storage;
- String temp_key_description;
- // LED
- const int LED = 13;
- bool led_active = true;
- // IO
- char in_bytes[100];
- char* p_buffer;
- byte bytes_counter;
- bool always_false(){
- return false;
- }
- // Repeat <function> until it returns True, or time is over
- template<typename Fun> bool repeat_for(Fun function=always_false, int repeat_time=_waiting_time, int delay_time=_delay_time){
- int executing_time = 0;
- bool func_result = false;
- while (executing_time <= repeat_time && !(func_result = function())){
- // Monitoring serial input for the "reset" command
- if (Serial.available()){
- read_input();
- if (String(in_bytes).equalsIgnoreCase("reset")){
- return false;
- }
- if (state == SET){
- // Terminate the function with 'true' state when state == SET
- return true;
- }
- }
- // Delay and increase time counter
- delay(delay_time);
- executing_time += delay_time;
- }
- return func_result;
- }
- // Create the key from the input buffer and put it to the buffer for writing
- void parse_key_from_input_buffer(){
- if (!in_bytes) return;
- byte hex_ascii[2];
- int current_symbol = 0;
- for (int i = 0; i < 8; i++){
- hex_ascii[0] = in_bytes[current_symbol++]; hex_ascii[1] = in_bytes[current_symbol++];
- keys_storage.key_for_writing[i] = ascii_to_byte(hex_ascii, 2, 16);
- current_symbol++; // skip the delimiter
- }
- }
- // Bytes in hex_ascii must be in the direct order
- char ascii_to_byte(char ascii[], byte len, byte base){
- char result = 0, c, digit = 0;
- for (int i = 0; i < len; i++){
- c = ascii[i];
- if (c >= 48 && c <= 57) digit = c - 48;
- else if (c >= 65 && c <= 70) digit = c - 65 + 0xA;
- else if (c >= 97 && c <= 102) digit = c - 97 + 0xA;
- for (int j = 0; j < len - 1 - i; j++){
- digit *= base;
- }
- // digit = digit << (4 * (len - 1 - i)); // shift by corresponding count of bytes
- result += digit;
- }
- return result;
- }
- // Arduino functions
- //============================================//
- void setup(){
- Serial.begin(port_speed);
- pinMode(LED, OUTPUT);
- digitalWrite(LED, HIGH);
- }
- void loop(){
- // Read from Bluetooth
- if (Serial.available())
- {
- read_input();
- process_input();
- reset_state();
- } else {
- standing_led_control();
- }
- }
- void read_input(){
- bytes_counter = 0;
- while (Serial.available()){
- in_bytes[bytes_counter++] = Serial.read();
- delay(10);
- }
- in_bytes[bytes_counter++] = '\0';
- // Serial.println("Buffer content after the reading " + String(bytes_counter) + " bytes: " + String(in_bytes));
- }
- void process_input(){
- p_buffer = strtok(in_bytes, " ");
- // String last_error = "";
- bool last_error = true;
- String command = String(p_buffer);
- if (command.equalsIgnoreCase("reset")){
- reset_state();
- Serial.println("Reseted successfully");
- } else
- if (state == BASE){
- if (command.equalsIgnoreCase("copy")){
- last_error = process_copy();
- } else
- if (command.equalsIgnoreCase("storage")){
- Serial.println("STORAGE CONTENT:\n" + keys_storage.get_storage_content());
- } else
- if (command.equalsIgnoreCase("clear")){
- keys_storage.clear_storage();
- Serial.println("Storage has been cleaned");
- } else
- if (command.equalsIgnoreCase("set")){
- last_error = process_set();
- } else
- if (command.equalsIgnoreCase("write")){
- last_error = process_write();
- }
- if (!last_error){
- Serial.println("ERROR: undescribed error occured");
- }
- }
- reset_state();
- }
- void reset_state(){
- state = BASE;
- }
- //char error_incorrect_command_write[100] = "Incorrect call of 'write' command: you should use 'write <number of a cell> <number of copies>'";
- bool process_write(){
- // Read number of a cell
- p_buffer = strtok(NULL, " ");
- int cell_number = 0, copies_count = 0;
- if (p_buffer && (cell_number = String(p_buffer).toInt()) == 0) {
- // return error_incorrect_command_write;
- return false;
- }
- if (cell_number <= 0 || cell_number > STORAGE_SIZE){
- // return "Incorrect cell number";
- return false;
- }
- // Read count of copies
- p_buffer = strtok(NULL, " ");
- if (p_buffer && (copies_count = String(p_buffer).toInt()) == 0) {
- // return error_incorrect_command_write;
- return false;
- }
- if (copies_count < 0){
- // return "Incorrect copies number";
- return false;
- }
- if (!copies_count){
- copies_count++;
- }
- // Copy selected key to temp_storage from where it will be writing
- if (!keys_storage.set_for_writing(cell_number - 1)){
- // return "Selected cell #" + String(cell_number) + " is empty.";
- return false;
- }
- state = WRITE;
- Serial.println("Start writing " + String(copies_count) + " copies of the key #" + String(cell_number) + " " + keys_storage.get_key_string(cell_number - 1) + "\n");
- for (short i = 0; i < copies_count; i++){
- Serial.println("Please, apply #" + String(i + 1) + "-th slave key");
- if (!repeat_for(write_key, _waiting_time, _delay_time)){
- // return String("Failed writing the key #" + String(i + 1));
- return false;
- } else {
- Serial.println("Key " + keys_storage.build_key_string(keys_storage.last_key) + " rewrited");
- }
- }
- // return "";
- return true;
- }
- bool process_set(){
- // Read number of the cell for setting
- p_buffer = strtok(NULL, " ");
- int cell_number = 0;
- if (p_buffer && (cell_number = String(p_buffer).toInt()) == 0 || !p_buffer) {
- // return "Incorrect call of the 'set' command: you should use 'set <number of the cell>'";
- return false;
- }
- if (cell_number <= 0 || cell_number > STORAGE_SIZE){
- // return "Incorrect cell number";
- return false;
- }
- state = SET;
- Serial.println("Please, send the key value in format 'FF:FF:FF:FF:FF:FF:FF:FF'");
- // If a key was received
- if (repeat_for(always_false, _waiting_time, _delay_time)){
- //Put key to temp_storage
- parse_key_from_input_buffer();
- Serial.println("Now, please, send me short description of the key");
- if (repeat_for(always_false, _waiting_time, _delay_time)){
- temp_key_description = String(in_bytes);
- if (keys_storage.set(cell_number - 1, keys_storage.key_for_writing, temp_key_description)){
- Serial.println("New value successfully setted up.\nSTORAGE CONTENT:\n" + keys_storage.get_storage_content());
- } else {
- // return "Incorrect cell number";
- return false;
- }
- } else {
- // return "Waiting time for the description is exceeded";
- return false;
- }
- } else {
- // return "Waiting time for the key is exceeded";
- return false;
- }
- // return "";
- return true;
- }
- bool process_copy(){
- p_buffer = strtok(NULL, " ");
- int copy_times = 0;
- if (p_buffer && (copy_times = String(p_buffer).toInt()) == 0) {
- // return "Incorrect call of the copy command: you should use 'copy <number greater than 0>' or 'copy' instead";
- return false;
- }
- state = COPY;
- if (copy_times == 0)
- copy_times = 1;
- Serial.println("Start of copying " + String(copy_times) + " times. Waiting " + String(_waiting_time / 1000) + " seconds for the master key...");
- // Key has been applied
- if (repeat_for(read_key, _waiting_time, _delay_time)){
- Serial.println("Master-key " + keys_storage.build_key_string(keys_storage.key_for_writing));
- for (int i = 0; i < copy_times; i++){
- Serial.println("Please, apply #" + String(i + 1) + "-th slave key");
- if (!repeat_for(write_key, _waiting_time, _delay_time)){
- // return String("Failed writing the key #" + String(i + 1));
- return false;
- } else {
- Serial.println("Key " + keys_storage.build_key_string(keys_storage.last_key) + " rewrited");
- }
- }
- } else {
- // return "Master key wasn't applied in 10 seconds";
- return false;
- }
- // return "";
- return true;
- }
- void standing_led_control(){
- // Try to read the key
- if (_read_key()){
- // Set active LED
- set_led(true);
- // Print time and current buffer value
- Serial.println(String(millis()/1000) + "> " + keys_storage.build_key_string(keys_storage.last_key));
- } else {
- // Switch LED off and delay
- set_led(false);
- }
- delay(500);
- }
- // Auxiliary functions
- //============================================//
- void set_led(bool state){
- if (state == led_active) return;
- if (state){
- digitalWrite(LED, HIGH);
- } else {
- digitalWrite(LED, LOW);
- }
- led_active = state;
- }
- bool read_key(){
- bool key_exists = _read_key();
- if (key_exists){
- keys_storage.save_last_to_writing_buffer();
- set_led(false);
- } else {
- set_led(!led_active);
- }
- return key_exists;
- }
- bool write_key(){
- bool key_exists = _read_key() && (!keys_storage.is_last_key_in_writing_buffer());
- if (key_exists){
- _write_key(keys_storage.key_for_writing);
- set_led(false);
- } else {
- set_led(!led_active);
- }
- return key_exists;
- }
- bool _read_key(){
- bool key_exists = ibutton.search(keys_storage.last_key);
- if (!key_exists){
- ibutton.reset_search();
- }
- return key_exists;
- }
- void _write_key(byte* key){
- ibutton.skip(); ibutton.reset(); ibutton.write(0x33);
- // Send preparing commands
- ibutton.skip();
- ibutton.reset();
- ibutton.write(0xD1); // send 0xD1
- digitalWrite(10, LOW); pinMode(10, OUTPUT); delayMicroseconds(60); // send logical 0
- pinMode(10, INPUT); digitalWrite(10, HIGH); delay(10);
- ibutton.skip();
- ibutton.reset();
- ibutton.write(0xD5);
- // Write the key by bytes
- for (byte x = 0; x < 8; x++){
- writeByte(key[x]);
- }
- // Send end commands
- ibutton.reset();
- ibutton.write(0xD1); // send 0xD1
- digitalWrite(10, LOW); pinMode(10, OUTPUT); delayMicroseconds(10); // send logical 1
- pinMode(10, INPUT); digitalWrite(10, HIGH); delay(10);
- }
- int writeByte(byte data){
- int data_bit;
- for(data_bit=0; data_bit<8; data_bit++){
- if (data & 1){
- digitalWrite(pin, LOW); pinMode(pin, OUTPUT);
- delayMicroseconds(60);
- pinMode(pin, INPUT); digitalWrite(pin, HIGH);
- delay(10);
- } else {
- digitalWrite(pin, LOW); pinMode(pin, OUTPUT);
- pinMode(pin, INPUT); digitalWrite(pin, HIGH);
- delay(10);
- }
- data = data >> 1;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement