Skip to content

Updated ODIN drivers to v2.5.0 RC1 #6913

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

Closed
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 additions & 0 deletions features/FEATURE_LWIP/lwip-interface/LWIPInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,11 @@ nsapi_error_t LWIP::Interface::bringdown()
#if LWIP_IPV6
mbed_lwip_clear_ipv6_addresses(&netif);
#endif
#if LWIP_IPV4
Copy link
Contributor

Choose a reason for hiding this comment

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

Why was this needed? My recollection was that lwip did zero this itself, and forgot to for IPv6, but maybe that's not true.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@andreaslarssonublox could you please respond to this?

Choose a reason for hiding this comment

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

I think it was not done for IPv4 and discovered for some case like re-connecting with static IP.

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay, I've got no problem with this going in - don't see how it can hurt.

But let's try to avoid too many miscellaneous tweaks going in - we've got a deadline (Friday) and a misbehaving CI system.

ip_addr_set_zero(&(netif.ip_addr));
ip_addr_set_zero(&(netif.netmask));
ip_addr_set_zero(&(netif.gw));
#endif

osSemaphoreDelete(has_any_addr);
osSemaphoreAttr_t attr;
Expand Down
17 changes: 17 additions & 0 deletions features/FEATURE_LWIP/lwip-interface/lwip-sys/lwip_random.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,28 @@
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip_random.h"

#if defined(DEVICE_TRNG)
#include "hal/trng_api.h"
#endif

#include "randLIB.h"

void lwip_seed_random(void)
{
#if defined(DEVICE_TRNG)
Copy link
Contributor

@kjbracey kjbracey May 16, 2018

Choose a reason for hiding this comment

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

What's going on here? LWIP is not using rand(), it's using randLIB, so this defeats lwIP's seeding.

If your driver needs rand() seeded, that's your issue, not anything to do with lwIP. And this won't achieve anything if you're not using lwIP.

If you really need to do this, it should be in your driver. However, conceptually I like to think rand() is for applications, so applications should be free to manually seed it to something non-random, without being bothered by drivers using it or seeding it in the background.

I would suggest you also use randLIB as your RNG source - that doesn't function as a a manually-seedable PRNG, so you can't interfere with other users. (And randLIB already uses the TRNG and potentially other sources as seeds).

Copy link

@andreaslarssonublox andreaslarssonublox May 16, 2018

Choose a reason for hiding this comment

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

There are two cases in this file either FEATURE_COMMON_PAL is defined or not. randLIB is only used when FEATURE_COMMON_PAL is defined if you look at the whole file. Shouldn't the seed behavior be the same for both?
We don't use rand in the driver but lwIP uses it for port assignment and depending on if FEATURE_COMMON_PAL is defined or not the behavior(seed or no seed) differs I guess?

We can remove the seeding it if it's more suited somewhere else(i.e. the application).

Copy link
Contributor

Choose a reason for hiding this comment

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

Look again - there aren't two cases in this file any more; FEATURE_COMMON_PAL was eliminated a few weeks back, so randLIB is always in use and the 'srand' isn't achieving anything. Presumably this is the result of a rebase.

Anyway, there's no time do be doing any more general non-EMAC-related lwIP fixes before 5.9 release - only things that are blocking actual EMAC integration like #6926

Copy link

@andreaslarssonublox andreaslarssonublox May 16, 2018

Choose a reason for hiding this comment

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

Ok, thanks. That explains it. We'll remove the change. Can you fix it @asifrizwanubx ?

uint32_t result;
size_t olen;
trng_t trng_obj;

trng_init(&trng_obj);
trng_get_bytes(&trng_obj, (uint8_t*)&result, sizeof result, &olen);
trng_free(&trng_obj);

srand(result);
#else
randLIB_seed_random();
#endif
}

void lwip_add_random_seed(uint64_t seed)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Copy link
Contributor

Choose a reason for hiding this comment

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

This file presumably shouldn't be being added?

Original file line number Diff line number Diff line change
@@ -0,0 +1,304 @@
#if DEVICE_WIFI

#include "mbed_interface.h"
#include "mbed_assert.h"
#include "netsocket/nsapi_types.h"

#include "wifi_emac.h"

#include "cb_wlan_target_data.h"
#include "cb_wlan_types.h"
#include "cb_wlan.h"
#include "cb_otp.h"
#include "cb_main.h"

#define WIFI_EMAC_MTU_SIZE (1500U)
static const char _ifname[] = "WL0";

cb_boolean handleWlanTargetCopyFromDataFrame(uint8_t* buffer, cbWLANTARGET_dataFrame* frame, uint32_t size, uint32_t offsetInFrame);
cb_boolean handleWlanTargetCopyToDataFrame(cbWLANTARGET_dataFrame* frame, uint8_t* buffer, uint32_t size, uint32_t offsetInFrame);
cbWLANTARGET_dataFrame* handleWlanTargetAllocDataFrame(uint32_t size);
void handleWlanTargetFreeDataFrame(cbWLANTARGET_dataFrame* frame);
cb_uint32 handleWlanTargetGetDataFrameSize(cbWLANTARGET_dataFrame* frame);
cb_uint8 handleWlanTargetGetDataFrameTID(cbWLANTARGET_dataFrame* frame);
void handleWlanStatusIndication(void *dummy, cbWLAN_StatusIndicationInfo status, void *data);
void handleWlanPacketIndication(void *dummy, cbWLAN_PacketIndicationInfo *packetInfo);
void send_wlan_packet(void *buf);

static const cbWLANTARGET_Callback _wlanTargetCallback =
{
handleWlanTargetCopyFromDataFrame,
handleWlanTargetCopyToDataFrame,
handleWlanTargetAllocDataFrame,
handleWlanTargetFreeDataFrame,
handleWlanTargetGetDataFrameSize,
handleWlanTargetGetDataFrameTID
};

void handleWlanStatusIndication(void *dummy, cbWLAN_StatusIndicationInfo status, void *data)
{
WIFI_EMAC &instance = WIFI_EMAC::get_instance();
bool linkUp = false;
bool sendCb = true;
(void)dummy;
(void)data;

switch (status) {
case cbWLAN_STATUS_CONNECTED:
case cbWLAN_STATUS_AP_STA_ADDED:
linkUp = true;
break;
case cbWLAN_STATUS_STOPPED:
case cbWLAN_STATUS_ERROR:
case cbWLAN_STATUS_DISCONNECTED:
case cbWLAN_STATUS_CONNECTION_FAILURE:
break;
case cbWLAN_STATUS_CONNECTING:
default:
sendCb = false;
break;
}
if (sendCb && instance.emac_link_state_cb) {
instance.emac_link_state_cb(linkUp);
}
}

void handleWlanPacketIndication(void *dummy, cbWLAN_PacketIndicationInfo *packetInfo)
{
WIFI_EMAC &instance = WIFI_EMAC::get_instance();
(void)dummy;

if (instance.emac_link_input_cb) {
instance.emac_link_input_cb((void*)packetInfo->rxData);
}
}

cb_boolean handleWlanTargetCopyFromDataFrame(uint8_t* buffer, cbWLANTARGET_dataFrame* frame, uint32_t size, uint32_t offsetInFrame)
{
EMACMemoryManager *mem = WIFI_EMAC::get_instance().memory_manager;
MBED_ASSERT(mem != NULL);

//emac_mem_buf_t* phead = (emac_mem_buf_t *)frame;
emac_mem_buf_t* pbuf = (emac_mem_buf_t *)frame;
uint32_t copySize, bytesCopied = 0, pbufOffset = 0;

MBED_ASSERT(frame != NULL);
MBED_ASSERT(buffer != NULL);

//pbuf = mem->get_next(phead);
while (pbuf != NULL) {
if ((pbufOffset + mem->get_len(pbuf)) >= offsetInFrame) {
copySize = cb_MIN(size, mem->get_len(pbuf) - (offsetInFrame - pbufOffset));
memcpy(buffer, (int8_t *)mem->get_ptr(pbuf) + (offsetInFrame - pbufOffset), copySize);
buffer += copySize;
bytesCopied += copySize;
pbuf = mem->get_next(pbuf);
break;
}
pbufOffset += mem->get_len(pbuf);
pbuf = mem->get_next(pbuf);
}

while (pbuf != NULL && bytesCopied < size) {
copySize = cb_MIN(mem->get_len(pbuf), size - bytesCopied);
memcpy(buffer, mem->get_ptr(pbuf), copySize);
buffer += copySize;
bytesCopied += copySize;
pbuf = mem->get_next(pbuf);
}

MBED_ASSERT(bytesCopied <= size);

return (bytesCopied == size);
}

cb_boolean handleWlanTargetCopyToDataFrame(cbWLANTARGET_dataFrame* frame, uint8_t* buffer, uint32_t size, uint32_t offsetInFrame)
{
EMACMemoryManager *mem = WIFI_EMAC::get_instance().memory_manager;
MBED_ASSERT(mem != NULL);

//emac_mem_buf_t* phead = (emac_mem_buf_t *)frame;
emac_mem_buf_t* pbuf = (emac_mem_buf_t *)frame;
uint32_t copySize, bytesCopied = 0, pbufOffset = 0;

MBED_ASSERT(frame != NULL);
MBED_ASSERT(buffer != NULL);

//pbuf = mem->get_next(phead);
while (pbuf != NULL) {
if ((pbufOffset + mem->get_len(pbuf)) >= offsetInFrame) {
copySize = cb_MIN(size, mem->get_len(pbuf) - (offsetInFrame - pbufOffset));
memcpy((uint8_t *)mem->get_ptr(pbuf) + (offsetInFrame - pbufOffset), buffer, copySize);
buffer += copySize;
bytesCopied += copySize;
pbuf = mem->get_next(pbuf);
break;
}
pbufOffset += mem->get_len(pbuf);
pbuf = mem->get_next(pbuf);
}

while (pbuf != NULL && bytesCopied < size) {
copySize = cb_MIN(mem->get_len(pbuf), size - bytesCopied);
memcpy(mem->get_ptr(pbuf), buffer, copySize);
buffer += copySize;
bytesCopied += copySize;
pbuf = mem->get_next(pbuf);
}

MBED_ASSERT(bytesCopied <= size);

return (bytesCopied == size);
}

cbWLANTARGET_dataFrame* handleWlanTargetAllocDataFrame(uint32_t size)
{
EMACMemoryManager *mem = WIFI_EMAC::get_instance().memory_manager;
MBED_ASSERT(mem != NULL);
return (cbWLANTARGET_dataFrame*)mem->alloc_pool(size,0);
}

void handleWlanTargetFreeDataFrame(cbWLANTARGET_dataFrame* frame)
{
EMACMemoryManager *mem = WIFI_EMAC::get_instance().memory_manager;
MBED_ASSERT(mem != NULL);
mem->free((emac_mem_buf_t*)frame);
}

uint32_t handleWlanTargetGetDataFrameSize(cbWLANTARGET_dataFrame* frame)
{
EMACMemoryManager *mem = WIFI_EMAC::get_instance().memory_manager;
MBED_ASSERT(mem != NULL);
return mem->get_total_len((emac_mem_buf_t*)frame);
}

uint8_t handleWlanTargetGetDataFrameTID(cbWLANTARGET_dataFrame* frame)
{
(void)frame;
return (uint8_t)cbWLAN_AC_BE;
}

WIFI_EMAC::WIFI_EMAC()
{
emac_link_input_cb = NULL;
emac_link_state_cb = NULL;
cbWLANTARGET_registerCallbacks((cbWLANTARGET_Callback*)&_wlanTargetCallback);
}

void send_wlan_packet(void *buf)
{
cbWLAN_sendPacket(buf);
}

bool WIFI_EMAC::link_out(emac_mem_buf_t *buf)
{
EMACMemoryManager *mem = WIFI_EMAC::get_instance().memory_manager;

// Break call chain to avoid the driver affecting stack usage for the IP stack thread too much
emac_mem_buf_t *new_buf = mem->alloc_pool(mem->get_total_len(buf), 0);
if (new_buf != NULL) {
mem->copy(new_buf, buf);
int id = cbMAIN_getEventQueue()->call(send_wlan_packet, new_buf);
if (id != 0) {
cbMAIN_dispatchEventQueue();
} else {
mem->free(new_buf);
}
}
mem->free(buf);
return true;
}

bool WIFI_EMAC::power_up()
{
/* Initialize the hardware */
/* No-op at this stage */
return true;
}

uint32_t WIFI_EMAC::get_mtu_size() const
{
return WIFI_EMAC_MTU_SIZE;
}

void WIFI_EMAC::get_ifname(char *name, uint8_t size) const
{
memcpy(name, _ifname, (size < sizeof(_ifname)) ? size : sizeof(_ifname));
}

uint8_t WIFI_EMAC::get_hwaddr_size() const
{
return sizeof(cbWLAN_MACAddress);
}

bool WIFI_EMAC::get_hwaddr(uint8_t *addr) const
{
cbOTP_read(cbOTP_MAC_WLAN, sizeof(cbWLAN_MACAddress), addr);
return true;
}

void WIFI_EMAC::set_hwaddr(const uint8_t *addr)
{
/* No-op at this stage */
}

void WIFI_EMAC::set_link_input_cb(emac_link_input_cb_t input_cb)
{
emac_link_input_cb = input_cb;

cbMAIN_driverLock();
cbWLAN_registerPacketIndicationCallback(handleWlanPacketIndication, NULL);
cbMAIN_driverUnlock();
}

void WIFI_EMAC::set_link_state_cb(emac_link_state_change_cb_t state_cb)
{
emac_link_state_cb = state_cb;

cbMAIN_driverLock();
cbWLAN_registerStatusCallback(handleWlanStatusIndication, NULL);
cbMAIN_driverUnlock();
}

void WIFI_EMAC::power_down()
{
/* No-op at this stage */
}

void WIFI_EMAC::set_memory_manager(EMACMemoryManager &mem_mngr)
{
memory_manager = &mem_mngr;
}

uint32_t WIFI_EMAC::get_align_preference() const
{
return 1; // TODO not sure if there is a requirement but don't think so
}

void WIFI_EMAC::add_multicast_group(const uint8_t *address)
{
// TODO anything to do here for WiFi?
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't need to do anything as long as your interface is always returning all multicasts.

Choose a reason for hiding this comment

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

Agree, so the TODOs can be removed.

}

void WIFI_EMAC::remove_multicast_group(const uint8_t *address)
{
// TODO anything to do here for WiFi?
}

void WIFI_EMAC::set_all_multicast(bool all)
{
// TODO anything to do here for WiFi?
}

WIFI_EMAC &WIFI_EMAC::get_instance() {
static WIFI_EMAC emac;
return emac;
}

// Weak so a module can override
MBED_WEAK EMAC &EMAC::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.

You should not be defining yourself as the default EMAC instance. That's only useful for Ethernet-type interfaces that can be run without configuration - it lets EthernetInterface pick you up.

(And this is causing double-definition compile errors versus the definition in stm32xx_emac.cpp)

Choose a reason for hiding this comment

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

Corrected EMAC tests to not to refer to "get_default_instance()" in this pull request: #6941
Update test environment with that when removing the "get_default_instance()"

{
return WIFI_EMAC::get_instance();
}

#endif // DEVICE_WIFI
Loading