flightonary / Moscapsule

MQTT Client for iOS written in Swift
MIT License
271 stars 70 forks source link

Use this library to connect with AWS IoT broker #22

Open sandeepp-cuelogic opened 8 years ago

sandeepp-cuelogic commented 8 years ago

Hello everyone,

We are developing an application which needs to consume AWS IoT service based on a MQTT protocol deviation. We are currently facing issues to get connected with MQTT broker provided by AWS IoT cloud server.

Following is the environment:

  1. iOS Version: 8.0 / 9.0
  2. Programming language: Swift
  3. Library for MQTT: Moscapsule

Steps followed: 1.Set initial config clientid, host, port 2.Set client certificate with private key, providing .pem file path (e.g. cert.pem, privateKey.pem) 3.Set server certificate which is root certificate .pem file path (e.g. rootCA.pem) 4.Set tls opts with tsl_insecure: false, cert_reqs: SSL_VERIFY_PEER, tls version: tlsv1.2, ciphers: nil

Problems faced: 1.When trying to connect to server/broker gives error “unable to create TLS_Context”. 2.With setting tls cert_reqs: SSL_VERIFY_NONE, gives connection status success with subcribe and publish sucess, but doesn’t reflect on server or broker.

Any help in this context is highly appreciable.

Thanks in advance.

teuteuguy commented 8 years ago

Am also interested in this. Have you found a solution ?

teuteuguy commented 8 years ago

I believe I've managed to get it to connect. However everytime I try to publish, I get a disconnect callback triggered, with unexpected response.

Any ideas ?

sandeepp-cuelogic commented 8 years ago

Hi teuteuguy,

Are you connecting with AWS broker? If so and getting connected with AWS broker, then info about security configuration would be helpful to us.

About getting disconnected after publish, does not seem to be problem, please try subscribing to a topic and publish message using MQTTfx ,, if app can receive messages published on subscribed topic, you are surely a step ahead.

Waiting to hear about security config. We tried using NO_VERIFY option, but its not making sense as we really need to verify peers for successful handshake.

Any ideas about this?

teuteuguy commented 8 years ago

Yes I'm using it on AWS IoT.

I've actually managed to get it to work now.

It was due to the qos setting in the publishString. The examples have it set to 2, but that fails. Putting it to 0 works fine.

sandeepp-cuelogic commented 8 years ago

That's nice to hear, mate!! Have you confirmed it by checking whether a subscriber gets that message?

teuteuguy commented 8 years ago

Yes, I use MQTTfx and have subscribed to the same topic. Messages are received.

sandeepp-cuelogic commented 8 years ago

That's great, will you mind sharing your configuration code, ours look like this

let certFilePath: String = NSBundle.mainBundle().pathForResource("rootCA", ofType: "pem")!

        let pathCert: String = NSBundle.mainBundle().pathForResource("cert", ofType: "pem")!

        let pathPrivateCert: String = NSBundle.mainBundle().pathForResource("privateKey", ofType: "pem")!
   mqttConfig = MQTTConfig(clientId: "person@company.com", host: "xxxxxxxxxxx.iot.us-east-1.amazonaws.com", port: 8883, keepAlive: 300)

        mqttConfig.mqttClientCert = MQTTClientCert(certfile: pathCert, keyfile: pathPrivateCert, keyfile_passwd: nil)

        mqttConfig.mqttServerCert = MQTTServerCert(cafile: nil, capath: certFilePath)

        mqttConfig.mqttTlsOpts = MQTTTlsOpts(tls_insecure: false, cert_reqs: CertReqs.SSL_VERIFY_PEER, tls_version: "tlsv1.2", ciphers: nil)

        mqttConfig.onPublishCallback = { messageId in
            NSLog("published (mid=\(messageId))")
        }

        mqttConfig.onMessageCallback = { mqttMessage in
            NSLog("MQTT Message received: payload=\(mqttMessage.payloadString)")
        }

So, we can figure out, if we are missing anything. Thanks.

teuteuguy commented 8 years ago

I'm not too sure about your code, cause I get the certes differently:

    let bundleURL = NSURL(fileURLWithPath: NSBundle(forClass: self.dynamicType).pathForResource("certs", ofType: "bundle")!)
    let certFile = bundleURL.URLByAppendingPathComponent("02dfc3747f-certificate.pem.crt").path!
    let keyFile = bundleURL.URLByAppendingPathComponent("02dfc3747f-private.pem.key").path!
    let rootCAFile = bundleURL.URLByAppendingPathComponent("root-CA.pem").path!

    mqttConfig.mqttClientCert = MQTTClientCert(certfile: certFile, keyfile: keyFile, keyfile_passwd: nil)
    mqttConfig.mqttServerCert = MQTTServerCert(cafile: rootCAFile, capath: nil)

Also, the clientId is the "thingName" in your AWS console, not your email.

sandeepp-cuelogic commented 8 years ago

Thanks for sharing details, but i suspect that when we set MQTTTlsOpts some thing is missing out,

mqttConfig.mqttTlsOpts = MQTTTlsOpts(tls_insecure: false, cert_reqs: CertReqs.SSL_VERIFY_PEER, tls_version: "tlsv1.2", ciphers: nil)

Do you set anything different from above settings? Apart from cert_reqs others are enums, so may be some gap is there.

buganini commented 7 years ago

Did you call moscapsule_init() before everything?