USSD-common

USSD-common is a command line utility for making USSD queries from n900. It is used as a backend by ussd-widget and ussd-pad. You can use it manually or utilize in your scripts.

Features

  • Decoding from all defined in standard encodings (I hope)
  • Output is always in utf-8
  • Proper locking for preventing simultaneous modem usage
  • Automatic retry support
  • USSD menu navigating support (with locking, preventing other applications eventually select wrong item)
  • Interactive mode
Locking works only within ussdquery.py command. If other application would use direct communication with modem, nothing is guaranteed.

Usage

All communication is held through ussdquery.py utility. It can be launched in two modes:
ussdquery.py <ussd number> [options]
ussdquery.py interactive [options]
Allowed options are:
  • -l language. Allowed languages: German, English, Italian, French, Spanish, Dutch, Swedish, Danish, Portuguese, Finnish, Norwegian, Greek, Turkish, Reserved1, Reserved2, Unspecified
  • -r retry count. 0 default. Use -1 for infinite
  • -f If specified, errors, which occur on last query are threated as fatal
  • -t timeout in seconds. Default 30. Timeout is considered to be critical error because you can't be sure answer for what request was returned
  • -d delimeter. Default is '\n> '
For USSD menu navigation divide USSD number via spacebars for every next menu selection. But number must be a single argument, so if you invoke ussdquery.py from shell put number in-to quotes. In intercative mode type exit to exit. In scripts you probably would mostly use first one: invoke ussdquery.py with number as argument and read reply from stdout. If an error happened stdout would always be empty and errors can be read from stderr:
Nokia-N900-42-11:~# ussdquery.py *100#
Баланс:547,11р
A little more trickery is used if you want access item from USSD menu. For this you have to make several queries, fist one with a number for menu, operator would remember that and would expect, that next USSD request contains number of an item from menu. The problem is that if several scripts try to use USSD services their queries would mix. This may lead to undefined consequences. So this operation must be atomic and your script must ensure, that it has left menu mode. As far as USSD menu is simple text without apriory known semantic, only you can handle correct leaving menu.
Making queries atomic is not a big problem because it is supported by ussdquery.py.
  • You can specify several USSD queries delimiting them by space-bar. They will be executed in one lock session. As far as one of the queries may fail and this will lead to menu not being closed, what may cause other queries fail, there is a retry functionality. You just need to specify allowed numbers of errors. Additionally you can control, if ussdquery.py should retry if last command fails. Theoretically phone may report a failure even if operator has received query. If retry is active, you would accidently make two queries, which may be not good if they activate pricey service. Anyway, this type of communications should be considered as something that works in most of the cases, but may brake and there are no good tools for dealing with this errors. In worst case you even would have to manually exit from USSD menu if script would fail somewhere in the middle.
  • Use interactive mode. In this case you would have full control on queries and would be able to handle most of errors. Put USSD queries in-to stdin (\n means, that you have finished entering query) and read replies from stdout. Additionally you can select delimiter, which would be appended to the end of every reply, so your script would be able to recognize it. Try use such delimiter, that won't occur in reply, good idea is using \r (carriage return) because \r is used to mark end of USSD reply, so something like "\r-------------------\n" should suit.
    It is guaranteed, that while you are in interactive mode other instances of ussdquery.py won't get access to modem.