import os import time import random import logging from urllib import urlopen, urlencode import thread from collections import defaultdict log = logging.getLogger() INTERVALL = 3 MAX_INTERVALL = 100 #~ LWS_ADDRESS = 'http://loco.visual-library.de' LWS_ADDRESS = 'http://127.0.0.1:20080' INTERESTING_SSIDS = set(['']) # ALL # for virtual device to replay measurements ID2MAC = {'107': '00:22:15:21:b0:c2', '108': '00:22:15:24:25:97', '109p2': '00:22:15:26:ad:c2', '114': '00:22:15:26:ac:ee', '104': '00:0f:a3:11:17:9a', '106': '00:22:15:22:51:18', '110p2': '00:22:15:26:ac:eb', 'edueg031': '00:17:df:a8:1b:41', 'eduegdemo': '00:17:df:a8:19:91', 'eduegcorr1': '00:17:df:a8:19:e1', 'eduegcorr2': '00:17:df:a7:e8:0d', 'eduog1108': '00:17:df:a8:03:21', 'eduog1server': '00:17:df:a7:e8:e1', 'eduog2206': '00:17:df:a8:a4:f1', 'eduog2kitchen': '00:17:df:a7:e9:31', 'eduog2corr': '00:17:df:a7:ea:f1', 'gaia': '00:23:69:b9:af:45', 'iris': '00:23:69:c2:67:1f', 'hyperion': '00:23:69:b9:aa:29', 'freya': '00:23:69:b9:a9:8d', '171': '00:12:17:cb:f8:26', '172': '00:0f:66:90:45:12',} def android(droid): ''' uses android API for wifi signals''' def _inner(): scandata = {} try: startscan_result = droid.wifiStartScan().result res = droid.wifiGetScanResults().result except Exception: log.exception('error during accessing wifi api') return scandata for scanres in res: if not any(e in scanres['ssid'].lower() for e in INTERESTING_SSIDS): continue scandata[scanres['bssid']] = {'rssi': scanres['level'], 'ts': time.time(), 'ssid': scanres['ssid']} return scandata return _inner def pcap(): ''' uses PCAP API for wifi signals''' from scapy.all import sniff from ieee_802_11_radio import Packet listPackets = sniff(iface='wlan1', timeout=0.11) def _inner(): scandata = {} for channelN in [1,4,7,10,13,2,5,8,11,3,6,9,12]: os.system("iwconfig "+ 'wlan1' +" channel "+ str(channelN)) for packet in listPackets: packetDecode = Packet(str(packet), packet) if packetDecode.prsntDbmSignal and packetDecode.prsntManagement: mac = packetDecode.AdrTranmitter ssid = packetDecode.SSID channel = packetDecode.Channel if not any(e in ssid.lower() for e in INTERESTING_SSIDS): continue if channel != channelN: continue rssi = packetDecode.DbmSignal #~ print mac, ssid, channel, rssi scandata[mac] = {'rssi': rssi, 'ts': time.time(), 'ssid': ssid} return scandata return _inner def virtual(datafile, pushfactor=1, buffer=1, filter=None): ''' virtual device, pumps data from measurement file''' state = {'i': 0, 'forward': True, 'lastts': 0} lines = open(datafile).read().strip().split('\n') def _inner(): scandata = defaultdict(list) for j in range(buffer): i = state['i'] s = lines[i] if state['forward']: if i < len(lines) - 1: i += 1 else: state['forward'] = not state['forward'] else: if i > 0: i -= 1 else: state['forward'] = not state['forward'] state['i'] = i data = [e.split(':') for e in s.split()] delay = 0 pos = None for name, value in data: if name == 'ts': delay = abs(float(value) - state['lastts']) state['lastts'] = float(value) elif name == 'pos': pos = [float(e) for e in value.split(',')] else: if filter is not None: if not any(e in name for e in filter): continue # its an rssi value ssid = name # this is not really correct but we dont have a ssid stored rssi = value mac = ID2MAC.get(name, name) d = {'rssi': float(rssi), 'ts': time.time(), 'ssid': ssid} if pos is not None: d['pos'] = pos scandata[mac].append(d) time.sleep(delay / pushfactor) return scandata return _inner def communicate(url, post_params): t = time.time() log.info('transmitting...') try: #~ print url, urlencode(post_params) #~ print post_params return urlopen(url, data=urlencode(post_params)).read() except Exception: log.exception('error during communication') finally: log.info('... in %.3f sec' % (time.time() - t)) def main(stationname, maxiter, iterlength, datafunc): url = '%s/%s/%s' % (LWS_ADDRESS, 'initDevice', stationname) log.info('fetching device cfg from %s' % url) cfg = urlopen(url).read() log.info('got: %s' % cfg) threaded, iterlength = cfg.split() threaded = threaded == 'true' iterlength = float(iterlength) log.info('threaded: %s, iterlength: %s' % (threaded, iterlength)) def buildRecord(v): res = {'bssid': bssid, 'rssi': v['rssi'], 'ts': v['ts'], 'ssid': v['ssid'], } if 'pos' in v: res['pos'] = v['pos'] return res url = '%s/%s' % (LWS_ADDRESS, 'newData') for i in range(maxiter): log.info('scan %s of %s' % (i+1, maxiter)) scandata = datafunc() # convert to list of dicts _scandata = [] for bssid, values in sorted(scandata.items()): if isinstance(values, list): # multiple values for this macaddr=bssid for _values in values: #~ log.debug('%s/%s: %.1f' % (_values['ssid'], bssid, _values['rssi'])) _scandata.append(buildRecord(_values)) else: #~ log.debug('%s/%s: %.1f' % (values['ssid'], bssid, values['rssi'])) _scandata.append(buildRecord(values)) post_params = [('name', stationname), ('data', str(_scandata))] if threaded: thread.start_new_thread(communicate, (url, post_params)) else: communicate(url, post_params) time.sleep(iterlength) if __name__ == '__main__': logging.basicConfig(level=logging.DEBUG) #~ main('messbook', 20, 3, pcap()) #~ main('iconia', 20000, 0, virtual(r'D:\loco-dev\dirk\tests\data\synthetic\measurements_0.txt', 1, 1, filter={'107', '108'})) main('iconia', 20000, 0, virtual(r'D:\loco-dev\dirk\tmp\tracked_path_synthetic\sigma_8.0\og1_long_rooms\measurements_00.txt', pushfactor=15, buffer=1, filter=None)) #~ main('iconia', 20000, 0, virtual(r'D:\loco-dev\dirk\tmp\tracked_path_synthetic\sigma_8.0\og1_long_rooms\measurements_00.txt', #~ pushfactor=15, buffer=1, filter=None))