1 | #include <avr/io.h>
|
2 | #include <stdbool.h>
|
3 | #include "stdlib.h"
|
4 |
|
5 | typedef unsigned long DWORD;
|
6 |
|
7 |
|
8 | // - Wichtig!
|
9 | // RandomReleaseNumber muss vor jedem Flashen des Senderprogramms
|
10 | // zufällig gewählt werden (sonst würden sich wegen gelöschtem
|
11 | // EEProm die vorherigen Sendedaten wiederholen).
|
12 | const DWORD RandomReleaseNumber = 0x12fdf454;
|
13 |
|
14 | void Crypter(DWORD* Data, char Count)
|
15 | {
|
16 | srandom(Data[0]); // beim AVR die 32 Bit Version von srand()
|
17 | for(int i=1; i<Count; i++)
|
18 | {
|
19 | Data[i] ^= random();
|
20 | }
|
21 | }
|
22 |
|
23 | void EncodeData(DWORD* Data, char Count)
|
24 | {
|
25 | static DWORD EEProm_Seed = 0;
|
26 | static DWORD EEProm_Counter = 0;
|
27 | Data[0] = EEProm_Seed;
|
28 | Data[1] = EEProm_Counter;
|
29 | Data[2] = RandomReleaseNumber;
|
30 | Crypter(Data, Count); // verschlüsseln
|
31 | EEProm_Seed = random(); // beim AVR die 32 Bit Version von rand()
|
32 | EEProm_Counter++;
|
33 | }
|
34 |
|
35 | bool DecodeData(DWORD* Data, char Count, bool DoSynconize)
|
36 | {
|
37 | static DWORD EEProm_Counter = 0;
|
38 | static DWORD EEProm_ID = 0;
|
39 | Crypter(Data, Count);
|
40 | if(!DoSynconize)
|
41 | {
|
42 | // passt der "Geräte-Code"?
|
43 | if(Data[2]!=EEProm_ID) return false; // nein -> ungültig
|
44 | // passt der Zählerstand (nur die nächsten 65536 Codes sind erlaubt)?
|
45 | DWORD dCounter = Data[1]-EEProm_Counter;
|
46 | if(dCounter==0) return false;
|
47 | if(dCounter>0xffff) return false;
|
48 | }
|
49 | // es liegen gültige Nutzdaten vor (FunkDaten[3..])
|
50 | EEProm_Counter = Data[1];
|
51 | EEProm_ID = Data[2];
|
52 | return true;
|
53 | }
|
54 |
|
55 | int main(void)
|
56 | {
|
57 | while(true)
|
58 | {
|
59 | // - CryptedData[]
|
60 | // Das Array enthält die zu sendenden bzw. die empfangenen Daten
|
61 | // Die ersten drei DWORDs sind reserviert. Mit dem vierten DWORD
|
62 | // beginnen die Nutzdaten.
|
63 | DWORD CryptedData[4]; // 4 = 3+1 -> die Nutzdaten sind ein DWORD
|
64 |
|
65 | // - Sender-SourceCode
|
66 | {
|
67 | CryptedData[3] = 12345789; // Nutzdaten
|
68 | EncodeData(CryptedData, sizeof(CryptedData)/sizeof(*CryptedData));
|
69 | // CryptedData[] wird gesendet...
|
70 | }
|
71 |
|
72 | // - Empfänger-SourceCode
|
73 | {
|
74 | // ...CryptedData[] wird empfangen
|
75 |
|
76 | // - Variable "SynchronizeKeyPressed"
|
77 | // Beim Empfänger müsste einmalig eine Taste gedrückt werden, damit
|
78 | // sich der Empfänger auf die Senderkodierung einstellen kann.
|
79 | static bool SynchronizeKeyPressed = true; // die "Sync-Taste"
|
80 |
|
81 | if(DecodeData(CryptedData,
|
82 | sizeof(CryptedData)/sizeof(*CryptedData),
|
83 | SynchronizeKeyPressed))
|
84 | {
|
85 | // es wurden Nutzdaten empfangen... (CryptedData[3])
|
86 | }
|
87 |
|
88 | SynchronizeKeyPressed = false; // Empfänger nun Synchron
|
89 | }
|
90 |
|
91 | }
|
92 | }
|