Skip to content
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

[wiring] Network: introduce isOn() and isOff() APIs to enquiry the modem power state #2205

Merged
merged 9 commits into from
Dec 22, 2020
5 changes: 5 additions & 0 deletions hal/inc/cellular_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ cellular_result_t cellular_init(void* reserved);
*/
cellular_result_t cellular_off(void* reserved);

/**
* Check if the cellular module is powered.
*/
bool cellular_powered(void* reserved);

/**
* Wait for the cellular module to register on the GSM network.
*/
Expand Down
3 changes: 2 additions & 1 deletion hal/inc/hal_dynalib_cellular.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ DYNALIB_FN(BASE_CELL_IDX + 1, hal_cellular, cellular_registration_timeout_set, c

#if !HAL_PLATFORM_NCP
DYNALIB_FN(BASE_CELL_IDX + 2, hal_cellular, cellular_process, cellular_result_t(void*, void*))
#define BASE_CELL_IDX1 (BASE_CELL_IDX + 3)
DYNALIB_FN(BASE_CELL_IDX + 3, hal_cellular, cellular_powered, bool(void*))
#define BASE_CELL_IDX1 (BASE_CELL_IDX + 4)
#else
#define BASE_CELL_IDX1 (BASE_CELL_IDX + 2)
#endif // !HAL_PLATFORM_NCP
Expand Down
18 changes: 16 additions & 2 deletions hal/network/api/ifapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ typedef enum if_xflags_t {
IFXF_DHCP6 = 0x20000,
IFXF_AUTOIP = 0x40000,

IFXF_CANTCHANGE = 0
IFXF_READY = 0x100000,

IFXF_CANTCHANGE = (IFXF_READY)
} if_xflags_t;

#ifndef IF_NAMESIZE
Expand Down Expand Up @@ -141,7 +143,8 @@ typedef enum if_event_type_t {
IF_EVENT_LINK = 0x04,
IF_EVENT_ADDR = 0x05,
IF_EVENT_LLADDR = 0x06,
IF_EVENT_POWER_STATE = 0x07
IF_EVENT_POWER_STATE = 0x07,
IF_EVENT_PHY_STATE = 0x08,
XuGuohui marked this conversation as resolved.
Show resolved Hide resolved
} if_event_type_t;

typedef enum if_state_t {
Expand All @@ -164,6 +167,12 @@ typedef enum if_power_state_t {
IF_POWER_STATE_POWERING_UP = 0x04,
} if_power_state_t;

typedef enum if_phy_state_t {
IF_PHY_STATE_UNKNOWN = 0x00,
IF_PHY_STATE_OFF = 0x01,
IF_PHY_STATE_ON = 0x02
} if_phy_state_t;

struct if_event_state {
uint8_t state;
};
Expand All @@ -176,6 +185,10 @@ struct if_event_power_state {
uint8_t state;
};

struct if_event_phy_state {
uint8_t state;
};

struct if_event_addr {
struct if_addr* oldaddr;
struct if_addr* addr;
Expand All @@ -196,6 +209,7 @@ struct if_event {
struct if_event_addr* ev_if_addr;
struct if_event_lladdr* ev_if_lladdr;
struct if_event_power_state* ev_power_state;
struct if_event_phy_state* ev_phy_state;
};
};

Expand Down
1 change: 1 addition & 0 deletions hal/network/lwip/basenetif.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class BaseNetif {
virtual int powerDown() = 0;

virtual int getPowerState(if_power_state_t* state) const = 0;
virtual int getNcpState(unsigned int* state) const = 0;

protected:
void registerHandlers();
Expand Down
26 changes: 26 additions & 0 deletions hal/network/lwip/cellular/pppncpnetif.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,17 @@ int PppNcpNetif::getPowerState(if_power_state_t* state) const {
return SYSTEM_ERROR_NONE;
}

int PppNcpNetif::getNcpState(unsigned int* state) const {
auto s = celMan_->ncpClient()->ncpState();
if (s == NcpState::ON) {
*state = 1;
} else {
// NcpState::OFF or NcpState::DISABLED
*state = 0;
}
return SYSTEM_ERROR_NONE;
}

int PppNcpNetif::upImpl() {
up_ = true;
auto r = celMan_->ncpClient()->on();
Expand Down Expand Up @@ -340,6 +351,21 @@ void PppNcpNetif::ncpEventHandlerCb(const NcpEvent& ev, void* ctx) {
} else {
LOG(ERROR, "NCP power state unknown");
}
} else if (ev.type == NcpEvent::NCP_STATE_CHANGED) {
const auto& cev = static_cast<const NcpStateChangedEvent&>(ev);
if_event evt = {};
struct if_event_phy_state ev_if_phy_state = {};
evt.ev_len = sizeof(if_event);
evt.ev_type = IF_EVENT_PHY_STATE;
evt.ev_phy_state = &ev_if_phy_state;
if (cev.state == NcpState::ON) {
evt.ev_phy_state->state = IF_PHY_STATE_ON;
} else if (cev.state == NcpState::OFF) {
evt.ev_phy_state->state = IF_PHY_STATE_OFF;
} else {
evt.ev_phy_state->state = IF_PHY_STATE_UNKNOWN;
}
if_notify_event(self->interface(), &evt, nullptr);
}
}

Expand Down
1 change: 1 addition & 0 deletions hal/network/lwip/cellular/pppncpnetif.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class PppNcpNetif : public BaseNetif {
virtual int powerDown() override;

virtual int getPowerState(if_power_state_t* state) const override;
virtual int getNcpState(unsigned int* state) const override;

static int ncpDataHandlerCb(int id, const uint8_t* data, size_t size, void* ctx);
static void ncpEventHandlerCb(const NcpEvent& ev, void* ctx);
Expand Down
11 changes: 11 additions & 0 deletions hal/network/lwip/esp32/esp32ncpnetif.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,17 @@ int Esp32NcpNetif::getPowerState(if_power_state_t* state) const {
return SYSTEM_ERROR_NONE;
}

int Esp32NcpNetif::getNcpState(unsigned int* state) const {
auto s = wifiMan_->ncpClient()->ncpState();
if (s == NcpState::ON) {
*state = 1;
} else {
// NcpState::OFF or NcpState::DISABLED
*state = 0;
}
return SYSTEM_ERROR_NONE;
}

int Esp32NcpNetif::upImpl() {
up_ = true;
auto r = queryMacAddress();
Expand Down
1 change: 1 addition & 0 deletions hal/network/lwip/esp32/esp32ncpnetif.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Esp32NcpNetif : public BaseNetif {
virtual int powerDown() override;

virtual int getPowerState(if_power_state_t* state) const override;
virtual int getNcpState(unsigned int* state) const override;

static int ncpDataHandlerCb(int id, const uint8_t* data, size_t size, void* ctx);
static void ncpEventHandlerCb(const NcpEvent& ev, void* ctx);
Expand Down
10 changes: 10 additions & 0 deletions hal/network/lwip/ifapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,16 @@ int if_get_xflags(if_t iface, unsigned int* xflags) {

/* TODO: WOL */

ifxf &= ~IFXF_READY;
auto bnetif = getBaseNetif(iface);
if (bnetif) {
unsigned int state;
bnetif->getNcpState(&state);
if (state) {
ifxf |= IFXF_READY;
}
}

*xflags = ifxf;

return 0;
Expand Down
5 changes: 5 additions & 0 deletions hal/network/lwip/wiznet/wiznetif.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,11 @@ int WizNetif::getPowerState(if_power_state_t* state) const {
return SYSTEM_ERROR_NOT_SUPPORTED;
}

int WizNetif::getNcpState(unsigned int* state) const {
// TODO: implement it
return SYSTEM_ERROR_NOT_SUPPORTED;
}

int WizNetif::openRaw() {
LwipTcpIpCoreLock lk;

Expand Down
1 change: 1 addition & 0 deletions hal/network/lwip/wiznet/wiznetif.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class WizNetif : public BaseNetif {
virtual int powerDown() override;

virtual int getPowerState(if_power_state_t* state) const override;
virtual int getNcpState(unsigned int* state) const override;

static WizNetif* instance() {
return instance_;
Expand Down
9 changes: 5 additions & 4 deletions hal/network/ncp_client/quectel/quectel_ncp_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1739,19 +1739,21 @@ int QuectelNcpClient::modemPowerOff() {

int QuectelNcpClient::modemSoftPowerOff() {
if (modemPowerState()) {
ncpPowerState(NcpPowerState::TRANSIENT_OFF);

LOG(TRACE, "Try powering modem off using AT command");
if (!ready_) {
LOG(ERROR, "NCP client is not ready");
return SYSTEM_ERROR_INVALID_STATE;
}

// Delay 1s in case that the modem is just powered up and refuse to execute the power down command.
HAL_Delay_Milliseconds(1000);
int r = CHECK_PARSER(parser_.execCommand("AT+QPOWD"));
if (r != AtResponse::OK) {
LOG(ERROR, "AT+QPOWD command is not responding");
return SYSTEM_ERROR_AT_NOT_OK;
}
ncpPowerState(NcpPowerState::TRANSIENT_OFF);
system_tick_t now = HAL_Timer_Get_Milli_Seconds();
LOG(TRACE, "Waiting the modem to be turned off...");
// Verify that the module was powered down by checking the VINT pin up to 30 sec
Expand Down Expand Up @@ -1786,11 +1788,10 @@ int QuectelNcpClient::modemHardReset(bool powerOff) {

// The modem restarts automatically after hard reset.
if (powerOff) {
// Need to delay at least 5s, otherwise, the modem cannot be powered off.
HAL_Delay_Milliseconds(5000);

ncpPowerState(NcpPowerState::TRANSIENT_OFF);

// Need to delay at least 5s, otherwise, the modem cannot be powered off.
HAL_Delay_Milliseconds(5000);
LOG(TRACE, "Powering modem off");
// Power off, power off pulse >= 650ms
// NOTE: The BGPWR pin is inverted
Expand Down
2 changes: 1 addition & 1 deletion hal/network/ncp_client/sara/sara_ncp_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2100,6 +2100,7 @@ int SaraNcpClient::modemPowerOff() {

int SaraNcpClient::modemSoftPowerOff() {
if (modemPowerState()) {
ncpPowerState(NcpPowerState::TRANSIENT_OFF);
LOG(TRACE, "Try powering modem off using AT command");
if (!ready_) {
LOG(ERROR, "NCP client is not ready");
Expand All @@ -2110,7 +2111,6 @@ int SaraNcpClient::modemSoftPowerOff() {
LOG(ERROR, "AT+CPWROFF command is not responding");
return SYSTEM_ERROR_AT_NOT_OK;
}
ncpPowerState(NcpPowerState::TRANSIENT_OFF);
system_tick_t now = HAL_Timer_Get_Milli_Seconds();
LOG(TRACE, "Waiting the modem to be turned off...");
// Verify that the module was powered down by checking the VINT pin up to 10 sec
Expand Down
5 changes: 5 additions & 0 deletions hal/src/electron/cellular_hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,11 @@ cellular_result_t cellular_off(void* reserved)
return 0;
}

bool cellular_powered(void* reserved)
{
return electronMDM.powerState();
}

cellular_result_t cellular_register(void* reserved)
{
CHECK_SUCCESS(electronMDM.registerNet());
Expand Down
8 changes: 4 additions & 4 deletions hal/src/electron/modem/mdm_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,10 @@ class MDMParser

int process();

/** Detects the modem power state
*/
bool powerState(void);

protected:
/** Write bytes to the physical interface. This function should be
implemented in a inherited class.
Expand Down Expand Up @@ -534,10 +538,6 @@ class MDMParser
*/
void SMSreceived(int index);

/** Detects the modem power state
*/
bool powerState(void);

protected:
// String helper to prevent buffer overrun
struct CStringHelper {
Expand Down
2 changes: 2 additions & 0 deletions system/inc/system_dynalib_net.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ DYNALIB_FN(12, system_net, network_set_listen_timeout, void(network_handle_t, ui
DYNALIB_FN(13, system_net, network_get_listen_timeout, uint16_t(network_handle_t, uint32_t, void*))
DYNALIB_FN(14, system_net, network_set_hostname, int(network_handle_t, uint32_t, const char*, void*))
DYNALIB_FN(15, system_net, network_get_hostname, int(network_handle_t, uint32_t, char*, size_t, void*))
DYNALIB_FN(16, system_net, network_is_on, bool(network_handle_t, void*))
DYNALIB_FN(17, system_net, network_is_off, bool(network_handle_t, void*))

DYNALIB_END(system_net)

Expand Down
2 changes: 2 additions & 0 deletions system/inc/system_network.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ void network_disconnect(network_handle_t network, uint32_t reason, void* reserve
bool network_ready(network_handle_t network, uint32_t type, void* reserved);
void network_on(network_handle_t network, uint32_t flags, uint32_t param1, void* reserved);
void network_off(network_handle_t network, uint32_t flags, uint32_t param1, void* reserved);
bool network_is_on(network_handle_t network, void* reserved);
bool network_is_off(network_handle_t network, void* reserved);
int network_connect_cancel(network_handle_t network, uint32_t flags, uint32_t param1, void* reserved);

#define NETWORK_LISTEN_EXIT (1<<0)
Expand Down
4 changes: 4 additions & 0 deletions system/src/system_network_cellular.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ class CellularNetworkInterface : public ManagedIPNetworkInterface<CellularConfig
cellular_off(nullptr);
}

bool is_powered() override {
return cellular_powered(nullptr);
}

void disconnect_now() override {
cellular_disconnect(nullptr);
}
Expand Down
8 changes: 8 additions & 0 deletions system/src/system_network_compat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ void network_on(network_handle_t network, uint32_t flags, uint32_t param, void*
SYSTEM_THREAD_CONTEXT_ASYNC_CALL(nif(network).on());
}

bool network_is_on(network_handle_t network, void* reserved) {
return nif(network).isOn();
}

bool network_is_off(network_handle_t network, void* reserved) {
return nif(network).isOff();
}

bool network_has_credentials(network_handle_t network, uint32_t param, void* reserved)
{
SYSTEM_THREAD_CONTEXT_SYNC_CALL_RESULT(nif(network).has_credentials());
Expand Down
13 changes: 13 additions & 0 deletions system/src/system_network_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,9 @@ struct NetworkInterface
virtual void setup()=0;

virtual int on()=0;
virtual bool isOn()=0;
virtual void off(bool disconnect_cloud=false)=0;
virtual bool isOff()=0;
virtual void connect(bool listen_enabled=true)=0;
virtual bool connecting()=0;
virtual void connect_cancel(bool cancel)=0;
Expand Down Expand Up @@ -374,6 +376,7 @@ class ManagedNetworkInterface : public NetworkInterface

virtual int on_now()=0;
virtual void off_now()=0;
virtual bool is_powered()=0;

virtual int process_now()=0;

Expand Down Expand Up @@ -611,6 +614,16 @@ class ManagedNetworkInterface : public NetworkInterface
return 0;
}

bool isOn() override
{
return WLAN_INITIALIZED && SPARK_WLAN_STARTED;
}

bool isOff() override
{
return !SPARK_WLAN_STARTED && !is_powered();
}

void off(bool disconnect_cloud=false) override
{
LOG_NETWORK_STATE();
Expand Down
Loading