Skip to content

Commit b977c1a

Browse files
authored
Merge pull request #1053 from pennam/catm1-retry-rebased
GSM patches to allow retries if connection fails
2 parents 32e34dc + 2f127e7 commit b977c1a

26 files changed

+772
-51
lines changed

cores/arduino/mbed/connectivity/cellular/include/cellular/framework/API/CellularDevice.h

+11
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,17 @@ class CellularDevice {
201201
*/
202202
virtual nsapi_error_t soft_power_off() = 0;
203203

204+
/** Resets the modem via AT command
205+
*
206+
* @remark CellularStateMachine disconnect or destruct does not reset the modem,
207+
* but you need to do that yourself.
208+
*
209+
* @pre You must call shutdown to prepare the modem for reset.
210+
*
211+
* @return NSAPI_ERROR_OK on success
212+
*/
213+
virtual nsapi_error_t soft_reset() = 0;
214+
204215
/** Open the SIM card by setting the pin code for SIM.
205216
*
206217
* @param sim_pin PIN for the SIM card

cores/arduino/mbed/connectivity/cellular/include/cellular/framework/AT/AT_CellularDevice.h

+2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ class AT_CellularDevice : public CellularDevice {
8080

8181
virtual nsapi_error_t soft_power_off();
8282

83+
virtual nsapi_error_t soft_reset();
84+
8385
virtual nsapi_error_t set_pin(const char *sim_pin);
8486

8587
virtual nsapi_error_t get_sim_state(SimState &state);

cores/arduino/mbed/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION.h

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ class GEMALTO_CINTERION : public AT_CellularDevice {
5555

5656
protected:
5757
virtual nsapi_error_t init();
58+
virtual nsapi_error_t shutdown();
59+
virtual nsapi_error_t soft_power_off();
60+
virtual nsapi_error_t soft_reset();
5861

5962
private:
6063
static Module _module;

cores/arduino/mbed/connectivity/drivers/cellular/GEMALTO/CINTERION/GEMALTO_CINTERION_CellularStack.h

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class GEMALTO_CINTERION_CellularStack : public AT_CellularStack {
4343
void stopGNSS();
4444
void PSMEnable();
4545
void PSMDisable();
46+
int ping(const char *host, int ttl);
4647

4748
protected:
4849

libraries/GSM/src/GSM.cpp

+85-28
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,28 @@ mbed::CellularDevice *mbed::CellularDevice::get_default_instance()
4646

4747
int arduino::GSMClass::begin(const char* pin, const char* apn, const char* username, const char* password, RadioAccessTechnologyType rat, uint32_t band, bool restart) {
4848

49-
if (restart || isCmuxEnable()) {
50-
reset();
49+
/* Assume module is powered ON. Uncomment this line is you are using
50+
* Edge Control without Arduino_ConnectionHandler
51+
* #if defined (ARDUINO_EDGE_CONTROL)
52+
* pinMode(ON_MKR2, OUTPUT);
53+
* digitalWrite(ON_MKR2, HIGH);
54+
* #endif
55+
*/
56+
57+
/* Ensure module is not under reset */
58+
pinMode(MBED_CONF_GEMALTO_CINTERION_RST, OUTPUT);
59+
digitalWrite(MBED_CONF_GEMALTO_CINTERION_RST, LOW);
60+
61+
/* Reset module if needed */
62+
const bool emergencyReset = restart || isCmuxEnable();
63+
DEBUG_INFO("Emergency reset %s", emergencyReset ? "enabled" : "disabled");
64+
if (emergencyReset) {
65+
hardwareReset();
5166
}
5267

68+
/* Create rising edge on pin ON */
69+
on();
70+
5371
if (!_context) {
5472
_context = mbed::CellularContext::get_default_instance();
5573
}
@@ -59,20 +77,18 @@ int arduino::GSMClass::begin(const char* pin, const char* apn, const char* usern
5977
return 0;
6078
}
6179

62-
pinMode(MBED_CONF_GEMALTO_CINTERION_ON, INPUT_PULLDOWN);
63-
80+
#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4)
81+
/* This is needed to wakeup module if hw flow control is enabled */
6482
static mbed::DigitalOut rts(MBED_CONF_GEMALTO_CINTERION_RTS, 0);
83+
#endif
6584

6685
_device = _context->get_device();
6786
_device->modem_debug_on(_at_debug);
6887

69-
if (!isReady()) {
70-
DEBUG_ERROR("Cellular device not ready");
71-
return 0;
72-
}
73-
88+
DEBUG_INFO("CMUX %s", _cmuxGSMenable ? "enabled" : "disabled");
7489
_device->set_cmux_status_flag(_cmuxGSMenable);
7590
_device->set_retry_timeout_array(_retry_timeout, sizeof(_retry_timeout) / sizeof(_retry_timeout[0]));
91+
_device->set_timeout(_timeout);
7692
_device->attach(mbed::callback(this, &GSMClass::onStatusChange));
7793
_device->init();
7894

@@ -106,6 +122,10 @@ int arduino::GSMClass::begin(const char* pin, const char* apn, const char* usern
106122
return connect_status == NSAPI_ERROR_OK ? 1 : 0;
107123
}
108124

125+
void arduino::GSMClass::setTimeout(unsigned long timeout) {
126+
_timeout = timeout;
127+
}
128+
109129
void arduino::GSMClass::enableCmux() {
110130
_cmuxGSMenable = true;
111131
}
@@ -115,13 +135,62 @@ bool arduino::GSMClass::isCmuxEnable() {
115135
}
116136

117137
void arduino::GSMClass::end() {
138+
if(_device) {
139+
_device->shutdown();
140+
}
141+
}
142+
143+
void arduino::GSMClass::reset() {
144+
if(_device) {
145+
_device->soft_reset();
146+
}
147+
}
148+
149+
void arduino::GSMClass::off() {
150+
if(_device) {
151+
_device->soft_power_off();
152+
}
153+
}
154+
155+
int arduino::GSMClass::ping(const char* hostname, int ttl) {
156+
157+
mbed::GEMALTO_CINTERION_CellularStack* stack = (mbed::GEMALTO_CINTERION_CellularStack*)_context->get_stack();
158+
if (!stack) {
159+
return -1;
160+
}
161+
return stack->ping(hostname, ttl);
162+
}
163+
164+
int arduino::GSMClass::ping(const String &hostname, int ttl)
165+
{
166+
return ping(hostname.c_str(), ttl);
167+
}
118168

169+
int arduino::GSMClass::ping(IPAddress ip, int ttl)
170+
{
171+
String host;
172+
host.reserve(15);
173+
174+
host += ip[0];
175+
host += '.';
176+
host += ip[1];
177+
host += '.';
178+
host += ip[2];
179+
host += '.';
180+
host += ip[3];
181+
182+
return ping(host, ttl);
119183
}
120184

121185
int arduino::GSMClass::disconnect() {
122-
if (_context) {
186+
if (!_context) {
187+
return 0;
188+
}
189+
190+
if (_context->is_connected()) {
123191
return _context->disconnect();
124192
}
193+
125194
return 0;
126195
}
127196

@@ -158,34 +227,22 @@ NetworkInterface* arduino::GSMClass::getNetwork() {
158227
return _context;
159228
}
160229

161-
void arduino::GSMClass::reset() {
230+
void arduino::GSMClass::hardwareReset() {
231+
/* Reset logic is inverted */
162232
pinMode(MBED_CONF_GEMALTO_CINTERION_RST, OUTPUT);
163233
digitalWrite(MBED_CONF_GEMALTO_CINTERION_RST, HIGH);
164234
delay(800);
165235
digitalWrite(MBED_CONF_GEMALTO_CINTERION_RST, LOW);
236+
}
237+
238+
void arduino::GSMClass::on() {
239+
/* Module needs a rising edge to power on */
166240
pinMode(MBED_CONF_GEMALTO_CINTERION_ON, OUTPUT);
167241
digitalWrite(MBED_CONF_GEMALTO_CINTERION_ON, LOW);
168242
delay(1);
169243
digitalWrite(MBED_CONF_GEMALTO_CINTERION_ON, HIGH);
170244
delay(1);
171245
}
172246

173-
bool arduino::GSMClass::isReady(const int timeout) {
174-
if (!_device) {
175-
DEBUG_ERROR("No device found");
176-
return false;
177-
}
178-
179-
const unsigned int start = millis();
180-
while (_device->is_ready() != NSAPI_ERROR_OK) {
181-
182-
if (millis() - start > timeout) {
183-
DEBUG_WARNING("Timeout waiting device ready");
184-
return false;
185-
}
186-
delay(100);
187-
}
188-
return true;
189-
}
190247

191248
arduino::GSMClass GSM;

libraries/GSM/src/GSM.h

+42-21
Original file line numberDiff line numberDiff line change
@@ -75,30 +75,47 @@ class GSMClass : public MbedSocketClass {
7575
}
7676
}
7777

78-
/* Start GSM connection.
79-
* Configure the credentials into the device.
80-
*
81-
* param pin: Pointer to the pin string.
82-
* param apn: Pointer to the apn string.
83-
* param username: Pointer to the username string.
84-
* param password: Pointer to the password string.
85-
* param rat: Radio Access Technology.
86-
*
87-
* return: 0 in case of success, negative number in case of failure
88-
*/
89-
int begin(const char* pin, const char* apn, const char* username, const char* password, RadioAccessTechnologyType rat = CATNB, uint32_t band = BAND_20, bool restart = true);
78+
/*
79+
* Start GSM connection. Configure the credentials into the device.
80+
*
81+
* param pin: Pointer to the pin string.
82+
* param apn: Pointer to the apn string.
83+
* param username: Pointer to the username string.
84+
* param password: Pointer to the password string.
85+
* param rat: Radio Access Technology.
86+
*
87+
* return: 0 in case of success, negative number in case of failure
88+
*/
89+
int begin(const char* pin, const char* apn, const char* username, const char* password, RadioAccessTechnologyType rat = CATNB, uint32_t band = BAND_20, bool restart = false);
9090

9191
/*
92-
* Disconnect from the network
93-
*
94-
* return: one value of wl_status_t enum
95-
*/
92+
* Disconnect from the network
93+
*
94+
* return: one value of wl_status_t enum
95+
*/
9696
int disconnect(void);
9797

98+
/*
99+
* Reset internal state machine in order to be ready to reconnect again.
100+
*/
98101
void end(void);
99102

100-
unsigned long getTime();
103+
/*
104+
* Send AT+CFUN=1,1 command to trigger a software reset. To be called only after end();
105+
*/
106+
void reset();
101107

108+
/*
109+
* Send AT^SMSO="fast command to power off the modem. To be called only after end();
110+
*/
111+
void off();
112+
113+
/*
114+
* Change cellular state timeouts. Needs to be called before GSM.begin()
115+
*/
116+
void setTimeout(unsigned long timeout);
117+
118+
unsigned long getTime();
102119
unsigned long getLocalTime();
103120

104121
bool setTime(unsigned long const epoch, int const timezone = 0);
@@ -108,6 +125,9 @@ class GSMClass : public MbedSocketClass {
108125
void trace(Stream& stream);
109126
void setTraceLevel(int trace_level, bool timestamp = false, bool at_trace = false);
110127
#endif
128+
int ping(const char* hostname, int ttl = 5000);
129+
int ping(const String& hostname, int ttl = 5000);
130+
int ping(IPAddress host, int ttl = 5000);
111131
bool isConnected();
112132

113133
friend class GSMClient;
@@ -127,11 +147,12 @@ class GSMClass : public MbedSocketClass {
127147
mbed::CellularContext* _context = nullptr;
128148
mbed::CellularDevice* _device = nullptr;
129149
bool _at_debug = false;
150+
unsigned long _timeout = 1000;
130151

131152
/* Internal cellular state machine retries. Values are in seconds.
132-
* This array also defines the maximum number of retries to 6
153+
* This array also defines the maximum number of retries to CELLULAR_RETRY_ARRAY_SIZE
133154
*/
134-
const uint16_t _retry_timeout[6] = {1, 2, 4, 8, 16, 32};
155+
const uint16_t _retry_timeout[CELLULAR_RETRY_ARRAY_SIZE] = {1, 2, 4, 8, 8, 8, 8, 8, 8, 8};
135156

136157
static constexpr int RSSI_UNKNOWN = 99;
137158
static const char * const sim_state_str[];
@@ -146,8 +167,8 @@ class GSMClass : public MbedSocketClass {
146167
static const char * getRegistrationStateString(const mbed::CellularNetwork::RegistrationStatus state);
147168
void onStatusChange(nsapi_event_t ev, intptr_t in);
148169

149-
void reset();
150-
bool isReady(const int timeout = 5000);
170+
void hardwareReset();
171+
void on();
151172
};
152173

153174
}

libraries/GSM/src/GSMClient.h

+20
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,29 @@
2626
namespace arduino {
2727

2828
class GSMClient : public AClient {
29+
private:
2930
NetworkInterface *getNetwork() {
3031
return GSM.getNetwork();
3132
}
33+
34+
public:
35+
size_t write(uint8_t b) {
36+
int ret = 0;
37+
do {
38+
ret = client->write(b);
39+
delay(0);
40+
} while (ret == 0 && status());
41+
return ret;
42+
}
43+
44+
size_t write(const uint8_t *buf, size_t size) {
45+
int ret = 0;
46+
do {
47+
ret = client->write(buf, size);
48+
delay(0);
49+
} while (ret == 0 && status());
50+
return ret;
51+
}
3252
};
3353

3454
}

libraries/GSM/src/GSMSSLClient.h

+19
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,25 @@ class GSMSSLClient : public arduino::ASslClient {
3232
NetworkInterface *getNetwork() {
3333
return GSM.getNetwork();
3434
}
35+
36+
public:
37+
size_t write(uint8_t b) {
38+
int ret = 0;
39+
do {
40+
ret = client->write(b);
41+
delay(0);
42+
} while (ret == 0 && status());
43+
return ret;
44+
}
45+
46+
size_t write(const uint8_t *buf, size_t size) {
47+
int ret = 0;
48+
do {
49+
ret = client->write(buf, size);
50+
delay(0);
51+
} while (ret == 0 && status());
52+
return ret;
53+
}
3554
};
3655

3756
}

0 commit comments

Comments
 (0)