Hints for libGammu Novices  -  Phil Endecott, 3 Jan 2004
--------------------------------------------------------

Here are some brief hints for anyone who, like me, wants to write some
quick c / C++ code to talk to their phone using the Gammu library.

This document is based on Gammu version 0.90.0.


1. Basic library usage:
-----------------------

#include <gammu.h>

Compile with flags from pkg-config: pkg-config --cflags gammu

Link with flags from pkg-config: pkg-config --libs gammu


Gammu stores all its data in a GSM_StateMachine struct.  Declare one
of those:

GSM_StateMachine state_machine;

You'll want to check for errors from time to time.  Do it using a
function something like this:

void check_error(GSM_Error err)
{
  if (err==GE_NONE) {
    return;
  }
  cerr << "Gammu error \""
       << print_error(err,state_machine.di.df,state_machine.msg)
       << "\"" << endl;
  exit(1);
}

Start with this initialisation:

  state_machine.opened=false;
  state_machine.msg=NULL;
  state_machine.ConfigNum=0;

Now think about the configuration file.  To use the default
~/.gammurc, do this:

  CFG_Header* cfg_header = CFG_FindGammuRC();
  assert(cfg_header);

There are functions to read arbitary files, or you could probably
populate the structure yourself.

Now put the information from the file into the state_machine structure:

  state_machine.Config[0].Localize=NULL;
  assert(CFG_ReadConfig(cfg_header,&state_machine.Config[0],0));
  state_machine.ConfigNum++;

OK, now initialise the connection:

  check_error( GSM_InitConnection(&state_machine,3) );

(Don't ask me what the "3" does!!!)

Do stuff by calling function-pointers in state_machine.Phone.Functions.
For example, this reads from a phone-book memory:

check_error ( state_machine.Phone.Functions->GetMemory(&state_machine, &entry) )

where entry is declared as a GSM_MemoryEntry.  Specify which entry to
get by setting the entry.MemoryType and entry.Location fields first.

Similarly, this writes one back:

check_error ( state_machine.Phone.Functions->SetMemory(&state_machine, &entry) )

There are numerous other functions to achieve all the same things you
can do from the gammu command-line application.

When you're finished:

check_error ( GSM_TerminateConnection(&state_machine) );


2. For C++ users:

I'm using libgammu from C++, and have the following suggestions:

- Put 'extern "C"' around the #include <gammu/gammu.h> as it doesn't
have this itself.

- #undef bool after #including it (they #define bool int).

- The gammu headers generally declare strings as "unsigned char*"
rather than "const char*".  I presume they actually are const, but
experience tells me it is best not to make assumptions and avoid
const_cast.  Copy your string literal into a writable unsigned char
array.  Ugly but safe.



3. Unicode:

Strings, e.g. in the GSM_MemoryEntry structure, are stored in Unicode.
If you've got "normal" strings you'll need to convert them.  I
strongly suggest using the GNU recode library.  It is simple to use
and well documented (info recode).  You need to use UCS-2 encoding.

Note that UCS-2 strings will have null bytes in them, so functions
that expect null-terminated strings (e.g. strlen, strcpy) won't work.
(C++ STL strings work, apart from the from-char*-constructor).  This
also means you can't use the librecode recode_string function.  I
think (?) that the output from recode_string_to_buffer needs to have
16 bits of 0 appended (else how does anyone know where the string
ends?).


4. Other hints:

I spent a long time trying to work out why I couldn't save address
book entries until I discovered that you're not allowed to have spaces
in phone numbers.  Strip them out first.

Use these two lines to get copiuos debugging output:
di.dl = DL_TEXTALL;
di.df = stdout;
(di is declared as "extern Debug_Info di;" in gammu/misc/misc.h)


5. Further documentation:

There isn't any.  Your best best is to look at the include files, and
to try to decipher the 7000+ lines of gammu.c, the command-line
program, which calls most of the functions in the library.  (You'll
need the Gammu source package for that.)

For Phone.Functions function names, look for struct
GSM_Phone_Functions in gsmstate.h.  For address book entry structures,
look in services/gsmpbk.h.

The author is unlikely to know the answer to your question, but you
may email me if the gammu mailing list doesn't know the answer (or
won't tell you).  Visit http://chezphil.org/email/genemail.cgi for an
email address.


This document is in the public domain.  Do what you like with it.

