1#!/usr/local/bin/python3.8
2# -*- coding: utf-8 -*-
3
4# Copyright (c) 2017 Jon Levell <levell@uk.ibm.com>
5#
6# All rights reserved. This program and the accompanying materials
7# are made available under the terms of the Eclipse Distribution License v1.0
8# which accompanies this distribution.
9#
10# The Eclipse Distribution License is available at
11#   http://www.eclipse.org/org/documents/edl-v10.php.
12#
13# All rights reserved.
14
15# This shows a example of an MQTT subscriber with the ability to use
16# user name, password CA certificates based on command line arguments
17
18import paho.mqtt.client as mqtt
19import os
20import ssl
21import argparse
22
23parser = argparse.ArgumentParser()
24
25parser.add_argument('-H', '--host', required=False, default="mqtt.eclipse.org")
26parser.add_argument('-t', '--topic', required=False, default="$SYS/#")
27parser.add_argument('-q', '--qos', required=False, type=int, default=0)
28parser.add_argument('-c', '--clientid', required=False, default=None)
29parser.add_argument('-u', '--username', required=False, default=None)
30parser.add_argument('-d', '--disable-clean-session', action='store_true', help="disable 'clean session' (sub + msgs not cleared when client disconnects)")
31parser.add_argument('-p', '--password', required=False, default=None)
32parser.add_argument('-P', '--port', required=False, type=int, default=None, help='Defaults to 8883 for TLS or 1883 for non-TLS')
33parser.add_argument('-k', '--keepalive', required=False, type=int, default=60)
34parser.add_argument('-s', '--use-tls', action='store_true')
35parser.add_argument('--insecure', action='store_true')
36parser.add_argument('-F', '--cacerts', required=False, default=None)
37parser.add_argument('--tls-version', required=False, default=None, help='TLS protocol version, can be one of tlsv1.2 tlsv1.1 or tlsv1\n')
38parser.add_argument('-D', '--debug', action='store_true')
39
40args, unknown = parser.parse_known_args()
41
42
43def on_connect(mqttc, obj, flags, rc):
44    print("rc: " + str(rc))
45
46
47def on_message(mqttc, obj, msg):
48    print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))
49
50
51def on_publish(mqttc, obj, mid):
52    print("mid: " + str(mid))
53
54
55def on_subscribe(mqttc, obj, mid, granted_qos):
56    print("Subscribed: " + str(mid) + " " + str(granted_qos))
57
58
59def on_log(mqttc, obj, level, string):
60    print(string)
61
62usetls = args.use_tls
63
64if args.cacerts:
65    usetls = True
66
67port = args.port
68if port is None:
69    if usetls:
70        port = 8883
71    else:
72        port = 1883
73
74mqttc = mqtt.Client(args.clientid,clean_session = not args.disable_clean_session)
75
76if usetls:
77    if args.tls_version == "tlsv1.2":
78       tlsVersion = ssl.PROTOCOL_TLSv1_2
79    elif args.tls_version == "tlsv1.1":
80       tlsVersion = ssl.PROTOCOL_TLSv1_1
81    elif args.tls_version == "tlsv1":
82       tlsVersion = ssl.PROTOCOL_TLSv1
83    elif args.tls_version is None:
84       tlsVersion = None
85    else:
86       print ("Unknown TLS version - ignoring")
87       tlsVersion = None
88
89    if not args.insecure:
90        cert_required = ssl.CERT_REQUIRED
91    else:
92        cert_required = ssl.CERT_NONE
93
94    mqttc.tls_set(ca_certs=args.cacerts, certfile=None, keyfile=None, cert_reqs=cert_required, tls_version=tlsVersion)
95
96    if args.insecure:
97        mqttc.tls_insecure_set(True)
98
99if args.username or args.password:
100    mqttc.username_pw_set(args.username, args.password)
101
102mqttc.on_message = on_message
103mqttc.on_connect = on_connect
104mqttc.on_publish = on_publish
105mqttc.on_subscribe = on_subscribe
106
107if args.debug:
108    mqttc.on_log = on_log
109
110print("Connecting to "+args.host+" port: "+str(port))
111mqttc.connect(args.host, port, args.keepalive)
112mqttc.subscribe(args.topic, args.qos)
113
114mqttc.loop_forever()
115