on Feb.07, 2016, under Android
There are few things more frustrating than when an upgrade causes the loss of features you depend upon. In the case of my upgrade from the Nexus 4 to the Nexus 5x (and therefore from Android 5 to 6, ahem, Lollipop to Marshmallow) I lost my automation that would enable the WiFi hotspot while in my vehicle. Tethering works fine by enabling it through Settings, but it generates an error when enabling it with Macrodroid.
Enabling the hotspot is not something that is accessible from a public API, so the ordinary method seems to be to use reflection to make the change using the private API.
enforceTetherChangePermission() is called in ConnectivityManager.java. This method checks if
config_mobile_hotspot_provision_app is set, and if so, requires the
CONNECTIVITY_INTERNAL permission which is only granted to system applications.
The cause of my problem, therefore, seems to be that “Entitlement APP provisioning for Tethering” (
config_mobile_hotspot_provision_app) is enabled in the Nexus 5x-specific configuration for at least my mcc/mnc, and was not present on the Nexus 4.
After not finding any other applications or configuration to solve this problem, the path I went down was to create my own system application with the
CONNECTIVITY_INTERNAL permission, to see if it could enable the hotspot. I was successful, so I implemented the application as a Locale plugin (i.e., quickly hacked it together with the example plugin) so that it could be called directly by Macrodroid. This seems to be working fine. You can (at your own risk) download it here and then you will need to move it into /system/priv-app for it to get the privileges of a system application, probably using your recovery image (TWRP, for instance).
It may also be possible (and perhaps better) to resolve this by removing the
config_mobile_hotspot_provision_app configuration, after which it should be possible to use the native Macrodroid hotspot actions, as described here, but I’ve not tried it yet for myself.
Update 2016-09-10: For Android 7 / Nougat, the permission required is now
TETHER_PRIVILEGED, but otherwise the above method still works.
Over the past year or so, there has been the occasional threat of the Pennsylvania Game Commission requiring permits for and partially banning hiking on State Game Lands. As someone who grew up with Game Lands literally in the back yard, I’ve been following this with concern.
Naturally, media coverage is abysmal, but at least it exists. But fortunately, the PGC does post its meeting minutes. Reading from the September minutes (the January minutes are not yet posted… does that wait until they are approved at the next meeting?), the most vocal dissent of the proposal came from Commissioner Martone:
Before this proposal comes to a vote, I want to make it clear the details surrounding this proposal. As of last Thursday there were 869 comments from hunters and non-hunters opposed to this, while 197 were in favor. That’s the initial count. I will admit, that includes 597 Rails-to-Trails comments that were all opposed. Key legislators, including take 25 member at a House Game and Fisheries Committee and two other legislators are opposed to this. The Governor’s Advisory Council for hunting, fishing, and conservation unanimously opposed this. Our key conservation partners, including the Western Pennsylvania Conservancy, National Wild Turkey Federation, United Bow Hunters of Pennsylvania, Pennsylvania Federation of Sportsmen’s Clubs, all opposed to this.
Major organizations representing the Pennsylvania Equine Council, Pennsylvania State Snowmobilers Association, International Mountain Bikers Association, Keystone Rails-to-Trails, all opposed to this proposal. And most important of all, this issue is opposed by the Pennsylvania Game Commission itself. From the field staff, regional staff, headquarters staff and even senior administration, all oppose this proposal.
I would encourage everyone following this issue to pay close attention to the results of today’s vote and pay attention to who voted and how they voted, I think it’s important. Thank you.
But Commissioner Martone no longer has his position. He was replaced by a new Commissioner as one of Governor Corbett’s final acts. Ostensibly, it was administrative issue – his term was due to expire, and his replacement was named.
Now, we do know that the revised proposal was removed from the agenda of the January meeting. But it seems likely it’s not dead and buried, and in some form, it will resurface again. In the meantime, you may want to let your opinion be known on this, through the PGC, PA legislature, etc.
I’m starting to think that my preferred solution would be for all of the State Game Lands to be ceded to the Bureau of Forestry, which of all of the state lands, seems the most accommodating of all uses of public land. Now, you can cry about Game Fund money having been used to purchase all of this land, but really – with 1.5 million acres already… can’t you give some of us folks who would like to privately buy some land a chance? Perhaps the license fees need to start contributing back to the state’s general fund, instead of contributing to the Game Commission’s empire building. I’m sure there’s lots of red tape that causes it to be the way it is (which has Federal fingerprints all over it with money from the Firearms and Ammunition Excise Tax involved).
on Jan.02, 2015, under Happenings
What did I read in 2014?
Not as much as I should have. I have a lot of books on the queue, and just didn’t spend a lot of time reading this past year.
The Three Investigator’s (read these from the library as a kid; building my own collection now and re-reading them as I get them):
- The Liberty Amendments: Restoring the American Republic
- Levin presents some interesting ideas on constitutional amendments, many in support of providing for additional checks and balances in the system.
- One Second After
- Forstchen provides an account of how a small town is affected by an EMP attack on the United States. While I’m hopeful that the situation would not be as bad as the author supposes, it is a compelling story about how we would react to having most of our technology suddenly stripped away.
- Lila: An Inquiry into Morals
- Interesting, but to me seemed to end without concluding much useful.
- The Martian: A Novel
on May.06, 2013, under Linux
I have an Android car radio, and this OBD2 to USB adapter. Unfortunately, the rooted firmware currently available does not provide a cp210x kernel module that is needed to make this adapter work. This article tries to describe the process of building and installing one. Much of this article draws on the more general Building a Linux kernel module without the exact kernel headers and adds specifics for this particular purpose. I strongly suggest reading that article for more of the technical details. I don’t doubt there may be easier ways of accomplishing this, but these steps (produced through much trial-and-error and false starts) did work for me.
If you don’t need or want the how or the why, install this cp210x.ko in /system/lib/modules and run this update to change the init scripts to load it. Use at your own risk – if you brick your radio, don’t come blaming me. This expects you are already running Hal9k_’s rooted software update.
Building the Module
Finding the Parts
Finding Suitable Kernel Source
Since we’re trying to build a binary module for an already compiled kernel, we need to identify a very close copy of kernel source code to work with. To my knowledge, the exact kernel source used on the Ouku has not been released. Looking through Freescale’s website, I found a link to Linux kernel source for the SABRE tablet platform that seemed to meet the bill. The SABRE for automotive appeared to be an earlier version.
- Page containing: http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=IMX53_SW&parentCode=IMX53QSB&fpsp=1
- Link towards the download: https://www.freescale.com/webapp/Download?colCode=L2.6.35_11.05_ER_SOURCE&appType=license&location=null&fsrch=1&sr=1&Parent_nodeId=from%20search&Parent_pageType=from%20search&Parent_nodeId=1298573788032723957803&Parent_pageType=product
You need to sign up for a free account with Freescale, and accept their terms and conditions to obtain the download.
Finding Suitable Cross-Compiler
I originally tried compiling with the arm-linux-androideabi-4.4.3 that ships with android-ndk-r8e. Unfortunately, the resulting modules had compatibility problems. The solution was to use arm-linux-androideabi-4.4.0 that ships with android-ndk-r5b which can be found at http://dl.google.com/android/ndk/android-ndk-r5b-linux-x86.tar.bz2.
Obtaining the Kernel Configuration
The kernel provides a copy of its own configuration in the /proc/config.gz file. Copy this file from the unit so we can use it to configure the kernel source.
Preparing to Compile
Untar the cross-compiler
$ tar jxvf android-ndk-r5b-linux-x86.tar.bz2
Setup cross-compiler environment variables
$ export ARCH=arm
$ export SUBARCH=arm
$ export CROSS_COMPILE="/path/to/android-ndk-r5b/toolchains/arm-eabi-4.4.0/prebuilt/linux-x86/bin/arm-eabi-"
Untar the source
$ tar zxvf L2.6.35_11.05.01_ER_source_bundle.tar.gz
$ tar zxvf L2.6.35_11.05.01_ER_source.tar.gz
$ cd L2.6.35_11.05.01_ER_source/pkgs
$ tar jxvf linux-18.104.22.168.tar.bz2
$ tar jxvf linux-22.214.171.124-imx_11.05.01.bz2
Apply provided patches
$ mv patches linux-126.96.36.199
$ cd linux-188.8.131.52
Configure the kernel
$ mkdir build
$ gunzip -c /path/to/config.gz > build/.config
$ make silentoldconfig prepare headers_install scripts O=build KERNELRELEASE="184.108.40.206-01274-gb455778-dirty"
Extracting Module Symbols
Even with using this “close enough” kernel and the actual configuration from the running kernel, the module symbols used will not be identical. We need these symbols to compile our module with for it to load successfully.
Obtain the Kernel Image
We have the uImage file from Hal9k_’s software update, so we’ll use that. It is contained in a U-Boot image, so we need to strip the header off of it. We’ll also want
mkimage, a utility for making U-Boot images (on Fedora, this is available from the
$ mkimage -l uImage
Image Name: Linux-220.127.116.11-01274-gb455778-di
Created: Mon Dec 10 02:34:26 2012
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2547996 Bytes = 2488.28 kB = 2.43 MB
Load Address: 70008000
Entry Point: 70008000
$ dd if=uImage of=kernel.img bs=1 skip=64 count=70008000
Find the kernel base address
From a shell on the car radio, shortly after boot, capture the output of
dmesg and look for the “
.init” line. I copied it to my desktop first. The first hex address listed is the base address. In our case, it’s
$ grep \.init dmesg.txt
free_area_init_node: node 0, pgdat c04f94b4, node_mem_map c0599000
Kernel command line: console=null init=/init androidboot.console=null video=mxcdi0fb:RGB24,SEIKO-WVGA ldb=off di0_primary pmem=32M,64M fbmem=5M gpu_memory=64M calibration
.init : 0xc0008000 - 0xc0037000 ( 188 kB)
Grab glandium’s extract-symvers script
$ wget https://raw.github.com/glandium/extract-symvers/master/extract-symvers.py
Extract the symbols
$ python extract-symvers.py -B 0xc0008000 kernel.img > Module.symvers
Compile the Module
Copy the module symbols into kernel build
$ cp /path/to/Module.symvers build/
Create a workspace elsewhere for the cp210x module
$ mkdir cp210x
Copy the cp210x source from the kernel source to your workspace
$ cd /path/to/L2.6.35_11.05.01_ER_source/pkgs/linux-18.104.22.168/drivers/usb/serial
$ cp cp210x.c /path/to/cp210x
Create a Makefile
$ cd /path/to/cp210x
$ echo "obj-m = cp210x.o"> Makefile
Compile the module
$ cd /path/to/L2.6.35_11.05.01_ER_source/pkgs/linux-22.214.171.124
$ make M=/path/to/cp210x O=build modules KERNELRELEASE="126.96.36.199-01274-gb455778-dirty"
Testing the module
On the radio, try to install the module to make sure it loads.
# insmod cp210x.ko
<6>USB Serial support registered for cp210x
<6>cp210x 2-1.1:1.0: cp210x converter detected
<6>usb 2-1.1: reset full speed USB device using fsl-ehci and address 3
<6>usb 2-1.1: cp210x converter now attached to ttyUSB0
<6>usbcore: registered new interface driver cp210x
<6>cp210x: v0.09:Silicon Labs CP210x RS232 serial adaptor driver
Try using the serial port as well.
Installing the Module
While it’s great to have a working module, it quickly becomes tiresome to manually install it each time the radio boots. To make it more permanent, we need to properly install it.
Install to the modules directory
# mount -o rw,remount /dev/block/mmcblk0p2 /system
# cp /path/to/cp210x.ko /system/lib/modules
We also need to edit the
/init.rc file to cause the module to load on boot. Unfortunately, the root file system on which it resides is the kernel’s initial ramdisk, not a file system that we can remount as writeable on the system. Fortunately, we have this image as part of Hal9k_’s update.
Extract the initrd
Back to the desktop.
$ mkimage -l uramdisk.img
Image Name: Android Root Filesystem
Created: Sat Apr 6 08:49:03 2013
Image Type: ARM Linux RAMDisk Image (gzip compressed)
Data Size: 183417 Bytes = 179.12 kB = 0.17 MB
Load Address: 70308000
Entry Point: 70308000
$ dd if=uramdisk.img of=ramdisk.img.gz bs=1 skip=64
$ gunzip ramdisk.img.gz
$ mkdir ramdisk; cd ramdisk
$ cpio -iv < ../ramdisk.img
Edit the extracted
init.rc in your favorite text editor, and add the line for our new module, directly below the line for
Rebuild the initrd
$ find . | cpio --create --format='newc' > ../newramdisk.img
$ cd .. ; gzip newramdisk.img
$ mkimage -A arm -O linux -T ramdisk -C gzip -a 70308000 -e 70308000 -n Linux -d newramdisk.img.gz new-uramdisk.img
Image Name: Linux
Created: Mon May 6 22:17:47 2013
Image Type: ARM Linux RAMDisk Image (gzip compressed)
Data Size: 183159 Bytes = 178.87 kB = 0.17 MB
Load Address: 70308000
Entry Point: 70308000
Install the new initrd
new-uramdisk.img to the root directory of your external microSD card on the radio. Rename the file to
uramdisk.img. Reboot the radio, holding the volume knob and menu buttons down during the boot. You should see an indication that the update was successful, and the radio will reboot. The
cp210x module should now be loaded on boot!
That wasn’t such a chore, was it?
Let’s face it, Android is far more interesting when you have full control of it. The software pre-loaded on the unit does not provide root access. Hal9k_ on the xda-developers forum has created a software update that provides root and adds some additional features. To perform the update, you place the files on the root of the removable SD card, power off the radio by holding down the volume knob/button, and start the radio by holding down the volume knob/button and the menu button simultaneously.
Not exclusively a software topic, but I’ll cover this here. For full functionality, it is desirable to have the radio with internet connectivity whenever possible. When at home, this means a WiFi connection to the home network. The location of the WiFi dongle provides decent signal strength to the home network from the usual vehicle locations and works as well.
For mobile connections, it is possible to use a 3G USB dongle to provide the unit with network connectivity. I don’t have such a dongle, and with mobile provider pricing structures such as they are, I have no intention of providing my car radio with a dedicated service at this time. The alternative is to tether to my cell phone, which is also an Android device. Right now, I’m using MacroDroid on my Nexus 4 to enable and disable the WiFi hotspot feature automatically. The rules I have are:
- On Bluetooth connect to the Radio, and WiFi is not connected on the phone, enable the hotspot.
- On WiFi disconnect, and Bluetooth is connected to the Radio, enable the hotspot.
- On Bluetooth disconnect from the Radio, and hotspot enabled, disable the hotspot.
This tries to prevent enabling the hotspot in cases where WiFi is available, but properly turn on the hotspot if driving out of range of the home WiFi. So far it seems to work relatively well.
One additional area of interest is how to show the cell phone signal strength on the radio. I found the Tether Signal Strength app that provides a capability for this. Unfortunately, the current design of the app makes the signal strength hard to see, and worse, is not easily automated to start on boot on the radio, or start on hotspot on the cell phone. I think either improvements to this app, or maybe a new one entirely, will be the solution.
GPS and Navigation
Android generally will only enable the GPS receiver when there is an application actively using it, primarily as a power-saving measure. Even though there are no real power usage concerns with this device, the default software still disables the GPS receiver when not in use. Since GPS takes some time to acquire, I really prefer it to be active the entire time the device is running. I found the ActiveGPS app to meet this need, but there are probably other 3rd party apps that do just as well. As with the rest of my Android devices, I installed GPS Status to be able to check the received signal strength from the GPS constellation.
Google Maps and Navigation are certainly part of the solution for navigation on an Android device. I did want to try an App that provided similar functionality to the Garmin nüvi that I’ve used for years. While Garmin does sell navigation software for Android, from what I can tell, the reviews of recent versions have not been great, and it is also not currently available for customers in the US. I wanted something that would be fully functional when working without an Internet connection, since when I’m off exploring in the mountains and valleys around here, it’s fairly common to be without connectivity.
Currently, I’m using Sygic for this purpose. I’m not entirely sold on it, but it does appear to be functional. Depending on how actual use goes, I may just use it as a backup for the more accurate Google Navigation. Here are some notes, observations, etc:
- The navigation does not appear to be extremely efficient. I plugged in a destination of Renovo, PA from home, and the proposed route was something like 2 hours longer (and very far out of the way) as opposed to Google or the Nuvi.
- It has a small battery display which I have not found a way to turn off. It’s obviously irrelevant for the car radio.
- By default, it notifies on sharp turns and railroad crossings. While it starts out kind of novel, it quickly becomes annoying. Fortunately, these can be easily disabled in settings.
The jury is still out on this.
Vehicle Sensors and Diagnostics
It seems that the application for OBD2 stuff on Android is Torque, and it is pretty awesome.
The most common way of connecting to OBD2 seems to be to use a Bluetooth to OBD2 bridge. The Bluetooth capability of the radio, however, is not accessible to Android. The updated software provided by Hal9k_ provides a work-around to this, by adding the kernel modules necessary to support Bluetooth. You are then able to use a Linux-supported Bluetooth USB dongle. You need to install a 3rd party Bluetooth manager application, since the Bluetooth settings applet is not included in the software. When paired with an OBD2 Bluetooth adapter, you’re able to use Torque.
There are some apparent downsides to this approach. For the cheap adapter I bought, it is powered by the OBD2 port and stays active even when the engine is off. I’m not sure how significant of a drain this would be, but I would prefer not to deal with it. The second issue is related to security. The Bluetooth adapter uses a fixed, default security code for pairing, and appears to always be available to pair. It would not surprise me at all if the OBD2 could be abused to do terrible things, such as unlock the doors, by someone knowledgeable. Sure, this is probably a very small risk, but I’d prefer to avoid it. (I think those of you with OnStar are insane from a someone-else-can-control-my-vehicle-remotely standpoint).
Alternatively, Torque also supports OBD2 to USB adapters. Hal9k_’s software update also provides the
pl2303 kernel module, which supports the USB to serial bridge used by many of these adapters. If you have one of these, the only additional thing you need to do is configure Torque to use it. While Torque does have USB settings in its menu, these appear to be insufficient and you need to create a configuration file that makes it think it is a Ca-Fi unit.
echo "finland_rds_ru" > /etc/carit_version2 ; chmod 644 /etc/carit_version2
Alas, the OBD2 to USB adapter that I bought does not use the
pl2303, and instead needs
cp210x. I did successfully build and install the
cp210x kernel module, but it was an ordeal that deserves its own article. The adapter is powered by the USB, so it does not draw power when the vehicle is off.
Torque provides a variety of dials and graphs that can be used to display sensor data. You place them on a grid on the screen, and can swipe to page between multiple screens. I found it difficult to get accurate placement using the resistive touchscreen, so I used a USB mouse for most of the screen setup. As far as the sensors themselves, I was just recently able to add what seems to be a transmission fluid sensor reading. I still can’t find a usable PID for fuel level, which I found odd, since my truck and previous car both support the general PID for this, which is apparently not common. I would also like to find a way to show more details about transmission operation, such as current gear.
When I saw Doug give a short presentation on SDR on Android using the same RTL2832U/E4000 USB dongles that I have laying around, I knew this had to be an objective of my Android-in-the-car project. On the face of it, it looked as if it could be a problem. Most of the information on the SDR Touch software was on Android 3.0 or higher, while the head unit still runs 2.3. I also was concerned that the device would not have enough CPU power to make it work, or that the USB port would not have enough power to keep it working. Fortunately, these concerns were mostly unwarranted.
Out of the box, the software did fail to work. After some Google’ing, it was determined that the
chmod that comes with this system does not support the
-R option. This caused the software to fail when trying to change the permissions on the USB devices. Mounting the /system file system as read-write, and then linking
chmod to the
busybox binary, resolved the problem.
As far as CPU usage was concerned, it was not as bad as I feared it might be. Here is a table of observed CPU usage of the
androsdr2 process, when performing NFM demodulation with different settings. In all cases, the
rtl_tcp_andro process is running at a steady 5% CPU utilization, which is not included in the numbers below. Also, as one would expect and hope, when the app is not in the foreground it behaves as if the spectrum display is off. There was a noticeable, but not substantial, degradation in audio quality with the Low CPU option enabled.
|SDR CPU Selection||Spectrum Display||CPU Usage|
The user interface of the software is not very well suited (yet) for use in a vehicle. Too much user interaction is required to operate it. When loading the software, it does not automatically enable the radio. You have to select the “Off” button to turn it on. It does remember the last tuned frequency, but it does not remember the bandwidth last selected. In my case, to listen to the local weather band transmissions, it greatly improves the intelligibility of the audio to narrow the reception bandwidth. This requires something of a precise dragging motion on the screen, which is not trivial with the resistive screen, and is not really possible while the vehicle is in motion. Some minor improvements in the app could really improve this – such as remembering the last bandwidth, enabling the radio reception upon the app starting, and providing a means of having pre-sets of frequency and other parameters for listening to favorites.
Overall, this is still an amazing capability to be able to add to a car radio head unit.
There is probably more to say on this, but the article is long enough.