Fitbit / golden-gate

Framework to connect wearables and other IoT devices to mobile phones, tablets and PCs with an IP-based protocol stack over Bluetooth Low Energy
Other
298 stars 31 forks source link

Golden gate socket and MTU questions #28

Closed yangchi closed 3 years ago

yangchi commented 3 years ago

Hi,

This isn't an issue, but a couple questions I have when it comes to using golden gate.

(1) I find a datagram socket in gg_sockets.h, but no stream socket. Is it correct that golden gate currently only provides a datagram socket?

(2) The GATT link MTU seems to be much smaller than IP MTU. But I do find a IP packet assembler code in golden gate. Do I understand it right that if I program against the datagram socket interface in gg_socket, I only need to worry about IP MTU, not the GATT MTU or the L2CAP MTU?

(3) For NIP, GG_NipDatagramSocket_Create seems ignoring the max_datagram_size parameter. Then what type of MTU limit should I expect from NIP?

(4) I see both Android and iOS_Macos profile files set Lwip as the default socket module. May I know why isn't BSD used as default since you also provide a BSD port?

(5) Should I expect the C APIs in general in Golden Gate to work on both iOS and Android?

Thanks!

barbibulle commented 3 years ago

Hi @yangchi, sorry for not responding earlier. (1) The sockets API for now only includes UDP sockets, because the first use case for the framework was to enable secure CoAP transactions, and CoAP is transported over UDP. I do have a work in progress to add TCP sockets to the API (the underlying IP stack supports it), I'm hoping to have a PR for that soon.

(2) That's right. The GATT MTU is transparent to the upper layers, the UDP packets will get properly split into smaller payloads (that's one of the features of the so-called Gattlink protocol that we layer between the IP stack and GATT). We also don't enable IP fragmentation in the IP stack (to keep buffers at a minimum), so you do need to limit the UDP datagrams to something that fits in a single IP packet. The default IP MTU we configure is 1280, but that can be changed at runtime via the API.

(3) The NIP stack is very limited in what it supports. It doesn't enforce any runtime-changeable MTU. There's a fixed compile-time limit (GG_NIP_MAX_PACKET_SIZE) set currently at 0xFFFF. So as long as there's enough memory, it will allow you to send large datagrams. But large datagrams would likely be rejected by the next layer down, because the default size for the Gattlink ring buffer is, by default, set at 2 times the IP MTU (by default, that's configurable at runtime), so if you have datagrams that don't fit in the Gattlink buffer, they'll be rejected.

(4) On macOS and iOS, the default sockets are still LwIP sockets (BSD sockets are still enabled, but you need to ask for the specifically), because those are the ones that get routed to the Bluetooth layer. BSD sockets go through the host OS's native IP stack, so you can go over WiFi or LTE. Unfortunately, we can't connect the Bluetooth/gattlink network interface to the OS's native IP stack, because doing so would require to use an IP tunnel, which on iOS and Android require the app to act as a VPN, which isn't something practical for most apps. In the macOS build of the stack tool, however, there's an option to bridge packets to the tun/tap network interface, so as to communicate through the macOS native IP stack, but that's mostly for experimentation and debugging.

(5) All the C APIs are available on all platforms. On Android, we expose some of them, indirectly, via JNI and some Kotlin classes. But if you're willing to write your own JNI code, you can make calls into any of the C APIs. On iOS, there's no need for JNI, as the Apple tools create a Swift/C bridge automatically, but the concept is the same.

yangchi commented 3 years ago

Hi @barbibulle : Thank you so much for such detailed reply! You cleared all my questions. This is so awesome.