Monday, October 8, 2018

"Full Boat" - flew to Lompoc, CA to watch the Falcon 9 launch

I flew down to Lompoc, CA on Sunday with Miles, and our friends the Baalmans (Gary, Laura, & their two kids) to watch the SpaceX Falcon 9 launch at Vandenberg AFB. This was the first Falcon 9 "return to land" on the west coast, and it went spectacularly. We found a great viewing spot along HWY 1 overlooking the launchpad.




Wednesday, September 12, 2018

Monday, July 30, 2018

I bought a new aircraft!


I decided, at long last, it was time to upgrade to something capable of more speed, altitude, and carrying my family.   N6779B is a 1978 Cessna T210M.  It's turbocharged and capable of climbing into the flight levels, so it's much more suitable for getting in and out of the Sierras.  ;)

Adventures to come!

Sunday, January 21, 2018

Sonoff S31 Disassemble and Flash Instructions

I recently bought some Sonoff S31 "smart outlet" switches, as I like the form factor better than the Sonoff Basic and the larger Sonoff S20.  I was able to disassemble and flash them with the fantastic Sonoff-Tasmota firmware from Theo Arends.

Disassembly instructions:

1. The darker colored square panel with the button on it snaps off.  Pry it carefully off from one side to remove it:

2. There's two "slide-out" corner pieces on the male plug side. Slide these towards the button side:


3. Remove the three screws that are now exposed:


4. The case containing the female outlet side should separate easily now.  No prying necessary:


5. The circuit board is actually two boards soldered together in an "L" shape.  The small edge with the button on it contains the serial header for the ESP8266.  From the top down, the connections are VCC, RX, TX, N/C, N/C, GND   (Notice the two unused pads labeled TX & RX.  They don't appear to be connected.)


6. Here's a shot of the ESP8266EX chip on the back of the smaller board, beneath the relay.


7. I soldered a pin-header to the pads to program it.  At the time I didn't know which two TX/RX pins to use so I soldered all four.  You can ignore the lower two.


8. The button is connected to GPIO0, just like the Sonoff Basic.  Press and hold the button while plugging in the USB Serial adapter to put the ESP8266 in flash mode (Follow the flash instructions on the Sonoff-Tasmota project from here.)

The S31 purportedly does power/current monitoring, too.  I haven't tried getting that working yet.  (I'll update this blog post if I get that working too.)  As of this writing the Sonoff-Tasmota 5.11.1 firmware runs on it and controls it as a "Sonoff Basic" just fine.  Relay toggling and button control work as expected.

UPDATE 1: Looking at the board I see the ChipSea 7766 energy monitoring chip. Seems that it sends energy use via uart:
http://www.chipsea.com/UploadFiles/2017/08/11144342F01B5662.pdf

It's connected to the ESP8266 UART0 port through R2.  More to come!

UPDATE 2: Theo Arends added support for the S31 in version Sonoff-Tasmota ver 5.11.1i



Cheers!

Thursday, August 4, 2016

TOWL - Telemetry over Opportunistic WiFi Links

Premise & Background:


Can you build a "LoJack" style asset tracking capability using open WiFi hotspots?

The proliferation of cheap, lightweight WiFi embedded ("IoT") devices made me wonder.  The WiFi association stack, DHCP client stack, et al. has to be incredibly lightweight and simple to fit in the firmware on, say, an ESP8266.  If you programmed one to scan, find an AP, associate, get an address, and send a single packet - would it be able to do it fast enough to report its location from a moving vehicle?

[Aside: This is actually something I've wondered about for years, but the IoT chips offered a unique and low-cost way to try it.]

"But wait," you say, "there really aren't that many open APs these days.  Most of them are captive or paywall portals, or at least make you agree to some goofy ToS."

Right, but as has been pointed out multiple times by multiple people all the way back to Dan Kaminsky's DNS tunneling talk in 2004 - hotspots diligently resolve DNS queries.  All you have to do is base32 encode the data you want to send in the hostname of a valid DNS record request, and set up a DNS server for a subdomain (under a domain you own) to catch the queries.

If it works, you get near real-time telemetry over opportunistic WiFi links using DNS recursion!  Think: "low cost LoJack with no data subscriptions".
Digistump Oak ESP8266

I used the Digistump Oak variant of the ESP8266 prototype boards.  I like the fact that it can be flashed OTA, which proves to be useful once the device is deployed in something like an automobile.

In my testing, the complete chain from calling connectAP() to getting the DNS query response typically takes between 3 and 6 seconds, which is certainly fast enough from a slow moving vehicle.

Device Output


The device stores the telemetry in a 16-byte struct consisting of:

struct telem {
  uint32_t tstamp;  // GPS time in ctime format
  int32_t lat;      // Latitude * 1000000
  int32_t lon;      // Longitude * 1000000
  uint8_t spd;      // Speed in MPH
  uint8_t sats;     // Number of GPS satellites received
  uint8_t id;       // Arbitrary number for ACK
  uint8_t mode;     // Object state information
};  // 16 bytes total

The fields are largely self-explanatory.  You'll notice that I used an 8-bit number for speed, so the max speed it will report is 255 MPH.  Also, the 32-bit ctime field means it's vulnerable to the Year 2038 Problem.

The field worth explanation is "mode", which is set as follows:

Value |   Meaning
 255  |  Startup position.
 254  |  Live. Transmitted and ACKed in realtime
 1-n  |  Stored position

The first few position observations are always flagged as mode 255, regardless of whether they're able to be transmitted live or not.  (This way you know where the device started.)

The stored position value is simply the number of 10-second intervals since last transmission modulo the MAX_INTERVAL setting.  This is how the unit "downsamples" the stored waypoint resolution if the buffer fills up.

So... how well does it work?

Here's a plot on OpenStreetMaps of me driving to work one morning.  The blue markers are live (mode 254) and the red markers are stored.


Of note are the blue markers along the freeway.  I've regularly observed this device successfully logging the telemetry data at speeds upward of 60 MPH! 

Technical Details


Hardware:

  • Digistump Oak
  • NMEA serial GPS module (e.g. uBlox or MTK)

Software:

The software for the Digistump Oak, as well as a PoC DNS server (in python) to log the output, is available here:  
https://github.com/phreakmonkey/towl

Check the README notes under both subdirectories for build dependencies / config notes.

Setup:


You'll need to host a custom nameserver on the Internet to receive the DNS queries.  You'll also need to control a domain so that you can designate your DNS query receiver as a subdomain. 

E.g. if you own the domain "MyDomain.com", you could designate a server to receive the TOWL queries by creating a NS record for "TOWL.MyDomain.com", pointing at the server you intend to run the catcher on. If said server is at IP address 1.2.3.4, then that record looks something akin to:

TOWL IN NS 1.2.3.4

Run the PoC code on the designated server. Be sure to configure both the TOWL devices and the server code for the "TOWL.MyDomain.com" domain name. (See README under each directory for instructions.)

Have fun!

gps tracker dns

Wednesday, July 20, 2016

Script to toggle LEDs on the Netgear Nighthawk AC1900 / R7000

I recently purchased the Netgear Nighthawk AC1900 dual-band router, to go along with my new faster Internet connection.

First off, I'll say- I wasn't a fan of Netgear's past home routers, but this one is quite amazing!  Not only can it keep up with my 1Gbps fiber connection, it also seems to have massively improved the wireless situation in my home over my previous Linksys router.

Anyway, enough of that.  One funny thing about this router, in addition to looking like a 1990s stealth aircraft, is that it's covered with SUPER HIGH INTENSITY WHITE LEDs.  They add to the sleek look, for sure, but you can practically read by them in a dark room.  (!)  Not so great if you happen to sleep in the same room with the router.

Thankfully, the Advanced Setup UI provides a mode to turn off all the LEDs (save for the power LED, which I just stuck a piece of gaffers tape over.)

I like the status LEDs, though, so I thought - wouldn't it be nice to be able to programatically toggle them?

I was hoping I could do it with a simple request from curl, but it turns out you need to auth to the setup page and retrieve a timestamped id token, probably as an anti-CSRF measure (albeit not a bulletproof one.)  So, voila - a quick & dirty python script to toggle the LEDs on the nighthawk router.

Requirements:
Python 2.7
Python requests library

Download link: http://cdn.phreakmonkey.com/r7000-LEDs.py

Script:


#!/usr/bin/python2.7
# Quick and dirty script to toggle the super-bright LEDs on the Netgear
# Nighthawk R7000 router.  Tested on FW V1.0.5.70_1.1.91.  YMMV.

import requests
import sys

# !!!
# IMPORTANT:  Put your actual router password and router IP address below:
# !!!
ROUTERADMIN = 'admin'
ROUTERPASS = 'password'
ROUTERADDR = 'http://192.168.1.1/'

# First, we have to get a valid timestamp from the settings page:
r = requests.get(ROUTERADDR + 'start.htm',
                 auth=(ROUTERADMIN, ROUTERPASS))
r = requests.get(ROUTERADDR + 'LED_settings.htm',
                 auth=(ROUTERADMIN, ROUTERPASS))
o = r.text.find('led_settings.cgi?id=')
if o == -1:
  if r.text.find('multiLogin') > -1:
    print 'Error: Another browser is currently logged into the router.'
  else:  
    print 'Invalid response from router:'
    print r.text
  sys.exit(1)

o2 = r.text[o:].find('"')

# Next, construct the CGI URL with the returned timestamp
led_url = ROUTERADDR + r.text[o:o+o2]

if len(sys.argv) == 2 and sys.argv[1].upper() == 'OFF':
  data = 'Apply=Apply&led_settings=turn_off&led_now=en_blink'
else:
  data = 'Apply=Apply&led_settings=en_blink&led_now=turn_off'

# Send the magic command:
r = requests.post(led_url, data=data, auth=(ROUTERADMIN, ROUTERPASS))
print 'Status code: %d' % r.status_code
#print r.text

# Avoid "multiLogin" errors:
r = requests.get(ROUTERADDR + 'LGO_logout.htm', auth=(ROUTERADMIN, ROUTERPASS))