kovtam
Published © GPL3+

Arduino KNX RF packet sniffer

You can sniff an KNX RF network by an CC1101 radio transceiver. I sniffed my Siemens Synco Living Home automation system

IntermediateShowcase (no instructions)13,746
Arduino KNX RF packet sniffer

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
5V
×1
Texas Instruments CC1101 radio transceiver
×1
Level Shifter Board
SparkFun Level Shifter Board
4ch bidirectional level shifter
×1

Story

Read more

Schematics

Wiring diagram

Code

Modified panstamp library

Arduino
You need to use this lib for the KNX RF communication.
You find the radio configuration in this files
No preview (download only).

The main code

Arduino
You can run this code for sniff KNX RF packages
#include "EEPROM.h"
#include "cc1101.h"
#include <Wire.h> 
#include <Crc16.h>

// The connection to the hardware chip CC1101 the RF Chip
CC1101 cc1101;


// a flag that a wireless packet has been received 
boolean packetAvailable = false;         
boolean crcerror = false;         
int i;
int packetcounter=0;
int packeterrorcounter=0;
byte * buffer;
int mdec;
boolean flushed=false;
byte mrcsat;  //main radio control state
byte rxbytes;
byte ecounter=0;
CCPACKET packet;
Crc16 crc; 
unsigned short crcvalue;
byte data[120];
unsigned long timer=0;
unsigned long lcdtimer=0;

void setup()
{
  SPCR &= ~_BV(SPE);  //SPI switch off
  Serial.begin(115200);
  Serial.println("start");
  
  // initialize the RF Chip
  cc1101.init();
  delay(1000);
  Serial.println("device initialized");

  Serial.println("setup done");


  //chech the configuration values writed to the radio chip. I read the radio chip out
  //if you read zero or default values the configuration is not well, check the wiring 
  for(i=0 ; i<20 ; i++) {
     Serial.print(i, HEX);
     Serial.print(":");
     Serial.print(cc1101.readReg(i, CC1101_CONFIG_REGISTER), HEX);
     Serial.print(" ");
  }

   
  Serial.println("Go...");
  cc1101.flushRxFifo();
  delay(500);
  //set radio chip to listen mode 
  cc1101.setRxState(); 
  delay(500);
  
  //and waiting for any packet
  attachInterrupt(0, cc1101signalsInterrupt, RISING);
  
}

/**
* The loop method gets called on and on after the start of the system.
*/

void readr () {
    packet.ecode=0;
    packetAvailable=false;

    byte tot=0;
    byte len;
    byte chk;
    byte chk2;
    byte pckidx=0;
    unsigned long last=0;
    do {
      last++;
      cc1101.receiveData(&packet,tot);
      
      if (packet.length>0) {
        if (tot==0) {
            //calc and set pack length
            len=cc1101.mandecode(packet.data[0]*256+packet.data[1]);
            chk=cc1101.mandecode(packet.data[2]*256+packet.data[3]);
            chk2=cc1101.mandecode(packet.data[4]*256+packet.data[5]);
            len=14+((len-9)%16)+(((len-9)/16)*18);
            len=len*2;
            if (len>100) len=100;
            if ((chk==68)&&(chk2=255)) cc1101.writeReg(0x0006, len); //Package length
            else {
                cc1101.writeReg(0x0006, 16);
                len=packet.length;
                packet.ecode=1;
                packeterrorcounter++;
                cc1101.cmdStrobe(CC1101_SIDLE);
                cc1101.cmdStrobe(CC1101_SFRX);
            }

        }
   //     Serial.print("*");
        tot=tot+packet.length;
        for(int i=0 ; i<packet.length; i++) {
           if (i%2==1) {
               data[pckidx]=cc1101.mandecode(packet.data[i-1]*256+packet.data[i]);
//               Serial.print(data[pckidx],HEX);
//               Serial.print(";");
               pckidx++;
           }
        }
      }
      delayMicroseconds(1000);
    } while ((tot<len)&&(last<100)); 
    if (tot>0) {
    packetcounter++;
    if (packet.ecode!=0) ecounter++;
    else ecounter=0;
    crcerror=false;
    Serial.print(";CRC:");
    crcvalue = crc.fastCrc(data,0,10,false,false,0x13D65,0,0,0x8000,0)^0xFFFF;
    if (crcvalue!=data[10]*256+data[11]) {Serial.print("ERROR1");crcerror=true;}
    else {
           crcvalue = crc.fastCrc(data,12,min(pckidx-14,16),false,false,0x13D65,0,0,0x8000,0)^0xFFFF;
           if (crcvalue!=data[min(pckidx-2,28)]*256+data[min(pckidx-1,29)]) {Serial.print("ERROR2");crcerror=true;}
           else {
                  if (pckidx>32) {
                      crcvalue = crc.fastCrc(data,30,min(pckidx-32,16),false,false,0x13D65,0,0,0x8000,0)^0xFFFF;
                      if (crcvalue!=data[pckidx-2]*256+data[pckidx-1]) {Serial.print("ERROR3");crcerror=true;}
                      else Serial.print("OK3");
                  } 
                  else Serial.print("OK2");
                }
         }
//    if (crcerror==false)
    {
        for(int i=0 ; i<pckidx; i++) {
               if ((i==10)||(i==11)) {;}
               else if ((i==28)||(i==29)) {;}
               else if ((i==pckidx-1)||(i==pckidx-2)) {;}
               else { 
                 Serial.print(";");
//                 if (data[i]<10) Serial.print("  ");
//                 else if (data[i]<100) Serial.print(" ");
                 Serial.print(data[i]);
               }
        }
        Serial.println(";");
    }
    if (crcerror==true) 
    {
       packeterrorcounter++;
       Serial.print("Total:");
       Serial.print(tot);
       Serial.print(";Error:");
       Serial.print(packet.ecode);
       Serial.print(";RXCount:");
       Serial.print(packet.rxcount);
       Serial.print(";Overflow:");
       Serial.print(packet.overflow);
       Serial.print(";MRCS:");
       mrcsat=cc1101.readReg(CC1101_MARCSTATE,CC1101_STATUS_REGISTER);    
       Serial.print(mrcsat);
       Serial.println(";");
    }
    if (ecounter==3) {
        Serial.println("***RESET***");
        cc1101.reset();
        delay(500);
        ecounter=0;
    } 
    cc1101.setRxState();
    cc1101.writeReg(0x0006, 100);
    }
}

void cc1101signalsInterrupt(void){
  //if it has some received byte in the fifo and reach the defined count the the chip send an interrupt to the arduino
  packetAvailable=true;
}


void loop() {
  //this is an unlimited loop
  if (packetAvailable) {
     timer=0;
     //if received some bytes i call my own read out procedure
     readr();
  } else {
     timer++;
     if (timer%100000==0) {
        //sometimes i check the chip, maybe it freezed, and sometimes need to reboot
        timer=0;

        mrcsat=cc1101.readReg(CC1101_MARCSTATE,CC1101_STATUS_REGISTER); 
  
        cc1101.cmdStrobe(CC1101_SIDLE);
        cc1101.cmdStrobe(CC1101_SFRX);
        cc1101.cmdStrobe(CC1101_SRX);
        
                
      
     }
  }


  
}

My SPI lib

Arduino
I dont remember, maybe has some modification in my SPI lib...
You can read it if something not working, or if you use another chip, like MEGA
No preview (download only).

CRC check library

Arduino
I used an CRC library. Thank you.
No preview (download only).

Credits

kovtam
1 project • 6 followers

Comments