This small program dials a voice call using libgnokii version 3. Note that at this moment it has been tested only with a Nokia 3330.

Edit 2006-07-16:
Tested with Nokia 3210, will work with driver nk6100.c version 1.187 or later (gnokii later than 0.6.13) but will not detect if call is terminated from outside the program.

Edit2 2006-07-16:
Tested with Nokia 3310, will work with driver nk6100.c version 1.189 or later (gnokii later than 0.6.13) but will not detect if call is terminated from outside the program.

Changes since version 0.1

  • exit loop if the call is terminated from outside this program
/*
  This is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this file; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

  Copyright (C) 2006 by Daniele Forsi

  compile with
  gcc -Wall -o dialvoice dialvoice.c `pkg-config --libs gnokii`

*/

#include 
#include 
#include 
#include 
#include 

#include 

/* prepare for i18n */
#define _(x) x

struct gn_statemachine *state;
int quit = 0;

static void businit(void) {
	if (GN_ERR_NONE != gn_lib_phoneprofile_load(NULL,&state))
		exit(2);
	if (GN_ERR_NONE != gn_lib_phone_open(state))
		exit(2);
}
	
static void busterminate(void) {
	gn_lib_phone_close(state);
	gn_lib_phoneprofile_free(&state);
	gn_lib_library_free();
}

void signal_handler(int signal) {
	quit = 1;
}

gn_error dialvoice(char *number, int *call_id) {
	gn_data		data;
	gn_call_info	call_info;
	
	memset(&call_info, 0, sizeof(call_info));
	snprintf(call_info.number, sizeof(call_info.number), "%s", number);
	call_info.number[sizeof(call_info.number)-1] = '\0';
	call_info.type = GN_CALL_Voice;
	call_info.send_number = GN_CALL_Default;

	gn_data_clear(&data);
	data.call_info = &call_info;

	return gn_call_dial(call_id, &data, state);
}

int main(int argc, char *argv[]) {
	gn_error	error;
	int		call_id;
	char		*number;
	
	if (argc != 2) {
		fprintf(stderr, _("dialvoice 0.2\nUsage: %s number\n"), argv[0]);
		exit(1);
	}
	
	number = argv[1];
	
	businit();
	
	signal(SIGINT, signal_handler);
	
	fprintf(stderr, _("Dialling %s\n"), number);
	
	error = dialvoice(number, &call_id);
	
	if (error != GN_ERR_NONE) {
		fprintf(stderr, _("Dialling failed: %s\n"), gn_error_print(error));
	} else {
		fprintf(stderr, _("Dialling ok. Press CTRL-C to hang up\n"));
		
		while (!quit) {
			/* need to do some housekeeping before using gn_call_get_active() */
			gn_call_check_active(state);
			if (!gn_call_get_active(call_id)) break;
			
			/* start of your code */
			fprintf(stderr, ".");
			/* end of your code */
			
			sleep(1);
		}
		fprintf(stderr, "\n");
		
		/* need to do some housekeeping before using gn_call_get_active() */
		gn_call_check_active(state);
		if (gn_call_get_active(call_id)) {		
			error = gn_call_cancel(call_id);
			if (error != GN_ERR_NONE) {
				fprintf(stderr, _("Hang up failed: %s\n"), gn_error_print(error));
			} else {
				fprintf(stderr, _("Hang up ok\n"));
			}
		} else {
			fprintf(stderr, _("Call is no more active\n"));
		}
	}
	
	busterminate();
	
	return 0;
}