0

so I have been working on the task of connecting a pi to an android via wifi direct for a while, and I was able to get it to work, using the information given in this question: Issue connecting raspberry pi to android via Wifi p2p.

I now want to write some code, preferably using python and some command line libraries that automates the connection. My goal is that the connection should be completely automated as if the pi is an obfuscated IoT product, so the end user would not have to interact with the innards of the pi in any way, and could make the connection just using their phone.

This is hard to do, because the connection procedure as I understand it, requires the pi to find devices, then the user has to invite the pi on their android, and then the pi has to initiate the connection on the command line.

Is there a way to have the pi listen for invitations and initiate the connection automatically? If not, does anyone have any ideas for how I can get this to work?

One way I could do it is connect the pi to a button and have the button run the connect command, but that is not the best solution because it would be confusing and inconvenient for a user, and the pi might choose the wrong device to connect to if it finds multiple. If I go this route I would probably need a way for the user to input their device name/ mac address, perhaps with a local web server.

Thanks!

also tagging @Ingo and @Seamus. No pressure, but let me know if you guys have any ideas!

Dyskord
  • 119
  • 5
  • I'm trying to do something similar when I came across your question, it became too difficult and unstable for me (and also because what you describe needing much user interference) so going the MQTT route. My method is now: Use bluetooth to set up the RPI's wifi, then switch connection over regular internet. My method is still buggy, but you can see nymea on gihub for much cleaner approach. https://github.com/nymea thought I'd share in case this is a viable alternative for you. – gSaenz Oct 19 '20 at 07:56
  • That's actually a really good idea. In theory then the connection could be seamless because you could use the android wifi direct API to automate the connection. That's a bit harder to set up, but it definitely beats my push button idea. What frameworks/ technologies did you use to program the bluetooth connection on RPI. If you have any resources that you used you could you link me? I haven't worked with bluetooth on RPI before. Thanks! @gSaenz – Dyskord Oct 19 '20 at 17:20
  • I'm new to this also and can't articulate the details.To learn I've been reading about Bluetooth to serial, and also testing some Apps. There's Bluetooth to serial and then you have to program all the BLE commands on the rpi side. Then there's SSH as we know it, which is what I want due to the reach limitations bluetooth has. To setup the Wi-Fi over BLE the one that's worked every time is berryLan https://github.com/nymea/berrylan but I don't use their image, I install on top of my own image. In the end MQTT would be my ideal choice but unfortunately is out of reach as it requires cloud server – gSaenz Oct 20 '20 at 19:44
  • I figured out a few things about this. Check out the answer I posted – Dyskord Nov 16 '20 at 02:52

2 Answers2

2

Is there a way to have the pi listen for invitations and initiate the connection automatically? If not, does anyone have any ideas for how I can get this to work?

Wi-Fi Direct defines to use WPS (Wi-Fi Protected Setup) for authorization. WPS uses mainly two methods: mandatory PIN Entry and optional Push Button. But Push Button is mostly used because you do not have to fiddle with numbers, displays and keyboards. To push a button for authorization is very easy, but surprisingly it is one of the most secure authorization methods. An attacker from the internet can never bush a button on your device.

This is by design. Now you try to bypass authorization, but as you see it isn't easy, because it is an essential part of WPS and not intended. It will break any authorization.

If you really want to have open connections then you should consider to simply use unprotected open access points that any device can connect.

Ingo
  • 40,606
  • 15
  • 76
  • 189
0

So after a bit of poking around I've come up with two possible ways to do this.

I noticed that each p2p_peer (wpa_cli) has a status field and a flags field as well as a device_name field. When my phone is not connected to anything, the status is 0 and the flags is [PROBE_REQ something or other]. when the phone invites the pi, the status then becomes 1 and the flags becomes something like [PEER_AWAITING_RESPONSE], after another p2p_find. I imagine it is possible to check those values and then do p2p_connect after seeing the change. However, this method has some drawbacks.

  • For one, the pi doesn't know the device name or the mac address that you want. This method works best if you are connecting to a static mac address or device name, ie one type of devices or if you just need to connect to one device.
  • Secondly, it seems a bit finnicky, and when I added another phone into the mix, I got enough unexpected results that I wasn't able to tell if flags had the same value when the peer was awaiting a response from another peer other than the raspi. Sometimes the flags was empty and sometimes it said the peer was awaiting a response when it most certainly was not. I found that the online documentation on it was pretty poor, but maybe I was looking in the wrong place.

I chose to go with the second solution, but I thought I'd mention this in case someone had this problem and wasn't a fan of solution 2. If anyone does some experimentation with this and figures something out, leave a comment!

Way two is to start out with a Bluetooth connection and send data over Bluetooth to help initiate the connection, as mentioned by @gSaenz. I was able to implement this using Bluetooth Low Energy (BLE). I implemented the BLE functionality on an Arduino Nano BLE Sense, communicating the values to the raspi zero w via a serial connection. This worked for me because I was already using the arduino for other aspects of my project, and it seems to be a lot easier to get a BLE service up and running on the arduino than the pi, but you can also use the raspi zero w's built in BLE capabilities as well.

My BLE service has two characteristics (both write only): one for device name and one to tell the pi to initiate the connection. Here are the steps:

  • The phone connects over BLE, which initiates a p2p_find on the raspi.
  • The phone then writes its device name to the device name characteristic
  • Then the phone does the equivalent of a p2p_find and upon finding the raspi, it invites it to connect. now the raspi needs to p2p_connect.
  • The phone writes 1 to the second characteristic and upon seeing this, the raspi knows to start connecting.
  • It looks through its p2p_peers and finds the mac address that fits the given device name, then runs p2p_connect, finishing the connection.

The code for my solution is available at this github repo: https://github.com/MrStashley/Android-RasPi-WifiP2P-Communication

Dyskord
  • 119
  • 5
  • 1
    have an upvote, thank you for sharing. And also, what is your end goal? For me I ended up using a daemon network manager to set up the wifi via ble, then I just ssh into the rpi. (but now working to have ble gatt protocol & eliminate ssh) – gSaenz Nov 17 '20 at 16:20