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

drivers: esp_at: implement bind() and recvfrom() for UDP sockets #68586

Merged

Conversation

LonesomeUnixCowboy
Copy link
Contributor

Implement bind() and recvfrom() for UDP sockets. This is achived by setting remote field in net_pkt which in return makes recvfrom() fill in *src_addr. This only works in passiv mode. Also set net_if to non-dormant when enableing AP mode to make binding to a port and address possible and back to dormant when AP is disabled.

Comment on lines 115 to 117
if (!IS_ENABLED(CONFIG_NET_IPV4) || addr->sa_family != AF_INET) {
return -EAFNOSUPPORT;
}
Copy link
Member

Choose a reason for hiding this comment

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

Looks like this is dead code. The check two lines above already checks that IPv4 is enabled so it cannot be disabled here.

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 it is. Had some brain slippage, I apologize.

/* IP addr comes within quotation marks, which is disliked by
* conv function. So we remove them.
*/
char remote_ip_addr[18];
Copy link
Member

Choose a reason for hiding this comment

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

We should not use magic constants as they are hard to guess where the number comes from. There is INET_ADDRSTRLEN that could be used here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to INT_ADDRSTRLEN.


strcpy(remote_ip_addr, &argv[1][1]);
Copy link
Member

Choose a reason for hiding this comment

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

No strcpy allowed, you need to use strncpy that restricts the length.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed to strncpy


strcpy(remote_ip_addr, &argv[1][1]);
remote_ip_addr[strlen(remote_ip_addr)-1] = 0;
Copy link
Member

Choose a reason for hiding this comment

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

Please do remote_ip_addr[sizeof(remote_ip_addr)] = '\0' instead as then the length is calculated at compile time instead of runtime.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed to suggested

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 noticed a bug with this. If the IP address is less than sizeof(remote_ip_addr) garbage would end up in remote_ip_addr. So I suggest this solution:

char remote_ip_addr[INET_ADDRSTRLEN]; 
size_t remote_ip_str_len = strlen(argv[1]); 

strncpy(remote_ip_addr, &argv[1][1], remote_ip_str_len - 2);                                                                  
remote_ip_addr[remote_ip_str_len - 2] = '\0';       


strcpy(remote_ip_addr, &argv[1][1]);
remote_ip_addr[strlen(remote_ip_addr)-1] = 0;
if (0 > net_addr_pton(AF_INET, remote_ip_addr, &recv_addr->sin_addr)) {
Copy link
Member

Choose a reason for hiding this comment

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

Please reverse the ordering here, so var < 0

Copy link
Contributor Author

Choose a reason for hiding this comment

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

reversed order

@LonesomeUnixCowboy LonesomeUnixCowboy force-pushed the esp_at_bind_udp_ap branch 3 times, most recently from 8b1c972 to 74a11e8 Compare February 6, 2024 11:56
Comment on lines 452 to 456
char remote_ip_addr[INET_ADDRSTRLEN];
size_t remote_ip_str_len = strlen(argv[1]);

err = cmd_ciprecvdata_parse(sock, data->rx_buf, len, &data_offset,
&data_len);
if (err) {
if (err == -EAGAIN) {
return -EAGAIN;
}
strncpy(remote_ip_addr, &argv[1][1], remote_ip_str_len - 2);
remote_ip_addr[remote_ip_str_len - 2] = '\0';
Copy link
Member

Choose a reason for hiding this comment

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

I do not quite follow the logic here, but guessing that -2 is there for the quotation marks? Perhaps a more clear comment could be added for that.
When copying strings, we should figure out the limit from the copy target, and not from the source.
So I suggest:

	remote_ip_str_len = MIN(sizeof(remote_ip_addr) - 1, strlen(argv[1]) - 2); 
	strncpy(remote_ip_addr, &argv[1][1], remote_ip_str_len);
	remote_ip_addr[remote_ip_str_len] = '\0';

This is not tested.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added suggested solution and extended comment. Regarding test did you mean if remote_ip_str_len is to big for remote_ip_addr? I that case i added a check for that aswell.

Copy link
Member

Choose a reason for hiding this comment

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

I just meant that I wrote the code snippet without actually testing and verifying that it works ok.

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 see. I have tested it and it works.

@LonesomeUnixCowboy LonesomeUnixCowboy force-pushed the esp_at_bind_udp_ap branch 2 times, most recently from d1c611b to 42cdc57 Compare February 6, 2024 13:07
Comment on lines 458 to 462
if (remote_ip_str_len > sizeof(remote_ip_addr) - 1) {
LOG_ERR("Received IP-address string it too long.");
err = -EIO;
return err;
}
Copy link
Member

Choose a reason for hiding this comment

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

This check is no-op, the remote_ip_str_len cannot be larger that the sizeof() as we just set the minimum value in previous line. You can remove the check, it is not really needed here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed it.

jukkar
jukkar previously approved these changes Feb 7, 2024
Copy link
Member

@jukkar jukkar left a comment

Choose a reason for hiding this comment

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

LGTM

@LonesomeUnixCowboy
Copy link
Contributor Author

Thank you @jukkar 😊

@LonesomeUnixCowboy
Copy link
Contributor Author

LonesomeUnixCowboy commented Feb 13, 2024

I have gone back from using MODEM_CMD to MODEM_CMD_DIRECT and extended cmd_ciprecvdata_parse to parse out peer IP and PORT from +CIPRECVDATA message.

Implement bind() and recvfrom() for UDP sockets. This is achived by
setting remote field in net_pkt which in return makes recvfrom() fill
in *src_addr. This is only implemented for passiv mode and CIPDINFO needs
to be enabled. Also set net_if to non-dormant when enabling AP mode to
make binding to a port and address possible.

Signed-off-by: John Johnson <john.filip.johnson@gmail.com>
@aescolar aescolar merged commit dbf3d6e into zephyrproject-rtos:main Feb 26, 2024
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants