summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbtscan.py305
-rw-r--r--gpspoller.py6
-rw-r--r--testreceive.pd42
-rw-r--r--ttg01.xml4
-rwxr-xr-xwim.py27
5 files changed, 353 insertions, 31 deletions
diff --git a/btscan.py b/btscan.py
new file mode 100755
index 0000000..b183816
--- /dev/null
+++ b/btscan.py
@@ -0,0 +1,305 @@
+#!/usr/bin/python
+
+import bluetooth
+import select, socket, struct, os, time, random, shelve
+from threading import Thread
+
+#take out the osc stuff initially
+#change it to be run as a thread by wim
+#could have a bt_event function
+#and a gps_event function
+#saving a bit of processing
+import socket
+outsock = socket.socket( socket.AF_INET,socket.SOCK_DGRAM )
+
+import bluetooth._bluetooth as _bt
+#import the .so
+
+def debug(m):
+ print m
+
+def _gethcisock (device_id = -1):
+ try:
+ sock = _bt.hci_open_dev (device_id)
+ return sock
+ except:
+ debug("error accessing bluetooth device")
+ exit(0)
+
+
+class Devicemanager:
+ def __init__(s,log=False,host='127.0.0.1',port=9000):
+ s.devices={}
+ s.logi=0
+ s.now=time.time()
+ s.logging=log
+ s.host=host
+ s.port=port
+ s.triggers={}
+ def msg(s,message):
+ outsock.sendto(str(message[0])+' '+str(message[1])+'\n', (s.host, s.port))
+
+ def dolog(s,o):
+ log=shelve.open('s_btlog')
+ log[str(s.logi)]=o
+ log[str(s.logi)+'int']=time.time()-s.now
+ s.now=time.time()
+ log.close()
+ s.logi+=1
+ def play(s,e):
+ if e[0]=='discovered':
+ s.discovered(e[1],e[2],e[3])
+ elif e[0]=='name':
+ s.name_found(e[1],e[2])
+ elif e[0]=='complete':
+ s.inquiry_complete()
+ def discovered(s, address, device_class='',rssi=0):
+ if not address in s.devices:
+ s.devices[address]=True
+ if (debug):
+ print "wim: found:",address
+ if address in s.triggers:
+ s.msg(s.triggers[address])
+ if (debug):
+ print "wim: sending",str(s.triggers[address][0]),str(s.triggers[address][1])
+ def name_found(s,address,name):
+ #catch for log
+ if address not in s.devices:
+ s.discovered(address)
+ #s.devices[address].foundname(name)
+ #if s.logging:
+ # s.dolog(['name',address, name])
+ def inquiry_complete(s):
+ num=0
+ devs="";
+ #for i in s.devices:
+ # if s.devices[i].checklost():
+ # num +=1
+ # if num>1:
+ # devs+=","
+ # devs+=s.devices[i].name
+ #if s.logging:
+ # s.dolog(['complete'])
+
+ #print num,"bluetooth devices (",devs,")"
+ #s.msg("bt",[num])
+
+
+class MyDiscoverer(bluetooth.DeviceDiscoverer):
+
+ def __init__ (s,host='127.0.0.1',port=9000):
+ s.sock = None
+ s.is_inquiring = False
+ s.lookup_names = False
+ s.names_to_find = {}
+ s.names_found = {}
+ s.dm=Devicemanager(False,host,port)
+
+ def pre_inquiry(s):
+ s.done = False
+
+ def device_discovered(s, address, device_class,rssi=0):
+ s.dm.discovered(address, device_class,rssi=0)
+
+ def name_found(s,address,name):
+ s.dm.name_found(address,name)
+
+ def inquiry_complete(s):
+ s.dm.inquiry_complete()
+ s.done = True
+
+ def find_devices (s, lookup_names=True, duration=8, flush_cache=True):
+ if s.is_inquiring:
+ raise BluetoothError ("Already inquiring!")
+
+ s.lookup_names = lookup_names
+
+ s.sock = _gethcisock ()
+ flt = _bt.hci_filter_new ()
+ _bt.hci_filter_all_events (flt)
+ _bt.hci_filter_set_ptype (flt, _bt.HCI_EVENT_PKT)
+
+ try:
+ s.sock.setsockopt (_bt.SOL_HCI, _bt.HCI_FILTER, flt)
+ except:
+ raise BluetoothError ("problem with local bluetooth device.")
+
+ # send the inquiry command
+ max_responses = 255
+ cmd_pkt = struct.pack ("BBBBB", 0x33, 0x8b, 0x9e, \
+ duration, max_responses)
+
+ s.pre_inquiry ()
+
+ try:
+ _bt.hci_send_cmd (s.sock, _bt.OGF_LINK_CTL, \
+ _bt.OCF_INQUIRY, cmd_pkt)
+ except:
+ raise BluetoothError ("problem with local bluetooth device.")
+
+ s.is_inquiring = True
+
+ s.names_to_find = {}
+ #s.names_found = {}
+
+ def _process_hci_event (s):
+
+ if s.sock is None: return
+ # voodoo magic!!!
+ pkt = s.sock.recv (255)
+ ptype, event, plen = struct.unpack ("BBB", pkt[:3])
+ pkt = pkt[3:]
+ if event == _bt.EVT_INQUIRY_RESULT:
+ nrsp = struct.unpack ("B", pkt[0])[0]
+ for i in range (nrsp):
+ addr = _bt.ba2str (pkt[1+6*i:1+6*i+6])
+ psrm = pkt[ 1+6*nrsp+i ]
+ pspm = pkt[ 1+7*nrsp+i ]
+ devclass_raw = struct.unpack ("BBB",
+ pkt[1+9*nrsp+3*i:1+9*nrsp+3*i+3])
+ devclass = (devclass_raw[2] << 16) | \
+ (devclass_raw[1] << 8) | \
+ devclass_raw[0]
+ clockoff = pkt[1+12*nrsp+2*i:1+12*nrsp+2*i+2]
+
+ if addr not in s.names_found and addr not in s.names_to_find:
+ s.names_to_find[addr] = (devclass, psrm, pspm, clockoff)
+ s.device_discovered (addr, devclass)
+ elif event == _bt.EVT_INQUIRY_RESULT_WITH_RSSI:
+ nrsp = struct.unpack ("B", pkt[0])[0]
+ for i in range (nrsp):
+ addr = _bt.ba2str (pkt[1+6*i:1+6*i+6])
+ psrm = pkt[ 1+6*nrsp+i ]
+ pspm = pkt[ 1+7*nrsp+i ]
+ # devclass_raw = pkt[1+8*nrsp+3*i:1+8*nrsp+3*i+3]
+ # devclass = struct.unpack ("I", "%s\0" % devclass_raw)[0]
+ devclass_raw = struct.unpack ("BBB",
+ pkt[1+8*nrsp+3*i:1+8*nrsp+3*i+3])
+ devclass = (devclass_raw[2] << 16) | \
+ (devclass_raw[1] << 8) | \
+ devclass_raw[0]
+ clockoff = pkt[1+11*nrsp+2*i:1+11*nrsp+2*i+2]
+ rssi = struct.unpack ("b", pkt[1+13*nrsp+i])[0]
+ #print "%s rssi: %i" % (addr, rssi)
+ if addr not in s.names_found and addr not in s.names_to_find:
+ s.names_to_find[addr] = (devclass, psrm, pspm, clockoff)
+ s.device_discovered (addr, devclass,rssi)
+ #s.signalstrength(addr,rssi)
+ elif event == _bt.EVT_INQUIRY_COMPLETE:
+ s.is_inquiring = False
+ if len (s.names_to_find) == 0:
+ # print "inquiry complete (evt_inquiry_complete)"
+ s.sock.close ()
+ s.inquiry_complete ()
+ else:
+ s._send_next_name_req ()
+
+ elif event == _bt.EVT_CMD_STATUS:
+ # XXX shold this be "<BBH"
+ status, ncmd, opcode = struct.unpack ("BBH", pkt[:4])
+ if status != 0:
+ s.is_inquiring = False
+ s.sock.close ()
+
+ # print "inquiry complete (bad status 0x%X 0x%X 0x%X)" % \
+ # (status, ncmd, opcode)
+ s.names_to_find = {}
+ s.inquiry_complete ()
+ elif event == _bt.EVT_REMOTE_NAME_REQ_COMPLETE:
+ status = struct.unpack ("B", pkt[0])[0]
+ addr = _bt.ba2str (pkt[1:7])
+ if status == 0:
+ try:
+ name = pkt[7:].split ('\0')[0]
+ except IndexError:
+ name = ''
+ if addr in s.names_to_find:
+ device_class = s.names_to_find[addr][0]
+ s.names_found[addr] = ( device_class, name)
+ #s.device_discovered (addr, device_class, name)
+ del s.names_to_find[addr]
+ s.name_found(addr,name)
+ else:
+ pass
+ else:
+ if addr in s.names_to_find: del s.names_to_find[addr]
+ # XXX should we do something when a name lookup fails?
+ # print "name req unsuccessful %s - %s" % (addr, status)
+
+ if len (s.names_to_find) == 0:
+ s.is_inquiring = False
+ s.sock.close ()
+ s.inquiry_complete ()
+ # print "inquiry complete (name req complete)"
+ else:
+ s._send_next_name_req ()
+ else:
+ pass
+ # print "unrecognized packet type 0x%02x" % ptype
+
+class scanner(Thread):
+ def __init__ (s,host="127.0.0.1",port=9000,log=False):
+ s.host=host
+ s.port=port
+ s.d = MyDiscoverer(s.host,s.port)
+ s.simulate=False
+ Thread.__init__(s)
+ s.active=True
+ s.kill=False
+
+ def control(s,*msg):
+ x,y=msg
+ if x[2]=="sim":
+ s.devices={}
+ s.simulate=(x[3]==1)
+ if x[2]=="active":
+ s.active=(x[3]==1)
+ def run(s):
+ sock = _gethcisock ()
+ if sock is None:
+ print "bt scanner: no bluetooth"
+ exit(0)
+ else:
+ s.d.find_devices(lookup_names = False)
+ readfiles = [ s.d, ]
+
+ while not s.kill:
+ if s.active:
+ if s.simulate:
+ print "simulating bluetooth.."
+ try:
+ f=shelve.open('btlog')
+ except:
+ print "bt log not found."
+ break
+ while s.active and s.simulate:
+ i=1
+ n=len(f.dict.keys())
+ while i<n and s.active and s.simulate:
+ event=f[str(i)]
+ s.d.dm.play(event)
+ i+=1
+ time.sleep(f[str(i)+'int'])
+ f.close()
+
+ else:
+ rfds = select.select( readfiles, [], [] )[0]
+ if s.d in rfds:
+ s.d.process_event()
+ if s.d.done:
+ s.d.find_devices(lookup_names = False)
+ else:
+ time.sleep(1)
+
+def main():
+ sock = _gethcisock ()
+ if sock is None:
+ print "no bluetooth"
+ exit(0)
+ else:
+ scan=scanner("127.0.0.1",5401,False)
+ scan.start()
+ while True:
+ pass
+
+if __name__ == '__main__': main()
diff --git a/gpspoller.py b/gpspoller.py
index 13ad5bb..37cd441 100644
--- a/gpspoller.py
+++ b/gpspoller.py
@@ -16,6 +16,7 @@ class GpsPoller(threading.Thread):
changed = False
fix=0
satellites=0
+ gps =""
def __init__(self,port,test=False):
self.test=test
@@ -88,8 +89,9 @@ class GpsPoller(threading.Thread):
except StopIteration:
pass
- def __del__():
- self.gps.close()
+ def __del__(self):
+ if self.gps!="":
+ self.gps.close()
if __name__ == '__main__':
diff --git a/testreceive.pd b/testreceive.pd
index 1376a6c..aa1d7e1 100644
--- a/testreceive.pd
+++ b/testreceive.pd
@@ -1,22 +1,28 @@
-#N canvas 210 148 450 300 10;
+#N canvas 892 475 529 348 10;
#X msg 29 61 /pd 1;
#X msg 82 26 /other 1;
#X obj 169 50 netreceive 5401 1;
-#X obj 145 210 print play;
-#X obj 352 172 print other;
-#X obj 148 140 route play cc01 gpsstatus;
-#X obj 212 217 print cc01;
-#X msg 296 204 set \$1;
-#X floatatom 301 244 5 0 0 0 - - -;
-#X obj 344 39 loadbang;
-#X msg 341 86 set 0;
-#X connect 0 0 5 0;
-#X connect 1 0 5 0;
-#X connect 2 0 5 0;
-#X connect 5 0 3 0;
-#X connect 5 1 6 0;
-#X connect 5 2 7 0;
-#X connect 5 3 4 0;
+#X obj 73 219 print play;
+#X obj 140 226 print cc01;
+#X msg 212 215 set \$1;
+#X floatatom 215 283 5 0 0 0 - - -;
+#X obj 225 237 loadbang;
+#X msg 224 260 set 0;
+#X obj 148 140 route play cc01 gps bt;
+#X obj 307 188 print bt;
+#X obj 194 184 route status;
+#X obj 294 239 print gps;
+#X obj 322 162 print other;
+#X connect 0 0 9 0;
+#X connect 1 0 9 0;
+#X connect 2 0 9 0;
+#X connect 5 0 6 0;
#X connect 7 0 8 0;
-#X connect 9 0 10 0;
-#X connect 10 0 8 0;
+#X connect 8 0 6 0;
+#X connect 9 0 3 0;
+#X connect 9 1 4 0;
+#X connect 9 2 11 0;
+#X connect 9 3 10 0;
+#X connect 9 4 13 0;
+#X connect 11 0 5 0;
+#X connect 11 1 12 0;
diff --git a/ttg01.xml b/ttg01.xml
index 0effeb3..6fc0880 100644
--- a/ttg01.xml
+++ b/ttg01.xml
@@ -17,7 +17,9 @@
</scale>
</gps>
<bt freq="10">
- <trigger id="00:11:95:00:1A:CF" command="play" param="i01.wav">
+ <trigger id="00:1A:7D:0A:BA:C3" command="play" param="i01.wav">
+ </trigger>
+ <trigger id="50:EA:D6:A6:7F:DD" command="play" param="i02.wav">
</trigger>
</bt>
</tomorrowtheground> \ No newline at end of file
diff --git a/wim.py b/wim.py
index ccc0ac8..e8f6c78 100755
--- a/wim.py
+++ b/wim.py
@@ -5,7 +5,7 @@ import signal,sys
def signal_handler(signal, frame):
insock.close()
- print "tomorrowtheground: interrupted"
+ print "wim: tomorrowtheground: interrupted"
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
@@ -16,7 +16,7 @@ from xml2obj import *
if len(sys.argv)<2:
- print "usage: tomorrowtheground configfile [-D] (debug)]"
+ print "wim: usage: tomorrowtheground configfile [-D] (debug)]"
debug=False
if len(sys.argv)>2:
@@ -37,9 +37,9 @@ try:
g.triggers.append(trigger(int(t.id),t.command,t.param))
gpslayers.append(g)
except:
- print "error parsing xml index entry"
+ print "wim: error parsing xml index entry"
except:
- print "no index layers found"
+ print "wim: no index layers found"
#catch invalid xml
try:
@@ -50,9 +50,9 @@ try:
g.setcommand(i.command)
gpslayers.append(g)
except:
- print "error parsing xml index entry"
+ print "wim: error parsing xml index entry"
except:
- print "no scale layers found"
+ print "wim: no scale layers found"
from gpspoller import *
gpsp=""
@@ -61,7 +61,14 @@ try:
gpsp = GpsPoller(doc.gpsdevice)
gpsp.start()
except:
- print "gps device not found"
+ print "wim: gps device not found"
+
+from btscan import *
+
+scan=scanner("127.0.0.1",5401,False)
+for t in doc.bt.trigger:
+ scan.d.dm.triggers[t.id]=(t.command,t.param)
+scan.start()
import socket
@@ -86,7 +93,7 @@ while True:
data, addr = insock.recvfrom(128)
pos.parse(data)
if debug:
- print "received:",data
+ print "wim: received:",data
posChanged=True
except:
nothing=None
@@ -102,7 +109,7 @@ while True:
check=gpsp.check()
if check!=False:
if debug:
- print "received from gps",check[0],check[1]
+ print "wim: received from gps",check[0],check[1]
pos=latLng(check[0],check[1])
posChanged=True
if posChanged:
@@ -111,7 +118,7 @@ while True:
r=layer.checkcoord(pos) #returns a message or None
if r!=None:
if (debug):
- print "sending:",str(r[0]),str(r[1])
+ print "wim: sending:",str(r[0]),str(r[1])
#pd needs \n at end of message
outsock.sendto( str(r[0])+' '+str(r[1])+'\n', (PD_IP, PD_PORT) )