#!/usr/bin/env python
# GoodFET Chipcon RF Radio Client
#
-# (C) 2009 Travis Goodspeed <travis at radiantmachines.com>
+# (C) 2009, 2012 Travis Goodspeed <travis at radiantmachines.com>
#
# This code is being rewritten and refactored. You've been warned!
#Set up the radio for ZigBee
self.strobe(0x01); #SXOSCON
self.strobe(0x02); #SCAL
- self.poke(0x11, 0x0AC2); #MDMCTRL0
+ self.poke(0x11, 0x0AC2 & (~0x0800)); #MDMCTRL0, promiscuous
self.poke(0x12, 0x0500); #MDMCTRL1
self.poke(0x1C, 0x007F); #IOCFG0
self.poke(0x19, 0x01C4); #SECCTRL0, disabling crypto
- self.RF_setsync();
+ #self.poke(0x19, 0x0204); #SECCTRL0, as seen elsewhere.
+ #self.RF_setsync();
def ident(self):
return self.peek(0x1E); #MANFIDL
self.strobe(0x04); #0x05 for CCA
def CC_RFST_RX(self):
"""Switch the radio to RX mode."""
- self.strobe(0x03);
+ self.strobe(0x03); #RX ON
def CC_RFST_CAL(self):
"""Calibrate strobe the radio."""
- self.strobe(0x02);
+ self.strobe(0x02); #RX Calibrate
def CC_RFST(self,state=0x00):
self.strobe(state);
return;
#Radio stuff begins here.
def RF_setenc(self,code="802.15.4"):
"""Set the encoding type."""
- return;
+ return code;
def RF_getenc(self):
"""Get the encoding type."""
return "802.15.4";
self.poke(0x14,sync);
return;
+ def RF_setkey(self,key):
+ """Sets the first key for encryption to the given argument."""
+ print "ERROR: Forgot to set the key.";
+
+ return;
+ def RF_setnonce(self,key):
+ """Sets the first key for encryption to the given argument."""
+ print "ERROR: Forgot to set the nonce.";
+
+ return;
+
def RF_setfreq(self,frequency):
"""Set the frequency in Hz."""
mhz=frequency/1000000;
- fsctrl=0x8000; #self.peek(0x18)&(~0x3FF);
+ #fsctrl=0x8000; #
+ fsctrl=self.peek(0x18)&(~0x3FF);
fsctrl=fsctrl+int(mhz-2048)
self.poke(0x18,fsctrl);
+ #self.CC_RFST_IDLE();
self.strobe(0x02);#SCAL
+ time.sleep(0.01);
self.strobe(0x03);#SRXON
def RF_getfreq(self):
"""Get the frequency in Hz."""
"""Set the target MAC address."""
return 0xdeadbeef;
def RF_getrssi(self):
- """Returns the received signal strenght, with a weird offset."""
+ """Returns the received signal strength, with a weird offset."""
rssival=self.peek(0x13)&0xFF; #raw RSSI register
return rssival^0x80;
+
+ def peekram(self,adr,count):
+ """Peeks data from CC2420 RAM."""
+ data=[
+ adr&0xFF,adr>>8, # Address first.
+ count&0xFF,count>>8 # Then length.
+ ];
+ self.writecmd(self.CCSPIAPP,0x84,len(data),data);
+ return self.data;
+ def pokeram(self,adr,data):
+ """Pokes data into CC2420 RAM."""
+ data=[adr&0xFF, adr>>8]+data;
+ self.writecmd(self.CCSPIAPP,0x85,len(data),data);
+ return;
+
lastpacket=range(0,0xff);
def RF_rxpacket(self):
- """Get a packet from the radio. Returns None if none is waiting. In
- order to not require the SFD, FIFO, or FIFOP lines, this
- implementation works by comparing the buffer to the older
- contents.
- """
+ """Get a packet from the radio. Returns None if none is
+ waiting."""
data="\0";
self.data=data;
self.lastpacket=buffer;
if(len(buffer)==0):
return None;
+
+ return buffer;
+ def RF_rxpacketrepeat(self):
+ """Gets packets from the radio, ignoring all future requests so as
+ not to waste time. Call RF_rxpacket() after this."""
+
+ self.writecmd(self.CCSPIAPP,0x91,0,None);
+ return None;
+
+ def RF_rxpacketdec(self):
+ """Get and decrypt a packet from the radio. Returns None if
+ none is waiting."""
+
+ data="\0";
+ self.data=data;
+ self.writecmd(self.CCSPIAPP,0x90,len(data),data);
+ buffer=self.data;
+
+ self.lastpacket=buffer;
+ if(len(buffer)==0):
+ return None;
+
return buffer;
+
def RF_txpacket(self,packet):
"""Send a packet through the radio."""
self.writecmd(self.CCSPIAPP,0x81,len(packet),packet);
choice=choices[len];
self.poke(0x03,choice);
self.maclen=len;
- def printpacket(self,packet):
+ def printpacket(self,packet,prefix="#"):
+ print self.packet2str(packet,prefix);
+ def packet2str(self,packet,prefix="#"):
s="";
i=0;
for foo in packet:
s="%s %02x" % (s,ord(foo));
- print "#%s" % s;
+ return "%s%s" % (prefix,s);
def printdissect(self,packet):
try: