/* * This is a dirty hack implementing SIP MESSAGE queuing for later delivery when user becomes * online. * * (c) 2005 Juraj Bednar * * Uses SQLite */ static int queue_message(char *from, char *peername, char *content_type, char *text) { sqlite3 *db; sqlite3_stmt *statement; int rc; rc = sqlite3_open(DB_PATH, &db); if( rc ){ ast_log(LOG_ERROR, "queue_message: Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); return RESULT_FAILURE; } if ( sqlite3_prepare(db, "INSERT INTO queue (sender, recipient, content_type, body) values (?, ?, ?, ?);", -1, &statement, NULL) != SQLITE_OK) { ast_log(LOG_ERROR, "queue_message: SQL error: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); return RESULT_FAILURE; } sqlite3_bind_text(statement, 1, from, -1, SQLITE_TRANSIENT); sqlite3_bind_text(statement, 2, peername, -1, SQLITE_TRANSIENT); sqlite3_bind_text(statement, 3, content_type, -1, SQLITE_TRANSIENT); sqlite3_bind_blob(statement, 4, (void *) text, strlen(text)+1, SQLITE_TRANSIENT); sqlite3_busy_timeout(db, 500); rc = sqlite3_step(statement); if ( rc == SQLITE_DONE ) rc = RESULT_SUCCESS; else { ast_log(LOG_ERROR, "queue_message: SQL execution error: %s\n", sqlite3_errmsg(db)); rc = RESULT_FAILURE; } sqlite3_finalize(statement); sqlite3_close(db); return rc; } static int queue_try_deliver(char *peername) { sqlite3 *db; sqlite3_stmt *statement, *del_statement; int rc; char *sql_query; if (peername==NULL) peername=""; rc = sqlite3_open(DB_PATH, &db); if( rc ){ ast_log(LOG_ERROR, "queue_deliver: Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); return RESULT_FAILURE; } if (ast_strlen_zero(peername)) sql_query="SELECT id, sender, recipient, content_type, body from queue;"; else sql_query="SELECT id, sender, recipient, content_type, body from queue where recipient=?;"; if ( sqlite3_prepare(db, sql_query, -1, &statement, NULL) != SQLITE_OK ) { ast_log(LOG_ERROR, "queue_deliver: SQL error: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); return RESULT_FAILURE; } if ( sqlite3_prepare(db, "DELETE FROM queue WHERE id=?;", -1, &del_statement, NULL) != SQLITE_OK ) { ast_log(LOG_ERROR, "queue_deliver: SQL error: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); return RESULT_FAILURE; } if (!ast_strlen_zero(peername)) sqlite3_bind_text(statement, 1, peername, -1, SQLITE_TRANSIENT); sqlite3_busy_timeout(db, 500); while ( (rc = sqlite3_step(statement)) == SQLITE_ROW ) { if ( send_message_by_name( sqlite3_column_text(statement, 1), sqlite3_column_text(statement, 2), sqlite3_column_text(statement, 3), sqlite3_column_blob(statement, 4) ) == RESULT_SUCCESS ) { /* message was sent correctly, delete it from queue */ sqlite3_bind_int(del_statement, 1, sqlite3_column_int(statement, 0) ); sqlite3_reset(statement); /* release the lock on the queue table */ if (sqlite3_step(del_statement) != SQLITE_DONE) { /* This is fatal error, we quit in order to stop sending messages * twice. There may be one message sent once */ ast_log(LOG_ERROR, "queue_deliver: delete SQL execution error: %s\n", sqlite3_errmsg(db)); sqlite3_finalize(del_statement); sqlite3_finalize(statement); sqlite3_close(db); return RESULT_FAILURE; } sqlite3_reset(del_statement); } } if ( rc == SQLITE_DONE ) rc = RESULT_SUCCESS; else { ast_log(LOG_ERROR, "queue_deliver: SQL execution error: %s\n", sqlite3_errmsg(db)); rc = RESULT_FAILURE; } sqlite3_finalize(del_statement); sqlite3_finalize(statement); sqlite3_close(db); return rc; }