Skip to contentSkip to conversation

Motorola motmdm support

DISCUSSION Pavel Machek 2 participants 12 messages Dec 29, 2018 – Jan 7, 2019 12 messages not in the archive Multifunction devices (MFD)

lore
Share & tools
lore
#0 lore raw

Hi!

Motorola phones use "interesting" setup.

There's qmi and "normal" (but very buggy) AT interface on them. Unfortunately that uses USB and uses too much power (which is a problem on phone).

Plus there's /dev/motmdm1, motmdm3 and motmdm9, multiplexed over serial line.

It uses subset of AT commands (good) with slightly modified protocol... it says ":OK" instead of "OK" and puts ~ before unsolicited messages.

Other major difference is that commands need to be sent to the right device. It seems motmdm1 is for status and call control, and motmdm9 is for incoming sms.

I guess that right way to do this is to introduce drivers/motorolamodem (or can we just have drivers/motorola?).

Best regards,
Pavel

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#1 lore raw

Hi Pavel,

Quoted 10 lines · Pavel Machek

Hi!

Motorola phones use "interesting" setup.

There's qmi and "normal" (but very buggy) AT interface on them. Unfortunately that uses USB and uses too much power (which is a problem on phone).

Plus there's /dev/motmdm1, motmdm3 and motmdm9, multiplexed over serial line.

Kernel 27.010 multiplexer or something else entirely?

Quoted 4 lines

It uses subset of AT commands (good) with slightly modified protocol... it says ":OK" instead of "OK" and puts ~ before unsolicited messages.

Funny

Quoted 8 lines

Other major difference is that commands need to be sent to the right device. It seems motmdm1 is for status and call control, and motmdm9 is for incoming sms.

I guess that right way to do this is to introduce drivers/motorolamodem (or can we just have drivers/motorola?).

For some weird historic reason we called the atom drivers and thus the subdirectory housing the relevant sources with the 'modem' suffix. So I guess we should stick to that just to be consistent.

We can have a separate discussion on whether it makes sense to drop the 'modem' suffix and what the implications are (probably none). If we decide to drop the suffix, then we should/will do it for all drivers.

Regards,
-Denis

#3 lore raw
In reply to a message not in the archive

Hi!

And thanks for a quick replies.

Quoted 8 lines
Quoted 6 lines

There's qmi and "normal" (but very buggy) AT interface on them. Unfortunately that uses USB and uses too much power (which is a problem on phone).

Plus there's /dev/motmdm1, motmdm3 and motmdm9, multiplexed over serial line.

Kernel 27.010 multiplexer or something else entirely?

Kernel 27.010 multiplexer, AFAICT. Some of the endpoints are handled in kernel (gps, audio mixer control).

Quoted 10 lines
Quoted 6 lines

Other major difference is that commands need to be sent to the right device. It seems motmdm1 is for status and call control, and motmdm9 is for incoming sms.

I guess that right way to do this is to introduce drivers/motorolamodem (or can we just have drivers/motorola?).

For some weird historic reason we called the atom drivers and thus the subdirectory housing the relevant sources with the 'modem' suffix. So I guess we should stick to that just to be consistent.

Ok.

One more question: I guess I'll need to implement this... Is there another example of driver doing AT commands but on multiple file descriptors? I could really use something to look at as a template..

Thanks,

Pavel

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#4 lore raw

Hi Pavel,

Quoted 5 lines
Quoted 1 line

Kernel 27.010 multiplexer or something else entirely?

Kernel 27.010 multiplexer, AFAICT. Some of the endpoints are handled in kernel (gps, audio mixer control).

Who sets up the multiplexer? Kernel?

It might make your job easier if the oFono driver itself invoked the necessary magic to setup the multiplexer and handed off the devices as needed. We used to have a driver like this, but not sure if it ever made it upstream.

Quoted 4 lines

One more question: I guess I'll need to implement this... Is there another example of driver doing AT commands but on multiple file descriptors? I could really use something to look at as a template..

Any driver for a USB based device would be setup this way. Each AT port is a separate file, e.g. ttyUSB1, ttyACM2, etc. The discovery is done via udev. See plugins/mbm.c or plugins/ublox.c or plugins/telit.c, etc.

Assuming you don't want to setup the multiplexer in oFono, then the only tricky part is the port setup. udevng.c setup_serial_modem() assumes a single port, so you might need to add some extra logic to setup the ports via udev rules.

Alternatively, simply use a config file specific to your driver. See for example how plugins/phonesim.c does this.

Or, if it is an extremely platform specific driver, then just hardcode it. E.g. like plugins/calypso.c, which only works for the Freerunner.

Regards,
-Denis

#7 lore raw
In reply to a message not in the archive

Hi Tony,

Quoted 10 lines
Quoted 4 lines

It might make your job easier if the oFono driver itself invoked the necessary magic to setup the multiplexer and handed off the devices as needed. We used to have a driver like this, but not sure if it ever made it upstream.

Playing with ldattach and user space handling earlier this year did not work out good.. It needed app specific handling for the Motorola custom layer on top of ts 27.010, custom handling for all the devices such as GNSS and audio mixer, and did not work well with device specific power management. So let's not go back to that :)

You still need someone to send AT+CMUX, no? And you most likely need to integrate power management into the telephony stack anyway. As I mentioned, we had a driver like this that worked just fine. oFono ended up using a user space MUX since most of the quality of life improvements to n_gsm came in much later. If I was writing a new MUXed driver these days, I'd seriously consider using GSMIOC_SETCONF and GSMIOC_ENABLE_NET.

How does the audio mixer handling work? Just some AT commands to setup the mixing parameters, or something more involved?

Some other things to consider:
- oFono expects / is designed to expect exclusive access to all the tty ports
- GNSS/GPS is intended to be handled via oFono LocationReporting API. I would recommend integrating this as intended...

Quoted 14 lines
Quoted 5 lines
Quoted 4 lines

One more question: I guess I'll need to implement this... Is there another example of driver doing AT commands but on multiple file descriptors? I could really use something to look at as a template..

Quoted 8 lines

Any driver for a USB based device would be setup this way. Each AT port is a separate file, e.g. ttyUSB1, ttyACM2, etc. The discovery is done via udev. See plugins/mbm.c or plugins/ublox.c or plugins/telit.c, etc.

Assuming you don't want to setup the multiplexer in oFono, then the only tricky part is the port setup. udevng.c setup_serial_modem() assumes a single port, so you might need to add some extra logic to setup the ports via udev rules.

Quoted 4 lines

We have network status data at /dev/motmdm1, outgoing SMS PDU device at /dev/motmdm3, incoming SMS PDU device at /dev/motmdm9 and so on for each ts 27.010 channel. At least incoming and outgoing SMS PDU devices could be considered as separate modems if that makes things easier?

No, that just makes things more difficult.

Quoted 4 lines
Quoted 4 lines

Alternatively, simply use a config file specific to your driver. See for example how plugins/phonesim.c does this.

Quoted 9 lines
Quoted 2 lines

Or, if it is an extremely platform specific driver, then just hardcode it. E.g. like plugins/calypso.c, which only works for the Freerunner.

Just adding one more thing to consider: Looks like the modem handling for SMS PDU's needs to be specific to the nework. First the network needs to be detected, and then the GSM or CDMA handlers need to be used for sending and receiving SMS. After that things should get standard.. Looks like ofono has parsing for the different type SMS PDUs in src/*sms*.c :)

There's no real functional CDMA support in oFono anyhow. Given that most CDMA networks are about to be switched off, I don't know why you would bother?

Regards,
-Denis

#10 lore raw
In reply to a message not in the archive

Hi Tony,

Quoted 11 lines · Tony Lindgren
Quoted 6 lines · Denis Kenzior

You still need someone to send AT+CMUX, no? And you most likely need to integrate power management into the telephony stack anyway. As I mentioned, we had a driver like this that worked just fine. oFono ended up using a user space MUX since most of the quality of life improvements to n_gsm came in much later. If I was writing a new MUXed driver these days, I'd seriously consider using GSMIOC_SETCONF and GSMIOC_ENABLE_NET.

No need to type AT+CMUX or anything, things start in ts 27.010 mode from the start for the hardware. Then the serdev driver layer handles doing GSMIOC_SETCONF.

Gotcha. That makes things a bit easier.

Quoted 4 lines

I have not played with GSMIOC_ENABLE_NET, I thought that needed support on the modem side as well, but maybe not?

It requires the modem to support Raw IP. Many (most?) AT command based modems do these days, no idea about your hardware.

Quoted 2 lines

Would GSMIOC_ENABLE_NET make things easier from ofono point of view?

Depends on your definition of easier. The real reason for GSMIOC_ENABLE_NET is speed/efficiency. In a typical 27.010 / 27.007 compliant modem you'd setup N logical AT command channels where N = 1 (minimum, but can be more if you want) + max number of active contexts. Typically modems support 3+ of these. Once a context is activated, you'd switch the channel into data mode via AT+CGDATA (e.g. for PPP or raw IP) and start shoving your network packets on that channel in the format chosen.

How are you handling data connections? PPP? Or is there some other protocol to transfer packets back and forth?

Quoted 5 lines
Quoted 2 lines

- GNSS/GPS is intended to be handled via oFono LocationReporting API. I would recommend integrating this as intended...

We have a standard kernel GNSS API now :) And we have /dev/gnss0 already working for droid 4.

That's great. But I think my recommendation still stands. You want GPS state to be synchronized with the overall modem state, etc...

Quoted 9 lines
Quoted 4 lines

There's no real functional CDMA support in oFono anyhow. Given that most CDMA networks are about to be switched off, I don't know why you would bother?

Hmm right, good point. Anyways that's how the SMS gets sent and received in the US for droid 4 currently.. The file I was looking at is src/cdma-sms.c and the only thing to do there is the PDU coding and encoding.

I believe the utilities you mention should be good enough to decode the basics. I think someone has even tested these on a real network at some point. But the people working on CDMA have not contributed since ~2011, so I have no idea about the state of that code. I was considering removing it given that CDMA is essentially defunct (or will be in a few years).

Regards,
-Denis

#13 lore raw
In reply to a message not in the archive

Hi Tony,

Quoted 7 lines
Quoted 2 lines

How are you handling data connections? PPP? Or is there some other protocol to transfer packets back and forth?

All the data connections in this case are done using QMI over USB.

And that probably explains why I have not seen any data related stuff on ts 27.010.

Ew. So is everything related to packet services is running over QMI?

When Pavel explained that he wanted to use the weird squiggly AT commands, I assumed you wanted to run the packet services over AT as well.

Quoted 7 lines
Quoted 7 lines
Quoted 6 lines
Quoted 3 lines

- GNSS/GPS is intended to be handled via oFono LocationReporting API. I would recommend integrating this as intended...

We have a standard kernel GNSS API now :) And we have /dev/gnss0 already working for droid 4.

Quoted 7 lines
Quoted 2 lines

That's great. But I think my recommendation still stands. You want GPS state to be synchronized with the overall modem state, etc...

Hmm sounds like ofono would benefit from using /dev/gnss0 in the long run though. I guess the situation is similar to having multiple computer mouse drivers earlier with their own interfaces vs standard /dev/input :)

Yep, agreed. I already tried to nudge Pavel to propose something.

Quoted 9 lines
Quoted 6 lines

I believe the utilities you mention should be good enough to decode the basics. I think someone has even tested these on a real network at some point. But the people working on CDMA have not contributed since ~2011, so I have no idea about the state of that code. I was considering removing it given that CDMA is essentially defunct (or will be in a few years).

OK, sounds like we might need the CDMA PDU features for few more years though.

That's fine, as long as someone is actually using these. Right now it is unmaintained code.

Quoted 7 lines

Oh, I think I forgot to answer your question regarding PM, there's nothing that the user space needs to except to avoid polling the /dev/motmdm* devices unnecessarily. And to type AT+SCRN=0 on /dev/motmdm1 when no notifications for signal strength and network status are needed.

Right, but since /dev/motmdm1 would in theory belong exclusively to oFono, you probably still need some way of sending the screen 'off' command. So in effect you're integrating power management with the telephony stack.

Regards,
-Denis

#15 lore raw
In reply to a message not in the archive

Hi!

Quoted 5 lines
Quoted 5 lines
Quoted 2 lines

How are you handling data connections? PPP? Or is there some other protocol to transfer packets back and forth?

All the data connections in this case are done using QMI over USB.

Quoted 7 lines
Quoted 2 lines

And that probably explains why I have not seen any data related stuff on ts 27.010.

Ew. So is everything related to packet services is running over QMI?

When Pavel explained that he wanted to use the weird squiggly AT commands, I assumed you wanted to run the packet services over AT as well.

No idea about packet data for now. I currently run them over qmi... which means increased power consumption, I guess that's ok if data are active.

Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

- GNSS/GPS is intended to be handled via oFono LocationReporting API. I would recommend integrating this as intended...

We have a standard kernel GNSS API now :) And we have /dev/gnss0 already working for droid 4.

That's great. But I think my recommendation still stands. You want GPS state to be synchronized with the overall modem state, etc...

Quoted 6 lines
Quoted 4 lines

Hmm sounds like ofono would benefit from using /dev/gnss0 in the long run though. I guess the situation is similar to having multiple computer mouse drivers earlier with their own interfaces vs standard /dev/input :)

Yep, agreed. I already tried to nudge Pavel to propose something.

?

I believe that kernel doing the multiplexing and "normal" /dev/gnss0 being available to userspace is actually very nice solution.

Quoted 10 lines
Quoted 6 lines

Oh, I think I forgot to answer your question regarding PM, there's nothing that the user space needs to except to avoid polling the /dev/motmdm* devices unnecessarily. And to type AT+SCRN=0 on /dev/motmdm1 when no notifications for signal strength and network status are needed.

Right, but since /dev/motmdm1 would in theory belong exclusively to oFono, you probably still need some way of sending the screen 'off' command. So in effect you're integrating power management with the telephony stack.

I don't understand. Display power management should be separate from ofono?

Tony: are there expected to be differences between motmdm1 and other ttys? It does not gatchat seems to work ok with ttyUSB4, but does not quite behave with motmdm1. Are the settings like ctsrts and baudrates used for something?

Plus, it seems has its own subsystem, so
this is needed:

+ udev_enumerate_add_match_subsystem(enumerate, "motmdm");

Best regards,

Pavel

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#23 lore raw
In reply to Pavel Machek

Hi!

Quoted 6 lines

Motorola phones use "interesting" setup.

There's qmi and "normal" (but very buggy) AT interface on them. Unfortunately that uses USB and uses too much power (which is a problem on phone).

Quoted 6 lines

Plus there's /dev/motmdm1, motmdm3 and motmdm9, multiplexed over serial line.

It uses subset of AT commands (good) with slightly modified protocol... it says ":OK" instead of "OK" and puts ~ before unsolicited messages.

Ok, turns out the setup is not that unusual, calypso also uses few different channels.

This is where I got so far; yes, I'm probably doing everything wrong, but hey, at least motmdm1 is detected and in some cases I even get status messages...

Pavel

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#16 lore raw
In reply to a message not in the archive

Hi!

Quoted 5 lines

Oh, I think I forgot to answer your question regarding PM, there's nothing that the user space needs to except to avoid polling the /dev/motmdm* devices unnecessarily. And to type AT+SCRN=0 on /dev/motmdm1 when no notifications for signal strength and network status are needed.

Is it possible that epoll() does not work properly with /dev/motmdm*? I am debugging weird problems with ofonod, and that would be an explanation...

epoll.poll() should be returning list of file descriptors and if they are ready. And it seems to work for ttyUSB4 but not for motmdm.

Hmm. And motmdm_cdev_poll() lacks EPOLLOUT() support, right? That could explain things...

Best regards,
Pavel

Type "help", "copyright", "credits" or "license" for more information.

Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

f = open("/dev/ttyUSB4", "r+")
f.write("AT\r\n")

import select
epoll = select.epoll()
epoll.register(1, select.EPOLLOUT) epoll.register(f.fileno(), select.EPOLLOUT | select.EPOLLIN) epoll.poll(1)

[(1, 4), (3, 5)]

Quoted 1 line
Quoted 1 line
Quoted 1 line

select.EPOLLOUT

4

Quoted 1 line
Quoted 1 line
Quoted 1 line

select.EPOLLIN

1

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

f = open("/dev/motmdm1", "r+")
#f = open("/dev/ttyUSB4", "r+")

... f.write("AT\r\n")

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

import select
epoll = select.epoll()
epoll.register(1, select.EPOLLOUT) epoll.register(f.fileno(), select.EPOLLOUT | select.EPOLLIN) epoll.poll(1)

[(1, 4)]

Quoted 1 line
Quoted 1 line
Quoted 1 line
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#19 lore raw
In reply to a message not in the archive
Quoted 11 lines · Tony Lindgren
Quoted 9 lines · Pavel Machek

Is it possible that epoll() does not work properly with /dev/motmdm*? I am debugging weird problems with ofonod, and that would be an explanation...

epoll.poll() should be returning list of file descriptors and if they are ready. And it seems to work for ttyUSB4 but not for motmdm.

Hmm. And motmdm_cdev_poll() lacks EPOLLOUT() support, right? That could explain things...

Quoted 7 lines

Hmm yeah maybe.

FYI, I just pushed a test script into github droid4-sms-tools repo for sending SMS and a related kernel fix for ctrl-z termination into k.o droid4-pending-mdm-v4.20 branch.

But that seems to fix a different issue from what you're seeing.

Yes, I can easily work around the problem like this:

It needs huge fixme there, but if you could include it... "always ready" is better than "never ready".

I'm currently adding code to ofono... I can decode incoming SMS. Current is here. https://github.com/pavelmachek/ofono

Have you figured out how the incoming calls are supposed to work? I'm getting this on incoming call:

ofonod[2534]: Voice: < ~+WAKEUP\n\r
ignoring line
ofonod[2534]: Voice: < ~+WAKEUP\n\r
ignoring line
ofonod[2534]: Voice: < ~+WAKEUP\n\r
ignoring line
ofonod[2534]: Voice: < ~+CIEV=1,4,0\n\r
ignoring line
ofonod[2534]: Voice: < ~+CLIP="+420xxxxxxxxx",1,1,"",0,"",0\n\r ignoring line
ofonod[2534]: Voice: < ~+WAKEUP\n\r
ignoring line
ofonod[2534]: Voice: < ~+WAKEUP\n\r
ignoring line
ofonod[2534]: Voice: < ~+WAKEUP\n\r
ignoring line
ofonod[2534]: Voice: < ~+CIEV=1,0,0\n\r
ignoring line

ofonod[2534]: Voice: < ~+WAKEUP\n\r
ignoring line
ofonod[2534]: Voice: < ~+WAKEUP\n\r
ignoring line
ofonod[2534]: Voice: < ~+WAKEUP\n\r

I probably could use +CLIP as "there's incoming call", but I don't see anything useful when I hang up and phone should stop ringing.

Best regards,
Pavel

drivers/mfd/motorola-mdm.c +1 -0
index 2cdc9e8..abf58e3 100644
@@ -706,6 +706,7 @@ static __poll_t motmdm_cdev_poll(struct file *file, poll_table *wait)
 		mask |= EPOLLIN | EPOLLRDNORM;
 	if (cdata->disconnected)
 		mask |= EPOLLHUP;
+	mask |= (EPOLLOUT | EPOLLWRNORM);
 
 	return mask;
 }
Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#22 lore raw
In reply to a message not in the archive

Hi!

Quoted 9 lines
Quoted 6 lines
Quoted 1 line

But that seems to fix a different issue from what you're seeing.

Yes, I can easily work around the problem like this:

It needs huge fixme there, but if you could include it... "always ready" is better than "never ready".

OK I'll take a look when I get a chance. I think all we need to do there is check that cdata->write_offset < cdata->write_buf_sz.

Makes sense. And you probably need to wake up userspace when buffer was full and free space appears.

Quoted 2 lines
Quoted 2 lines

Have you figured out how the incoming calls are supposed to work? I'm getting this on incoming call:

...

Quoted 10 lines
Quoted 7 lines

ofonod[2534]: Voice: < ~+CIEV=1,4,0\n\r
ignoring line
ofonod[2534]: Voice: < ~+CLIP="+420xxxxxxxxx",1,1,"",0,"",0\n\r ignoring line

I probably could use +CLIP as "there's incoming call", but I don't see anything useful when I hang up and phone should stop ringing.

Parsing the number(s) from +CIEV should tell that, see what I added to motmdm_read_state().

+CIEV is documented as "indicator event". I can make ofono parse that, but it will be ... slightly hacky.

Is there "RING" or something like that going on any of the interfaces?

BTW does 5.0-rc1 boot for you?

Best regards,
Pavel

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html