#include RCSwitch rx = RCSwitch(); // باید با فرستنده یکسان باشد const String PRIVATE_KEY = "as23f"; // دستگاه‌های مجاز const String ALLOWED_DEVICES[] = {"dr142", "abcde", "fghij"}; const int NUM_ALLOWED_DEVICES = 3; // بافرهای دریافت String receivedKey = ""; String receivedHex = ""; // کنترل فریم bool receivingPublicKey = true; int receivedChars = 0; unsigned long lastReceiveTime = 0; const unsigned long TIMEOUT_MS = 500; // طول متن اصلی انتظار می‌رود 25 باشد const int EXPECTED_PLAIN_LEN = 25; // XOR ساده String decryptData(const String &data, const String &key) { String out; out.reserve(data.length()); for (int i = 0; i < data.length(); i++) { out += (char)(data[i] ^ key[i % key.length()]); } return out; } bool isDeviceAllowed(const String &deviceId) { for (int i = 0; i < NUM_ALLOWED_DEVICES; i++) { if (deviceId == ALLOWED_DEVICES[i]) return true; } return false; } static inline bool isHexChar(char c) { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); } void resetFrame() { receivedKey = ""; receivedHex = ""; receivingPublicKey = true; receivedChars = 0; } void setup() { Serial.begin(9600); rx.enableReceive(0); // interrupt 0 → پایه 2 در آردوینو UNO rx.setProtocol(1); rx.setPulseLength(300); resetFrame(); Serial.println(F("=== Receiver Started ===")); Serial.print(F("Private Key: ")); Serial.println(PRIVATE_KEY); Serial.print(F("Allowed IDs: ")); for (int i = 0; i < NUM_ALLOWED_DEVICES; i++) { Serial.print(ALLOWED_DEVICES[i]); Serial.print(' '); } Serial.println(); } void loop() { if (rx.available()) { unsigned long value = rx.getReceivedValue(); unsigned int bitlen = rx.getReceivedBitlength(); if (bitlen == 8) { char c = (char)value; if (receivingPublicKey) { if (receivedKey.length() < 5) { receivedKey += c; //Serial.print(F("Received key char: ")); Serial.println(c); receivedChars++; if (receivedKey.length() == 5) { receivingPublicKey = false; Serial.println(F("Now receiving encrypted HEX data...")); } } } else { // فقط کاراکتر HEX معتبر ذخیره شود if (isHexChar(c)) { receivedHex += c; //Serial.print(F("Received HEX char: ")); Serial.println(c); receivedChars++; } else { // نویز را رد کن Serial.print(F("Ignored non-HEX char: 0x")); Serial.println((int)(uint8_t)c, HEX); } } lastReceiveTime = millis(); } rx.resetAvailable(); } // اگر وقفه افتاد، پردازش کن if (receivedChars >= 5 && (millis() - lastReceiveTime) > TIMEOUT_MS) { Serial.println(F("=== Processing Data ===")); Serial.print(F("Received Public Key: ")); Serial.println(receivedKey); if (receivedKey != PRIVATE_KEY) { Serial.println(F("Key verification: FAILED")); resetFrame(); return; } Serial.println(F("Key verification: SUCCESS")); // طول HEX باید زوج باشد (هر دو کاراکتر → یک بایت) if ((receivedHex.length() % 2) != 0) { Serial.print(F("Odd HEX length: ")); Serial.println(receivedHex.length()); resetFrame(); return; } // تبدیل HEX → بایت‌ها String decoded; decoded.reserve(receivedHex.length() / 2); for (int i = 0; i + 1 < receivedHex.length(); i += 2) { char hex2[3] = { receivedHex[i], receivedHex[i+1], '\0' }; char b = (char) strtol(hex2, NULL, 16); decoded += b; } Serial.print(F("Decoded length: ")); Serial.println(decoded.length()); Serial.print(F("Decoded (raw XORed) bytes: ")); for (int i = 0; i < decoded.length(); i++) { Serial.print((int)(uint8_t)decoded[i]); Serial.print(' '); } Serial.println(); // باید دقیقاً به طول 25 بایت باشد if (decoded.length() != EXPECTED_PLAIN_LEN) { Serial.println(F("Unexpected decoded length (should be 25).")); resetFrame(); return; } // رمزگشایی String plain = decryptData(decoded, PRIVATE_KEY); Serial.print(F("Decrypted Data: ")); Serial.println(plain); // اعتبارسنجی قالب if (plain.length() != EXPECTED_PLAIN_LEN || plain[5] != 'S' || plain[10] != 'G' || plain[15] != 'T' || plain[20] != 'H') { Serial.println(F("Format check failed.")); resetFrame(); return; } String deviceId = plain.substring(0, 5); Serial.print(F("Device ID: ")); Serial.println(deviceId); if (!isDeviceAllowed(deviceId)) { Serial.println(F("Device authorization: FAILED")); resetFrame(); return; } Serial.println(F("Device authorization: SUCCESS")); // پارس مقادیر String sSoil = plain.substring(6, 10); // بین S و G String sGas = plain.substring(11, 15); // بین G و T String sTemp = plain.substring(16, 20); // بین T و H String sHum = plain.substring(21, 25); // بعد از H int soilMoisture = sSoil.toInt(); int gasValue = sGas.toInt(); float temperature = sTemp.toInt() / 10.0; float humidity = sHum.toInt() / 10.0; Serial.println(F("=== Authorized Data ===")); Serial.print(F("Soil Moisture: ")); Serial.print(soilMoisture); Serial.print(F(" - Gas Value : ")); Serial.print(gasValue); Serial.print(F(" - Temperature : ")); Serial.print(temperature); Serial.print(F(" C")); Serial.print(F(" - Humidity : ")); Serial.print(humidity); Serial.println(F(" %")); Serial.println(F("=======================")); // آماده دریافت بعدی resetFrame(); } delay(5); }