Merge "conman:  WifiSimulateWireless experiment."
diff --git a/Makefile b/Makefile
index 0c5089a..5de9eaa 100644
--- a/Makefile
+++ b/Makefile
@@ -84,6 +84,10 @@
 DIRS+=presterastats
 endif
 
+ifeq ($(BUILD_LEDPATTERN),y)
+DIRS+=ledpattern
+endif
+
 PREFIX=/usr
 BINDIR=$(DESTDIR)$(PREFIX)/bin
 LIBDIR=$(DESTDIR)$(PREFIX)/lib
diff --git a/cache_warming/fetch_popular.py b/cache_warming/fetch_popular.py
new file mode 100644
index 0000000..fe0f2b4
--- /dev/null
+++ b/cache_warming/fetch_popular.py
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+"""Pre-fetches top requested hosts.
+
+Sorts dictionary represented in hit_log.json by number of hits
+and sends DNS requests to a predetermined number of the top hosts.
+"""
+
+import argparse
+import json
+import dns.resolver
+
+TOP_N = 50
+HITS_LOG_JSON_PATH = '/tmp/hits_log.json'
+
+
+def sort_hits_log(path):
+  """Sorts hosts in hits log by number of hits.
+
+  Args:
+    path: Path of JSON representation of dictionary mapping host
+          to tuple of most recent hit time and hit count.
+
+  Returns:
+    A list of hosts sorted by number of hits in descending order.
+  """
+  try:
+    log_json = open(path, 'r')
+  except IOError:
+    print 'unable to open ' + path
+    raise
+  else:
+    log = json.load(log_json)
+    return sorted(log, key=log.get, reverse=True)
+
+
+def prefetch(hosts, port, server):
+  """Pre-fetches list of hosts.
+
+  Args:
+    hosts: List of hosts to be fetched sorted by number of hits
+           in descending order.
+    port: Port to which to send queries (default is 53).
+    server: Alternate nameservers to query (default is None).
+  """
+  my_resolver = dns.resolver.Resolver()
+  my_resolver.port = port
+  if server is not None:
+    my_resolver.nameservers = server
+
+  if len(hosts) > TOP_N:
+    hosts = hosts[:TOP_N]
+  for host in hosts:
+    my_resolver.query(host)
+
+
+if __name__ == '__main__':
+  parser = argparse.ArgumentParser()
+  parser.add_argument('-p', '--port', nargs='?', default=53, type=int,
+                      help='port to which to send queries (default is 53).')
+  parser.add_argument('-s', '--server', nargs='*', type=str,
+                      help='alternate nameservers to query (default is None).')
+  args = parser.parse_args()
+
+  sorted_log = sort_hits_log(HITS_LOG_JSON_PATH)
+  prefetch(sorted_log, args.port, args.server)
diff --git a/cache_warming/fetch_popular_test.py b/cache_warming/fetch_popular_test.py
new file mode 100644
index 0000000..ea9da8d
--- /dev/null
+++ b/cache_warming/fetch_popular_test.py
@@ -0,0 +1,39 @@
+#!/usr/bin/python
+"""Tests for fetch_popular.py."""
+
+import os
+import fetch_popular
+from wvtest import wvtest
+
+
+@wvtest.wvtest
+def testSortHitsLog_empty():
+  try:
+    file_name = 'test_log.json'
+    with open(file_name, 'w') as f:
+      f.write('{}')
+
+    expected = []
+    actual = fetch_popular.sort_hits_log(file_name)
+    wvtest.WVPASSEQ(actual, expected)
+  finally:
+    os.remove(file_name)
+
+
+@wvtest.wvtest
+def testSortHitsLog_nonEmpty():
+  try:
+    file_name = 'test_log.json'
+    with open(file_name, 'w') as f:
+      f.write('{"www.google.com": [2, "123456789"], "www.yahoo.com":'
+      	       ' [1,"987654321"], "www.espn.com": [3, "135792468"]}')
+
+    expected = ['www.espn.com', 'www.google.com', 'www.yahoo.com']
+    actual = fetch_popular.sort_hits_log(file_name)
+    wvtest.WVPASSEQ(actual, expected)
+  finally:
+    os.remove(file_name)
+
+
+if __name__ == '__main__':
+  wvtest.wvtest_main()
diff --git a/cache_warming/log_hits.py b/cache_warming/log_hits.py
new file mode 100644
index 0000000..5fbc2e8
--- /dev/null
+++ b/cache_warming/log_hits.py
@@ -0,0 +1,124 @@
+#!/usr/bin/python
+"""Updates most recent hit time and hit count for hosts in hits log.
+
+Reads queries from dns_query_log.txt and updates hosts in hits log
+dictionary with most recent hit time and hit count for each host.
+Saves hits log dictionary as hits_log.json for future modification.
+"""
+
+import json
+import os.path
+
+DNS_QUERY_LOG_PATH = '/tmp/dns_query_log.txt'
+HITS_LOG_JSON_PATH = '/tmp/hits_log.json'
+
+
+def process_line(log, ln):
+  """Processes a line of DNS query log and updates hits log.
+
+  Parses line and updates most recent hit time and hit count
+  for host in hits log.
+
+  Args:
+    log: Dictionary mapping host to tuple of hit count and most
+         recent hit time.
+    ln: String representing a line of DNS query log of the
+          format '[Unix time] [host name]'.
+
+  Returns:
+    An updated dictionary mapping host to tuple of hit count and
+    most recent hit time.
+  """
+  time, _, host = ln[:-1].partition(' ')
+  if host in log:
+    log[host] = (log[host][0] + 1, time)
+  else:
+    log[host] = (1, time)
+  return log
+
+
+def read_dns_query_log(path):
+  """Reads a DNS query log.
+
+  Processes each line of file, updating a hits log.
+
+  Args:
+    path: Path of DNS query log to be read.
+
+  Returns:
+    An updated dictionary mapping host to tuple of hit count and
+    most recent hit time.
+  """
+  try:
+    dns_query_log = open(path, 'r')
+  except IOError:
+    print 'unable to open ' + path
+  else:
+    log = {}
+    for line in dns_query_log:
+      log = process_line(log, line)
+    dns_query_log.close()
+    return log
+
+
+def clear_dns_query_log(path):
+  """Clears a DNS query log.
+
+  Opens file for write without writing anything.
+
+  Args:
+    path: Path of DNS query log to be cleared.
+  """
+  try:
+    open(path, 'w').close()
+    return
+  except IOError:
+    print 'unable to open ' + path
+
+
+def merge_logs(log, hist):
+  """Merges two hit logs.
+
+  Merges smaller hit log to larger hit log. Uses most recent hit
+  time and sums hit count from each log for each host.
+
+  Args:
+    log: Dictionary mapping host to tuple of hit count and
+         most recent hit time.
+    hist: Similar dictionary representing previous query history.
+
+  Returns:
+    An updated dictionary mapping host to tuple of hit count and
+    most recent hit time.
+  """
+  hist_larger = len(hist) > len(log)
+  big_log, small_log = (hist, log) if hist_larger else (log, hist)
+  for k, v in small_log.iteritems():
+    if k in big_log:
+      time = log[k][1]
+      big_log[k] = (big_log[k][0] + v[0], time)
+    else:
+      big_log[k] = (v[0], v[1])
+  return big_log
+
+
+if __name__ == '__main__':
+  hit_log = read_dns_query_log(DNS_QUERY_LOG_PATH)
+  clear_dns_query_log(DNS_QUERY_LOG_PATH)
+  if os.path.isfile(HITS_LOG_JSON_PATH):
+    hist_json = open(HITS_LOG_JSON_PATH, 'r')
+    hit_log_hist = json.load(hist_json)
+    hist_json.close()
+
+    hist_json = open(HITS_LOG_JSON_PATH, 'w')
+    json.dump(merge_logs(hit_log, hit_log_hist), hist_json)
+    hist_json.close()
+  else:
+    try:
+      hist_json = open(HITS_LOG_JSON_PATH, 'w')
+    except IOError:
+      print 'unable to open ' + HITS_LOG_JSON_PATH
+      raise
+    else:
+      json.dump(hit_log, hist_json)
+      hist_json.close()
diff --git a/cache_warming/log_hits_test.py b/cache_warming/log_hits_test.py
new file mode 100644
index 0000000..26944ce
--- /dev/null
+++ b/cache_warming/log_hits_test.py
@@ -0,0 +1,169 @@
+#!/usr/bin/python
+"""Tests for log_hits.py."""
+
+import os
+import log_hits
+from wvtest import wvtest
+
+
+@wvtest.wvtest
+def testProcessLine_firstHit():
+  line = '123456789 www.yahoo.com\n'
+  expected = {'www.yahoo.com': (1, '123456789')}
+  actual = log_hits.process_line({}, line)
+  wvtest.WVPASSEQ(actual, expected)
+
+
+@wvtest.wvtest
+def testProcessLine_updateHitCount():
+  line = '123456789 www.yahoo.com\n'
+  log = {'www.yahoo.com': (1, '123456789')}
+  expected = 2
+  actual = log_hits.process_line(log, line)['www.yahoo.com'][0]
+  wvtest.WVPASSEQ(actual, expected)
+
+
+@wvtest.wvtest
+def testProcessLine_updateRecentHitTime():
+  line = '123456789 www.yahoo.com\n'
+  log = {'www.yahoo.com': (1, '987654321')}
+  expected = '123456789'
+  actual = log_hits.process_line(log, line)['www.yahoo.com'][1]
+  wvtest.WVPASSEQ(actual, expected)
+
+
+@wvtest.wvtest
+def testMergeLogs_emptyLog():
+  hist = {'www.yahoo.com': (1, '123456789')}
+  expected = hist
+  actual = log_hits.merge_logs({}, hist)
+  wvtest.WVPASSEQ(actual, expected)
+
+
+@wvtest.wvtest
+def testMergeLogs_emptyHist():
+  log = {'www.yahoo.com': (1, '123456789')}
+  expected = log
+  actual = log_hits.merge_logs(log, {})
+  wvtest.WVPASSEQ(actual, expected)
+
+
+@wvtest.wvtest
+def testMergeLogs_bothEmpty():
+  expected = {}
+  actual = log_hits.merge_logs({}, {})
+  wvtest.WVPASSEQ(actual, expected)
+
+
+@wvtest.wvtest
+def testMergeLogs_noOverlap():
+  log = {'www.yahoo.com': (1, '123456789')}
+  hist = {'www.google.com': (1, '123456789')}
+  expected = {
+      'www.yahoo.com': (1, '123456789'),
+      'www.google.com': (1, '123456789')
+  }
+  actual = log_hits.merge_logs(log, hist)
+  wvtest.WVPASSEQ(actual, expected)
+
+
+@wvtest.wvtest
+def testMergeLogs_updateHitCount():
+  log = {'www.yahoo.com': (1, '987654321')}
+  hist = {'www.yahoo.com': (1, '123456789')}
+  expected = 2
+  actual = log_hits.merge_logs(log, hist)['www.yahoo.com'][0]
+  wvtest.WVPASSEQ(actual, expected)
+
+
+@wvtest.wvtest
+def testMergeLogs_updateRecentHitTime():
+  log = {'www.yahoo.com': (1, '987654321')}
+  hist = {'www.yahoo.com': (1, '123456789')}
+  expected = '987654321'
+  actual = log_hits.merge_logs(log, hist)['www.yahoo.com'][1]
+  wvtest.WVPASSEQ(actual, expected)
+
+
+@wvtest.wvtest
+def testMergeLogs_histLargerNoOverlap():
+  log = {'www.yahoo.com': (1, '123456789')}
+  hist = {
+      'www.google.com': (1, '123456789'),
+      'www.espn.com': (1, '123456789')
+  }
+  expected = {
+      'www.yahoo.com': (1, '123456789'),
+      'www.google.com': (1, '123456789'),
+      'www.espn.com': (1, '123456789')
+  }
+  actual = log_hits.merge_logs(log, hist)
+  wvtest.WVPASSEQ(actual, expected)
+
+
+@wvtest.wvtest
+def testMergeLogs_histLargerUpdateHitCount():
+  log = {'www.yahoo.com': (1, '987654321')}
+  hist = {
+      'www.yahoo.com': (1, '123456789'),
+      'www.google.com': (1, '123456789')
+  }
+  expected = 2
+  actual = log_hits.merge_logs(log, hist)['www.yahoo.com'][0]
+  wvtest.WVPASSEQ(actual, expected)
+
+
+@wvtest.wvtest
+def testMergeLogs_histLargerUpdateRecentHitTime():
+  log = {'www.yahoo.com': (1, '987654321')}
+  hist = {
+      'www.yahoo.com': (1, '123456789'),
+      'www.google.com': (1, '123456789')
+  }
+  expected = '987654321'
+  actual = log_hits.merge_logs(log, hist)['www.yahoo.com'][1]
+  wvtest.WVPASSEQ(actual, expected)
+
+
+@wvtest.wvtest
+def testReadDNSQueryLog_empty():
+  file_name = 'test_log.txt'
+  open(file_name, 'w').close()
+  expected = {}
+  actual = log_hits.read_dns_query_log(file_name)
+  wvtest.WVPASSEQ(actual, expected)
+  os.remove(file_name)
+
+
+@wvtest.wvtest
+def testReadDNSQueryLog_nonEmpty():
+  file_name = 'test_log.txt'
+  f = open(file_name, 'w')
+  f.write('123456789 www.yahoo.com\n987654321 www.google.com\n'
+          '135792468 www.yahoo.com\n')
+  f.close()
+  expected = {
+      'www.yahoo.com': (2, '135792468'),
+      'www.google.com': (1, '987654321')
+  }
+  actual = log_hits.read_dns_query_log(file_name)
+  wvtest.WVPASSEQ(actual, expected)
+  os.remove(file_name)
+
+
+@wvtest.wvtest
+def testClearDNSQueryLog():
+  file_name = 'test_log.txt'
+  f = open(file_name, 'w')
+  f.write('testing clear_dns_query_log()\n')
+  f.close()
+
+  log_hits.clear_dns_query_log(file_name)
+  expected = 0
+  actual = os.stat(file_name).st_size
+  wvtest.WVPASSEQ(actual, expected)
+  os.remove(file_name)
+
+
+if __name__ == '__main__':
+  wvtest.wvtest_main()
diff --git a/cache_warming/warm_cache b/cache_warming/warm_cache
new file mode 100644
index 0000000..fa334d0
--- /dev/null
+++ b/cache_warming/warm_cache
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# Periodically processes logged DNS queries and prefetches
+# prefetches the most requested hosts, warming the cache.
+
+while sleep 60; do
+  python log_hits.py
+  python fetch_popular.py
+done
diff --git a/cache_warming/wvtest b/cache_warming/wvtest
new file mode 120000
index 0000000..75927a5
--- /dev/null
+++ b/cache_warming/wvtest
@@ -0,0 +1 @@
+../cmds/wvtest
\ No newline at end of file
diff --git a/cmds/Makefile b/cmds/Makefile
index 069e6ff..38557fa 100644
--- a/cmds/Makefile
+++ b/cmds/Makefile
@@ -227,7 +227,7 @@
 host-wifi_files_test: LIBS += -lnl-3 -lnl-genl-3 -lglib-2.0
 dhcpvendortax: dhcpvendortax.o dhcpvendorlookup.o
 dhcpvendorlookup.c: dhcpvendorlookup.gperf
-	$(GPERF) -G -C -t -L ANSI-C -N exact_match -K vendor_class \
+	$(GPERF) -G -C -t -L ANSI-C -N exact_match -K vendor_class --delimiters="|" \
 		--includes --output-file=dhcpvendorlookup.c dhcpvendorlookup.gperf
 dhcpvendorlookup.o: CFLAGS += -Wno-missing-field-initializers
 host-dhcpvendorlookup.o: CFLAGS += -Wno-missing-field-initializers
diff --git a/cmds/dhcpvendorlookup.gperf b/cmds/dhcpvendorlookup.gperf
index b4b0ee1..884625a 100644
--- a/cmds/dhcpvendorlookup.gperf
+++ b/cmds/dhcpvendorlookup.gperf
@@ -18,50 +18,51 @@
 %}
 struct string_match {
   char *vendor_class;
+  char *genus;
   char *species;
 };
 %%
-6328-2Re, "InnoMedia VoIP adapter"
-AEROHIVE, "Aerohive Wifi AP"
-AirStation Series BUFFALO INC., "Buffalo Wifi AP"
-ArubaAP, "Aruba Wifi AP"
-ArubaInstantAP, "Aruba Wifi AP"
-ccp.avaya.com, "Avaya IP Phone"
-Cisco 802.11n AP Bridge, "Cisco Wifi AP"
-Dell Network Printer, "Dell Printer"
-DUNEHD, "Dune media player"
-ecobee1, "ecobee thermostat"
-HD409N, "ZaapTV"
-Hewlett-Packard JetDirect, "HP Printer"
-Hewlett-Packard LaserJet, "HP LaserJet"
-Hewlett-Packard OfficeJet, "HP OfficeJet"
-iDRAC, "Dell Remote Access Controller"
-ipphone.mitel.com, "Mitel IP Phone"
-IP2061, "Icon IP Phone"
-IWATSUIP, "Icon IP Phone"
-MC361, "Oki Printer"
-MC362, "Oki Printer"
-MERAKI, "Meraki Wifi AP"
-MicroChip Network Stack, "Microchip board"
-Motorola_AP, "Motorola Wifi AP"
-OptiIpPhone, "Siemens IP Phone"
-PS3, "Sony Playstation 3"
-PS4, "Sony Playstation 4"
-PS Vita, "Sony Playstation Vita"
-PS Vita TV, "Sony Playstation Vita"
-Ruckus CPE, "Ruckus Wifi AP"
-SAMSUNG Network Printer, "Samsung Printer"
-SEC_ITP, "Samsung IP Phone"
-ShoreTel IP Phone, "ShoreTel IP Phone"
-SIP-T38G, "Yealink IP Phone"
-SSG5-Serial-WLAN, "Juniper Gateway"
-TOSHIBA IPedge, "Toshiba VoIP adapter"
-ubnt, "Ubiquiti AP"
-VIZIO VIA, "Vizio TV"
-Withings00, "Withings Scale"
-XBOX 1.0, "Xbox"
-Xbox 360, "Xbox 360"
-Xerox Phaser, "Xerox Printer"
-XEROX Network Printer, "Xerox Printer"
-yealink, "Yealink IP Phone"
+6328-2Re| "InnoMedia VoIP adapter", "MTA6328-2Re"
+AEROHIVE| "Aerohive Wifi AP", "Aerohive Wifi AP"
+AirStation Series BUFFALO INC.| "Buffalo Wifi AP", "Buffalo AirStation AP"
+ArubaAP| "Aruba Wifi AP", "Aruba Wifi AP"
+ArubaInstantAP| "Aruba Wifi AP", "Aruba Wifi AP"
+ccp.avaya.com| "Avaya IP Phone", "Avaya IP Phone"
+Cisco 802.11n AP Bridge| "Cisco Wifi AP", "Cisco Wifi AP"
+Dell Network Printer| "Dell Printer", "Dell Printer"
+DUNEHD| "Dune media player", "DuneHD media player"
+ecobee1| "ecobee thermostat", "ecobee thermostat"
+HD409N| "ZaapTV", "Zaap HD409N"
+Hewlett-Packard JetDirect| "HP Printer", "HP Printer"
+Hewlett-Packard LaserJet| "HP Printer", "HP LaserJet"
+Hewlett-Packard OfficeJet| "HP Printer", "HP OfficeJet"
+iDRAC| "Dell Remote Access Controller", "DRAC"
+ipphone.mitel.com| "Mitel IP Phone", "Mitel IP Phone"
+IP2061| "Icon IP Phone", "IP2061"
+IWATSUIP| "Icon IP Phone", "Icon IP Phone"
+MC361| "Oki Printer", "Oki MC361"
+MC362| "Oki Printer", "Oki MC362"
+MERAKI| "Meraki Wifi AP", "Meraki Wifi AP"
+MicroChip Network Stack| "Microchip board", "Microchip board"
+Motorola_AP| "Motorola Wifi AP", "Motorola Wifi AP"
+OptiIpPhone| "Siemens IP Phone", "Siemens IP Phone"
+PS3| "Sony Playstation", "PS3"
+PS4| "Sony Playstation", "PS4"
+PS Vita| "Sony Playstation", "PS-Vita"
+PS Vita TV| "Sony Playstation", "PS-Vita"
+Ruckus CPE| "Ruckus Wifi AP", "Ruckus Wifi AP"
+SAMSUNG Network Printer| "Samsung Printer", "Samsung Printer"
+SEC_ITP| "Samsung IP Phone", "Samsung IP Phone"
+ShoreTel IP Phone| "ShoreTel IP Phone", "ShoreTel IP Phone"
+SIP-T38G| "Yealink IP Phone", "SIP-T38G"
+SSG5-Serial-WLAN| "Juniper Gateway", "SSG5"
+TOSHIBA IPedge| "Toshiba VoIP adapter", "Toshiba VoIP adapter"
+ubnt| "Ubiquiti Wifi AP", "Ubiquiti Wifi AP"
+VIZIO VIA| "Vizio Smart TV", "Vizio Smart TV"
+Withings00| "Withings Scale", "Withings Scale"
+XBOX 1.0| "Xbox", "Xbox"
+Xbox 360| "Xbox", "Xbox 360"
+Xerox Phaser| "Xerox Printer", "Xerox Printer"
+XEROX Network Printer| "Xerox Printer", "Xerox Printer"
+yealink| "Yealink IP Phone", "Yealink IP Phone"
 %%
diff --git a/cmds/dhcpvendortax.c b/cmds/dhcpvendortax.c
index ee0ca24..7c9adac 100644
--- a/cmds/dhcpvendortax.c
+++ b/cmds/dhcpvendortax.c
@@ -25,6 +25,7 @@
 
 struct string_match {
   char *vendor_class;
+  char *genus;
   char *species;
 };
 
@@ -33,39 +34,45 @@
     unsigned int len);
 
 
-struct string_match substring_matches[] = {
+struct regex_match {
+  char *regex;
+  char *genus;
+};
+
+
+struct regex_match regex_matches[] = {
   /*
    * Examples:
    *   AastraIPPhone55i
    *   AastraIPPhone57iCT
    *   AastraIPPhone6737i
    */
-  {"AastraIPPhone", "Aastra IP Phone"},
+  {"AastraIPPhone([[:alnum:]]+)", "Aastra IP Phone"},
 
   /* Examples:
    * AXIS,Network Camera,M3006,5.40.13
    * AXIS,Network Camera,P3346,5.20.1
    * AXIS,Thermal Network Camera,Q1931-E,5.55.4.1
    */
-  {"AXIS,Network Camera", "AXIS Network Camera"},
-  {"AXIS,Thermal Network Camera", "AXIS Network Camera"},
+  {"AXIS,Network Camera,([^,]+)", "AXIS Network Camera"},
+  {"AXIS,Thermal Network Camera,([^,]+)", "AXIS Network Camera"},
 
   /* Examples:
    * Canon MF620C Series
    */
-  {"Canon MF", "Canon Printer"},
+  {"Canon (MF[[:alnum:]]+)", "Canon Printer"},
 
   /* Examples:
    * Cisco AP c1200
    * Cisco AP c1240
    */
-  {"Cisco AP", "Cisco Wifi AP"},
+  {"Cisco AP ([[:alnum:]]+)", "Cisco Wifi AP"},
 
   /* Examples:
    *   Cisco Systems, Inc. IP Phone CP-7961G
    *   Cisco Systems, Inc. IP Phone CP-8861
    */
-  {"Cisco Systems, Inc. IP Phone", "Cisco IP Phone"},
+  {"Cisco Systems, Inc. IP Phone ([[:alnum:]-]+)", "Cisco IP Phone"},
 
   /* Examples:
    *   Cisco SPA504G
@@ -73,24 +80,31 @@
    *   CISCO SPA112
    *   ATA186-H6.0|V3.2.0|B041111A
    */
-  {"Cisco SPA", "Cisco IP Phone"},
-  {"CISCO SPA", "Cisco IP Phone"},
-  {"ATA186", "Cisco IP Phone"},
+  {"Cisco (SPA[[:alnum:]]+)", "Cisco IP Phone"},
+  {"CISCO (SPA[[:alnum:]]+)", "Cisco IP Phone"},
+  {"(ATA186)", "Cisco IP Phone"},
 
   /* Examples:
    * CPQRIB3
    */
-  {"CPQRIB", "Compaq Remote Insight"},
+  {"(CPQRIB[[:digit:]]+)", "Compaq Remote Insight"},
 
   /* Examples:
    * Dell Color MFP E525w
    */
-  {"Dell Color MFP", "Dell Printer"},
+  {"Dell Color MFP ([[:alnum:]]+)", "Dell Printer"},
+
+  /* Examples:
+   * Dell C1760nw Color Printer
+   * Dell C2660dn Color Laser
+   * Dell 2155cn Color MFP
+   */
+  {"^Dell ([[:alnum:]]+) Color (Printer|Laser|MFP)", "Dell Printer"},
 
   /* Examples:
    * digium_D40_1_4_2_0_63880
    */
-  {"digium", "Digium IP Phone"},
+  {"digium_([^_]+)", "Digium IP Phone"},
 
   /* Examples:
    * FortiAP-FP321C-AC-Discovery
@@ -98,8 +112,8 @@
    * FortiAP-FP321C
    * FortiWiFi-60D-POE
    */
-  {"FortiAP", "Fortinet Wifi AP"},
-  {"FortiWiFi", "Fortinet Wifi AP"},
+  {"FortiAP-([^-]+)", "Fortinet Wifi AP"},
+  {"FortiWiFi-([[:alnum:]-]+)", "Fortinet Wifi AP"},
 
   /* Examples:
    * Grandstream GXP1405 dslforum.org
@@ -107,41 +121,48 @@
    * Grandstream GXV3275 dslforum.org
    * Grandstream HT702 dslforum.org
    */
-  {"Grandstream GXP", "Grandstream IP Phone"},
-  {"Grandstream GXV", "Grandstream IP Phone"},
-  {"Grandstream HT", "Grandstream VoIP adapter"},
+  {"Grandstream (GX[[:alnum:]]+)", "Grandstream IP Phone"},
+  {"Grandstream (HT[[:alnum:]]+)", "Grandstream VoIP Adapter"},
+
+  /* Grandstream Voice over IP adapters. Examples:
+   * HT500 dslforum.org
+   * HT7XX dslforum.org
+   * DP7XX dslforum.org
+   */
+  {"^(HT[[:alnum:]]+) dslforum.org", "Grandstream VoIP Adapter"},
+  {"^(DP[[:alnum:]]+) dslforum.org", "Grandstream IP Phone"},
 
   /* Examples:
    * iPECS IP Edge 5000i-24G
    */
-  {"iPECS IP Edge", "iPECS IP PHONE"},
+  {"iPECS IP Edge ([[:alnum:]-]+)", "iPECS IP Phone"},
 
   /* Examples:
    * Juniper-ex2200-c-12p-2g
    */
-  {"Juniper-ex", "Juniper router"},
+  {"Juniper-(ex[^-]+)", "Juniper Router"},
 
   /* Examples:
    *   LINKSYS SPA-922
    *   LINKSYS SPA-942
    */
-  {"LINKSYS SPA", "Linksys IP Phone"},
+  {"LINKSYS (SPA-[[:alnum:]]+)", "Linksys IP Phone"},
 
   /* Examples:
    * MotorolaAP.AP7131
    */
-  {"MotorolaAP", "Motorola Wifi AP"},
+  {"MotorolaAP.([[:alnum:]]+)", "Motorola Wifi AP"},
 
   /* Examples:
    * NECDT700
    */
-  {"NECDT", "NEC IP Phone"},
+  {"(NECDT[[:alnum:]]+)", "NEC IP Phone"},
 
   /* Examples:
    *   6=qPolycomSoundPointIP-SPIP_1234567-12345-001
    *   6=tPolycomSoundStationIP-SSIP_12345678-12345-001
    */
-  {"PolycomSoundPointIP", "Polycom IP Phone"},
+  {".*PolycomSoundPointIP-([^-]+)", "Polycom IP Phone"},
 
   /* Examples:
    *   Polycom-SPIP335
@@ -151,26 +172,26 @@
    *   Polycom-VVX500
    *   Polycom-VVX600
    */
-  {"Polycom-SPIP", "Polycom IP Phone"},
-  {"Polycom-SSIP", "Polycom IP Phone"},
-  {"Polycom-VVX", "Polycom IP Phone"},
+  {"Polycom-(SPIP[[:alnum:]]+)", "Polycom IP Phone"},
+  {"Polycom-(SSIP[[:alnum:]]+)", "Polycom IP Phone"},
+  {"Polycom-(VVX[[:alnum:]]+)", "Polycom IP Phone"},
 
   /* Examples:
-   * Rabbit2000-TCPIP:Z-World:Testfoo:1.1.3
    * Rabbit-TCPIP:Z-World:DHCP-Test:1.2.0
+   * Rabbit2000-TCPIP:Z-World:Testfoo:1.1.3
    */
-  {"Rabbit-TCPIP", "Rabbit Microcontroller"},
-  {"Rabbit2000-TCPIP", "Rabbit Microcontroller"},
+  {"(Rabbit)-TCPIP", "Rabbit Microcontroller"},
+  {"(Rabbit2000)-TCPIP", "Rabbit Microcontroller"},
 
   /* Examples:
    * ReadyNet_WRT500
    */
-  {"ReadyNet_WRT", "ReadyNet Wifi AP"},
+  {"ReadyNet_(WRT[[:alnum:]]+)", "ReadyNet Wifi AP"},
 
   /* Examples:
    * SAMSUNG SCX-6x45
    */
-  {"SAMSUNG SCX", "Samsung Network MFP"},
+  {"SAMSUNG (SCX-[[:alnum:]]+)", "Samsung Network MFP"},
 
   /* Examples:
    * SF200-24P
@@ -182,29 +203,30 @@
    * SG200-50P
    * SG300-10
    */
-  {"SF200", "Cisco Managed Switch"},
-  {"SG 200", "Cisco Managed Switch"},
-  {"SG200", "Cisco Managed Switch"},
-  {"SG 300", "Cisco Managed Switch"},
-  {"SG300", "Cisco Managed Switch"},
+  {"(SF200-[[:alnum:]]+)", "Cisco Managed Switch"},
+  {"(SG 200-[[:alnum:]]+)", "Cisco Managed Switch"},
+  {"(SG200-[[:alnum:]]+)", "Cisco Managed Switch"},
+  {"(SG 300-[[:alnum:]]+)", "Cisco Managed Switch"},
+  {"(SG300-[[:alnum:]]+)", "Cisco Managed Switch"},
 
   /* Examples:
    * snom-m3-SIP/02.11//18-Aug-10 15:36
    * snom320
    * snom710
    */
-  {"snom", "Snom IP Phone"},
+  {"(snom[^/]+)", "Snom IP Phone"},
 
   /* Examples:
    * telsey-stb-f8
    */
-  {"telsey-stb", "Telsey Media Player"},
+  {"telsey-stb-([[:alnum:]]+)", "Telsey Media Player"},
 
   {NULL, NULL}
 };
 
 
-/* Copy a string with no funny schtuff allowed; only alphanumerics + space. */
+/* Copy a string with no funny schtuff allowed; only alphanumerics + space
+ * plus a few characters considered safe. */
 static void no_mischief_strncpy(char *dst, const char *src, size_t n)
 {
   size_t i;
@@ -213,10 +235,11 @@
     int is_lower = (s >= 'a' && s <= 'z');
     int is_upper = (s >= 'A' && s <= 'Z');
     int is_digit = (s >= '0' && s <= '9');
+    int is_safe = (s == '_' || s == '-' || s == '.');
     if (s == '\0') {
       dst[i] = '\0';
       break;
-    } else if (is_lower || is_upper || is_digit) {
+    } else if (is_lower || is_upper || is_digit || is_safe) {
       dst[i] = s;
     } else if (s == ' ' || s == '\t') {
       dst[i] = ' ';
@@ -237,8 +260,9 @@
  *   Mfg=Hewlett Packard;Typ=Printer;Mod=HP LaserJet 400 M401n;Ser=ABCDE01234;
  *   mfg=Xerox;typ=MFP;mod=WorkCentre 3220;ser=ABC012345;loc=
  */
-int check_for_printer(const char *vendor_class, char *species,
-    size_t species_len)
+int check_for_printer(const char *vendor_class,
+    char *genus, size_t genus_len,
+    char *species, size_t species_len)
 {
   regex_t r_vendor, r_type, r_model;
   regmatch_t match[2];
@@ -270,9 +294,10 @@
   if (vendor && type) {
     char buf[128];
     snprintf(buf, sizeof(buf), "%s %s", vendor, type);
-    no_mischief_strncpy(species, buf, species_len);
+    no_mischief_strncpy(genus, buf, genus_len);
     rc = 0;
-  } else if (model) {
+  }
+  if (model) {
     no_mischief_strncpy(species, model, species_len);
     rc = 0;
   }
@@ -280,92 +305,49 @@
   if (vendor) free(vendor);
   if (type) free(type);
   if (model) free(model);
+  regfree(&r_vendor);
+  regfree(&r_type);
+  regfree(&r_model);
 
   return(rc);
 }
 
-/*
- * Check a few patterns from common vendors with lots of model
- * numbers.
- */
-int check_specials(const char *vendor_class, char *species,
-    size_t species_len)
-{
-  regex_t r_dellprinter, r_grandstream;
 
-  /*
-   * Dell printers. Examples:
-   * Dell C1760nw Color Printer
-   * Dell C2660dn Color Laser
-   * Dell 2155cn Color MFP
-   */
-  if (regcomp(&r_dellprinter, "^Dell \\S+ Color (Printer|Laser|MFP)",
-        REG_EXTENDED | REG_ICASE | REG_NOSUB)) {
-    fprintf(stderr, "%s: regcomp failed!\n", __FUNCTION__);
-    exit(1);
-  }
-  if (regexec(&r_dellprinter, vendor_class, 0, NULL, 0) == 0) {
-    snprintf(species, species_len, "Dell Printer");
-    return(0);
-  }
-
-  /*
-   * Grandstream Voice over IP adapters. Examples:
-   * HT500 dslforum.org
-   * HT7XX dslforum.org
-   */
-  if (regcomp(&r_grandstream, "^HT.* dslforum.org",
-        REG_EXTENDED | REG_ICASE | REG_NOSUB)) {
-    fprintf(stderr, "%s: regcomp failed!\n", __FUNCTION__);
-    exit(1);
-  }
-  if (regexec(&r_grandstream, vendor_class, 0, NULL, 0) == 0) {
-    snprintf(species, species_len, "Grandstream VoIP adapter");
-    return(0);
-  }
-
-  /*
-   * Grandstream IP phones. Examples:
-   * DP7XX dslforum.org
-   */
-  if (regcomp(&r_grandstream, "^DP.* dslforum.org",
-        REG_EXTENDED | REG_ICASE | REG_NOSUB)) {
-    fprintf(stderr, "%s: regcomp failed!\n", __FUNCTION__);
-    exit(1);
-  }
-  if (regexec(&r_grandstream, vendor_class, 0, NULL, 0) == 0) {
-    snprintf(species, species_len, "Grandstream IP phone");
-    return(0);
-  }
-
-  return(1);
-}
-
-
-int lookup_vc(const char *vendor_class, char *species, size_t species_len)
+int lookup_vc(const char *vendor_class,
+    char *genus, size_t genus_len,
+    char *species, size_t species_len)
 {
   const struct string_match *p;
+  const struct regex_match *r;
   int slen = strlen(vendor_class);
 
   if ((p = exact_match(vendor_class, slen)) != NULL) {
+    no_mischief_strncpy(genus, p->genus, genus_len);
     no_mischief_strncpy(species, p->species, species_len);
     return(0);
   }
 
-  p = &substring_matches[0];
-  while (p->vendor_class != NULL) {
-    if (strstr(vendor_class, p->vendor_class) != NULL) {
-      no_mischief_strncpy(species, p->species, species_len);
+  for (r = &regex_matches[0]; r->regex != NULL; ++r) {
+    regex_t rx;
+    regmatch_t match[2];
+    if (regcomp(&rx, r->regex, REG_EXTENDED | REG_ICASE)) {
+      fprintf(stderr, "%s: regcomp failed!\n", r->regex);
+      exit(1);
+    }
+    if (regexec(&rx, vendor_class, 2, match, 0) == 0) {
+      int len = match[1].rm_eo - match[1].rm_so;
+      char *model = strndup(vendor_class + match[1].rm_so, len);
+      no_mischief_strncpy(species, model, species_len);
+      free(model);
+
+      snprintf(genus, genus_len, "%s", r->genus);
       return(0);
     }
-    p++;
+    regfree(&rx);
   }
 
-  if (check_for_printer(vendor_class, species, species_len) == 0) {
-    return(0);
-  }
-
-  if (check_specials(vendor_class, species, species_len) == 0) {
+  if (check_for_printer(vendor_class,
+        genus, genus_len, species, species_len) == 0) {
     return(0);
   }
 
@@ -390,6 +372,7 @@
   int c;
   const char *label = NULL;
   const char *vendor = NULL;
+  char genus[80];
   char species[80];
 
   setlinebuf(stdout);
@@ -410,9 +393,10 @@
   if (optind < argc || vendor == NULL || label == NULL)
     usage(argv[0]);
 
+  memset(genus, 0, sizeof(genus));
   memset(species, 0, sizeof(species));
-  if (lookup_vc(vendor, species, sizeof(species)) == 0) {
-    printf("dhcpv %s %s\n", label, species);
+  if (lookup_vc(vendor, genus, sizeof(genus), species, sizeof(species)) == 0) {
+    printf("dhcpv %s %s;%s\n", label, genus, species);
   }
   exit(0);
 }
diff --git a/cmds/host-test-ssdptax.sh b/cmds/host-test-ssdptax.sh
index 3b12fdf..ebb3ae7 100755
--- a/cmds/host-test-ssdptax.sh
+++ b/cmds/host-test-ssdptax.sh
@@ -5,12 +5,21 @@
 . ./wvtest/wvtest.sh
 
 SSDP=./host-ssdptax
-
 FIFO="/tmp/ssdptax.test.$$"
-python ./ssdptax-test-server.py "$FIFO" &
-sleep 0.5
 
 WVSTART "ssdptax test"
-WVPASSEQ "$($SSDP -t $FIFO)" "ssdp 00:00:00:00:00:00 Test Device;Google Fiber ssdptax"
 
+python ./ssdptax-test-server.py "$FIFO" 1 &
+sleep 0.5
+WVPASSEQ "$($SSDP -t $FIFO)" "ssdp 00:00:00:00:00:00 Test Device;Google Fiber ssdptax"
+rm "$FIFO"
+
+python ./ssdptax-test-server.py "$FIFO" 2 &
+sleep 0.5
+WVPASSEQ "$($SSDP -t $FIFO)" "ssdp 00:00:00:00:00:00 REDACTED;server type"
+rm "$FIFO"
+
+python ./ssdptax-test-server.py "$FIFO" 3 &
+sleep 0.5
+WVPASSEQ "$($SSDP -t $FIFO)" "ssdp 00:00:00:00:00:00 Unknown;server type"
 rm "$FIFO"
diff --git a/cmds/hostnamelookup.gperf b/cmds/hostnamelookup.gperf
index bfae6fe..5c3526f 100644
--- a/cmds/hostnamelookup.gperf
+++ b/cmds/hostnamelookup.gperf
@@ -75,10 +75,16 @@
 NP-1P| "Roku", "Roku LT 2700"
 NP-1X| "Roku", "Roku 1 2710"
 NP-2L| "Roku", "Roku Streaming Stick 3500"
+NP-2N| "Roku TV", "Roku TV"
 NP-41| "Roku", "Roku 3 4200"
+NP-4A| "Roku", "Roku 2 4210X"
 NP-4E| "Roku", "Roku 3 4230RW"
+NP-5F| "Roku", "Roku 2 4210X"
+NP-5G| "Roku", "Roku 3 4230X"
+NP-5S| "Roku", "Roku Streaming Stick 3600"
 NP-5Y| "Roku", "Roku 2 4210"
 NP-63| "Roku", "Roku 3 4230"
+NP-YW| "Roku TV", "Roku TV"
 NP-YY| "Roku", "Roku 4 4400"
 OBi200%1,3,6,12,15,28,42,66| "Obihai VoIP Adaptor", "OBi200"
 OBi202%1,3,6,12,15,28,42,66| "Obihai VoIP Adaptor", "OBi202"
@@ -97,6 +103,7 @@
 Slingbox-500%1,3,6,12,15,28,42| "Slingbox", "Slingbox 500"
 Slingbox500%1,3,6,12,15,28,42| "Slingbox", "Slingbox 500"
 Slingbox-M1%1,3,6,12,15,28,40,41,42,119| "Slingbox", "Slingbox M1"
+SmartThings%1,3,6,12| "Samsung SmartThings", "SmartThings Hub"
 SPA112%1,3,6,7,12,15,28,42,43,44,66,67,125,128,150,159,160| "Cisco VoIP Adaptor", "SPA112"
 SPA-112%1,3,6,7,12,15,28,42,43,44,66,67,125,128,150,159,160| "Cisco VoIP Adaptor", "SPA112"
 SPA122%1,3,6,7,12,15,28,42,43,44,66,67,125,128,150,159,160| "Cisco VoIP Adaptor", "SPA122"
diff --git a/cmds/ssdptax-test-server.py b/cmds/ssdptax-test-server.py
index c0346cb..54831d4 100644
--- a/cmds/ssdptax-test-server.py
+++ b/cmds/ssdptax-test-server.py
@@ -8,18 +8,39 @@
 import sys
 
 
+text_device_xml = """<root>
+  <specVersion><major>1</major><minor>0</minor></specVersion>
+  <device><friendlyName>Test Device</friendlyName>
+  <manufacturer>Google Fiber</manufacturer>
+  <modelDescription>Unit Test</modelDescription>
+  <modelName>ssdptax</modelName>
+</device></root>"""
+
+
+email_address_xml = """<root>
+  <specVersion><major>1</major><minor>0</minor></specVersion>
+  <device><friendlyName>FOOBAR: foo@example.com:</friendlyName>
+  <manufacturer>Google Fiber</manufacturer>
+  <modelDescription>Unit Test</modelDescription>
+  <modelName>ssdptax</modelName>
+</device></root>"""
+
+
+no_friendlyname_xml = """<root>
+  <specVersion><major>1</major><minor>0</minor></specVersion>
+  <device></device></root>"""
+
+
+xml = ['']
+
+
 class XmlHandler(BaseHTTPServer.BaseHTTPRequestHandler):
   def do_GET(self):
     self.send_response(200)
     self.send_header('Content-type','text/xml')
     self.end_headers()
-    self.wfile.write("""<root>
-        <specVersion><major>1</major><minor>0</minor></specVersion>
-        <device><friendlyName>Test Device</friendlyName>
-        <manufacturer>Google Fiber</manufacturer>
-        <modelDescription>Unit Test</modelDescription>
-        <modelName>ssdptax</modelName>
-    </device></root>""")
+    self.wfile.write(xml[0])
+
 
 def main():
   un = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
@@ -27,6 +48,14 @@
   un.listen(1)
   conn, _ = un.accept()
 
+  testnum = int(sys.argv[2])
+  if testnum == 1:
+    xml[0] = text_device_xml
+  if testnum == 2:
+    xml[0] = email_address_xml
+  if testnum == 3:
+    xml[0] = no_friendlyname_xml
+
   s = BaseHTTPServer.HTTPServer(("", 0), XmlHandler)
   sn = s.socket.getsockname()
   port = sn[1]
diff --git a/cmds/ssdptax.cc b/cmds/ssdptax.cc
index 2a991cb..2a06c7a 100644
--- a/cmds/ssdptax.cc
+++ b/cmds/ssdptax.cc
@@ -31,6 +31,7 @@
 #include <curl/curl.h>
 #include <getopt.h>
 #include <netinet/in.h>
+#include <regex.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -172,6 +173,27 @@
 
 
 /*
+ * Returns true if the friendlyName appears to include an email address.
+ */
+bool contains_email_address(const std::string &friendlyName)
+{
+  regex_t r_email;
+  int rc;
+
+  if (regcomp(&r_email, ".+@[a-z0-9.-]+\\.[a-z0-9.-]+",
+        REG_EXTENDED | REG_ICASE | REG_NOSUB)) {
+    fprintf(stderr, "%s: regcomp failed!\n", __FUNCTION__);
+    exit(1);
+  }
+
+  rc = regexec(&r_email, friendlyName.c_str(), 0, NULL, 0);
+  regfree(&r_email);
+
+  return (rc == 0);
+}
+
+
+/*
  * Combine the manufacturer and model. If the manufacturer name
  * is already present in the model string, don't duplicate it.
  */
@@ -206,7 +228,9 @@
   }
 
   mac = get_l2addr_for_ip(info->ipaddr);
-  if (info->friendlyName.length() > 0) {
+  if (contains_email_address(info->friendlyName)) {
+    result = "ssdp " + mac + " REDACTED;" + info->srv_type;
+  } else if (info->friendlyName.length() > 0) {
     result = "ssdp " + mac + " " + info->friendlyName + ";" +
       unfriendly_name(info->manufacturer, info->model);
   } else {
diff --git a/cmds/test-dhcpvendortax.sh b/cmds/test-dhcpvendortax.sh
index 8f8d474..5704ed2 100755
--- a/cmds/test-dhcpvendortax.sh
+++ b/cmds/test-dhcpvendortax.sh
@@ -8,48 +8,101 @@
 
 # Check regex matches
 WVPASS $TAX -l label -v "AastraIPPhone55i" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Aastra IP Phone"
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Aastra IP Phone;55i"
+WVPASS $TAX -l label -v "AXIS,Network Camera,M3006,5.40.13" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label AXIS Network Camera;M3006"
+WVPASS $TAX -l label -v "AXIS,Thermal Network Camera,Q1931-E,5.55.4.1" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label AXIS Network Camera;Q1931-E"
+WVPASS $TAX -l label -v "Canon MF620C Series" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Canon Printer;MF620C"
+WVPASS $TAX -l label -v "Cisco AP c1240" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Cisco Wifi AP;c1240"
+WVPASS $TAX -l label -v "Cisco Systems, Inc. IP Phone CP-7961G" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Cisco IP Phone;CP-7961G"
+WVPASS $TAX -l label -v "Cisco SPA525G2" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Cisco IP Phone;SPA525G2"
+WVPASS $TAX -l label -v "ATA186-H6.0|V3.2.0|B041111A" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Cisco IP Phone;ATA186"
+WVPASS $TAX -l label -v "CPQRIB3" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Compaq Remote Insight;CPQRIB3"
+WVPASS $TAX -l label -v "Dell Color MFP E525w" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Dell Printer;E525w"
+WVPASS $TAX -l label -v "Dell C1760nw Color Printer" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Dell Printer;C1760nw"
+WVPASS $TAX -l label -v "Dell C2660dn Color Laser" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Dell Printer;C2660dn"
+WVPASS $TAX -l label -v "Dell 2155cn Color MFP" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Dell Printer;2155cn"
+WVPASS $TAX -l label -v "FortiAP-FP321C" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Fortinet Wifi AP;FP321C"
+WVPASS $TAX -l label -v "FortiWiFi-60D-POE" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Fortinet Wifi AP;60D-POE"
+WVPASS $TAX -l label -v "Grandstream GXP1405 dslforum.org" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Grandstream IP Phone;GXP1405"
+WVPASS $TAX -l label -v "Grandstream HT702 dslforum.org" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Grandstream VoIP Adapter;HT702"
+WVPASS $TAX -l label -v "HT500 dslforum.org" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Grandstream VoIP Adapter;HT500"
+WVPASS $TAX -l label -v "DP7XX dslforum.org" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Grandstream IP Phone;DP7XX"
+WVPASS $TAX -l label -v "iPECS IP Edge 5000i-24G" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label iPECS IP Phone;5000i-24G"
+WVPASS $TAX -l label -v "Juniper-ex2200-c-12p-2g" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Juniper Router;ex2200"
+WVPASS $TAX -l label -v "LINKSYS SPA-942" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Linksys IP Phone;SPA-942"
+WVPASS $TAX -l label -v "MotorolaAP.AP7131" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Motorola Wifi AP;AP7131"
+WVPASS $TAX -l label -v "NECDT700" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label NEC IP Phone;NECDT700"
 WVPASS $TAX -l label -v "6=qPolycomSoundPointIP-SPIP_1234567-12345-001" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Polycom IP Phone"
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Polycom IP Phone;SPIP_1234567"
 WVPASS $TAX -l label -v "Polycom-VVX310" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Polycom IP Phone"
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Polycom IP Phone;VVX310"
+WVPASS $TAX -l label -v "Rabbit2000-TCPIP:Z-World:Testfoo:1.1.3" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Rabbit Microcontroller;Rabbit2000"
+WVPASS $TAX -l label -v "Rabbit-TCPIP:Z-World:DHCP-Test:1.2.0" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Rabbit Microcontroller;Rabbit"
+WVPASS $TAX -l label -v "ReadyNet_WRT500" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label ReadyNet Wifi AP;WRT500"
+WVPASS $TAX -l label -v "SAMSUNG SCX-6x45" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Samsung Network MFP;SCX-6x45"
+WVPASS $TAX -l label -v "SF200-24P" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Cisco Managed Switch;SF200-24P"
+WVPASS $TAX -l label -v "SG 200-08" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Cisco Managed Switch;SG 200-08"
+WVPASS $TAX -l label -v "SG200-26" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Cisco Managed Switch;SG200-26"
+WVPASS $TAX -l label -v "SG300-10" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Cisco Managed Switch;SG300-10"
+WVPASS $TAX -l label -v "snom-m3-SIP/02.11//18-Aug-10 15:36" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Snom IP Phone;snom-m3-SIP"
+WVPASS $TAX -l label -v "snom320" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Snom IP Phone;snom320"
+WVPASS $TAX -l label -v "telsey-stb-f8" >test1.$pid.tmp
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Telsey Media Player;f8"
 
 # Check exact matches
 WVPASS $TAX -l label -v "Dell Network Printer" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Dell Printer"
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Dell Printer;Dell Printer"
 WVPASS $TAX -l label -v "Xbox 360" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Xbox 360"
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Xbox;Xbox 360"
 
 # Check model/type/manufacturer handling
 WVPASS $TAX -l label -v "Mfg=DELL;Typ=Printer;Mod=Dell 2330dn Laser Printer;Ser=0123AB5;" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label DELL Printer"
-WVPASS $TAX -l label -v "Mfg=DELL;Mod=Dell 2330dn Laser Printer;Ser=0123AB5;" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Dell 2330dn Laser Printer"
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label DELL Printer;Dell 2330dn Laser Printer"
 
 # Check case sensitivity
 WVPASS $TAX -l label -v "mFG=DELL;tYP=Printer;mOD=Dell 2330dn Laser Printer;Ser=0123AB5;" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label DELL Printer"
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label DELL Printer;Dell 2330dn Laser Printer"
 
 # Check some other printer vendor formats
 WVPASS $TAX -l label -v "Mfg=FujiXerox;Typ=AIO;Mod=WorkCentre 6027;Ser=P1A234567" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label FujiXerox AIO"
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label FujiXerox AIO;WorkCentre 6027"
 WVPASS $TAX -l label -v "Mfg=Hewlett Packard;Typ=Printer;Mod=HP LaserJet 400 M401n;Ser=ABCDE01234;" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Hewlett Packard Printer"
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Hewlett Packard Printer;HP LaserJet 400 M401n"
 WVPASS $TAX -l label -v "mfg=Xerox;typ=MFP;mod=WorkCentre 3220;ser=ABC012345;loc=" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Xerox MFP"
-
-# Check specials
-WVPASS $TAX -l label -v "Dell 2155cn Color MFP" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Dell Printer"
-WVPASS $TAX -l label -v "Dell C1760nw Color Printer" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Dell Printer"
-WVPASS $TAX -l label -v "Dell C2660dn Color Laser" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Dell Printer"
-
-WVPASS $TAX -l label -v "HT500 dslforum.org" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Grandstream VoIP adapter"
-WVPASS $TAX -l label -v "HT7XX dslforum.org" >test1.$pid.tmp
-WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Grandstream VoIP adapter"
+WVPASSEQ "$(cat test1.$pid.tmp)" "dhcpv label Xerox MFP;WorkCentre 3220"
 
 # check invalid or missing arguments. -l and -v are required.
 WVFAIL $TAX
diff --git a/conman/connection_manager.py b/conman/connection_manager.py
index aa1b320..cbb3b5b 100755
--- a/conman/connection_manager.py
+++ b/conman/connection_manager.py
@@ -95,9 +95,9 @@
 
   @property
   def client_up(self):
-    wpa_cli_status = self.wifi.wpa_cli_status()
-    return (wpa_cli_status.get('wpa_state') == 'COMPLETED'
-            and wpa_cli_status.get('ssid') == self.ssid)
+    wpa_status = self.wifi.wpa_status()
+    return (wpa_status.get('wpa_state') == 'COMPLETED'
+            and wpa_status.get('ssid') == self.ssid)
 
   def start_access_point(self):
     """Start an access point."""
diff --git a/conman/interface.py b/conman/interface.py
index 71a7046..82d1506 100755
--- a/conman/interface.py
+++ b/conman/interface.py
@@ -387,15 +387,15 @@
       logging.error('Error attaching to wpa_supplicant: %s', e)
       return False
 
-    status = self.wpa_cli_status()
+    status = self.wpa_status()
     self.wpa_supplicant = status.get('wpa_state') == 'COMPLETED'
     if not self._initialized:
       self.initial_ssid = status.get('ssid')
 
     return True
 
-  def wpa_cli_status(self):
-    """Parse the STATUS response from the wpa_supplicant CLI.
+  def wpa_status(self):
+    """Parse the STATUS response from the wpa_supplicant control interface.
 
     Returns:
       A dict containing the parsed results, where key and value are separated by
@@ -403,8 +403,12 @@
     """
     status = {}
 
-    if self._wpa_control:
-      lines = self._wpa_control.request('STATUS').splitlines()
+    if self._wpa_control and self._wpa_control.attached:
+      lines = []
+      try:
+        lines = self._wpa_control.request('STATUS').splitlines()
+      except wpactrl.error:
+        logging.error('wpa_control STATUS request failed')
       for line in lines:
         if '=' not in line:
           continue
diff --git a/conman/interface_test.py b/conman/interface_test.py
index 2c82aaa..4283a2a 100755
--- a/conman/interface_test.py
+++ b/conman/interface_test.py
@@ -79,6 +79,7 @@
     self.attached = False
     self.connected = False
     self.ssid_testonly = None
+    self.request_status_fails = False
 
   def pending(self):
     self.check_socket_exists('pending: socket does not exist')
@@ -101,6 +102,8 @@
 
   def request(self, request_type):
     if request_type == 'STATUS':
+      if self.request_status_fails:
+        raise wpactrl.error('test error')
       return ('foo\nwpa_state=COMPLETED\nssid=%s\nbar' % self.ssid_testonly
               if self.connected else 'foo')
     else:
@@ -189,6 +192,7 @@
   def __init__(self, *args, **kwargs):
     super(FrenzyWPACtrl, self).__init__(*args, **kwargs)
     self.ssid_testonly = None
+    self.request_status_fails = False
 
   def _qcsapi(self, *command):
     return self.fake_qcsapi.get(command[0], None)
@@ -211,6 +215,12 @@
     self.add_terminating_event()
     super(FrenzyWPACtrl, self).detach()
 
+  def request(self, request_type):
+    if request_type == 'STATUS' and self.request_status_fails:
+      raise wpactrl.error('test error')
+
+    return super(FrenzyWPACtrl, self).request(request_type)
+
 
 class FrenzyWifi(FakeInterfaceMixin, interface.FrenzyWifi):
   WPACtrl = FrenzyWPACtrl
@@ -370,6 +380,10 @@
   w.initialize()
   wvtest.WVPASSEQ(w.initial_ssid, None)
 
+  wvtest.WVPASSNE(w.wpa_status(), {})
+  w._wpa_control.request_status_fails = True
+  wvtest.WVPASSEQ(w.wpa_status(), {})
+
   # The wpa_supplicant process disconnects and terminates.
   wpa_control.add_disconnected_event()
   wpa_control.add_terminating_event()
diff --git a/conman/iw.py b/conman/iw.py
index f4932f1..300c3e2 100755
--- a/conman/iw.py
+++ b/conman/iw.py
@@ -7,6 +7,7 @@
 
 
 FIBER_OUI = 'f4:f5:e8'
+DEFAULT_GFIBERSETUP_SSID = 'GFiberSetupAutomation'
 
 
 def _scan(band, **kwargs):
@@ -115,6 +116,11 @@
           bss_info.ssid = ''.join(octets[1:]).decode('hex')
           continue
 
+    # Some of our devices (e.g. Frenzy) can't see vendor IEs.  If we find a
+    # hidden network no vendor IEs or SSID, guess 'GFiberSetupAutomation'.
+    if not bss_info.ssid and not bss_info.vendor_ies:
+      bss_info.ssid = DEFAULT_GFIBERSETUP_SSID
+
     for oui, data in bss_info.vendor_ies:
       if vendor_ie_function(oui, data):
         result_with_ie.add(bss_info)
diff --git a/conman/iw_test.py b/conman/iw_test.py
index 9c259e8..3f80d6c 100755
--- a/conman/iw_test.py
+++ b/conman/iw_test.py
@@ -486,7 +486,7 @@
      * BK: CW 15-1023, AIFSN 7
      * VI: CW 7-15, AIFSN 2, TXOP 3008 usec
      * VO: CW 3-7, AIFSN 2, TXOP 1504 usec
-BSS 94:b4:0f:f1:36:41(on wcli0)
+BSS 94:b4:0f:f1:36:42(on wcli0)
   TSF: 12499150000 usec (0d, 03:28:19)
   freq: 2437
   beacon interval: 100 TUs
@@ -552,6 +552,70 @@
      * VO: CW 3-7, AIFSN 2, TXOP 1504 usec
   Vendor specific: OUI 00:11:22, data: 01 23 45 67
   Vendor specific: OUI f4:f5:e8, data: 03 47 46 69 62 65 72 53 65 74 75 70 41 75 74 6f 6d 61 74 69 6f 6e
+BSS f4:f5:e8:f1:36:43(on wcli0)
+  TSF: 12499150000 usec (0d, 03:28:19)
+  freq: 2437
+  beacon interval: 100 TUs
+  capability: ESS Privacy ShortPreamble SpectrumMgmt ShortSlotTime RadioMeasure (0x1531)
+  signal: -66.00 dBm
+  last seen: 2350 ms ago
+  Information elements from Probe Response frame:
+  SSID:
+  Supported rates: 36.0* 48.0 54.0
+  DS Parameter set: channel 6
+  TIM: DTIM Count 0 DTIM Period 1 Bitmap Control 0x0 Bitmap[0] 0x0
+  Country: US Environment: Indoor/Outdoor
+    Channels [1 - 11] @ 36 dBm
+  Power constraint: 0 dB
+  TPC report: TX power: 3 dBm
+  ERP: <no flags>
+  BSS Load:
+     * station count: 0
+     * channel utilisation: 28/255
+     * available admission capacity: 27500 [*32us]
+  HT capabilities:
+    Capabilities: 0x19ad
+      RX LDPC
+      HT20
+      SM Power Save disabled
+      RX HT20 SGI
+      TX STBC
+      RX STBC 1-stream
+      Max AMSDU length: 7935 bytes
+      DSSS/CCK HT40
+    Maximum RX AMPDU length 65535 bytes (exponent: 0x003)
+    Minimum RX AMPDU time spacing: 4 usec (0x05)
+    HT RX MCS rate indexes supported: 0-23
+    HT TX MCS rate indexes are undefined
+  HT operation:
+     * primary channel: 6
+     * secondary channel offset: no secondary
+     * STA channel width: 20 MHz
+     * RIFS: 1
+     * HT protection: nonmember
+     * non-GF present: 1
+     * OBSS non-GF present: 1
+     * dual beacon: 0
+     * dual CTS protection: 0
+     * STBC beacon: 0
+     * L-SIG TXOP Prot: 0
+     * PCO active: 0
+     * PCO phase: 0
+  Overlapping BSS scan params:
+     * passive dwell: 20 TUs
+     * active dwell: 10 TUs
+     * channel width trigger scan interval: 300 s
+     * scan passive total per channel: 200 TUs
+     * scan active total per channel: 20 TUs
+     * BSS width channel transition delay factor: 5
+     * OBSS Scan Activity Threshold: 0.25 %
+  Extended capabilities: HT Information Exchange Supported, Extended Channel Switching, BSS Transition, 6
+  WMM:   * Parameter version 1
+     * u-APSD
+     * BE: CW 15-1023, AIFSN 3
+     * BK: CW 15-1023, AIFSN 7
+     * VI: CW 7-15, AIFSN 2, TXOP 3008 usec
+     * VO: CW 3-7, AIFSN 2, TXOP 1504 usec
 """
 
 
@@ -573,9 +637,11 @@
                                  bssid='00:23:97:57:f4:d8',
                                  security=['WEP'],
                                  vendor_ies=[test_ie])
-  provisioning_bss_info = iw.BssInfo(ssid='GFiberSetupAutomation',
-                                     bssid='94:b4:0f:f1:36:41',
+  provisioning_bss_info = iw.BssInfo(ssid=iw.DEFAULT_GFIBERSETUP_SSID,
+                                     bssid='94:b4:0f:f1:36:42',
                                      vendor_ies=[test_ie, ssid_ie])
+  provisioning_bss_info_frenzy = iw.BssInfo(ssid=iw.DEFAULT_GFIBERSETUP_SSID,
+                                            bssid='f4:f5:e8:f1:36:43')
 
   with_ie, without_ie = iw.find_bssids('wcli0', lambda o, d: o == '00:11:22',
                                        True)
@@ -584,7 +650,8 @@
 
   wvtest.WVPASSEQ(
       without_ie,
-      set([iw.BssInfo(ssid='GoogleGuest', bssid='94:b4:0f:f1:36:41'),
+      set([provisioning_bss_info_frenzy,
+           iw.BssInfo(ssid='GoogleGuest', bssid='94:b4:0f:f1:36:41'),
            iw.BssInfo(ssid='GoogleGuest', bssid='94:b4:0f:f1:3a:e1'),
            iw.BssInfo(ssid='GoogleGuest', bssid='94:b4:0f:f1:35:61'),
            iw.BssInfo(ssid='Google', bssid='94:b4:0f:f1:36:40',
@@ -601,7 +668,8 @@
   wvtest.WVPASSEQ(with_ie, set([provisioning_bss_info]))
   wvtest.WVPASSEQ(
       without_ie,
-      set([iw.BssInfo(ssid='GoogleGuest', bssid='94:b4:0f:f1:36:41'),
+      set([provisioning_bss_info_frenzy,
+           iw.BssInfo(ssid='GoogleGuest', bssid='94:b4:0f:f1:36:41'),
            iw.BssInfo(ssid='GoogleGuest', bssid='94:b4:0f:f1:3a:e1'),
            iw.BssInfo(ssid='GoogleGuest', bssid='94:b4:0f:f1:35:61')]))
 
diff --git a/conman/test/fake_wpactrl/wpactrl/__init__.py b/conman/test/fake_wpactrl/wpactrl/__init__.py
index e69de29..b8ce1fd 100644
--- a/conman/test/fake_wpactrl/wpactrl/__init__.py
+++ b/conman/test/fake_wpactrl/wpactrl/__init__.py
@@ -0,0 +1,5 @@
+class error(Exception):
+  pass
+
+class WPACtrl(object):
+  pass
diff --git a/craftui/craftui.py b/craftui/craftui.py
index 59441b3..1bcd704 100755
--- a/craftui/craftui.py
+++ b/craftui/craftui.py
@@ -171,14 +171,24 @@
   example = '******'
 
   def Validate(self, value):
-    super(VPassword, self).Validate(value)
-    pw = ''
+    # value is { admin: admin_pw, new: new_pw, confirm: confirm_pw }
+    # passwords are in base64
+    super(VPassword, self).Validate(value['new'])
+
+    # TODO(edjames) ascii decodes legally; how to check it's really base64?
     try:
-      pw = base64.b64decode(value)
+      current = base64.b64decode(self.admin)
+      admin_pw = base64.b64decode(value['admin'])
+      new_pw = base64.b64decode(value['new'])
     except TypeError:
       raise ConfigError('passwords must be base64 encoded')
-    # TODO(edjames) ascii decodes legally; how to check it's really base64?
-    if len(pw) < 5 or len(pw) > 16:
+
+    # verify correct admin pw is passed, confirm matches
+    if current != admin_pw:
+      raise ConfigError('admin password is incorrect')
+    if value['new'] != value['confirm']:
+      raise ConfigError('new password does not match confirm password')
+    if len(new_pw) < 5 or len(new_pw) > 16:
       raise ConfigError('passwords should be 5-16 characters')
 
 
@@ -194,6 +204,9 @@
   def Configure(self):
     raise Exception('override Config.Configure')
 
+  def SetUI(self, ui):
+    self.ui = ui
+
   @staticmethod
   def Run(command):
     """Run a command."""
@@ -216,6 +229,15 @@
     Config.Run(['ptp-config', '-s', self.key, self.validator.config])
 
 
+class PtpPassword(PtpConfig):
+  """Configure a password (need password_admin setting)."""
+
+  def Validate(self, value):
+    admin = self.ui.ReadFile('%s/config/settings/password_admin' % self.ui.sim)
+    self.validator.admin = admin
+    super(PtpPassword, self).Validate(value)
+
+
 class PtpActivate(Config):
   """Configure using ptp-config."""
 
@@ -266,8 +288,8 @@
   """A web server that configures and displays Chimera data."""
 
   handlers = {
-      'password_admin': PtpConfig(VPassword, 'password_admin'),
-      'password_guest': PtpConfig(VPassword, 'password_guest'),
+      'password_admin': PtpPassword(VPassword, 'password_admin'),
+      'password_guest': PtpPassword(VPassword, 'password_guest'),
 
       'craft_ipaddr': PtpConfig(VSlash, 'craft_ipaddr'),
       'link_ipaddr': PtpConfig(VSlash, 'local_ipaddr'),
@@ -293,8 +315,6 @@
       'rx_gainindex': Glaukus(VGainIndex, '/api/radio/rx/agcDigitalGainIndex',
                               '%s'),
       'palna_on': Glaukus(VTrueFalse, '/api/radio/paLnaPowerEnabled', '%s'),
-      'transceivers_on': Glaukus(VTrueFalse,
-                                 '/api/radio/transceiversPowerEnabled', '%s'),
 
       'reboot': Reboot(VTrueFalse)
   }
@@ -346,6 +366,7 @@
           if k not in self.handlers:
             raise ConfigError('unknown key "%s"' % k)
           h = self.handlers[k]
+          h.SetUI(self)
           h.Validate(v)
       # do it again for real
       for c in conf:
@@ -450,6 +471,7 @@
     data['refreshCount'] += 1
     data['uptime'] = self.ReadFile(sim + '/proc/uptime')
     data['ledstate'] = self.ReadFile(sim + '/tmp/gpio/ledstate')
+    data['peer_up'] = os.path.exists(sim + '/tmp/peer-up')
     cs = '/config/settings/'
     data['craft_ipaddr'] = self.ReadFile(sim + cs + 'craft_ipaddr')
     data['link_ipaddr'] = self.ReadFile(sim + cs + 'local_ipaddr')
diff --git a/craftui/craftui_test.sh b/craftui/craftui_test.sh
index dc71fe2..56be130 100755
--- a/craftui/craftui_test.sh
+++ b/craftui/craftui_test.sh
@@ -177,14 +177,25 @@
   check_success
 
   testname "password is base64"
-  d='{"config":[{"password_guest":"ZHVja3k="}]}'	# ducky
-  $curl $admin_auth -d $d $url/content.json |& grep '"error": 0}'
+  admin=$(echo -n admin | base64)
+  new=$(echo -n ducky | base64)
+  d='{ "config": [ { "password_guest": {
+        "admin": "'"$admin"'",
+        "new": "'"$new"'",
+        "confirm": "'"$new"'"
+      } } ] }'
+  $curl $admin_auth -d "$d" $url/content.json |& grep '"error": 0}'
   check_success
 
   # TODO(edjames): duckduck does not fail.  Need to catch that.
   testname "password not base64"
-  d='{"config":[{"password_guest":"abc123XXX"}]}'
-  $curl $admin_auth -d $d $url/content.json |& grep '"error": 1}'
+  new=ducky
+  d='{ "config": [ { "password_guest": {
+        "admin": "'"$admin"'",
+        "new": "'"$new"'",
+        "confirm": "'"$new"'"
+      } } ] }'
+  $curl $admin_auth -d "$d" $url/content.json |& grep '"error": 1}'
   check_success
 
   testname "process still running at end of test sequence"
diff --git a/craftui/www/config.thtml b/craftui/www/config.thtml
index aa81c3e..7f87c26 100644
--- a/craftui/www/config.thtml
+++ b/craftui/www/config.thtml
@@ -22,179 +22,225 @@
     </section>
   </header>
   <br>
+
   <div class="tabs">
     <div class="tab">
       <input type="radio" id="tab-1" name="tab-group-1" checked>
-      <label for="tab-1">Site Configuration</label>
+      <label for="tab-1">Running Configuration</label>
       <div class="content">
-	<b>Platform Parameters:</b>
-	<table>
-	  <tr>
-	    <td align=center><b>Parameter
-	    <td align=center><b>Active Value
-	    <td align=center><b>Last Configured
-	    <td align=center><b>Configure
-	    <td align=center><b>Status
+        <b>Running Configuration:</b><br>
+        <textarea id=configuration cols=60 rows=30>...</textarea><br>
+        <input type=submit value=Apply onclick="CraftUI.config('password_admin', 0, 1)">
+      </div>
+    </div>
 
-	  <tr>
-	    <td><b>Craft IP Address
-	    <td align=right><span id="platform/active_craft_inet">...</span>
-	    <td align=right>
-	      <span id="platform/craft_ipaddr">...</span>
-	      <input type=submit value="Apply Now" onclick="CraftUI.config('craft_ipaddr', 1)">
-	    <td>
-	      <input id=craft_ipaddr type=text value="">
-	      <input type=submit value=Configure onclick="CraftUI.config('craft_ipaddr')">
-	    <td>
-	      <span id=craft_ipaddr_result>...</span>
+    <div class="tab">
+      <input type="radio" id="tab-2" name="tab-group-1">
+      <label for="tab-2">Passwords</label>
+      <div class="content">
+        <b>Passwords:</b>
+        <table>
+          <tr>
+            <td align=center><b>Account
+            <td align=center><b>Old, New and Confirmed Password
+            <td align=center><b>Status
 
-	  <tr>
-	    <td><b>Link IP Address
-	    <td align=right><span id="platform/active_link_inet">...</span>
-	    <td align=right>
-	      <span id="platform/link_ipaddr">...</span>
-	      <input type=submit value="Apply Now" onclick="CraftUI.config('link_ipaddr', 1)">
-	    <td>
-	      <input id=link_ipaddr type=text value="">
-	      <input type=submit value=Configure onclick="CraftUI.config('link_ipaddr')">
-	    <td>
-	      <span id=link_ipaddr_result>...</span>
+          <tr>
+            <td>
+              Admin
+            <td align=right>
+              Current <b>Admin</b> Password: <input id=password_admin_admin type=password value=""><br>
+              New Admin Password: <input id=password_admin_new type=password value=""><br>
+              Confirm: <input id=password_admin_confirm type=password value=""><br>
+              <input type=submit value="Apply Now" onclick="CraftUI.config('password_admin', 0, 1)">
+            <td>
+              <span id=password_admin_result>...</span>
 
-	  <tr>
-	    <td><b>Peer IP Address
-	    <td align=right>See Peer
-	    <td align=right>
-	      <span id="platform/peer_ipaddr">...</span>
-	      <input type=submit value="Apply Now" onclick="CraftUI.config('peer_ipaddr', 1)">
-	    <td>
-	      <input id=peer_ipaddr type=text value="">
-	      <input type=submit value=Configure onclick="CraftUI.config('peer_ipaddr')">
-	    <td>
-	      <span id=peer_ipaddr_result>...</span>
+          <tr>
+            <td>
+              Guest
+            <td align=right>
+              Current <b>Admin</b> Password: <input id=password_guest_admin type=password value=""><br>
+              New Guest Password: <input id=password_guest_new type=password value=""><br>
+              Confirm: <input id=password_guest_confirm type=password value=""><br>
+              <input type=submit value="Apply Now" onclick="CraftUI.config('password_guest', 0, 1)">
+            <td>
+              <span id=password_guest_result>...</span>
 
-	  <tr>
-	    <td><b>In-band Management VLAN
-	    <td align=right><span id="platform/active_inband_vlan">...</span>
-	    <td align=right>
-	      <span id="platform/vlan_inband">...</span>
-	      <input type=submit value="Apply Now" onclick="CraftUI.config('vlan_inband', 1)">
-	    <td>
-	      <input id=vlan_inband type=text value="">
-	      <input type=submit value=Configure onclick="CraftUI.config('vlan_inband')">
-	    <td>
-	      <span id=vlan_inband_result>...</span>
+        </table>
+      </div>
+    </div>
 
-	  <tr>
-	    <td><b>Out-of-band Management VLAN
-	    <td align=right><span id="platform/active_ooband_vlan">...</span>
-	    <td align=right>
-	      <span id="platform/vlan_ooband">...</span>
-	      <input type=submit value="Apply Now" onclick="CraftUI.config('vlan_ooband', 1)">
-	    <td>
-	      <input id=vlan_ooband type=text value="">
-	      <input type=submit value=Configure onclick="CraftUI.config('vlan_ooband')">
-	    <td>
-	      <span id=vlan_ooband_result>...</span>
+    <div class="tab">
+      <input type="radio" id="tab-3" name="tab-group-1">
+      <label for="tab-3">Network</label>
+      <div class="content">
+        <b>Platform Parameters:</b>
+        <table>
+          <tr>
+            <td align=center><b>Parameter
+            <td align=center><b>Active Value
+            <td align=center><b>Last Configured
+            <td align=center><b>Configure
+            <td align=center><b>Status
 
-	  <tr>
-	    <td><b>Link VLAN (to peer)
-	    <td align=right><span id="platform/active_link_vlan">...</span>
-	    <td align=right>
-	      <span id="platform/vlan_link">...</span>
-	      <input type=submit value="Apply Now" onclick="CraftUI.config('vlan_peer', 1)">
-	    <td>
-	      <input id=vlan_peer type=text value="">
-	      <input type=submit value=Configure onclick="CraftUI.config('vlan_peer')">
-	    <td>
-	      <span id=vlan_peer_result>...</span>
+          <tr>
+            <td><b>Craft IP Address
+            <td align=right><span id="platform/active_craft_inet">...</span>
+            <td align=right>
+              <span id="platform/craft_ipaddr">...</span>
+              <input type=submit value="Apply Now" onclick="CraftUI.config('craft_ipaddr', 1)">
+            <td>
+              <input id=craft_ipaddr type=text value="">
+              <input type=submit value=Configure onclick="CraftUI.config('craft_ipaddr')">
+            <td>
+              <span id=craft_ipaddr_result>...</span>
 
-	</table>
-	<b>Radio Parameters:</b>
-	<table>
-	  <tr>
-	    <td align=center><b>Parameter
-	    <td align=center><b>Active Value
-	    <td align=center><b>Configure and Apply
-	    <td align=center><b>Status
+          <tr>
+            <td><b>Link IP Address
+            <td align=right><span id="platform/active_link_inet">...</span>
+            <td align=right>
+              <span id="platform/link_ipaddr">...</span>
+              <input type=submit value="Apply Now" onclick="CraftUI.config('link_ipaddr', 1)">
+            <td>
+              <input id=link_ipaddr type=text value="">
+              <input type=submit value=Configure onclick="CraftUI.config('link_ipaddr')">
+            <td>
+              <span id=link_ipaddr_result>...</span>
 
-	  <tr>
-	    <td><b>High Frequency
-	    <td align=right><span id="radio/hiTransceiver/pll/frequency">...</span>
-	    <td>
-	      <input id=freq_hi type=text value="">
-	      <input type=submit value=Configure onclick="CraftUI.config('freq_hi')">
-	    <td>
-	      <span id=freq_hi_result>...</span>
+          <tr>
+            <td><b>Peer IP Address
+            <td align=right>See Peer
+            <td align=right>
+              <span id="platform/peer_ipaddr">...</span>
+              <input type=submit value="Apply Now" onclick="CraftUI.config('peer_ipaddr', 1)">
+            <td>
+              <input id=peer_ipaddr type=text value="">
+              <input type=submit value=Configure onclick="CraftUI.config('peer_ipaddr')">
+            <td>
+              <span id=peer_ipaddr_result>...</span>
 
-	  <tr>
-	    <td><b>Low Frequency
-	    <td align=right><span id="radio/loTransceiver/pll/frequency">...</span>
-	    <td>
-	      <input id=freq_lo type=text value="">
-	      <input type=submit value=Configure onclick="CraftUI.config('freq_lo')">
-	    <td>
-	      <span id=freq_lo_result>...</span>
+          <tr>
+            <td><b>In-band Management VLAN
+            <td align=right><span id="platform/active_inband_vlan">...</span>
+            <td align=right>
+              <span id="platform/vlan_inband">...</span>
+              <input type=submit value="Apply Now" onclick="CraftUI.config('vlan_inband', 1)">
+            <td>
+              <input id=vlan_inband type=text value="">
+              <input type=submit value=Configure onclick="CraftUI.config('vlan_inband')">
+            <td>
+              <span id=vlan_inband_result>...</span>
 
-	  <tr>
-	    <td><b>High Frequency Mode
-	    <td align=right><span id="radio/hiTransceiver/mode">...</span>
-	    <td>
-	      <input id=mode_hi type=text value="">
-	      <input type=submit value=Configure onclick="CraftUI.config('mode_hi')">
-	    <td>
-	      <span id=mode_hi_result>...</span>
+          <tr>
+            <td><b>Out-of-band Management VLAN
+            <td align=right><span id="platform/active_ooband_vlan">...</span>
+            <td align=right>
+              <span id="platform/vlan_ooband">...</span>
+              <input type=submit value="Apply Now" onclick="CraftUI.config('vlan_ooband', 1)">
+            <td>
+              <input id=vlan_ooband type=text value="">
+              <input type=submit value=Configure onclick="CraftUI.config('vlan_ooband')">
+            <td>
+              <span id=vlan_ooband_result>...</span>
 
-	  <tr>
-	    <td><b>Transmit Power (dB x 100)
-	    <td align=right><span id="radio/tx/paPowerSet">...</span>
-	    <td>
-	      <input id=tx_powerlevel type=text value="">
-	      <input type=submit value=Configure onclick="CraftUI.config('tx_powerlevel')">
-	    <td>
-	      <span id=tx_powerlevel_result>...</span>
+          <tr>
+            <td><b>Link VLAN (to peer)
+            <td align=right><span id="platform/active_link_vlan">...</span>
+            <td align=right>
+              <span id="platform/vlan_link">...</span>
+              <input type=submit value="Apply Now" onclick="CraftUI.config('vlan_peer', 1)">
+            <td>
+              <input id=vlan_peer type=text value="">
+              <input type=submit value=Configure onclick="CraftUI.config('vlan_peer')">
+            <td>
+              <span id=vlan_peer_result>...</span>
 
-	  <tr>
-	    <td><b>Transmit VGA Gain
-	    <td align=right><span id="radio/tx/vgaGain">...</span>
-	    <td>
-	      <input id=tx_gain type=text value="">
-	      <input type=submit value=Configure onclick="CraftUI.config('tx_gain')">
-	    <td>
-	      <span id=tx_gain_result>...</span>
+        </table>
+      </div>
+    </div>
 
-	  <tr>
-	    <td><b>Receiver AGC Digital Gain Index
-	    <td align=right><span id="radio/rx/agcDigitalGainIndex">...</span>
-	    <td>
-	      <input id=rx_gainindex type=text value="">
-	      <input type=submit value=Configure onclick="CraftUI.config('rx_gainindex')">
-	    <td>
-	      <span id=rx_gainindex_result>...</span>
+    <div class="tab">
+      <input type="radio" id="tab-4" name="tab-group-1">
+      <label for="tab-4">Radio</label>
+      <div class="content">
+        <b>Radio Parameters:</b>
+        <table>
+          <tr>
+            <td align=center><b>Parameter
+            <td align=center><b>Active Value
+            <td align=center><b>Configure and Apply
+            <td align=center><b>Status
 
-	  <tr>
-	    <td><b>Receiver PA/LNA Power Enabled
-	    <td align=right><span id="radio/paLnaPowerEnabled">...</span>
-	    <td>
-	      <input id=palna_on type=text value="">
-	      <input type=submit value=Configure onclick="CraftUI.config('palna_on')">
-	    <td>
-	      <span id=palna_on_result>...</span>
+          <tr>
+            <td><b>High Frequency
+            <td align=right><span id="radio/hiTransceiver/pll/frequency">...</span>
+            <td>
+              <input id=freq_hi type=text value="">
+              <input type=submit value=Configure onclick="CraftUI.config('freq_hi')">
+            <td>
+              <span id=freq_hi_result>...</span>
 
-	  <tr>
-	    <td><b>Transceivers Power Enabled
-	    <td align=right><span id="radio/transceiversPowerEnabled">...</span>
-	    <td>
-	      <input id=transceivers_on type=text value="">
-	      <input type=submit value=Configure onclick="CraftUI.config('transceivers_on')">
-	    <td>
-	      <span id=transceivers_on_result>...</span>
+          <tr>
+            <td><b>Low Frequency
+            <td align=right><span id="radio/loTransceiver/pll/frequency">...</span>
+            <td>
+              <input id=freq_lo type=text value="">
+              <input type=submit value=Configure onclick="CraftUI.config('freq_lo')">
+            <td>
+              <span id=freq_lo_result>...</span>
 
-	</table>
+          <tr>
+            <td><b>High Frequency Mode
+            <td align=right><span id="radio/hiTransceiver/mode">...</span>
+            <td>
+              <input id=mode_hi type=text value="">
+              <input type=submit value=Configure onclick="CraftUI.config('mode_hi')">
+            <td>
+              <span id=mode_hi_result>...</span>
+
+          <tr>
+            <td><b>Transmit Power (dB x 100)
+            <td align=right><span id="radio/tx/paPowerSet">...</span>
+            <td>
+              <input id=tx_powerlevel type=text value="">
+              <input type=submit value=Configure onclick="CraftUI.config('tx_powerlevel')">
+            <td>
+              <span id=tx_powerlevel_result>...</span>
+
+          <tr>
+            <td><b>Transmit VGA Gain
+            <td align=right><span id="radio/tx/vgaGain">...</span>
+            <td>
+              <input id=tx_gain type=text value="">
+              <input type=submit value=Configure onclick="CraftUI.config('tx_gain')">
+            <td>
+              <span id=tx_gain_result>...</span>
+
+          <tr>
+            <td><b>Receiver AGC Digital Gain Index
+            <td align=right><span id="radio/rx/agcDigitalGainIndex">...</span>
+            <td>
+              <input id=rx_gainindex type=text value="">
+              <input type=submit value=Configure onclick="CraftUI.config('rx_gainindex')">
+            <td>
+              <span id=rx_gainindex_result>...</span>
+
+          <tr>
+            <td><b>PA & LNA Enabled
+            <td align=right><span id="radio/paLnaPowerEnabled">...</span>
+            <td>
+              <input id=palna_on type=text value="">
+              <input type=submit value=Configure onclick="CraftUI.config('palna_on')">
+            <td>
+              <span id=palna_on_result>...</span>
+
+        </table>
       </div>
     </div>
     <div class="tab">
-      <input type="radio" id="tab-2" name="tab-group-1">
-      <label for="tab-2">Debug</label>
+      <input type="radio" id="tab-5" name="tab-group-1">
+      <label for="tab-5">Debug</label>
       <div class="content">
         <b>refreshCount:</b><span class="values" id="platform/refreshCount">...</span><br>
         <b>unhandled xml:</b><span class="values" id="unhandled"></span>
diff --git a/craftui/www/index.thtml b/craftui/www/index.thtml
index 54a5ccb..3ca4237 100644
--- a/craftui/www/index.thtml
+++ b/craftui/www/index.thtml
@@ -39,6 +39,7 @@
       <input type="radio" id="tab-2" name="tab-group-1">
       <label for="tab-2">Network</label>
       <div class="content">
+        <b>Peer is up:</b><span class="values" id="platform/peer_up">...</span><br>
         <b>IP Addresses:</b>
 	<table>
 	  <tr>
diff --git a/craftui/www/static/craft.js b/craftui/www/static/craft.js
index f93df89..fe7d9bc 100644
--- a/craftui/www/static/craft.js
+++ b/craftui/www/static/craft.js
@@ -82,20 +82,28 @@
   xhr.send();
 };
 
-CraftUI.config = function(key, activate) {
+CraftUI.config = function(key, activate, is_password) {
   // POST as json
   var el = document.getElementById(key);
-  var value = el.value;
   var xhr = new XMLHttpRequest();
   var action = "Configured";
   xhr.open('post', 'content.json');
   xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
   var data;
-  if (activate) {
+  if (is_password) {
+    var value_admin = btoa(document.getElementById(key + "_admin").value);
+    var value_new = btoa(document.getElementById(key + "_new").value);
+    var value_confirm = btoa(document.getElementById(key + "_confirm").value);
+    data = { config: [ { [key]: {
+          "admin": value_admin,
+          "new": value_new,
+          "confirm": value_confirm,
+        } } ] };
+  } else if (activate) {
     data = { config: [ { [key + "_activate"]: "true" } ] };
     action = "Applied";
   } else {
-    data = { config: [ { [key]: value } ] };
+    data = { config: [ { [key]: el.value } ] };
   }
   var txt = JSON.stringify(data);
   var resultid = key + "_result"
diff --git a/ginstall/ginstall.py b/ginstall/ginstall.py
index 983d76c..5db5493 100755
--- a/ginstall/ginstall.py
+++ b/ginstall/ginstall.py
@@ -346,6 +346,13 @@
   return subprocess.call(cmd)
 
 
+def UnlockMtd(mtddevname):
+  """Unlocks an mtd partition."""
+  VerbosePrint('Unlocking flash partition %r\n', mtddevname)
+  cmd = ['flash_unlock', mtddevname]
+  return subprocess.call(cmd)
+
+
 def Nandwrite(f, mtddevname):
   """Write file to NAND flash using nandwrite."""
   cmd = ['nandwrite', '--quiet', '--markbad', mtddevname]
@@ -415,6 +422,9 @@
   """Write an image to an mtd device."""
   if not isinstance(f, FileWithSecureHash):
     f = FileWithSecureHash(f, None)
+  if GetPlatform().startswith('GFLT'):
+    if UnlockMtd(mtddevname):
+      raise IOError('Flash unlocking failed.')
   if EraseMtd(mtddevname):
     raise IOError('Flash erase failed.')
   VerbosePrint('Writing to mtd partition %r\n', mtddevname)
diff --git a/ginstall/install_test.sh b/ginstall/install_test.sh
index 38064f5..4338bac 100755
--- a/ginstall/install_test.sh
+++ b/ginstall/install_test.sh
@@ -182,7 +182,9 @@
 expected="\
 psback
 logos ginstall
+flash_unlock ${tmpdir}/dev/mtd6
 flash_erase --quiet ${tmpdir}/dev/mtd6 0 0
+flash_unlock ${tmpdir}/dev/mtd0
 flash_erase --quiet ${tmpdir}/dev/mtd0 0 0
 hnvram -q -w ACTIVATED_KERNEL_NAME=kernel0"
 
diff --git a/ginstall/testdata/bin/flash_unlock b/ginstall/testdata/bin/flash_unlock
new file mode 120000
index 0000000..3c2bde7
--- /dev/null
+++ b/ginstall/testdata/bin/flash_unlock
@@ -0,0 +1 @@
+write_args_to_file
\ No newline at end of file
diff --git a/jsonpoll/jsonpoll.py b/jsonpoll/jsonpoll.py
index f69fac3..bee52a0 100755
--- a/jsonpoll/jsonpoll.py
+++ b/jsonpoll/jsonpoll.py
@@ -23,7 +23,6 @@
 import socket
 import sys
 import tempfile
-import textwrap
 import time
 import urllib2
 import options
@@ -61,17 +60,39 @@
                                'api/radio': self.api_radio_output_file}
     self.last_response = None
 
+  def _FlatObject(self, base, obj, out):
+    """Open json object to a list of strings.
+
+    Args:
+      base: is a string that has a base name for a key.
+      obj: is a JSON object that will be flatten.
+      out: is an output where strings will be appended.
+
+    Example:
+         data = {"a": 1, "b": { "c": 2, "d": 3}}
+         out = []
+         _FlatObject('', data, out)
+
+         out will be equal to
+           [u'/a=1', u'/b/c=2', u'/b/d=3']
+    """
+    for k, v in obj.items():
+      name = base + '/' + k
+      if isinstance(v, dict):
+        self._FlatObject(name, v, out)
+      else:
+        val = '%s=' % name
+        out.append(val + str(v))
+
   def WriteToStderr(self, msg, is_json=False):
     """Write a message to stderr."""
     if is_json:
-      # Make the json easier to parse from the logs.
       json_data = json.loads(msg)
-      json_str = json.dumps(json_data, sort_keys=True, indent=2,
-                            separators=(',', ': '))
-      # Logging pretty-printed json is like logging one huge line. Logos is
-      # configured to limit lines to 768 characters. Split the logged output at
-      # half of that to make sure logos doesn't clip our output.
-      sys.stderr.write('\n'.join(textwrap.wrap(json_str, width=384)))
+      flat_data = []
+      self._FlatObject('', json_data, flat_data)
+      # Make the json easier to parse from the logs.
+      for s in flat_data:
+        sys.stderr.write('%s\n' % s)
       sys.stderr.flush()
     else:
       sys.stderr.write(msg)
diff --git a/jsonpoll/jsonpoll_test.py b/jsonpoll/jsonpoll_test.py
index d8431f0..f4f0240 100644
--- a/jsonpoll/jsonpoll_test.py
+++ b/jsonpoll/jsonpoll_test.py
@@ -120,6 +120,12 @@
       output = ''.join(line.rstrip() for line in f)
       self.assertEqual('', output)
 
+  def testFlatObject(self):
+    obj = {'key1': 1, 'key2': {'key3': 3, 'key4': 4}}
+    got = []
+    self.poller._FlatObject('base', obj, got)
+    want = ['base/key1=1', 'base/key2/key3=3', 'base/key2/key4=4']
+    self.assertEqual(got.sort(), want.sort())
 
 if __name__ == '__main__':
   unittest.main()
diff --git a/ledpattern/Makefile b/ledpattern/Makefile
new file mode 100644
index 0000000..705a398
--- /dev/null
+++ b/ledpattern/Makefile
@@ -0,0 +1,28 @@
+default:
+
+PREFIX=/
+BINDIR=$(DESTDIR)$(PREFIX)/bin
+PYTHON?=python
+
+all:
+
+install:
+	mkdir -p $(BINDIR)
+	cp ledpattern.py $(BINDIR)/ledpattern
+
+install-libs:
+	@echo "No libs to install."
+
+test: lint
+	set -e; \
+	for pytest in $(wildcard *_test.py); do \
+		echo; \
+		echo "Testing $$pytest"; \
+		$(PYTHON) $$pytest; \
+	done
+
+clean:
+	rm -rf *.pyc
+
+lint:
+	gpylint ledpattern.py ledpattern_test.py
diff --git a/ledpattern/ledpattern.py b/ledpattern/ledpattern.py
new file mode 100755
index 0000000..bcd3b03
--- /dev/null
+++ b/ledpattern/ledpattern.py
@@ -0,0 +1,163 @@
+#!/usr/bin/python
+
+"""Blinks a specific LED pattern read from a simple pattern file.
+
+The first value is the state that the LED pattern represents. Followed by
+any combination of the following values:
+
+  R = Red blink
+  B = Blue blink
+  P = Purple blink
+
+An example pattern file might look like:
+
+ echo "blink,R,R,R" > /tmp/test.pat
+
+Invoking "ledpattern.py /tmp/test.pat blink" would result in the red LED
+blinking three times.
+"""
+
+__author__ = 'Chris Gibson <cgibson@google.com>'
+
+import csv
+import os
+import sys
+import time
+
+# Unit tests can override these values.
+DISABLE_GPIOMAILBOX = '/tmp/gpio/disable'
+SYSFS_RED_BRIGHTNESS = '/sys/class/leds/sys-red/brightness'
+SYSFS_BLUE_BRIGHTNESS = '/sys/class/leds/sys-blue/brightness'
+SLEEP_TIMEOUT = 0.5
+
+
+class LedPattern(object):
+  """Read, parse, and blink LEDs based on a pattern from a file."""
+
+  def ReadCsvPatternFile(self, pattern_file, state):
+    """Read a CSV pattern file."""
+    if not os.path.exists(pattern_file):
+      print 'Error: Pattern file: "%s" not found.' % pattern_file
+      return None
+    if not state:
+      print 'Error: led state cannot be empty.'
+      return None
+    try:
+      with open(pattern_file, 'r') as f:
+        patterns = csv.reader(f, delimiter=',')
+        for row in patterns:
+          if row[0] == state:
+            return [c for c in row[1:] if c in ['R', 'B', 'P']]
+      print ('Error: Could not find led state: "%s" in pattern file: %s'
+             % (state, pattern_file))
+      return None
+    except (IOError, OSError) as ex:
+      print ('Failed to open the pattern file: %s, error: %s.'
+             % (pattern_file, ex))
+      return None
+
+  def SetRedBrightness(self, level):
+    with open(SYSFS_RED_BRIGHTNESS, 'w') as f:
+      f.write(level)
+
+  def SetBlueBrightness(self, level):
+    with open(SYSFS_BLUE_BRIGHTNESS, 'w') as f:
+      f.write(level)
+
+  def SetLedsOff(self):
+    self.SetRedBrightness('0')
+    self.SetBlueBrightness('0')
+
+  def RedBlink(self):
+    self.SetLedsOff()
+    time.sleep(SLEEP_TIMEOUT)
+    self.SetRedBrightness('100')
+    self.SetBlueBrightness('0')
+    time.sleep(SLEEP_TIMEOUT)
+    self.SetLedsOff()
+
+  def BlueBlink(self):
+    self.SetLedsOff()
+    time.sleep(SLEEP_TIMEOUT)
+    self.SetRedBrightness('0')
+    self.SetBlueBrightness('100')
+    time.sleep(SLEEP_TIMEOUT)
+    self.SetLedsOff()
+
+  def PurpleBlink(self):
+    self.SetLedsOff()
+    time.sleep(SLEEP_TIMEOUT)
+    self.SetRedBrightness('100')
+    self.SetBlueBrightness('100')
+    time.sleep(SLEEP_TIMEOUT)
+    self.SetLedsOff()
+
+  def PlayPattern(self, pattern):
+    for color in pattern:
+      if color == 'R':
+        self.RedBlink()
+      elif color == 'B':
+        self.BlueBlink()
+      elif color == 'P':
+        self.PurpleBlink()
+
+  def Run(self, pattern_file, state):
+    """Sets up an LED pattern to play.
+
+    Arguments:
+      pattern_file: Pattern file containing a list of LED states/patterns.
+      state: Name of the LED state to play.
+
+    Returns:
+      An integer exit code: 0 means everything succeeded. Non-zero exit codes
+      mean something went wrong.
+    """
+    try:
+      open(DISABLE_GPIOMAILBOX, 'w').close()
+    except (IOError, OSError) as ex:
+      # If we can't disable gpio-mailbox then we can't guarantee control
+      # over the LEDs, so we just have to admit defeat.
+      print 'Error: Failed to disable gpio-mailbox! %s' % ex
+      return 1
+
+    try:
+      pattern = self.ReadCsvPatternFile(pattern_file, state)
+      if not pattern:
+        print 'Reading pattern failed! Exiting!'
+        return 1
+    except (IOError, OSError) as ex:
+      print 'Error: Failed to read pattern file, %s' % ex
+      return 1
+
+    # Depending on what state the LEDs are in when we touched the gpio-mailbox
+    # disable file, the LEDs will remain in that last state. Firstly, turn both
+    # LEDs off then sleep for a second to indicate that the pattern is about
+    # to begin.
+    self.SetLedsOff()
+    time.sleep(1)
+
+    self.PlayPattern(pattern)
+
+    # Turn off the LEDs and sleep for a second to clearly delineate the end of
+    # the current pattern.
+    self.SetLedsOff()
+    time.sleep(1)
+
+    os.unlink(DISABLE_GPIOMAILBOX)
+    return 0
+
+
+def Usage():
+  print 'Usage:'
+  print '  %s {pattern file} {state}' % sys.argv[0]
+  print
+  print '    pattern file: path to a pattern file'
+  print '    state: the LED state to select'
+
+
+if __name__ == '__main__':
+  if len(sys.argv) != 3:
+    Usage()
+    sys.exit(1)
+  ledpattern = LedPattern()
+  sys.exit(ledpattern.Run(sys.argv[1], sys.argv[2]))
diff --git a/ledpattern/ledpattern_test.py b/ledpattern/ledpattern_test.py
new file mode 100755
index 0000000..0a42dad
--- /dev/null
+++ b/ledpattern/ledpattern_test.py
@@ -0,0 +1,70 @@
+#!/usr/bin/python
+
+"""Tests for ledpattern."""
+
+import os
+import tempfile
+import unittest
+
+import ledpattern
+
+
+class TestLedpattern(unittest.TestCase):
+
+  def setUp(self):
+    self.ledpattern = ledpattern.LedPattern()
+    self.fd_red, ledpattern.SYSFS_RED_BRIGHTNESS = tempfile.mkstemp()
+    print ledpattern.SYSFS_RED_BRIGHTNESS
+    self.fd_blue, ledpattern.SYSFS_BLUE_BRIGHTNESS = tempfile.mkstemp()
+    print ledpattern.SYSFS_BLUE_BRIGHTNESS
+
+  def tearDown(self):
+    os.close(self.fd_red)
+    os.close(self.fd_blue)
+    os.unlink(ledpattern.SYSFS_RED_BRIGHTNESS)
+    os.unlink(ledpattern.SYSFS_BLUE_BRIGHTNESS)
+
+  def testReadCsvPatternFileTest(self):
+    expected = ['R', 'B', 'P']
+    actual = self.ledpattern.ReadCsvPatternFile('./testdata/test.pat', 'test')
+    self.assertEqual(expected, actual)
+
+  def testReadCsvPatternFileNotFound(self):
+    actual = self.ledpattern.ReadCsvPatternFile('/does/not/exist.pat', 'test')
+    self.assertEqual(None, actual)
+
+  def testReadCsvPatternFileNoState(self):
+    actual = self.ledpattern.ReadCsvPatternFile('./testdata/test.pat', '')
+    self.assertEqual(None, actual)
+
+  def testReadCsvPatternFileIsMissingState(self):
+    actual = self.ledpattern.ReadCsvPatternFile('./testdata/test.pat', 'foo')
+    self.assertEqual(None, actual)
+
+  def testReadCsvPatternFileInvalidCharsGetFiltered(self):
+    expected = ['B', 'B', 'B']
+    actual = self.ledpattern.ReadCsvPatternFile('./testdata/test.pat',
+                                                'test_with_invalid_chars')
+    self.assertEqual(expected, actual)
+
+  def testReadCsvPatternFileEmptyPattern(self):
+    expected = []
+    actual = self.ledpattern.ReadCsvPatternFile('./testdata/test.pat',
+                                                'test_empty_pattern')
+    self.assertEqual(expected, actual)
+
+  def testSetRedBrightness(self):
+    self.ledpattern.SetRedBrightness('foo')
+    with open(ledpattern.SYSFS_RED_BRIGHTNESS, 'r') as f:
+      actual = f.read()
+    self.assertEqual('foo', actual)
+
+  def testSetBlueBrightness(self):
+    self.ledpattern.SetBlueBrightness('bar')
+    with open(ledpattern.SYSFS_BLUE_BRIGHTNESS, 'r') as f:
+      actual = f.read()
+    self.assertEqual('bar', actual)
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/ledpattern/testdata/test.pat b/ledpattern/testdata/test.pat
new file mode 100644
index 0000000..6b49acf
--- /dev/null
+++ b/ledpattern/testdata/test.pat
@@ -0,0 +1,3 @@
+test_with_invalid_chars,B,B,B,X,X,X
+test,R,B,P
+test_empty_pattern,,
diff --git a/logupload/client/log_uploader_main.c b/logupload/client/log_uploader_main.c
index 7a4e0fb..e160dd1 100644
--- a/logupload/client/log_uploader_main.c
+++ b/logupload/client/log_uploader_main.c
@@ -52,6 +52,13 @@
   interrupted = 1;
 }
 
+static void got_usr1(int sig) {
+  // Do nothing.
+  // We create the signal handler without SA_RESTART, so this will interrupt
+  // an in-progress sleep, which is enough to wake us up and cause another
+  // upload cycle, if we're not already uploading.
+}
+
 // To allow overriding for testing.
 int getnameinfo_resolver(const struct sockaddr* sa, socklen_t salen, char* host,
     size_t hostlen, char* serv, size_t servlen, int flags) {
@@ -92,7 +99,7 @@
   fprintf(stderr, " --server URL    Server URL [" DEFAULT_SERVER "]\n");
   fprintf(stderr, " --all           Upload entire logs, not just new data\n");
   fprintf(stderr, " --logtype TYPE  Tell server which log category this is\n");
-  fprintf(stderr, " --freq SECS     Upload logs every SECS seconds [60]\n");
+  fprintf(stderr, " --freq SECS     Repeat every SECS secs (default=once)\n");
   fprintf(stderr, " --stdout        Print to stdout instead of uploading\n");
   fprintf(stderr,
           " --stdin NAME    Get data from stdin, not /dev/kmsg, and\n"
@@ -183,6 +190,9 @@
   sa.sa_handler = got_alarm;
   sigaction(SIGALRM, &sa, NULL);
 
+  sa.sa_handler = got_usr1;
+  sigaction(SIGUSR1, &sa, NULL);
+
   // Initialize the random number generator
   srandom(getpid() ^ time(NULL));
 
@@ -220,7 +230,7 @@
   parse_params.dev_kmsg_path = DEV_KMSG_PATH;
   parse_params.version_path = VERSION_PATH;
   parse_params.ntp_synced_path = NTP_SYNCED_PATH;
-  // This'll set it to zero if it can't read the file which is fine.
+  // This'll set it to zero if it can't read the file, which is fine.
   parse_params.last_log_counter = read_file_as_uint64(COUNTER_MARKER_FILE);
   parse_params.log_buffer = log_buffer;
   parse_params.line_buffer = line_buffer;
diff --git a/presterastats/presterastats.py b/presterastats/presterastats.py
index bb703c5..2757e0c 100755
--- a/presterastats/presterastats.py
+++ b/presterastats/presterastats.py
@@ -75,7 +75,7 @@
       return
     kill_proc = lambda p: os.killpg(os.getpgid(p.pid), signal.SIGTERM)
     timer = threading.Timer(self.timeout, kill_proc, [proc])
-    cpss_cmd_prefix = 'show interfaces mac json-counters ethernet '
+    cpss_cmd_prefix = 'do show interfaces mac json-counters ethernet '
     try:
       timer.start()
       cpssout, _ = proc.communicate(input=cpss_cmd_prefix + self.ports + '\n')
diff --git a/taxonomy/dhcp.py b/taxonomy/dhcp.py
index db3797d..19b7cd6 100644
--- a/taxonomy/dhcp.py
+++ b/taxonomy/dhcp.py
@@ -74,8 +74,8 @@
 
     '1,28,2,3,15,6,12': ['tivo'],
 
-    '1,3,6,12,15,28,42': ['visiotv', 'wemo'],
-    '1,3,6,12,15,28,40,41,42': ['visiotv', 'kindle'],
+    '1,3,6,12,15,28,42': ['viziotv', 'wemo'],
+    '1,3,6,12,15,28,40,41,42': ['viziotv', 'kindle'],
 
     '1,3,6,15,28,33': ['wii'],
     '1,3,6,15': ['wii', 'xbox'],
diff --git a/taxonomy/ethernet.py b/taxonomy/ethernet.py
index 7489a76..223d228 100644
--- a/taxonomy/ethernet.py
+++ b/taxonomy/ethernet.py
@@ -38,6 +38,7 @@
 
     '08:60:6e': ['asus'],
     '08:62:66': ['asus'],
+    '10:bf:48': ['asus'],
     '1c:87:2c': ['asus'],
     '2c:56:dc': ['asus'],
     '30:85:a9': ['asus'],
@@ -94,6 +95,7 @@
     '3c:bd:d8': ['lg'],
     '40:b0:fa': ['lg'],
     '58:3f:54': ['lg'],
+    '5c:70:a3': ['lg'],
     '64:89:9a': ['lg'],
     '64:bc:0c': ['lg'],
     '78:f8:82': ['lg'],
@@ -111,6 +113,8 @@
     'f8:95:c7': ['lg'],
     'f8:a9:d0': ['lg'],
 
+    'd0:73:d5': ['lifx'],
+
     '24:fd:52': ['liteon', 'sling'],
 
     '00:0d:3a': ['microsoft'],
@@ -128,6 +132,7 @@
     '60:45:bd': ['microsoft'],
     '7c:1e:52': ['microsoft'],
     '7c:ed:8d': ['microsoft'],
+    '98:5f:d3': ['microsoft'],
     'b4:ae:2b': ['microsoft'],
     'c0:33:5e': ['microsoft'],
 
@@ -146,8 +151,9 @@
     '98:4b:4a': ['motorola'],
     '9c:d9:17': ['motorola'],
     'cc:c3:ea': ['motorola'],
-    'ec:88:92': ['motorola'],
+    'e4:90:7e': ['motorola'],
     'e8:91:20': ['motorola'],
+    'ec:88:92': ['motorola'],
     'f8:7b:7a': ['motorola'],
     'f8:cf:c5': ['motorola'],
     'f8:e0:79': ['motorola'],
@@ -171,7 +177,7 @@
     'fc:c2:de': ['murata', 'samsung'],
     'fc:db:b3': ['murata', 'samsung'],
 
-    '18:b4:30': ['nest'],
+    '18:b4:30': ['nest', 'dropcam'],
 
     'c0:ee:fb': ['oneplus'],
 
@@ -183,8 +189,10 @@
     '14:32:d1': ['samsung'],
     '14:49:e0': ['samsung'],
     '18:22:7e': ['samsung'],
+    '20:55:31': ['samsung'],
     '20:6e:9c': ['samsung'],
     '24:4b:81': ['samsung'],
+    '28:27:bf': ['samsung'],
     '28:ba:b5': ['samsung'],
     '2c:ae:2b': ['samsung'],
     '30:19:66': ['samsung'],
@@ -194,6 +202,7 @@
     '38:d4:0b': ['samsung'],
     '3c:8b:fe': ['samsung'],
     '3c:a1:0d': ['samsung'],
+    '3c:bb:fd': ['samsung'],
     '40:0e:85': ['samsung'],
     '48:5a:3f': ['samsung', 'wisol'],
     '4c:3c:16': ['samsung'],
@@ -207,6 +216,7 @@
     '78:40:e4': ['samsung'],
     '78:d6:f0': ['samsung'],
     '78:bd:bc': ['samsung'],
+    '7c:0b:c6': ['samsung'],
     '80:65:6d': ['samsung'],
     '84:11:9e': ['samsung'],
     '84:25:db': ['samsung'],
@@ -223,10 +233,12 @@
     'a8:06:00': ['samsung'],
     'ac:36:13': ['samsung'],
     'ac:5f:3e': ['samsung'],
+    'b0:47:bf': ['samsung'],
     'b0:df:3a': ['samsung'],
     'b0:ec:71': ['samsung'],
     'b4:07:f9': ['samsung'],
     'b4:79:a7': ['samsung'],
+    'b8:57:d8': ['samsung'],
     'b8:5a:73': ['samsung'],
     'bc:20:a4': ['samsung'],
     'bc:72:b1': ['samsung'],
@@ -238,9 +250,11 @@
     'cc:07:ab': ['samsung'],
     'cc:3a:61': ['samsung'],
     'd0:22:be': ['samsung'],
+    'd0:59:e4': ['samsung'],
     'e0:99:71': ['samsung'],
     'e0:db:10': ['samsung'],
     'e4:12:1d': ['samsung'],
+    'e4:58:b8': ['samsung'],
     'e4:92:fb': ['samsung'],
     'e8:3a:12': ['samsung'],
     'e8:50:8b': ['samsung'],
@@ -248,6 +262,7 @@
     'ec:9b:f3': ['samsung'],
     'f0:25:b7': ['samsung'],
     'f4:09:d8': ['samsung'],
+    'f8:04:2e': ['samsung'],
     'fc:f1:36': ['samsung'],
 
     '00:d9:d1': ['sony'],
diff --git a/taxonomy/pcaptest.py b/taxonomy/pcaptest.py
index 1e7baac..97873b2 100644
--- a/taxonomy/pcaptest.py
+++ b/taxonomy/pcaptest.py
@@ -10,68 +10,74 @@
 regression = [
   # devices for which we have a pcap but have decided not to add
   # to the database
-  ('Unknown', './testdata/pcaps/ASUS Transformer TF300 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Blackberry Bold 9930 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Blackberry Bold 9930 5GHz.pcap'),
-  ('Unknown', './testdata/pcaps/HTC Evo 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/HTC Incredible 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/HTC Inspire 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/HTC Sensation 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/HTC Thunderbolt 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/HTC Titan 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Lenovo_T440_80211ac_2x2_Windows8_2_4_GHz.pcap'),
-  ('Unknown', './testdata/pcaps/LG E900 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/LG G2X 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/LG Revolution 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/MediaTek MT7610U 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Motorola Droid 2 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Motorola Droid 3 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Motorola Droid Razr 2.4GHz XT910 Broadcast Probe.pcap'),
-  ('Unknown', './testdata/pcaps/Motorola Droid Razr 2.4GHz XT910 Specific Probe.pcap'),
-  ('Unknown', './testdata/pcaps/Motorola Droid Razr 2.4GHz XT910.pcap'),
-  ('Unknown', './testdata/pcaps/Motorola Droid Razr 5GHz XT910.pcap'),
-  ('Unknown', './testdata/pcaps/Motorola Droid Razr Maxx 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Nexus One 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Samsung Charge 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Samsung Captivate 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Samsung Continuum 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Samsung Epic 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Samsung Exhibit 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Samsung Fascinate 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Samsung Galaxy Tab 2 2.4GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Samsung Infuse 5GHz.pcap'),
-  ('Unknown', './testdata/pcaps/Samsung Vibrant 2.4GHz.pcap'),
+  ('', './testdata/pcaps/ASUS Transformer TF300 2.4GHz.pcap'),
+  ('', './testdata/pcaps/Blackberry Bold 9930 2.4GHz.pcap'),
+  ('', './testdata/pcaps/Blackberry Bold 9930 5GHz.pcap'),
+  ('', './testdata/pcaps/HTC Evo 2.4GHz.pcap'),
+  ('', './testdata/pcaps/HTC Incredible 2.4GHz.pcap'),
+  ('', './testdata/pcaps/HTC Inspire 2.4GHz.pcap'),
+  ('', './testdata/pcaps/HTC Sensation 2.4GHz.pcap'),
+  ('', './testdata/pcaps/HTC Thunderbolt 2.4GHz.pcap'),
+  ('', './testdata/pcaps/HTC Titan 2.4GHz.pcap'),
+  ('', './testdata/pcaps/Lenovo_T440_80211ac_2x2_Windows8_2_4_GHz.pcap'),
+  ('', './testdata/pcaps/LG E900 2.4GHz.pcap'),
+  ('', './testdata/pcaps/LG G2X 2.4GHz.pcap'),
+  ('', './testdata/pcaps/LG Revolution 2.4GHz.pcap'),
+  ('', './testdata/pcaps/MediaTek MT7610U 2.4GHz.pcap'),
+  ('', './testdata/pcaps/MacBook Air late 2014 (A1466) 5GHz.pcap'),
+  ('', './testdata/pcaps/MacBook Pro early 2014 (A1502) 2.4GHz.pcap'),
+  ('', './testdata/pcaps/MacBook Air late 2014 (A1466) 2.4GHz.pcap'),
+  ('', './testdata/pcaps/MacBook Air late 2010 (A1369) 2.4GHz.pcap'),
+  ('', './testdata/pcaps/MacBook Pro early 2014 (A1502) 5GHz.pcap'),
+  ('', './testdata/pcaps/MacBook Air late 2010 (A1369) 5GHz.pcap'),
+  ('', './testdata/pcaps/Motorola Droid 2 2.4GHz.pcap'),
+  ('', './testdata/pcaps/Motorola Droid 3 2.4GHz.pcap'),
+  ('', './testdata/pcaps/Motorola Droid Razr 2.4GHz XT910 Broadcast Probe.pcap'),
+  ('', './testdata/pcaps/Motorola Droid Razr 2.4GHz XT910 Specific Probe.pcap'),
+  ('', './testdata/pcaps/Motorola Droid Razr 2.4GHz XT910.pcap'),
+  ('', './testdata/pcaps/Motorola Droid Razr 5GHz XT910.pcap'),
+  ('', './testdata/pcaps/Motorola Droid Razr Maxx 2.4GHz.pcap'),
+  ('', './testdata/pcaps/Nexus One 2.4GHz.pcap'),
+  ('', './testdata/pcaps/Samsung Charge 2.4GHz.pcap'),
+  ('', './testdata/pcaps/Samsung Captivate 2.4GHz.pcap'),
+  ('', './testdata/pcaps/Samsung Continuum 2.4GHz.pcap'),
+  ('', './testdata/pcaps/Samsung Epic 2.4GHz.pcap'),
+  ('', './testdata/pcaps/Samsung Exhibit 2.4GHz.pcap'),
+  ('', './testdata/pcaps/Samsung Fascinate 2.4GHz.pcap'),
+  ('', './testdata/pcaps/Samsung Galaxy Tab 2 2.4GHz.pcap'),
+  ('', './testdata/pcaps/Samsung Infuse 5GHz.pcap'),
+  ('', './testdata/pcaps/Samsung Vibrant 2.4GHz.pcap'),
 
   # Names where the identified species doesn't exactly match the filename,
   # usually because multiple devices are too similar to distinguish. We name
   # the file for the specific device which was captured, and add an entry
   # here for the best identification which we can manage.
-  ('iPad (1st/2nd gen)', './testdata/pcaps/iPad 1st gen 5GHz.pcap'),
-  ('iPad (1st/2nd gen)', './testdata/pcaps/iPad 2nd gen 5GHz.pcap'),
-  ('iPad (4th gen or Air)', './testdata/pcaps/iPad (4th gen) 5GHz.pcap'),
-  ('iPad (4th gen or Air)', './testdata/pcaps/iPad (4th gen) 2.4GHz.pcap'),
-  ('iPad (4th gen or Air)', './testdata/pcaps/iPad Air 5GHz.pcap'),
-  ('iPad (4th gen or Air)', './testdata/pcaps/iPad Air 2.4GHz.pcap'),
+  ('iPad 1st or 2nd gen', './testdata/pcaps/iPad 1st gen 5GHz.pcap'),
+  ('iPad 1st or 2nd gen', './testdata/pcaps/iPad 2nd gen 5GHz.pcap'),
+  ('iPad 4th gen or Air 1st gen', './testdata/pcaps/iPad (4th gen) 5GHz.pcap'),
+  ('iPad 4th gen or Air 1st gen', './testdata/pcaps/iPad (4th gen) 2.4GHz.pcap'),
+  ('iPad 4th gen or Air 1st gen', './testdata/pcaps/iPad Air 5GHz.pcap'),
+  ('iPad 4th gen or Air 1st gen', './testdata/pcaps/iPad Air 2.4GHz.pcap'),
   ('iPhone 6/6+', './testdata/pcaps/iPhone 6 5GHz.pcap'),
   ('iPhone 6/6+', './testdata/pcaps/iPhone 6+ 5GHz.pcap'),
   ('iPhone 6s/6s+', './testdata/pcaps/iPhone 6s 2.4GHz.pcap'),
   ('iPhone 6s/6s+', './testdata/pcaps/iPhone 6s+ 2.4GHz.pcap'),
   ('iPhone 6s/6s+', './testdata/pcaps/iPhone 6s 5GHz.pcap'),
   ('iPhone 6s/6s+', './testdata/pcaps/iPhone 6s+ 5GHz.pcap'),
-  ('iPod Touch 1st/2nd gen', './testdata/pcaps/iPod Touch 1st gen 2.4GHz.pcap'),
+  ('iPod Touch 1st or 2nd gen', './testdata/pcaps/iPod Touch 1st gen 2.4GHz.pcap'),
   ('Moto G or Moto X', './testdata/pcaps/Moto X 2.4GHz Specific.pcap'),
   ('Moto G or Moto X', './testdata/pcaps/Moto X 2.4GHz.pcap'),
-  ('Nest Thermostat v1/v2', './testdata/pcaps/Nest Thermostat 2.4GHz.pcap'),
+  ('Nest Thermostat v1 or v2', './testdata/pcaps/Nest Thermostat 2.4GHz.pcap'),
   ('Roku 3 or Streaming Stick', './testdata/pcaps/Roku 3 2.4GHz 4230.pcap'),
   ('Roku 3 or Streaming Stick', './testdata/pcaps/Roku 3 5GHz 4230.pcap'),
   ('Samsung Galaxy Note or S2+', './testdata/pcaps/Samsung Galaxy S2+ 5GHz.pcap'),
   ('Samsung Galaxy Note or S2+', './testdata/pcaps/Samsung Galaxy Note 5GHz.pcap'),
   ('Samsung Galaxy S2 or Infuse', './testdata/pcaps/Samsung Galaxy S2 2.4GHz.pcap'),
   ('Samsung Galaxy S2 or Infuse', './testdata/pcaps/Samsung Infuse 2.4GHz.pcap'),
-  ('Sony Xperia Z4/Z5', './testdata/pcaps/Sony Xperia Z5 5GHz.pcap'),
-  ('Sony Xperia Z4/Z5', './testdata/pcaps/Sony Xperia Z5 2.4GHz.pcap'),
-  ('Sony Xperia Z4/Z5', './testdata/pcaps/Sony Xperia Z4 Tablet 5GHz.pcap'),
-  ('Sony Xperia Z4/Z5', './testdata/pcaps/Sony Xperia Z4 Tablet 2.4GHz.pcap'),
+  ('Sony Xperia Z4 or Z5', './testdata/pcaps/Sony Xperia Z5 5GHz.pcap'),
+  ('Sony Xperia Z4 or Z5', './testdata/pcaps/Sony Xperia Z5 2.4GHz.pcap'),
+  ('Sony Xperia Z4 or Z5', './testdata/pcaps/Sony Xperia Z4 Tablet 5GHz.pcap'),
+  ('Sony Xperia Z4 or Z5', './testdata/pcaps/Sony Xperia Z4 Tablet 2.4GHz.pcap'),
 ]
 
 
@@ -92,11 +98,15 @@
 
 def check_pcap(expected_model, pcap):
   mac, sig = get_taxonomy_from_pcap(pcap)
-  _, actual_model, _ = wifi.identify_wifi_device(sig, mac)
-  if expected_model != actual_model:
+  genus, species, _ = wifi.identify_wifi_device(sig, mac)
+  actual_model = genus + " " + species if species else genus
+  if expected_model and expected_model != actual_model:
     print 'Mismatch in %s: %s %s != %s' % (pcap, mac, expected_model,
                                            actual_model)
     return True
+  if not expected_model and 'Unknown' not in actual_model:
+    print 'Mismatch in %s: %s %s != Unknown' % (pcap, mac, actual_model)
+    return True
 
 
 if __name__ == '__main__':
diff --git "a/taxonomy/testdata/pcaps/Apple TV \0501st gen\051 2.4GHz.pcap" b/taxonomy/testdata/pcaps/Apple TV 1st gen 2.4GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Apple TV \0501st gen\051 2.4GHz.pcap"
rename to taxonomy/testdata/pcaps/Apple TV 1st gen 2.4GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Apple TV \0501st gen\051 5GHz.pcap" b/taxonomy/testdata/pcaps/Apple TV 1st gen 5GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Apple TV \0501st gen\051 5GHz.pcap"
rename to taxonomy/testdata/pcaps/Apple TV 1st gen 5GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Apple TV \0502nd gen\051 2.4GHz.pcap" b/taxonomy/testdata/pcaps/Apple TV 2nd gen 2.4GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Apple TV \0502nd gen\051 2.4GHz.pcap"
rename to taxonomy/testdata/pcaps/Apple TV 2nd gen 2.4GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Apple TV \0502nd gen\051 5GHz.pcap" b/taxonomy/testdata/pcaps/Apple TV 2nd gen 5GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Apple TV \0502nd gen\051 5GHz.pcap"
rename to taxonomy/testdata/pcaps/Apple TV 2nd gen 5GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Apple TV \0503rd gen rev A\051 2.4GHz.pcap" b/taxonomy/testdata/pcaps/Apple TV 3rd gen rev A 2.4GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Apple TV \0503rd gen rev A\051 2.4GHz.pcap"
rename to taxonomy/testdata/pcaps/Apple TV 3rd gen rev A 2.4GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Apple TV \0503rd gen rev A\051 5GHz.pcap" b/taxonomy/testdata/pcaps/Apple TV 3rd gen rev A 5GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Apple TV \0503rd gen rev A\051 5GHz.pcap"
rename to taxonomy/testdata/pcaps/Apple TV 3rd gen rev A 5GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Apple TV \0504th gen\051 2.4GHz.pcap" b/taxonomy/testdata/pcaps/Apple TV 4th gen 2.4GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Apple TV \0504th gen\051 2.4GHz.pcap"
rename to taxonomy/testdata/pcaps/Apple TV 4th gen 2.4GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Apple TV \0504th gen\051 5GHz.pcap" b/taxonomy/testdata/pcaps/Apple TV 4th gen 5GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Apple TV \0504th gen\051 5GHz.pcap"
rename to taxonomy/testdata/pcaps/Apple TV 4th gen 5GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Chromebook 14\" HP 2.4GHz.pcap" b/taxonomy/testdata/pcaps/Chromebook HP 14 2.4GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Chromebook 14\" HP 2.4GHz.pcap"
rename to taxonomy/testdata/pcaps/Chromebook HP 14 2.4GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Chromebook 14\" HP 5GHz.pcap" b/taxonomy/testdata/pcaps/Chromebook HP 14 5GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Chromebook 14\" HP 5GHz.pcap"
rename to taxonomy/testdata/pcaps/Chromebook HP 14 5GHz.pcap
Binary files differ
diff --git a/taxonomy/testdata/pcaps/Chromecast 2.4GHz.pcap b/taxonomy/testdata/pcaps/Chromecast v1 2.4GHz.pcap
similarity index 100%
rename from taxonomy/testdata/pcaps/Chromecast 2.4GHz.pcap
rename to taxonomy/testdata/pcaps/Chromecast v1 2.4GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Moto E \0502nd gen\051 2.4GHz.pcap" b/taxonomy/testdata/pcaps/Moto E 2nd gen 2.4GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Moto E \0502nd gen\051 2.4GHz.pcap"
rename to taxonomy/testdata/pcaps/Moto E 2nd gen 2.4GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Nexus 7 \0502012\051 2.4GHz.pcap" b/taxonomy/testdata/pcaps/Nexus 7 2012 edition 2.4GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Nexus 7 \0502012\051 2.4GHz.pcap"
rename to taxonomy/testdata/pcaps/Nexus 7 2012 edition 2.4GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Nexus 7 \0502013\051 2.4GHz Broadcast Probe.pcap" b/taxonomy/testdata/pcaps/Nexus 7 2013 edition 2.4GHz Broadcast Probe.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Nexus 7 \0502013\051 2.4GHz Broadcast Probe.pcap"
rename to taxonomy/testdata/pcaps/Nexus 7 2013 edition 2.4GHz Broadcast Probe.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Nexus 7 \0502013\051 2.4GHz Specific Probe.pcap" b/taxonomy/testdata/pcaps/Nexus 7 2013 edition 2.4GHz Specific Probe.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Nexus 7 \0502013\051 2.4GHz Specific Probe.pcap"
rename to taxonomy/testdata/pcaps/Nexus 7 2013 edition 2.4GHz Specific Probe.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Nexus 7 \0502013\051 2.4GHz.pcap" b/taxonomy/testdata/pcaps/Nexus 7 2013 edition 2.4GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Nexus 7 \0502013\051 2.4GHz.pcap"
rename to taxonomy/testdata/pcaps/Nexus 7 2013 edition 2.4GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Nexus 7 \0502013\051 5GHz Broadcast Probe.pcap" b/taxonomy/testdata/pcaps/Nexus 7 2013 edition 5GHz Broadcast Probe.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Nexus 7 \0502013\051 5GHz Broadcast Probe.pcap"
rename to taxonomy/testdata/pcaps/Nexus 7 2013 edition 5GHz Broadcast Probe.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Nexus 7 \0502013\051 5GHz Specific Probe.pcap" b/taxonomy/testdata/pcaps/Nexus 7 2013 edition 5GHz Specific Probe.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Nexus 7 \0502013\051 5GHz Specific Probe.pcap"
rename to taxonomy/testdata/pcaps/Nexus 7 2013 edition 5GHz Specific Probe.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/Nexus 7 \0502013\051 5GHz.pcap" b/taxonomy/testdata/pcaps/Nexus 7 2013 edition 5GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/Nexus 7 \0502013\051 5GHz.pcap"
rename to taxonomy/testdata/pcaps/Nexus 7 2013 edition 5GHz.pcap
Binary files differ
diff --git a/taxonomy/testdata/pcaps/Samsung Galaxy Note 2 2.4GHz.pcap b/taxonomy/testdata/pcaps/Samsung Galaxy Note II 2.4GHz.pcap
similarity index 100%
rename from taxonomy/testdata/pcaps/Samsung Galaxy Note 2 2.4GHz.pcap
rename to taxonomy/testdata/pcaps/Samsung Galaxy Note II 2.4GHz.pcap
Binary files differ
diff --git a/taxonomy/testdata/pcaps/Samsung Galaxy Note 2 5GHz.pcap b/taxonomy/testdata/pcaps/Samsung Galaxy Note II 5GHz.pcap
similarity index 100%
rename from taxonomy/testdata/pcaps/Samsung Galaxy Note 2 5GHz.pcap
rename to taxonomy/testdata/pcaps/Samsung Galaxy Note II 5GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/iPad \0501st gen\051 2.4GHz.pcap" b/taxonomy/testdata/pcaps/iPad 1st gen 2.4GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/iPad \0501st gen\051 2.4GHz.pcap"
rename to taxonomy/testdata/pcaps/iPad 1st gen 2.4GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/iPad \0502nd gen\051 2.4GHz.pcap" b/taxonomy/testdata/pcaps/iPad 2nd gen 2.4GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/iPad \0502nd gen\051 2.4GHz.pcap"
rename to taxonomy/testdata/pcaps/iPad 2nd gen 2.4GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/iPad Air \0502nd gen\051 2.4GHz.pcap" b/taxonomy/testdata/pcaps/iPad Air 2nd gen 2.4GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/iPad Air \0502nd gen\051 2.4GHz.pcap"
rename to taxonomy/testdata/pcaps/iPad Air 2nd gen 2.4GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/iPad Air \0502nd gen\051 5GHz.pcap" b/taxonomy/testdata/pcaps/iPad Air 2nd gen 5GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/iPad Air \0502nd gen\051 5GHz.pcap"
rename to taxonomy/testdata/pcaps/iPad Air 2nd gen 5GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/iPad Mini \0501st gen\051 2.4GHz.pcap" b/taxonomy/testdata/pcaps/iPad Mini 1st gen 2.4GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/iPad Mini \0501st gen\051 2.4GHz.pcap"
rename to taxonomy/testdata/pcaps/iPad Mini 1st gen 2.4GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/iPad Mini \0501st gen\051 5GHz.pcap" b/taxonomy/testdata/pcaps/iPad Mini 1st gen 5GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/iPad Mini \0501st gen\051 5GHz.pcap"
rename to taxonomy/testdata/pcaps/iPad Mini 1st gen 5GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/iPad Mini \0502nd gen\051 2.4GHz.pcap" b/taxonomy/testdata/pcaps/iPad Mini 2nd gen 2.4GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/iPad Mini \0502nd gen\051 2.4GHz.pcap"
rename to taxonomy/testdata/pcaps/iPad Mini 2nd gen 2.4GHz.pcap
Binary files differ
diff --git "a/taxonomy/testdata/pcaps/iPad Mini \0502nd gen\051 5GHz.pcap" b/taxonomy/testdata/pcaps/iPad Mini 2nd gen 5GHz.pcap
similarity index 100%
rename from "taxonomy/testdata/pcaps/iPad Mini \0502nd gen\051 5GHz.pcap"
rename to taxonomy/testdata/pcaps/iPad Mini 2nd gen 5GHz.pcap
Binary files differ
diff --git a/taxonomy/tests/wifi_test.py b/taxonomy/tests/wifi_test.py
index 13eb234..8d68b96 100755
--- a/taxonomy/tests/wifi_test.py
+++ b/taxonomy/tests/wifi_test.py
@@ -36,16 +36,20 @@
     self.assertEqual(3, len(taxonomy))
     self.assertEqual('802.11n n:1,w:20', taxonomy[2])
 
-    signature = ('wifi4|probe:0,1,45,221(00904c,51),htcap:09ef,htagg:1b,'
-        'htmcs:0000ffff|assoc:0,1,33,36,48,45,221(00904c,51),221(0050f2,2),'
-        'htcap:09ef,htagg:1b,htmcs:0000ffff,txpow:0005')
-    taxonomy = wifi.identify_wifi_device(signature, '3c:15:c2:00:00:01')
-    expected = 'BCM4331;MacBook Pro 17" late 2011 (A1297);802.11n n:2,w:40'
+    signature = ('wifi4|probe:0,1,45,191,221(0050f2,4),221(506f9a,9),'
+                 '221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,'
+                 'vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,'
+                 'extcap:000008800140,wps:Nexus_6|assoc:0,1,33,36,48,45,'
+                 '127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,'
+                 'htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,'
+                 'vhttxmcs:0000fffa,txpow:e009,extcap:000008800140')
+    taxonomy = wifi.identify_wifi_device(signature, '00:00:01:00:00:02')
+    expected = 'Nexus 6;;802.11ac n:2,w:80'
     self.assertEqual(';'.join(taxonomy), expected)
     self.assertEqual(3, len(taxonomy))
-    self.assertEqual('BCM4331', taxonomy[0])
-    self.assertEqual('MacBook Pro 17" late 2011 (A1297)', taxonomy[1])
-    self.assertEqual('802.11n n:2,w:40', taxonomy[2])
+    self.assertEqual('Nexus 6', taxonomy[0])
+    self.assertEqual('', taxonomy[1])
+    self.assertEqual('802.11ac n:2,w:80', taxonomy[2])
 
   def testNameLookup(self):
     signature = ('wifi4|probe:0,1,45,3,221(001018,2),221(00904c,51),htcap:0100,'
@@ -59,7 +63,8 @@
     self.assertEqual(3, len(taxonomy))
     self.assertEqual('Unknown', taxonomy[1])
     taxonomy = wifi.identify_wifi_device(signature, 'c8:69:cd:5e:b5:43')
-    self.assertEqual('Apple TV (3rd gen)', taxonomy[1])
+    self.assertEqual('Apple TV', taxonomy[0])
+    self.assertEqual('3rd gen', taxonomy[1])
 
   def testChecksumWhenNoIdentification(self):
     taxonomy = wifi.identify_wifi_device('wifi|probe:1,2,3,4,htcap:0|assoc:1',
@@ -76,23 +81,25 @@
     taxonomy = wifi.identify_wifi_device(signature, '00:00:01:00:00:01')
     self.assertIn('Unknown', taxonomy[1])
     taxonomy = wifi.identify_wifi_device(signature, 'b4:52:7e:00:00:01')
-    self.assertIn('Sony Xperia Z Ultra', taxonomy[1])
+    self.assertIn('Sony Xperia', taxonomy[0])
     taxonomy = wifi.identify_wifi_device(signature, 'f8:f1:b6:00:00:01')
-    self.assertIn('Moto E (2nd gen)', taxonomy[1])
+    self.assertIn('Moto E', taxonomy[0])
+    self.assertIn('2nd gen', taxonomy[1])
 
     # Test one of the OUIs with multiple vendors listed.
     signature = ('wifi4|probe:0,1,3,45,50,htcap:0120,htagg:03,htmcs:00000000|'
                  'assoc:0,1,48,50,127,221(0050f2,2),45,htcap:012c,'
                  'htagg:03,htmcs:000000ff,extcap:0000000000000140|oui:google')
     taxonomy = wifi.identify_wifi_device(signature, '6c:ad:f8:00:00:01')
-    self.assertEqual('Chromecast', taxonomy[1])
+    self.assertEqual('Chromecast', taxonomy[0])
+    self.assertEqual('v1', taxonomy[1])
 
   def testOS(self):
     signature = 'wifi4|probe:0,1,50|assoc:0,1,50,48,221(0050f2,2)'
     taxonomy = wifi.identify_wifi_device(signature, '00:00:01:00:00:01')
     self.assertIn('Unknown', taxonomy[1])
     taxonomy = wifi.identify_wifi_device(signature, '28:ef:01:00:00:01')
-    self.assertIn('Kindle', taxonomy[1])
+    self.assertIn('Kindle', taxonomy[0])
 
   def testCommonSignature(self):
     signature = ('wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),'
diff --git a/taxonomy/wifi.py b/taxonomy/wifi.py
index 87c7d86..58b6ead 100644
--- a/taxonomy/wifi.py
+++ b/taxonomy/wifi.py
@@ -22,1022 +22,1032 @@
 import ethernet
 
 
+# Associated with each signature is a tuple:
+# Field #1 = Genus = a human-recognizeable name for the device. If the device
+#   has branding silkscreened on it (ex: "Samsung Galaxy S4" on the back), that
+#   should probably be the Genus though this isn't rigidly adhered to.
+#   We want someone reading the Genus to recognize it without thinking to
+#   themselves "Wow, that is comically detailed."
+# Field #2 = Species = the most specific designation we know of, such as the
+#   version or model number or vintage. Not all entries will have a Species,
+#   if the Genus is very specific we may not have any additional information
+#   to put in the species.
+#   We want someone reading the Species to think to themselves "Wow, that is
+#   comically detailed."
+# Field #3 = Frequency = band of this signature, '2.4GHz' or '5GHz'.
+
 database = {
+    'wifi4|probe:0,1,50,127,107,221(0050f2,4),221(506f9a,9),221(506f9a,16),extcap:00000080,wps:5042T|assoc:0,1,50,45,48,127,221(0050f2,2),htcap:1172,htagg:03,htmcs:000000ff,extcap:01':
+        ('Alcatel OneTouch', 'Pop Astro', '2.4GHz'),
+
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:110c,htagg:19,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:110c,htagg:19,htmcs:000000ff|os:dashbutton':
-        ('BCM43362', 'Amazon Dash Button', '2.4GHz'),
+        ('Amazon Dash Button', '', '2.4GHz'),
 
     'wifi4|probe:0,1,3,45,221(0050f2,8),191,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31805120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe|assoc:0,1,48,45,221(0050f2,2),191,127,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31805120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:00000a0200000040|oui:amazon':
-        ('', 'Amazon Fire Phone', '5GHz'),
+        ('Amazon Fire Phone', '', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),191,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe|assoc:0,1,48,45,221(0050f2,2),191,127,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31805120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:00000a0200000040|oui:amazon':
-        ('', 'Amazon Fire Phone', '5GHz'),
+        ('Amazon Fire Phone', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a0200000000|oui:amazon':
-        ('', 'Amazon Fire Phone', '2.4GHz'),
-
-    'wifi4|probe:0,1,45,htcap:11ee,htagg:02,htmcs:0000ffff|assoc:0,1,33,36,48,221(0050f2,2),45,127,htcap:11ee,htagg:02,htmcs:0000ffff,txpow:0e00,extcap:01|oui:amazon':
-        ('', 'Amazon Kindle', '5GHz'),
-    'wifi4|probe:0,1,50|assoc:0,1,50,48,221(0050f2,2)|oui:amazon':
-        ('', 'Amazon Kindle', '2.4GHz'),
-    'wifi4|probe:0,1,50,45,htcap:01ac,htagg:02,htmcs:0000ffff|assoc:0,1,50,48,221(0050f2,2),45,127,htcap:01ac,htagg:02,htmcs:0000ffff,extcap:01|oui:amazon':
-        ('', 'Amazon Kindle', '2.4GHz'),
-
-    'wifi4|probe:0,1,50,3,45,221(0050f2,8),htcap:1130,htagg:18,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),htcap:1130,htagg:18,htmcs:000000ff|oui:amazon':
-        ('TI_WL1271', 'Amazon Kindle Fire 7" (2011 edition)', '2.4GHz'),
-    'wifi4|probe:0,1,50,221(0050f2,4),221(506f9a,9),wps:KFFOWI|assoc:0,1,50,45,48,127,221(0050f2,2),htcap:1172,htagg:03,htmcs:000000ff,extcap:01':
-        ('', 'Amazon Kindle Fire 7" (2015 edition)', '2.4GHz'),
+        ('Amazon Fire Phone', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,45,127,221(0050f2,4),221(506f9a,9),htcap:01ed,htagg:1f,htmcs:0000ffff,extcap:00,wps:AFTS|assoc:0,1,50,45,127,221(000c43,6),221(0050f2,2),48,127,htcap:008c,htagg:1f,htmcs:0000ffff,extcap:00000a02':
-        ('', 'Amazon Fire TV', '2.4GHz'),
+        ('Amazon Fire TV', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(001018,2),221(00904c,51),htcap:007e,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,45,221(001018,2),221(0050f2,2),htcap:007e,htagg:1b,htmcs:0000ffff,txpow:e50d|oui:amazon':
-        ('', 'Amazon Fire TV Stick', '5GHz'),
+        ('Amazon Fire TV Stick', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,221(001018,2),221(00904c,51),htcap:003c,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,50,45,221(001018,2),221(0050f2,2),htcap:003c,htagg:1b,htmcs:0000ffff,txpow:170c|oui:amazon':
-        ('', 'Amazon Fire TV Stick', '2.4GHz'),
+        ('Amazon Fire TV Stick', '', '2.4GHz'),
+
+    'wifi4|probe:0,1,45,htcap:11ee,htagg:02,htmcs:0000ffff|assoc:0,1,33,36,48,221(0050f2,2),45,127,htcap:11ee,htagg:02,htmcs:0000ffff,txpow:0e00,extcap:01|oui:amazon':
+        ('Amazon Kindle', '', '5GHz'),
+    'wifi4|probe:0,1,50|assoc:0,1,50,48,221(0050f2,2)|oui:amazon':
+        ('Amazon Kindle', '', '2.4GHz'),
+    'wifi4|probe:0,1,50,45,htcap:01ac,htagg:02,htmcs:0000ffff|assoc:0,1,50,48,221(0050f2,2),45,127,htcap:01ac,htagg:02,htmcs:0000ffff,extcap:01|oui:amazon':
+        ('Amazon Kindle', '', '2.4GHz'),
+
+    'wifi4|probe:0,1,50,3,45,221(0050f2,8),htcap:1130,htagg:18,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),htcap:1130,htagg:18,htmcs:000000ff|oui:amazon':
+        ('Amazon Kindle', 'Fire 7" (2011 edition)', '2.4GHz'),
+    'wifi4|probe:0,1,50,221(0050f2,4),221(506f9a,9),wps:KFFOWI|assoc:0,1,50,45,48,127,221(0050f2,2),htcap:1172,htagg:03,htmcs:000000ff,extcap:01':
+        ('Amazon Kindle', 'Fire 7" (2015 edition)', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(001018,2),221(00904c,51),htcap:081e,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:081e,htagg:1b,htmcs:0000ffff,txpow:0008|os:appletv1':
-        ('BCM94321', 'Apple TV (1st gen)', '5GHz'),
+        ('Apple TV', '1st gen', '5GHz'),
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:181c,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:181c,htagg:1b,htmcs:0000ffff,txpow:1308|os:appletv1':
-        ('BCM94321', 'Apple TV (1st gen)', '2.4GHz'),
+        ('Apple TV', '1st gen', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:581c,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:581c,htagg:1b,htmcs:0000ffff,txpow:1308|os:appletv1':
-        ('BCM94321', 'Apple TV (1st gen)', '2.4GHz'),
+        ('Apple TV', '1st gen', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:181c,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:581c,htagg:1b,htmcs:0000ffff,txpow:1308|os:appletv1':
-        ('BCM94321', 'Apple TV (1st gen)', '2.4GHz'),
+        ('Apple TV', '1st gen', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:581c,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:181c,htagg:1b,htmcs:0000ffff,txpow:1308|os:appletv1':
-        ('BCM94321', 'Apple TV (1st gen)', '2.4GHz'),
+        ('Apple TV', '1st gen', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(001018,2),221(00904c,51),htcap:080c,htagg:1b,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:080c,htagg:1b,htmcs:000000ff,txpow:1208|os:ios':
-        ('BCM4329', 'Apple TV (2nd gen)', '5GHz'),
+        ('Apple TV', '2nd gen', '5GHz'),
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:180c,htagg:1b,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:180c,htagg:1b,htmcs:000000ff,txpow:1308|os:ios':
-        ('BCM4329', 'Apple TV (2nd gen)', '2.4GHz'),
+        ('Apple TV', '2nd gen', '2.4GHz'),
 
     'wifi4|probe:0,1,45,3,221(001018,2),221(00904c,51),htcap:0100,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0100,htagg:19,htmcs:000000ff,txpow:180f|name:appletv':
-        ('BCM4330', 'Apple TV (3rd gen)', '2.4GHz'),
+        ('Apple TV', '3rd gen', '2.4GHz'),
     'wifi4|probe:0,1,45,3,221(001018,2),221(00904c,51),htcap:0100,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0100,htagg:19,htmcs:000000ff,txpow:180f|name:appletv':
-        ('BCM4330', 'Apple TV (3rd gen)', '2.4GHz'),
+        ('Apple TV', '3rd gen', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0062,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1907|os:ios':
-        ('BCM4334', 'Apple TV (3rd gen rev A)', '5GHz'),
+        ('Apple TV', '3rd gen rev A', '5GHz'),
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0062,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1907|os:ios':
-        ('BCM4334', 'Apple TV (3rd gen rev A)', '5GHz'),
+        ('Apple TV', '3rd gen rev A', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0020,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff,txpow:1a07|os:ios':
-        ('BCM4334', 'Apple TV (3rd gen rev A)', '2.4GHz'),
+        ('Apple TV', '3rd gen rev A', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0020,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,50,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff,txpow:1a07|os:ios':
-        ('BCM4334', 'Apple TV (3rd gen rev A)', '2.4GHz'),
+        ('Apple TV', '3rd gen rev A', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0400088400000040|assoc:0,1,33,36,48,70,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|name:appletv':
-        ('', 'Apple TV (4th gen)', '5GHz'),
+        ('Apple TV', '4th gen', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0400088400000040|assoc:0,1,50,33,36,48,70,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1502,extcap:0000000000000040|name:appletv':
-        ('', 'Apple TV (4th gen)', '2.4GHz'),
+        ('Apple TV', '4th gen', '2.4GHz'),
 
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0020,htagg:1a,htmcs:000000ff,extcap:00000804|assoc:0,1,48,50,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff|os:ios':
-        ('', 'Apple Watch', '2.4GHz'),
+        ('Apple Watch', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,221(0050f2,4)|assoc:0,1,50,45,221(0050f2,2),48,htcap:000c,htagg:1b,htmcs:000000ff|os:wemo':
-        ('', 'Belkin WeMo Switch', '2.4GHz'),
+        ('Belkin WeMo', 'Switch', '2.4GHz'),
 
     'wifi4|probe:0,1,50,221(0050f2,4),221(506f9a,9),wps:BLU_DASH_M|assoc:0,1,50,45,48,127,221(0050f2,2),htcap:1172,htagg:03,htmcs:000000ff,extcap:01':
-        ('', 'BLU Dash M', '2.4GHz'),
+        ('BLU Dash', 'M', '2.4GHz'),
 
     'wifi4|probe:0,1,50,127,107,221(0050f2,4),221(506f9a,9),221(506f9a,16),extcap:00000080,wps:BLU_STUDIO_5_0_C_HD|assoc:0,1,50,45,48,127,221(0050f2,2),htcap:1172,htagg:03,htmcs:000000ff,extcap:0100008000c6':
-        ('', 'BLU Studio 5.0.C HD', '2.4GHz'),
+        ('BLU Studio', '5.0.C HD', '2.4GHz'),
 
     'wifi4|probe:0,1,50,221(0050f2,4),221(506f9a,9),wps:BLU_STUDIO_C_SUPER_CAMERA|assoc:0,1,50,45,48,127,221(0050f2,2),htcap:1172,htagg:03,htmcs:000000ff,extcap:01':
-        ('', 'BLU Studio C Super Camera', '2.4GHz'),
+        ('BLU Studio', 'C Super Camera', '2.4GHz'),
 
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:112c,htagg:19,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:112c,htagg:19,htmcs:000000ff|os:brotherprinter':
-        ('', 'Brother Printer', '2.4GHz'),
+        ('Brother Printer', '', '2.4GHz'),
 
     'wifi4|probe:0,1,3,45,50,htcap:007e,htagg:00,htmcs:000000ff|assoc:0,1,45,48,50,221(0050f2,2),htcap:000c,htagg:1b,htmcs:000000ff|os:canonprinter':
-        ('', 'Canon Printer', '2.4GHz'),
+        ('Canon Printer', '', '2.4GHz'),
     'wifi4|probe:0,1,3,45,50,htcap:007e,htagg:00,htmcs:000000ff|assoc:0,1,48,50,221(0050f2,2),45,htcap:000c,htagg:1b,htmcs:000000ff|os:canonprinter':
-        ('', 'Canon Printer', '2.4GHz'),
+        ('Canon Printer', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,191,htcap:11e2,htagg:17,htmcs:0000ffff,vhtcap:038071a0,vhtrxmcs:0000fffa,vhttxmcs:0000fffa|assoc:0,1,48,45,127,191,221(0050f2,2),htcap:11e6,htagg:17,htmcs:0000ffff,vhtcap:038001a0,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000000000000040|os:chromeos':
-        ('Intel_7260', 'Chromebook Pixel 2', '5GHz'),
+        ('Chromebook', 'Pixel 2', '5GHz'),
     'wifi4|probe:0,1,45,191,htcap:11e2,htagg:17,htmcs:0000ffff,vhtcap:038071a0,vhtrxmcs:0000fffa,vhttxmcs:0000fffa|assoc:0,1,48,45,127,191,221(0050f2,2),htcap:11ee,htagg:17,htmcs:0000ffff,vhtcap:038001a0,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000000000000040|os:chromeos':
-        ('Intel_7260', 'Chromebook Pixel 2', '5GHz'),
+        ('Chromebook', 'Pixel 2', '5GHz'),
     'wifi4|probe:0,1,45,191,htcap:11e2,htagg:17,htmcs:0000ffff,vhtcap:038071a0,vhtrxmcs:0000fffa,vhttxmcs:0000fffa|assoc:0,1,33,36,48,45,127,191,221(0050f2,2),htcap:11e6,htagg:17,htmcs:0000ffff,vhtcap:038001a0,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:1600,extcap:0000000000000040|os:chromeos':
-        ('Intel_7260', 'Chromebook Pixel 2', '5GHz'),
+        ('Chromebook', 'Pixel 2', '5GHz'),
     'wifi4|probe:0,1,50,45,htcap:11e2,htagg:17,htmcs:0000ffff|assoc:0,1,50,48,45,127,221(0050f2,2),htcap:11a4,htagg:17,htmcs:0000ffff,extcap:0000000000000040|os:chromeos':
-        ('Intel_7260', 'Chromebook Pixel 2', '2.4GHz'),
+        ('Chromebook', 'Pixel 2', '2.4GHz'),
     'wifi4|probe:0,1,50,45,htcap:11e2,htagg:17,htmcs:0000ffff|assoc:0,1,50,48,45,127,221(0050f2,2),htcap:11ac,htagg:17,htmcs:0000ffff,extcap:0000000000000040|os:chromeos':
-        ('Intel_7260', 'Chromebook Pixel 2', '2.4GHz'),
+        ('Chromebook', 'Pixel 2', '2.4GHz'),
 
     'wifi4|probe:0,1,45,htcap:11ef,htagg:1b,htmcs:0000ffff|assoc:0,1,48,45,221(0050f2,2),htcap:11ef,htagg:1b,htmcs:0000ffff|os:chromeos':
-        ('AR5822', 'Chromebook 14" HP', '5GHz'),
+        ('Chromebook', 'HP 14', '5GHz'),
     'wifi4|probe:0,1,50,3,45,htcap:11ef,htagg:1b,htmcs:0000ffff|assoc:0,1,50,48,45,221(0050f2,2),htcap:11ef,htagg:1b,htmcs:0000ffff|os:chromeos':
-        ('AR5822', 'Chromebook 14" HP', '2.4GHz'),
+        ('Chromebook', 'HP 14', '2.4GHz'),
 
     'wifi4|probe:0,1,45,50,htcap:016e,htagg:03,htmcs:0000ffff|assoc:0,1,48,127,221(0050f2,2),45,htcap:016e,htagg:03,htmcs:0000ffff,extcap:00':
-        ('AR9382', 'Chromebook 11" Samsung', '5GHz'),
+        ('Chromebook', 'Samsung 11.6"', '5GHz'),
     'wifi4|probe:0,1,3,45,50,htcap:016e,htagg:03,htmcs:0000ffff|assoc:0,1,48,50,127,221(0050f2,2),45,htcap:016e,htagg:03,htmcs:0000ffff,extcap:00':
-        ('AR9382', 'Chromebook 11" Samsung', '2.4GHz'),
+        ('Chromebook', 'Samsung 11.6"', '2.4GHz'),
 
     'wifi4|probe:0,1,3,45,50,htcap:0120,htagg:03,htmcs:00000000|assoc:0,1,48,50,127,221(0050f2,2),45,htcap:012c,htagg:03,htmcs:000000ff,extcap:0000000000000140|oui:google':
-        ('Marvell_88W8797', 'Chromecast', '2.4GHz'),
+        ('Chromecast', 'v1', '2.4GHz'),
     'wifi4|probe:0,1,45,50,127,191,htcap:0062,htagg:03,htmcs:00000000,vhtcap:33c07030,vhtrxmcs:0124fffc,vhttxmcs:0124fffc,extcap:0000000000000040|assoc:0,1,48,127,221(0050f2,2),45,191,htcap:006e,htagg:03,htmcs:000000ff,vhtcap:33c07030,vhtrxmcs:0186fffe,vhttxmcs:0186fffe,extcap:0400000000000140|oui:google':
-        ('Marvell_88W8887', 'Chromecast v2', '5GHz'),
+        ('Chromecast', 'v2', '5GHz'),
     'wifi4|probe:0,1,45,50,127,191,htcap:0062,htagg:03,htmcs:00000000,vhtcap:33c07030,vhtrxmcs:0124fffc,vhttxmcs:0124fffc,extcap:0000000000000040|assoc:0,1,33,36,48,127,221(0050f2,2),45,191,htcap:006e,htagg:03,htmcs:000000ff,vhtcap:33c07030,vhtrxmcs:0186fffe,vhttxmcs:0186fffe,extcap:0400000000000140|oui:google':
-        ('Marvell_88W8887', 'Chromecast v2', '5GHz'),
+        ('Chromecast', 'v2', '5GHz'),
     'wifi4|probe:0,1,45,50,127,191,htcap:0062,htagg:03,htmcs:00000000,vhtcap:33c07030,vhtrxmcs:0124fffc,vhttxmcs:0124fffc,extcap:0000000000000040|assoc:0,1,33,36,48,127,221(0050f2,2),45,191,htcap:006e,htagg:03,htmcs:000000ff,vhtcap:33c07030,vhtrxmcs:0186fffe,vhttxmcs:0186fffe,txpow:1308,extcap:0400000000000140|oui:google':
-        ('Marvell_88W8887', 'Chromecast v2', '5GHz'),
+        ('Chromecast', 'v2', '5GHz'),
     'wifi4|probe:0,1,3,45,50,127,191,htcap:0062,htagg:03,htmcs:00000000,vhtcap:33c07030,vhtrxmcs:0124fffc,vhttxmcs:0124fffc,extcap:0000000000000040|assoc:0,1,48,50,127,221(0050f2,2),45,htcap:002c,htagg:03,htmcs:000000ff,extcap:0000000000000140|oui:google':
-        ('Marvell_88W8887', 'Chromecast v2', '2.4GHz'),
+        ('Chromecast', 'v2', '2.4GHz'),
 
     'wifi4|probe:0,1,45,htcap:106e,htagg:01,htmcs:000000ff|assoc:0,1,45,33,36,48,221(0050f2,2),htcap:106e,htagg:01,htmcs:000000ff,txpow:0e00|oui:dropcam':
-        ('', 'Dropcam', '5GHz'),
+        ('Dropcam', '', '5GHz'),
     'wifi4|probe:0,1,50,45,htcap:002c,htagg:01,htmcs:000000ff|assoc:0,1,50,45,48,221(0050f2,2),htcap:002c,htagg:01,htmcs:000000ff|oui:dropcam':
-        ('', 'Dropcam', '2.4GHz'),
+        ('Dropcam', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,45,htcap:002c,htagg:01,htmcs:000000ff|assoc:0,1,50,45,48,221(0050f2,2),htcap:002c,htagg:01,htmcs:000000ff|oui:ecobee':
-        ('', 'ecobee thermostat', '2.4GHz'),
+        ('ecobee thermostat', '', '2.4GHz'),
 
     'wifi4|probe:0,1,3,45,50,htcap:0162,htagg:00,htmcs:000000ff|assoc:0,1,45,48,127,50,221(0050f2,2),htcap:016e,htagg:1b,htmcs:000000ff,extcap:00|os:epsonprinter':
-        ('', 'Epson Printer', '2.4GHz'),
+        ('Epson Printer', '', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:182c,htagg:1b,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:182c,htagg:1b,htmcs:000000ff|os:epsonprinter':
-        ('', 'Epson Printer', '2.4GHz'),
+        ('Epson Printer', '', '2.4GHz'),
     'wifi4|probe:0,1,50,221(001018,2)|assoc:0,1,48,50,221(001018,2)|os:epsonprinter':
-        ('', 'Epson Printer', '2.4GHz'),
+        ('Epson Printer', '', '2.4GHz'),
+    'wifi4|probe:0,1,50,3,45,221(001018,2),221(00904c,51),htcap:0020,htagg:1a,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff|os:epsonprinter':
+        ('Epson Printer', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:100c,htagg:19,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:100c,htagg:19,htmcs:000000ff|os:hpprinter':
-        ('', 'HP Printer', '2.4GHz'),
+        ('HP Printer', '', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:102c,htagg:1b,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:102c,htagg:1b,htmcs:000000ff|os:hpprinter':
-        ('', 'HP Printer', '2.4GHz'),
+        ('HP Printer', '', '2.4GHz'),
     'wifi4|probe:0,1,3,45,50,htcap:0160,htagg:03,htmcs:000000ff|assoc:0,1,48,50,127,221(0050f2,2),45,htcap:016c,htagg:03,htmcs:000000ff,extcap:00|os:hpprinter':
-        ('', 'HP Printer', '2.4GHz'),
+        ('HP Printer', '', '2.4GHz'),
     'wifi4|probe:0,1,3,45,50,htcap:0160,htagg:03,htmcs:000000ff|assoc:0,1,45,48,127,50,221(0050f2,2),htcap:016c,htagg:03,htmcs:000000ff,extcap:00000000|os:hpprinter':
-        ('', 'HP Printer', '2.4GHz'),
+        ('HP Printer', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(001018,2),221(00904c,51),htcap:0020,htagg:1a,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(0050f2,2),221(506f9a,9),htcap:0020,htagg:1a,htmcs:000000ff|os:hpprinter':
-        ('', 'HP Printer', '2.4GHz'),
+        ('HP Printer', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(001018,2),221(00904c,51),htcap:0020,htagg:1a,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff|os:hpprinter':
-        ('', 'HP Printer', '2.4GHz'),
+        ('HP Printer', '', '2.4GHz'),
     'wifi4|probe:0,1,3,45,50,htcap:0060,htagg:03,htmcs:000000ff|assoc:0,1,48,50,127,221(0050f2,2),45,htcap:006c,htagg:03,htmcs:000000ff,extcap:00|os:hpprinter':
-        ('', 'HP Printer', '2.4GHz'),
+        ('HP Printer', '', '2.4GHz'),
     'wifi4|probe:0,1,3,45,50,127,htcap:010c,htagg:1b,htmcs:0000ffff,extcap:00|assoc:0,1,45,48,127,50,221(0050f2,2),htcap:016c,htagg:1b,htmcs:000000ff,extcap:00|os:hpprinter':
-        ('', 'HP Printer', '2.4GHz'),
+        ('HP Printer', '', '2.4GHz'),
     'wifi4|probe:0,1,50,221(001018,2)|assoc:0,1,48,50,221(001018,2)|os:hpprinter':
-        ('', 'HP Printer', '2.4GHz'),
+        ('HP Printer', '', '2.4GHz'),
     'wifi4|probe:0,1,3,45,50,127,htcap:010c,htagg:1b,htmcs:0000ffff,extcap:00|assoc:0,1,48,50,221(0050f2,2)|os:hpprinter':
-        ('', 'HP Printer', '2.4GHz'),
+        ('HP Printer', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,191,221(001018,2),221(00904c,51),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:03800032,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000000000000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:03800032,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e008,extcap:0000000000000040|oui:htc':
-        ('BCM4335', 'HTC One', '5GHz'),
+        ('HTC One', '', '5GHz'),
     'wifi4|probe:0,1,3,45,127,191,221(001018,2),221(00904c,51),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:03800032,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000000000000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:03800032,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e008,extcap:0000000000000040|oui:htc':
-        ('BCM4335', 'HTC One', '5GHz'),
+        ('HTC One', '', '5GHz'),
     'wifi4|probe:0,1,50,45,127,221(001018,2),221(00904c,51),htcap:102d,htagg:17,htmcs:000000ff,extcap:0000000000000040|assoc:0,1,33,36,48,50,45,221(001018,2),221(0050f2,2),htcap:102d,htagg:17,htmcs:000000ff,txpow:1408|oui:htc':
-        ('BCM4335', 'HTC One', '2.4GHz'),
+        ('HTC One', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(001018,2),221(00904c,51),htcap:102d,htagg:17,htmcs:000000ff,extcap:0000000000000040|assoc:0,1,33,36,48,50,45,221(001018,2),221(0050f2,2),htcap:102d,htagg:17,htmcs:000000ff,txpow:1408|oui:htc':
-        ('BCM4335', 'HTC One', '2.4GHz'),
+        ('HTC One', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,wps:HTC_VLE_U|assoc:0,1,50,48,45,221(0050f2,2),htcap:012c,htagg:03,htmcs:000000ff':
-        ('', 'HTC One S', '2.4GHz'),
+        ('HTC One', 'S', '2.4GHz'),
     'wifi4|probe:0,1,3,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,wps:HTC_VLE_U|assoc:0,1,50,48,45,221(0050f2,2),htcap:012c,htagg:03,htmcs:000000ff':
-        ('', 'HTC One S', '2.4GHz'),
+        ('HTC One', 'S', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(0050f2,8),191,127,107,221(0050f2,4),221(506f9a,9),221(506f9a,16),htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:00000a820040,wps:HTC_One_M8|assoc:0,1,48,45,221(0050f2,2),191,127,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:00000a8201400040':
-        ('WCN3680', 'HTC One M8', '5GHz'),
+        ('HTC One', 'M8', '5GHz'),
     'wifi4|probe:0,1,3,45,221(0050f2,8),191,127,107,221(0050f2,4),221(506f9a,9),221(506f9a,16),htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:00000a820040,wps:HTC_One_M8|assoc:0,1,48,45,221(0050f2,2),191,127,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:00000a8201400040':
-        ('WCN3680', 'HTC One M8', '5GHz'),
+        ('HTC One', 'M8', '5GHz'),
     'wifi4|probe:0,1,3,45,221(0050f2,8),191,127,107,221(0050f2,4),221(506f9a,10),221(506f9a,9),221(506f9a,16),htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:000000800040,wps:HTC_One_M8|assoc:0,1,33,36,48,70,45,221(0050f2,2),191,127,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:1e0d,extcap:0000008001400040':
-        ('WCN3680', 'HTC One M8', '5GHz'),
+        ('HTC One', 'M8', '5GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),127,107,221(0050f2,4),221(506f9a,9),221(506f9a,16),htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a820040,wps:HTC_One_M8|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a8201400000':
-        ('WCN3680', 'HTC One M8', '2.4GHz'),
+        ('HTC One', 'M8', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a8201400000|oui:htc':
-        ('WCN3680', 'HTC One M8', '2.4GHz'),
+        ('HTC One', 'M8', '2.4GHz'),
+
+    'wifi4|probe:0,1,50,3,45,221(0050f2,8),127,107,221(0050f2,4),221(506f9a,10),221(506f9a,9),221(506f9a,16),htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a820040,wps:831C|assoc:0,1,50,33,48,70,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,txpow:170d,extcap:00000a8201400000':
+        ('HTC One', 'M8, Sprint edition', '2.4GHz'),
+    'wifi4|probe:0,1,50,3,45,221(0050f2,8),127,107,221(0050f2,4),221(506f9a,9),221(506f9a,16),htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a820040,wps:HTC6525LVW|assoc:0,1,50,33,48,70,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,txpow:160d,extcap:00000a8201400000':
+        ('HTC One', 'M8, Verizon edition', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,191,221(506f9a,16),221(0050f2,8),221(001018,2),htcap:0063,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000088001400040|assoc:0,1,33,36,48,45,127,107,191,221(001018,2),221(0050f2,2),htcap:0063,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e009,extcap:0000088001400040|oui:htc':
-        ('BCM4356', 'HTC One M9', '5GHz'),
+        ('HTC One', 'M9', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(506f9a,16),221(0050f2,8),221(001018,2),htcap:1063,htagg:17,htmcs:000000ff,extcap:0000088001400040|assoc:0,1,50,33,36,45,127,107,221(001018,2),221(0050f2,2),htcap:1063,htagg:17,htmcs:000000ff,txpow:1309,extcap:000008800140|oui:htc':
-        ('BCM4356', 'HTC One M9', '2.4GHz'),
+        ('HTC One', 'M9', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(506f9a,16),221(0050f2,8),221(001018,2),htcap:1063,htagg:17,htmcs:000000ff,extcap:0000088001400040|assoc:0,1,50,33,36,45,127,107,221(001018,2),221(0050f2,2),htcap:1063,htagg:17,htmcs:000000ff,txpow:1309,extcap:000008800140|oui:htc':
-        ('BCM4356', 'HTC One M9', '2.4GHz'),
+        ('HTC One', 'M9', '2.4GHz'),
+
+    'wifi4|probe:0,1,50,3,45,127,221(0050f2,4),221(506f9a,9),221(506f9a,16),221(0050f2,8),221(001018,2),htcap:1063,htagg:17,htmcs:000000ff,extcap:000008800140,wps:0PJA2|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:1063,htagg:17,htmcs:000000ff,txpow:1309,extcap:000008800140':
+        ('HTC One', 'M9, Sprint edition', '2.4GHz'),
 
     'wifi4|probe:0,1,50,45,3,221(0050f2,4),221(001018,2),221(00904c,51),htcap:100c,htagg:19,htmcs:000000ff,wps:_|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:100c,htagg:19,htmcs:000000ff|oui:htc':
-        ('', 'HTC One V', '2.4GHz'),
+        ('HTC One', 'V', '2.4GHz'),
 
     'wifi4|probe:0,1,45,htcap:0130,htagg:18,htmcs:000000ff|assoc:0,1,48,45,221(0050f2,2),htcap:013c,htagg:18,htmcs:000000ff|oui:htc':
-        ('', 'HTC One X', '5GHz'),
+        ('HTC One', 'X', '5GHz'),
     'wifi4|probe:0,1,50,45,htcap:0130,htagg:18,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),htcap:013c,htagg:18,htmcs:000000ff|oui:htc':
-        ('', 'HTC One X', '2.4GHz'),
+        ('HTC One', 'X', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(001018,2),221(00904c,51),htcap:080c,htagg:1b,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:080c,htagg:1b,htmcs:000000ff,txpow:1008|os:ios':
-        ('BCM4329', 'iPad (1st/2nd gen)', '5GHz'),
+        ('iPad', '1st or 2nd gen', '5GHz'),
     'wifi4|probe:0,1,45,221(001018,2),221(00904c,51),htcap:0800,htagg:1b,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0800,htagg:1b,htmcs:000000ff,txpow:1008|os:ios':
-        ('BCM4329', 'iPad (1st/2nd gen)', '5GHz'),
+        ('iPad', '1st or 2nd gen', '5GHz'),
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:180c,htagg:1b,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:180c,htagg:1b,htmcs:000000ff,txpow:1008|os:ios':
-        ('BCM4329', 'iPad (1st gen)', '2.4GHz'),
+        ('iPad', '1st gen', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:1800,htagg:1b,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:1800,htagg:1b,htmcs:000000ff,txpow:1008|os:ios':
-        ('BCM4329', 'iPad (1st gen)', '2.4GHz'),
+        ('iPad', '1st gen', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:180c,htagg:1b,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:180c,htagg:1b,htmcs:000000ff,txpow:1108|os:ios':
-        ('BCM4329', 'iPad (2nd gen)', '2.4GHz'),
+        ('iPad', '2nd gen', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:1800,htagg:1b,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:1800,htagg:1b,htmcs:000000ff,txpow:1108|os:ios':
-        ('BCM4329', 'iPad (2nd gen)', '2.4GHz'),
+        ('iPad', '2nd gen', '2.4GHz'),
 
     'wifi4|probe:0,1,45,3,221(001018,2),221(00904c,51),htcap:0100,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0100,htagg:19,htmcs:000000ff,txpow:180f|os:ios':
-        ('BCM4330', 'iPad (3rd gen)', '5GHz'),
+        ('iPad', '3rd gen', '5GHz'),
     'wifi4|probe:0,1,45,3,221(001018,2),221(00904c,51),htcap:0100,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0100,htagg:19,htmcs:000000ff,txpow:180f|os:ios':
-        ('BCM4330', 'iPad (3rd gen)', '5GHz'),
+        ('iPad', '3rd gen', '5GHz'),
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:0100,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,50,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0100,htagg:19,htmcs:000000ff,txpow:150c|os:ios':
-        ('BCM4330', 'iPad (3rd gen)', '2.4GHz'),
+        ('iPad', '3rd gen', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01fe,htagg:1b,htmcs:0000ffff,extcap:00000804|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:01fe,htagg:1b,htmcs:0000ffff,txpow:e708|os:ios':
-        ('BCM4334', 'iPad (4th gen or Air)', '5GHz'),
+        ('iPad', '4th gen or Air 1st gen', '5GHz'),
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01fe,htagg:1b,htmcs:0000ffff,extcap:00000804|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:01fe,htagg:1b,htmcs:0000ffff,txpow:e708|os:ios':
-        ('BCM4334', 'iPad (4th gen or Air)', '5GHz'),
+        ('iPad', '4th gen or Air 1st gen', '5GHz'),
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01fe,htagg:1b,htmcs:0000ffff,extcap:00000004|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:01fe,htagg:1b,htmcs:0000ffff,txpow:e708|os:ios':
-        ('BCM4334', 'iPad (4th gen or Air)', '5GHz'),
+        ('iPad', '4th gen or Air 1st gen', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01bc,htagg:1b,htmcs:0000ffff,extcap:00000804|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:01bc,htagg:1b,htmcs:0000ffff,txpow:1805|os:ios':
-        ('BCM4334', 'iPad (4th gen or Air)', '2.4GHz'),
+        ('iPad', '4th gen or Air 1st gen', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01bc,htagg:1b,htmcs:0000ffff,extcap:00000804|assoc:0,1,33,36,48,50,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:01bc,htagg:1b,htmcs:0000ffff,txpow:1805|os:ios':
-        ('BCM4334', 'iPad (4th gen or Air)', '2.4GHz'),
+        ('iPad', '4th gen or Air 1st gen', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0400088400000040|assoc:0,1,33,36,48,70,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|name:ipad':
-        ('BCM4350', 'iPad Air (2nd gen)', '5GHz'),
+        ('iPad', 'Air 2nd gen', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffe,extcap:0400088400000040|assoc:0,1,33,36,48,70,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|name:ipad':
-        ('BCM4350', 'iPad Air (2nd gen)', '5GHz'),
+        ('iPad', 'Air 2nd gen', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffe,vhttxmcs:0000fffa,extcap:0400088400000040|assoc:0,1,33,36,48,70,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|name:ipad':
-        ('BCM4350', 'iPad Air (2nd gen)', '5GHz'),
+        ('iPad', 'Air 2nd gen', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0400088400000040|assoc:0,1,33,36,48,70,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|name:ipad':
-        ('BCM4350', 'iPad Air (2nd gen)', '5GHz'),
+        ('iPad', 'Air 2nd gen', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0400088400000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|name:ipad':
-        ('BCM4350', 'iPad Air (2nd gen)', '5GHz'),
+        ('iPad', 'Air 2nd gen', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffe,extcap:0400088400000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|name:ipad':
-        ('BCM4350', 'iPad Air (2nd gen)', '5GHz'),
+        ('iPad', 'Air 2nd gen', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f815832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0400088400000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|name:ipad':
-        ('BCM4350', 'iPad Air (2nd gen)', '5GHz'),
+        ('iPad', 'Air 2nd gen', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0400088400000040|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1502,extcap:0000000000000040|os:ios':
-        ('BCM4335', 'iPad Air (2nd gen)', '2.4GHz'),
+        ('iPad', 'Air 2nd gen', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0400088400000040|assoc:0,1,50,33,36,48,70,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1502,extcap:0000000000000040|os:ios':
-        ('BCM4335', 'iPad Air (2nd gen)', '2.4GHz'),
+        ('iPad', 'Air 2nd gen', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0062,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1807|os:ios':
-        ('BCM4334', 'iPad Mini (1st gen)', '5GHz'),
+        ('iPad Mini', '1st gen', '5GHz'),
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0062,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1807|os:ios':
-        ('BCM4334', 'iPad Mini (1st gen)', '5GHz'),
+        ('iPad Mini', '1st gen', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0020,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff,txpow:1605|os:ios':
-        ('BCM4334', 'iPad Mini (1st gen)', '2.4GHz'),
+        ('iPad Mini', '1st gen', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0020,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,50,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff,txpow:1605|os:ios':
-        ('BCM4334', 'iPad Mini (1st gen)', '2.4GHz'),
+        ('iPad Mini', '1st gen', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01fe,htagg:1b,htmcs:0000ffff,extcap:00000804|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:01fe,htagg:1b,htmcs:0000ffff,txpow:e606|os:ios':
-        ('BCM4324', 'iPad Mini (2nd gen)', '5GHz'),
+        ('iPad Mini', '2nd gen', '5GHz'),
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01fe,htagg:1b,htmcs:0000ffff,extcap:00000804|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:01fe,htagg:1b,htmcs:0000ffff,txpow:e606|os:ios':
-        ('BCM4324', 'iPad Mini (2nd gen)', '5GHz'),
+        ('iPad Mini', '2nd gen', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01bc,htagg:1b,htmcs:0000ffff,extcap:00000804|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:01bc,htagg:1b,htmcs:0000ffff,txpow:1603|os:ios':
-        ('BCM4324', 'iPad Mini (2nd gen)', '2.4GHz'),
+        ('iPad Mini', '2nd gen', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:01bc,htagg:1b,htmcs:0000ffff,extcap:00000804|assoc:0,1,33,36,48,50,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:01bc,htagg:1b,htmcs:0000ffff,txpow:1603|os:ios':
-        ('BCM4324', 'iPad Mini (2nd gen)', '2.4GHz'),
+        ('iPad Mini', '2nd gen', '2.4GHz'),
 
     'wifi4|probe:0,1,3,50|assoc:0,1,48,50|os:ios':
-        ('', 'iPhone 2', '2.4GHz'),
+        ('iPhone 2', '', '2.4GHz'),
 
     'wifi4|probe:0,1,3,50|assoc:0,1,48,50,221(0050f2,2)|os:ios':
-        ('', 'iPhone 3', '2.4GHz'),
+        ('iPhone 3', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,3,221(001018,2)|assoc:0,1,48,50,221(001018,2),221(0050f2,2)|os:ios':
-        ('', 'iPhone 3GS', '2.4GHz'),
+        ('iPhone 3GS', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:1800,htagg:1b,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:1800,htagg:1b,htmcs:000000ff|os:ios':
-        ('BCM4329', 'iPhone 4', '2.4GHz'),
+        ('iPhone 4', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:0100,htagg:19,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0100,htagg:19,htmcs:000000ff|os:ios':
-        ('BCM4330', 'iPhone 4s', '2.4GHz'),
+        ('iPhone 4s', '', '2.4GHz'),
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:0100,htagg:19,htmcs:000000ff|assoc:0,1,48,50,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0100,htagg:19,htmcs:000000ff|os:ios':
-        ('BCM4330', 'iPhone 4s', '2.4GHz'),
+        ('iPhone 4s', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0062,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1504|os:ios':
-        ('BCM4334', 'iPhone 5', '5GHz'),
+        ('iPhone 5', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0062,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1504|os:ios':
-        ('BCM4334', 'iPhone 5', '5GHz'),
+        ('iPhone 5', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0020,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff,txpow:1403|os:ios':
-        ('BCM4334', 'iPhone 5', '2.4GHz'),
+        ('iPhone 5', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0020,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,50,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff,txpow:1403|os:ios':
-        ('BCM4334', 'iPhone 5', '2.4GHz'),
+        ('iPhone 5', '', '2.4GHz'),
 
-    'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0062,htagg:1a,htmcs:000000ff,extcap:00000804|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1805|os:ios':
-        ('BCM4334', 'iPhone 5c', '5GHz'),
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0062,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1805|os:ios':
-        ('BCM4334', 'iPhone 5c', '5GHz'),
+        ('iPhone 5c', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0062,htagg:1a,htmcs:000000ff,extcap:00000804|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1805|os:ios':
-        ('BCM4334', 'iPhone 5c', '5GHz'),
+        ('iPhone 5c', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0062,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1805|os:ios':
-        ('BCM4334', 'iPhone 5c', '5GHz'),
+        ('iPhone 5c', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0020,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff,txpow:1704|os:ios':
-        ('BCM4334', 'iPhone 5c', '2.4GHz'),
+        ('iPhone 5c', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0020,htagg:1a,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff,txpow:1704|os:ios':
-        ('BCM4334', 'iPhone 5c', '2.4GHz'),
+        ('iPhone 5c', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0020,htagg:1a,htmcs:000000ff,extcap:00000804|assoc:0,1,33,36,48,50,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff,txpow:1704|os:ios':
-        ('BCM4334', 'iPhone 5c', '2.4GHz'),
+        ('iPhone 5c', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0062,htagg:1a,htmcs:000000ff,extcap:00000804|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1603|os:ios':
-        ('BCM4334', 'iPhone 5s', '5GHz'),
+        ('iPhone 5s', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0062,htagg:1a,htmcs:000000ff,extcap:00000804|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1603|os:ios':
-        ('BCM4334', 'iPhone 5s', '5GHz'),
+        ('iPhone 5s', '', '5GHz'),
+    'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0062,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1603|os:ios':
+        ('iPhone 5s', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0020,htagg:1a,htmcs:000000ff,extcap:00000804|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff,txpow:1805|os:ios':
-        ('BCM4334', 'iPhone 5s', '2.4GHz'),
+        ('iPhone 5s', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0020,htagg:1a,htmcs:000000ff,extcap:00000804|assoc:0,1,33,36,48,50,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff,txpow:1805|os:ios':
-        ('BCM4334', 'iPhone 5s', '2.4GHz'),
+        ('iPhone 5s', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:0063,htagg:17,htmcs:000000ff,vhtcap:0f805032,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0400088400000040|assoc:0,1,33,36,48,70,45,127,191,221(001018,2),221(0050f2,2),htcap:0063,htagg:17,htmcs:000000ff,vhtcap:0f805032,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e002,extcap:0400000000000040|os:ios':
-        ('BCM4339', 'iPhone 6/6+', '5GHz'),
+        ('iPhone 6/6+', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:0063,htagg:17,htmcs:000000ff,vhtcap:0f805032,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0400088400000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:0063,htagg:17,htmcs:000000ff,vhtcap:0f805032,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e002,extcap:0400000000000040|os:ios':
-        ('BCM4339', 'iPhone 6/6+', '5GHz'),
+        ('iPhone 6/6+', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(00904c,51),221(0050f2,8),221(001018,2),htcap:0063,htagg:17,htmcs:000000ff,vhtcap:0f805032,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0400088400000040|assoc:0,1,33,36,48,70,45,127,191,221(001018,2),221(0050f2,2),htcap:0063,htagg:17,htmcs:000000ff,vhtcap:0f805032,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e002,extcap:0400000000000040|os:ios':
-        ('BCM4339', 'iPhone 6/6+', '5GHz'),
+        ('iPhone 6/6+', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(00904c,51),221(0050f2,8),221(001018,2),htcap:0063,htagg:17,htmcs:000000ff,vhtcap:0f805032,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0400088400000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:0063,htagg:17,htmcs:000000ff,vhtcap:0f805032,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e002,extcap:0400000000000040|os:ios':
-        ('BCM4339', 'iPhone 6/6+', '5GHz'),
+        ('iPhone 6/6+', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(0050f2,8),221(001018,2),htcap:0021,htagg:17,htmcs:000000ff,extcap:0400088400000040|assoc:0,1,50,33,36,48,70,45,127,221(001018,2),221(0050f2,2),htcap:0021,htagg:17,htmcs:000000ff,txpow:1302,extcap:0000000000000040|os:ios':
-        ('BCM4339', 'iPhone 6', '2.4GHz'),
+        ('iPhone 6', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(0050f2,8),221(001018,2),htcap:0021,htagg:17,htmcs:000000ff,extcap:0400088400000040|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:0021,htagg:17,htmcs:000000ff,txpow:1302,extcap:0000000000000040|os:ios':
-        ('BCM4339', 'iPhone 6', '2.4GHz'),
+        ('iPhone 6', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(00904c,51),221(0050f2,8),221(001018,2),htcap:0021,htagg:17,htmcs:000000ff,extcap:0400088400000040|assoc:0,1,50,33,36,48,70,45,127,221(001018,2),221(0050f2,2),htcap:0021,htagg:17,htmcs:000000ff,txpow:1302,extcap:0000000000000040|os:ios':
-        ('BCM4339', 'iPhone 6', '2.4GHz'),
+        ('iPhone 6', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(0050f2,8),221(001018,2),htcap:0021,htagg:17,htmcs:000000ff,extcap:0400088400000040|assoc:0,1,50,33,36,48,70,45,127,221(001018,2),221(0050f2,2),htcap:0021,htagg:17,htmcs:000000ff,txpow:1402,extcap:0000000000000040|os:ios':
-        ('BCM4339', 'iPhone 6+', '2.4GHz'),
+        ('iPhone 6+', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(0050f2,8),221(001018,2),htcap:0021,htagg:17,htmcs:000000ff,extcap:0400088400000040|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:0021,htagg:17,htmcs:000000ff,txpow:1402,extcap:0000000000000040|os:ios':
-        ('BCM4339', 'iPhone 6+', '2.4GHz'),
+        ('iPhone 6+', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0400088400000040|assoc:0,1,33,36,48,70,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '5GHz'),
+        ('iPhone 6s/6s+', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffe,extcap:0400088400000040|assoc:0,1,33,36,48,70,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '5GHz'),
+        ('iPhone 6s/6s+', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffe,vhttxmcs:0000fffa,extcap:0400088400000040|assoc:0,1,33,36,48,70,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '5GHz'),
+        ('iPhone 6s/6s+', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0400088400000040|assoc:0,1,33,36,48,70,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '5GHz'),
+        ('iPhone 6s/6s+', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f815832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0400088400000040|assoc:0,1,33,36,48,70,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '5GHz'),
+        ('iPhone 6s/6s+', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f815832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0400088400000040|assoc:0,1,33,36,48,70,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f815832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e002,extcap:0400000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '5GHz'),
+        ('iPhone 6s/6s+', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0400088400000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '5GHz'),
+        ('iPhone 6s/6s+', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffe,extcap:0400088400000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '5GHz'),
+        ('iPhone 6s/6s+', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f815832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0400088400000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0400000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '5GHz'),
+        ('iPhone 6s/6s+', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0400088400000040|assoc:0,1,33,36,48,70,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f815832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e002,extcap:0400000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '5GHz'),
+        ('iPhone 6s/6s+', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0400088400000040|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1202,extcap:0000000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '2.4GHz'),
+        ('iPhone 6s/6s+', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:000000ff,extcap:0400088400000040|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1202,extcap:0000000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '2.4GHz'),
+        ('iPhone 6s/6s+', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0400088400000040|assoc:0,1,50,33,36,48,70,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1202,extcap:0000000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '2.4GHz'),
+        ('iPhone 6s/6s+', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:000000ff,extcap:0400088400000040|assoc:0,1,50,33,36,48,70,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1202,extcap:0000000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '2.4GHz'),
+        ('iPhone 6s/6s+', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:000000ff,extcap:0400088400000040|assoc:0,1,50,33,36,48,70,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:000000ff,txpow:1202,extcap:0000000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '2.4GHz'),
+        ('iPhone 6s/6s+', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(00904c,51),221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0400088400000040|assoc:0,1,50,33,36,48,70,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1202,extcap:0000000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '2.4GHz'),
+        ('iPhone 6s/6s+', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(00904c,51),221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:000000ff,extcap:0400088400000040|assoc:0,1,50,33,36,48,70,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1202,extcap:0000000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '2.4GHz'),
+        ('iPhone 6s/6s+', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0400088400000040|assoc:0,1,50,33,36,48,70,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:000000ff,txpow:1202,extcap:0000000000000040|os:ios':
-        ('BCM4350', 'iPhone 6s/6s+', '2.4GHz'),
+        ('iPhone 6s/6s+', '', '2.4GHz'),
 
     'wifi4|probe:0,1,3,50|assoc:0,1,48,50|os:ipodtouch1':
-        ('Marvell_W8686B22', 'iPod Touch 1st/2nd gen', '2.4GHz'),
+        ('iPod Touch', '1st or 2nd gen', '2.4GHz'),
 
     'wifi4|probe:0,1,50,221(001018,2)|assoc:0,1,48,50,221(001018,2),221(0050f2,2)|name:ipod':
-        ('BCM4329', 'iPod Touch 3rd gen', '2.4GHz'),
+        ('iPod Touch', '3rd gen', '2.4GHz'),
 
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:180c,htagg:1b,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:180c,htagg:1b,htmcs:000000ff|os:ios':
-        ('BCM4329', 'iPod Touch 4th gen', '2.4GHz'),
+        ('iPod Touch', '4th gen', '2.4GHz'),
 
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0020,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff,txpow:1504|os:ios':
-        ('BCM4334', 'iPod Touch 5th gen', '5GHz'),
+        ('iPod Touch', '5th gen', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0020,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,50,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff,txpow:1504|os:ios':
-        ('BCM4334', 'iPod Touch 5th gen', '5GHz'),
+        ('iPod Touch', '5th gen', '5GHz'),
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0062,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,45,70,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1706|os:ios':
-        ('BCM4334', 'iPod Touch 5th gen', '2.4GHz'),
+        ('iPod Touch', '5th gen', '2.4GHz'),
     'wifi4|probe:0,1,45,127,107,221(001018,2),221(00904c,51),221(0050f2,8),htcap:0062,htagg:1a,htmcs:000000ff,extcap:00000004|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1706|os:ios':
-        ('BCM4334', 'iPod Touch 5th gen', '2.4GHz'),
+        ('iPod Touch', '5th gen', '2.4GHz'),
 
     'wifi4|probe:0,1,3,45,127,191,221(001018,2),221(00904c,51),221(0050f2,8),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000080000000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e001,extcap:0000000000000040|oui:lg':
-        ('BCM4335', 'LG G2', '5GHz'),
+        ('LG G2', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(001018,2),221(00904c,51),221(0050f2,8),htcap:102d,htagg:17,htmcs:000000ff,extcap:0000080000000040|assoc:0,1,33,36,48,50,45,127,221(001018,2),221(0050f2,2),htcap:102d,htagg:17,htmcs:000000ff,txpow:11ff|oui:lg':
-        ('BCM4335', 'LG G2', '2.4GHz'),
+        ('LG G2', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(001018,2),221(00904c,51),221(0050f2,8),htcap:102d,htagg:17,htmcs:000000ff,extcap:0000080000000040|assoc:0,1,33,36,48,50,45,221(001018,2),221(0050f2,2),htcap:102d,htagg:17,htmcs:000000ff,txpow:11ff|oui:lg':
-        ('BCM4335', 'LG G2', '2.4GHz'),
+        ('LG G2', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(0050f2,8),191,127,107,221(506f9a,16),htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:000000800040|assoc:0,1,33,36,48,45,221(0050f2,2),191,127,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31805120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:170d,extcap:00000a8201400040|oui:lg':
-        ('BCM4339', 'LG G3', '5GHz'),
+        ('LG G3', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),127,107,221(506f9a,16),htcap:012c,htagg:03,htmcs:000000ff,extcap:000000800040|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a8201400000|oui:lg':
-        ('BCM4339', 'LG G3', '2.4GHz'),
+        ('LG G3', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),127,107,221(506f9a,16),htcap:012c,htagg:03,htmcs:000000ff,extcap:000000800040|assoc:0,1,50,33,48,70,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,txpow:170d,extcap:00000a8201400000|oui:lg':
-        ('BCM4339', 'LG G3', '2.4GHz'),
+        ('LG G3', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),127,107,221(506f9a,16),htcap:016e,htagg:03,htmcs:000000ff,extcap:000000800040|assoc:0,1,50,33,48,70,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,txpow:170d,extcap:00000a8201400000|oui:lg':
-        ('BCM4339', 'LG G3', '2.4GHz'),
+        ('LG G3', '', '2.4GHz'),
 
     'wifi4|probe:0,1,3,45,127,107,191,221(506f9a,16),221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000088001400040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(00904c,4),221(0050f2,2),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:1d01,extcap:0000008001400040|oui:lg':
-        ('BCM4339', 'LG G4', '5GHz'),
+        ('LG G4', '', '5GHz'),
     'wifi4|probe:0,1,50,45,127,107,221(506f9a,16),221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:112d,htagg:17,htmcs:000000ff,extcap:0000088001400040|assoc:0,1,33,36,48,50,45,127,221(001018,2),221(0050f2,2),htcap:112d,htagg:17,htmcs:000000ff,txpow:1001,extcap:000000800140|oui:lg':
-        ('BCM4339', 'LG G4', '2.4GHz'),
+        ('LG G4', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,wps:LGL16C|assoc:0,1,50,48,45,221(0050f2,2),htcap:012c,htagg:03,htmcs:000000ff':
-        ('', 'LG Lucky', '2.4GHz'),
+        ('LG Lucky', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,wps:LGMS323|assoc:0,1,50,48,45,221(0050f2,2),221(004096,3),htcap:012c,htagg:03,htmcs:000000ff':
-        ('QCA_WCN3360', 'LG Optimus L70', '2.4GHz'),
+        ('LG Optimus', 'L70', '2.4GHz'),
 
     'wifi4|probe:0,1,3,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:016e,htagg:03,htmcs:000000ff,wps:LG_V400|assoc:0,1,33,36,48,70,45,221(0050f2,2),127,htcap:016e,htagg:03,htmcs:000000ff,txpow:170d,extcap:00000a0200000000':
-        ('', 'LG Pad v400', '5GHz'),
+        ('LG Pad', 'v400', '5GHz'),
 
     'wifi4|probe:0,1,50,3,45,127,221(001018,2),221(00904c,51),htcap:11ac,htagg:16,htmcs:0000ffff,extcap:0000000000000040|assoc:0,1,33,36,48,50,45,127,221(001018,2),221(0050f2,2),htcap:11ac,htagg:16,htmcs:0000ffff,txpow:140a,extcap:0000000000000040|os:lgtv':
-        ('', 'LG Smart TV', '2.4GHz'),
+        ('LG Smart TV', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,wps:LGLS660|assoc:0,1,50,48,45,221(0050f2,2),htcap:012c,htagg:03,htmcs:000000ff':
-        ('', 'LG Tribute', '2.4GHz'),
+        ('LG Tribute', '', '2.4GHz'),
 
-    'wifi4|probe:0,1,45,221(001018,2),221(00904c,51),htcap:087e,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:087e,htagg:1b,htmcs:0000ffff,txpow:0f07|os:macos':
-        ('BCM43224', 'MacBook Air late 2010 (A1369)', '5GHz'),
-    'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:187c,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:187c,htagg:1b,htmcs:0000ffff,txpow:1207|os:macos':
-        ('BCM43224', 'MacBook Air late 2010 (A1369)', '2.4GHz'),
-
-    'wifi4|probe:0,1,45,221(00904c,51),htcap:086e,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,45,221(00904c,51),221(0050f2,2),htcap:086e,htagg:1b,htmcs:0000ffff,txpow:0f07|os:macos':
-        ('BCM4322', 'MacBook Air late 2011', '5GHz'),
-
-    'wifi4|probe:0,1,45,221(00904c,51),htcap:09ef,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,45,221(00904c,51),221(0050f2,2),htcap:09ef,htagg:1b,htmcs:0000ffff,txpow:0005|os:macos':
-        ('BCM4331', 'MacBook Pro 17" late 2011 (A1297)', '5GHz'),
-    'wifi4|probe:0,1,3,45,221(00904c,51),htcap:09ef,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,45,221(00904c,51),221(0050f2,2),htcap:09ef,htagg:1b,htmcs:0000ffff,txpow:0005|os:macos':
-        ('BCM4331', 'MacBook Pro 17" late 2011 (A1297)', '5GHz'),
-    'wifi4|probe:0,1,50,3,45,221(00904c,51),htcap:19ad,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,48,50,45,221(00904c,51),221(0050f2,2),htcap:19ad,htagg:1b,htmcs:0000ffff,txpow:1305|os:macos':
-        ('BCM4331', 'MacBook Pro 17" late 2011 (A1297)', '2.4GHz'),
-
-    'wifi4|probe:0,1,45,127,htcap:09ef,htagg:17,htmcs:0000ffff,extcap:0400000000000040|assoc:0,1,33,36,48,45,127,221(0050f2,2),htcap:09ef,htagg:17,htmcs:0000ffff,txpow:e007,extcap:0400000000000040|os:macos':
-        ('BCM4331', 'MacBook Pro 15" late 2013 (A1398)', '5GHz'),
-    'wifi4|probe:0,1,50,3,45,127,htcap:49ad,htagg:17,htmcs:0000ffff,extcap:0400000000000040|assoc:0,1,50,33,36,48,45,127,221(0050f2,2),htcap:49ad,htagg:17,htmcs:0000ffff,txpow:1307,extcap:0000000000000040|os:macos':
-        ('BCM4331', 'MacBook Pro 15" late 2013 (A1398)', '2.4GHz'),
-
-    'wifi4|probe:0,1,45,127,191,htcap:09ef,htagg:17,htmcs:0000ffff,vhtcap:0f8159b2,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0400000000000040|assoc:0,1,33,36,48,45,127,191,221(0050f2,2),htcap:09ef,htagg:17,htmcs:0000ffff,vhtcap:0f8159b2,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e007,extcap:0400000000000040|os:macos':
-        ('BCM4360', 'MacBook Air late 2014 (A1466)', '5GHz'),
-    'wifi4|probe:0,1,50,3,45,127,htcap:49ad,htagg:17,htmcs:0000ffff,extcap:0400000000000040|assoc:0,1,50,33,36,48,45,127,221(0050f2,2),htcap:49ad,htagg:17,htmcs:0000ffff,txpow:1407,extcap:0000000000000040|os:macos':
-        ('BCM4360', 'MacBook Air late 2014 (A1466)', '2.4GHz'),
-
-    'wifi4|probe:0,1,45,127,191,221(00904c,51),htcap:09ef,htagg:17,htmcs:0000ffff,vhtcap:0f8259b2,vhtrxmcs:0000ffea,vhttxmcs:0000ffea,extcap:0000000000000040|assoc:0,1,33,36,48,45,127,191,221(00904c,51),221(0050f2,2),htcap:09ef,htagg:17,htmcs:0000ffff,vhtcap:0f8259b2,vhtrxmcs:0000ffea,vhttxmcs:0000ffea,txpow:e808,extcap:0000000000000040|os:macos':
-        ('BCM4360', 'MacBook Pro early 2014 (A1502)', '5GHz'),
-    'wifi4|probe:0,1,50,45,127,221(00904c,51),htcap:59ad,htagg:17,htmcs:0000ffff,extcap:0000000000000040|assoc:0,1,33,36,48,50,45,127,221(00904c,51),221(0050f2,2),htcap:59ad,htagg:17,htmcs:0000ffff,txpow:1906,extcap:0000000000000040|os:macos':
-        ('BCM4360', 'MacBook Pro early 2014 (A1502)', '2.4GHz'),
+    'wifi4|probe:0,1,50|assoc:0,1,50,48,221(0050f2,2)|oui:lifx':
+        ('LIFX LED light bulb', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,50,htcap:0102,htagg:03,htmcs:0000ffff|assoc:0,1,48,221(0050f2,2),45,htcap:010e,htagg:03,htmcs:0000ffff|oui:microsoft':
-        ('Marvell_88W8797', 'Microsoft Surface RT', '5GHz'),
+        ('Microsoft Surface', 'RT', '5GHz'),
     'wifi4|probe:0,1,45,50,htcap:0102,htagg:03,htmcs:0000ffff|assoc:0,1,33,36,48,221(0050f2,2),45,htcap:010e,htagg:03,htmcs:0000ffff|oui:microsoft':
-        ('Marvell_88W8797', 'Microsoft Surface RT', '5GHz'),
+        ('Microsoft Surface', 'RT', '5GHz'),
     'wifi4|probe:0,1,3,45,50,htcap:0102,htagg:03,htmcs:0000ffff|assoc:0,1,48,50,221(0050f2,2),45,htcap:012c,htagg:03,htmcs:0000ffff|oui:microsoft':
-        ('Marvell_88W8797', 'Microsoft Surface RT', '2.4GHz'),
+        ('Microsoft Surface', 'RT', '2.4GHz'),
 
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a0200000000|oui:motorola':
-        ('QCA_WCN3620', 'Moto E (2nd gen)', '2.4GHz'),
+        ('Moto E', '2nd gen', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,33,48,70,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,txpow:170d,extcap:00000a0200000000|oui:motorola':
-        ('QCA_WCN3620', 'Moto E (2nd gen)', '2.4GHz'),
+        ('Moto E', '2nd gen', '2.4GHz'),
 
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02|oui:motorola':
-        ('QCA_WCN3620', 'Moto G or Moto X', '2.4GHz'),
+        ('Moto G or Moto X', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(0050f2,8),191,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe|assoc:0,1,48,45,221(0050f2,2),191,127,127,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:00000a02|oui:motorola':
-        ('QCA_WCN3680', 'Moto X', '5GHz'),
+        ('Moto X', '', '5GHz'),
     'wifi4|probe:0,1,3,45,221(0050f2,8),191,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31805120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe|assoc:0,1,48,45,221(0050f2,2),191,127,127,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31805120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:00000a02|oui:motorola':
-        ('QCA_WCN3680', 'Moto X', '5GHz'),
+        ('Moto X', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),191,htcap:012c,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffe,vhttxmcs:0000fffe|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02|oui:motorola':
-        ('QCA_WCN3680', 'Moto X', '2.4GHz'),
+        ('Moto X', '', '2.4GHz'),
 
     'wifi4|probe:0,1,127,45,htcap:01ef,htagg:03,htmcs:0000ffff,extcap:00000a0201|assoc:0,1,48,45,221(0050f2,2),191,127,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:338001b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:00000a020100004040|oui:motorola':
-        ('', 'Moto X Style', '5GHz'),
+        ('Moto X', 'Style', '5GHz'),
     'wifi4|probe:0,1,3,45,221(0050f2,8),191,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:338001b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa|assoc:0,1,48,45,221(0050f2,2),191,127,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:338001b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:00000a020100004040|oui:motorola':
-        ('', 'Moto X Style', '5GHz'),
+        ('Moto X', 'Style', '5GHz'),
     'wifi4|probe:0,1,50,127,45,htcap:01ef,htagg:03,htmcs:0000ffff,extcap:00000a0201|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:01ad,htagg:03,htmcs:0000ffff,extcap:00000a020100000040|oui:motorola':
-        ('', 'Moto X Style', '2.4GHz'),
+        ('Moto X', 'Style', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),127,htcap:01ad,htagg:03,htmcs:0000ffff,extcap:00000a0201|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:01ad,htagg:03,htmcs:0000ffff,extcap:00000a020100000040|oui:motorola':
-        ('', 'Moto X Style', '2.4GHz'),
+        ('Moto X', 'Style', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(001018,2),221(00904c,51),htcap:082c,htagg:1b,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:082c,htagg:1b,htmcs:000000ff,txpow:0a08|oui:motorola':
-        ('BCM4329', 'Motorola Xoom', '5GHz'),
+        ('Motorola Xoom', '', '5GHz'),
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:182c,htagg:1b,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:182c,htagg:1b,htmcs:000000ff,txpow:0e08|oui:motorola':
-        ('BCM4329', 'Motorola Xoom', '2.4GHz'),
+        ('Motorola Xoom', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,45,htcap:0130,htagg:18,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),htcap:013c,htagg:18,htmcs:000000ff|oui:nest':
-        ('TI_WL1270', 'Nest Thermostat v1/v2', '2.4GHz'),
+        ('Nest Thermostat', 'v1 or v2', '2.4GHz'),
     'wifi4|probe:0,1,45,221(001018,2),221(00904c,51),htcap:0062,htagg:1a,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:0f09|oui:nest':
-        ('', 'Nest Thermostat v3', '5GHz'),
+        ('Nest Thermostat', 'v3', '5GHz'),
     'wifi4|probe:0,1,50,3,45,221(001018,2),221(00904c,51),htcap:0020,htagg:1a,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff,txpow:150b|oui:nest':
-        ('', 'Nest Thermostat v3', '2.4GHz'),
+        ('Nest Thermostat', 'v3', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,wps:Nexus_4|assoc:0,1,48,45,221(0050f2,2),htcap:012c,htagg:03,htmcs:000000ff':
-        ('QCA_WCN3360', 'Nexus 4', '5GHz'),
+        ('Nexus 4', '', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),191,221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,vhtcap:31811120,vhtrxmcs:01b2fffc,vhttxmcs:01b2fffc,wps:Nexus_4|assoc:0,1,48,45,221(0050f2,2),htcap:012c,htagg:03,htmcs:000000ff':
-        ('QCA_WCN3360', 'Nexus 4', '5GHz'),
+        ('Nexus 4', '', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),191,221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,vhtcap:31811120,vhtrxmcs:01b2fffc,vhttxmcs:01b2fffc,wps:Nexus_4|assoc:0,1,33,36,48,45,221(0050f2,2),htcap:012c,htagg:03,htmcs:000000ff,txpow:130d':
-        ('QCA_WCN3360', 'Nexus 4', '5GHz'),
+        ('Nexus 4', '', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,wps:Nexus_4|assoc:0,1,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02':
-        ('QCA_WCN3360', 'Nexus 4', '5GHz'),
+        ('Nexus 4', '', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),191,221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,vhtcap:31811120,vhtrxmcs:01b2fffc,vhttxmcs:01b2fffc,wps:Nexus_4|assoc:0,1,50,48,45,221(0050f2,2),htcap:012c,htagg:03,htmcs:000000ff':
-        ('QCA_WCN3360', 'Nexus 4', '5GHz'),
+        ('Nexus 4', '', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,wps:Nexus_4|assoc:0,1,33,36,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,txpow:170d,extcap:00000a02':
-        ('QCA_WCN3360', 'Nexus 4', '5GHz'),
+        ('Nexus 4', '', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,33,36,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,txpow:170d,extcap:00000a02|oui:lg':
-        ('QCA_WCN3360', 'Nexus 4', '5GHz'),
+        ('Nexus 4', '', '5GHz'),
     'wifi4|probe:0,1,50,45,221(0050f2,8),191,221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,vhtcap:31811120,vhtrxmcs:01b2fffc,vhttxmcs:01b2fffc,wps:Nexus_4|assoc:0,1,50,48,45,221(0050f2,2),htcap:012c,htagg:03,htmcs:000000ff':
-        ('QCA_WCN3360', 'Nexus 4', '2.4GHz'),
+        ('Nexus 4', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,wps:Nexus_4|assoc:0,1,50,48,45,221(0050f2,2),htcap:012c,htagg:03,htmcs:000000ff':
-        ('QCA_WCN3360', 'Nexus 4', '2.4GHz'),
+        ('Nexus 4', '', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02|oui:lg':
-        ('QCA_WCN3360', 'Nexus 4', '2.4GHz'),
+        ('Nexus 4', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02|oui:lg':
-        ('QCA_WCN3360', 'Nexus 4', '2.4GHz'),
+        ('Nexus 4', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,wps:Nexus_4|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02':
-        ('QCA_WCN3360', 'Nexus 4', '2.4GHz'),
+        ('Nexus 4', '', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,wps:Nexus_4|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02|oui:lg':
-        ('QCA_WCN3360', 'Nexus 4', '2.4GHz'),
+        ('Nexus 4', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,191,221(001018,2),221(00904c,51),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000000000000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e003,extcap:0000000000000040|oui:lg':
-        ('BCM4339', 'Nexus 5', '5GHz'),
+        ('Nexus 5', '', '5GHz'),
     'wifi4|probe:0,1,3,45,127,191,221(001018,2),221(00904c,51),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000000000000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e003,extcap:0000000000000040|oui:lg':
-        ('BCM4339', 'Nexus 5', '5GHz'),
+        ('Nexus 5', '', '5GHz'),
     'wifi4|probe:0,1,45,127,191,221(001018,2),221(00904c,51),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000000000000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e003,extcap:0000000000000040|oui:lg':
-        ('BCM4339', 'Nexus 5', '5GHz'),
+        ('Nexus 5', '', '5GHz'),
+    'wifi4|probe:0,1,45,127,191,221(001018,2),221(00904c,51),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000000000000040|assoc:0,1,33,36,45,127,191,221(001018,2),221(0050f2,2),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e003,extcap:0000000000000040|oui:lg':
+        ('Nexus 5', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(506f9a,16),221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000088001400040|assoc:0,1,33,36,48,45,127,70,191,221(001018,2),221(00904c,4),221(0050f2,2),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e003,extcap:0000008001400040|oui:lg':
-        ('BCM4339', 'Nexus 5', '5GHz'),
+        ('Nexus 5', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(001018,2),221(00904c,51),htcap:112d,htagg:17,htmcs:000000ff,extcap:0000000000000040|assoc:0,1,33,36,48,50,45,221(001018,2),221(0050f2,2),htcap:112d,htagg:17,htmcs:000000ff,txpow:1303|oui:lg':
-        ('BCM4339', 'Nexus 5', '2.4GHz'),
+        ('Nexus 5', '', '2.4GHz'),
     'wifi4|probe:0,1,50,45,127,221(001018,2),221(00904c,51),htcap:112d,htagg:17,htmcs:000000ff,extcap:0000000000000040|assoc:0,1,33,36,48,50,45,221(001018,2),221(0050f2,2),htcap:112d,htagg:17,htmcs:000000ff,txpow:1303|oui:lg':
-        ('BCM4339', 'Nexus 5', '2.4GHz'),
+        ('Nexus 5', '', '2.4GHz'),
 
     'wifi4|probe:0,1,127,45,191,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:338061b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:00000a0201000040|assoc:0,1,48,45,221(0050f2,2),191,127,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:339071b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:0000000000000040|oui:lg':
-        ('QCA6174', 'Nexus 5X', '5GHz'),
+        ('Nexus 5X', '', '5GHz'),
     'wifi4|probe:0,1,127,extcap:00000a020100004080|assoc:0,1,48,45,221(0050f2,2),191,127,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:339071b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:000000000000004080|oui:lg':
-        ('QCA6174', 'Nexus 5X', '5GHz'),
+        ('Nexus 5X', '', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),191,127,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:339071b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:000000000000004080|assoc:0,1,48,45,221(0050f2,2),191,127,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:339071b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:000000000000004080|oui:lg':
-        ('QCA6174', 'Nexus 5X', '5GHz'),
+        ('Nexus 5X', '', '5GHz'),
     'wifi4|probe:0,1,127,45,191,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:338061b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:00000a020100004080|assoc:0,1,48,45,221(0050f2,2),191,127,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:339071b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:000000000000004080|oui:lg':
-        ('QCA6174', 'Nexus 5X', '5GHz'),
+        ('Nexus 5X', '', '5GHz'),
     'wifi4|probe:0,1,127,45,191,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:338001b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:00000a020100004080|assoc:0,1,48,45,221(0050f2,2),191,127,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:339071b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:000000000000004080|oui:lg':
-        ('QCA6174', 'Nexus 5X', '5GHz'),
+        ('Nexus 5X', '', '5GHz'),
     'wifi4|probe:0,1,127,45,191,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:338061b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:00000a020100004080|assoc:0,1,33,36,48,70,45,221(0050f2,2),191,127,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:339071b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,txpow:1e08,extcap:000000000000004080|oui:lg':
-        ('QCA6174', 'Nexus 5X', '5GHz'),
+        ('Nexus 5X', '', '5GHz'),
     'wifi4|probe:0,1,127,extcap:00000a020100004080|assoc:0,1,33,36,48,70,45,221(0050f2,2),191,127,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:339071b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,txpow:1e08,extcap:000000000000004080|oui:lg':
-        ('QCA6174', 'Nexus 5X', '5GHz'),
+        ('Nexus 5X', '', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),191,127,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:339071b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:000000000000004080|assoc:0,1,33,36,48,70,45,221(0050f2,2),191,127,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:339071b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,txpow:1e08,extcap:000000000000004080|oui:lg':
-        ('QCA6174', 'Nexus 5X', '5GHz'),
+        ('Nexus 5X', '', '5GHz'),
     'wifi4|probe:0,1,50,127,45,191,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:338061b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:00000a0201000040|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:01ad,htagg:03,htmcs:0000ffff,extcap:0000000000000000|oui:lg':
-        ('QCA6174', 'Nexus 5X', '2.4GHz'),
+        ('Nexus 5X', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),127,htcap:01ad,htagg:03,htmcs:0000ffff,extcap:000000000000000080|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:01ad,htagg:03,htmcs:0000ffff,extcap:000000000000000080|oui:lg':
-        ('QCA6174', 'Nexus 5X', '2.4GHz'),
+        ('Nexus 5X', '', '2.4GHz'),
     'wifi4|probe:0,1,50,127,45,191,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:338061b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:00000a020100004080|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:01ad,htagg:03,htmcs:0000ffff,extcap:000000000000000080|oui:lg':
-        ('QCA6174', 'Nexus 5X', '2.4GHz'),
+        ('Nexus 5X', '', '2.4GHz'),
     'wifi4|probe:0,1,50,127,45,191,htcap:01ef,htagg:03,htmcs:0000ffff,vhtcap:338061b2,vhtrxmcs:030cfffa,vhttxmcs:030cfffa,extcap:00000a020100004080|assoc:0,1,50,33,48,70,45,221(0050f2,2),127,htcap:01ad,htagg:03,htmcs:0000ffff,txpow:1e08,extcap:000000000000000080|oui:lg':
-        ('QCA6174', 'Nexus 5X', '2.4GHz'),
+        ('Nexus 5X', '', '2.4GHz'),
     'wifi4|probe:0,1,50,127,extcap:00000a020100004080|assoc:0,1,50,33,48,70,45,221(0050f2,2),127,htcap:01ad,htagg:03,htmcs:0000ffff,txpow:1e08,extcap:000000000000000080|oui:lg':
-        ('QCA6174', 'Nexus 5X', '2.4GHz'),
+        ('Nexus 5X', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),127,htcap:01ad,htagg:03,htmcs:0000ffff,extcap:000000000000000080|assoc:0,1,50,33,48,70,45,221(0050f2,2),127,htcap:01ad,htagg:03,htmcs:0000ffff,txpow:1e08,extcap:000000000000000080|oui:lg':
-        ('QCA6174', 'Nexus 5X', '2.4GHz'),
+        ('Nexus 5X', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,191,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:000008800140,wps:Nexus_6|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e009,extcap:000008800140':
-        ('BCM4356', 'Nexus 6', '5GHz'),
+        ('Nexus 6', '', '5GHz'),
     'wifi4|probe:0,1,45,127,191,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:000008800140,wps:Nexus_6|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e009,extcap:000008800140':
-        ('BCM4356', 'Nexus 6', '5GHz'),
+        ('Nexus 6', '', '5GHz'),
     'wifi4|probe:0,1,45,191,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,wps:Nexus_6|assoc:0,1,33,36,48,45,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e009':
-        ('BCM4356', 'Nexus 6', '5GHz'),
+        ('Nexus 6', '', '5GHz'),
     'wifi4|probe:0,1,45,127,191,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000088001400040,wps:Nexus_6|assoc:0,1,33,36,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e009,extcap:0000088001400040':
-        ('BCM4356', 'Nexus 6', '5GHz'),
+        ('Nexus 6', '', '5GHz'),
     'wifi4|probe:0,1,45,127,191,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:000008800140,wps:Nexus_6|assoc:0,1,33,36,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e009,extcap:000008800140':
-        ('BCM4356', 'Nexus 6', '5GHz'),
+        ('Nexus 6', '', '5GHz'),
     'wifi4|probe:0,1,45,127,191,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000088001400040,wps:Nexus_6|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e009,extcap:0000088001400040':
-        ('BCM4356', 'Nexus 6', '5GHz'),
+        ('Nexus 6', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0000088001400040,wps:Nexus_6|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1209,extcap:000008800140':
-        ('BCM4356', 'Nexus 6', '2.4GHz'),
+        ('Nexus 6', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:000008800140,wps:Nexus_6|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1209,extcap:000008800140':
-        ('BCM4356', 'Nexus 6', '2.4GHz'),
+        ('Nexus 6', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:000008800140,wps:Nexus_6|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1209,extcap:000008800140':
-        ('BCM4356', 'Nexus 6', '2.4GHz'),
+        ('Nexus 6', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,wps:Nexus_6|assoc:0,1,50,33,36,48,45,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1209':
-        ('BCM4356', 'Nexus 6', '2.4GHz'),
+        ('Nexus 6', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,191,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,wps:Nexus_6P|assoc:0,1,33,36,48,45,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002':
-        ('BCM4358', 'Nexus 6P', '5GHz'),
+        ('Nexus 6P', '', '5GHz'),
     'wifi4|probe:0,1,45,127,191,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000088001400040,wps:Nexus_6P|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0000088001400040':
-        ('BCM4358', 'Nexus 6P', '5GHz'),
+        ('Nexus 6P', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0000088001400040,wps:Nexus_6P|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1402,extcap:0000088001400040':
-        ('BCM4358', 'Nexus 6P', '2.4GHz'),
+        ('Nexus 6P', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:110c,htagg:19,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:110c,htagg:19,htmcs:000000ff|oui:asus':
-        ('BCM4330', 'Nexus 7 (2012)', '2.4GHz'),
+        ('Nexus 7', '2012 edition', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:016e,htagg:03,htmcs:000000ff,wps:Nexus_7|assoc:0,1,33,36,48,45,221(0050f2,2),127,htcap:016e,htagg:03,htmcs:000000ff,extcap:00000a02':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '5GHz'),
+        ('Nexus 7', '2013 edition', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:016e,htagg:03,htmcs:000000ff,wps:Nexus_7|assoc:0,1,33,36,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '5GHz'),
+        ('Nexus 7', '2013 edition', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),htcap:016e,htagg:03,htmcs:000000ff|assoc:0,1,33,36,48,45,221(0050f2,2),127,htcap:016e,htagg:03,htmcs:000000ff,extcap:00000a02|oui:asus':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '5GHz'),
+        ('Nexus 7', '2013 edition', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),127,221(0050f2,4),221(506f9a,9),htcap:016e,htagg:03,htmcs:000000ff,extcap:00000a02,wps:Nexus_7|assoc:0,1,33,36,48,45,221(0050f2,2),127,htcap:016e,htagg:03,htmcs:000000ff,extcap:00000a02':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '5GHz'),
+        ('Nexus 7', '2013 edition', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),221(0050f2,4),221(506f9a,10),221(506f9a,9),htcap:016e,htagg:03,htmcs:000000ff,wps:Nexus_7|assoc:0,1,33,36,48,45,221(0050f2,2),127,htcap:016e,htagg:03,htmcs:000000ff,extcap:00000a02':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '5GHz'),
+        ('Nexus 7', '2013 edition', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),127,221(0050f2,4),221(506f9a,9),htcap:016e,htagg:03,htmcs:000000ff,extcap:00000a02,wps:Nexus_7|assoc:0,1,48,45,221(0050f2,2),127,htcap:016e,htagg:03,htmcs:000000ff,extcap:00000a02':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '5GHz'),
+        ('Nexus 7', '2013 edition', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),127,221(0050f2,4),221(506f9a,9),htcap:016e,htagg:03,htmcs:000000ff,extcap:00000a02,wps:Nexus_7|assoc:0,1,33,36,48,45,221(0050f2,2),127,htcap:016e,htagg:03,htmcs:000000ff,txpow:1e0d,extcap:00000a02':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '5GHz'),
+        ('Nexus 7', '2013 edition', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),127,221(0050f2,4),221(506f9a,9),htcap:016e,htagg:03,htmcs:000000ff,extcap:00000a02,wps:Nexus_7|assoc:0,1,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '5GHz'),
+        ('Nexus 7', '2013 edition', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),127,221(0050f2,4),221(506f9a,10),221(506f9a,9),htcap:016e,htagg:03,htmcs:000000ff,extcap:00000a02,wps:Nexus_7|assoc:0,1,33,36,48,45,221(0050f2,2),127,htcap:016e,htagg:03,htmcs:000000ff,txpow:1e0d,extcap:00000a02':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '5GHz'),
+        ('Nexus 7', '2013 edition', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:016e,htagg:03,htmcs:000000ff,wps:Nexus_7|assoc:0,1,33,36,48,45,221(0050f2,2),127,htcap:016e,htagg:03,htmcs:000000ff,txpow:1e0d,extcap:00000a02':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '5GHz'),
+        ('Nexus 7', '2013 edition', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),127,221(0050f2,4),221(506f9a,9),htcap:016e,htagg:03,htmcs:000000ff,extcap:00000a02,wps:Nexus_7|assoc:0,1,33,36,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,txpow:1e0d,extcap:00000a02':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '5GHz'),
+        ('Nexus 7', '2013 edition', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,8),htcap:016e,htagg:03,htmcs:000000ff|assoc:0,1,33,36,48,45,221(0050f2,2),127,htcap:016e,htagg:03,htmcs:000000ff,txpow:1e0d,extcap:00000a02|oui:asus':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '5GHz'),
+        ('Nexus 7', '2013 edition', '5GHz'),
     'wifi4|probe:0,1,45,htcap:016e,htagg:03,htmcs:000000ff|assoc:0,1,33,36,48,45,221(0050f2,2),127,htcap:016e,htagg:03,htmcs:000000ff,txpow:1e0d,extcap:00000a02|oui:asus':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '5GHz'),
+        ('Nexus 7', '2013 edition', '5GHz'),
     'wifi4|probe:0,1,50,45,221(0050f2,8),127,221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02,wps:Nexus_7|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '2.4GHz'),
+        ('Nexus 7', '2013 edition', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,wps:Nexus_7|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '2.4GHz'),
+        ('Nexus 7', '2013 edition', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02|oui:asus':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '2.4GHz'),
+        ('Nexus 7', '2013 edition', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02|oui:asus':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '2.4GHz'),
+        ('Nexus 7', '2013 edition', '2.4GHz'),
     'wifi4|probe:0,1,50,45,htcap:016e,htagg:03,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a02|oui:asus':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '2.4GHz'),
+        ('Nexus 7', '2013 edition', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(0050f2,8),221(0050f2,4),221(506f9a,9),htcap:012c,htagg:03,htmcs:000000ff,wps:Nexus_7|assoc:0,1,50,48,45,221(0050f2,2),htcap:012c,htagg:03,htmcs:000000ff':
-        ('QCA_WCN3660', 'Nexus 7 (2013)', '2.4GHz'),
+        ('Nexus 7', '2013 edition', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,191,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:000008800140,wps:Nexus_9|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e009,extcap:000008800140':
-        ('BCM4354', 'Nexus 9', '5GHz'),
+        ('Nexus 9', '', '5GHz'),
+    'wifi4|probe:0,1,45,191,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,wps:Nexus_9|assoc:0,1,33,36,48,45,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e009':
+        ('Nexus 9', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0000088001400040,wps:Nexus_9|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1309,extcap:000008800140':
-        ('BCM4354', 'Nexus 9', '2.4GHz'),
+        ('Nexus 9', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:000008800140,wps:Nexus_9|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:150b,extcap:000008800140':
-        ('BCM4354', 'Nexus 9', '2.4GHz'),
+        ('Nexus 9', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:000008800140,wps:Nexus_9|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1309,extcap:000008800140':
-        ('BCM4354', 'Nexus 9', '2.4GHz'),
-    'wifi4|probe:0,1,50,3,45,127,221(00904c,4),221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:000008800140|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1309,extcap:000008800140|oui:samsung':
-        ('BCM4354', 'Nexus 9', '2.4GHz'),
+        ('Nexus 9', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,wps:Nexus_9|assoc:0,1,50,33,36,48,45,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1309':
-        ('BCM4354', 'Nexus 9', '2.4GHz'),
+        ('Nexus 9', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(001018,2),221(00904c,51),htcap:01fe,htagg:1b,htmcs:0000ffff|assoc:0,1,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:01fe,htagg:1b,htmcs:0000ffff|oui:samsung':
-        ('', 'Nexus 10', '5GHz'),
+        ('Nexus 10', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,221(001018,2),221(00904c,51),htcap:01bc,htagg:1b,htmcs:0000ffff|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:01bc,htagg:1b,htmcs:0000ffff|oui:samsung':
-        ('', 'Nexus 10', '2.4GHz'),
+        ('Nexus 10', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,191,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000088001400040,wps:Nexus_Player|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e009,extcap:0000088001400040':
-        ('BCM4356', 'Nexus Player', '5GHz'),
+        ('Nexus Player', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:000008800140,wps:Nexus_Player|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1209,extcap:000008800140':
-        ('BCM4356', 'Nexus Player', '2.4GHz'),
+        ('Nexus Player', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0000088001400040,wps:Nexus_Player|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1209,extcap:000008800140':
-        ('BCM4356', 'Nexus Player', '2.4GHz'),
+        ('Nexus Player', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,45,51,127,htcap:012c,htagg:1b,htmcs:000000ff,extcap:0100000000000040|assoc:0,1,48,50,221(0050f2,2),45,51,127,htcap:012c,htagg:1b,htmcs:000000ff,extcap:0100000000000040|os:windows-phone':
-        ('', 'Nokia Lumia 635', '2.4GHz'),
+        ('Nokia Lumia', '635', '2.4GHz'),
     'wifi4|probe:0,1,50,45,htcap:012c,htagg:1b,htmcs:000000ff|assoc:0,1,48,50,221(0050f2,2),45,51,127,htcap:012c,htagg:1b,htmcs:000000ff,extcap:0100000000000040|os:windows-phone':
-        ('', 'Nokia Lumia 635', '2.4GHz'),
+        ('Nokia Lumia', '635', '2.4GHz'),
 
     'wifi4|probe:0,1,45,htcap:016e,htagg:03,htmcs:000000ff|assoc:0,1,48,45,221(0050f2,2),htcap:016e,htagg:03,htmcs:000000ff|os:windows-phone':
-        ('', 'Nokia Lumia 920', '5GHz'),
+        ('Nokia Lumia', '920', '5GHz'),
     'wifi4|probe:0,1,50,45,htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),htcap:012c,htagg:03,htmcs:000000ff|os:windows-phone':
-        ('', 'Nokia Lumia 920', '2.4GHz'),
+        ('Nokia Lumia', '920', '2.4GHz'),
+
+    'wifi4|probe:0,1,45,127,191,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000008001000040,wps:SHIELD_Android_TV|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e007,extcap:0000008001000040':
+        ('NVidia SHIELD', 'Android TV', '5GHz'),
+    'wifi4|probe:0,1,50,3,45,127,221(0050f2,4),221(506f9a,9),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0000008001000040,wps:SHIELD_Android_TV|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1207,extcap:0000008001000040':
+        ('NVidia SHIELD', 'Android TV', '2.4GHz'),
 
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,33,48,70,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,txpow:170d,extcap:00000a0200000000|oui:oneplus':
-        ('', 'Oneplus X', '2.4GHz'),
+        ('Oneplus', 'X', '2.4GHz'),
 
     'wifi4|probe:0,1,50,48|assoc:0,1,33,36,50,221(0050f2,2),45,221(00037f,1),221(00037f,4),48,htcap:1004,htagg:1b,htmcs:0000ffff,txpow:0f0f|os:panasonictv':
-        ('', 'Panasonic TV', '2.4GHz'),
+        ('Panasonic TV', '', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(0050f2,4),htcap:01ad,htagg:02,htmcs:0000ffff,wps:WPS_SUPPLICANT_STATION|assoc:0,1,50,45,48,221(0050f2,2),htcap:01ad,htagg:02,htmcs:0000ffff|os:panasonictv':
-        ('', 'Panasonic TV', '2.4GHz'),
+        ('Panasonic TV', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50|assoc:0,1,50,48,221(005043,1)|os:playstation':
-        ('', 'Playstation 3 or 4', '2.4GHz'),
+        ('Playstation', '3 or 4', '2.4GHz'),
 
     'wifi4|probe:0,1,3,50|assoc:0,1,33,48,50,221(0050f2,2),45,htcap:010c,htagg:03,htmcs:0000ffff,txpow:1209|os:playstation':
-        ('Marvell_88W8797', 'Playstation 4', '2.4GHz'),
+        ('Playstation', '4', '2.4GHz'),
     'wifi4|probe:0,1,3,50|assoc:0,1,48,50,221(0050f2,2),45,htcap:112c,htagg:03,htmcs:0000ffff,txpow:0f06|os:playstation':
-        ('Marvell_88W8797', 'Playstation 4', '2.4GHz'),
+        ('Playstation', '4', '2.4GHz'),
     'wifi4|probe:0,1,3,50|assoc:0,1,33,48,50,221(0050f2,2),45,htcap:112c,htagg:03,htmcs:0000ffff,txpow:0f06|os:playstation':
-        ('Marvell_88W8797', 'Playstation 4', '2.4GHz'),
+        ('Playstation', '4', '2.4GHz'),
     'wifi4|probe:0,1,3,50|assoc:0,1,33,48,50,221(0050f2,2),45,htcap:010c,htagg:03,htmcs:0000ffff,txpow:0f06|os:playstation':
-        ('Marvell_88W8797', 'Playstation 4', '2.4GHz'),
+        ('Playstation', '4', '2.4GHz'),
 
     'wifi4|probe:0,1,50,221(0050f2,4),221(506f9a,9),wps:RCT6303W87DK|assoc:0,1,50,45,48,127,221(0050f2,2),htcap:1172,htagg:03,htmcs:000000ff,extcap:01':
-        ('', 'RCA 10 Viking Pro', '2.4GHz'),
+        ('RCA Viking Tablet', 'RCA 10 Viking Pro', '2.4GHz'),
+
+    'wifi4|probe:0,1,50,221(0050f2,4),221(506f9a,9),wps:RCT6773W42B|assoc:0,1,50,45,48,127,221(0050f2,2),htcap:1172,htagg:03,htmcs:000000ff,extcap:01':
+        ('RCA Voyager Tablet', 'v1', '2.4GHz'),
+
+    # RCA Voyager-II
+    'wifi4|probe:0,1,50,221(0050f2,4),221(506f9a,9),wps:RCT6773W22B|assoc:0,1,50,45,48,127,221(0050f2,2),htcap:1172,htagg:03,htmcs:000000ff,extcap:01':
+        ('RCA Voyager Tablet', 'v2', '2.4GHz'),
 
     # Roku model 1100, 2500 and LT model 2450
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:110c,htagg:19,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:110c,htagg:19,htmcs:000000ff|os:roku':
-        ('BCM43362', 'Roku HD/LT', '2.4GHz'),
+        ('Roku', 'HD or LT', '2.4GHz'),
 
     # Roku model 1101
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:186e,htagg:1a,htmcs:0000ffff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:186e,htagg:1a,htmcs:0000ffff,txpow:1208|os:roku':
-        ('', 'Roku HD-XR', '2.4GHz'),
+        ('Roku', 'HD-XR', '2.4GHz'),
 
     # Roku Streaming Stick model 3400X
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:187c,htagg:1a,htmcs:0000ffff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:187c,htagg:1a,htmcs:0000ffff,txpow:1208|os:roku':
-        ('', 'Roku Streaming Stick', '2.4GHz'),
+        ('Roku', 'Streaming Stick', '2.4GHz'),
 
-    # Roku 1 models 2000, 2050, 2100, and "XD" (not sure of model number)
+    # Roku 1 models 2000, 2050, 2100, and XD
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:186e,htagg:1a,htmcs:0000ffff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:186e,htagg:1a,htmcs:0000ffff,txpow:1308|os:roku':
-        ('', 'Roku 1', '2.4GHz'),
+        ('Roku', '1', '2.4GHz'),
 
     # Roku 1 model 2710 and Roku LT model 2700
     'wifi4|probe:0,1,50,3,45,221(001018,2),221(00904c,51),htcap:0020,htagg:1a,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0020,htagg:1a,htmcs:000000ff|os:roku':
-        ('', 'Roku 1/LT', '2.4GHz'),
+        ('Roku', '1 or LT', '2.4GHz'),
 
     # Roku 2 models 3000, 3050, 3100, and Roku LT model 2400
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:100c,htagg:19,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:100c,htagg:19,htmcs:000000ff|os:roku':
-        ('BCM4336', 'Roku 2/LT', '2.4GHz'),
+        ('Roku', '2 or LT', '2.4GHz'),
 
     # Roku 2 model 2720
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:187c,htagg:1a,htmcs:0000ffff|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:187c,htagg:1a,htmcs:0000ffff|os:roku':
-        ('BCM4336', 'Roku 2', '2.4GHz'),
+        ('Roku', '2', '2.4GHz'),
 
-    # Roku 3 model 4230, 4200, 4200X and Roku Streaming Stick model 3500
+    # Roku 3 model 4230, 4200, 4200X, 4230X, Roku Streaming Stick model 3500
     'wifi4|probe:0,1,45,127,221(001018,2),221(00904c,51),htcap:09bc,htagg:16,htmcs:0000ffff,extcap:0000000000000040|assoc:0,1,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:09bc,htagg:16,htmcs:0000ffff,txpow:100a,extcap:0000000000000040|os:roku':
-        ('BCM43236', 'Roku 3 or Streaming Stick', '5GHz'),
+        ('Roku', '3 or Streaming Stick', '5GHz'),
     'wifi4|probe:0,1,3,45,127,221(001018,2),221(00904c,51),htcap:09bc,htagg:16,htmcs:0000ffff,extcap:0000000000000040|assoc:0,1,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:09bc,htagg:16,htmcs:0000ffff,txpow:100a,extcap:0000000000000040|os:roku':
-        ('BCM43236', 'Roku 3 or Streaming Stick', '5GHz'),
+        ('Roku', '3 or Streaming Stick', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(001018,2),221(00904c,51),htcap:19bc,htagg:16,htmcs:0000ffff,extcap:0000000000000040|assoc:0,1,33,36,48,50,45,127,221(001018,2),221(0050f2,2),htcap:19bc,htagg:16,htmcs:0000ffff,txpow:140a,extcap:0000000000000040|os:roku':
-        ('BCM43236', 'Roku 3 or Streaming Stick', '2.4GHz'),
+        ('Roku', '3 or Streaming Stick', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(001018,2),221(00904c,51),htcap:193c,htagg:16,htmcs:0000ffff,extcap:0000000000000040|assoc:0,1,33,36,48,50,45,127,221(001018,2),221(0050f2,2),htcap:193c,htagg:16,htmcs:0000ffff,txpow:140a,extcap:0000000000000040|os:roku':
-        ('BCM43236', 'Roku 3 or Streaming Stick', '2.4GHz'),
+        ('Roku', '3 or Streaming Stick', '2.4GHz'),
 
     # Roku 4 model 4400
     'wifi4|probe:0,1,45,127,191,221(001018,2),htcap:01ad,htagg:17,htmcs:0000ffff,vhtcap:0f8159b2,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000000000000040|assoc:0,1,33,36,48,45,127,191,199,221(001018,2),221(0050f2,2),htcap:01ad,htagg:17,htmcs:0000ffff,vhtcap:0f8159b2,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:1109,extcap:0000000000000040|os:roku':
-        ('', 'Roku 4', '5GHz'),
+        ('Roku', '4', '5GHz'),
     'wifi4|probe:0,1,45,191,221(001018,2),htcap:01ad,htagg:17,htmcs:0000ffff,vhtcap:0f8159b2,vhtrxmcs:0000fffa,vhttxmcs:0000fffa|assoc:0,1,33,36,48,45,191,199,221(001018,2),221(0050f2,2),htcap:01ad,htagg:17,htmcs:0000ffff,vhtcap:0f8159b2,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:1109|os:roku':
-        ('', 'Roku 4', '5GHz'),
+        ('Roku', '4', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(001018,2),htcap:01ad,htagg:17,htmcs:0000ffff,extcap:0000000000000040|assoc:0,1,50,33,36,48,45,221(001018,2),221(0050f2,2),htcap:01ad,htagg:17,htmcs:0000ffff,txpow:1209|os:roku':
-        ('', 'Roku 4', '2.4GHz'),
+        ('Roku', '4', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,221(001018,2),htcap:01ad,htagg:17,htmcs:0000ffff|assoc:0,1,50,33,36,48,45,221(001018,2),221(0050f2,2),htcap:01ad,htagg:17,htmcs:0000ffff,txpow:1209|os:roku':
-        ('', 'Roku 4', '2.4GHz'),
+        ('Roku', '4', '2.4GHz'),
 
     'wifi4|probe:0,1,50,3,45,htcap:0020,htagg:01,htmcs:000000ff|assoc:0,1,50,45,61,48,221(0050f2,2),htcap:0020,htagg:01,htmcs:000000ff|oui:samsung':
-        ('', 'Samsung Galaxy Mini', '2.4GHz'),
+        ('Samsung Galaxy', 'Mini', '2.4GHz'),
 
     'wifi4|probe:0,1,45,3,221(0050f2,4),221(001018,2),221(00904c,51),htcap:010c,htagg:19,htmcs:000000ff,wps:Galaxy_Nexus|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:010c,htagg:19,htmcs:000000ff,txpow:0f09':
-        ('BCM4330', 'Samsung Galaxy Nexus', '5GHz'),
+        ('Samsung Galaxy Nexus', '', '5GHz'),
     'wifi4|probe:0,1,45,221(0050f2,4),221(001018,2),221(00904c,51),htcap:010c,htagg:19,htmcs:000000ff,wps:Galaxy_Nexus|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:010c,htagg:19,htmcs:000000ff,txpow:0f09':
-        ('BCM4330', 'Samsung Galaxy Nexus', '5GHz'),
+        ('Samsung Galaxy Nexus', '', '5GHz'),
     'wifi4|probe:0,1,45,3,221(0050f2,4),221(001018,2),221(00904c,51),htcap:000c,htagg:19,htmcs:000000ff,wps:_|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:000c,htagg:19,htmcs:000000ff,txpow:0f0a|oui:samsung':
-        ('BCM4330', 'Samsung Galaxy Nexus', '5GHz'),
+        ('Samsung Galaxy Nexus', '', '5GHz'),
     'wifi4|probe:0,1,50,45,221(0050f2,4),221(001018,2),221(00904c,51),htcap:110c,htagg:19,htmcs:000000ff,wps:Galaxy_Nexus|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:110c,htagg:19,htmcs:000000ff,txpow:1209':
-        ('BCM4330', 'Samsung Galaxy Nexus', '2.4GHz'),
+        ('Samsung Galaxy Nexus', '', '2.4GHz'),
     'wifi4|probe:0,1,50,45,3,221(0050f2,4),221(001018,2),221(00904c,51),htcap:110c,htagg:19,htmcs:000000ff,wps:Galaxy_Nexus|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:110c,htagg:19,htmcs:000000ff,txpow:1209':
-        ('BCM4330', 'Samsung Galaxy Nexus', '2.4GHz'),
+        ('Samsung Galaxy Nexus', '', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(0050f2,4),221(001018,2),221(00904c,51),htcap:100c,htagg:19,htmcs:000000ff,wps:_|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:100c,htagg:19,htmcs:000000ff,txpow:120a|oui:samsung':
-        ('BCM4330', 'Samsung Galaxy Nexus', '2.4GHz'),
+        ('Samsung Galaxy Nexus', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,3,221(001018,2),221(00904c,51),htcap:000c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:000c,htagg:19,htmcs:000000ff,txpow:0f09|oui:samsung':
-        ('', 'Samsung Galaxy Note or S2+', '5GHz'),
+        ('Samsung Galaxy Note or S2+', '', '5GHz'),
 
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:100c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:100c,htagg:19,htmcs:000000ff,txpow:1409|oui:samsung':
-        ('', 'Samsung Galaxy Note', '2.4GHz'),
+        ('Samsung Galaxy Note', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(001018,2),221(00904c,51),htcap:0062,htagg:1a,htmcs:000000ff|assoc:0,1,33,36,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:0e09|oui:samsung':
-        ('BCM4330', 'Samsung Galaxy Note 2', '5GHz'),
+        ('Samsung Galaxy Note II', '', '5GHz'),
     'wifi4|probe:0,1,45,221(001018,2),221(00904c,51),htcap:0062,htagg:1a,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:0e09|oui:samsung':
-        ('BCM4330', 'Samsung Galaxy Note 2', '5GHz'),
+        ('Samsung Galaxy Note II', '', '5GHz'),
     'wifi4|probe:0,1,45,3,221(001018,2),221(00904c,51),htcap:0062,htagg:1a,htmcs:000000ff|assoc:0,1,33,36,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:0e09|oui:samsung':
-        ('BCM4330', 'Samsung Galaxy Note 2', '5GHz'),
+        ('Samsung Galaxy Note II', '', '5GHz'),
     'wifi4|probe:0,1,45,3,221(001018,2),221(00904c,51),htcap:0062,htagg:1a,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:0e09|oui:samsung':
-        ('BCM4330', 'Samsung Galaxy Note 2', '5GHz'),
+        ('Samsung Galaxy Note II', '', '5GHz'),
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:1020,htagg:1a,htmcs:000000ff|assoc:0,1,33,36,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:1020,htagg:1a,htmcs:000000ff,txpow:1209|oui:samsung':
-        ('BCM4330', 'Samsung Galaxy Note 2', '2.4GHz'),
+        ('Samsung Galaxy Note II', '', '2.4GHz'),
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:1020,htagg:1a,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:1020,htagg:1a,htmcs:000000ff,txpow:1209|oui:samsung':
-        ('BCM4330', 'Samsung Galaxy Note 2', '2.4GHz'),
+        ('Samsung Galaxy Note II', '', '2.4GHz'),
 
     'wifi4|probe:0,1,3,45,127,191,221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000080000000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(00904c,4),221(0050f2,2),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e008,extcap:0000000000000040|oui:samsung':
-        ('BCM4335', 'Samsung Galaxy Note 3', '5GHz'),
+        ('Samsung Galaxy Note 3', '', '5GHz'),
     'wifi4|probe:0,1,45,127,191,221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000080000000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(00904c,4),221(0050f2,2),htcap:016f,htagg:17,htmcs:000000ff,vhtcap:0f805932,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e008,extcap:0000000000000040|oui:samsung':
-        ('BCM4335', 'Samsung Galaxy Note 3', '5GHz'),
+        ('Samsung Galaxy Note 3', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:112d,htagg:17,htmcs:000000ff,extcap:0000080000000040|assoc:0,1,33,36,48,50,45,221(001018,2),221(0050f2,2),htcap:112d,htagg:17,htmcs:000000ff,txpow:1208|oui:samsung':
-        ('BCM4335', 'Samsung Galaxy Note 3', '2.4GHz'),
+        ('Samsung Galaxy Note 3', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:112d,htagg:17,htmcs:000000ff,extcap:0000080000000040|assoc:0,1,33,36,48,50,45,127,221(001018,2),221(0050f2,2),htcap:112d,htagg:17,htmcs:000000ff,txpow:1208|oui:samsung':
-        ('BCM4335', 'Samsung Galaxy Note 3', '2.4GHz'),
+        ('Samsung Galaxy Note 3', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,191,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000088001400040|assoc:0,1,33,36,48,45,127,107,191,221(00904c,4),221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e009,extcap:0000088001400040|oui:samsung':
-        ('BCM4358', 'Samsung Galaxy Note 4', '5GHz'),
+        ('Samsung Galaxy Note 4', '', '5GHz'),
     'wifi4|probe:0,1,45,127,191,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000088001400040|assoc:0,1,33,36,48,70,45,127,191,221(00904c,4),221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e009,extcap:0000088001400040|oui:samsung':
-        ('BCM4358', 'Samsung Galaxy Note 4', '5GHz'),
+        ('Samsung Galaxy Note 4', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0000088001400040|assoc:0,1,50,33,36,48,45,127,107,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1509,extcap:0000088001400040|oui:samsung':
-        ('BCM4358', 'Samsung Galaxy Note 4', '2.4GHz'),
+        ('Samsung Galaxy Note 4', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0000088001400040|assoc:0,1,50,33,36,48,70,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1509,extcap:0000088001400040|oui:samsung':
-        ('BCM4358', 'Samsung Galaxy Note 4', '2.4GHz'),
+        ('Samsung Galaxy Note 4', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,191,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:01ef,htagg:17,htmcs:0000ffff,vhtcap:0f9118b2,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:00080f8401400040|assoc:0,1,33,36,48,45,127,191,199,221(00904c,4),221(001018,2),221(0050f2,2),htcap:01ef,htagg:17,htmcs:0000ffff,vhtcap:0f9118b2,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:1102,extcap:0000000000000040|oui:samsung':
-        ('BCM4359', 'Samsung Galaxy Note 5', '5GHz'),
+        ('Samsung Galaxy Note 5', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:01ef,htagg:17,htmcs:0000ffff,vhtcap:0f9118b2,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:00080f8401400040|assoc:0,1,33,36,48,70,45,127,191,199,221(00904c,4),221(001018,2),221(0050f2,2),htcap:01ef,htagg:17,htmcs:0000ffff,vhtcap:0f9118b2,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:1202,extcap:0000000000000040|oui:samsung':
-        ('BCM4359', 'Samsung Galaxy Note 5', '5GHz'),
+        ('Samsung Galaxy Note 5', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:01ef,htagg:17,htmcs:0000ffff,vhtcap:0f9118b2,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:00080f840140|assoc:0,1,33,36,48,70,45,191,199,221(00904c,4),221(001018,2),221(0050f2,2),htcap:01ef,htagg:17,htmcs:0000ffff,vhtcap:0f9118b2,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:1202|oui:samsung':
-        ('BCM4359', 'Samsung Galaxy Note 5', '5GHz'),
+        ('Samsung Galaxy Note 5', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:01ad,htagg:17,htmcs:0000ffff,extcap:00080f8401400040|assoc:0,1,50,33,36,48,45,221(001018,2),221(0050f2,2),htcap:01ad,htagg:17,htmcs:0000ffff,txpow:1202|oui:samsung':
-        ('BCM4359', 'Samsung Galaxy Note 5', '2.4GHz'),
+        ('Samsung Galaxy Note 5', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(001018,2),221(00904c,51),htcap:000c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:000c,htagg:19,htmcs:000000ff,txpow:0f0a|oui:samsung':
-        ('', 'Samsung Galaxy S2', '5GHz'),
+        ('Samsung Galaxy S2', '', '5GHz'),
     'wifi4|probe:0,1,45,3,221(001018,2),221(00904c,51),htcap:000c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:000c,htagg:19,htmcs:000000ff,txpow:0f0a|oui:samsung':
-        ('', 'Samsung Galaxy S2', '5GHz'),
+        ('Samsung Galaxy S2', '', '5GHz'),
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:100c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:100c,htagg:19,htmcs:000000ff,txpow:120a|oui:samsung':
-        ('', 'Samsung Galaxy S2 or Infuse','2.4GHz'),
+        ('Samsung Galaxy S2 or Infuse', '', '2.4GHz'),
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:100c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:100c,htagg:19,htmcs:000000ff,txpow:120a|oui:samsung':
-        ('', 'Samsung Galaxy S2 or Infuse','2.4GHz'),
+        ('Samsung Galaxy S2 or Infuse', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:100c,htagg:19,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:100c,htagg:19,htmcs:000000ff,txpow:1209|oui:samsung':
-        ('', 'Samsung Galaxy S2+', '2.4GHz'),
+        ('Samsung Galaxy S2+', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(001018,2),221(00904c,51),htcap:0062,htagg:1a,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1409|oui:samsung':
-        ('BCM4334', 'Samsung Galaxy S3', '5GHz'),
+        ('Samsung Galaxy S3', '', '5GHz'),
     'wifi4|probe:0,1,45,3,221(001018,2),221(00904c,51),htcap:0062,htagg:1a,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:0062,htagg:1a,htmcs:000000ff,txpow:1409|oui:samsung':
-        ('BCM4334', 'Samsung Galaxy S3', '5GHz'),
+        ('Samsung Galaxy S3', '', '5GHz'),
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:1020,htagg:1a,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:1020,htagg:1a,htmcs:000000ff,txpow:1409|oui:samsung':
-        ('BCM4334', 'Samsung Galaxy S3', '2.4GHz'),
+        ('Samsung Galaxy S3', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,191,221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000080000000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(00904c,4),221(0050f2,2),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e001,extcap:0000000000000040|oui:samsung':
-        ('BCM4335', 'Samsung Galaxy S4', '5GHz'),
+        ('Samsung Galaxy S4', '', '5GHz'),
     'wifi4|probe:0,1,3,45,127,191,221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000080000000040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(00904c,4),221(0050f2,2),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e001,extcap:0000000000000040|oui:samsung':
-        ('BCM4335', 'Samsung Galaxy S4', '5GHz'),
+        ('Samsung Galaxy S4', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(506f9a,16),221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000088000400040|assoc:0,1,33,36,48,45,127,107,191,221(001018,2),221(00904c,4),221(0050f2,2),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e001,extcap:0000008000400040|oui:samsung':
-        ('BCM4335', 'Samsung Galaxy S4', '5GHz'),
+        ('Samsung Galaxy S4', '', '5GHz'),
     'wifi4|probe:0,1,3,45,127,107,191,221(506f9a,16),221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000088000400040|assoc:0,1,33,36,48,45,127,107,191,221(001018,2),221(00904c,4),221(0050f2,2),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e001,extcap:0000008000400040|oui:samsung':
-        ('BCM4335', 'Samsung Galaxy S4', '5GHz'),
+        ('Samsung Galaxy S4', '', '5GHz'),
     'wifi4|probe:0,1,45,127,191,221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000080000400040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(00904c,4),221(0050f2,2),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e001,extcap:0000000000400040|oui:samsung':
-        ('BCM4335', 'Samsung Galaxy S4', '5GHz'),
+        ('Samsung Galaxy S4', '', '5GHz'),
     'wifi4|probe:0,1,3,45,127,191,221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,extcap:0000080000400040|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(00904c,4),221(0050f2,2),htcap:006f,htagg:17,htmcs:000000ff,vhtcap:0f805832,vhtrxmcs:0000fffe,vhttxmcs:0000fffe,txpow:e001,extcap:0000000000400040|oui:samsung':
-        ('BCM4335', 'Samsung Galaxy S4', '5GHz'),
+        ('Samsung Galaxy S4', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(506f9a,16),221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:102d,htagg:17,htmcs:000000ff,extcap:0000088000400040|assoc:0,1,33,36,48,50,45,127,107,221(001018,2),221(0050f2,2),htcap:102d,htagg:17,htmcs:000000ff,txpow:1201,extcap:000000800040|oui:samsung':
-        ('BCM4335', 'Samsung Galaxy S4', '2.4GHz'),
+        ('Samsung Galaxy S4', '', '2.4GHz'),
     'wifi4|probe:0,1,50,45,127,221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:102d,htagg:17,htmcs:000000ff,extcap:0000080000000040|assoc:0,1,33,36,48,50,45,221(001018,2),221(0050f2,2),htcap:102d,htagg:17,htmcs:000000ff,txpow:1201|oui:samsung':
-        ('BCM4335', 'Samsung Galaxy S4', '2.4GHz'),
+        ('Samsung Galaxy S4', '', '2.4GHz'),
     'wifi4|probe:0,1,50,45,127,107,221(506f9a,16),221(001018,2),221(00904c,51),221(00904c,4),221(0050f2,8),htcap:102d,htagg:17,htmcs:000000ff,extcap:0000088000400040|assoc:0,1,33,36,48,50,45,127,107,221(001018,2),221(0050f2,2),htcap:102d,htagg:17,htmcs:000000ff,txpow:1201,extcap:000000800040|oui:samsung':
-        ('BCM4335', 'Samsung Galaxy S4', '2.4GHz'),
+        ('Samsung Galaxy S4', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,191,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000088001400040|assoc:0,1,33,36,48,45,127,107,191,221(00904c,4),221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e20b,extcap:0000088001400040|oui:samsung':
-        ('BCM4354', 'Samsung Galaxy S5', '5GHz'),
+        ('Samsung Galaxy S5', '', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:000008800140|assoc:0,1,33,36,48,45,127,107,191,221(00904c,4),221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e20b,extcap:000008800140|oui:samsung':
-        ('BCM4354', 'Samsung Galaxy S5', '5GHz'),
+        ('Samsung Galaxy S5', '', '5GHz'),
     'wifi4|probe:0,1,45,191,221(00904c,4),221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa|assoc:0,1,33,36,48,45,191,221(00904c,4),221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e20b|oui:samsung':
-        ('BCM4354', 'Samsung Galaxy S5', '5GHz'),
+        ('Samsung Galaxy S5', '', '5GHz'),
     'wifi4|probe:0,1,45,191,221(00904c,4),221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:9b40fffa,vhttxmcs:18dafffa|assoc:0,1,33,36,48,45,191,221(00904c,4),221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:9b40fffa,vhttxmcs:18dafffa,txpow:e20b|oui:samsung':
-        ('BCM4354', 'Samsung Galaxy S5', '5GHz'),
+        ('Samsung Galaxy S5', '', '5GHz'),
     'wifi4|probe:0,1,45,127,191,221(00904c,4),221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:000008800140|assoc:0,1,33,36,48,45,127,191,221(00904c,4),221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e20b,extcap:000008800140|oui:samsung':
-        ('BCM4354', 'Samsung Galaxy S5', '5GHz'),
+        ('Samsung Galaxy S5', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:000008800140|assoc:0,1,50,33,36,48,45,127,107,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1209,extcap:000008800140|oui:samsung':
-        ('BCM4354', 'Samsung Galaxy S5', '2.4GHz'),
+        ('Samsung Galaxy S5', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0000088001400040|assoc:0,1,50,33,36,48,45,127,107,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1209,extcap:000008800140|oui:samsung':
-        ('BCM4354', 'Samsung Galaxy S5', '2.4GHz'),
+        ('Samsung Galaxy S5', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:000008800140|assoc:0,1,50,33,36,48,70,45,127,107,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1209,extcap:000008800140|oui:samsung':
-        ('BCM4354', 'Samsung Galaxy S5', '2.4GHz'),
+        ('Samsung Galaxy S5', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,191,221(00904c,4),221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000088001400040|assoc:0,1,33,36,48,45,127,191,221(00904c,4),221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0000088001400040|oui:samsung':
-        ('BCM4358', 'Samsung Galaxy S6', '5GHz'),
+        ('Samsung Galaxy S6', '', '5GHz'),
     'wifi4|probe:0,1,45,127,191,221(00904c,4),221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000088001400040|assoc:0,1,33,36,45,127,191,221(00904c,4),221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002,extcap:0000088001400040|oui:samsung':
-        ('BCM4358', 'Samsung Galaxy S6', '5GHz'),
+        ('Samsung Galaxy S6', '', '5GHz'),
     'wifi4|probe:0,1,45,191,221(00904c,4),221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa|assoc:0,1,33,36,48,45,191,221(00904c,4),221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e002|oui:samsung':
-        ('BCM4358', 'Samsung Galaxy S6', '5GHz'),
+        ('Samsung Galaxy S6', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(00904c,4),221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0000088001400040|assoc:0,1,50,33,36,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1402,extcap:0000088001400040|oui:samsung':
-        ('BCM4358', 'Samsung Galaxy S6', '2.4GHz'),
+        ('Samsung Galaxy S6', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(00904c,4),221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0000088001400040|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1402,extcap:0000088001400040|oui:samsung':
-        ('BCM4358', 'Samsung Galaxy S6', '2.4GHz'),
+        ('Samsung Galaxy S6', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,221(00904c,4),221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0000088001400040|assoc:0,1,50,33,36,48,70,45,127,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1402,extcap:0000088001400040|oui:samsung':
-        ('BCM4358', 'Samsung Galaxy S6', '2.4GHz'),
+        ('Samsung Galaxy S6', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,191,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:0163,htagg:17,htmcs:0000ffff,vhtcap:0f907032,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:00080f8401400040|assoc:0,1,33,36,48,70,45,127,191,199,221(00904c,4),221(001018,2),221(0050f2,2),htcap:01ef,htagg:17,htmcs:0000ffff,vhtcap:0f9118b2,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:1102,extcap:0000000000000040|oui:samsung':
-        ('', 'Samsung Galaxy S7', '5GHz'),
+        ('Samsung Galaxy S7', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:01ad,htagg:17,htmcs:0000ffff,extcap:00080f8401400040|assoc:0,1,50,33,36,48,70,45,221(001018,2),221(0050f2,2),htcap:01ad,htagg:17,htmcs:0000ffff,txpow:1402|oui:samsung':
-        ('', 'Samsung Galaxy S7', '2.4GHz'),
+        ('Samsung Galaxy S7', '', '2.4GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:01ad,htagg:17,htmcs:0000ffff,extcap:00080f840140|assoc:0,1,50,33,36,48,70,45,221(001018,2),221(0050f2,2),htcap:01ad,htagg:17,htmcs:0000ffff,txpow:1402|oui:samsung':
-        ('', 'Samsung Galaxy S7', '2.4GHz'),
+        ('Samsung Galaxy S7', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,191,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:01ef,htagg:17,htmcs:0000ffff,vhtcap:0f9178b2,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:00080f840140|assoc:0,1,33,36,48,70,45,191,199,221(00904c,4),221(001018,2),221(0050f2,2),htcap:01ef,htagg:17,htmcs:0000ffff,vhtcap:0f9118b2,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:1102|oui:samsung':
-        ('', 'Samsung Galaxy S7 Edge', '5GHz'),
+        ('Samsung Galaxy S7 Edge', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(506f9a,16),221(00904c,4),221(0050f2,8),221(001018,2),htcap:1163,htagg:17,htmcs:0000ffff,extcap:00080f8401400040|assoc:0,1,50,33,36,48,70,45,221(001018,2),221(0050f2,2),htcap:01ad,htagg:17,htmcs:0000ffff,txpow:1302|oui:samsung':
-        ('', 'Samsung Galaxy S7 Edge', '2.4GHz'),
+        ('Samsung Galaxy S7 Edge', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(001018,2),221(00904c,51),htcap:082c,htagg:1b,htmcs:000000ff|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:082c,htagg:1b,htmcs:000000ff,txpow:0f08|oui:samsung':
-        ('BCM4329', 'Samsung Galaxy Tab', '5GHz'),
+        ('Samsung Galaxy Tab', '', '5GHz'),
     'wifi4|probe:0,1,50,45,221(001018,2),221(00904c,51),htcap:182c,htagg:1b,htmcs:000000ff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:182c,htagg:1b,htmcs:000000ff,txpow:1208|oui:samsung':
-        ('BCM4329', 'Samsung Galaxy Tab', '2.4GHz'),
+        ('Samsung Galaxy Tab', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,50,htcap:0162,htagg:03,htmcs:00000000|assoc:0,1,48,127,221(0050f2,2),45,htcap:016e,htagg:03,htmcs:000000ff,extcap:0400000000000140|oui:samsung':
-        ('Marvell_88W8787', 'Samsung Galaxy Tab 3', '5GHz'),
+        ('Samsung Galaxy Tab 3', '', '5GHz'),
     'wifi4|probe:0,1,45,50,htcap:0162,htagg:03,htmcs:00000000|assoc:0,1,33,36,48,127,221(0050f2,2),45,htcap:016e,htagg:03,htmcs:000000ff,txpow:1208,extcap:0400000000000140|oui:samsung':
-        ('Marvell_88W8787', 'Samsung Galaxy Tab 3', '5GHz'),
+        ('Samsung Galaxy Tab 3', '', '5GHz'),
     'wifi4|probe:0,1,3,45,50,htcap:0162,htagg:03,htmcs:00000000|assoc:0,1,48,50,127,221(0050f2,2),45,htcap:012c,htagg:03,htmcs:000000ff,extcap:0000000000000140|oui:samsung':
-        ('Marvell_88W8787', 'Samsung Galaxy Tab 3', '2.4GHz'),
+        ('Samsung Galaxy Tab 3', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(0050f2,8),htcap:016e,htagg:03,htmcs:000000ff|assoc:0,1,33,36,48,45,221(0050f2,2),221(004096,3),htcap:016e,htagg:03,htmcs:000000ff,txpow:170d|oui:samsung':
-        ('APQ8026', 'Samsung Galaxy Tab 4', '5GHz'),
+        ('Samsung Galaxy Tab 4', '', '5GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,48,45,221(0050f2,2),221(004096,3),htcap:012c,htagg:03,htmcs:000000ff|oui:samsung':
-        ('APQ8026', 'Samsung Galaxy Tab 4', '2.4GHz'),
+        ('Samsung Galaxy Tab 4', '', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(0050f2,4),221(001018,2),221(00904c,51),htcap:000c,htagg:19,htmcs:000000ff,wps:_|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:000c,htagg:19,htmcs:000000ff,txpow:0c0a|oui:samsung':
-        ('BCM4330', 'Samsung Galaxy Tab 10.1', '5GHz'),
+        ('Samsung Galaxy Tab 10.1', '', '5GHz'),
     'wifi4|probe:0,1,45,3,221(0050f2,4),221(001018,2),221(00904c,51),htcap:000c,htagg:19,htmcs:000000ff,wps:_|assoc:0,1,33,36,48,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:000c,htagg:19,htmcs:000000ff,txpow:0c0a|oui:samsung':
-        ('BCM4330', 'Samsung Galaxy Tab 10.1', '5GHz'),
+        ('Samsung Galaxy Tab 10.1', '', '5GHz'),
     'wifi4|probe:0,1,50,45,3,221(0050f2,4),221(001018,2),221(00904c,51),htcap:100c,htagg:19,htmcs:000000ff,wps:_|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:100c,htagg:19,htmcs:000000ff,txpow:0f0a|oui:samsung':
-        ('BCM4330', 'Samsung Galaxy Tab 10.1', '2.4GHz'),
+        ('Samsung Galaxy Tab 10.1', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,3,45,221(001018,2),htcap:0020,htagg:1f,htmcs:000000ff|assoc:0,1,50,33,36,48,45,221(001018,2),221(0050f2,2),htcap:0020,htagg:1f,htmcs:000000ff,txpow:1203|os:tizen':
-        ('', 'Samsung Gear S2', '2.4GHz'),
+        ('Samsung Watch', 'Gear S2', '2.4GHz'),
 
     'wifi4|probe:0,1,45,htcap:11ee,htagg:02,htmcs:0000ffff|assoc:0,1,45,127,33,36,48,221(0050f2,2),htcap:11ee,htagg:02,htmcs:0000ffff,txpow:1100,extcap:01|os:samsungtv':
-        ('', 'Samsung Smart TV', '5GHz'),
+        ('Samsung Smart TV', '', '5GHz'),
     'wifi4|probe:0,1,50,45,htcap:01ac,htagg:02,htmcs:0000ffff|assoc:0,1,50,45,127,48,221(0050f2,2),htcap:01ac,htagg:02,htmcs:0000ffff,extcap:01|os:samsungtv':
-        ('', 'Samsung Smart TV', '2.4GHz'),
+        ('Samsung Smart TV', '', '2.4GHz'),
     'wifi4|probe:0,1,50,45,221(002d25,32),htcap:01ac,htagg:02,htmcs:0000ffff|assoc:0,1,50,48,221(0050f2,2),45,127,htcap:01ac,htagg:02,htmcs:0000ffff,extcap:01|os:samsungtv':
-        ('', 'Samsung Smart TV', '2.4GHz'),
+        ('Samsung Smart TV', '', '2.4GHz'),
     'wifi4|probe:0,1,50,45,htcap:0120,htagg:02,htmcs:000000ff|assoc:0,1,50,48,221(0050f2,2),45,127,htcap:0120,htagg:02,htmcs:000000ff,extcap:01|os:samsungtv':
-        ('', 'Samsung Smart TV', '2.4GHz'),
+        ('Samsung Smart TV', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,3,45,htcap:11ef,htagg:1b,htmcs:0000ffff|assoc:0,1,50,48,45,221(0050f2,2),htcap:11ef,htagg:1b,htmcs:0000ffff|oui:sling':
-        ('', 'Slingbox 500', '2.4GHz'),
+        ('Slingbox', '500', '2.4GHz'),
 
     'wifi4|probe:0,1,45,221(0050f2,4),htcap:11ee,htagg:02,htmcs:0000ffff,wps:Sony_BRAVIA|assoc:0,1,33,36,48,221(0050f2,2),45,127,htcap:11ee,htagg:02,htmcs:0000ffff,txpow:0500,extcap:01':
-        ('', 'Sony Bravia TV', '5GHz'),
+        ('Sony Bravia TV', '', '5GHz'),
     'wifi4|probe:0,1,50,45,127,221(0050f2,4),221(506f9a,10),221(506f9a,9),htcap:01ed,htagg:13,htmcs:0000ffff,extcap:00,wps:BRAVIA_2015|assoc:0,1,50,45,127,221(000c43,6),221(0050f2,2),48,127,htcap:008c,htagg:13,htmcs:0000ffff,extcap:00000a02':
-        ('', 'Sony Bravia TV', '2.4GHz'),
+        ('Sony Bravia TV', '', '2.4GHz'),
+    'wifi4|probe:0,1,50,221(0050f2,4),221(506f9a,10),221(506f9a,9),wps:BRAVIA_4K_2015|assoc:0,1,50,45,127,221(000c43,6),221(0050f2,2),48,127,htcap:008c,htagg:13,htmcs:0000ffff,extcap:00000a02':
+        ('Sony Bravia TV', '', '2.4GHz'),
 
     'wifi4|probe:0,1,3,45,221(0050f2,8),191,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffc,vhttxmcs:0000fffc|assoc:0,1,33,36,48,70,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff|oui:sony':
-        ('WCN3680', 'Sony Xperia Z Ultra', '5GHz'),
+        ('Sony Xperia', 'Z Ultra', '5GHz'),
     'wifi4|probe:0,1,3,45,221(0050f2,8),191,htcap:016e,htagg:03,htmcs:000000ff,vhtcap:31800120,vhtrxmcs:0000fffc,vhttxmcs:0000fffc|assoc:0,1,48,45,221(0050f2,2),htcap:012c,htagg:03,htmcs:000000ff|oui:sony':
-        ('WCN3680', 'Sony Xperia Z Ultra', '5GHz'),
+        ('Sony Xperia', 'Z Ultra', '5GHz'),
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,33,48,70,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,txpow:170d,extcap:00000a0200000000|oui:sony':
-        ('WCN3680', 'Sony Xperia Z Ultra', '2.4GHz'),
+        ('Sony Xperia', 'Z Ultra', '2.4GHz'),
     'wifi4|probe:0,1,50,45,htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,33,48,70,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,txpow:170d,extcap:00000a0200000000|oui:sony':
-        ('WCN3680', 'Sony Xperia Z Ultra', '2.4GHz'),
+        ('Sony Xperia', 'Z Ultra', '2.4GHz'),
 
     'wifi4|probe:0,1,45,127,107,191,221(506f9a,16),221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815032,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000088001400040|assoc:0,1,33,36,48,70,45,127,107,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815032,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e007,extcap:0000088001400040|oui:sony':
-        ('', 'Sony Xperia Z4/Z5', '5GHz'),
+        ('Sony Xperia', 'Z4 or Z5', '5GHz'),
     'wifi4|probe:0,1,45,127,107,191,221(506f9a,16),221(0050f2,8),221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000088001400040|assoc:0,1,33,36,48,70,45,127,107,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e007,extcap:0000088001400040|oui:sony':
-        ('', 'Sony Xperia Z4/Z5', '5GHz'),
+        ('Sony Xperia', 'Z4 or Z5', '5GHz'),
     'wifi4|probe:0,1,50,3,45,127,107,221(506f9a,16),221(0050f2,8),221(001018,2),htcap:002d,htagg:17,htmcs:0000ffff,extcap:0000088001400040|assoc:0,1,50,33,36,48,70,45,127,107,221(001018,2),221(0050f2,2),htcap:002d,htagg:17,htmcs:0000ffff,txpow:1307,extcap:0000088001400040|oui:sony':
-        ('', 'Sony Xperia Z4/Z5', '2.4GHz'),
-
-    'wifi4|probe:0,1,50,3,45,221(0050f2,8),127,107,221(0050f2,4),221(506f9a,10),221(506f9a,9),221(506f9a,16),htcap:012c,htagg:03,htmcs:000000ff,extcap:00000a820040,wps:831C|assoc:0,1,50,33,48,70,45,221(0050f2,2),127,htcap:012c,htagg:03,htmcs:000000ff,txpow:170d,extcap:00000a8201400000':
-        ('', 'Sprint One M8', '2.4GHz'),
-
-    'wifi4|probe:0,1,50,3,45,127,221(0050f2,4),221(506f9a,9),221(506f9a,16),221(0050f2,8),221(001018,2),htcap:1063,htagg:17,htmcs:000000ff,extcap:000008800140,wps:0PJA2|assoc:0,1,50,33,36,48,45,127,221(001018,2),221(0050f2,2),htcap:1063,htagg:17,htmcs:000000ff,txpow:1309,extcap:000008800140':
-        ('', 'Sprint One M9', '2.4GHz'),
+        ('Sony Xperia', 'Z4 or Z5', '2.4GHz'),
 
     # TIVO-849
     'wifi4|probe:0,1,45,127,191,221(001018,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,extcap:0000008001|assoc:0,1,33,36,48,45,127,191,221(001018,2),221(0050f2,2),htcap:006f,htagg:17,htmcs:0000ffff,vhtcap:0f815832,vhtrxmcs:0000fffa,vhttxmcs:0000fffa,txpow:e009,extcap:0000008001|os:tivo':
-        ('', 'TiVo BOLT', '5GHz'),
+        ('TiVo', 'BOLT', '5GHz'),
     # TIVO-746
     'wifi4|probe:0,1,50,221(00904c,51),45,48,htcap:13ce,htagg:1b,htmcs:0000ffff|assoc:0,1,33,36,50,221(0050f2,2),221(00904c,51),45,221(002163,1),221(002163,4),48,htcap:13ce,htagg:1b,htmcs:0000ffff,txpow:0f0f|os:tivo':
-        ('', 'TiVo Premiere Series 4', '2.4GHz'),
+        ('TiVo', 'Premiere Series 4', '2.4GHz'),
     # TIVO-846
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:107c,htagg:19,htmcs:0000ffff|assoc:0,1,33,36,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:107c,htagg:19,htmcs:0000ffff,txpow:1208|os:tivo':
-        ('', 'TiVo Roamio', '2.4GHz'),
+        ('TiVo', 'Roamio', '2.4GHz'),
     # TIVO-848
     'wifi4|probe:0,1,50|assoc:0,1,50,221(0050f2,2),45,51,48,htcap:01ac,htagg:1b,htmcs:0000ffff|os:tivo':
-        ('', 'TiVo Roamio Plus', '2.4GHz'),
+        ('TiVo', 'Roamio Plus', '2.4GHz'),
     # TiVo-652 HD and HD XL, TIVO-648, and TIVO-750 have the same signature
     'wifi4|probe:0,1,50,221(001018,2)|assoc:0,1,48,50,221(001018,2)|os:tivo':
-        ('', 'TiVo Series 3/4', '2.4GHz'),
+        ('TiVo', 'Series3 or Series4', '2.4GHz'),
 
-    'wifi4|probe:0,1,50,221(0050f2,4),wps:Ralink_Wireless_Linux_Client|assoc:0,1,50,45,127,221(000c43,6),221(0050f2,2),48,htcap:000c,htagg:12,htmcs:000000ff,extcap:01000000|os:visiotv':
-        ('', 'Vizio Smart TV', '2.4GHz'),
-    'wifi4|probe:0,1,50,221(0050f2,4),wps:Ralink_Wireless_Linux_Client|assoc:0,1,50,45,127,221(000c43,6),221(0050f2,2),48,htcap:000c,htagg:13,htmcs:000000ff,extcap:01|os:visiotv':
-        ('', 'Vizio Smart TV', '2.4GHz'),
-    'wifi4|probe:0,1,50,45,127,221(0050f2,4),htcap:106e,htagg:12,htmcs:000000ff,extcap:00,wps:Ralink_Wireless_Linux_Client|assoc:0,1,50,45,127,221(000c43,6),221(0050f2,2),48,htcap:000c,htagg:12,htmcs:000000ff,extcap:01000000|os:visiotv':
-        ('', 'Vizio Smart TV', '2.4GHz'),
-    'wifi4|probe:0,1,50,221(0050f2,4),wps:Ralink_Wireless_Linux_Client|assoc:0,1,50,45,221(000c43,6),221(0050f2,2),48,htcap:000c,htagg:13,htmcs:000000ff|os:visiotv':
-        ('', 'Vizio Smart TV', '2.4GHz'),
-    'wifi4|probe:0,1,50,48|assoc:0,1,50,221(0050f2,2),45,51,127,48,htcap:012c,htagg:1b,htmcs:000000ff,extcap:01|os:visiotv':
-        ('', 'Vizio Smart TV', '2.4GHz'),
+    'wifi4|probe:0,1,50,221(0050f2,4),wps:Ralink_Wireless_Linux_Client|assoc:0,1,50,45,127,221(000c43,6),221(0050f2,2),48,htcap:000c,htagg:12,htmcs:000000ff,extcap:01000000|os:viziotv':
+        ('Vizio Smart TV', '', '2.4GHz'),
+    'wifi4|probe:0,1,50,221(0050f2,4),wps:Ralink_Wireless_Linux_Client|assoc:0,1,50,45,127,221(000c43,6),221(0050f2,2),48,htcap:000c,htagg:13,htmcs:000000ff,extcap:01|os:viziotv':
+        ('Vizio Smart TV', '', '2.4GHz'),
+    'wifi4|probe:0,1,50,45,127,221(0050f2,4),htcap:106e,htagg:12,htmcs:000000ff,extcap:00,wps:Ralink_Wireless_Linux_Client|assoc:0,1,50,45,127,221(000c43,6),221(0050f2,2),48,htcap:000c,htagg:12,htmcs:000000ff,extcap:01000000|os:viziotv':
+        ('Vizio Smart TV', '', '2.4GHz'),
+    'wifi4|probe:0,1,50,221(0050f2,4),wps:Ralink_Wireless_Linux_Client|assoc:0,1,50,45,221(000c43,6),221(0050f2,2),48,htcap:000c,htagg:13,htmcs:000000ff|os:viziotv':
+        ('Vizio Smart TV', '', '2.4GHz'),
+    'wifi4|probe:0,1,50,48|assoc:0,1,50,221(0050f2,2),45,51,127,48,htcap:012c,htagg:1b,htmcs:000000ff,extcap:01|os:viziotv':
+        ('Vizio Smart TV', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,221(001018,2)|assoc:0,1,48,50,221(001018,2)|os:wii':
-        ('BCM4318', 'Wii', '2.4GHz'),
+        ('Wii', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,45,3,221(00904c,51),htcap:100c,htagg:19,htmcs:000000ff|assoc:0,1,48,50,45,221(00904c,51),221(0050f2,2),htcap:100c,htagg:19,htmcs:000000ff|os:wii':
-        ('BCM43362', 'Wii-U', '2.4GHz'),
-
-    'wifi4|probe:0,1,50,45,htcap:016e,htagg:03,htmcs:000000ff|assoc:0,1,48,50,221(0050f2,2),45,221(00904c,51),127,htcap:016e,htagg:03,htmcs:000000ff,extcap:0100008000000000|os:windows':
-        ('', 'Windows 802.11n PC', '2.4GHz'),
+        ('Wii-U', '', '2.4GHz'),
 
     'wifi4|probe:0,1,50,45,3,221(001018,2),221(00904c,51),htcap:110c,htagg:19,htmcs:000000ff|assoc:0,1,48,50,45,221(001018,2),221(00904c,51),221(0050f2,2),htcap:110c,htagg:19,htmcs:000000ff|oui:withings':
-        ('', 'Withings Scale', '2.4GHz'),
+        ('Withings Scale', '', '2.4GHz'),
 
     'wifi4|probe:0,1,3,45,50,127,htcap:010c,htagg:1b,htmcs:0000ffff,extcap:00|assoc:0,1,45,48,50,221(0050f2,2),htcap:010c,htagg:1b,htmcs:000000ff|oui:microsoft':
-        ('', 'Xbox', '5GHz'),
+        ('Xbox', '', '5GHz'),
     'wifi4|probe:0,1,3|assoc:0,1,48,33,36,221(0050f2,2),txpow:1405|oui:microsoft':
-        ('', 'Xbox', '5GHz'),
+        ('Xbox', '', '5GHz'),
     'wifi4|probe:0,1,3,45,50,htcap:016e,htagg:03,htmcs:0000ffff|assoc:0,1,33,48,50,127,221(0050f2,2),45,htcap:012c,htagg:03,htmcs:0000ffff,txpow:1208,extcap:0000000000000140|oui:microsoft':
-        ('', 'Xbox', '5GHz'),
+        ('Xbox', '', '5GHz'),
     'wifi4|probe:0,1,50|assoc:0,1,3,33,36,50,221(0050f2,2),45,221(00037f,1),221(00037f,4),48,htcap:104c,htagg:00,htmcs:000000ff,txpow:0f0f|oui:microsoft':
-        ('', 'Xbox', '2.4GHz'),
+        ('Xbox', '', '2.4GHz'),
     'wifi4|probe:0,1,50,48|assoc:0,1,3,33,36,50,221(0050f2,2),45,221(00037f,1),221(00037f,4),48,htcap:104c,htagg:00,htmcs:0000ffff,txpow:0f0f|oui:microsoft':
-        ('', 'Xbox', '2.4GHz'),
+        ('Xbox', '', '2.4GHz'),
     'wifi4|probe:0,1,45,50,htcap:058f,htagg:03,htmcs:0000ffff|assoc:0,1,33,36,48,221(0050f2,2),45,htcap:058f,htagg:03,htmcs:0000ffff,txpow:1208|oui:microsoft':
-        ('', 'Xbox', '2.4GHz'),
+        ('Xbox', '', '2.4GHz'),
     'wifi4|probe:0,1,3,50|assoc:0,1,33,48,50,127,127,221(0050f2,2),45,htcap:012c,htagg:03,htmcs:0000ffff,txpow:1208,extcap:0000000000000140|oui:microsoft':
-        ('', 'Xbox', '2.4GHz'),
+        ('Xbox', '', '2.4GHz'),
 
     'wifi4|probe:0,1,3,45,50,htcap:058f,htagg:03,htmcs:0000ffff|assoc:0,1,48,50,221(0050f2,2),45,htcap:058d,htagg:03,htmcs:0000ffff|oui:microsoft':
-        ('Marvell_88W8897', 'Xbox One', '2.4GHz'),
+        ('Xbox', 'One', '2.4GHz'),
     'wifi4|probe:0,1,45,50,htcap:058f,htagg:03,htmcs:0000ffff|assoc:0,1,48,50,221(0050f2,2),45,htcap:058d,htagg:03,htmcs:0000ffff|oui:microsoft':
-        ('Marvell_88W8897', 'Xbox One', '2.4GHz'),
+        ('Xbox', 'One', '2.4GHz'),
     'wifi4|probe:0,1|assoc:0,1,50,45,127,221(000c43,0),221(0050f2,2),33,48,htcap:008d,htagg:02,htmcs:0000ffff,txpow:0805,extcap:0100000000000000|oui:microsoft':
-        ('', 'Xbox One', '2.4GHz'),
+        ('Xbox', 'One', '2.4GHz'),
     'wifi4|probe:0,1,50|assoc:0,1,50,45,127,221(000c43,0),221(0050f2,2),33,48,htcap:008d,htagg:02,htmcs:0000ffff,txpow:0805,extcap:0100000000000000|oui:microsoft':
-        ('', 'Xbox One', '2.4GHz'),
+        ('Xbox', 'One', '2.4GHz'),
 
     'wifi4|probe:0,1,50,3,45,221(0050f2,8),htcap:012c,htagg:03,htmcs:000000ff|assoc:0,1,50,33,48,70,45,221(0050f2,2),htcap:012c,htagg:03,htmcs:000000ff,txpow:170d|oui:xiaomi':
-        ('', 'Xiaomi Redmi 3', '2.4GHz'),
+        ('Xiaomi Redmi', '3', '2.4GHz'),
+
+    'wifi4|probe:0,1,50,221(0050f2,4),221(506f9a,9),wps:Z820|assoc:0,1,50,45,48,127,221(0050f2,2),htcap:1172,htagg:03,htmcs:000000ff,extcap:01':
+        ('ZTE Obsidian', '', '2.4GHz'),
 }
 
 
@@ -1148,9 +1158,9 @@
     mac: MAC address of the client, a string of the form 'qq:rr:ss:tt:uu:vv'
 
   Returns:
-    A tuple describing the Wifi chipset and the type of device.
+    A tuple describing the model of the device.
 
-    If we know what it is, this will be (ChipName, ModelName, PerformanceInfo)
+    If we know what it is, this will be (Genus, Species, PerformanceInfo)
 
     If the signature is not known, calculate a SHA256 of the signature and
     return (SHA256, 'Unknown', PerformanceInfo)
diff --git a/waveguide/clientinfo_test.py b/waveguide/clientinfo_test.py
index e7471f3..df0ccd9 100755
--- a/waveguide/clientinfo_test.py
+++ b/waveguide/clientinfo_test.py
@@ -27,9 +27,9 @@
 def TaxonomyTest():
   taxonomy.dhcp.DHCP_LEASES_FILE = 'fake/dhcp.leases'
   clientinfo.FINGERPRINTS_DIR = 'fake/taxonomy'
-  wvtest.WVPASS(';Nexus 6;' in clientinfo.taxonomize('00:00:01:00:00:01'))
-  wvtest.WVPASS(';Nexus 6;' in clientinfo.taxonomize('00:00:01:00:00:01\n'))
-  v = ';Moto G or Moto X;'
+  wvtest.WVPASS('Nexus 6' in clientinfo.taxonomize('00:00:01:00:00:01'))
+  wvtest.WVPASS('Nexus 6' in clientinfo.taxonomize('00:00:01:00:00:01\n'))
+  v = 'Moto G or Moto X'
   wvtest.WVPASS(v in clientinfo.taxonomize('9c:d9:17:00:00:02'))
   wvtest.WVPASSEQ(clientinfo.taxonomize('00:00:22:00:00:22'), None)
 
diff --git a/wifi/quantenna.py b/wifi/quantenna.py
index 6c68029..33378ba 100755
--- a/wifi/quantenna.py
+++ b/wifi/quantenna.py
@@ -78,6 +78,9 @@
   if not interface:
     return False
 
+  if opt.encryption == 'WEP':
+    raise utils.BinWifiException('WEP not supported')
+
   if mode == 'scan':
     mode = 'sta'
     scan = True
@@ -88,7 +91,7 @@
   _qcsapi('restore_default_config', 'noreboot')
 
   config = {
-      'bw': opt.width,
+      'bw': opt.width if mode == 'ap' else 80,
       'channel': 149 if opt.channel == 'auto' else opt.channel,
       'mode': mode,
       'pmf': 0,
@@ -102,7 +105,7 @@
   if int(_qcsapi('is_startprod_done')):
     _qcsapi('reload_in_mode', 'wifi0', mode)
   else:
-    _qcsapi('startprod', 'wifi0')
+    _qcsapi('startprod')
     for _ in xrange(30):
       if int(_qcsapi('is_startprod_done')):
         break
@@ -113,20 +116,35 @@
   if mode == 'ap':
     _set_interface_in_bridge(opt.bridge, interface, True)
     _qcsapi('set_ssid', 'wifi0', opt.ssid)
-    _qcsapi('set_passphrase', 'wifi0', 0, os.environ['WIFI_PSK'])
+    if opt.encryption == 'NONE':
+      _qcsapi('set_beacon_type', 'wifi0', 'Basic')
+    else:
+      protocol, authentication, encryption = opt.encryption.split('_')
+      protocol = {'WPA': 'WPA', 'WPA2': '11i', 'WPA12': 'WPAand11i'}[protocol]
+      authentication += 'Authentication'
+      encryption += 'Encryption'
+      _qcsapi('set_beacon_type', 'wifi0', protocol)
+      _qcsapi('set_wpa_authentication_mode', 'wifi0', authentication)
+      _qcsapi('set_wpa_encryption_modes', 'wifi0', encryption)
+      _qcsapi('set_passphrase', 'wifi0', 0, os.environ['WIFI_PSK'])
     _qcsapi('set_option', 'wifi0', 'ssid_broadcast', int(not opt.hidden_mode))
     _qcsapi('rfenable', 1)
   elif mode == 'sta' and not scan:
     _set_interface_in_bridge(opt.bridge, interface, False)
     _qcsapi('create_ssid', 'wifi0', opt.ssid)
-    _qcsapi('ssid_set_passphrase', 'wifi0', opt.ssid, 0,
-            os.environ['WIFI_CLIENT_PSK'])
+    if opt.bssid:
+      _qcsapi('set_ssid_bssid', 'wifi0', opt.ssid, opt.bssid)
+    if opt.encryption == 'NONE' or not os.environ.get('WIFI_CLIENT_PSK'):
+      _qcsapi('ssid_set_authentication_mode', 'wifi0', opt.ssid, 'NONE')
+    else:
+      _qcsapi('ssid_set_passphrase', 'wifi0', opt.ssid, 0,
+              os.environ['WIFI_CLIENT_PSK'])
     # In STA mode, 'rfenable 1' is already done by 'startprod'/'reload_in_mode'.
     # 'apply_security_config' must be called instead.
     _qcsapi('apply_security_config', 'wifi0')
 
     for _ in xrange(10):
-      if _qcsapi('get_bssid', 'wifi0') != '00:00:00:00:00:00':
+      if _qcsapi('get_ssid', 'wifi0'):
         break
       time.sleep(1)
     else:
@@ -177,7 +195,8 @@
   if not _get_interface():
     return False
 
-  if _qcsapi('get_mode', 'wifi0') == 'Access point':
+  if (int(_qcsapi('is_startprod_done')) and
+      _qcsapi('get_mode', 'wifi0') == 'Access point'):
     _qcsapi('rfenable', 0)
 
   return True
@@ -188,7 +207,8 @@
   if not _get_interface():
     return False
 
-  if _qcsapi('get_mode', 'wifi0') == 'Station':
+  if (int(_qcsapi('is_startprod_done')) and
+      _qcsapi('get_mode', 'wifi0') == 'Station'):
     _qcsapi('rfenable', 0)
 
   return True
diff --git a/wifi/quantenna_test.py b/wifi/quantenna_test.py
index e19c76e..ebef2a0 100755
--- a/wifi/quantenna_test.py
+++ b/wifi/quantenna_test.py
@@ -20,9 +20,9 @@
 def fake_qcsapi(*args):
   calls.append([str(x) for x in args])
   if args[0] == 'is_startprod_done':
-    return '1' if ['startprod', 'wifi0'] in calls else '0'
-  if args[0] == 'get_bssid':
-    return '00:11:22:33:44:55'
+    return '1' if ['startprod'] in calls else '0'
+  if args[0] == 'get_ssid':
+    return calls[matching_calls_indices(['set_ssid', 'create_ssid'])[-1]][1]
   if args[0] == 'get_mode':
     i = [c for c in matching_calls_indices(['update_config_param'])
          if calls[c][2] == 'mode']
@@ -126,7 +126,7 @@
 
   # 'update_config_param' and 'set_mac_addr' must be run before 'startprod',
   # since 'startprod' runs scripts that read these configs.
-  sp = calls.index(['startprod', 'wifi0'])
+  sp = calls.index(['startprod'])
   i = matching_calls_indices(['update_config_param', 'set_mac_addr'])
   wvtest.WVPASSLT(i[-1], sp)
 
@@ -161,7 +161,7 @@
   wvtest.WVPASSEQ(calls[1], ['restore_default_config', 'noreboot'])
 
   # Check that 'startprod' is not run.
-  wvtest.WVPASS(['startprod', 'wifi0'] not in calls)
+  wvtest.WVPASS(['startprod'] not in calls)
 
   # Check that configs are written.
   wvtest.WVPASS(['update_config_param', 'wifi0', 'bw', '80'] in calls)
diff --git a/wifi/wifi.py b/wifi/wifi.py
index 5531eee..241d626 100755
--- a/wifi/wifi.py
+++ b/wifi/wifi.py
@@ -1014,9 +1014,14 @@
   """
   global lockfile_taken
 
+  serial = 'UNKNOWN'
+  try:
+    serial = subprocess.check_output(('serial')).strip()
+  except subprocess.CalledProcessError:
+    utils.log('Could not get serial number')
+
   optspec = _OPTSPEC_FORMAT.format(
-      bin=__file__.split('/')[-1],
-      ssid='%s_TestWifi' % subprocess.check_output(('serial')).strip())
+      bin=__file__.split('/')[-1], ssid='%s_TestWifi' % serial)
   parser = options.Options(optspec)
   opt, _, extra = parser.parse(argv)
   stringify_options(opt)