def send_hex(frequency, baud, repeat, data): """ Send a hex string as hex over an RFcat radio :param frequency: :param baud: :param repeat: :param data: :return: """ click.secho('Building RF Data from hex string: {}'.format(data), bold=True) rf_data = bitstring.BitArray(hex=data) # Print some information about what we have so far click.secho('Full PWM key: {}'.format(rf_data.bin), fg='green') click.secho('RF data packet length: {}'.format(len(rf_data)), fg='green') click.secho('Packet as hex: {}'.format(rf_data), fg='green') click.secho('Preparing radio', fg='yellow') # Setup the Radio d = rflib.RfCat() configure_dongle(d, frequency=frequency, pktflen=len(rf_data), baud=baud) # Transmit the data click.secho('Sending transmission \'{}\' time(s)...'.format(repeat), fg='red', bold=True) d.RFxmit(data=rf_data.tobytes(), repeat=repeat) # Idle the radio click.secho('Idling radio', fg='yellow') d.setModeIDLE() return
def jam(frequency, data, baud, maxpower): """ Jam a frequency by continuously sending crap. :param frequency: :param data: :param baud: :param maxpower: :return: """ click.secho('Configuring Radio', fg='yellow') d = rflib.RfCat() configure_dongle(d, frequency=frequency, pktflen=len(data), baud=baud, maxpower=maxpower) click.secho('Starting jam on frequency: {}. Press [ENTER] to stop.'.format( frequency), fg='green') # Fire Ze Lazers! while not keystop(): d.RFxmit(data=data) # Idle the radio click.secho('Idling radio', fg='yellow') d.setModeIDLE()
def radio(self): if self._radio is None: # Single radio configuration. The USB interface gets confused if this used multiple times. self._radio = rflib.RfCat() self._radio.setFreq(314973000) self._radio.setMdmModulation(rflib.MOD_ASK_OOK) self._radio.setMdmDRate(2400) return self._radio
def send_binary(frequency, prefix, suffix, baud, repeat, data, full): """ Send a binary string as hex over an RFcat radio :param frequency: :param prefix: :param suffix: :param baud: :param repeat: :param data: :param full: :return: """ click.secho('Building RF Data from binary string: {}'.format(data), bold=True) if full: # Warn that the data length is a little short for a 'full' key if len(data) <= 12: click.secho('WARNING: Data specified as full binary ' 'but its only {} long'.format(len(data)), fg='yellow') # Convert the data to bytes for the radio to send rf_data = bitstring.BitArray(bin=data).tobytes() else: # Calculate the PWM version of the binary we got. rf_data_string = pwm_encode(data, suffix=suffix, prefix=prefix) click.secho('Full PWM key: {}'.format(rf_data_string), fg='green') # Convert the data to bytes for the radio to send rf_data = bitstring.BitArray(bin=rf_data_string).tobytes() # Print some information about what we have so far click.secho('RF data packet length: {}'.format(len(rf_data)), fg='green') click.secho('Packet as hex: {}'.format(rf_data.encode('hex')), fg='green') click.secho('Preparing radio', fg='yellow') # Setup the Radio click.secho('Configuring Radio', fg='yellow') d = rflib.RfCat() configure_dongle(d, frequency=frequency, pktflen=len(rf_data), baud=baud) # Transmit the data click.secho('Sending transmission \'{}\' time(s)...'.format(repeat), fg='red', bold=True) d.RFxmit(data=rf_data, repeat=repeat) # Idle the radio click.secho('Idling radio', fg='yellow') d.setModeIDLE() return
def main(argv): level = 1 rxid = '' sysid = '' input_hex = '' output_hex = '' output_bin = '' try: opts, args = getopt.getopt(argv, "hl:r:s:", ["level=", "receiver=", "systemid"]) except getopt.GetoptError as error: print(error) print(help_msg) sys.exit(2) for opt, arg in opts: if opt == '-h': print(help_msg) sys.exit() elif opt in ("-l", "--level"): level = int(arg) elif opt in ("-r", "--receiver"): rxid = int(arg) elif opt in ("-s", "--systemid"): sysid = int(arg) if len(sys.argv) == 1: print('Invalid input, program accepts the following input format:\n' + help_msg) sys.exit(2) level, rxid, sysid = ValidateInputs(level, rxid, sysid) #Generate packet hex input_hex = PacketValues(level, rxid, sysid) #Convert hex to binary ascii stream input_bin = hex_to_binary(input_hex) #Convert binary data to format that the radio is expecting. 1 = 1110 0 = 1000 for bit in input_bin: if bit == '0': output_bin += '1000' elif bit == '1': output_bin += '1110' else: print("lolwut?") rf_data = bitstring.BitArray(bin=output_bin + data_spoiler).tobytes() keyLen = len(rf_data) #Configure Radio here. d = rflib.RfCat() ConfigureD(d) #Transmit here. print('Sending packet payload 4*: ' + input_hex) d.RFxmit(rf_data, repeat=3) d.setModeIDLE() print('Done!') quit()
def init(): d = rflib.RfCat() # Set Modulation. We using On-Off Keying here d.setMdmModulation(rflib.MOD_ASK_OOK) # Configure the radio #d.makePktFLEN(len(rf_data)) # Set the RFData packet length d.setMdmDRate(4800) # Set the Baud Rate d.setMdmSyncMode(0) # Disable preamble d.setFreq(433920000) # Set the frequency return d
def _open_data(self, data): if type(data) == str: if data == '-': data = rflib.RfCat() data._debug = 1 freq = int(self._low_freq) spc = int(self._spacing) numChans = int((self._high_freq-self._low_freq) / self._spacing) data._doSpecAn(freq, spc, numChans) else: data = pickle.load(file(data,'rb')) if data is None: raise Exception('Data not found') return data
def play(source, repeat): """ Replay frames from a previous recording :param source: :param repeat: :return: """ click.secho('Source Information:') click.secho('Recording Date: {}'.format( datetime.fromtimestamp(source['date'])), bold=True, fg='green') click.secho('Recording Frequency: {}'.format(source['frequency']), bold=True, fg='green') click.secho('Recording Baud: {}'.format(source['baud']), bold=True, fg='green') click.secho('Recording Framecount: {}'.format(source['framecount']), bold=True, fg='green') # Setup RFCat click.secho('Configuring Radio', fg='yellow') d = rflib.RfCat() configure_dongle(d, frequency=source['frequency'], pktflen=0, baud=source['baud']) # Transmit the frames from the recordin click.secho('Processing {} frames from the source file'.format( source['framecount']), bold=True) for (index, ), frame in numpy.ndenumerate(source['frames']): oneline_print('Progress [{}/{}]'.format(index + 1, source['framecount'])) # Transmit the frame! d.RFxmit(data=frame.decode('hex'), repeat=repeat) # Try and be nice to the radio by setting it to Idle. click.secho('\nIdling Radio\n', fg='yellow') d.setModeIDLE() return
def configure_RfCat(rf_debug=False): """ create Rflib obj Configure RfCat device returns Rflib obj """ # Start up RfCat c = rflib.RfCat(debug=rf_debug) c.RESET() # Set Modulation. We using On-Off Keying here c.setMdmModulation(rflib.MOD_ASK_OOK) # Configure the radio c.makePktFLEN(230) # Set the RFData packet length c.setMdmDRate(DRATE) # Set the Baud Rate c.setMdmSyncMode(0) # Disable preamble c.setMdmSyncWord(0x000) c.setFreq(rf_freq) # Set the frequency c.setEnableMdmManchester(0) # c.setMaxPower() if TX_Power: c.setPower(TX_Power) if chan_bw: c.setMdmChanBW(chan_bw) if verbose: bw = c.getMdmChanBW() dr = c.getMdmDRate() f1 = c.getFreq() print("DRate:", dr, bw) print("Freq:", f1[0]) return c
import rflib from bottle import route, run, abort import devices.rfdevices as rf d = rflib.RfCat() @route('/fireplace/<action>') def control_fireplace(action): if action == 'on': rf.Fireplace().turnon(d) elif action == 'off': rf.Fireplace().turnoff(d) else: abort(404, "Not Found") return "ok" @route('/bedroom-2-light/<action>') def control_light(action): if action == 'on': rf.Bedroom2FanLight().turn_light_on(d) elif action == "off": rf.Bedroom2FanLight().turn_light_off(d) else: abort(404, "Not Found") return "ok" @route('/bedroom-2-fan/<action>') def control_fan(action):
def main(argv): data = 1 rxid = '' sysid = '' sysid_lower = False sysid_upper = False sysid_range = False sysid_single = False record = False bruteforce = False input_hex = '' output_hex = '' try: opts, args = getopt.getopt(argv,"hl:u:s:b:r:",["lower=","upper=","systemid","bruteforce","record"]) except getopt.GetoptError as error: print(error) print(help_msg) sys.exit(2) for opt, arg in opts: if opt == '-h': print(help_msg) sys.exit() elif opt in ("-l", "--lower"): sysid_lower = int(arg) sysid_single = False record = False elif opt in ("-u", "--upper"): sysid_upper = int(arg) sysid_single = False record = False elif opt in ("-s", "--systemid"): sysid = int(arg) sysid_range = False sysid_single = True record = False elif opt in ("-r", "--record"): running = int(arg) bruteforce = False sysid_single = False sysid_range = False record = True elif opt in ("-b", "--bruteforce"): bruteforce = True sysid_single = False sysid_range = False record = False sysid_lower = 1 sysid_upper = 16383 if len(sys.argv) == 1: print('Invalid input, program accepts the following input format:\n' + help_msg) sys.exit(2) if (sysid_lower or sysid_upper) and sysid: print('Invalid input, cannot accept range AND single System ID!') if (sysid_lower and sysid_upper) and not bruteforce: print('Generating System ID ' + str(sysid_lower) + ' through ' + str(sysid_upper)) sysid_range = True sysid_single = False if not (sysid_lower and sysid_upper) and sysid: print('Sending single System ID ' + str(sysid)) sysid_range = False if (sysid_lower and sysid_upper) and bruteforce: print('Generating System ID ' + str(sysid_lower) + ' through ' + str(sysid_upper)) sysid_range = False sysid_single = False if sysid_single: sysid = ValidateInput_sysid_single(sysid) #Generate packet hex input_hex = PacketValues(sysid, 6) #Convert hex to binary ascii stream input_bin = hex_to_binary(input_hex) input_bin = input_bin[4:] #Removing extra null byte output_bin = FormatBitFrame_tx(input_bin) #print('Configuring RfCat...') d = rflib.RfCat() d.setModeIDLE() #print('Configuring Radio...') ConfigureD(d) sync_frame = "000001" data_frame = "001000000001001000" #value = 2 null_tail = "000000" TransmitData(output_bin, input_hex, d, sync_frame, data_frame, null_tail, 3) time.sleep(0.01) d.setModeIDLE() print('Done!') quit() if sysid_range: sysid_lower = ValidateInput_sysid_lower(sysid_lower, sysid_upper) sysid_upper = ValidateInput_sysid_upper(sysid_lower, sysid_upper) #print('Configuring RfCat...') d = rflib.RfCat() d.setModeIDLE() #print('Configuring Radio...') ConfigureD(d) sync_frame = "000001" data_frame = "001000000001001000" #value = 2 null_tail = "000000" for i in range(sysid_lower, sysid_upper+1, 1): #Generate packet hex input_hex = PacketValues(i, 6) #Convert hex to binary ascii stream input_bin = hex_to_binary(input_hex) input_bin = input_bin[4:] #Removing extra null byte output_bin = FormatBitFrame_tx(input_bin) TransmitData(output_bin, input_hex, d, sync_frame, data_frame, null_tail, 3) time.sleep(0.005) d.setModeIDLE() print('Done!') quit() if bruteforce: sysid_lower = ValidateInput_sysid_lower(sysid_lower, sysid_upper) sysid_upper = ValidateInput_sysid_upper(sysid_lower, sysid_upper) #print('Configuring RfCat...') d = rflib.RfCat() d.setModeIDLE() #print('Configuring Radio...') ConfigureD(d) sync_frame = "000001 000001 001000 000001 001000" data_frame = "001000 001000 001000 000001 001000" #value = 2 null_tail = "000000" rand_list = list(range(sysid_lower, sysid_upper+1, 1)) random.shuffle(rand_list) for i in rand_list: #Generate packet hex input_hex = PacketValues(i, 6) #Convert hex to binary ascii stream input_bin = hex_to_binary(input_hex).lstrip("0") #print(input_bin + ' ' + str(len(input_bin))) input_bin = PadBytes(14, input_bin) #print(input_bin + ' ' + str(len(input_bin))) output_bin = FormatBitFrame_tx(input_bin) TransmitData(output_bin, input_hex, d, sync_frame, data_frame, null_tail, 3) time.sleep(0.005) d.setModeIDLE() print('Done!') quit() if record: rxlist = [] now = datetime.datetime.now() logfile = 'linear_' + str(now.isoformat()).replace(':','_') + '.log' print('Saving packet data to ' + logfile) log = open(logfile, 'w') log.write('Linear Packet Log\n') #print('Configuring RfCat...') d = rflib.RfCat() #d.setModeIDLE() #print('Configuring Radio...') ConfigureD(d) while running > 0: running = running-1 print(str(running) + ' Seconds remaining') for payload in Capture(d): if '1' in payload[:1] and (len(payload) == 136) and (len(payload) % 2 == 0): binary = "00000"+payload+"000000000" if len(binary) == 150: log = open(logfile, 'a') now = datetime.datetime.now() Linear_packet = [] Linear_packet_raw = FormatBitFrame_rx(binary) log.write('-'*25 + '\n' + str(now.isoformat()) + '\nLinear Packet: ' + Linear_packet_raw) print('-'*25 + '\n' + str(now.isoformat()) + '\nLinear Packet: ' + Linear_packet_raw) Linear_packet_systemid_rx = str(int(Linear_packet_raw[1:len(Linear_packet_raw)-3], 2)) log.write('\nSystem ID: ' + Linear_packet_systemid_rx) print('System ID: ' + Linear_packet_systemid_rx) Linear_packet_data = str(int(Linear_packet_raw[len(Linear_packet_raw)-3:], 2)) log.write('\nData: ' + Linear_packet_data + '\n') print('Data: ' + Linear_packet_data + '\n') log.close() Linear_packet += binary, Linear_packet_raw, Linear_packet_systemid_rx, Linear_packet_data rxlist += Linear_packet else: continue #for pkt in rxlist: # print(pkt) d.setModeIDLE() print('Done!') if not [sysid_range, sysid_single, record, bruteforce]: print('Incomplete parameters specified!') print(help_msg)
def _create_device(): if Radio.device is None: Radio.device = rflib.RfCat()
def bruteforce(frequency, baud, maxpower, start, end, repeat, prefix, suffix): """ Brute force an OOK signal by sending permutations of a bitstring. :param frequency: :param baud: :param maxpower: :param start: :param end: :param repeat: :param prefix: :param suffix: :return: """ start = bitstring.BitArray(bin=start) end = bitstring.BitArray(bin=end) click.secho('Start binary : \'{}\' or \'{}\' as an integer'.format( start.bin, start.uint), fg='green') click.secho('End binary : \'{}\' or \'{}\' as an integer'.format( end.bin, end.uint), fg='green') # Ensure that the start value is less than the end value if start.uint > end.uint: click.secho('Start position is larger than end position.', fg='red') return click.secho('Generating {} combinations...'.format(end.uint - start.uint), fg='green', bold=True) # Placeholder for all of the PWM permutations that # will be calculated. permutations = [] # Set the current value to the start value as a starting # point for the brute force current_value = start.uint # Loop over the range and generate PWM encoded strings to # send along with the radio while current_value < end.uint: # Get a proper BitArray instance of the binary binary = bitstring.BitArray(bin=bin(current_value)) # Get the PWM version of the binary string pwm_data = pwm_encode(binary.bin, prefix=prefix, suffix=suffix) # Add the permutation and append the current value permutations.append(pwm_data) current_value += 1 click.secho('Configuring Radio', fg='yellow') d = rflib.RfCat() configure_dongle(d, frequency=frequency, pktflen=len(permutations[0]), baud=baud, maxpower=maxpower) click.secho( 'Running brute force with a total of ({} combinations * {} repeats) {} RF transmits.' .format(len(permutations), repeat, len(permutations) * repeat), bold=True) # Small function used to format a label for the progressbar def show_current_data(data): return '[Current PWM string: {}]'.format(data) # Run the brute force with click.progressbar(permutations, show_pos=True, item_show_func=show_current_data) as combinations: for combination in combinations: # Generate the bytes needed for the RFXmit rf_data = bitstring.BitArray(bin=combination).tobytes() # Send the data using the radio d.RFxmit(data=rf_data, repeat=repeat) # Idle the radio click.secho('Idling radio', fg='yellow') d.setModeIDLE()
def search(start_frequency, end_frequency, baud, increment, framecount): """ Search for a signal :param start_frequency: :param end_frequency: :param baud: :param increment: :param framecount: :return: """ click.secho('Starting on frequency: {}'.format(start_frequency), fg='green') click.secho('Ending on frequency: {}'.format(end_frequency), fg='red') # Setup RFCat click.secho('Configuring Radio', fg='yellow') d = rflib.RfCat() configure_dongle(d, frequency=start_frequency, pktflen=0, baud=baud, lowball=True) # The frequency variable is used to track the current # frequency that we are scanning. frequency = start_frequency # The signals variable will hold all of the frequencies # and the valid data packets found for that frequency. signals = dict() click.secho('\nScanning frequency range. Press [ENTER] to stop.', fg='green', bold=True) # Lables for the values that will update during scanning click.secho('Frequency | Framecount | Found', dim=True) # While ENTER has not yet been pressed, iterate over # the frequencies as calculated for x abount of frame counts. # Each time valid data is detected, the data frame is added # to a dictionary using the frequency it was detected on as # the key. while not keystop(): # Read packets 'framecount' amount of times for framecounter in xrange(0, framecount): # Status Update. Spacing is to match up with the previously # echoed 'lables'. oneline_print('{} | {}/{} | {}'.format( frequency, framecounter, framecount, len(signals))) # This try/except is just to catch the UsbTimeout # that gets thrown if data has not been received in # the time specified in RFrecv. try: # Get a packet from the RFcat radio pkt, _ = d.RFrecv(timeout=1000) packet = pkt.encode('hex') # If we have a 'valid' packet, append it as a frame # to the frequency. A valid packet is defined as one # that has 38 0's in its hex representation. if valid_packet(packet=packet, constraint='0' * 38): # If this is the first time we are seeing valid # data on this frequency, prepare a data dict # with the first packet added. if frequency not in signals: signals[frequency] = {'data': [(pkt, packet)]} # Otherwise, just append the packet we just got # to the existing dict for this frequency else: signals[frequency]['data'].append((pkt, packet)) # A timeout in RFrecv will raise an exception. except rflib.ChipconUsbTimeoutException: pass # Set the new frequency incremented by the # increment count. If we have passed the end # frequency, reset back to the start. if frequency > end_frequency: frequency = start_frequency else: frequency += increment # Update the radio to the new frequency d.setFreq(freq=frequency) # Try and be nice to the radio by setting it to Idle. click.secho('\nIdling Radio\n', fg='yellow') d.setModeIDLE() # If we found nothing, just end. if not signals: click.secho('No signals were found.', fg='red') return # Sort the output signals. # signals.items() translates into a list of tuples with # t[0] being the frequency and t[1] the data: # eg: # [(433800000, {'data': ['x', 'x', 'x']})] f = sorted(signals.items(), key=lambda t: (len(t[1]['data']), t[0]), reverse=True) # Iterate the sorted list, printing how many data packets # were found on what frequency. click.secho('# of valid packets per frequency', fg='green') click.secho('Frequency | # packets', bold=True) for frequency, data in f: click.secho('{} | {}'.format(frequency, len(data['data']))) return
def record(frequency, baud, framecount, destination): """ Record symbols from an RFCat dongle to a file. :param frequency: :param baud: :param framecount: :param destination: :return: """ click.secho('Recording on frequency: {} to {}'.format( frequency, destination), fg='green') # Setup RFCat click.secho('Configuring Radio', fg='yellow') d = rflib.RfCat() configure_dongle(d, frequency=frequency, pktflen=0, baud=baud, lowball=True) # The final payload that will be written payload = { 'date': time.mktime(datetime.now().timetuple()), 'frequency': frequency, 'baud': baud, 'framecount': 0, 'frames': [] } # A help message to get maximum # of frames written to file. click.secho( 'For maximum frames, press and release the remote multiple times.', fg='green') # Capture frames! for c in xrange(0, framecount): oneline_print('Progress [{}/{}] Frames: {}'.format( c, framecount, len(payload['frames']))) # This try/except is just to catch the UsbTimeout # that gets thrown if data has not been received in # the time specified in RFrecv. try: # Get a packet from the RFcat radio pkt, _ = d.RFrecv(timeout=1000) packet = pkt.encode('hex') # If we have a 'valid' packet, append it as a frame # to the frequency. A valid packet is defined as one # that has 38 0's in its hex representation. if valid_packet(packet=packet, constraint='0' * 38): payload['framecount'] += 1 payload['frames'].append(packet) # A timeout in RFrecv will raise an exception. except rflib.ChipconUsbTimeoutException: pass # Try and be nice to the radio by setting it to Idle. click.secho('\nIdling Radio\n', fg='yellow') d.setModeIDLE() click.secho('Writing saved payload to: {}'.format(destination), bold=True) with open(destination, 'wb') as f: f.write(json.dumps(payload)) return