--- plugins/oFono_History_DB.sql | 27 ++++ plugins/sqlite_history.c | 301 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 328 insertions(+), 0 deletions(-) create mode 100644 plugins/oFono_History_DB.sql create mode 100644 plugins/sqlite_history.c diff --git a/plugins/oFono_History_DB.sql b/plugins/oFono_History_DB.sql new file mode 100644 index 0000000..7cfc3ba --- /dev/null +++ b/plugins/oFono_History_DB.sql @@ -0,0 +1,27 @@ +CREATE TABLE IF NOT EXISTS "ofono_history_calls" ( + "ohc_modem_path" TEXT, -- Modem path string i.e. "/modem0" + "ohc_type" INTEGER, -- Call type ( 0 = Call ended, 1 = Call missed ) + "ohc_direction" INTEGER, -- Call direction ( 0 = Mobile Originated, 1 = Mobile Terminated ) + "ohc_phone_number" TEXT, -- Other party phone number + "ohc_start_time" TEXT, -- Starting date/time + "ohc_end_time" TEXT -- Ending date/time +); +CREATE TABLE IF NOT EXISTS "ofono_history_incoming_messages" ( + "ohim_modem_path" TEXT, -- Modem path string i.e. "/modem0" + "ohim_msg_id" INTEGER, -- oFono unique message id number + "ohim_sender" TEXT, -- Sender phone number + "ohim_text" TEXT, -- Message text + "ohim_local_date" TEXT, -- Local sent date/time + "ohim_remote_date" TEXT -- Remote sent date/time +); +CREATE TABLE IF NOT EXISTS "ofono_history_outgoing_messages" ( + "ohom_modem_path" TEXT, -- Modem path string i.e. "/modem0" + "ohom_msg_id" INTEGER, -- oFono unique message id number + "ohom_recipient" TEXT, -- Recipient phone number + "ohom_text" TEXT, -- Message text + "ohom_creation_date" TEXT, -- Message creation date/time + "ohom_send_status" INTEGER, -- Sending status ( 0 = Pending, 1 = Submitted, 2 = Failed ) + "ohom_status_update_date" TEXT -- Last row update date/time +); +CREATE UNIQUE INDEX IF NOT EXISTS "ohim_idx_msg_id" on ofono_history_incoming_messages (ohim_msg_id ASC); +CREATE UNIQUE INDEX IF NOT EXISTS "ohom_idx_msg_id" on ofono_history_outgoing_messages (ohom_msg_id ASC); diff --git a/plugins/sqlite_history.c b/plugins/sqlite_history.c new file mode 100644 index 0000000..35dce71 --- /dev/null +++ b/plugins/sqlite_history.c @@ -0,0 +1,301 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2010 Dario 'Djdas' Conigliaro. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#define OFONO_API_SUBJECT_TO_CHANGE +#include +#include +#include +#include +#include + +#include "common.h" + +#include + +#define SQL_HISTORY_DB_PATH STORAGEDIR "/ofono_history.sqlite" +#define SQL_HISTORY_DB_SQL STORAGEDIR "/oFono_History_DB.sql" + +#define SELECT_CALLS "SELECT * FROM ofono_history_calls" +#define INSERT_CALLS "INSERT INTO ofono_history_calls VALUES (?,?,?,?,?,?)" +#define INSERT_IN_MSGS "INSERT INTO ofono_history_incoming_messages VALUES (?,?,?,?,?,?)" +#define INSERT_OUT_MSGS "INSERT INTO ofono_history_outgoing_messages VALUES (?,?,?,?,?,?,?)" +#define UPDATE_OUT_MSGS "UPDATE ofono_history_outgoing_messages SET \ + ohom_send_status = ?, \ + ohom_status_update_date = ? \ + WHERE ohom_msg_id = ?" + +sqlite3 *db = NULL; + +static int sqlite_history_probe(struct ofono_history_context *context) +{ + char *execerror; + + ofono_debug("SQLite History Probe for modem: %p", context->modem); + + if (sqlite3_open(SQL_HISTORY_DB_PATH, &db) != SQLITE_OK) { + ofono_debug("Error opening DB: %s", sqlite3_errmsg(db)); + sqlite3_close(db); + return -1; + } + + if (sqlite3_exec(db, SELECT_CALLS, NULL, NULL, &execerror) != SQLITE_OK) { + char *sqlscript; + GError *sqlerror = NULL; + + ofono_debug("Creating DB"); + + g_file_get_contents(SQL_HISTORY_DB_SQL, &sqlscript, NULL, &sqlerror); + + if (sqlerror != NULL) { + ofono_debug("Error opening sql script: %s", sqlerror->message); + g_error_free(sqlerror); + return -1; + } + + if (sqlite3_exec(db, sqlscript, NULL, NULL, &execerror) != SQLITE_OK) { + ofono_debug("Error executing sql script: %s", execerror); + sqlite3_free(execerror); + g_free(sqlscript); + return -1; + } + + g_free(sqlscript); + } + + return 0; +} + +static void sqlite_history_remove(struct ofono_history_context *context) +{ + ofono_debug("SQLite History Remove for modem: %p", context->modem); + + if (db != NULL) + sqlite3_close(db); +} + +static void sqlite_history_call_ended(struct ofono_history_context *context, + const struct ofono_call *call, + time_t start, time_t end) +{ + const char *from = "Unknown"; + char buf[128]; + char buf1[128]; + sqlite3_stmt *statement; + + ofono_debug("Call Ended on modem: %p", context->modem); + + if (call->type != 0) + return; + + if (db == NULL) + return; + + from = phone_number_to_string(&call->phone_number); + + strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z", localtime(&start)); + buf[127] = '\0'; + + sqlite3_prepare_v2(db, INSERT_CALLS, -1, &statement, NULL); + sqlite3_bind_text(statement, 1, ofono_modem_get_path(context->modem), + -1, SQLITE_STATIC); + sqlite3_bind_int(statement, 2, 0); + sqlite3_bind_int(statement, 3, call->direction); + sqlite3_bind_text(statement, 4, from, -1, SQLITE_STATIC); + sqlite3_bind_text(statement, 5, buf, -1, SQLITE_STATIC); + + strftime(buf1, 127, "%Y-%m-%dT%H:%M:%S%z", localtime(&end)); + buf1[127] = '\0'; + + sqlite3_bind_text(statement, 6, buf1, -1, SQLITE_STATIC); + + if (sqlite3_step(statement) != SQLITE_DONE) + ofono_debug("SQLite Error: %s", sqlite3_errmsg(db)); + + sqlite3_finalize(statement); +} + +static void sqlite_history_call_missed(struct ofono_history_context *context, + const struct ofono_call *call, + time_t when) +{ + const char *from = "Unknown"; + char buf[128]; + sqlite3_stmt *statement; + + ofono_debug("Call Missed on modem: %p", context->modem); + + if (call->type != 0) + return; + + if (db == NULL) + return; + + from = phone_number_to_string(&call->phone_number); + + strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z", localtime(&when)); + buf[127] = '\0'; + + sqlite3_prepare_v2(db, INSERT_CALLS, -1, &statement, NULL); + sqlite3_bind_text(statement, 1, ofono_modem_get_path(context->modem), + -1, SQLITE_STATIC); + sqlite3_bind_int(statement, 2, 1); + sqlite3_bind_int(statement, 3, call->direction); + sqlite3_bind_text(statement, 4, from, -1, SQLITE_STATIC); + sqlite3_bind_text(statement, 5, buf, -1, SQLITE_STATIC); + sqlite3_bind_text(statement, 6, buf, -1, SQLITE_STATIC); + + if (sqlite3_step(statement) != SQLITE_DONE) + ofono_debug("SQLite Error: %s", sqlite3_errmsg(db)); + + sqlite3_finalize(statement); +} + +static void sqlite_history_sms_received(struct ofono_history_context *context, + unsigned int msg_id, const char *from, + const struct tm *remote, const struct tm *local, + const char *text) +{ + char buf[128]; + char buf1[128]; + sqlite3_stmt *statement; + + ofono_debug("Incoming SMS on modem: %p", context->modem); + + if (db == NULL) + return; + + strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z", local); + buf[127] = '\0'; + + strftime(buf1, 127, "%Y-%m-%dT%H:%M:%S%z", remote); + buf1[127] = '\0'; + + sqlite3_prepare_v2(db, INSERT_IN_MSGS, -1, &statement, NULL); + sqlite3_bind_text(statement, 1, ofono_modem_get_path(context->modem), + -1, SQLITE_STATIC); + sqlite3_bind_int(statement, 2, msg_id); + sqlite3_bind_text(statement, 3, from, -1, SQLITE_STATIC); + sqlite3_bind_text(statement, 4, text, -1, SQLITE_STATIC); + sqlite3_bind_text(statement, 5, buf, -1, SQLITE_STATIC); + sqlite3_bind_text(statement, 6, buf1, -1, SQLITE_STATIC); + + if (sqlite3_step(statement) != SQLITE_DONE) + ofono_debug("SQLite Error: %s", sqlite3_errmsg(db)); + + sqlite3_finalize(statement); +} + +static void sqlite_history_sms_send_pending(struct ofono_history_context *context, + unsigned int msg_id, + const char *to, time_t when, + const char *text) +{ + char buf[128]; + char buf1[128]; + sqlite3_stmt *statement; + time_t currtime; + + ofono_debug("Sending SMS on modem: %p", context->modem); + + if (db == NULL) + return; + + strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z", localtime(&when)); + buf[127] = '\0'; + + currtime = time(NULL); + strftime(buf1, 127, "%Y-%m-%dT%H:%M:%S%z", localtime(&currtime)); + buf1[127] = '\0'; + + sqlite3_prepare_v2(db, INSERT_OUT_MSGS, -1, &statement, NULL); + sqlite3_bind_text(statement, 1, ofono_modem_get_path(context->modem), + -1, SQLITE_STATIC); + sqlite3_bind_int(statement, 2, msg_id); + sqlite3_bind_text(statement, 3, to, -1, SQLITE_STATIC); + sqlite3_bind_text(statement, 4, text, -1, SQLITE_STATIC); + sqlite3_bind_text(statement, 5, buf, -1, SQLITE_STATIC); + sqlite3_bind_int(statement, 6, OFONO_HISTORY_SMS_STATUS_PENDING); + sqlite3_bind_text(statement, 7, buf1, -1, SQLITE_STATIC); + + if (sqlite3_step(statement) != SQLITE_DONE) + ofono_debug("SQLite Error: %s", sqlite3_errmsg(db)); + + sqlite3_finalize(statement); +} + +static void sqlite_history_sms_send_status(struct ofono_history_context *context, + unsigned int msg_id, time_t when, + enum ofono_history_sms_status s) +{ + char buf[128]; + sqlite3_stmt *statement; + + ofono_debug("SMS status on modem: %p", context->modem); + + if (db == NULL) + return; + + strftime(buf, 127, "%Y-%m-%dT%H:%M:%S%z", localtime(&when)); + buf[127] = '\0'; + + sqlite3_prepare_v2(db, UPDATE_OUT_MSGS, -1, &statement, NULL); + sqlite3_bind_int(statement, 1, s); + sqlite3_bind_text(statement, 2, buf, -1, SQLITE_STATIC); + sqlite3_bind_int(statement, 3, msg_id); + + if (sqlite3_step(statement) != SQLITE_DONE) + ofono_debug("SQLite Error: %s", sqlite3_errmsg(db)); + + sqlite3_finalize(statement); +} + +static struct ofono_history_driver sqlite_driver = { + .name = "SQLite History", + .probe = sqlite_history_probe, + .remove = sqlite_history_remove, + .call_ended = sqlite_history_call_ended, + .call_missed = sqlite_history_call_missed, + .sms_received = sqlite_history_sms_received, + .sms_send_pending = sqlite_history_sms_send_pending, + .sms_send_status = sqlite_history_sms_send_status, +}; + +static int sqlite_history_init(void) +{ + return ofono_history_driver_register(&sqlite_driver); +} + +static void sqlite_history_exit(void) +{ + ofono_history_driver_unregister(&sqlite_driver); +} + +OFONO_PLUGIN_DEFINE(sqlite_history, "SQLite History Plugin", + VERSION, OFONO_PLUGIN_PRIORITY_DEFAULT, + sqlite_history_init, sqlite_history_exit) -- 1.6.3.3