Beispiel #1
0
    def list_pairings(self):
        """
        This method returns all pairings of a HomeKit accessory. This always includes the local controller and can only
        be done by an admin controller.

        The keys in the resulting dicts are:
         * pairingId: the pairing id of the controller
         * publicKey: the ED25519 long-term public key of the controller
         * permissions: bit value for the permissions
         * controllerType: either admin or regular

        :return: a list of dicts
        :raises: UnknownError: if it receives unexpected data
        :raises: UnpairedError: if the polled accessory is not paired
        """
        if not self.session:
            self.session = IpSession(self.pairing_data)
        request_tlv = TLV.encode_list([(TLV.kTLVType_State, TLV.M1),
                                       (TLV.kTLVType_Method, TLV.ListPairings)
                                       ])
        try:
            response = self.session.sec_http.post('/pairings',
                                                  request_tlv.decode())
            data = response.read()
        except (AccessoryDisconnectedError, EncryptionError):
            self.session.close()
            self.session = None
            raise
        data = TLV.decode_bytes(data)

        if not (data[0][0] == TLV.kTLVType_State and data[0][1] == TLV.M2):
            raise UnknownError('unexpected data received: ' + str(data))
        elif data[1][0] == TLV.kTLVType_Error and data[1][
                1] == TLV.kTLVError_Authentication:
            raise UnpairedError('Must be paired')
        else:
            tmp = []
            r = {}
            for d in data[1:]:
                if d[0] == TLV.kTLVType_Identifier:
                    r = {}
                    tmp.append(r)
                    r['pairingId'] = d[1].decode()
                if d[0] == TLV.kTLVType_PublicKey:
                    r['publicKey'] = d[1].hex()
                if d[0] == TLV.kTLVType_Permissions:
                    controller_type = 'regular'
                    if d[1] == b'\x01':
                        controller_type = 'admin'
                    r['permissions'] = int.from_bytes(d[1], byteorder='little')
                    r['controllerType'] = controller_type
            return tmp
    def list_pairings(self):
        """
        This method returns all pairings of a HomeKit accessory. This always includes the local controller and can only
        be done by an admin controller.

        The keys in the resulting dicts are:
         * pairingId: the pairing id of the controller
         * publicKey: the ED25519 long-term public key of the controller
         * permissions: bit value for the permissions
         * controllerType: either admin or regular

        :return: a list of dicts
        :raises: UnknownError: if it receives unexpected data
        :raises: UnpairedError: if the polled accessory is not paired
        """
        if not self.session:
            self.session = IpSession(self.pairing_data)
        request_tlv = tlv8.encode([
            tlv8.Entry(TlvTypes.State, States.M1),
            tlv8.Entry(TlvTypes.Method, Methods.ListPairings)
        ])
        try:
            response = self.session.sec_http.post('/pairings', request_tlv)
            data = response.read()
        except (AccessoryDisconnectedError, EncryptionError):
            self.session.close()
            self.session = None
            raise
        data = tlv8.decode(
            data, {
                TlvTypes.State: tlv8.DataType.INTEGER,
                TlvTypes.Error: tlv8.DataType.INTEGER,
                TlvTypes.Identifier: tlv8.DataType.BYTES,
                TlvTypes.PublicKey: tlv8.DataType.BYTES,
                TlvTypes.Permissions: tlv8.DataType.BYTES
            })

        error = data.first_by_id(TlvTypes.Error)
        if not (data.first_by_id(TlvTypes.State).data == States.M2):
            raise UnknownError('unexpected data received: ' +
                               tlv8.format_string(data))
        elif error and error.data == Errors.Authentication:
            raise UnpairedError('Must be paired')
        else:
            tmp = []
            r = {}
            for d in data[1:]:
                if d.type_id == TlvTypes.Identifier:
                    r = {}
                    tmp.append(r)
                    r['pairingId'] = d.data.decode()
                if d.type_id == TlvTypes.PublicKey:
                    r['publicKey'] = d.data.hex()
                if d.type_id == TlvTypes.Permissions:
                    controller_type = 'regular'
                    if d.data == b'\x01':
                        controller_type = 'admin'
                    r['permissions'] = int.from_bytes(d.data,
                                                      byteorder='little')
                    r['controllerType'] = controller_type
            tmp.sort(key=lambda x: x['pairingId'])
            return tmp