Package barobo :: Module _comms
[hide private]
[frames] | no frames]

Source Code for Module barobo._comms

  1  #!/usr/bin/env python 
  2   
  3  import socket 
  4  try: 
  5      import serial 
  6      havePySerial = True 
  7  except: 
  8      havePySerial = False 
  9  import threading 
 10  import struct 
 11  import time 
 12  import barobo 
 13   
 14  import ctypes 
 15  import ctypes.util 
 16  import os 
 17  import sys 
 18   
 19  haveSFP = False 
 20  try: 
 21      from sys import platform as platform 
 22      if "win32" == platform: 
 23          for p in sys.path: 
 24              fname = os.path.join(p, "barobo/lib/libsfp.dll") 
 25              if os.path.isfile(fname): 
 26                  _sfp = ctypes.CDLL(fname) 
 27                  haveSFP = True 
 28                  break 
 29      else: 
 30          for p in sys.path: 
 31              fname = os.path.join(p, "barobo/lib/libsfp.so") 
 32              if os.path.isfile(fname): 
 33                  _sfp = ctypes.CDLL(fname) 
 34                  haveSFP = True 
 35                  break 
 36      # This is the only enum value in libsfp's header that we need 
 37      _SFP_WRITE_MULTIPLE = 1 
 38  except: 
 39      haveSFP = False 
 40   
 41  DEBUG=False 
 42   
43 -class Packet:
44 - def __init__(self, data=None, addr=None):
45 self.data = data 46 self.addr = addr
47
48 - def __getitem__(self, key):
49 return self.data[key]
50
51 - def __len__(self):
52 return len(self.data)
53 54 if havePySerial:
55 - class PhysicalLayer_TTY(serial.Serial):
56 - def __init__(self, ttyfilename):
57 serial.Serial.__init__(self, ttyfilename, baudrate=230400) 58 time.sleep(1) 59 self.stopbits = serial.STOPBITS_TWO 60 self.timeout = None
61
62 - def disconnect(self):
63 self.close() 64 pass
65
66 -class PhysicalLayer_Socket(socket.socket):
67 - def __init__(self, hostname, port):
68 socket.socket.__init__(self) 69 self.connect((hostname, port))
70
71 - def disconnect(self):
72 self.close()
73
74 - def flush(self):
75 pass
76 - def flushInput(self):
77 pass
78 - def flushOutput(self):
79 pass
80
81 - def read(self):
82 # Read and return a single byte 83 return self.recv(1)
84
85 - def write(self, packet):
86 self.sendall(packet)
87 88 import sys 89 if sys.version_info[0] >= 3 and sys.version_info[1] >= 3: 90 # We can use sockets for Bluetooth 91 import socket
92 - class PhysicalLayer_Bluetooth():
93 - def __init__(self, bluetooth_mac_addr):
94 self.sock = socket.socket( 95 socket.AF_BLUETOOTH, 96 socket.SOCK_STREAM, 97 socket.BTPROTO_RFCOMM) 98 self.sock.connect((bluetooth_mac_addr, 1))
99
100 - def disconnect(self):
101 self.sock.close()
102
103 - def flush(self):
104 pass
105 - def flushInput(self):
106 pass
107 - def flushOutput(self):
108 pass
109 - def read(self):
110 return self.sock.recv(1)
111 - def write(self, packet):
112 self.sock.sendall(packet)
113 114 else: 115 try: 116 import bluetooth
117 - class PhysicalLayer_Bluetooth(bluetooth.BluetoothSocket):
118 - def __init__(self, bluetooth_mac_addr):
119 bluetooth.BluetoothSocket.__init__(self, bluetooth.RFCOMM) 120 self.connect((bluetooth_mac_addr, 1))
121
122 - def disconnect(self):
123 self.close()
124
125 - def flush(self):
126 pass
127 - def flushInput(self):
128 pass
129 - def flushOutput(self):
130 pass
131
132 - def read(self):
133 return self.recv(1)
134
135 - def write(self, packet):
136 import os 137 if os.name == 'nt': 138 self.send(str(packet)) 139 else: 140 self.sendall(str(bytearray((packet))))
141 except: 142 pass 143
144 -class LinkLayer_Base:
145 - def __init__(self, physicalLayer, readCallback):
146 self.phys = physicalLayer 147 self.deliver = readCallback 148 self.writeLock = threading.Lock() 149 self.stopflag = False
150
151 - def start(self):
152 self.thread = threading.Thread(target=self._run) 153 self.thread.daemon = True 154 self.thread.start()
155
156 - def stop(self):
157 self.stopflag = True
158
159 -class LinkLayer_TTY(LinkLayer_Base):
160 - def __init__(self, physicalLayer, readCallback):
161 LinkLayer_Base.__init__(self, physicalLayer, readCallback)
162
163 - def write(self, packet, address):
164 newpacket = bytearray([ packet[0], 165 len(packet)+5, 166 address>>8, 167 address&0x00ff, 168 1 ]) 169 newpacket += bytearray(packet) 170 self.writeLock.acquire() 171 if DEBUG: 172 print ("Send: {0}".format(list(map(hex, newpacket)))) 173 self.phys.write(newpacket) 174 self.writeLock.release()
175
176 - def _run(self):
177 # Try to read byte from physical layer 178 self.readbuf = bytearray([]) 179 self.phys.flush() 180 self.phys.flushInput() 181 self.phys.flushOutput() 182 while True: 183 byte = self.phys.read() 184 if self.stopflag: 185 break 186 if byte is None: 187 continue 188 if DEBUG: 189 print ("Byte: {0}".format(list(map(hex, bytearray(byte))))) 190 self.readbuf += bytearray(byte) 191 if (len(self.readbuf) <= 2): 192 continue 193 if len(self.readbuf) == self.readbuf[1]: 194 # Received whole packet 195 if DEBUG: 196 print ("Recv: {0}".format(list(map(hex, self.readbuf)))) 197 zigbeeAddr = barobo._unpack('!H', self.readbuf[2:4])[0] 198 if self.readbuf[0] != barobo.BaroboCtx.EVENT_REPORTADDRESS: 199 pkt = Packet(self.readbuf[5:-1], zigbeeAddr) 200 else: 201 pkt = Packet(self.readbuf, zigbeeAddr) 202 self.deliver(pkt) 203 self.readbuf = self.readbuf[self.readbuf[1]:]
204
205 -class LinkLayer_SFP(LinkLayer_Base):
206 - def __init__(self, physicalLayer, readCallback):
207 LinkLayer_Base.__init__(self, physicalLayer, readCallback) 208 self.ctx = (ctypes.c_ubyte * _sfp.sfpGetSizeof())() 209 _sfp.sfpInit(self.ctx) 210 211 # I think the function prototypes (SFP*fun) and the callbacks themselves 212 # (sfp_*_cb) need to be saved in the object instance, otherwise they'll be 213 # garbage collected and all hell will break loose when libsfp calls one of 214 # the callbacks. 215 216 self.SFPdeliverfun = ctypes.CFUNCTYPE(None, 217 ctypes.POINTER(ctypes.c_ubyte), ctypes.c_ulong, ctypes.c_void_p) 218 self.SFPwritenfun = ctypes.CFUNCTYPE(ctypes.c_int, 219 ctypes.POINTER(ctypes.c_ubyte), ctypes.c_ulong, 220 ctypes.POINTER(ctypes.c_ulong), ctypes.c_void_p) 221 self.SFPlockfun = ctypes.CFUNCTYPE(None, ctypes.c_void_p) 222 self.SFPunlockfun = ctypes.CFUNCTYPE(None, ctypes.c_void_p) 223 224 self.sfp_deliver_cb = self.SFPdeliverfun(self.sfp_deliver) 225 self.sfp_write_cb = self.SFPwritenfun(self.sfp_write) 226 self.sfp_lock_tx_cb = self.SFPlockfun(self.sfp_lock_tx) 227 self.sfp_unlock_tx_cb = self.SFPunlockfun(self.sfp_unlock_tx) 228 229 _sfp.sfpSetDeliverCallback(self.ctx, self.sfp_deliver_cb, None) 230 _sfp.sfpSetWriteCallback(self.ctx, _SFP_WRITE_MULTIPLE, self.sfp_write_cb, None) 231 _sfp.sfpSetLockCallback(self.ctx, self.sfp_lock_tx_cb, None) 232 _sfp.sfpSetUnlockCallback(self.ctx, self.sfp_unlock_tx_cb, None)
233
234 - def sfp_deliver(self, buf, size, userdata):
235 if (size <= 2): 236 return 237 if size == buf[1]: 238 # Received whole packet 239 if DEBUG: 240 print ("Recv: {0}".format(list(map(hex, buf[:size])))) 241 zigbeeAddr = barobo._unpack('!H', bytearray(buf[2:4]))[0] 242 if buf[0] != barobo.BaroboCtx.EVENT_REPORTADDRESS: 243 pkt = Packet(bytearray(buf[5:size]), zigbeeAddr) 244 else: 245 pkt = Packet(bytearray(buf[:size]), zigbeeAddr) 246 self.deliver(pkt)
247
248 - def sfp_write(self, buf, size, outlen, userdata):
249 if DEBUG: 250 print ("Send: {0}".format(list(map(hex, buf[:size])))) 251 outlen_w = ctypes.cast(outlen, ctypes.POINTER(ctypes.c_ulong)) 252 addr = ctypes.addressof(outlen_w.contents) 253 outlen_w2 = ctypes.c_ulong.from_address(addr) 254 outlen_w2 = self.phys.write(bytearray(buf[:size])) 255 return 0
256
257 - def sfp_lock_tx(self, userdata):
258 self.writeLock.acquire()
259
260 - def sfp_unlock_tx(self, userdata):
261 self.writeLock.release()
262
263 - def write(self, packet, address):
264 newpacket = bytearray([ packet[0], 265 len(packet)+5, 266 address>>8, 267 address&0x00ff, 268 1 ]) 269 newpacket += bytearray(packet) 270 buf = (ctypes.c_ubyte * len(newpacket))(*newpacket) 271 _sfp.sfpWritePacket(self.ctx, buf, len(buf), None)
272
273 - def _run(self):
274 # Try to read byte from physical layer 275 self.phys.flush() 276 self.phys.flushInput() 277 self.phys.flushOutput() 278 _sfp.sfpConnect(self.ctx) 279 while True: 280 byte = self.phys.read() 281 if self.stopflag: 282 break 283 if byte is None: 284 continue 285 if DEBUG: 286 print ("Byte: {0}".format(list(map(hex, bytearray(byte))))) 287 from sys import version_info 288 if version_info < (3,0): 289 octet = ord(byte[0]) 290 else: 291 octet = byte[0] 292 rc = _sfp.sfpDeliverOctet(self.ctx, octet, None, 0, None) 293 if DEBUG: 294 print ("SFP Link Layer stopping...")
295
296 -class LinkLayer_Socket(LinkLayer_Base):
297 - def __init__(self, physicalLayer, readCallback):
298 LinkLayer_Base.__init__(self, physicalLayer, readCallback)
299
300 - def write(self, packet, address):
301 self.writeLock.acquire() 302 self.phys.write(packet) 303 if DEBUG: 304 print ("Send: {0}".format(list(map(hex, packet)))) 305 self.writeLock.release()
306
307 - def _run(self):
308 # Try to read byte from physical layer 309 self.readbuf = bytearray([]) 310 self.phys.flush() 311 self.phys.flushInput() 312 self.phys.flushOutput() 313 while True: 314 byte = self.phys.read() 315 if self.stopflag: 316 break 317 if DEBUG: 318 print ("Byte: {0}".format(list(map(hex, bytearray(byte))))) 319 if byte is None: 320 continue 321 self.readbuf += bytearray(byte) 322 if (len(self.readbuf) <= 2): 323 continue 324 if len(self.readbuf) == self.readbuf[1]: 325 # Received whole packet 326 if DEBUG: 327 print ("Recv: {0}".format(list(map(hex, self.readbuf)))) 328 pkt = Packet(self.readbuf, 0x8000) 329 self.deliver(pkt) 330 self.readbuf = self.readbuf[self.readbuf[1]:]
331