TB_SENSE_12 would have been left behind by the changes in #7778. This commit implements the changes in mbed to allow targets to provide a default network interface for Silicon Labs targets.
[Warning] InternetSocket.h@237,10: 'InternetSocket::_factory_allocated' will be initialized after [-Wreorder]
[Warning] InternetSocket.h@236,23: 'volatile unsigned int InternetSocket::_pending' [-Wreorder]
[Warning] InternetSocket.cpp@22,1: when initialized here [-Wreorder]
Typo in the config file made the LwIP stack way too small on EFM32GG11 STK3701 target. Additionally, the EMAC thread stack was slightly too small when debug printing is on.
Setting ""nsapi.dns-cache-size": 0" still left some of the DNS
caching code in. Add crude #if to remove all of it.
This allows one to save 429 bytes of flash and 48 bytes of RAM on
ARMC5 builds.
* Move IP Socket stuff to InternetSocket class which is inherited by TCP/UDP
* Implement sendto() and recvfrom() on TCP socket
* Implement connect() call on UDP
* Implement send() and recv() calls on UDP socket
Code was written using MBED_CONF_DEFAULT_* but the mbed_lib.json file
that created these values is prefixed with "nsapi" and therefore
final macros are MBED_CONF_NSAPI_DEFAULT_*
Currently, if all TX descriptors are in use and IP stack calls K64F/K66F
ethernet driver link out, link out drops the packet. Added 10ms delay
to link out to wait for a descriptor to become available before dropping
the packet.
Changed K64F/K66F power up to return without waiting for link up i.e. for
the ethernet cable to be connected. This is needed for non-blocking use
of driver e.g. for using the driver from event queue.
Two cascading copy-paste errors stopped this working:
* PPPCellularInterface::get_gateway() called
nsapi_ppp_get_ip_address();
* nsapi_ppp_get_gateway() called the interface's get_netmask().
First bug has always been there - second one was introduced in 5.9.
AT_CellularNetwork currently lacks calls to get both netmask and gateway
- this patch would be needed for that when added.
When all TX descriptors were reserved in a row so that TX buffer
reclaim interrupt did not happen during reservation sequence, after
the interrupt occurred, TX buffer reclaim did no longer free buffers.
This happened because when all descriptors were in use, last free
index pointed to consumed index.
TX pointer array was using RX ring length in its declaration.
Wasted memory if RX ring > TX ring, as is the default, but would
be broken if RX ring < TX ring.
16 RX buffers and 8 TX buffers is probably excessive. Nanostack
version of driver successfully used 4+4, and data pump should be
broadly equivalent.
This means that switching K64F devices from Nanostack to EMAC increases
base heap usage by 18K - observed in Nanostack border router builds.
Add a config option to make it possible to lower the number of buffers.
Defer consideration of lowering the default to later.
DNS resolver now counts how many sendto operations are successful
during one DNS server attempt cycle (attempting to contact DNS
servers from 0 to last index, including stack specific ones). If all
socket sendto operations fail, DNS resolution is aborted.
If one or more are successful, DNS resolution is continued until
total network attempts count is reached or all sendto operations
fails during a cycle.
- Set network stack to store event queue so that mbed::mbed_event_queue() call
is not needed every time call_in() is called
- Added dns state variables and enum (states are: created, initiated and cancelled)
- Corrected DNS response handling so that if DNS server returns that host name is
unknown the DNS query is not tried again
- Reorder mutexes in nsapi_dns_query_multiple_async()
- Created nsapi_dns_query_async_initiate_next() function to initiate the next
DNS query from the queue after delete of previous query
- Added dsn_timer_running variable to supervise DNS timer start/stop
- Changed cancel function to only mark query as deleted and moved deletion
to timer function. This allows to run socket close on DNS thread
- Added new nsapi error NSAPI_ERROR_TIMEOUT for DNS (and other) timeouts
Subtract 4 from the received packet length - the buffer contains the
CRC, which we shouldn't pass up.
Ensure we allocate receive buffers of a size corresponding to the
rounded-up size we tell the hardware - the hardware was overrunning the
allocation by a couple of bytes.
- Changed mutexes to platform mutexes
- Removed not needed null check from delete
- Changed nsapi_dns_call_in_set() to use call_in_callback_cb_t and
added prototype to header
- Serialized the sending of multiple async DNS queries since limits on event
message box sizes
- Added timer function that supervises the total time used to make DNS query
and triggers socket timeouts
- Changed nsapi_error_t to new nsapi_value_or_error_t on interface headers
- Corrected wording of gethostbyname_async return values
- Clarified .json options
- Added a new data type for socket callback that can be used from interrupts
- Corrected variable limits to use INT32_MAX etc. defines
- Changed mallocs to new
- Optimized variable sizes on DNS_QUERY definition
- Changed call_in/call methods of the stack to callback provided by the stack
- Specified what are limitations for operations that are made in callback
- Added pure virtual class DNS that defines DNS operations
- Added cancel operation and unique ID to DNS request used in cancel
- Added DNS configuration options to netsocket/mbed_lib.json for retries,
response wait time and cache size
- Changed host name to use dynamic memory in DNS query list and cache,
set maximum length for the name to 255 bytes.
- Added mutex to asynchronous DNS
- Reworked retries: there is now total retry count and a server specific count
- Ignores invalid incoming UDP socket messages (DNS header is not valid), and retries DNS query
- Reworked DNS module asynchronous operation functions
- Corrected other review issues (nothrow new, missing free, missing mutex unlock etc.)
- Added non-blocking DNS interface to network interface and
network stack.
- Added caching of DNS replies.
- Added a network stack function to get DNS addresses from stack.
- Added call and call_in hooks to onboard network stack to
allow calling functions from onboard stack context.
- Added support to call and call_in functions to LWIP and
Nanostack.
- Disabled LWIP DNS translator with the exception of DNS
address storage used in DNS address get.
Implementation of unified EMAC driver for Renesas mbed boards
Based on the driver so far, Renesas implemented the emac driver for GR-PEACH and VK-RZ/A1H.
The mainly changes is below.
- Add the connection part with LWIP according to the unified emac specification.
- Add three new multicast functions(add, remove, set_all).
The Greentea test netsocket and emac test passed.
Just checking "does the chip have an EMAC" doesn't work - there are
targets using those chips which do not have an Ethernet connector and
don't provide the necessary surrounding infrastructure (eg DISCO_F429ZI,
not providing the board emac config call, and HEXIWEAR not providing PHY
info).
Make the targets that actually do want EMAC define their own local
Freescale_EMAC and STM_EMAC labels, and move the drivers into
the corresponding TARGET_ directories, removing the #ifdefs.
Checking DEVICE_EMAC is problematic - particularly for the Odin W2 where
apps have been shutting this off to disable the Wi-fi interface.
Make drivers check a locally-relevant flag instead, pending new
thoughts on how to achieve application/test-relevant flagging for
XXX:get_default_instance() being provided by a system.
However that is achieved, drivers do require a flag set purely by the
target - they mustn't be tripped up by an add-on module providing itself
as the system's default EMAC.
Make Nanostack an OnboardNetworkInterface, implementing
add_ethernet_interface so it can use EMAC drivers.
Can now be used via EthernetInterface, and be the system's default
network stack.
Legacy support for NanostackEthernetInterface retained. Some
restructuring of mesh interface code to fit into the
OnboardNetworkStack:::Interface system.
As we've introduced virtual inheritance to support EMACInterface, we can
no longer use C-style casts or static_cast to downcast from
NetworkInterface to more specific types. RTTI is disabled in the
toolchains, so dynamic_cast is unavailables.
Add virtual downcast methods to permit conversions to the 6 derived
classes. Probably only needed for EMACInterface, WiFiInterface and
EthInterface, but handles the set.
This has been superceded by CellularBase. Name change occurred late
in review of https://github.com/ARMmbed/mbed-os/pull/4119 and
original unused CellularInterface was left behind.
Rather than let "EthernetInterface" be the base EMAC NetworkInterface,
insert an "EMACInterface" class.
EthernetInterface then derives from EMACInterface and EthInterface.
A Wi-Fi driver can derive from EMACInterface and WiFiInterface - this
will be more logical than deriving from EthernetInterface and
WiFiInterface.
This does mean adding a couple of virtual inheritances to avoid
duplicate NetworkInterfaces:
NetworkInterface
/ \
virtual / \ virtual
/ \
EMACInterface WiFiInterface
\ /
\ /
\ /
MyCustomWiFiInterface
Initial work by Bartek Szatkowski in https://github.com/ARMmbed/mbed-os/pull/4079,
reworked following review of https://github.com/ARMmbed/mbed-os/pull/5202 to
transform the entire system into C++, retaining the basic functionality.
Bartek's summary:
* Porting ethernet to EMAC
* Updating EMAC to enable multiple interfaces
* Untangling networking classes, making the abstractions a bit clearer to follow, etc
* General refactoring
* Removal of DEVICE_EMAC flag and introducing DEVICE_ETH and DEVICE_WIFI
Revisions since initial branch:
* Remove lwip depencies
* Correct doxygen warnings
* Remove emac_api.h, replace with C++ EMAC abstract class.
* Create OnboardNetworkInterface, and LWIP implementation.
* Mappings since #4079
lwip-interface/nsapi_stack_lwip.c -> LWIPStack.cpp
lwip-interface/ipstack_lwip.c -> LWIPInterface.cpp
netsocket/mbed_ipstack.h -> OnboardNetworkStack.h
hal/emac_api.h -> EMAC.h
* Reinstate use of EthInterface abstraction
* Correct and clarify HW address EMAC ops
* Restore MBED_MAC_ADDR implementation
* Integrate PPP support with LWIP::Interface.
* Convert K64F lwIP driver to K64F_EMAC.
To do:
* Convert emac_stack_mem.h to follow this pattern.
* Figure out DEVICE_ETH/EMAC
* Update all drivers to use EMAC
Documentation states that nsapi_dns_query_multiple returns the number of
addresses found on success - it was returning 0.
Overloads using SocketAddress are relying on the return value, meaning
those calls didn't work at all.
Fixes#5921.
Previously, send() was somewhat soft - it only ever made one send
call to the underlying stack, so it would typically take as much data
as would fit in the buffer, and only block if it was unable to write
anything.
This is not the intent of a POSIX socket/filehandle write. It should try
to send everything if blocking, and only send less if interrupted by a
signal:
- If the O_NONBLOCK flag is clear, write() shall block the calling
thread until the data can be accepted.
- If the O_NONBLOCK flag is set, write() shall not block the thread.
If some data can be written without blocking the thread, write()
shall write what it can and return the number of bytes written.
Otherwise, it shall return -1 and set errno to [EAGAIN].
This "send all" behaviour is of slightly limited usefulness in POSIX, as
you still usually have to worry about the interruption possibility:
- If write() is interrupted by a signal before it writes any data, it
shall return -1 with errno set to [EINTR].
- If write() is interrupted by a signal after it successfully writes
some data, it shall return the number of bytes written.
But as mbed OS does not have the possibility of signal interruption, if we
strengthen send to write everything, we can make applications' lives
easier - they can just do "send(large amount)" confident that it will
all go in one call (if no errors).
So, rework to make multiple sends to the underlying stack, blocking as
necessary, until all data is written.
This change does not apply to recv(), which is correct in only blocking until
some data is available:
- If O_NONBLOCK is set, read() shall return -1 and set errno to [EAGAIN].
- If O_NONBLOCK is clear, read() shall block the calling thread until some
data becomes available.
- The use of the O_NONBLOCK flag has no effect if there is some data
available.
From C++11 and beyond string literals must be seperated by space
so that they are recongizable as seperate tokens.
Context macro in PPPCellularInterface (CTX) has been causing issues
as it was not augmented with a space from a nearby string literal.
Cellular example had build issues with IAR8, combination of define and string
as argument to send function resulted in above error. Typecasting to const char *
didn't help, hence replacing the define explicitly.
Basic TCP/UDP tests for PPP based onboard cellular modems.
Tests basic public APIs defined in CellularBase.h
A customer port must pass this test set, hence verifying their
particular implementation.
For keep supporting external APIs with the same name (supposedly there are a larger
number of users of those APIs), BufferedSerial and ATParser are being renamed.
BufferedSerial becomes UARTSerial, will complement a future USBSerial etc.
ATParser becomes ATCmdParser.
* UARTSerial moves to /drivers
* APN_db.h is moved from platform to cellular/util/.
* Original CellularInterface is restored for backward compatability (again, supposedly there
are users of that).
* A new file, CellularBase is added which will now servce as the base class for all
upcoming drivers.
* Special restructuring for the driver has been undertaken. This makes a clear cut distinction
between an on-board or an off-board implementation.
- PPPCellularInterface is a generic network interface that works with a generic FileHandle
and PPP. A derived class is needed to pass that FileHandle.
- PPPCellularInterface provides some base functionality like network registration, AT setup,
PPP connection etc. Lower level job is delegated to the derived classes and various modem
specific APIs are provided which are supposed to be overridden.
- UARTCellularInterface is derived from PPPCellularInterface. It constructs a FileHandle and
passes it back to PPPCellularInterface as well as provides modem hangupf functionality.
In future we could proive a USBInterface that would derive from PPPCellularInterface and could
pass the FileHandle back.
- OnboardCellularInterface is derived from UARTCellularInterfae and provides hooks to
the target provided implementation of onbard_modem_api.h. An off-board modem, i.e, a modem on
a shield has to override the modem_init(), modem_power_up() etc as it cannot use
onboard_modem_api.h.
GCC have not been capable enough to catch some linker errors which arose when
ethernet support for LWIP was disabled. Checks have been added to make sure that
unrefrenced code is not linked in.
nsapi_ppp glue layer is made more transparent to public cellular API. Storage of IP
addresses is removed. PPP layer already stores the addresses, so we pass the pointer back
to the upper layers.
If PPP is not used, we provide dummy functions.
* state machine corrections
* adding various standard API methods
* Addition/revision/enhancement of the nsapi_ppp glue layer
* Turning off debug by default
Mainly reutilizing code from ublox C027 support lib.
As we are using external PDP context, i.e., an external IP stack,
we will pass username and password to underlying stack running PPP.
We only support CHAP as the authentication protocol.
In case of carrier lost, we would like to inform PPP data pump.
That involved setting up link status flag down semaphores.
mbed_lwip_bringup() and mbed_lwip_bringdown() had been Ethernet specific only.
We extend these routines to support PPP as well. Currently we support only one interface
at a time. However, future enhancement to multi interface support should be trivial.
Observed during investigation of
https://github.com/ARMmbed/mbed-os/issues/4246 - DNS queries sent
the entire buffer, not just the bit filled in.
Inefficient, especially for 6LoWPAN, and a security hole - the trailing
data could be previously-used heap.
Note, the registered callback is still disabled by a call to
socket_attach. This will avoid being called after the socket is closed
unless close is called from the attached callback, which is in irq
context.
As pointed out by kjbracey-arm, the previous behaviour was broken
for sockets that started out listening.
To allow a network stack to support both NSAPI and its own options, try to make
sure the NSAPI levels don't collide with level numbers likely to be used by
network stacks.
Distinguish between socket and stack options, and tighten up documentation. Add
IP MRU stack options as an example (implementation not immediately planned for
any stack, but could be useful).
A few new error codes are added to nsapi_error_t and
support for non-blocking socket connect is added.
Nanostack's connect call will be non-blocking.
Whereas LWIP connect call is currently blocking, and it could be changed now
to be non-blocking.
During open, the socket checked the internal stack variable,
assuming it would alway be null on a socket not connected to
the network. However, when a socket is closed, the stack variable
was not updated, causing the socket to incorrectly return a
parameter error if reopened.
The simple fix was to set the stack to null on close. A non-null
stack is a predicate for a non-null socket variable, so no additional
checks are needed in socket functions.
It's currently possible to generate a socket event when a non-blocking socket is closed:
1. _pending is set to 0 in https://github.com/ARMmbed/mbed-os/blob/master/features/netsocket/TCPSocket.cpp#L22
when the socket is created.
2. close() calls event() in https://github.com/ARMmbed/mbed-os/blob/master/features/netsocket/Socket.cpp#L66
3. event() increments _pending, and since _pending is 1 it will call _callback() in https://github.com/ARMmbed/mbed-os/blob/master/features/netsocket/TCPSocket.cpp#L167
However, if send() (for example) is called, this can happen:
- send() is called and sets _pending to 0.
- when the data is sent, event() is called, which sets _pending to 1 and calls _callback().
- if close() is called at this point, there won't be an event generated for close() anymore,
since _pending will be set to 2.
Same thing for recv. Also, same thing for TCPServer and UDPSocket.
This PR changes the initial value of _pending to 1 instead of 0, so that
events are never generated for close().
Initially these assertions were added to protected simultaneous
send/recv from the same socket when similarly purposed mutexes were
removed.
However, simultaneous send/recv can still be useful for UDP if the
payload is guaranteed to be less than the MTU across the entire
connection.
set_ip_bytes() does a 16-byte memcpy from the input buffer to
the local nsapi_addr_t despite the address version.
If the address version is ipv4, the input buffer may only be
4-byte in size. This causes a out-of-bound access on the input buffer.
Signed-off-by: Tony Wu <tonywu@realtek.com>
nsapi_error_t - enum of errors or 0 for NSAPI_ERROR_OK
nsapi_size_t - unsigned size of data that could be sent
nsapi_size_or_error_t - either a non-negative size or negative error
Replace Comodo and OpenDNS IPv4 servers with Google and DNS.WATCH IPv6
servers, so IPv6-only devices (eg 6LoWPAN) have a default.
3 IPv4 resolvers should be plenty - existing code doesn't remember which
one last worked, so if early list entries were unreachable performance
would be consistently bad anyway. Replacing two entries avoids
increasing image size and RAM consumption.
On an IPv6-only or IPv4-only system, the sendto() for the wrong type of
address should fail immediately - change loop to move on to the next
server for any sendto() error.
- cc.h@57,1: "BYTE_ORDER" redefined
- lwip_inet_chksum.c@560,44: passing argument 1 of 'thumb2_checksum'
discards 'const' qualifier from pointer target type
- lwip_pbuf.c@1172,9: variable 'err' set but not used
- SocketAddress.cpp@293,1: control reaches end of non-void function
Takes advantage of the get_ip_address function to predict the IP
address version wanted by the underlying interface. The should avoid
the need for most IPv6 interfaces to overload gethostbyname.
suggested by @kjbracey-arm
Returning a wifi access point without information regarding the
security type is only valid if the security type is unknown (from
the perspective of the network-socket API). For clarity in situations
in which scan may return an unsupported, but known security type,
type name has been changed to NSAPI_SECURITY_UNKNOWN.