Skip to content
This repository has been archived by the owner on Nov 11, 2024. It is now read-only.

Commit

Permalink
Handle case where the module changes RAT on us: when this happens bet…
Browse files Browse the repository at this point in the history
…ween 2G and LTE the module reactivates the context internally but doesn't say that it has done so, it just drops the PPP connection when we next try to use it. In order to handle this, if we spot a RAT change when PPP is active we reconnect the PDP context/PPP at that point.
  • Loading branch information
RobMeades committed Sep 23, 2024
1 parent 62be5fc commit cfd6cf6
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 10 deletions.
20 changes: 14 additions & 6 deletions cell/src/u_cell_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
#include "u_cell_mno_db.h"
#include "u_cell_ppp_shared.h"

#include "u_cell_ppp_private.h"
#include "u_cell_pwr_private.h"

/* ----------------------------------------------------------------
Expand Down Expand Up @@ -316,6 +317,7 @@ static void setNetworkStatus(uCellPrivateInstance_t *pInstance,
{
uCellNetRegistationStatus_t *pStatus;
bool printAllowed = true;
uCellNetRat_t previousRat = pInstance->rat[regType];
#if U_CFG_OS_CLIB_LEAKS
// If we're in a URC and the C library leaks memory
// when printf() is called from a dynamically
Expand Down Expand Up @@ -429,12 +431,18 @@ static void setNetworkStatus(uCellPrivateInstance_t *pInstance,
// support LTE but does support Cat-M1, switch it
pInstance->rat[regType] = U_CELL_NET_RAT_CATM1;
}
if (pInstance->profileState == U_CELL_PRIVATE_PROFILE_STATE_REQUIRES_REACTIVATION) {
// This flag will be set if we had been knocked out
// of our PDP context by a network outage and need
// to get it back again; make sure to get this in the
// queue before any user registratioon status callback
// so that everything is sorted for them
if ((pInstance->profileState == U_CELL_PRIVATE_PROFILE_STATE_REQUIRES_REACTIVATION) ||
((previousRat != U_CELL_NET_RAT_UNKNOWN_OR_NOT_USED) &&
(pInstance->rat[regType] != previousRat) && (uCellPppPrivateIsOpen(pInstance)))) {
// profileState will have been set to "reactivation required"
// if we had been knocked out of our PDP context by a network
// outage and need to get it back again. We also need to do
// this if the module has changed RAT underneath us, potentially
// between 2G and LTE, and we have a PPP connection up; the PPP
// connection could have become inactive, without notification,
// on such a RAT change, activateContextCallback() will reconnect it.
// Make sure this is in the queue before any user registration
// status callback so that everything is sorted for the user.
if (!U_CELL_PRIVATE_HAS(pInstance->pModule,
U_CELL_PRIVATE_FEATURE_USE_UPSD_CONTEXT_ACTIVATION)) {
// Use the AT client's callback mechanism to do the operation
Expand Down
20 changes: 16 additions & 4 deletions cell/src/u_cell_ppp.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,20 @@ void uCellPppPrivateRemoveContext(uCellPrivateInstance_t *pInstance)
}
}

// Determine if PPP is up and running.
bool uCellPppPrivateIsOpen(uCellPrivateInstance_t *pInstance)
{
bool isRunning = false;
uCellPppContext_t *pContext;

if ((pInstance != NULL) && (pInstance->pPppContext != NULL)) {
pContext = (uCellPppContext_t *) pInstance->pPppContext;
isRunning = pContext->pDeviceSerial != NULL;
}

return isRunning;
}

/* ----------------------------------------------------------------
* PUBLIC FUNCTIONS KEPT WITHIN THE SRC DIRECTORY
* -------------------------------------------------------------- */
Expand Down Expand Up @@ -550,16 +564,14 @@ bool uCellPppIsOpen(uDeviceHandle_t cellHandle)
{
bool isRunning = false;
uCellPrivateInstance_t *pInstance;
uCellPppContext_t *pContext;

if (gUCellPrivateMutex != NULL) {

U_PORT_MUTEX_LOCK(gUCellPrivateMutex);

pInstance = pUCellPrivateGetInstance(cellHandle);
if ((pInstance != NULL) && (pInstance->pPppContext != NULL)) {
pContext = (uCellPppContext_t *) pInstance->pPppContext;
isRunning = pContext->pDeviceSerial != NULL;
if (pInstance != NULL) {
isRunning = uCellPppPrivateIsOpen(pInstance);
}

U_PORT_MUTEX_UNLOCK(gUCellPrivateMutex);
Expand Down
9 changes: 9 additions & 0 deletions cell/src/u_cell_ppp_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ extern "C" {
*/
void uCellPppPrivateRemoveContext(uCellPrivateInstance_t *pInstance);

/** Determine if a PPP connection is currently up.
*
* Note: gUCellPrivateMutex should be locked before this is called.
*
* @param[in] pInstance a pointer to the cellular instance.
* @return true if a PPP connection is up, else false.
*/
bool uCellPppPrivateIsOpen(uCellPrivateInstance_t *pInstance);

#ifdef __cplusplus
}
#endif
Expand Down

0 comments on commit cfd6cf6

Please sign in to comment.