Qstarz BT-Q1300 on Ubuntu 8.04 (Hardy Heron)

ewok251's picture

Thought I would do a quick post on how I got my Qstarz BT-1300 (aka. Qstarz Travel Recorder Nano) working on Ubuntu and BT747.

I was getting this message when plugging it in the USB port:

[ 5802.313458] usb 2-2: new full speed USB device using uhci_hcd and address 9
[ 5802.478549] usb 2-2: configuration #1 chosen from 1 choice
[ 5800.810546] /build/buildd/linux-2.6.24/drivers/usb/class/cdc-acm.c: Zero length descriptor references
[ 5800.810549]
[ 5800.810558] cdc_acm: probe of 2-2:1.1 failed with error -22

So, to fix this, a quick hack and recompile of the cdc_acm kernel module is required. The steps below are what I consider the "quick and dirty" method. The official way of recompiling the kernel and modules can be found on the Ubuntu site

Get what we need to recompile the kernel, create a .config file:

# apt-get install kernel-package libncurses5-dev fakeroot wget bzip2 buildessential linux-source module-assistant debhelper

# tar xvf linux-source-2.6.24.tar.bz2

# cd linux-source-2.6.24
# cp /boot/config-`uname -r` ./.config
# make menuconfig

This is followed by kernel configuration menu, scroll down to Load an Alternate Configuration File and choose .config (which is the default).

Now we edit the module source:

# vi drivers/usb/class/cdc-acm.c

In the file, after the line:

{ USB_DEVICE(0x0e8d,0x0003), /* MediaTek Inc MT6227 */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
},

You need to insert the following:

{ USB_DEVICE(0x0e8d, 0x3329), /* Qstarz BT-Q1300 */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
},

Now we compile:

# make modules
# make modules_install

I would suggest you now reboot just to be safe, but if you know what you're doing you can reload the cdc_acm module.

dmesg now looks like:

[ 8876.834158] usb 2-2: new full speed USB device using uhci_hcd and address 14
[ 8875.179752] usb 2-2: configuration #1 chosen from 1 choice
[ 8875.185725] cdc_acm 2-2:1.1: ttyACM0: USB ACM device

Your qstarz nano should now be accessible as /dev/ttyACM0

Hope this helps someone.

Incidently, I also tried this on an Asus Eee 901 with Ubuntu-Eee, and while I could read from /dev/ttyACM0 quite happily with MTKBabel, for some reason BT747 was unable to open the port.

mdeweerd's picture

Fixing the Eee problem

Thank you for the feedback here.

Regarding the problem you have on your Eee, I could help out if you post or send the error messages you can see in the 'info' window (if you use the desktop version).
Did you enter the '/dev/ttyACM0' path directly as the port name?

Currently BT747 does not have this as a known path which I'll fix in a future version. The Desktop version allows you to enter the path by hand and for the PDA version you need to edit the startup script.

Nice solution. Any chance you

Nice solution. Any chance you could send that patch to the kernel developers so everyone gets it in a new release?

ewok251's picture

Re: Fixing the Eee problem

Regarding sending the patch to the kernel developers, I'm not sure of the procedure, but I shall investigate it.

Eee problem, This is the message I get:

Info: trying to open /dev/ttyACM0

gnu.io.NoSuchPortException
at gnu.io.CommPortIdentifier.getPortIdentifier(CommPortIdentifier.java:218)
at gps.connection.GPSRxTxPort.openPort(Unknown Source)
at gps.connection.GPSrxtx.setFreeTextPortAndOpen(Unknown Source)
at bt747.model.Controller.openFreeTextPort(Unknown Source)
at bt747.j2se_view.BT747Main.access$300(Unknown Source)
at bt747.j2se_view.BT747Main$7.actionPerformed(Unknown Source)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6041)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
at java.awt.Component.processEvent(Component.java:5806)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4413)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4243)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
at java.awt.Container.dispatchEventImpl(Container.java:2102)
at java.awt.Window.dispatchEventImpl(Window.java:2440)
at java.awt.Component.dispatchEvent(Component.java:4243)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

I enter /dev/ttyACM0 directly as the port name, yes.

if you start the java program

if you start the java program with the following parameter (I modified run_j2se.sh)
-Dgnu.io.rxtx.SerialPorts=/dev/ttyACM0
it will accept /dev/ttyACM0 as port
(complete line:
$JAVA -Dgnu.io.rxtx.SerialPorts=/dev/ttyACM0 -Djava.library.path=${RXTXLIBPATH} -jar ${ROOT_DIR}/dist/BT747_j2se.jar &
)

and thanks for the kernel patch!

christian

patch + java program

Thanks, the both of you, for the kernel patch (I compiled a complete new sidux kernel) and for the adapted run_j2se.sh. I completely replaced the last $JAVA line with your one, christian.

And now it works!

alex

mdeweerd's picture

The need to specify the serial port on the command line ?

Hi
If you are running the 'PDA' version then you do indeed need to specify the port on the java call.

If you are running the J2SE version, there should be no need to do this: you can enter the port name directly in the port pull down box - that cell is editable and stored in the settings afterwards. The port name does not need to be in the list.
Do you have trouble with that?

Re: Nice solution. Any chance you

I have sent a patch to oliver at neukum.name who is listed as the maintainer of this part of the kernel. Hopefully this is all that will be needed to get it included in an upcoming kernel.

Hi mdeweerd Yes, I still need

Hi mdeweerd

Yes, I still need to adapt run_j2se.sh with my desktop (tested with V1.63.7 running sidux with kernel 2.6.28.1 and applied BT-1300 patch). It does not work by just entering the port in the pull down box.

Kind regards,

alex

mdeweerd's picture

Could you try with the most recent version

I changed something in one of the recent versions that probably has an impact.

The patch has been accepted for inclusion in the kernel

I just received a mail from Greg KH that the patch has been added to his local git repository. Hopefully
Linus will apply it before 2.6.29 is released. :)

It took a while to work out exactly where to send the patch and then to send it in the proper format.
Once submitted properly though, it was accepted in less than an hour. Amazing.

Could you please tell me, how

Could you please tell me, how this is done (sending a patch). Did you just send a patch to the maintainer?

FYI it will be in

FYI it will be in 2.6.29!
link to changelog entry

mdeweerd's picture

Thanks for keeping us

Thanks for keeping us updated.

No success yet

I just tried the V1.68.2. It doesn't run out of the box. I changed the last line to

$JAVA $MEM_HEAP_OPTION -Dgnu.io.rxtx.SerialPorts=/dev/ttyACM0 -Djava.library.path=${RXTXLIBPATH} -jar ${ROOT_DIR}/dist/BT747_j2se.jar $* &

and now it works flawlessly.

At least BT747 starts by just clicking on the run_j2se.sh file. Had to enter it manually in console for previous versions for some strange reason.

Hope it helps

Alexander

mdeweerd's picture

'/dev/ttyACM0'

/dev/ttyACM0 needs to be specified on the command line in the startup script currently. Following some trials of users encountering this problem I am now sure of that.

The problem seems to lie primarily with the ACM driver. I think it does not declare itself to the OS as a serial port driver which is the reason why RxTx does not detect it automatically.
The specification on the command line probably bypasses some internal RxTx checks which makes it work.

If somebody could look into that for the ACM driver that would be great.

I'll dig some more in RxTx.

mdeweerd's picture

NOt a driver problem - but default RxTx limitation

I looked into RxTx and it looks for device paths - no need for the device driver to declare itself.

Possibly a lin to the ACM device that starts with one of the following would help, it did not seem to work for one user, but looking into that further "now":
"ttyS", // linux Serial Ports
"ttySA", // for the IPAQs
"ttyUSB", // for USB frobs
"rfcomm", // bluetooth serial device
"ttyircomm", // linux IrCommdevices (IrDA serial emu)

mdeweerd's picture

RXTX hacked

I made a hack in RXTX which makes the connection to ACM0 work without changing the startup scripts.
This is currently done for the 'RXTX 2.2prelease' and can be downloaded on sourceforge in 1.68.6.1. Once 1.68.6.1 is confirmed to be working for ACM0 without hacking the startup script, I'll release it as a stable version and update the webstart versions too.

FYI: Linux kernel 2.6.29 with better BT receiver support

Just to let you know: With the new Linux kernel 2.6.29 several glitches concerning phone and BT receiver connectivity are now history.

- the Qstarz BTQ-1300 is now supported out of the box (/dev/ttyACM0) thanks to ewok251
- due to a new driver model all (?) newer Nokia phones with USB connector are now readily accessible

Unfortunately (for me), this

Unfortunately (for me), this doesn't work in x86_64 Linux (specifically, Fedora 11 with 64-bit JRE 1.6.0-14. After making the two changes to run_j2se.sh:

RXTXLIBPATH=${RXTXPATH}/Linux/x86_64-unknown-linux-gnu

and

$JAVA $MEM_HEAP_OPTION -Dgnu.io.rxtx.SerialPorts=/dev/ttyACM0 -Djava.library.path=${RXTXLIBPATH} bt747.j2se_view.BT747Main $* &

I'm able to type in /dev/ttyACM0 into the port box, but I click connect, I get a fatal error:

[me@myhost BT747]$ ./run_j2se.sh
./run_j2se.sh: line 25: [: too many arguments
./run_j2se.sh: line 38: [: too many arguments
[alan@viper BT747]$ 21 - Setting GPS port
5485 - BT747 2.X.1481 Build:BT747_mdeweerd.1481.20090706233302598
5486 - Linux
5487 - amd64
5487 - 2.6.29.5-191.fc11.x86_64
5488 - 1.6.0_14
5488 - Fail com.sun.java.swing.plaf.windows.WindowsLookAndFeel
Fail com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel
Success com.sun.java.swing.plaf.gtk.GTKLookAndFeel
javax.swing.plaf.metal.MetalLookAndFeel
com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel
com.sun.java.swing.plaf.motif.MotifLookAndFeel
com.sun.java.swing.plaf.gtk.GTKLookAndFeel

41453 - Classgps.connection.GPSRxTxPort
Experimental: JNI_OnLoad called.
RXTX Warning: Removing stale lock file. /var/lock/LCK..ttyACM0
41504 - Port opened
41529 - Attempting saving settings to /home/me/BT747SettingsJ2SE.pdb
41592 - Writing settings success for /home/me/BT747SettingsJ2SE.pdb
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fe48abc9462, pid=22200, tid=140619556858128
#
# JRE version: 6.0_14-b08
# Java VM: Java HotSpot(TM) 64-Bit Server VM (14.0-b16 mixed mode linux-amd64 )
# Problematic frame:
# C [librxtxSerial.so+0x6462] read_byte_array+0x52
#
# An error report file with more information is saved as:
# /home/me/Downloads/BT747/hs_err_pid22200.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

I think I saw a mention of incompatibility on a post previously (which I can't find now), but I was wondering if anyone knows of a solution to this (other than downgrading to the 32-bit java, of course!). I'll be glad to send the log file to someone if it'll help...

mdeweerd's picture

I do not like the 'line 25:

I do not like the 'line 25: [: too many arguments' which may well be the root cause of the issue because if this branch is not taken, the wrong library path is probably set.

You can ' -x' to the first line in 'run_j2se.sh' which will show the commands of the script.
I expected the 'if' construct to be correct, but this does not seem to be so on your system.

Try replacing the single '[' ']' with '[[' ']]' on these lines.

Replacing the single '[' ']'

Replacing the single '[' ']' with '[[' ']]' on the lines mentioned did indeed cause the error lines to go away, but didn't resolve the issue. On further investigation, it appears that the line:

ARCH=`$JAVA -jar ${ROOT_DIR}/dist/BT747_j2se.jar arch`

Is returning more than just the architecture. Specifically, it's returning (without the single quotes, but with the line feed):
'42 - Setting GPS port
amd64'

I found that if I commented out the

if [[ "$ARCH" = "amd64" ]] ; then

line and the corresponding

fi

line to force the code within to be executed, I WAS able to successfully communicate with my BT-Q1300S unit. The stranger thing is, the number before the "Setting GPS port" changes on successive runs. Another run, for example, gives:

[me@myhost BT747]$ ./run_j2se.sh
java -jar ./dist/BT747_j2se.jar arch
ARCH='40 - Setting GPS port
amd64'
[me@myhost BT747]$ 18 - Setting GPS port

In fact, running the line by itself from a bash shell yields:

[me@myhost BT747]$ java -jar ./dist/BT747_j2se.jar arch
56 - Setting GPS port
amd64[me@myhost BT747]$ java -jar ./dist/BT747_j2se.jar arch
56 - Setting GPS port
amd64[me@myhost BT747]$ java -jar ./dist/BT747_j2se.jar arch
52 - Setting GPS port
amd64[me@myhost BT747]$ java -jar ./dist/BT747_j2se.jar arch
57 - Setting GPS port
amd64[me@myhost BT747]$

So it appears that that jar file isn't doing quite what it should...

mdeweerd's picture

Hi Ok - then this is a

Hi

Ok - then this is a side-effect of a debug message I added. I'll make that message disappear in the next version ;-).
The number before the message indicates the number of ms since program start ;-).

To make things to do rapidly,

To make things to do rapidly, you can use 'bvi' binary editor.
With Ubuntu kernel source, it has a duplicated entry for device. We can edit kernel module directory without any side effect.

A procedure is as follows;

1. install 'bvi' binary editor using apt command ' apt-get install bvi'
2. backup kernel module:
$ cp /lib/modules/2.4.24-24-generic/kernel/drivers/usb/class/cdc-acm.ko ./
3. open kernel module by bvi editor
$ sudo bvi /lib/modules/2.4.24-24-generic/kernel/drivers/usb/class/cdc-acm.ko
4. search string value as (0x0e8d,0x0003) by using command
/0E8D
which is same as vi command.
there are TWO place in the module. please point 2nd one.
This may look like

000024D0 61 6C 69 61 73 3D 75 73 62 3A 76 30 45 38 44 70 alias=usb:v0E8Dp
000024E0 30 30 30 33 64 2A 64 63 2A 64 73 63 2A 64 70 2A 0003d*dc*dsc*dp*
000024F0 69 63 2A 69 73 63 2A 69 70 2A 00 00 61 6C 69 61 ic*isc*ip*..

5. change string from 0003 to 3329 using 'r' key command(same as vi key 'replace')
6. again search the raw values (0x0e8d,0x0003) by using command
#8D 0E#
the order is changed because of endian.
there are TWO place in the module. please point 2nd one.
the dump list is like
00003570 00 00 00 00 00 00 00 00 01 00 00 00 03 00 8D 0E ................
00003580 03 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 ................

7. you can edit this to '29 33' using 'r' on hex value like
00003570 00 00 00 00 00 00 00 00 01 00 00 00 03 00 8D 0E ................
00003580 29 33 00 00 00 00 00 00 00 00 00 00 01 00 00 00 )3..............

8. you can save it using command 'ZZ' now

9. 'sudo depmod -a'

10. 'sudo modprobe cdc-adm'

11. you may see good result when inserting GPS device.