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.