Example #1
0
    def connect_to_site(self):
        logger.info("Connecting to Site: {}".format(cfg.IP_CONNECTION_SITEID))
        if self.site_info is None:
            self.site_info = self.get_site_info(
                siteid=cfg.IP_CONNECTION_SITEID, email=cfg.IP_CONNECTION_EMAIL)

        if self.site_info is None:
            logger.error("Unable to get site info")
            return False
        try:
            logger.debug("Site Info: {}".format(
                json.dumps(self.site_info, indent=4)))
            xoraddr = binascii.unhexlify(
                self.site_info['site'][0]['module'][0]['xoraddr'])

            stun_host = 'turn.paradoxmyhome.com'

            logger.debug("STUN TCP Change Request")
            self.client = stun.StunClient(stun_host)
            self.client.send_tcp_change_request()
            stun_r = self.client.receive_response()
            if stun.is_error(stun_r):
                logger.error(stun.get_error(stun_r))
                return False

            logger.debug("STUN TCP Binding Request")
            self.client.send_binding_request()
            stun_r = self.client.receive_response()
            if stun.is_error(stun_r):
                logger.error(stun.get_error(stun_r))
                return False

            logger.debug("STUN Connect Request")
            self.client.send_connect_request(xoraddr=xoraddr)
            stun_r = self.client.receive_response()
            if stun.is_error(stun_r):
                logger.error(stun.get_error(stun_r))
                return False

            self.connection_timestamp = time.time()

            connection_id = stun_r[0]['attr_body']
            raddr = self.client.sock.getpeername()

            logger.debug("STUN Connection Bind Request")
            self.client1 = stun.StunClient(host=raddr[0], port=raddr[1])
            self.client1.send_connection_bind_request(
                binascii.unhexlify(connection_id))
            stun_r = self.client1.receive_response()
            if stun.is_error(stun_r):
                logger.error(stun.get_error(stun_r))
                return False

            self.socket = self.client1.sock
            logger.info("Connected to Site: {}".format(
                cfg.IP_CONNECTION_SITEID))
        except Exception:
            logger.exception("Unable to negotiate connection to site")

        return True
Example #2
0
 async def _stun_tcp_binding_request(self):
     logger.debug("STUN TCP Binding Request")
     self.stun_control.send_binding_request()
     stun_r = self.stun_control.receive_response()
     if stun.is_error(stun_r):
         raise ConnectToSiteFailed(
             f"STUN TCP Binding Request error: {stun.get_error(stun_r)}")
Example #3
0
 async def _stun_connect(self, xoraddr):
     logger.debug("STUN Connect Request")
     self.stun_control.send_connect_request(xoraddr=xoraddr)
     stun_r = self.stun_control.receive_response()
     if stun.is_error(stun_r):
         raise ConnectToSiteFailed(
             f"STUN Connect Request error: {stun.get_error(stun_r)}")
     return stun_r
Example #4
0
 async def _stun_tcp_change_request(self):
     stun_host = "turn.paradoxmyhome.com"
     logger.debug("STUN TCP Change Request")
     self.stun_control = stun.StunClient(stun_host)
     self.stun_control.send_tcp_change_request()
     stun_r = self.stun_control.receive_response()
     if stun.is_error(stun_r):
         raise ConnectToSiteFailed(
             f"STUN TCP Change Request error: {stun.get_error(stun_r)}")
Example #5
0
    def refresh_session_if_required(self) -> None:
        if self.site_info is None or self.connection_timestamp == 0:
            return

        # Refresh session if required
        if time.time() - self.connection_timestamp >= 500:
            logger.info("STUN Session Refresh")
            self.stun_control.send_refresh_request()
            stun_r = self.stun_control.receive_response()
            if stun.is_error(stun_r):
                self.connected = False
                raise StunSessionRefreshFailed(
                    f"STUN Session Refresh failed: {stun.get_error(stun_r)}")

            self.connection_timestamp = time.time()
Example #6
0
    async def connect(self) -> None:
        self.connection_timestamp = 0
        logger.info("Connecting to Site: {}".format(self.site_id))
        if self.site_info is None:
            self.site_info = await self._get_site_info(siteid=self.site_id,
                                                       email=self.email)

        if self.site_info is None:
            raise ConnectToSiteFailed("Unable to get site info")

        logger.debug("Site Info: {}".format(
            json.dumps(self.site_info, indent=4)))
        self.module = self._select_module()

        if self.module is None:
            self.site_info = None  # Reset state
            raise ConnectToSiteFailed(
                "Unable to find module with desired panel serial")

        xoraddr = binascii.unhexlify(self.module["xoraddr"])

        await self._stun_tcp_change_request()
        await self._stun_tcp_binding_request()
        stun_r = await self._stun_connect(xoraddr)

        self.connection_timestamp = time.time()

        connection_id = stun_r[0]["attr_body"]
        raddr = self.stun_control.sock.getpeername()

        logger.debug("STUN Connection Bind Request")
        self.stun_tunnel = stun.StunClient(host=raddr[0], port=raddr[1])
        self.stun_tunnel.send_connection_bind_request(
            binascii.unhexlify(connection_id))
        stun_r = self.stun_tunnel.receive_response()
        if stun.is_error(stun_r):
            raise ConnectToSiteFailed(
                f"STUN Connection Bind Request error: {stun.get_error(stun_r)}"
            )

        logger.info("Connected to Site: {}".format(self.site_id))
Example #7
0
    def refresh_stun(self):
        if self.site_info is None:
            return True

        try:
            # Refresh session if required
            if time.time() - self.connection_timestamp >= 500:
                logger.debug("Refreshing session")
                self.client.send_refresh_request()
                stun_r = self.client.receive_response()
                if stun.is_error(stun_r):
                    logger.error(stun.get_error(stun_r))
                    self.connected = False
                    return False

                self.connection_timestamp = time.time()

            return True
        except Exception:
            logger.exception("Session refresh")
            return False
Example #8
0
    async def connect(self) -> None:
        self.connection_timestamp = 0
        logger.info("Connecting to Site: {}".format(self.site_id))
        if self.site_info is None:
            self.site_info = await self._get_site_info(
                siteid=self.site_id, email=self.email
            )

        if self.site_info is None:
            raise ConnectToSiteFailed("Unable to get site info")

        # xoraddr = binascii.unhexlify(self.site_info['site'][0]['module'][0]['xoraddr'])
        self.module = None

        logger.debug("Site Info: {}".format(json.dumps(self.site_info, indent=4)))

        if self.panel_serial is not None:
            for site in self.site_info["site"]:
                for module in site:
                    logger.debug(
                        "Found module with panel serial: {}".format(
                            module["panelSerial"]
                        )
                    )
                    if module["panelSerial"] == self.panel_serial:
                        self.module = module
                        break

                if self.module is not None:
                    break
        else:
            self.module = self.site_info["site"][0]["module"][0]  # Use first

        if self.module is None:
            self.site_info = None  # Reset state
            raise ConnectToSiteFailed("Unable to find module with desired panel serial")

        xoraddr = binascii.unhexlify(self.module["xoraddr"])

        stun_host = "turn.paradoxmyhome.com"

        logger.debug("STUN TCP Change Request")
        self.stun_control = stun.StunClient(stun_host)
        self.stun_control.send_tcp_change_request()
        stun_r = self.stun_control.receive_response()
        if stun.is_error(stun_r):
            raise ConnectToSiteFailed(
                f"STUN TCP Change Request error: {stun.get_error(stun_r)}"
            )

        logger.debug("STUN TCP Binding Request")
        self.stun_control.send_binding_request()
        stun_r = self.stun_control.receive_response()
        if stun.is_error(stun_r):
            raise ConnectToSiteFailed(
                f"STUN TCP Binding Request error: {stun.get_error(stun_r)}"
            )

        logger.debug("STUN Connect Request")
        self.stun_control.send_connect_request(xoraddr=xoraddr)
        stun_r = self.stun_control.receive_response()
        if stun.is_error(stun_r):
            raise ConnectToSiteFailed(
                f"STUN Connect Request error: {stun.get_error(stun_r)}"
            )

        self.connection_timestamp = time.time()

        connection_id = stun_r[0]["attr_body"]
        raddr = self.stun_control.sock.getpeername()

        logger.debug("STUN Connection Bind Request")
        self.stun_tunnel = stun.StunClient(host=raddr[0], port=raddr[1])
        self.stun_tunnel.send_connection_bind_request(binascii.unhexlify(connection_id))
        stun_r = self.stun_tunnel.receive_response()
        if stun.is_error(stun_r):
            raise ConnectToSiteFailed(
                f"STUN Connection Bind Request error: {stun.get_error(stun_r)}"
            )

        logger.info("Connected to Site: {}".format(self.site_id))
Example #9
0
    async def connect_to_site(self):
        loop = asyncio.get_event_loop()
        self.connection_timestamp = 0
        logger.info("Connecting to Site: {}".format(cfg.IP_CONNECTION_SITEID))
        if self.site_info is None:
            self.site_info = self.get_site_info(siteid=cfg.IP_CONNECTION_SITEID, email=cfg.IP_CONNECTION_EMAIL)


        if self.site_info is None:
            logger.error("Unable to get site info")
            return False
        try:
            xoraddr = binascii.unhexlify(self.site_info['site'][0]['module'][0]['xoraddr'])
            if self.site_info is None:
                logger.error("Unable to get site info")
                return False

            self.module = None

            logger.debug("Site Info: {}".format(json.dumps(self.site_info, indent=4)))

            if cfg.IP_CONNECTION_PANEL_SERIAL is not None:
                for site in self.site_info['site']:
                    for module in site:
                        logger.debug("Found module with panel serial: {}".format(module['panelSerial']))
                        if module['panelSerial'] == cfg.IP_CONNECTION_PANEL_SERIAL:
                            self.module = module
                            break

                    if self.module is not None:
                        break
            else:
                self.module = self.site_info['site'][0]['module'][0]  # Use first

            if self.module is None:
                self.site_info = None  # Reset state
                logger.error("Unable to find module with desired panel serial")
                return False

            xoraddr = binascii.unhexlify(self.module['xoraddr'])

            stun_host = 'turn.paradoxmyhome.com'

            logger.debug("STUN TCP Change Request")
            self.client = stun.StunClient(stun_host)
            self.client.send_tcp_change_request()
            stun_r = self.client.receive_response()
            if stun.is_error(stun_r):
                logger.error(stun.get_error(stun_r))
                return False

            logger.debug("STUN TCP Binding Request")
            self.client.send_binding_request()
            stun_r = self.client.receive_response()
            if stun.is_error(stun_r):
                logger.error(stun.get_error(stun_r))
                return False

            logger.debug("STUN Connect Request")
            self.client.send_connect_request(xoraddr=xoraddr)
            stun_r = self.client.receive_response()
            if stun.is_error(stun_r):
                logger.error(stun.get_error(stun_r))
                return False

            self.connection_timestamp = time.time()

            connection_id = stun_r[0]['attr_body']
            raddr = self.client.sock.getpeername()

            logger.debug("STUN Connection Bind Request")
            self.client1 = stun.StunClient(host=raddr[0], port=raddr[1])
            self.client1.send_connection_bind_request(binascii.unhexlify(connection_id))
            stun_r = self.client1.receive_response()
            if stun.is_error(stun_r):
                logger.error(stun.get_error(stun_r))
                return False

            _, self.connection = await loop.create_connection(self.make_protocol, sock=self.client1.sock)
            logger.info("Connected to Site: {}".format(cfg.IP_CONNECTION_SITEID))
        except Exception:
            logger.exception("Unable to negotiate connection to site")

        return True