text: #!/usr/bin/env nodejs
  
  var noble = require('noble');
  var ble = require('../support/ble')
  var utils = require('../support/utils')
  var bmdware = require('../support/bmdware')
  var async = require('async')
  var commander = require('commander')
  
  var callbackAfterBeaconDiscovery
  var beaconUnderTestId
  
  var testConfig
  var testResult = 'FAIL'
  var testNote = ''
  var testShouldContinue = true
  var testTimer
  
  var expected_results = []
  var results = []
  
  var onDataCompleteCallback
  
  var txPowerValue = 0xfc
  var rssiValue = 0xc0
  
  function testSetup(setupCompleteCallback) {	
      async.series([
          function(callback) {
              ble.findTestDevice(bmdware.getBmdwareServiceUuids(), function(deviceFound) {
                  if(!deviceFound) {
                      testNote = 'Could not find a BMDware test device!'
                      testShouldContinue = false
                      setupCompleteCallback()
                  }
                  callback()
              })
          },
          function(callback) {
              if(setupCompleteCallback) {
                  setupCompleteCallback()
              }
          }
      ]);
  }
  
  function onData(data, isNotification) {
      utils.log(5, "Returned Code error: %d", data[0])
      utils.log(5, "Returned Code String: " + bmdware.returnCodeStr[data[0]])
      utils.log(1, "data = " + data.toString('hex'))
  
      if(onDataCompleteCallback) {
          utils.log(5, "onDataCompleteCallback")
          var expected = expected_results.pop()
          if(expected != null) {
              var result = false
              if (data.length > expected.length) {
                  var actual = new Buffer(data.slice(0, expected.length))
                  result = utils.compareBuffers(expected, actual)
              }
              else {
                  result = utils.compareBuffers(expected, data)
              }
              results.push(result)
          }
          onDataCompleteCallback()
      } else {
          utils.log(5, 'onDataCompleteCallback is null?!?!')
      }
  }
  
  function testRssiCalibration(testCompleteCallback) {
      if(!testShouldContinue) {
          testCompleteCallback()
          return
      }
  
      async.series([
          function(callback) {
              utils.log(5, "RSSI Calibration test connect")
              ble.connectPeripheralUT(function(connectResult) {
                  if(!connectResult) {
                      testNote = 'Failed to connect to device!'
                      testShouldContinue = false
                      testCompleteCallback()
                  }
                  callback()
              })
          },
          function(callback) {
              utils.log(5, "Notification enable")
              bmdware.configureBleReceiveNotifications(onData, callback)
          },
          function(callback) {
              utils.log(5, "Set RSSI Calibration")
              onDataCompleteCallback = callback
              expected_results.push(new Buffer([bmdware.RC_SUCCESS]))
              bmdware.setRssiCalibrationData(txPowerValue, rssiValue, null)
          },
          function(callback) {
              utils.log(5, "Get RSSI Calibration")
              onDataCompleteCallback = callback
              expected_results.push(new Buffer([0x41, txPowerValue, rssiValue]))
              bmdware.getRssiCalibrationData(null)
          },
          function(callback) {
              testResult = 'PASS'
              for (i = 0; i < results.length; i++) {
                  if(results.pop() != true) {
                      testResult = 'FAIL'
                      break
                  }
              }
  
              utils.log(5, "Test : " + testResult)
  
              utils.log(5, "RSSI Calibration test done")
              if(testCompleteCallback) {
                  testCompleteCallback()
              }
          } 
      ]);
  }
  
  function testTearDown(tearDownCompleteCallback) {
      if(!testShouldContinue) {
          tearDownCompleteCallback()
          return
      }
  
      async.series([
          function(callback) {
              utils.log(5, "TearDown connect")
              ble.connectPeripheralUT(function(connectResult) {
                  if(!connectResult) {
                      utils.log(2, 'Failed to connect to device for teardown')
                      tearDownCompleteCallback()
                  }
                  callback()
              })
          },
          function(callback) {
              utils.log(5, "Notification Disable")
              bmdware.disableBleReceiveNotifications(callback, callback)
          },
          function(callback) {
              utils.log(5, "TearDown disconnect")
              ble.disconnectPeripheralUT(function(disconnectResult) {
                  if(!disconnectResult) {
                      utils.log(2, 'Failed to disconnect after tear down!')
                  }
                  callback()
              })
          },
          function(callback) {
              utils.log(5, "TearDown done")
              if(tearDownCompleteCallback) {
                  tearDownCompleteCallback()
              }
          }
      ]);
  }
  
  function testRunner(testCompleteCallback) {
      ble.loadConfiguration('test_config.json')
      testConfig = ble.getConfiguration()
      async.series([
          function(callback) {
              testSetup(callback)
          },
          function(callback) {
              testRssiCalibration(callback)
          },
          function(callback, peripheral) {
              testTearDown(callback)
          },
          function(callback) {
              utils.log(5, "RSSI Calibration Test Complete")
              if(testCompleteCallback) {
                  testCompleteCallback(testResult, testNote)  
              } else {
                  process.exit(0)
              }
          }
      ])
  }
  
  function getName() {
          return 'RSSI Calibration Test'
      }
  
  //run all tests
  module.exports = {
      testRunner: testRunner,
      getName: getName
  }
  
  commander.
      version('1.0.0').
      usage('[options]').
      option('-r, --run', 'Run as stand alone test').
      parse(process.argv);
  
  if(commander.run) {
      utils.log(1, "Running test: " + getName())
      testRunner(function(testResult, testNote) {
          utils.log(1, "Test Result: " + testResult)
          if(testNote.length > 0) {
              utils.log(1, "Test Note: " + testNote)
          }
          process.exit(0)
      }) 
  }
  