
Prehistory
The motive for writing this application was coursework in the discipline "Computer systems and networks". Honestly, this is one of the most unloved of me in computer technology, and I decided to “tune” the course project for my interests, namely, for Android development.
It was decided to create a library for connecting Android devices using Wi-Fi Direct technology and transferring data between them (Wi-Fi Peer-to-Peer connection is made using Wi-Fi Direct technology).
Why Wi-Fi Direct?
After approval of the idea of ​​local connection of devices, the question arose before me: What technology would I use to accomplish this? The following options were considered:
- Bluetooth
- Wi-Fi hotspot
- Wi-Fi Direct or Wi-Fi Peer-to-Peer
Bluetooth
The main disadvantages of this approach are the restriction of users in one network and a small radius of action. I want to create a group of devices that communicate with each other at a distance of at least 10 meters.
Wi-Fi hotspot
Creating an access point is not a bad option, but I am confused by the situation with the loss of the main Wi-Fi connection. I would like users to be on the local network and at the same time have access to the global network, for example, to be connected to their home router.
')
However, using Wi-Fi Hotspot you can achieve maximum data transfer speeds (
Portal applications,
SHAREit ).
Wi-Fi Direct or Wi-Fi Peer-to-Peer
This approach solves all the above problems:
- unlimited number of clients (if not, please correct me)
- long range
- connecting to devices via Wi-Fi without creating an access point
- technology supported with API 14 (Android 4.0)
But at once a doubt creeps in, saying Wi-Fi Peer-to-Peer, while we are going to create a group with the owner and clients, and all the more so that everyone can communicate with each other. This is precisely the main reason for writing this article.
Wi-Fi Aware
This option is not mentioned in the main list, because I do not think that he can fully approach the task. However, Wi-Fi Aware is a relatively young technology for sending messages in a certain range.
Let's start with the problems
To be honest, the
documentation provided by developer.android.com was not easy for me. And I started looking for samples. After going through a bunch of material, I came across the most interesting
sample by Google .
I never thought that on the official website from Google you can find govnokod, but this is exactly the case. However, even this should be given its due, since thanks to this resource I realized what I wanted.
The sample demonstrates an example of the chat of two devices that found each other in the list, displaying nearby Wi-Fi Direct devices running a chat application. When you select a partner, ChatActivity opens directly.
A very important point is the search for interlocutors: the list will not display such Wi-Fi Direct devices as a TV set or some kind of headset. Only devices with a chat application are displayed.
There was also a problem with testing. Testing the performance of the application was necessary only on real devices.
What has been implemented to demonstrate the performance of the library
The application presents the following functionality:
- choice of role in the process of working with the application (for example, were created "Mafia" and "Peaceful Resident")
- group creation
- joining an existing group
- communication between devices (when the button is pressed, its color changes both in the initiator and in all the others corresponding to the current role (or broadcast))

Description of screens from left to right:
- start screen with a choice of action and role
- list of devices that have joined the current owner of the group
- list of active groups to join
- application settings (device login, group name, password to join the group)
- Gaming screen
After the user selects which group to join, the group owner receives a message about establishing connection with this device.

The basic concept of the library
The logic is based on the client-server architecture. The server is the owner of the group, the clients are the connected users.
The application has its own Serializer / Deserializer to convert the transmitted data into an array of bytes and vice versa. The following information is stored in the transmitted data:
- whom to send (mafias, civilians, everyone)
- what kind of data (for example: changing the button color)
- the data itself (serialized Object)
The first item “to whom to send” is not entirely correct, since data is sent to all. First, the server, then the server sends this packet to all clients. But the client himself decides whether he should process this data or not. This is done for the simple reason that the server does not know the roles of its clients. In this way equality was achieved in the group. The owner differs from all the others only in that he is burdened by the transfer of data to all his clients.
Library components

- WifiDirectManager - the main class of the library; responsible for creating a group, searching for devices, attaching a device to a group or inviting it into it, sending a data packet to all members of a group
- WifiP2pDeviceObservable - implementation of the Observable pattern; when finding the Wi-Fi Direct device notifies the observer
- WifiDirectBroadcastReceiver is engaged in notifying the application about changes to the Wi-Fi Direct connection (for example: whether the connection with another device was successful), Wi-Fi status on the device (for example, disconnecting should be followed by warning the user that the application cannot continue)
- MessageShaper is responsible for serializing / deserializing transmitted data; when deserializing, we get an object of type android.os.Message (obj - object, what - for what purpose an object (for example: change the color of the button), arg1 - access type (for mafia, civilians, or broadcast))
- Serializer is directly involved in the serialization / deserialization of objects
- Status - characterizes each device as an owner of a group or a client
- ChatNeedle stores a socket on which two devices are connected to each other; processes input / output data streams; the client has only one ChatNeedle - with the owner, the owner has their number equal to the number of clients
- Member - a class describing a member of a group (not himself) for further use in a game scenario; keeps ChatNeedle to connect with this group member
- MemberList - a class that stores in itself all the devices with which our device is connected; in the case of the owner of the group - all clients, in the case of the client - the owner
- GroupOwnerSocketHandler is used by the group owner to open a certain number of sockets to which clients connect.
- ClientSocketHandler is used to establish a connection between the client and the group owner.
The most difficult problem during development
When the project reached the stage of testing multiplayer (> 2 devices), then the heat started. Two devices, as before, were connected without problems (for which, by the way, Wi-Fi Peer-to-Peer was created), but when the third link was connected, almost always trash occurred. When you press the button at the "owner" (later you will understand why in quotes) the color changed only for the client with whom the "owner" last communicated.
After long and hard hours of thinking, I decided to connect the devices via the Wi-Fi Direct option in the Wi-Fi settings of each, and noticed a thing that turned my mind and added just one line to the code of the method to establish the connection.
Before that, I believed that the device that connects to another one will always be a client ... and this is far from the case. When devices were connected, the owner's rights were randomly transferred to one of them, which prompted me to search for a config setting that would correct this situation and make the device to be connected as a client.
When two devices are connected, a special config is written, which contains:
- the address of the device we want to join
- wps.setup allows you to set how we will connect: with a password or just by pressing a button
- groupOwnerIntent - here he (caught!), the one who solved my problem; an integer field whose value varies from 0 to 15 (0 - we want to be a client, 15 - we want to be an owner); the default is -1, which gives the system the right to choose the role in this connection
final WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = deviceAddress; config.wps.setup = WpsInfo.PBC; config.groupOwnerIntent = status.getIntent(); mWifiP2pManager.connect(mWifiP2pManagerChannel, config, null);
The status (enum) above is the current position of the device, if it is the creator of the group - GroupOwner, otherwise - Client.
Necessary improvements
So far there is no solution to the problem of reconnecting. For example, when you exit the application, for example, to make a call after waiting for us waiting ... nothing. After the destruction of activity, it is necessary again to pull customers to themselves, and to customers - the owner.
I would also like to introduce the concept of transferring the owner’s rights to one of the clients in case the group owner needs to leave the game.
Protection. To enter a specific group, it would be nice to implement authorization.
Conclusion
I don’t think that I implemented something new or revolutionary, but this project served as a good example of the unusual use of Wi-Fi Peer-to-Peer connections. I have successfully built a network between devices using Wi-Fi Direct, which allowed us to communicate seamlessly between them.
This is my first article, so judge strictly. Thanks for attention.
→
Link to GitHub(wifidirect module can be easily transferred to any android project)