Phicomm R1 Smart Speaker Revived
Wireless Configuration
Most smart devices such as speakers, sockets, air conditioners are headless embedded devices, these devices need to be connected to the home network to make it a smart device, since they are lack of user interfaces such as keyboards or touchscreens, SmartConfig was created to make this process easier, and most of the domestic smart speaker vendors adopted this method.
Since the company behind R1 is not in operation any more, the app they developed does not work, we need to find a solution to configure its wireless connection, follow the steps to complete wifi configuration:
- Device power up.
- Press the round button on top of the speaker for 5s until the light at the bottom turned on, and prompting, starting network configuration.
- Connect your computer to access point named Phicomm_R1_xxxx, and check the IP address of the computer.
- Connect to it with adb and install the latest release of adb-join-wifi.apk
adb connect 192.168.43.1 adb push ~/Downloads/adb-join-wifi.apk /data/local/tmp/ adb shell /system/bin/pm install -t /data/local/tmp/adb-join-wifi.apk adb shell am start -n com.steinwurf.adbjoinwifi/.MainActivity \ -e ssid avocado -e password_type WPA -e password yourpassword
You will see below screenshot if you have connection to it with scrcpy:
-
Waiting for the voice direction, network configuration completed, actually this is not the succeeded completion, it is timeout, but it just works. This is because the wifi module works in either station mode or AP mode, when R1 is in network configuration mode, it works as an AP, it cannot connect to another router, until it switched back to station mode.
- Now you can find its IP address through router’s web interface, the device name is PHICOMM_R1_xxxx.
Device Binding
The speaker cannot work without binding, the device binding process involves interaction with server, which is dead now, you will see the follow messages in logcat:
07-11 18:30:15.528 1119 1333 D DeviceStateMgr: [ lineNumber =233 ] query device bound status
07-11 18:30:15.546 1119 1333 E HttpUtils: [ lineNumber =-1 ] http post error : Unable to resolve host "aios-home.hivoice.cn": No address associated with hostname
07-11 18:30:15.546 1119 1333 E DeviceStateMgr: [ lineNumber =239 ] queryDeviceBoundStatus error, query bound status error, response is null
From the above message we know the process id is 1119, the package name and the
apk are easily to get with ps
and pm path
:
adb shell ps|grep 1119
u0_a8 1119 209 961540 127396 ffffffff 00000000 S com.phicomm.speaker.device
adb shell /system/bin/pm path com.phicomm.speaker.device
package:/system/app/Unisound/Unisound.apk
In order to make things clear we need to figure out what the app do when doing device binding.
Decompiling apk
REVERSE ENGINEERING APPS MAY BE ILLEGAL, THIS BLOG POST IS STRICTLY FOR EDUCATION PURPOSE.
jadx is a tool used for producing java source code from android dex or apk files.
First off, download the prebuilt release or build from source code:
git clone --depth 1 https://github.com/skylot/jadx.git
cd jadx
./gradlew dist
./build/jadx/bin/jadx-gui
Then decompile Unisound, we can locate the desired source code with the help of
the log message:
So, now we know we need to replay with a response with status set to 0 in json
format to make isDeviceBounded
to return true.
Add DNS Record to Pi-hole
To make the domain name aios-home.hivoice.cn
resolvable, a record need to add
to /etc/hosts
in device or add to DNS server, I use Pi-hole as my local network
DNS server:
Make A Tiny HTTP Server
I am not going to make fully functional server, this piece of code builds a simple http server only handling post message:
#!/usr/bin/env python
import logging
import json
from http.server import HTTPServer, BaseHTTPRequestHandler
class MessageHandler(BaseHTTPRequestHandler):
def do_POST(self):
user_status = {'status': '0'}
content_len = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_len)
logging.error("POST request,\nHeaders:\n%s\n\nBody:\n%s\n",
str(self.headers), post_data.decode('utf-8'))
self.send_response(200)
self.send_header("Content-type", "application/json")
self.end_headers()
self.wfile.write(json.dumps(user_status).encode())
if __name__ == "__main__":
serverip = ('', 19999)
httpd = HTTPServer(serverip, MessageHandler)
httpd.serve_forever()
Now, the speaker is working now, it is not as smart as before though, let’s play.
Streaming Music with Airplay
Playing music with a2dp connection is not a good choice as it is not stable when your cell phone and the speaker is not in the same room, and there are too many interferences at 2.4G Hz band, so airplay and DLNA are the best way to listen music with this good quality speaker.
- Make sure the speaker was connected to 5G wireless network.
- Activate bluetooth by saying, Open Bluetooth.
- Swipe up your phone to go to Control Center, touch airplay control at the top right corner and select the phicomm device under SPEAKERS &TVs:
The builtin airplay working well except you need to enable bluetooth every time you want to steam music with it.
Another way to do airplay is to install third-party apk, download hpplay from here, and install with adb connection:
adb push ~/Downloads/202005111602_hpplay-2003-release-v8.4.78_1.apk /data/local/tmp/hpplay.apk
adb shell /system/bin/pm install /data/local/tmp/hpplay.apk
adb shell am start com.hpplay.happyplay.aw/.WelcomeActivity
NOTE: When a new device trying to connect to the speaker, you need to select allow the connection when the app prompts you, this only need to set once.
Troubleshooting
Adb install failed with waiting for device
adb install ~/Downloads/202005111602_hpplay-2003-release-v8.4.78_1.apk
/Users/fdbai/Downloads/202005111602_hpplay-2003-release-v8.4.78_1.apk: 1 file pushed. 0.4 MB/s (19891275 bytes in 48.946s)
- waiting for device -
- waiting for device -
- waiting for device -
A: Use pm install
instead.
Pm install failed with error: closed
adb shell pm install /data/local/tmp/hpplay.apk
error: closed
A: Message in logcat show that it is not supported to create sub process:
07-12 17:02:32.979 211 211 I create_subproc_thread: create_subproc not support <pm install /data/local/tmp/hpplay.apk>, so return -1
Use pm with full path(/system/bin/pm) works.
Choppy music when connected to 2.4G wireless network
Both builtin airplay and hpplay
have this problem, with latter one, logcat show
there are many resend packets:
07-10 17:25:26.764 19475 20119 D hpplay-base: [AudioStream:48] ###resend_callback,request seq:38005,count:10###
07-10 17:25:27.062 19475 20119 D hpplay-base: [AudioStream:48] ###resend_callback,request seq:38018,count:4###
07-10 17:25:27.154 19475 20119 D hpplay-base: [AudioStream:48] ###resend_callback,request seq:38023,count:2###
07-10 17:25:27.254 19475 20119 D hpplay-base: [AudioStream:48] ###resend_callback,request seq:38029,count:8###
07-10 17:25:27.644 19475 20119 D hpplay-base: [AudioStream:48] ###resend_callback,request seq:38051,count:11###
This issue disappears after switched to 5G wireless net work.