> ## Documentation Index
> Fetch the complete documentation index at: https://docs.efference.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Use the Efference SDK Wirelessly

> Control the M1 over Bluetooth LE and stream video and IMU over WiFi

Wireless operation uses two separate links:

| Link               | Purpose                                                                 |
| ------------------ | ----------------------------------------------------------------------- |
| Bluetooth LE (BLE) | Control: identity, configuration, health, WiFi, recordings, and updates |
| WiFi/UDP           | Live data: video and IMU pushed from the M1 to a Linux host             |

BLE alone provides a control-only session. That is enough to inspect and
configure the device, run health checks, start device-local recordings, and
download recordings. Live video and IMU require a Linux receiving host
reachable by the M1 over WiFi.

## Before you begin

* Install the SDK on [Linux](/get-started/installation) or
  [Jetson](/get-started/install-jetson)
* Power on the M1
* Have the WiFi network name and password available
* Know the Linux host's IP address on that network if you plan to stream

## Connect with the command-line tools

<Steps>
  <Step title="Find the device">
    ```sh theme={null}
    ./sdk/linux/build/ef-cli list --scan-ble
    ```

    Each device advertises as `M1-<serial>`, so match the serial printed by
    `ef-cli list` and note that row's MAC. With several devices in range, the
    BLE address is the one just above the WiFi MAC.
  </Step>

  <Step title="Control over BLE">
    ```sh theme={null}
    ./sdk/linux/build/ef-cli --ble AA:BB:CC:DD:EE:FF info
    ```

    The factory control password is `123456`. Pass `--password` after rekeying
    the device.
  </Step>

  <Step title="Provision WiFi (once)">
    ```sh theme={null}
    ./sdk/linux/build/ef-cli --ble AA:BB:CC:DD:EE:FF \
      wifi add MyNetwork MyPassphrase US
    ./sdk/linux/build/ef-cli --ble AA:BB:CC:DD:EE:FF wifi status
    ```

    Use the ISO country code for the network's regulatory domain. Quote an
    SSID that contains spaces.
  </Step>

  <Step title="Stream video over WiFi">
    ```sh theme={null}
    ./sdk/linux/build/efference-viewer \
      --ble AA:BB:CC:DD:EE:FF --udp 192.168.1.50
    ```

    `--udp` is the Linux host's reachable IP, not the M1's address.
  </Step>
</Steps>

## Connect from C++

```cpp theme={null}
#include <ef/Device.hpp>

using namespace ef;

int main() {
    InitParameters init;
    init.input_type   = INPUT_TYPE::STREAM;      // BLE control plane
    init.ble_address  = "AA:BB:CC:DD:EE:FF";
    init.ble_password = "123456";
    init.udp_host     = "192.168.1.50";          // this machine's IP
    init.udp_port     = 5005;

    Device dev;
    if (dev.open(init) != ERROR_CODE::SUCCESS) return 1;

    Mat image;
    while (true) {
        ERROR_CODE ec = dev.grab();
        if (ec == ERROR_CODE::GRAB_TIMEOUT) continue;
        if (ec != ERROR_CODE::SUCCESS) break;

        if (dev.retrieve_image(image, VIEW::RGBA) == ERROR_CODE::SUCCESS) {
            // Process image.getPtr().
        }
    }
    dev.close();
    return 0;
}
```

Leave `udp_host` empty for a control-only BLE session. The device remains
`IDLE`, and `grab()` is unavailable.
