Having captured a few WiFi hot spots while driving around I wanted to export these hotspots to a KML file that I could then import into Google Maps. There are applications and scripts to do this but I decided to have a go a creating something myself. As I am currently learning Python and in my opinion the best way to learn a new language is by doing then Python was my first choice for this. I am by no means a Python expert and there will be better ways of doing this I am sure.
The first step is to open the Kismet XML file for parsing. The simplest way I found was to use an ElementTree.
import sys
import xml.etree.ElementTree as Etree
# Open the XML file
tree = Etree.parse("test.netxml")
root = tree.getroot()
Next we need to parse the child nodes looking specifically for the “wireless-network” tag. From there we can parse each sub element to extract the information we are interested in. Including the SSID, MAC address, location etc.
for child in root:
# If new network entry
if child.tag == "wireless-network":
essid = ""
bssid = ""
encryption = []
gpslat = ""
gpslng = ""
# Iterate through child elements
for element in child:
# SSID element
if element.tag == "SSID":
# Interate through each sub element
for subelement in element:
# Found encryption type add it to the list
if subelement.tag == "encryption":
encryption.append(str(subelement.text))
# Found SSID save it
elif subelement.tag == "essid":
essid = str(subelement.text)
# BSSID element contains MAC address save it
if element.tag == "BSSID":
bssid = str(element.text)
# Location fix element
if element.tag == "gps-info":
for gps in element:
# Extract latitude
if gps.tag == "avg-lat":
gpslat = str(gps.text)
# Extract longitude
if gps.tag == "avg-lon":
gpslng = str(gps.text)
# Sort encryption list
encryption.sort()
With the input file parsed we move on to exporting the results to a KML file. For this I used the SimpleKML python library. SimpleKML makes working with KML files a breeze.
import simplekml
# Create an instance if simplekml
kml = simplekml.Kml()
# Add a new point
kml.newpoint(name=essid, description=bssid + " " +
' '.join(encryption), coords=[(gpslng, gpslat)])
# Now save it
kml.save("output.kml")
That’s the basics covered. Time to add some features. One thing I wanted was to be able to filter hotspots found within a specific radius of a given point. For instance if you only wanted to save hotspots within a mile of your house you could enter you home location and set a search radius of one mile. The resulting KML file would then only contain hotspots that fell within that radius. For this we can use the Haversine formula. The Haversine formula determines the great-circle distance between two points on a sphere (in this case the earth) given their longitudes and latitudes. There is also happens to be a nice little Haversine python library.
from haversine import haversine
home = (45.7597, 4.8422)
dest = (48.8567, 2.3508)
distance = haversine(home, dest, unit='mi')
if distance > 1.0:
print ("Greater than 1.0 miles!")
More features were then added including/excluding specific SSID’s, specifying certain authentication types, specifying the output file etc all of which are passed as arguments to the script.
My resulting netxml2kml script can be seen below:-
#!/usr/bin/env python3
import sys
import xml.etree.ElementTree as Etree
import os.path
import simplekml
import argparse
from haversine import haversine
# python netxml2kml.py test4.netxml output.kml -r 5.0 -x 45.7597 -y 4.8422 -s
# python netxml2kml.py test4.netxml output.kml -i Raspberry -s
# python netxml2kml.py test4.netxml output.kml -e Raspberry -s
# python netxml2kml.py test4.netxml output.kml -a WEP -s
def str2bool(v):
if v.lower() in ('yes', 'true', 't', 'y', '1'):
return True
elif v.lower() in ('no', 'false', 'f', 'n', '0'):
return False
else:
raise argparse.ArgumentTypeError('Boolean value expected.')
parser = argparse.ArgumentParser(description='Convert Kismet Net XML to KML file.')
parser.add_argument("input_file", help="the Net XML file to be converted.")
parser.add_argument("output_file", help="the KML output file.")
parser.add_argument("-e", "--exclude", default="", help="exclude SSID string.")
parser.add_argument("-i", "--include", default="", help="include SSID string.")
parser.add_argument("-a", "--auth", default="", help="include search authentication string.")
parser.add_argument("-r", "--radius", type=float, default=0.0, help="include radius")
parser.add_argument("-x", "--lat", type=float, default=45.7597, help="start latitude")
parser.add_argument("-y", "--lon", type=float, default=4.8422, help="start longitude")
parser.add_argument("-s", "--show", type=str2bool, nargs='?', const=True, default=False, help="Show output entries.")
args = parser.parse_args()
def do_extraction(filename: str, output: str, exclude: str, include: str, auth: str, show: bool, radius: int,
lat: float, lon: float) -> int:
if os.path.exists(filename) is False:
print("Cannot find input file \"%s\"" % filename)
sys.exit(1)
print("Opening file \"%s\"" % filename)
print("Saving to file \"%s\"" % output)
tree = Etree.parse(filename)
root = tree.getroot()
kml = simplekml.Kml()
print("Extracting entries...")
found = 0
for child in root:
if child.tag == "wireless-network":
essid = ""
bssid = ""
encryption = []
gpslat = ""
gpslng = ""
for element in child:
if element.tag == "SSID":
for subelement in element:
if subelement.tag == "encryption":
encryption.append(str(subelement.text))
elif subelement.tag == "essid":
essid = str(subelement.text)
if element.tag == "BSSID":
bssid = str(element.text)
if element.tag == "gps-info":
for gps in element:
if gps.tag == "avg-lat":
gpslat = str(gps.text)
if gps.tag == "avg-lon":
gpslng = str(gps.text)
encryption.sort()
valid = True
if radius > 0.0:
if gpslat and gpslng:
home = (lat, lon)
dest = (float(gpslat), float(gpslng))
dist = haversine(home, dest, unit='mi')
if dist > radius:
valid = False
if include and essid.find(include) = 0:
valid = False
if auth and auth not in encryption:
valid = False
if valid:
found += 1
kml.newpoint(name=essid, description=bssid + " " + ' '.join(encryption), coords=[(gpslng, gpslat)])
if show:
print(essid + "," + bssid + "," + ' '.join(encryption) + "," + gpslat + "," + gpslng)
kml.save(output)
print("Extracted %d entries." % found)
return found
if __name__ == "__main__":
ret = do_extraction(args.input_file, args.output_file, args.exclude, args.include, args.auth, args.show,
args.radius, args.lat, args.lon)










Not only did it support traditional JTAG debugging but also debugWIRE. Atmels own propriety debug protocol aimed at low resource devices such as the ATMega88/168/328 family. I purchased the Atmel ICE basic kit. The kit consists of the Atmel ICE and a 10 pin ribbon cable to 10 to pin JTAG (0.05″ pitch) and 6 pin (0.1″ pitch) SPI connector. The full kit available at a much greater cost shipped with a number of different cables and adaptors. As debugWIRE uses the RESET line for debugging I deemed the 6 pin SPI cable would be all I needed. Or so I thought.

Using
In order to minimise the wiring somewhat I built a little interface board between the display, the switches and the header on the Raspberry Pi. I added a small potentiometer to the interface board to allow the overall volume to be configured.













