Skip to content

Commit b012b00

Browse files
committed
Release of version 1.1.0
1 parent b06a970 commit b012b00

File tree

25 files changed

+3106
-182
lines changed

25 files changed

+3106
-182
lines changed

AWS-IoT-Arduino-Yun-Library/aws_iot_config_SDK.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@
1818

1919
#define MAX_BUF_SIZE 256 // maximum number of bytes to publish/receive
2020
#define MAX_SUB 15 // maximum number of subscribe
21-
#define CMD_TIME_OUT 100 // maximum time to wait for feedback from AR9331, 100 = 10 sec
21+
#define CMD_TIME_OUT 200 // maximum time to wait for feedback from AR9331, 200 = 10 sec
2222

2323
#endif

AWS-IoT-Arduino-Yun-Library/aws_iot_error.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ typedef enum {
5252
SHADOW_DELETE_GENERIC_ERROR = -32,
5353
SHADOW_REGISTER_DELTA_CALLBACK_GENERIC_ERROR = -33,
5454
SHADOW_UNREGISTER_DELTA_CALLBACK_GENERIC_ERROR = -34,
55-
YIELD_ERROR = -35
55+
YIELD_ERROR = -35,
56+
WEBSOCKET_CREDENTIAL_NOT_FOUND = -36
5657
} IoT_Error_t;
5758

5859
#endif

AWS-IoT-Arduino-Yun-Library/aws_iot_mqtt.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ Baud_t aws_iot_mqtt_client::find_baud_type() {
4747
return rc_type;
4848
}
4949

50-
IoT_Error_t aws_iot_mqtt_client::setup_exec(char* client_id, bool clean_session, MQTTv_t MQTT_version) {
50+
IoT_Error_t aws_iot_mqtt_client::setup_exec(char* client_id, bool clean_session, MQTTv_t MQTT_version, bool useWebsocket) {
5151
// Serial1 is started before this call
5252
IoT_Error_t rc = NONE_ERROR;
5353
exec_cmd("cd /root/AWS-IoT-Python-Runtime/runtime/\n", false, false);
5454
exec_cmd("python run.py\n", false, false);
5555

5656
// Create obj
57-
exec_cmd("4\n", false, false);
57+
exec_cmd("5\n", false, false);
5858

5959
exec_cmd("i\n", false, false);
6060

@@ -66,6 +66,11 @@ IoT_Error_t aws_iot_mqtt_client::setup_exec(char* client_id, bool clean_session,
6666
exec_cmd(rw_buf, false, false);
6767

6868
sprintf(rw_buf, "%u\n", MQTT_version);
69+
exec_cmd(rw_buf, false, false);
70+
71+
// Websocket flag
72+
num_temp = useWebsocket ? 1 : 0;
73+
sprintf(rw_buf, "%d\n", num_temp);
6974
exec_cmd(rw_buf, true, false);
7075

7176
if(strncmp(rw_buf, "I T", 3) != 0) {
@@ -76,7 +81,7 @@ IoT_Error_t aws_iot_mqtt_client::setup_exec(char* client_id, bool clean_session,
7681
return rc;
7782
}
7883

79-
IoT_Error_t aws_iot_mqtt_client::setup(char* client_id, bool clean_session, MQTTv_t MQTT_version) {
84+
IoT_Error_t aws_iot_mqtt_client::setup(char* client_id, bool clean_session, MQTTv_t MQTT_version, bool useWebsocket) {
8085
IoT_Error_t rc = NONE_ERROR;
8186
if(client_id == NULL) {rc = NULL_VALUE_ERROR;}
8287
else if(strlen(client_id) >= MAX_BUF_SIZE) {rc = OVERFLOW_ERROR;}
@@ -86,13 +91,17 @@ IoT_Error_t aws_iot_mqtt_client::setup(char* client_id, bool clean_session, MQTT
8691
// Communication failed due to baud rate issue
8792
if(BAUD_TYPE_UNKNOWN == baud_type) {rc = SERIAL1_COMMUNICATION_ERROR;}
8893
else {
89-
rc = setup_exec(client_id, clean_session, MQTT_version);
94+
rc = setup_exec(client_id, clean_session, MQTT_version, useWebsocket);
9095
}
9196
}
9297

9398
return rc;
9499
}
95100

101+
IoT_Error_t aws_iot_mqtt_client::configWss(char* host, int port, char* cafile_path) {
102+
return config(host, port, cafile_path, "", ""); // No need for key and cert, IAM credentials are used.
103+
}
104+
96105
IoT_Error_t aws_iot_mqtt_client::config(char* host, int port, char* cafile_path, char* keyfile_path, char* certfile_path) {
97106
IoT_Error_t rc = NONE_ERROR;
98107

@@ -154,6 +163,7 @@ IoT_Error_t aws_iot_mqtt_client::connect(int keepalive_interval) {
154163
else if(strncmp(rw_buf, "C4F", 3) == 0) {rc = CONNECT_ERROR;}
155164
else if(strncmp(rw_buf, "C5F", 3) == 0) {rc = CONNECT_TIMEOUT;}
156165
else if(strncmp(rw_buf, "C6F", 3) == 0) {rc = CONNECT_CREDENTIAL_NOT_FOUND;}
166+
else if(strncmp(rw_buf, "C7F", 3) == 0) {rc = WEBSOCKET_CREDENTIAL_NOT_FOUND;}
157167
else if(strncmp(rw_buf, "CFF", 3) == 0) {rc = CONNECT_GENERIC_ERROR;}
158168
else rc = GENERIC_ERROR;
159169
}
@@ -609,10 +619,10 @@ void aws_iot_mqtt_client::exec_cmd(const char* cmd, bool wait, bool single_line)
609619
timeout_flag = false;
610620
timeout_sec = 0;
611621
// step2: waiting
612-
delay(10);
622+
delay(6);
613623
if(wait) {
614624
while(timeout_sec < CMD_TIME_OUT && !Serial1.available()) {
615-
delay(100); // 0.1 sec
625+
delay(50); // 50 ms
616626
timeout_sec++;
617627
}
618628
}
@@ -637,7 +647,6 @@ void aws_iot_mqtt_client::exec_cmd(const char* cmd, bool wait, bool single_line)
637647
}
638648
timeout_flag = false; // Clear timeout flag
639649
rw_buf[ptr] = '\0'; // add terminator in case of garbage data in rw_buf
640-
// printf("%s\n------\n", rw_buf);
641650
}
642651

643652
int aws_iot_mqtt_client::find_unused_subgroup() {

AWS-IoT-Arduino-Yun-Library/aws_iot_mqtt.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ class aws_iot_mqtt_client {
4747
sub_group[i].callback = NULL;
4848
}
4949
}
50-
IoT_Error_t setup(char* client_id, bool clean_session=true, MQTTv_t MQTT_version=MQTTv311);
50+
IoT_Error_t setup(char* client_id, bool clean_session=true, MQTTv_t MQTT_version=MQTTv311, bool useWebsocket=false);
5151
IoT_Error_t config(char* host, int port, char* cafile_path, char* keyfile_path, char* certfile_path);
52+
IoT_Error_t configWss(char* host, int port, char* cafile_path);
5253
IoT_Error_t connect(int keepalive_interval=60);
5354
IoT_Error_t publish(char* topic, char* payload, int payload_len, int qos, bool retain);
5455
IoT_Error_t subscribe(char* topic, int qos, message_callback cb);
@@ -74,7 +75,7 @@ class aws_iot_mqtt_client {
7475
bool timeout_flag; // Is there a timeout when executing RPC
7576
IoT_Error_t base_subscribe(char* topic, int qos, message_callback cb, int is_delta);
7677
Baud_t find_baud_type();
77-
IoT_Error_t setup_exec(char* client_id, bool clean_session, MQTTv_t MQTT_version);
78+
IoT_Error_t setup_exec(char* client_id, bool clean_session, MQTTv_t MQTT_version, bool useWebsocket);
7879
void exec_cmd(const char* cmd, bool wait, bool single_line);
7980
int find_unused_subgroup();
8081
void clearProtocolOnSerialBegin(long baudrate);

AWS-IoT-Arduino-Yun-Library/aws_iot_version.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
#define version_h
1818

1919
#define VERSION_MAJOR 1
20-
#define VERSION_MINOR 0
21-
#define VERSION_PATCH 3
20+
#define VERSION_MINOR 1
21+
#define VERSION_PATCH 0
2222
#define VERSION_TAG ""
2323

2424
#endif

AWS-IoT-Arduino-Yun-Library/keywords.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ aws_iot_version KEYWORD1
44
aws_iot_config KEYWORD1
55
setup KEYWORD2
66
config KEYWORD2
7+
configWss KEYWORD2
78
connect KEYWORD2
89
publish KEYWORD2
910
subscribe KEYWORD2
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Please place your credentials in this directory.

AWS-IoT-Python-Runtime/lib/command/commandConnect.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ def execute(self):
5555
returnMessage = "C5F: " + str(e.message)
5656
except IOError as e:
5757
returnMessage = "C6F: " + "Credentials not found."
58+
except ValueError as e:
59+
returnMessage = "C7F: " + "Key/KeyID not in $ENV."
5860
except Exception as e:
5961
returnMessage = "CFF: " + "Unknown error."
6062
self._serialCommServerHandler.writeToInternalProtocol(returnMessage)

AWS-IoT-Python-Runtime/lib/exception/AWSIoTExceptions.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,14 @@ def __init__(self, errorCode):
7575
class unsubscribeError(operationError.operationError):
7676
def __init__(self, errorCode):
7777
self.message = "Unsubscribe Error: " + str(errorCode)
78+
79+
80+
# Websocket Error
81+
class wssNoKeyInEnvironmentError(operationError.operationError):
82+
def __init__(self):
83+
self.message = "No AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY detected in $ENV."
84+
85+
86+
class wssHandShakeError(operationError.operationError):
87+
def __init__(self):
88+
self.message = "Error in WSS handshake."

AWS-IoT-Python-Runtime/lib/protocol/mqttCore.py

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
sys.path.append("../lib/")
2121
import ssl
2222
import time
23-
import paho.mqtt.client as mqtt
23+
import thread
24+
import protocol.paho.client as mqtt
2425
from threading import Lock
2526
from exception.AWSIoTExceptions import connectError
2627
from exception.AWSIoTExceptions import connectTimeoutException
@@ -45,6 +46,10 @@ class mqttCore:
4546
_unsubscribeSent = False
4647
_connectdisconnectTimeout = 0 # Default connect/disconnect timeout set to 0 second
4748
_mqttOperationTimeout = 0 # Default MQTT operation timeout set to 0 second
49+
# Use websocket
50+
_useWebsocket = False
51+
# Subscribe record
52+
_subscribePool = dict()
4853
# Broker information
4954
_host = ""
5055
_port = -1
@@ -76,13 +81,25 @@ def getMQTTOperationTimeoutSecond(self):
7681
def setUserData(self, srcUserData):
7782
self._pahoClient.user_data_set(srcUserData)
7883

79-
def createPahoClient(self, clientID, cleanSession, userdata, protocol):
80-
return mqtt.Client(clientID, cleanSession, userdata, protocol) # Throw exception when error happens
84+
def createPahoClient(self, clientID, cleanSession, userdata, protocol, useWebsocket):
85+
return mqtt.Client(clientID, cleanSession, userdata, protocol, useWebsocket) # Throw exception when error happens
86+
87+
def _doResubscribe(self):
88+
if self._connectResultCode == 0: # If this is a successful connect...
89+
for key in self._subscribePool.keys():
90+
qos, callback = self._subscribePool.get(key)
91+
try:
92+
self.subscribe(key, qos, callback)
93+
except subscribeError:
94+
pass
95+
except subscribeTimeoutException:
96+
pass # Subscribe error resulted from network error, will redo subscription in the next re-connect
8197

8298
# Callbacks
8399
def on_connect(self, client, userdata, flags, rc):
84100
self._disconnectResultCode = sys.maxint
85101
self._connectResultCode = rc
102+
thread.start_new_thread(self._doResubscribe, ())
86103
self._log.writeLog("Connect result code " + str(rc))
87104

88105
def on_disconnect(self, client, userdata, rc):
@@ -103,18 +120,19 @@ def on_message(self, client, userdata, message):
103120
self._log.writeLog("Received (No custom callback registered) : message: " + str(message.payload) + " from topic: " + str(message.topic))
104121

105122
####### API starts here #######
106-
def __init__(self, clientID, cleanSession, protocol, srcLogManager):
123+
def __init__(self, clientID, cleanSession, protocol, srcLogManager, srcUseWebsocket=False):
107124
if clientID is None or cleanSession is None or protocol is None or srcLogManager is None:
108125
raise TypeError("None type inputs detected.")
109126
self._log = srcLogManager
110127
self._clientID = clientID
111-
self._pahoClient = self.createPahoClient(clientID, cleanSession, None, protocol) # User data is set to None as default
128+
self._pahoClient = self.createPahoClient(clientID, cleanSession, None, protocol, srcUseWebsocket) # User data is set to None as default
112129
self._log.writeLog("Paho MQTT Client init.")
113130
self._pahoClient.on_connect = self.on_connect
114131
self._pahoClient.on_disconnect = self.on_disconnect
115132
self._pahoClient.on_message = self.on_message
116133
self._pahoClient.on_subscribe = self.on_subscribe
117134
self._pahoClient.on_unsubscribe = self.on_unsubscribe
135+
self._useWebsocket = srcUseWebsocket
118136
self._log.writeLog("Register Paho MQTT Client callbacks.")
119137
self._log.writeLog("mqttCore init.")
120138

@@ -135,7 +153,10 @@ def connect(self, keepAliveInterval=60):
135153
# Return connect succeeded/failed
136154
ret = False
137155
# TLS configuration
138-
self._pahoClient.tls_set(self._cafile, self._cert, self._key, ssl.CERT_REQUIRED, ssl.PROTOCOL_SSLv23) # Throw exception...
156+
if self._useWebsocket:
157+
self._pahoClient.tls_set(ca_certs=self._cafile, cert_reqs=ssl.CERT_REQUIRED, tls_version=ssl.PROTOCOL_SSLv23)
158+
else:
159+
self._pahoClient.tls_set(self._cafile, self._cert, self._key, ssl.CERT_REQUIRED, ssl.PROTOCOL_SSLv23) # Throw exception...
139160
# Connect
140161
self._pahoClient.connect(self._host, self._port, keepAliveInterval) # Throw exception...
141162
self._pahoClient.loop_start()
@@ -215,6 +236,7 @@ def subscribe(self, topic, qos, callback):
215236
if(self._subscribeSent):
216237
ret = rc == 0
217238
if(ret):
239+
self._subscribePool[topic] = (qos, callback)
218240
self._log.writeLog("Subscribe request " + str(mid) + " succeeded. Time consumption: " + str(float(TenmsCount) * 10) + "ms.")
219241
else:
220242
if(callback is not None):
@@ -252,6 +274,10 @@ def unsubscribe(self, topic):
252274
if(self._unsubscribeSent):
253275
ret = rc == 0
254276
if(ret):
277+
try:
278+
del self._subscribePool[topic]
279+
except KeyError:
280+
pass # Ignore topic that is never subscribed to
255281
self._log.writeLog("Unsubscribe request " + str(mid) + " succeeded. Time consumption: " + str(float(TenmsCount) * 10) + "ms.")
256282
self._pahoClient.message_callback_remove(topic)
257283
self._log.writeLog("Remove the callback.")

0 commit comments

Comments
 (0)