After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 638039 - USSD with Huawei E1750/E1650
USSD with Huawei E1750/E1650
Product: NetworkManager
Classification: Platform
Component: ModemManager
git master
Other Linux
: Normal normal
: ---
Assigned To: Dan Williams
Depends on:
Reported: 2010-12-26 11:20 UTC by Guido Günther
Modified: 2011-07-22 14:30 UTC
See Also:
GNOME target: ---
GNOME version: ---

USSD response on secondary port (1.66 KB, patch)
2010-12-26 11:20 UTC, Guido Günther
none Details | Review
patches rebased (5.01 KB, application/x-gzip)
2011-06-15 18:29 UTC, Felix Möller
Huawei modems need ussd messages encoded as packed gsm (11.19 KB, patch)
2011-06-19 21:45 UTC, Guido Günther
none Details | Review

Description Guido Günther 2010-12-26 11:20:00 UTC
Created attachment 177063 [details] [review]
USSD response on secondary port

This is more of a "how to implement this properly" than an actual bug report:

While we receive the OK of a USSD command as expected we don't get the actual USSD message since this is being send on the secondary port on Huawei E1750. I've set up a unsolicited_msg_handler (see attached patch) to capture the response but I didn't find a simple way to communicate this back to ussd_initiate_done.

I know that I can override ussd_initiate in plugins/mm-modem-huawei-gsm.c (and have done so to deal with huawei specific coding issues) but how can I pass the USSD response? The only thing I could think of is to store all necessary state in the priv and fetch that in handle_ussd_reply. I would then do the mm_callback_info_schedule from there. Would that be the right way to go?
Comment 1 Guido Günther 2011-01-23 17:14:05 UTC
Any hint on howto handle this would be greatly appreciated.
Comment 2 Dan Williams 2011-01-24 04:35:38 UTC
Yeah sorry for the lag.

So we probably want to use the same mechanism for handling the response, both on the primary port if it shows up there, or the secondary port.  To do that, add the unsolicited message handler like you have done, which will capture the message on both ports.  But I think we should do this in the generic GSM code in mm_generic_gsm_grab_port() instead, since the GSM 07.07 spec says that the response will always be returned via the unsolicited code, and that can happen on any port with any modem probably.  So handling it generically instead of just in the Huawei plugin sounds better to me.

So we'll move most of the processing logic from ussd_send_done() into the unsolicted response handler that we've just added.  Of course to make the response useful, we'll need to cache the MMCallbackInfo that was the original request, so we can send the reply from the unsolicited response handler.  Which means adding a pointer to the MMCallbackINfo into the MMGenericGsmPrivate struct.

There's one problem though, which is that we don't know how long it will take that response to come through, and it may or may not be before we get the OK on the primary port.  So we need to set up a timer, which also means caching the timer's ID and making sure we remove it when disabling the modem or disposing of it.  We probably don't want to handle more than one USSD request in-flight (and reading GSM 07.07 that may not even be supported), so we might want to return an error from ussd_send() if we're waiting for the USSD response.

So basically we add two new items to the Generic private structure, a MMCallbackInfo for the USSD request, and a second guint for the solicited request timer.  We need to clear both of those when disabling the modem from disable(), and when disposing the modem from dispose().

Then, in ussd_send_done(), since we've added an unsolicited handler for +CUSD response, we won't get the +CUSD string in the reply as it will be consumed by the unsolicited reply handler already.  So what happens here is that in ussd_send() we cache the new MMCallbackInfo into the MMGenericGsmPrivate struct, and then from the unsolicited handler if there is no cached callback info, we just drop the response.  Also in ussd_send() we start the response timer with g_timeout_add().

In ussd_send_done() if there's an ERROR resposne of any kind, of course we send that in the callback info and clear the callback info *and* the response timer.  If there is just an OK, we *don't* clear the callback info or the response timer, since those will be cleared from the unsolicited handler when the response is actually processed.

The timer, if it fires because the modem screwed us, we create a new GError, complete the cached MMCallbackInfo with that error, and clear the cached MMCallbackINfo pointer and the timer.

Does that make sense? It's somewhat complicated because we need the timer, but it's actually pretty contained in just the USSD code.

Thanks for working on this!
Comment 3 Dan Williams 2011-05-19 14:57:28 UTC
Ping?  Any more questions I can answer?
Comment 4 Guido Günther 2011-05-22 20:04:22 UTC
Just a lack of time on my side. I'll have a look next weekend.
Comment 5 Guido Günther 2011-05-30 07:43:08 UTC
The current USSD code is at:

Please let me know if there's anything lacking.

Tested with Huawei E1750 and N900.
Comment 6 Guido Günther 2011-06-08 09:26:47 UTC
Anything I can do to get this merged? Are patches preferred of a git pull?
Comment 7 Felix Möller 2011-06-15 17:50:30 UTC
Hi, i just tested this on my Fedora system and run into one problem when compiling. 

  CC     modem_manager-mm-serial-parsers.o
  CC     modem_manager-mm-modem-base.o
  CC     modem_manager-mm-generic-cdma.o
  CC     modem_manager-mm-generic-gsm.o
  CC     modem_manager-mm-modem-cdma.o
mm-generic-gsm.c: In function 'ussd_received':
mm-generic-gsm.c:4773:46: error: 'info' is used uninitialized in this function [-Werror=uninitialized]
cc1: all warnings being treated as errors

make[4]: *** [modem_manager-mm-generic-gsm.o] Error 1
Comment 8 Guido Günther 2011-06-15 18:21:15 UTC looks Dan committed another implementation but it's at least lacking the Huawai code? Dan?
Comment 9 Felix Möller 2011-06-15 18:29:35 UTC
Created attachment 189997 [details]
patches rebased

Not sure if we have a misunderstanding here. I poked in your git repo at

And then rebased these patches on current ModemManager.

But looking at it again, i might have done something wrong. Could you rebase them? I cannot do this right now.

Attached you find my try ...
Comment 10 Guido Günther 2011-06-15 19:13:52 UTC
You picked the right patches but Dan implemented it slightly different:

omitting the Huawei part.
Comment 11 Felix Möller 2011-06-15 19:47:22 UTC
Thanks Guido for mentioning this. It seems Dan and I have looked at this at the same time.

Now it compiles perfectly. Although when running I get:
ppm: ERROR: ussd_initiate failed: org.freedesktop.ModemManager.Modem.General: Failed to encode USSD command '*101#'

But I think this might be another bug now?

I have a device which starts as a
Bus 001 Device 018: ID 19d2:2000 ONDA Communication S.p.A. ZTE MF627/MF628/MF628+ HSDPA
and then gets:
Bus 001 Device 019: ID 19d2:0117 ONDA Communication S.p.A.
Comment 12 Guido Günther 2011-06-15 20:06:28 UTC
Yes, that looks like a different issue. Run modem-manger with --debug and try the USSD sequence using test/ If you can reproduce it open another bug and feel free to add me as cc:.
Comment 13 Felix Möller 2011-06-18 08:20:42 UTC
Just for the record and anybody finding this via google. The report for my ZTE stick is bug #652682
Comment 14 Guido Günther 2011-06-19 21:45:59 UTC
Created attachment 190231 [details] [review]
Huawei modems need ussd messages encoded as packed gsm

This patch adds ussd_{encode,decode} to the MMModemGsmUSSD Interface so we can add quirks for the different modems. 

Huawei modems need to use packed gsm for USSD message which is implemented via the huawei plugin. 

Split up versions for easy review of this patch are available at:

It would be great if this could be applied.