<commit_before>var util = require('util'); 
var EventEmitter = require('events').EventEmitter;

var PACKET_CONF = 0x55;
var ACK_CONF = 0x33;
var FIN_CONF = 0x16;

var ACK_CMD = 0x00;
var FIRMWARE_CMD = 0x01;
var IR_TX_CMD = 0x02;
var IR_RX_AVAIL_CMD = 0x03;
var IR_RX_CMD = 0x04;
var RX_START_CMD = 0x05;
var RX_STOP_CMD = 0x06;
var MAX_SIGNAL_DURATION = 200;

var Infrared = function(hardware, callback) {

  this.spi = hardware.SPI({clockSpeed : 1000, mode:2});
  this.chipSelect = hardware.gpio(1);
  this.reset = hardware.gpio(2);
  this.irq = hardware.gpio(3);
  this.transmitting = false;
  this.listening = false;
  this.chipSelect.output().high();
  this.reset.output().high();
  this.irq.output().low();

  var self = this;

  console.log('is this thing even on?');

  // If we get a new listener
  this.on('newListener', function(event) {
    // And they are listening for rx data and we haven't been yet
    if (event == "data" && !this.listeners(event).length) {
        self.setListening(1);
    }
  });

  this.on('removeListener', function(event) {
    // If this was for the rx data event and there aren't any more listeners
    if (event == "data" && !this.listeners(event).length) {
        self.setListening(0);
    }
  });

  // Make sure we can communicate with the module
  this.establishCommunication(3, function(err, version) {
    console.log('established...');
    if (err) {
      setImmediate( function() {
        // Emit an error event
        self.emit('error');
      });
    }
    else {
      setImmediate( function() {
        // Emit a ready event
        self.emit('ready');
         // Start listening for IRQ interrupts
        self.irq.watch('high', self.IRQHandler.bind(self));
      });
    }

    // Make sure we aren't gathering rx data until someone is listening.
    self.setListening(0);

    // Complete the setup
    if (callback) {
      callback(err, self);
    } 
  });
};

util.inherits(Infrared, EventEmitter);

Infrared.prototype.IRQHandler = function() {
  var self = this;
  // If we are not in the middle of transmitting
  if (!self.transmitting) {
    // Receive the durations
    self.fetchRXDurations( function fetched() {
    // Start listening for IRQ interrupts again
    self.irq.watch('high', self.IRQHandler.bind(self));
    });
  } else {
    // If we are, check back in a little bit
    setTimeout(self.IRQHandler.bind(self), 500);
  }
};

Infrared.prototype.setListening = function(set, callback) {
  var self = this;

  var cmd = set ? RX_START_CMD : RX_STOP_CMD;

  var response = this.SPITransfer(new Buffer([cmd, 0x00, 0x00]));

  self.validateResponse(response, [PACKET_CONF, cmd], function(valid) {
    
    if (!valid) {
        return callback && callback(new Error("Invalid response on setting rx on/off."));
    }
    else {
      self.listening = set ? true : false;

      if (callback) {
        callback();
      }
    }
  });
};

Infrared.prototype.fetchRXDurations = function(callback) {
  var self = this;
  // We have to pull chip select high in case we were in the middle of something else

  // this.chipSelect.high();
  this.SPITransfer(new Buffer([IR_RX_AVAIL_CMD, 0x00, 0x00, 0x00]), function(response) {
    // DO something smarter than this eventually

    self.validateResponse(response, [PACKET_CONF, IR_RX_AVAIL_CMD, 1], function(valid) {
      if (valid) {
        var numInt16 = response[3];

        // (We have two bytes per element...);
        var numBytes = numInt16 * 2;

        var rxHeader = [IR_RX_CMD, 0x00, 0x00];
        var packet = rxHeader.concat(new Array(numBytes));


        // Push the stop bit on there.
        packet.push(FIN_CONF);

        packet = new Buffer(packet);

        self.SPITransfer(packet, function(response) {

          var fin = response[response.length-1];

          if (fin != FIN_CONF) {
            console.log("Warning: Received Packet Out of Frame.");

            if (callback) {
              callback();
            }
          }

          if (err) {
            if (callback) {
              callback();
            }
            return;// console.log("Issue sending dummy bytes...");
          }

          else {
            // Remove the header echoes at the beginning
            var buf = response.slice(rxHeader.length, response.length);

            // Emit the buffer
            self.emit('data', buf);<commit_msg>Fixes bug where data emitted always had a stop bit<commit_after>var util = require('util'); 
var EventEmitter = require('events').EventEmitter;

var PACKET_CONF = 0x55;
var ACK_CONF = 0x33;
var FIN_CONF = 0x16;

var ACK_CMD = 0x00;
var FIRMWARE_CMD = 0x01;
var IR_TX_CMD = 0x02;
var IR_RX_AVAIL_CMD = 0x03;
var IR_RX_CMD = 0x04;
var RX_START_CMD = 0x05;
var RX_STOP_CMD = 0x06;
var MAX_SIGNAL_DURATION = 200;

var Infrared = function(hardware, callback) {

  this.spi = hardware.SPI({clockSpeed : 1000, mode:2});
  this.chipSelect = hardware.gpio(1);
  this.reset = hardware.gpio(2);
  this.irq = hardware.gpio(3);
  this.transmitting = false;
  this.listening = false;
  this.chipSelect.output().high();
  this.reset.output().high();
  this.irq.output().low();

  var self = this;

  console.log('is this thing even on?');

  // If we get a new listener
  this.on('newListener', function(event) {
    // And they are listening for rx data and we haven't been yet
    if (event == "data" && !this.listeners(event).length) {
        self.setListening(1);
    }
  });

  this.on('removeListener', function(event) {
    // If this was for the rx data event and there aren't any more listeners
    if (event == "data" && !this.listeners(event).length) {
        self.setListening(0);
    }
  });

  // Make sure we can communicate with the module
  this.establishCommunication(3, function(err, version) {
    if (err) {
      setImmediate( function() {
        // Emit an error event
        self.emit('error');
      });
    }
    else {
      setImmediate( function() {
        // Emit a ready event
        self.emit('ready');
         // Start listening for IRQ interrupts
        self.irq.watch('high', self.IRQHandler.bind(self));
      });
    }

    // Make sure we aren't gathering rx data until someone is listening.
    self.setListening(0);

    // Complete the setup
    if (callback) {
      callback(err, self);
    } 
  });
};

util.inherits(Infrared, EventEmitter);

Infrared.prototype.IRQHandler = function() {
  var self = this;
  // If we are not in the middle of transmitting
  if (!self.transmitting) {
    // Receive the durations
    self.fetchRXDurations( function fetched() {
    // Start listening for IRQ interrupts again
    self.irq.watch('high', self.IRQHandler.bind(self));
    });
  } else {
    // If we are, check back in a little bit
    setTimeout(self.IRQHandler.bind(self), 500);
  }
};

Infrared.prototype.setListening = function(set, callback) {
  var self = this;

  var cmd = set ? RX_START_CMD : RX_STOP_CMD;

  var response = this.SPITransfer(new Buffer([cmd, 0x00, 0x00]));

  self.validateResponse(response, [PACKET_CONF, cmd], function(valid) {
    
    if (!valid) {
        return callback && callback(new Error("Invalid response on setting rx on/off."));
    }
    else {
      self.listening = set ? true : false;

      if (callback) {
        callback();
      }
    }
  });
};

Infrared.prototype.fetchRXDurations = function(callback) {
  var self = this;
  // We have to pull chip select high in case we were in the middle of something else

  // this.chipSelect.high();
  this.SPITransfer(new Buffer([IR_RX_AVAIL_CMD, 0x00, 0x00, 0x00]), function(response) {
    // DO something smarter than this eventually

    self.validateResponse(response, [PACKET_CONF, IR_RX_AVAIL_CMD, 1], function(valid) {
      if (valid) {
        var numInt16 = response[3];

        // (We have two bytes per element...);
        var numBytes = numInt16 * 2;

        var rxHeader = [IR_RX_CMD, 0x00, 0x00];
        var packet = rxHeader.concat(new Array(numBytes));


        // Push the stop bit on there.
        packet.push(FIN_CONF);

        packet = new Buffer(packet);

        self.SPITransfer(packet, function(response) {

          var fin = response[response.length-1];

          if (fin != FIN_CONF) {
            console.warn("Warning: Received Packet Out of Frame.");

            if (callback) {
              callback();
            }
          }

          else {
            // Remove the header echoes at the beginning
            var buf = response.slice(rxHeader.length, response.length-1);
            
            // Emit the buffer
            self.emit('data', buf);
{'fraction_non_alphanumeric': 0.1265984654731458, 'fraction_numerical': 0.01801906533364334, 'mean_word_length': 2.5301600328272467, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5635917', 'n_tokens_mistral': 2873, 'n_tokens_neox': 2674, 'n_words': 739}