Skip to content

Add NetworkInterface::get_default_instance() #6855

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

Merged
merged 1 commit into from
May 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions features/nanostack/mbed-mesh-api/source/LoWPANNDInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,13 @@ bool LoWPANNDInterface::getRouterIpAddress(char *address, int8_t len)
{
return _interface->get_gateway(address, len);
}

#define LOWPAN 0x2345
#if MBED_CONF_NSAPI_DEFAULT_MESH_TYPE == LOWPAN && DEVICE_802_15_4_PHY
MBED_WEAK MeshInterface *MeshInterface::get_default_instance()
{
static LoWPANNDInterface lowpan(NanostackRfPhy::get_default_instance());

return lowpan;
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,10 @@ nsapi_error_t InterfaceNanostack::set_blocking(bool blocking)
_blocking = blocking;
return NSAPI_ERROR_OK;
}

#if !DEVICE_802_15_4_PHY
MBED_WEAK MeshInterface *MeshInterface::get_target_default_instance()
{
return NULL;
}
#endif
10 changes: 10 additions & 0 deletions features/nanostack/mbed-mesh-api/source/ThreadInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,3 +231,13 @@ mesh_error_t Nanostack::ThreadInterface::device_pskd_set(const char *pskd)
{
return (mesh_error_t)thread_tasklet_device_pskd_set(pskd);
}

#define THREAD 0x2345
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this macro comparison magic be commented somewhere, eg. here? On #6108 (comment) there was a good explanation for it.

#if MBED_CONF_NSAPI_DEFAULT_MESH_TYPE == THREAD && DEVICE_802_15_4_PHY
MBED_WEAK MeshInterface *MeshInterface::get_target_default_instance()
{
static ThreadInterface thread(NanostackRfPhy::get_default_instance());

return thread;
}
#endif
7 changes: 7 additions & 0 deletions features/nanostack/nanostack-interface/NanostackRfPhy.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
class NanostackRfPhy : public NanostackPhy {
public:

/** Return the default on-board NanostackRfPhy
*
* Returns the default on-board NanostackRfPhy - this will be target-specific, and
* may not be available on all targets.
*/
static NanostackRfPhy &get_default_instance();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curiosity why is this a reference and the rest pointers?

Copy link
Contributor Author

@kjbracey kjbracey May 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slightly different approach to "does it exist" handling.

This version aligns with what EMAC::get_default_instance() does, which says that it must exist, if DEVICE_XXX is defined. There's no "null" possibility, hence a reference. It's kind of the "HAL" end.

For all the app-level end - NetworkInterface and similar, there is no controlling macro, but there is the possibility to override at link or run time (including a runtime check for a module being fitted!). In that case, there are underlying weak definitions that return NULL if the thing isn't provided.

So:

#if DEVICE_EMAC
EMAC &emac = EMAC::get_default_instance(); // must work
#else  
#error "No default EMAC"
#endif

WiFiInterface *wifi = WiFiInterface::get_default_instance();
if (!wifi) {
    error("Wifi not available");
}

This doesn't quite align - the upper style is closer to what the "HAL" does, but the lower is more flexible. First approach was the initial, and is long-existing on feature-emac. We ultimately had to do the second to solve various build problems for the higher levels, and it didn't seem worth going back to change the EMAC form.


/** Register this physical interface with Nanostack
*
* @return Device driver ID or a negative error
Expand Down
22 changes: 22 additions & 0 deletions features/netsocket/CellularBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ class CellularBase: public NetworkInterface {

public:

/** Get the default Cellular interface.
*
* This is provided as a weak method so applications can override.
* Default behaviour is to get the target's default interface, if
* any.
*
* @return pointer to interface, if any
*/

static CellularBase *get_default_instance();

/** Set the Cellular network credentials
*
* Please check documentation of connect() for default behaviour of APN settings.
Expand Down Expand Up @@ -102,6 +113,17 @@ class CellularBase: public NetworkInterface {
virtual const char *get_gateway() = 0;

virtual CellularBase *cellularBase() { return this; }

protected:
/** Get the target's default Cellular interface.
*
* This is provided as a weak method so targets can override. The
* default implementation configures and returns the OnBoardModemInterface
* if available.
*
* @return pointer to interface, if any
*/
static CellularBase *get_target_default_instance();
};

#endif //CELLULAR_BASE_H
Expand Down
24 changes: 24 additions & 0 deletions features/netsocket/EthInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,31 @@
*/
class EthInterface : public virtual NetworkInterface
{
public:

virtual EthInterface *ethInterface() { return this; }

/** Get the default Ethernet interface.
*
* This is provided as a weak method so applications can override.
* Default behaviour is to get the target's default interface, if
* any.
*
* @return pointer to interface, if any
*/
static EthInterface *get_default_instance();

protected:

/** Get the target's default Ethernet interface.
*
* This is provided as a weak method so targets can override. The
* default implementation will invoke EthernetInterface with the
* default EMAC and default network stack, if DEVICE_EMAC is set.
*
* @return pointer to interface, if any
*/
static EthInterface *get_target_default_instance();
};


Expand Down
34 changes: 34 additions & 0 deletions features/netsocket/EthernetInterface.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/* LWIP implementation of NetworkInterfaceAPI
* Copyright (c) 2015 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "EthernetInterface.h"

/* No actual interface implementation here, as EthernetInterface is
* just an EMACInterface. But we can be the default EthInterface - step up
* if the target has a default EMAC.
*/
#if DEVICE_EMAC
MBED_WEAK EthInterface *EthInterface::get_target_default_instance()
{
static EthernetInterface ethernet;
return &ethernet;
}
#else
MBED_WEAK EthInterface *EthInterface::get_target_default_instance()
{
return NULL;
}
#endif
24 changes: 24 additions & 0 deletions features/netsocket/MeshInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,31 @@
*/
class MeshInterface : public virtual NetworkInterface
{
public:

virtual MeshInterface *meshInterface() { return this; }

/** Get the default Mesh interface.
*
* This is provided as a weak method so applications can override.
* Default behaviour is to get the target's default interface, if
* any.
*
* @return pointer to interface, if any
*/
static MeshInterface *get_default_instance();

protected:

/** Get the target's default Mesh interface.
*
* This is provided as a weak method so targets can override. The
* default implementation will invoke LoWPANNDInterface or ThreadInterface
* with the default NanostackRfPhy.
*
* @return pointer to interface, if any
*/
static MeshInterface *get_target_default_instance();
};


Expand Down
71 changes: 69 additions & 2 deletions features/netsocket/NetworkInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,46 @@ class EMACInterface;
class NetworkInterface: public DNS {
public:



virtual ~NetworkInterface() {};

/** Return the default network interface
*
* Returns the default network interface, as determined by JSON option
* target.network-default-interface-type or other overrides.
*
* The type of the interface returned can be tested via the ethInterface()
* etc downcasts.
*
* The default behaviour is to return the default interface for the
* interface type specified by target.network-default-interface-type. Targets
* should set this in their targets.json to guide default selection,
* and applications may override.
*
* The interface returned should be already configured for use such that its
* connect() method works with no parameters. For connection types needing
* configuration, settings should normally be obtained from JSON - the
* settings for the core types are under the "nsapi" JSON config tree.
*
* The list of possible settings for default interface type is open-ended,
* as is the number of possible providers. Core providers are:
*
* * ETHERNET: EthernetInterface, using default EMAC and OnboardNetworkStack
* * MESH: ThreadInterface or LoWPANNDInterface, using default NanostackRfPhy
* * CELLULAR: OnboardModemInterface
* * WIFI: None - always provided by a specific class
*
* Specific drivers may be activated by other settings of the
* default-network-interface-type configuration. This will depend on the
* target and the driver. For example a board may have its default setting
* as "AUTO" which causes it to autodetect an Ethernet cable. This should
* be described in the target's documentation.
*
* An application can override all target settings by implementing
* NetworkInterface::get_default_instance() themselves - the default
* definition is weak, and calls get_target_default_instance().
*/
static NetworkInterface *get_default_instance();

/** Get the local MAC address
*
* Provided MAC address is intended for info or debug purposes and
Expand Down Expand Up @@ -237,6 +273,37 @@ class NetworkInterface: public DNS {
* @return The underlying NetworkStack object
*/
virtual NetworkStack *get_stack() = 0;

/** Get the target's default network instance.
*
* This method can be overridden by the target. Default implementations
* are provided weakly by various subsystems as described in
* NetworkInterface::get_default_instance(), so targets should not
* need to override in simple cases.
*
* If a target has more elaborate interface selection, it can completely
* override this behaviour by implementing
* NetworkInterface::get_target_default_instance() themselves, either
* unconditionally, or for a specific network-default-interface-type setting
*
* For example, a device with both Ethernet and Wi-fi could be set up its
* target so that:
* * DEVICE_EMAC is set, and it provides EMAC::get_default_instance(),
* which means EthernetInterface provides EthInterface::get_target_instance()
* based on that EMAC.
* * It provides WifiInterface::get_target_default_instance().
* * The core will route NetworkInterface::get_default_instance() to
* either of those if network-default-interface-type is set to
* ETHERNET or WIFI.
* * The board overrides NetworkInterface::get_target_default_instance()
* if network-default-interface-type is set to AUTO. This returns
* either EthInterface::get_default_instance() or WiFIInterface::get_default_instance()
* depending on a cable detection.
*
*
* performs the search described by get_default_instance.
*/
static NetworkInterface *get_target_default_instance();
};


Expand Down
Loading