-
Notifications
You must be signed in to change notification settings - Fork 82
Add GSM and Ethernet conn_manager + add fallback UDP based getTime() #31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Some operators return bogus getTime; if reported value is too low (generating it at compile time would be awesome) use fallback mode.
int connectionTickTimeInterval; | ||
GSMUDP Udp; | ||
void sendNTPpacket(const char * address, uint8_t* packetBuffer); | ||
unsigned long getNTPTime(); | ||
}; | ||
|
||
static const unsigned long NETWORK_CONNECTION_INTERVAL = 30000; | ||
|
||
GSMConnectionManager::GSMConnectionManager(const char *pin, const char *apn, const char *login, const char *pass) : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The member variables pin
, apn
, login
and pass
are only stored as const char pointers. This implies that those variables must be of global scope within the calling code, otherwise we might read invalid data if we read them at a later point in time. A alternative would be to copy the content of those variables into the class, e.g. via a String
data type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, the structure is the same as WiFi wrapper that "requires" variables with global scope. I'd be ok to switch to strings, but it should be something shared between all the wrappers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lxrobotics @facchinm
because we use them in the Web IDE to create fields in the Secret
tab, they are indeed globally defined for our cases.
storing them as String might make sense. I also side with @facchinm with having this kind of structure shared amongst the wrappers
Co-Authored-By: facchinm <[email protected]>
return; | ||
} | ||
break; | ||
case CONNECTION_STATE_GETTIME: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add an exit condition from the CONNECTION_STATE_GETTIME state in a similar way of the WiFiConnectionManager.
Fellows, I've been going through the source and although it will work with just a couple rectifications (such as @ilcato 's note related to |
- minor refactoring on WiFiConnectionManager
- changed library version to 0.5.1 (new feature: GSM)
- aligned INTERVAL definitions between WiFi and GSM
- fixed typo
ok folks |
- fixed typo in example - cleanup GSMConnectionManager - cleanup WiFiConnectionManager - fixed missing WiFiUDP member which broke compilation
- removed unnecessary call to _mqttReconnect(...) in ArduinoIoTCloud - removed unncessary begin() into case IOT_STATUS_IDLE in ArduinoIoTCloud - removed unnecessary calls to update() in CloudSerial - fixed if statement in ConnectionManager
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me 👍
The following include line is used for WiFi enabled boards (MKR1000, MKR WiFi 1010) | ||
*/ | ||
ConnectionManager *ArduinoIoTPreferredConnection = new WiFiConnectionManager(SECRET_SSID, SECRET_PASS); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A quick side note: Everything that follows is a suggestion for improvement and must not necessarily implemented within this PR. We can (and probably should) do cleanups in further PRs after this is merged.
A misconception, for which I've fallen myself until quite recently, is that if you instantiate derived classes with virtual functions in it (C++ runtime polymorphism) you always need to use the keyword new
, effectively allocating the memory on the heap at runtime. Interestingly enough, the following statement also works:
ConnectionManager *ArduinoIoTPreferredConnection = new WiFiConnectionManager(SECRET_SSID, SECRET_PASS); | |
WiFiConnectionManager connection_mgr(SECRET_SSID, SECRET_PASS); |
Doing it this way the memory for the object is allocated on the stack and not on the heap (static memory allocation vs dynamic memory allocation - prefer the former whenever possible/feasible). The reason above statement works is because of a C++ "feature" called object slicing.
Now object slicing has some pitfalls to it but it can be used effectively in this scenario where we have an abstract base class (= one or more pure virtual functions in it) ConnectionManager
from which WiFiConnectionManager
and GSMConnectionManager
are derived. ConnectionManager
serves to define the interface for the derived classes and only those functions defined within ConnectionManager
are called by users of the derived classes.
When passing the connection around to various classes you then have to use pass-by-reference.
void myFunc(ConnectionManager & connection_mgr) { ...
It´s also possible to store a reference of it as a class member variable.
class MyClass {
public:
void MyClass(ConnectionManager & connection_mgr) : _connection_mgr(connection_mgr) { ... }
void myMemberFunc();
private:
ConnectionManager & _connection_mgr;
};
The ConnectionManager
can than be accessed within member functions via the .
operator instead of ->
as would be the case if the ConnectionManager
would be stored as a pointer (ConnectionManager * _connection_mgr;
)
void MyClass:myMemberFunc() {
_connection_mgr.check();
}
Furthermore I'd also suggest to keep variable names in lowercase so to not confuse them with class/type names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interesting...
I'm gonna level up on this stuff for the next version.
Thanks, @lxrobotics
I'll proceed to merge this PR in :)
|
||
|
||
char ssid[] = SECRET_SSID; // your network SSID (name) | ||
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP) | ||
// Your THING_ID |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Your THING_ID | |
// Enter your THING_ID here |
@@ -43,14 +43,12 @@ typedef struct { | |||
extern ConnectionManager *ArduinoIoTPreferredConnection; | |||
|
|||
enum ArduinoIoTConnectionStatus { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it would be an idea to convert the enum into a enum class?
enum ArduinoIoTConnectionStatus { | |
enum class CloudConnectionState { | |
Idle, | |
Connecting, | |
Connected, | |
... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lxrobotics
I've been looking up enum class
and I think it's a great way to go, but not for this PR.
We're awaiting on this merge to move forward and release MKR GSM support which after this is merged in will be ready.
this will definitely end up in the next update :)
@@ -130,7 +128,7 @@ class ArduinoIoTCloudClass { | |||
ArduinoIoTConnectionStatus getIoTStatus() { return iotStatus; } | |||
void setIoTConnectionState(ArduinoIoTConnectionStatus _newState); | |||
private: | |||
ArduinoIoTConnectionStatus iotStatus = IOT_STATUS_IDLE; | |||
ArduinoIoTConnectionStatus iotStatus = IOT_STATUS_CLOUD_IDLE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case you want to go ahead with an enum class:
ArduinoIoTConnectionStatus iotStatus = IOT_STATUS_CLOUD_IDLE; | |
CloudConnectionState _iot_cloud_state = CloudConnectionState::Idle; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
No description provided.