/* $Id: gsm.c,v 1.173.2.15 2011/01/23 16:18:28 khorben Exp $ */
/* Copyright (c) 2011 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Phone */
/* This program 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, version 3 of the License.
 *
 * 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 program.  If not, see <http://www.gnu.org/licenses/>. */



#include <stdlib.h>
#ifdef DEBUG
# include <stdio.h>
#endif
#include <string.h>
#include <System.h>
#include "gsm.h"


/* GSM */
/* private */
/* types */
typedef int (*GSMTriggerCallback)(GSM * gsm, char const * result,
		gboolean * answered);

typedef struct _GSMTrigger
{
	char const * trigger;
	size_t trigger_cnt;
	GSMTriggerCallback callback;
} GSMTrigger;

struct _GSM
{
	Modem * modem;
};


/* functions */
/* gsm_new */
GSM * gsm_new(Config * config, char const * plugin, unsigned int retry)
{
	GSM * gsm;

	if((gsm = object_new(sizeof(*gsm))) == NULL)
		return NULL;
	gsm->modem = modem_new(config, plugin, retry);
	if(gsm->modem == NULL)
	{
		gsm_delete(gsm);
		return NULL;
	}
	return gsm;
}


/* gsm_delete */
void gsm_delete(GSM * gsm)
{
	if(gsm->modem != NULL)
		modem_delete(gsm->modem);
	object_delete(gsm);
}


/* accessors */
/* gsm_get_config */
ModemConfig * gsm_get_config(GSM * gsm)
{
	return modem_get_config(gsm->modem);
}


/* gsm_set_callback */
void gsm_set_callback(GSM * gsm, ModemEventCallback callback, void * priv)
{
	modem_set_callback(gsm->modem, callback, priv);
}


/* gsm_set_call_presentation */
int gsm_set_call_presentation(GSM * gsm, int set)
{
	return modem_request_type(gsm->modem, MODEM_REQUEST_CALL_PRESENTATION,
			(set != 0) ? 1 : 0);
}


/* gsm_set_call_waiting_control */
int gsm_set_call_waiting_control(GSM * gsm, int unsollicited)
{
	return modem_request_type(gsm->modem,
			MODEM_REQUEST_CALL_WAITING_CONTROL,
			(unsollicited != 0) ? TRUE : FALSE);
}


/* useful */
/* gsm_call */
int gsm_call(GSM * gsm, ModemCallType calltype, char const * number)
{
	return modem_request_type(gsm->modem, MODEM_REQUEST_CALL, calltype,
			number);
}


/* gsm_call_answer */
int gsm_call_answer(GSM * gsm)
{
	return modem_request_type(gsm->modem, MODEM_REQUEST_CALL_ANSWER);
}


/* gsm_call_contact */
int gsm_call_contact(GSM * gsm, ModemCallType calltype, unsigned int id)
{
	return modem_request_type(gsm->modem, MODEM_REQUEST_CALL_CONTACT,
			calltype, id);
}


/* gsm_call_hangup */
int gsm_call_hangup(GSM * gsm)
{
	return modem_request_type(gsm->modem, MODEM_REQUEST_CALL_HANGUP);
}


/* gsm_contact_delete */
int gsm_contact_delete(GSM * gsm, unsigned int id)
{
	return modem_request_type(gsm->modem, MODEM_REQUEST_CONTACT_DELETE, id);
}


/* gsm_contact_edit */
int gsm_contact_edit(GSM * gsm, unsigned int id, char const * name,
		char const * number)
{
	return modem_request_type(gsm->modem, MODEM_REQUEST_CONTACT_EDIT,
			id, name, number);
}


/* gsm_contact_new */
int gsm_contact_new(GSM * gsm, char const * name, char const * number)
{
	return modem_request_type(gsm->modem, MODEM_REQUEST_CONTACT_NEW,
			name, number);
}


/* gsm_enter_sim_pin */
int gsm_enter_sim_pin(GSM * gsm, char const * code)
{
	if(code == NULL)
		return modem_trigger(gsm->modem,
				MODEM_EVENT_TYPE_AUTHENTICATION);
	return modem_request_type(gsm->modem, MODEM_REQUEST_AUTHENTICATE,
			"SIM PIN", NULL, code);
}


/* gsm_fetch_battery_charge */
int gsm_fetch_battery_charge(GSM * gsm)
{
	return modem_trigger(gsm->modem, MODEM_EVENT_TYPE_BATTERY_LEVEL);
}


/* gsm_fetch_contact_list */
int gsm_fetch_contact_list(GSM * gsm)
{
	return modem_request_type(gsm->modem, MODEM_REQUEST_CONTACT_LIST);
}


/* gsm_fetch_contacts */
int gsm_fetch_contacts(GSM * gsm, unsigned int start, unsigned int end)
{
	int ret = 0;
	unsigned int i;

	for(i = start; i <= end; i++)
		ret |= modem_request_type(gsm->modem, MODEM_REQUEST_CONTACT, i);
	return ret;
}


/* gsm_fetch_message_list */
int gsm_fetch_message_list(GSM * gsm, GSMMessageList list)
{
	return modem_request_type(gsm->modem, MODEM_REQUEST_MESSAGE_LIST, list);
}


/* gsm_fetch_message */
int gsm_fetch_message(GSM * gsm, unsigned int id)
{
	return modem_request_type(gsm->modem, MODEM_REQUEST_MESSAGE, id);
}


/* gsm_fetch_registration */
int gsm_fetch_registration(GSM * gsm)
{
	return modem_trigger(gsm->modem, MODEM_EVENT_TYPE_REGISTRATION);
}


/* queries */
/* gsm_is_pin_valid */
int gsm_is_pin_valid(GSM * gsm)
{
	return modem_trigger(gsm->modem, MODEM_EVENT_TYPE_AUTHENTICATION);
}


/* gsm_is_registered */
int gsm_is_registered(GSM * gsm)
{
	return modem_trigger(gsm->modem, MODEM_EVENT_TYPE_REGISTRATION);
}


/* messaging */
/* gsm_message_delete */
int gsm_message_delete(GSM * gsm, unsigned int id)
{
	return modem_request_type(gsm->modem, MODEM_REQUEST_MESSAGE_DELETE, id);
}


/* gsm_message_send */
int gsm_message_send(GSM * gsm, char const * number, GSMEncoding encoding,
		char const * text, size_t length)
{
	return 1; /* should not be reached */
}


/* queue management */
/* gsm_queue */
GSMCommand * gsm_queue(GSM * gsm, char const * command)
{
	return NULL;
}


/* gsm_start */
int gsm_start(GSM * gsm, unsigned int delay)
{
	return modem_start(gsm->modem);
}


/* gsm_stop */
int gsm_stop(GSM * gsm)
{
	return modem_stop(gsm->modem);
}


/* gsm_request */
int gsm_request(GSM * gsm, ModemRequest * request)
{
	return modem_request(gsm->modem, request);
}


/* gsm_trigger */
int gsm_trigger(GSM * gsm, ModemEventType event)
{
	return modem_trigger(gsm->modem, event);
}