class CameraConnection(): port = 10000 # class variable client = None # instance variables target = None adapter = None state = None index = 0 waiting_for_stop = False server_socket = None size = None def __init__(self, target, adapter, size=None): self.client = BluetoothAsyncSocket() self.adapter = adapter self.client.bind((self.adapter.bt_address, 0)) self.target = target self.target_t = (target, 1) self.size = size if size else 'QQVGA' self.streamserver = StreamServer('0.0.0.0', CameraConnection.port) self.streamserver.create_server_socket() CameraConnection.port += 1 def connected(self): logger.info("got connected") self.state = FSM.WELCOME self.client.setReadReady(self.data_available) if len(self.client.read_buffer) > 0: self.do_welcome() def connection_failed(self, condition): self.client.setCallback(None) self.client.setErrCallback(None) self.client.setReadReady(None) self.adapter.disconnected(self.target) def disconnect(self): self.client.setCallback(None) self.client.setErrCallback(None) self.client.setReadReady(None) self.adapter.disconnected(self.target) self.client.close() def connect(self): self.state = FSM.CONNECTING logger.info("connecting to %s from %s" % (self.target_t, self.adapter.bt_address)) if self.adapter.manager.zm_backend: self.pipe = '/tmp/camera_%s.pipe' % (self.target) if not os.path.exists(self.pipe): os.mkfifo(self.pipe) return self.client.connect_ex(self.target_t, self.connected, self.connection_failed) def do_welcome(self): if 'ACK0000' not in self.client.read_buffer: return logger.info("got welcome") self.client.read_buffer = "" self.state = FSM.SETUP protocol.set_command_mode(self.client) protocol.set_capture_mode(self.client, size=self.size) self.state = FSM.IDLE gobject.timeout_add(200, self.take_picture) def take_picture(self): logger.info("taking picture") self.state = FSM.STREAM protocol.send_command(self.client, "SET_PREVIEW_MODE") #gobject.timeout_add(300,self.ask_size) return False def ask_size(self): if self.state != FSM.ASK_SIZE: return logger.info("asking size") self.state = FSM.GET_SIZE protocol.send_command(self.client, 'GET_CAPTURE_SIZE') def get_size(self): if not CAPTURE_SIZE.match(self.client.read_buffer): return size = CAPTURE_SIZE.match(self.client.read_buffer).groupdict()['size'] self.size = size logger.info("got size %s" % size) self.state = FSM.STREAM protocol.send_command(self.client, 'START_CAPTURE_SEND') def extract_picture(self, start, end): logger.info("got picture") self.streamserver.send_to_all(self.client.read_buffer[start:end + 2], mimetype='image/jpeg') if self.adapter.manager.zm_backend: logger.info("writing %i bytes" % (end - start)) asyncpipe.write(self.pipe, self.client.read_buffer[start:end + 2]) if self.adapter.manager.op_backend: self.adapter.manager.tellListener( signals.HANDLE_PICTURE, dongle=self.adapter.bt_address, target=self.target, picture=self.client.read_buffer[start:end + 2]) self.index += 1 self.client.read_buffer = self.client.read_buffer[end + 2:] def wait_for_prompt(self): logger.info("wait for prompt") if time.time() - self.last > 2: logger.info("2 seconds without data, disconnect") self.disconnect() return False return True def do_stream(self): start, end = protocol.find_jpeg(self.client.read_buffer) if start > -1 and end > -1: self.extract_picture(start, end) if self.index == -100: protocol.send_command(self.client, 'SET_COMMAND_MODE') self.state = FSM.IDLE self.last = time.time() gobject.timeout_add(100, self.wait_for_prompt) def data_available(self, amount): if self.state == FSM.WELCOME: self.do_welcome() elif self.state == FSM.SETUP: self.do_setup() elif self.state == FSM.IDLE: logger.info("ignoring I'm in idle") self.last = time.time() self.client.read_buffer = "" elif self.state == FSM.ASK_SIZE: self.ask_size() elif self.state == FSM.GET_SIZE: self.get_size() elif self.state == FSM.STREAM: self.do_stream() else: logger.debug("not valid state %s" % self.state)
class CameraConnection(): port = 10000 # class variable client = None # instance variables target = None adapter = None state = None index = 0 waiting_for_stop = False server_socket = None size = None def __init__(self, target, adapter, size=None): self.client = BluetoothAsyncSocket() self.adapter = adapter self.client.bind( (self.adapter.bt_address, 0) ) self.target = target self.target_t = (target, 1) self.size = size if size else 'QQVGA' self.streamserver = StreamServer('0.0.0.0', CameraConnection.port) self.streamserver.create_server_socket() CameraConnection.port+=1 def connected(self): logger.info("got connected") self.state = FSM.WELCOME self.client.setReadReady(self.data_available) if len(self.client.read_buffer) > 0: self.do_welcome() def connection_failed(self, condition): self.client.setCallback(None) self.client.setErrCallback(None) self.client.setReadReady(None) self.adapter.disconnected(self.target) def disconnect(self): self.client.setCallback(None) self.client.setErrCallback(None) self.client.setReadReady(None) self.adapter.disconnected(self.target) self.client.close() def connect(self): self.state = FSM.CONNECTING logger.info("connecting to %s from %s" % (self.target_t, self.adapter.bt_address)) if self.adapter.manager.zm_backend: self.pipe = '/tmp/camera_%s.pipe' % (self.target) if not os.path.exists(self.pipe): os.mkfifo(self.pipe) return self.client.connect_ex( self.target_t, self.connected, self.connection_failed) def do_welcome(self): if 'ACK0000' not in self.client.read_buffer: return logger.info("got welcome") self.client.read_buffer = "" self.state = FSM.SETUP protocol.set_command_mode(self.client) protocol.set_capture_mode(self.client, size=self.size) self.state = FSM.IDLE gobject.timeout_add(200,self.take_picture) def take_picture(self): logger.info("taking picture") self.state = FSM.STREAM protocol.send_command(self.client, "SET_PREVIEW_MODE") #gobject.timeout_add(300,self.ask_size) return False def ask_size(self): if self.state != FSM.ASK_SIZE: return logger.info("asking size") self.state = FSM.GET_SIZE protocol.send_command(self.client, 'GET_CAPTURE_SIZE') def get_size(self): if not CAPTURE_SIZE.match(self.client.read_buffer): return size = CAPTURE_SIZE.match(self.client.read_buffer).groupdict()['size'] self.size = size logger.info("got size %s" % size) self.state = FSM.STREAM protocol.send_command(self.client, 'START_CAPTURE_SEND') def extract_picture(self, start, end): logger.info("got picture") self.streamserver.send_to_all( self.client.read_buffer[start:end+2], mimetype='image/jpeg' ) if self.adapter.manager.zm_backend: logger.info("writing %i bytes" % (end-start)) asyncpipe.write(self.pipe, self.client.read_buffer[start:end+2]) if self.adapter.manager.op_backend: self.adapter.manager.tellListener( signals.HANDLE_PICTURE, dongle = self.adapter.bt_address, target = self.target, picture = self.client.read_buffer[start:end+2] ) self.index+=1 self.client.read_buffer = self.client.read_buffer[end+2:] def wait_for_prompt(self): logger.info("wait for prompt") if time.time() - self.last > 2: logger.info("2 seconds without data, disconnect") self.disconnect() return False return True def do_stream(self): start, end = protocol.find_jpeg(self.client.read_buffer) if start > -1 and end > -1: self.extract_picture(start, end) if self.index == -100: protocol.send_command(self.client, 'SET_COMMAND_MODE') self.state = FSM.IDLE self.last = time.time() gobject.timeout_add(100, self.wait_for_prompt) def data_available(self, amount): if self.state == FSM.WELCOME: self.do_welcome() elif self.state == FSM.SETUP: self.do_setup() elif self.state == FSM.IDLE: logger.info("ignoring I'm in idle") self.last = time.time() self.client.read_buffer = "" elif self.state == FSM.ASK_SIZE: self.ask_size() elif self.state == FSM.GET_SIZE: self.get_size() elif self.state == FSM.STREAM: self.do_stream() else: logger.debug("not valid state %s" % self.state)