odyshewroman / AndroidTVRemoteControl

MIT License
30 stars 9 forks source link

Certificate Duplicate everytime #14

Closed Jacky154 closed 9 months ago

Jacky154 commented 9 months ago

Hi

Forgive for again and again problems. But i need the answer of it. It really mandatory for me as I am working on it for a very long time and Also I don't have a smart tv so I can't test the project again and again. I would be thankful to you. Just 2 questions.

  1. I need to know if I duplicate the certificate and delete old one everytime whenever we open the app, then If I pair with tv will it show the code on tv. I just want to know whether the certificate store the data that we connect with tv or not. So If i duplicate the certificate and delete old one, In this way will tv again show the code. I did like this Kindly check it whether it works or not.

func generateCertificates() { // Delete old cert.der let oldPemURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("cert.der") do { try FileManager.default.removeItem(at: oldPemURL!) print("Old cert.der deleted successfully.") } catch { print("Error deleting old cert.der: (error)") }

// Delete old cert.p12
let oldP12URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("cert.p12")
do {
    try FileManager.default.removeItem(at: oldP12URL!)
    print("Old cert.p12 deleted successfully.")
} catch {
    print("Error deleting old cert.p12: \(error)")
}

// Generate new cert.der
if let sourceURL = Bundle.main.url(forResource: "cert2", withExtension: "der"),
   let destinationURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("cert.der") {
    do {
        try FileManager.default.copyItem(at: sourceURL, to: destinationURL)
        print("New cert.der generated successfully.")
    } catch {
        print("Error copying new cert.der: \(error)")
    }
}

// Generate new cert.p12
if let sourceURL = Bundle.main.url(forResource: "cert2", withExtension: "p12"),
   let destinationURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("cert.p12") {
    do {
        try FileManager.default.copyItem(at: sourceURL, to: destinationURL)
        print("New cert.p12 generated successfully.")
    } catch {
        print("Error copying new cert.p12: \(error)")
    }
}

}

  1. Is this correct code (below one). In which when case waitingcode then I am calling the callback function pairingSuccess and when case successPaired then I am calling the callback function pairedback. Is this correct in connect function

func connect(host: String) { queue.async { self.remoteManager.stateChanged = { [weak self] remoteState in self?.remoteStateChanged?(remoteState.toString())

            if case .error(.connectionWaitingError) = remoteState {
                self?.pairingManager.stateChanged = { pairingState in
                    self?.pairingStateChanged?(pairingState.toString())
                   if case .waitingCode = pairingState {
                       self?.pairingSuccess?()
                   }
                    if case .successPaired = pairingState {
                        self?.remoteManager.connect(host)
                        self?.pairedback?()
                    }
                }

                self?.pairingManager.connect(host, "client", "iPhone")
            }
        }

        self.remoteManager.connect(host)
        self.connectionDelegate?.successConnect()
       self.pairedback?()
    }
}

And I am calling this connect function in my another file like this. When pairedback then I am navigating to another screen(Is this correct)

@objc private func sendCode() {

    guard let code = txtCode.text else {
        return
    }

    self.remoteManager.sendCode(code: code)

    self.remoteManager.pairedback = { [weak self] in
        DispatchQueue.main.async {
            self?.navigateToRemote()
        }
    }

    self.navigateToRemote()
}

@objc private func skipcode() {
    self.navigateToRemote()
}

}

It would be grateful and very helpful for me if you reply.

Jacky154 commented 9 months ago

Hi

Forgive for again and again problems. But i need the answer of it. It really mandatory for me as I am working on it for a very long time and Also I don't have a smart tv so I can't test the project again and again. I would be thankful to you. Just 2 questions.

  1. I need to know if I duplicate the certificate and delete old one everytime whenever we open the app, then If I pair with tv will it show the code on tv. I just want to know whether the certificate store the data that we connect with tv or not. So If i duplicate the certificate and delete old one, In this way will tv again show the code. I did like this Kindly check it whether it works or not.

func generateCertificates() { // Delete old cert.der let oldPemURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("cert.der") do { try FileManager.default.removeItem(at: oldPemURL!) print("Old cert.der deleted successfully.") } catch { print("Error deleting old cert.der: (error)") }

// Delete old cert.p12
let oldP12URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("cert.p12")
do {
    try FileManager.default.removeItem(at: oldP12URL!)
    print("Old cert.p12 deleted successfully.")
} catch {
    print("Error deleting old cert.p12: \(error)")
}

// Generate new cert.der
if let sourceURL = Bundle.main.url(forResource: "cert2", withExtension: "der"),
   let destinationURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("cert.der") {
    do {
        try FileManager.default.copyItem(at: sourceURL, to: destinationURL)
        print("New cert.der generated successfully.")
    } catch {
        print("Error copying new cert.der: \(error)")
    }
}

// Generate new cert.p12
if let sourceURL = Bundle.main.url(forResource: "cert2", withExtension: "p12"),
   let destinationURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("cert.p12") {
    do {
        try FileManager.default.copyItem(at: sourceURL, to: destinationURL)
        print("New cert.p12 generated successfully.")
    } catch {
        print("Error copying new cert.p12: \(error)")
    }
}

}

  1. Is this correct code (below one). In which when case waitingcode then I am calling the callback function pairingSuccess and when case successPaired then I am calling the callback function pairedback. Is this correct in connect function

func connect(host: String) { queue.async { self.remoteManager.stateChanged = { [weak self] remoteState in self?.remoteStateChanged?(remoteState.toString())

            if case .error(.connectionWaitingError) = remoteState {
                self?.pairingManager.stateChanged = { pairingState in
                    self?.pairingStateChanged?(pairingState.toString())
                   if case .waitingCode = pairingState {
                       self?.pairingSuccess?()
                   }
                    if case .successPaired = pairingState {
                        self?.remoteManager.connect(host)
                        self?.pairedback?()
                    }
                }

                self?.pairingManager.connect(host, "client", "iPhone")
            }
        }

        self.remoteManager.connect(host)
        self.connectionDelegate?.successConnect()
       self.pairedback?()
    }
}

And I am calling this connect function in my another file like this. When pairedback then I am navigating to another screen(Is this correct)

@objc private func sendCode() {

    guard let code = txtCode.text else {
        return
    }

    self.remoteManager.sendCode(code: code)

    self.remoteManager.pairedback = { [weak self] in
        DispatchQueue.main.async {
            self?.navigateToRemote()
        }
    }

    self.navigateToRemote()
}

@objc private func skipcode() {
    self.navigateToRemote()
}

}

It would be grateful and very helpful for me if you reply.

Hi, Please reply It.

Kindly I need to complete it today

odyshewroman commented 9 months ago

Sorry, but I don't understand why you need such complicated tricks to retrieve the code from the TV each time. For this behavior, it's enough to just call the connecting function every time (from PairingManager).

The smart TV does not save the certificate. You should familiarize yourself with how TLS connections work. The devices exchange public keys of certificates and then generate a session key, keeping only that.

Jacky154 commented 9 months ago

I understand but It is not working. I check the connect function of pairingmanager it stucks at waitingcode state and do not reach at successPaired after input the code

odyshewroman commented 9 months ago

Whats happened when you send code to Android TV device? The device should reply something, wrong code or success paired, whatever. In anyway, I have added logging opportunity, What's the logs say?

Jacky154 commented 9 months ago

Actually after sending code nothing happen. I mean state not changed when I try case .error in pairingState then I got this error

connectionWaitingError(POSIXErrorCode(rawValue: 60): Operation timed out)

You handle this error in your project, but there this error occur only first time pairing with tv and code also shown first time, While I want to show code everytime even in case if there is no error or case I already paired. I mean i just want to show code everytime in error case or not any error case.

I am using your this code

func connect(host: String){ queue.async { self.remoteManager.stateChanged = { [weak self] remoteState in self?.remoteStateChanged?(remoteState.toString()) }

        self.pairingManager.stateChanged = { [weak self] pairingState in
            self?.pairingStateChanged?(pairingState.toString())

if case .waitingCode = pairingState {

self?.pairingSuccess?() }

if case .successPaired = pairingState { self?.remoteManager.connect(host) self?.pairedback?() } }

        self.pairingManager.connect(host, "client", "iPhone")
    }

}

odyshewroman commented 9 months ago

First of all, let's respect each other and not send unformatted code. Do you see your message? If you want someone to help solve your problem, don't burden them with formatting your code from the message.

Secondly, I am not sure if you are sending the code to an Android TV device.

When you send the code, does your Android TV device immediately hide the code from the screen?

If you turn on debugging, do you receive the message: Debug: code: <your code> on the debug area?

Jacky154 commented 9 months ago

Hi,

Sorry for unformatted code.

I am sending the code to the android tv device when states reached at waitingCode but It not reaching at state of pairedSuccess after sending code to tv. It gives connectionWaitingError

Actually the code shown but pairingSuccess function (It is calling back function which calls when I reach at waitingCode state so that I show the input field to user to enter code display on tv) call again and again, I mean it calls 3 times in case .waitingCode. For this I attach flags on it so that it runs only one time.

The debugging case I just received the error which I described above.

I think you solve this error already in your project but the problem is I can't Integrate that error in the above code

Thanks for help

odyshewroman commented 9 months ago

Ohhh... Complicated to understand, send me your project or your demo if you have some private data, for I can trying to figure out where is mistake.

Jacky154 commented 9 months ago

TVController.zip

ok kindly try this. Two files one is your remoteTVManager from demo project check the connect function I want to get code everytime, second is writecodevc which is slighlty connecting to remoteTVManager file, I send this file so that you easily understand.

I just want to show code everytime but I got error and not reacing at successPaired state

Thanks

Jacky154 commented 9 months ago

Hi,

Bro you got any solution ?

Jacky154 commented 9 months ago

I got these messages in debug mode:

(lldb) po pairingState TVController.PairingManager.PairingState.extractTLSparams 2024-01-04 12:45:46.213204+0530 TVController[2669:525173] [SystemGestureGate] <0x137e16ef0> Gesture: System gesture gate timed out. (lldb) po pairingState TVController.PairingManager.PairingState.connectionPrepairing

Jacky154 commented 9 months ago

Bro can you please help. The problem is only after .waitingCode I am not reaching at any other state. I am trying to connect with tv using remoteManager.connect() and it shows me paired because I already connected with tv before. But now I try to pair again with tv using pairingManager.connect() but It stuck at .waitingCode and do not reaching to next state means .secretState

odyshewroman commented 9 months ago

There is no secretState, there is secretSent state, you not reach it cause you not send code, I tired of this thread.

Jacky154 commented 9 months ago

I tried it everything is working fine. Even when I just test your demo then in that case it also works. But now It is not working. When reaches at waitingCode state it suddenly give waitingConnectionError, I am trying your code which you gives previously for getting code everytime. Kindly help bro. Can you write code in which I get code everytime with some states handler (Waitingcode and successPaired) and then connect with tv using remoteManager.connect()

I appreciate your help. Thanks