3333
3434static size_t const CBOR_LORA_MSG_MAX_SIZE = 255 ;
3535
36+ /* *****************************************************************************
37+ LOCAL MODULE FUNCTIONS
38+ ******************************************************************************/
39+
40+ extern " C" unsigned long getTime ()
41+ {
42+ return ArduinoCloud.getInternalTime ();
43+ }
44+
3645/* *****************************************************************************
3746 CTOR/DTOR
3847 ******************************************************************************/
3948
4049ArduinoIoTCloudLPWAN::ArduinoIoTCloudLPWAN ()
41- : _retryEnable{false }
50+ : _state{State::ConnectPhy}
51+ , _retryEnable{false }
4252, _maxNumRetry{5 }
4353, _intervalRetry{1000 }
4454{
@@ -58,45 +68,21 @@ int ArduinoIoTCloudLPWAN::begin(ConnectionHandler& connection, bool retry)
5868{
5969 _connection = &connection;
6070 _retryEnable = retry;
71+ _time_service.begin (nullptr );
6172 return 1 ;
6273}
6374
6475void ArduinoIoTCloudLPWAN::update ()
6576{
66- // Check if a primitive property wrapper is locally changed
67- updateTimestampOnLocallyChangedProperties (_property_container);
68-
69- ArduinoIoTConnectionStatus next_iot_status = _iot_status;
70-
71- /* Since we do not have a direct connection to the Arduino IoT Cloud servers
72- * there is no such thing is a 'cloud connection state' since the LoRa
73- * board connection state to the gateway is all the information we have.
74- */
75- NetworkConnectionState const net_con_state = checkPhyConnection ();
76- if (net_con_state == NetworkConnectionState::CONNECTED) { next_iot_status = ArduinoIoTConnectionStatus::CONNECTED; execCloudEventCallback (ArduinoIoTCloudEvent::CONNECT); }
77- else if (net_con_state == NetworkConnectionState::CONNECTING) { next_iot_status = ArduinoIoTConnectionStatus::CONNECTING; }
78- else if (net_con_state == NetworkConnectionState::DISCONNECTED) { next_iot_status = ArduinoIoTConnectionStatus::DISCONNECTED; execCloudEventCallback (ArduinoIoTCloudEvent::DISCONNECT); }
79-
80- if (next_iot_status != _iot_status)
77+ /* Run through the state machine. */
78+ State next_state = _state;
79+ switch (_state)
8180 {
82- printConnectionStatus (next_iot_status);
83- _iot_status = next_iot_status;
84- }
85-
86- if (net_con_state != NetworkConnectionState::CONNECTED) return ;
87-
88- if (_connection->available ()) {
89- uint8_t msgBuf[CBOR_LORA_MSG_MAX_SIZE];
90- uint8_t i = 0 ;
91- while (_connection->available ()) {
92- msgBuf[i++] = _connection->read ();
93- }
94-
95- CBORDecoder::decode (_property_container, msgBuf, sizeof (msgBuf));
81+ case State::ConnectPhy: next_state = handle_ConnectPhy (); break ;
82+ case State::SyncTime: next_state = handle_SyncTime (); break ;
83+ case State::Connected: next_state = handle_Connected (); break ;
9684 }
97-
98- sendPropertiesToCloud ();
99- execCloudEventCallback (ArduinoIoTCloudEvent::SYNC);
85+ _state = next_state;
10086}
10187
10288void ArduinoIoTCloudLPWAN::printDebugInfo ()
@@ -106,23 +92,58 @@ void ArduinoIoTCloudLPWAN::printDebugInfo()
10692}
10793
10894/* *****************************************************************************
109- * PROTECTED MEMBER FUNCTIONS
95+ * PRIVATE MEMBER FUNCTIONS
11096 ******************************************************************************/
11197
112- int ArduinoIoTCloudLPWAN::connect ()
98+ ArduinoIoTCloudLPWAN::State ArduinoIoTCloudLPWAN::handle_ConnectPhy ()
11399{
114- _connection->connect ();
115- return 1 ;
100+ if (_connection->check () == NetworkConnectionState::CONNECTED)
101+ return State::SyncTime;
102+ else
103+ return State::ConnectPhy;
116104}
117105
118- void ArduinoIoTCloudLPWAN::disconnect ()
106+ ArduinoIoTCloudLPWAN::State ArduinoIoTCloudLPWAN::handle_SyncTime ()
119107{
120- _connection->disconnect ();
108+ unsigned long const internal_posix_time = _time_service.getTime ();
109+ DBG_VERBOSE (" ArduinoIoTCloudLPWAN::%s internal clock configured to posix timestamp %d" , __FUNCTION__, internal_posix_time);
110+ DBG_INFO (" Connected to Arduino IoT Cloud" );
111+ return State::Connected;
121112}
122113
123- /* *****************************************************************************
124- * PRIVATE MEMBER FUNCTIONS
125- ******************************************************************************/
114+ ArduinoIoTCloudLPWAN::State ArduinoIoTCloudLPWAN::handle_Connected ()
115+ {
116+ if (!connected ())
117+ {
118+ DBG_ERROR (" ArduinoIoTCloudLPWAN::%s connection to gateway lost" , __FUNCTION__);
119+ return State::ConnectPhy;
120+ }
121+
122+ /* Check if a primitive property wrapper is locally changed. */
123+ updateTimestampOnLocallyChangedProperties (_property_container);
124+
125+ /* Decode available data. */
126+ if (_connection->available ())
127+ decodePropertiesFromCloud ();
128+
129+ /* If properties need updating sent them to the cloud. */
130+ sendPropertiesToCloud ();
131+
132+ return State::Connected;
133+ }
134+
135+ void ArduinoIoTCloudLPWAN::decodePropertiesFromCloud ()
136+ {
137+ uint8_t lora_msg_buf[CBOR_LORA_MSG_MAX_SIZE];
138+ size_t bytes_received;
139+ for (bytes_received = 0 ;
140+ _connection->available () && (bytes_received < CBOR_LORA_MSG_MAX_SIZE);
141+ bytes_received++)
142+ {
143+ lora_msg_buf[bytes_received] = _connection->read ();
144+ }
145+ CBORDecoder::decode (_property_container, lora_msg_buf, bytes_received);
146+ }
126147
127148void ArduinoIoTCloudLPWAN::sendPropertiesToCloud ()
128149{
@@ -138,7 +159,8 @@ int ArduinoIoTCloudLPWAN::writeProperties(const byte data[], int length)
138159{
139160 int retcode = _connection->write (data, length);
140161 int i = 0 ;
141- while (_retryEnable && retcode < 0 && i < _maxNumRetry) {
162+ while (_retryEnable && retcode < 0 && i < _maxNumRetry)
163+ {
142164 delay (_intervalRetry);
143165 retcode = _connection->write (data, length);
144166 i++;
0 commit comments