def test_receive_appmessage_string():
    pebble = Mock()

    calls = [0]
    def handle_result(txid, uuid, result):
        assert uuid == UUID(int=128)
        assert txid == 42
        assert result == {
            14: "hello!",
            15: "éclair", # null terminated -> 'foo' should be omitted.
            16: "hello\uFFFDworld", # invalid unicode -> U+FFFD REPLACEMENT CHARACTER
        }
        calls[0] += 1

    service = AppMessageService(pebble)
    service.register_handler("appmessage", handle_result)
    assert pebble.register_endpoint.call_args is not None
    callback = pebble.register_endpoint.call_args[0][1]

    callback(
        AppMessage(
            transaction_id=42,
            data=AppMessagePush(
                uuid=UUID(int=128),
                dictionary=[
                    AppMessageTuple(key=14, type=AppMessageTuple.Type.CString, data=b"hello!\x00"),
                    AppMessageTuple(key=15, type=AppMessageTuple.Type.CString,
                                    data="éclair".encode('utf-8') + b'\x00foo',),
                    AppMessageTuple(key=16, type=AppMessageTuple.Type.CString, data=b"hello\xffworld"),
                ]
            )
        )
    )
    pebble.send_packet.assert_called_once_with(AppMessage(transaction_id=42, data=AppMessageACK()))
    assert calls[0] == 1
Exemple #2
0
class PebbleManager(object):
    def __init__(self, qemu):
        self.qemu = qemu.split(":")
        print self.qemu
        self.pebble = PebbleConnection(QemuTransport(*self.qemu), log_packet_level=logging.DEBUG)
        self.handle_start = None
        self.handle_stop = None
        self.blobdb = None
        self.launcher = None

    def connect(self):
        self.pebble.connect()
        greenlet = gevent.spawn(self.pebble.run_sync)
        self.pebble.fetch_watch_info()
        self.register_endpoints()
        self.pebble.transport.send_packet(QemuBluetoothConnection(connected=True), target=MessageTargetQemu())
        self.blobdb = BlobDBClient(self.pebble)
        self.request_running_app()
        logger.info("connected to %s", self.qemu)
        return greenlet

    def disconnect(self):
        if self.launcher is not None:
            self.launcher.shutdown()

    def register_endpoints(self):
        self.pebble.register_endpoint(AppRunState, self.handle_lifecycle)
        self.launcher = AppMessageService(self.pebble, message_type=LegacyAppLaunchMessage)
        self.launcher.register_handler("appmessage", self.handle_launcher)

    def request_running_app(self):
        if self.pebble.firmware_version.major >= 3:
            self.pebble.send_packet(AppRunState(data=AppRunStateRequest()))
        else:
            self.launcher.send_message(uuid.UUID(int=0), {LegacyAppLaunchMessage.Keys.StateFetch: Uint8(1)})

    def handle_lifecycle(self, packet):
        if isinstance(packet.data, AppRunStateStart):
            if callable(self.handle_start):
                self.handle_start(packet.data.uuid)
        elif isinstance(packet.data, AppRunStateStop):
            if callable(self.handle_stop):
                self.handle_stop(packet.data.uuid)

    def handle_launcher(self, txid, uuid, message):
        state = message[LegacyAppLaunchMessage.Keys.RunState]
        if state == LegacyAppLaunchMessage.States.Running:
            if callable(self.handle_start):
                self.handle_start(uuid)
        elif state == LegacyAppLaunchMessage.States.NotRunning:
            if callable(self.handle_stop):
                self.handle_stop(uuid)

    @property
    def timeline_is_supported(self):
        return self.pebble.firmware_version.major >= 3
Exemple #3
0
 def __init__(self,
              qemu,
              pbws,
              persist_dir=None,
              oauth_token=None,
              layout_file=None,
              block_private_addresses=False):
     self.qemu = qemu
     self.pebble = PebbleManager(qemu)
     self.persist_dir = persist_dir
     self.oauth_token = oauth_token
     self.pebble.handle_start = self.handle_start
     self.pebble.handle_stop = self.handle_stop
     # PBL-26034: Due to PBL-24009 we must be sure to respond to appmessages received with no JS running.
     # However, libpebble2 presently provides no way of NACKing. Making sure this exists is sufficient for
     # ACKs, so we just create it and pass it off. We should add NACKs later, though.
     self.appmessage = AppMessageService(self.pebble.pebble)
     self.pbws = {}
     self.logger = logging.getLogger("pypkjs")
     self.running_uuid = None
     self.js = None
     self.urls = URLManager()
     self.timeline = PebbleTimeline(self,
                                    persist=persist_dir,
                                    oauth=oauth_token,
                                    layout_file=layout_file)
     self.block_private_addresses = block_private_addresses
     self.load_cached_pbws()
     self.load_pbws(pbws)
def main(settings):
    """ Main function for the communicatior, loops here """

    if settings.transport == "websocket":
        pebble = PebbleConnection(WebsocketTransport(settings.device), log_packet_level=logging.DEBUG)
    else: # No elif, for compatibility with older configs
        pebble = PebbleConnection(SerialTransport(settings.device), log_packet_level=logging.DEBUG)
    pebble.connect()

    # For some reason it seems to timeout for the first time, with "somebody is eating our input" error,
    # replying seems to help.
    for loop in range(5):
        try:
            pebble.run_async()
            break
        except libpebble2.exceptions.TimeoutError:
            logging.info("Pebble timeouted, retrying..")
            continue

    # Register service for app messages
    appservice = AppMessageService(pebble)
    handler = CommandHandler(settings)

    commwatch = CommunicationKeeper(settings, appservice)
    appservice.register_handler("nack", commwatch.nack_received)
    appservice.register_handler("ack", commwatch.ack_received)

    # Start the watchapp
    pebble.send_packet(AppRunState(command = 0x01, data=AppRunStateStart(uuid = uuid.UUID(settings.uuid))))

    # Send our current config
    for (id_key, id_type) in get_button_ids():
        id_full = id_key[0] + "," + id_type[0]
        if id_full in settings.key_mappings:
            status = "T"
        else:
            status = "F"

        data = id_key[0] + id_type[0] + status
        commwatch.send_message({COMMUNICATION_KEY_CONFIG: CString(data)})

        # Wait for all
        for loop in range(10):
            if len(commwatch.pending) == 0:
                break
            if commwatch.error:
                raise PebbleConnectionException("Commwatch:" + commwatch.error)
            time.sleep(0.1)
        else:
            raise PebbleConnectionException("Pebble not respoding to config")

    logging.info("Connection ok, entering to active state..")
    appservice.register_handler("appmessage", handler.message_received_event)

    while True:
        commwatch.send_message({COMMUNICATION_KEY_PING: Uint8(0)})
        time.sleep(10)
Exemple #5
0
def meminiSense(startDateTime,hostIP,BASE_PORT,streaming=True,logging=True):
    global meminifilename
    #logging.basicConfig(level=logging.INFO)
    #file_path = "/media/card/memini/"
    #if file_path is None:
    #    print("DID NOT FIND PEBBLE_DATA_LOC")
    #    #print(os.environ)
    #    exit(1)
    #if not os.path.exists(file_path):
    #    os.mkdir(file_path) 
    #
    #filename = str(file_path) + "memini_data.csv"
    running = True
    #pebble = PebbleConnection(SerialTransport("/dev/rfcomm0"))
    #pebble.connect()
    
    while True:
        try:
            pebble = PebbleConnection(SerialTransport("/dev/rfcomm0"))
            pebble.connect()
            #print "connection try 0!"
            appUUID = APP_UUID[:]
            while running:
                try:
                    print "Attempt to Connect"
                    #logging.info("Attempting to connect to pebble")
                    pebble.run_async()
                    print "Connection Success"
                    #logging.info("Pebble connection success")
                    break
                except libpebble2.exceptions.TimeoutError:
                    print "Pebble timeouted, retrying.."
                    continue
            #print "Opening file!"
            #with open(meminifilename,'a') as dataFile:
            #    dataFile.write("message,timestamp,button_id,click_type,battery_charge\n") 
            if pebble.connected:
                restart_app_on_watch(pebble,appUUID)
                with open(meminifilename,'a') as dataFile:
                    dataFile.write("message,timestamp,button_id,click_type,battery_charge\n")
                
                # Register service for app messages
                mainMsgService = AppMessageService(pebble)
                mainCommHandler = CommunicationKeeper(appUUID, mainMsgService)
                mainMsgService.register_handler("nack", mainCommHandler.nack_received)
                mainMsgService.register_handler("ack", mainCommHandler.ack_received)
                mainMsgHandler = AppMsgHandler(appUUID)
                mainMsgService.register_handler("appmessage", mainMsgHandler.message_received_event)

            while pebble.connected:
                # time.sleep(10) 
                memini_main(mainMsgService,mainCommHandler,mainMsgHandler)
        except SerialException:
            print("Error: Pebble Disconnected!")
            time.sleep(30)
            exit(2)
Exemple #6
0
    def _install_legacy2(self):
        metadata = self._bundle.get_app_metadata()
        app_uuid = metadata['uuid']

        self._pebble.send_packet(LegacyAppInstallRequest(data=LegacyUpgradeAppUUID(uuid=app_uuid)))
        # We don't really care if this worked; we're just waiting for it.
        self._pebble.read_from_endpoint(LegacyAppInstallResponse)

        # Find somewhere to install to.
        self._pebble.send_packet(LegacyAppInstallRequest(data=LegacyBankInfoRequest()))
        result = self._pebble.read_from_endpoint(LegacyAppInstallResponse).data
        assert isinstance(result, LegacyBankInfoResponse)
        first_free = 0
        for app in result.apps:
            assert isinstance(app, LegacyBankEntry)
            if app.bank_number == first_free:
                first_free += 1
        if first_free == result.bank_count:
            raise AppInstallError("No app banks free.")

        # Send the app over
        binary = self._bundle.zip.read(self._bundle.get_app_path())
        self._send_part_legacy2(PutBytesType.Binary, binary, first_free)

        if self._bundle.has_resources:
            resources = self._bundle.zip.read(self._bundle.get_resource_path())
            self._send_part_legacy2(PutBytesType.Resources, resources, first_free)

        if self._bundle.has_worker:
            worker = self._bundle.zip.read(self._bundle.get_worker_path())
            self._send_part_legacy2(PutBytesType.Worker, worker, first_free)

        # Mark it as available
        self._pebble.send_packet(LegacyAppInstallRequest(data=LegacyAppAvailable(bank=first_free, vibrate=True)))
        self._pebble.read_from_endpoint(LegacyAppInstallResponse)

        # Launch it (which is painful on 2.x).
        appmessage = AppMessageService(self._pebble, message_type=LegacyAppLaunchMessage)
        appmessage.send_message(app_uuid, {
            LegacyAppLaunchMessage.Keys.RunState: AMUint8(LegacyAppLaunchMessage.States.Running)
        })
        appmessage.shutdown()
Exemple #7
0
def test_receive_appmessage_string():
    pebble = Mock()

    calls = [0]

    def handle_result(txid, uuid, result):
        assert uuid == UUID(int=128)
        assert txid == 42
        assert result == {
            14: "hello!",
            15: "éclair",  # null terminated -> 'foo' should be omitted.
            16:
            "hello\uFFFDworld",  # invalid unicode -> U+FFFD REPLACEMENT CHARACTER
        }
        calls[0] += 1

    service = AppMessageService(pebble)
    service.register_handler("appmessage", handle_result)
    assert pebble.register_endpoint.call_args is not None
    callback = pebble.register_endpoint.call_args[0][1]

    callback(
        AppMessage(transaction_id=42,
                   data=AppMessagePush(
                       uuid=UUID(int=128),
                       dictionary=[
                           AppMessageTuple(key=14,
                                           type=AppMessageTuple.Type.CString,
                                           data=b"hello!\x00"),
                           AppMessageTuple(
                               key=15,
                               type=AppMessageTuple.Type.CString,
                               data="éclair".encode('utf-8') + b'\x00foo',
                           ),
                           AppMessageTuple(key=16,
                                           type=AppMessageTuple.Type.CString,
                                           data=b"hello\xffworld"),
                       ])))
    pebble.send_packet.assert_called_once_with(
        AppMessage(transaction_id=42, data=AppMessageACK()))
    assert calls[0] == 1
Exemple #8
0
 def openApp(self, pebbleConnection, uuid):
     AppStartService = AppMessageService(
         pebbleConnection, message_type=LegacyAppLaunchMessage)
     AppStartService.send_message(
         uuid, {
             LegacyAppLaunchMessage.Keys.RunState:
             Uint8(LegacyAppLaunchMessage.States.Running)
         })
     AppStartService.shutdown()
Exemple #9
0
    def _install_legacy2(self):
        metadata = self._bundle.get_app_metadata()
        app_uuid = metadata['uuid']

        # We don't really care if this worked; we're just waiting for it.
        self._pebble.send_and_read(
            LegacyAppInstallRequest(data=LegacyUpgradeAppUUID(uuid=app_uuid)),
            LegacyAppInstallResponse)

        # Find somewhere to install to.
        result = self._pebble.send_and_read(
            LegacyAppInstallRequest(data=LegacyBankInfoRequest()),
            LegacyAppInstallResponse).data
        assert isinstance(result, LegacyBankInfoResponse)
        first_free = 0
        for app in result.apps:
            assert isinstance(app, LegacyBankEntry)
            if app.bank_number == first_free:
                first_free += 1
        if first_free == result.bank_count:
            raise AppInstallError("No app banks free.")

        # Send the app over
        binary = self._bundle.zip.read(self._bundle.get_app_path())
        self._send_part_legacy2(PutBytesType.Binary, binary, first_free)

        if self._bundle.has_resources:
            resources = self._bundle.zip.read(self._bundle.get_resource_path())
            self._send_part_legacy2(PutBytesType.Resources, resources,
                                    first_free)

        if self._bundle.has_worker:
            worker = self._bundle.zip.read(self._bundle.get_worker_path())
            self._send_part_legacy2(PutBytesType.Worker, worker, first_free)

        # Mark it as available
        self._pebble.send_and_read(
            LegacyAppInstallRequest(
                data=LegacyAppAvailable(bank=first_free, vibrate=True)),
            LegacyAppInstallResponse)

        # Launch it (which is painful on 2.x).
        appmessage = AppMessageService(self._pebble,
                                       message_type=LegacyAppLaunchMessage)
        appmessage.send_message(
            app_uuid, {
                LegacyAppLaunchMessage.Keys.RunState:
                AMUint8(LegacyAppLaunchMessage.States.Running)
            })
        appmessage.shutdown()
Exemple #10
0
def meminiSense(startDateTime,hostIP,BASE_PORT,streaming=True,logging=True):
	global meminifilename
	
	global agiType
	global agiIndx
	global agiStatus

	global server_address
	
	server_address = (hostIP, BASE_PORT)
	startTimeDT = rNTPTime.stripDateTime(startDateTime)

	#logging.basicConfig(level=logging.INFO)
	#file_path = "/media/card/memini/"
	#if file_path is None:
	#    print("DID NOT FIND PEBBLE_DATA_LOC")
	#    #print(os.environ)
	#    exit(1)
	#if not os.path.exists(file_path):
	#    os.mkdir(file_path) 
	#
	#filename = str(file_path) + "memini_data.csv"
	running = True
	#pebble = PebbleConnection(SerialTransport("/dev/rfcomm0"))
	#pebble.connect()
	
	while True:
		try:
			pebble = PebbleConnection(SerialTransport("/dev/rfcomm0"))
			pebble.connect()
			pebble.pump_reader()
			#print "connection try 0!"
			appUUID = APP_UUID[:]

			print "initializing Pebble connection.."
			# print pebble.send_and_read(AppRunState(data=AppRunStateRequest()), AppRunState).data.uuid

			while running:
				try:
					print "Attempt to Connect"
					#logging.info("Attempting to connect to pebble")
					pebble.run_async()
					print "Connection Success"
					#logging.info("Pebble connection success")
					break
				except libpebble2.exceptions.TimeoutError:
					print "Pebble timeouted, retrying.."
					continue

			while pebble.connected:
				try:
					print "Pebble Connected.."
					restart_app_on_watch(pebble,appUUID)
					with open(meminifilename,'a') as dataFile:
						dataFile.write("message,timestamp,button_id,click_type,battery_charge\n")
					
					# Register service for app messages
					print "initializing Services..."
					mainMsgService = AppMessageService(pebble)
					mainCommHandler = CommunicationKeeper(appUUID, mainMsgService)
					mainMsgService.register_handler("nack", mainCommHandler.nack_received)
					mainMsgService.register_handler("ack", mainCommHandler.ack_received)
					mainMsgHandler = AppMsgHandler(appUUID)
					mainMsgService.register_handler("appmessage", mainMsgHandler.message_received_event)

					break
				except Exception as err:
					print err
					print "Error Initializing Services, retrying.."
					pebble.run_async()
					continue

			while pebble.connected:
				# time.sleep(10) 
				is_app_on(pebble,appUUID)
				pebbleMessage = []
				pebbleMessage.append("checkNoti") #check for notiFlag from basestation
				pebbleMessage.append(str(BASE_PORT))
				temp = rNTPTime.checkNoti(hostIP, pebbleMessage, 5) 
				# if True: #for testing
				if int(rNTPTime.notiFlag) == 1:
					memini_main(mainMsgService,mainCommHandler,mainMsgHandler)
					# print("sending Message")
				else:
					#print "NO NOTIFICATION"
					time.sleep(NOTI_CHECK_DELAY)
		except SerialException:
			print("Pebble Disconnected!")
			time.sleep(30)
			continue

		except Exception as err:
			print err
			pass
 def produceAppMessageService(pebbleConnection):
     return AppMessageService(pebbleConnection)
Exemple #12
0
 def register_endpoints(self):
     self.pebble.register_endpoint(AppRunState, self.handle_lifecycle)
     self.launcher = AppMessageService(self.pebble, message_type=LegacyAppLaunchMessage)
     self.launcher.register_handler("appmessage", self.handle_launcher)
Exemple #13
0
 def register_endpoints(self):
     self.pebble.register_endpoint(AppRunState, self.handle_lifecycle)
     self.launcher = AppMessageService(self.pebble,
                                       message_type=LegacyAppLaunchMessage)
     self.launcher.register_handler("appmessage", self.handle_launcher)
Exemple #14
0
class PebbleManager(object):
    def __init__(self, qemu):
        self.qemu = qemu.split(':')
        print self.qemu
        self.pebble = PebbleConnection(QemuTransport(*self.qemu),
                                       log_packet_level=logging.DEBUG)
        self.handle_start = None
        self.handle_stop = None
        self.blobdb = None
        self.launcher = None

    def connect(self):
        self.pebble.connect()
        greenlet = gevent.spawn(self.pebble.run_sync)
        self.pebble.fetch_watch_info()
        self.register_endpoints()
        self.pebble.transport.send_packet(
            QemuBluetoothConnection(connected=True),
            target=MessageTargetQemu())
        self.blobdb = BlobDBClient(self.pebble)
        self.request_running_app()
        logger.info('connected to %s', self.qemu)
        return greenlet

    def disconnect(self):
        if self.launcher is not None:
            self.launcher.shutdown()

    def register_endpoints(self):
        self.pebble.register_endpoint(AppRunState, self.handle_lifecycle)
        self.launcher = AppMessageService(self.pebble,
                                          message_type=LegacyAppLaunchMessage)
        self.launcher.register_handler("appmessage", self.handle_launcher)

    def request_running_app(self):
        if self.pebble.firmware_version.major >= 3:
            self.pebble.send_packet(AppRunState(data=AppRunStateRequest()))
        else:
            self.launcher.send_message(
                uuid.UUID(int=0),
                {LegacyAppLaunchMessage.Keys.StateFetch: Uint8(1)})

    def handle_lifecycle(self, packet):
        if isinstance(packet.data, AppRunStateStart):
            if callable(self.handle_start):
                self.handle_start(packet.data.uuid)
        elif isinstance(packet.data, AppRunStateStop):
            if callable(self.handle_stop):
                self.handle_stop(packet.data.uuid)

    def handle_launcher(self, txid, uuid, message):
        state = message[LegacyAppLaunchMessage.Keys.RunState]
        if state == LegacyAppLaunchMessage.States.Running:
            if callable(self.handle_start):
                self.handle_start(uuid)
        elif state == LegacyAppLaunchMessage.States.NotRunning:
            if callable(self.handle_stop):
                self.handle_stop(uuid)

    @property
    def timeline_is_supported(self):
        return self.pebble.firmware_version.major >= 3
Exemple #15
0
 def perform(self, pebble, args, app):
     json_message = json.loads(open(args.formatted_data).read())
     app_message = dict((i, TYPE_CAST[key](json_message[key]))
                        for i, key in enumerate(APP_KEYS))
     AppMessageService(pebble).send_message(URCHIN_UUID, app_message)
     return {'received': True}