Skip to content
This repository has been archived by the owner on May 24, 2019. It is now read-only.

Cleaner .h/.cpp, overloaded for WiFi parameters #59

Merged
merged 5 commits into from
Dec 14, 2017

Conversation

JanneKiiskila
Copy link
Contributor

@JanneKiiskila JanneKiiskila commented Dec 8, 2017

A more pure .h/.cpp separation - implementation in the .cpp file
and the defines in the .h file.

Added also now the option to include WiFi SSID, Password as params
via an overloaded function. There is now logic to deduce if the
params were given and they were - those will be used.

If the paramers were note given (and we're using WiFi) we will
revert using the params given in the mbed_app.json -file.

That should sort out issue #56.

Rebased on top of the no-password commit by Andrew Chong, however
I think the the comparison should >1 rather than >2 - the password
could be just one character as well.

A more pure .h/.cpp separation - implementation in the .cpp file
and the defines in the .h file.

Added also now the option to include WiFi SSID, Password as params
via an overloaded function. There is now logic to deduce if the
params were given and they were - those will be used.

If the paramers were note given (and we're using WiFi) we will
revert using the params given in the `mbed_app.json` -file.

That should sort out issue #56.

Rebased on top of the no-password commit by Andrew Chong, however
I think the the comparison should >1 rather than >2 - the password
could be just one character as well.
Copy link
Contributor

@bridadan bridadan left a comment

Choose a reason for hiding this comment

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

Good to see this being separated into .h/.cpp files, nice work. I have a few comments below.

easy-connect.cpp Outdated
printf("[EasyConnect] Connecting to WiFi %s\n", _ssid);
}
network_interface = &wifi;
connect_success = wifi.connect(_ssid, _password, (strlen(_password) > 1) ? NSAPI_SECURITY_WPA_WPA2 : NSAPI_SECURITY_NONE);
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like all of the wifi connect calls are duplicated. would it be possible to just #ifdef for the log calls for each specific options, then just switch on the WIFI macro for the connect call?

So something like:

#elif defined(WIFI)
    if (log_messages) {
        #if MBED_CONF_APP_NETWORK_INTERFACE == WIFI_ESP8266
        printf("[EasyConnect] Using WiFi (ESP8266)\n");
        #elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_RTW
        printf("[EasyConnect] Using WiFi (RTW)\n");
        #elif ....
        #endif
        printf("[EasyConnect] Connecting to WiFi %s\n", _ssid);
    }
    network_interface = &wifi;
    connect_success = wifi.connect(_ssid, _password, (strlen(_password) > 1) ? NSAPI_SECURITY_WPA_WPA2 : NSAPI_SECURITY_NONE);

Copy link
Contributor Author

@JanneKiiskila JanneKiiskila Dec 8, 2017

Choose a reason for hiding this comment

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

You're right! Yes, it can be simplified. I'm however thinking of another way...

  • for each WIFI,
    #define a WIFI_TYPE and
    then just use printf("Using WiFi (%s)\n", WIFI_TYPE);

easy-connect.cpp Outdated
if(strlen(MBED_CONF_APP_WIFI_PASSWORD) > WIFI_PASSWORD_MAX_LEN) {
printf("WARNING - MBED_CONF_APP_WIFI_PASSWORD is too long - it will be cut to %d chars.\n", WIFI_PASSWORD_MAX_LEN);
}
strncpy(_password, MBED_CONF_APP_WIFI_PASSWORD, WIFI_PASSWORD_MAX_LEN);
Copy link
Contributor

Choose a reason for hiding this comment

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

Normally I'm a big fan of avoiding dynamic allocation whenever possible, but this might be a good case to use the heap? Is there another requirement for using static allocation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well, me neither - most dynamic allocs will eventually fragment the heap. However, typically this one would be done just once at start... Passwords are rarely longer than say 8-14 characters, so there would be potential savings.

Simplify WiFi printing/logging, idea originated by Brian Daniels.
- most of the code is just duplication and if we "abstract" the
  WiFi stack name via a #define, we can just use printf() with a
  parameter as the stack name.

This shaves of quite a few repetitive lines of the implementation.
easy-connect.cpp Outdated
// If they have not been set, use the ones we can gain from mbed_app.json.
if (strlen(_ssid) == 0) {
if(strlen(MBED_CONF_APP_WIFI_SSID) > WIFI_SSID_MAX_LEN) {
printf("WARNING - MBED_CONF_APP_WIFI_SSID is too long - it will be cut to %d chars.\n", WIFI_SSID_MAX_LEN);
Copy link
Contributor Author

@JanneKiiskila JanneKiiskila Dec 8, 2017

Choose a reason for hiding this comment

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

Or should we just return 0 here? Opinions? It would likely not be able to connect anyway.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah it should just fail outright. But I think using dynamic allocation would be acceptable in this case, unless you made the requirement that the user is responsible for keeping the SSID and PASSWORD strings in scope during the lifetime of the Network Interface. Then you wouldn't have to copy the SSID at all and you could just use a pointer.

Print out the type of mesh (similar to as how we do it for WiFi as well).

Simplify the Wifi-handling more - return with 0 if the SSID or
password are too long. As we have now just one WiFi branch in
the connection we can do it with one if.
- No extra memory allocations/hard-coded buffers
- No copying, just pass the pointer or use the mbed_app -defines.

I considered doing a calloc() and then strncopy(), but that would
leave us with dangling pointers we could never free.
@JanneKiiskila
Copy link
Contributor Author

@bridadan - I think your concerns are now handled?

easy-connect.h Outdated

#elif MBED_CONF_APP_NETWORK_INTERFACE == WIFI_ODIN
#include "OdinWiFiInterface.h"
#define WIFI
Copy link
Contributor

Choose a reason for hiding this comment

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

This macro seems too generic (same with MESH). Can we prefix this with EASY_CONNECT_ or something to avoid collisions in user applications?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, we can do that (good point).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed that now.

@janjongboom
Copy link
Contributor

@JanneKiiskila This had to go with Andrew's PR but due to GH's weird review flow it was not submitted.

Rather change this to something like:

#ifndef MBED_CONF_APP_WIFI_SECURITY
#if MBED_CONF_APP_WIFI_PASSWORD == ""
#define MBED_CONF_APP_WIFI_SECURITY NSAPI_SECURITY_NONE
#else
#define MBED_CONF_APP_WIFI_SECURITY NSAPI_SECURITY_WPA_WPA2
#endif
#endif

So you can override the security setting from mbed config too (and to avoid code duplication).

@JanneKiiskila
Copy link
Contributor Author

@janjongboom - that would not work with the 2nd overloaded API with the runtime params, so it needs to be like @andrewc-arm proposes.

easy-connect.cpp Outdated
#define WIFI_TYPE "ESP8266"

#ifdef MBED_CONF_APP_ESP8266_DEBUG
ESP8266Interface wifi(MBED_CONF_APP_ESP8266_TX, MBED_CONF_APP_ESP8266_RX, MBED_CONF_APP_ESP8266_DEBUG);
Copy link
Contributor

Choose a reason for hiding this comment

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

We are relying here on macros that require them to be defined in the applications mbed_app.json

Should we instead do this properly and have mbed_lib.json within this easy-connect library?

Same goes for all MBED_CONF_APP_* macros.

This module should be usable even when application does not have mbed_app.json at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

They need to have the mbed_app.json anyway for choosing the network, so I'm not seeing the point necessarily in that.

Copy link
Contributor

Choose a reason for hiding this comment

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

The point is that these are configuration variables for Easy connect, not for the application.

Now your module does not compile if application is not defining these in mbed_app.json I don't think it is acceptable.

To avoid polluting the namespace with something too common.
Ref: Jan Jongboom - review feedback.
@JanneKiiskila
Copy link
Contributor Author

@SeppoTakalo - it's near impossible to put those parameters inside the mbed_lib.json, as the values vary so much. You can see if from here:

https://github.com/ARMmbed/mbed-os-example-client/blob/master/configs/wifi_idw01m1_v4.json#L15-L21

https://github.com/ARMmbed/mbed-os-example-client/blob/master/configs/wifi_idw01m1_v4.json#L15-L21

https://github.com/ARMmbed/mbed-os-example-client/blob/master/configs/wifi_odin_v4.json#L15-L21

https://github.com/ARMmbed/mbed-os-example-client/blob/master/configs/wifi_odin_v4.json#L15-L21

or at least some creative work would be needed. They are now overlapping. Possibly we should re-factor some of the pins to be more module specific.. I'd be tempted to delay that to another PR, as the current status is the current status - there is no change for that in this PR.

@SeppoTakalo
Copy link
Contributor

I'm not against it, if you don't want to change it. But in reality, those are configuration values for Easy connect, therefore they should be introduced in easy-connect repository.
This whole pattern seem wrong, easy connect is now depending on application defining some configuration values.
At least they seem to be documented in README.md so maybe that model works.

I would have assumed this repository to define the mbed_lib.json as

{
    "name": "easy-connect",
    "config": {
        "network-interface":{
            "help": "options are ETHERNET, WIFI_ESP8266, WIFI_IDW0XX1, WIFI_ODIN, WIFI_RTW, MESH_LOWPAN_ND, MESH_THREAD, CELLULAR_ONBOARD",
            "value": "WIFI_ESP8266"
        },
        "esp8266-tx": {
            "help": "Pin used as TX (connects to ESP8266 RX)",
            "value": "PTD3"
        },
        "esp8266-rx": {
            "help": "Pin used as RX (connects to ESP8266 TX)",
            "value": "PTD2"
        },
        "esp8266-debug": {
            "value": true
        },
        "wifi-ssid": {
            "value": "\"SSID\""
        },
        "wifi-password": {
            "value": "\"Password\""
        }
    }

Then on the application you would have following in the mbed_app.json

       "target_overrides": {
        "*": {
            "easy-connect.network-interface": "ETHERNET"
        }

@JanneKiiskila
Copy link
Contributor Author

@janjongboom - thinking of your proposal for the 2nd time - I think it would work even with run-time.

Copy link

@TeroJaasko TeroJaasko left a comment

Choose a reason for hiding this comment

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

+2. We really need to get rid of these all-the-code-in-one-header implementations.

@JanneKiiskila
Copy link
Contributor Author

Ok, the #ifndef thing with the password will not work. It's just text pre-processing as it is macros, so it will not compute.

Compile [ 99.7%]: easy-connect.cpp
[Error] mbed_config.h@47,66: token ""Password"" is not valid in preprocessor expressions
[ERROR] In file included from <command-line>:0:0:
./.\BUILD\REALTEK_RTL8195AM\GCC_ARM\mbed_config.h:47:66: error: token ""Password"" is not valid in preprocessor expressions
 #define MBED_CONF_APP_WIFI_PASSWORD                              "Password"                     // set by application

We can't compare the string with a C macro, as that would require strcmp() or similar to work in C.

Copy link
Contributor

@bridadan bridadan left a comment

Choose a reason for hiding this comment

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

So many good changes in here!

I still think the use of dynamic allocation in this case for the copying of strings for SSID and password is fine and makes for a better user experience. Having a max SSID and password length is unintuitive in my opinion.

easy-connect.cpp Outdated
if (WiFiPassword != NULL) {
if(strlen(WiFiPassword) > WIFI_PASSWORD_MAX_LEN) {
printf("WARNING - WiFi Password is too long - it will be cut to %d chars.\n", WIFI_PASSWORD_MAX_LEN);
return 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

This message is no longer true now that the return 0 is added.

I think it'd be an ok trade off to use dynamic allocation in this case to remove this failure mode. The amount memory should be very small and it just removes this edge case which would only be found at run time.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I've fixed it already in my branch (I've not pushed YET the very latest).

The size limiation is actually coming the WiFi specification, I looked up those numbers from various sources:

https://serverfault.com/questions/45439/what-is-the-maximum-length-of-a-wifi-access-points-ssid

https://security.stackexchange.com/questions/15653/recommend-length-for-wi-fi-psk

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah ok, I didn't even think to look for that! I guess that's not bad then.

I'll keep an eye out for your update on the message 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's fixed now.

Change the way we handle the default pinouts - not via mbed_app.json,
but rather have them in mbed_lib.json. This is a non-backwards
compatible change to certain extent, as the current pin defines
potentially residing in mbed_app.json would not be valid anymore.

Potential overrides need to be done differently, as the define
one has to override is the easy-connect override,
not the app override.

Error handling was giving still wrong note in 2nd branch of
easy_connect(), fixed that (ref: review feedback from Brian Daniels).

README.md also updated a bit about the related changes.
@JanneKiiskila
Copy link
Contributor Author

JanneKiiskila commented Dec 12, 2017

@bridadan - we don't need to allocate anything now with the approach done here.

  • if the user passes it, we just use the strings they already have.
  • if the string comes via mbed_app.json, we just use the #define as is.

The length checks are based on IEEE specs, I dug out the IEEE spec ref for one of those. Didn't find the WPA2, but https://security.stackexchange.com/questions/15653/recommend-length-for-wi-fi-psk says 63.

@JanneKiiskila
Copy link
Contributor Author

@SeppoTakalo - going halfway where you want it. However, this one should be still quite compliant with our CI jobs, so should not wreak havoc there.

@SeppoTakalo
Copy link
Contributor

Actually, driver should do the size checks. Most of them don't currently, but I will be adding testcases to force them to test. Therefore tests in this module are irrelevant.

@JanneKiiskila
Copy link
Contributor Author

@SeppoTakalo - should I remove those then?

@SeppoTakalo
Copy link
Contributor

Maybe in another PR. This is already exploding.
It was just a suggestion for improvement.

@JanneKiiskila
Copy link
Contributor Author

Let's remove it then once you have the WiFi drivers sorted out, let me know.

@JanneKiiskila
Copy link
Contributor Author

Test results are looking ok; ARMmbed/mbed-os-example-client#352

Copy link
Contributor

@bridadan bridadan left a comment

Choose a reason for hiding this comment

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

Changes look good!

@janjongboom
Copy link
Contributor

So why do we treat WiFi as special? https://github.com/ARMmbed/easy-connect/pull/59/files#diff-6a48c228794543db76758fdc80be436aR98 Why not cellular APN settings, or mesh channels. I'm not a big fan of this change.

@janjongboom
Copy link
Contributor

I could live with some settings object, e.g.:

EasyConnectConfig config = { .wifi_ssid = "ssid", .wifi_password = "password" };
easy_connect(&config);

Would leave for flexibility.

@JanneKiiskila JanneKiiskila merged commit 15f9b1c into master Dec 14, 2017
@JanneKiiskila
Copy link
Contributor Author

@janjongboom - that's another PR then. Feel free to submit. Though that config thing would be an "API" breaking change for easy-connect.

@JanneKiiskila JanneKiiskila deleted the cpp-wifi-param branch December 14, 2017 06:08
@JanneKiiskila
Copy link
Contributor Author

We can @janjongboom create similar easy_connect overloads for all of the bearers, if need be. However, looking at the feedback so far (i.e. issues in this repo) -> wifi is the only one that's been requested. The same approach can be applied to all bearers, though.

@SeppoTakalo
Copy link
Contributor

The moment you specify that it will be Cellular or Wifi, you are basically already away from the Easy connect's topic.
Also the example makes sense but is not valid C++, and in C it requires you to have RAM for all possible configuration parameter that this struct may have. Or maybe it is a union.

In reality, I would like to move part of the Easy Connect's job into the Mbed OS so that you could query default Wifi interface, default Cellular, or similarly to any device type.
Then applications would became portable between the same connectivity type.

Easy connect abstracts away all that. So because you are not required to specify between Wifi or Ethernet, you are either not supposed to provide configuration for those. In runtime.

For runtime configuration, easy connect is not very usable and probably not event the right choice.

@JanneKiiskila
Copy link
Contributor Author

JanneKiiskila commented Dec 14, 2017

As long as there are 3 different wifi-stacks, you need something like this anyway. The whole easy-connect is a stop-gap-filler, as soon as there is something more sensible available in Mbed OS - we should move over to that and deprecate the easy-connect.

C/C++ discussion - well, Mbed OS choice of weapon is C++ - so any points of being pure C are invalid in that context.

@andrewc-arm
Copy link
Contributor

Sorry. I was terribly busy recently.

Rebased on top of the no-password commit by Andrew Chong, however I think the the comparison should >1 rather than >2 - the password could be just one character as well.

@JanneKiiskila, it is 2 characters because it has quotes ("") for no password setting.

@JanneKiiskila
Copy link
Contributor Author

@andrewc-arm - Did you try that out with what C actually sees in strlen()?

@andrewc-arm
Copy link
Contributor

@JanneKiiskila. Nope. I just assumed. If I have time to test later, I will let you know. However, I am terribly busy onboarding new partner...

@JanneKiiskila
Copy link
Contributor Author

JanneKiiskila commented Dec 19, 2017

I did test it... :) The mbed-app long define gets turned into a simple .h-file, if you look under BUILD/BOARD/COMPILER you will find an mbed_config.h and it there just a "", which is an empty string which has length of 0.

However, I doubt it to be very easy to set the password to anything shorter than 6, since at least my phone is simply letting me to put in anything shorter than 6 characters, so probably both 1 and 2 would work equally well.

@Carmeloning
Copy link

I have some problems and i don't konw how to slow them.my platfrom is L476rg
l9ju4x862j7ya u l 3

@JanneKiiskila
Copy link
Contributor Author

@Carmeloning - near impossible to offer any help, as there are no details. Seems the WiFi cant' connect to the APN you are offering to it.

  • please check SW versions (there's been a lot of bug fixes to ESP8266), Mbed OS itself, too
  • verify your APN name and passphrase.

bellashtiv pushed a commit that referenced this pull request Dec 27, 2018
* cli work with K64F and ODIN

* define to compile in linux

* odin use updated sd repository

* add documentation

* add leds 2-5 to define
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants