Hi Daniel,
Thanks for all the informations. Based on those informations, Loide Mara (lmvj@dcc.ufam.edu.br) and I have made changes on msilo module code to make it able to send messages at a time stored in the silo table.
Applying the patch patch-msilo-060117.diff the msilo module becomes able to send messages at the time stored on the table. Following the installation instructions for msilo module in http://openser.org/docs/modules/1.0.x/msilo.html#AEN199, it is just necessary to add a field in the silo table: sen_time (integer). This field will store the sending time of the stored messages. For offline messages, sending time equals incoming time.
It can be useful if users are interested in store messages to be sent to one or more different users at a given time. Reminders for meetings or special dates could be sent through it.
Here is a patch if someone is interested in testing it. Any comments will be appreciated.
Regards, Andrea Giordanna
--------------------------------- Yahoo! doce lar. Faça do Yahoo! sua homepage.
diff -urN msilo_orig/msilo.c msilo/msilo.c --- msilo_orig/msilo.c 2006-01-17 19:55:34.000000000 -0400 +++ msilo/msilo.c 2006-01-17 19:57:25.000000000 -0400 @@ -71,7 +71,7 @@ #include "msfuncs.h"
#define MAX_DEL_KEYS 1 -#define NR_KEYS 9 +#define NR_KEYS 10 /* LabVoIP: old value 9 */
char *sc_mid = "mid"; /* 0 */ char *sc_from = "src_addr"; /* 1 */ @@ -82,6 +82,7 @@ char *sc_ctype = "ctype"; /* 6 */ char *sc_exp_time = "exp_time"; /* 7 */ char *sc_inc_time = "inc_time"; /* 8 */ +char *sc_sen_time = "sen_time"; /* LabVoIP: 9 */
#define SET_STR_VAL(_str, _res, _r, _c) \ if (RES_ROWS(_res)[_r].values[_c].nul == 0) \ @@ -144,6 +145,7 @@ void destroy(void);
void m_clean_silo(unsigned int ticks, void *); +void m_send_ready(); /* LabVoIP */
/** TM callback function */ static void m_tm_callback( struct cell *t, int type, struct tmcb_params *ps); @@ -245,6 +247,8 @@ } register_timer( m_clean_silo, 0, ms_check_time);
+ register_timer( m_send_ready, 0, ms_check_time); /* LabVoIP */ + reg_addr.s = ms_registrar; reg_addr.len = (ms_registrar)?strlen(ms_registrar):0;
@@ -553,6 +557,13 @@ db_vals[nr_keys].val.int_val = val; nr_keys++;
+ /* LabVoIP: add sending time: equals incoming time */ + db_keys[nr_keys] = sc_inc_time; + db_vals[nr_keys].type = DB_INT; + db_vals[nr_keys].nul = 0; + db_vals[nr_keys].val.int_val = val; + nr_keys++; + if (msilo_dbf.use_table(db_con, ms_db_table) < 0) { LOG(L_ERR, "MSILO:m_store: Error in use_table\n"); @@ -639,9 +650,9 @@ struct to_body to, *pto = NULL; db_key_t db_keys[2]; db_val_t db_vals[2]; - db_key_t db_cols[6]; + db_key_t db_cols[7]; db_res_t* db_res = NULL; - int i, db_no_cols = 6, db_no_keys = 2, mid, n; + int i, db_no_cols = 7, db_no_keys = 2, mid, n; char hdr_buf[1024], body_buf[1024]; struct sip_uri puri;
@@ -658,6 +669,7 @@ db_cols[3]=sc_body; db_cols[4]=sc_ctype; db_cols[5]=sc_inc_time; + db_cols[6]=sc_sen_time;
DBG("MSILO:m_dump: ------------ start ------------\n"); @@ -759,48 +771,62 @@ DBG("MSILO:m_dump: dumping [%d] messages for <%.*s>!!!\n", RES_ROW_N(db_res), pto->uri.len, pto->uri.s);
+ int cur_time = (int) time(NULL); + for(i = 0; i < RES_ROW_N(db_res); i++) { mid = RES_ROWS(db_res)[i].values[0].val.int_val; - if(msg_list_check_msg(ml, mid)) - { - DBG("MSILO:m_dump: message[%d] mid=%d already sent.\n", - i, mid); - continue; - } + + if (RES_ROWS(db_res)[i].values[6].val.int_val > cur_time) { + DBG("MSILO:m_send_ready: message[%d] mid=%d not sent. Not ready!!!\nCurrent time: %d - Sending time: %d\n", i, mid, cur_time, RES_ROWS(db_res)[i].values[6].val.int_val); + } else { + + DBG("MSILO:m_send_ready: message[%d] mid=%d sent. Ready!!!\nCurrent time: %d - Sending time: %d\n", i, mid, cur_time, RES_ROWS(db_res)[i].values[6].val.int_val); + + if(msg_list_check_msg(ml, mid)) + { + DBG("MSILO:m_dump: message[%d] mid=%d already sent.\n", i, mid); + + if (msg_list_get_flag(ml, mid) & MS_MSG_ERRO) { + DBG("MSILO:m_dump: message[%d] mid=%d is a message to an offline user, or was not sent successfully. We're gonna send it again.\n", i, mid); + } else { + DBG("MSILO:m_dump: message[%d] mid=%d was sent successfully. Next...\n", i, mid); + continue; + } + } - memset(str_vals, 0, 4*sizeof(str)); - SET_STR_VAL(str_vals[0], db_res, i, 1); /* from */ - SET_STR_VAL(str_vals[1], db_res, i, 2); /* to */ - SET_STR_VAL(str_vals[2], db_res, i, 3); /* body */ - SET_STR_VAL(str_vals[3], db_res, i, 4); /* ctype */ + memset(str_vals, 0, 4*sizeof(str)); + SET_STR_VAL(str_vals[0], db_res, i, 1); /* from */ + SET_STR_VAL(str_vals[1], db_res, i, 2); /* to */ + SET_STR_VAL(str_vals[2], db_res, i, 3); /* body */ + SET_STR_VAL(str_vals[3], db_res, i, 4); /* ctype */
- hdr_str.len = 1024; - if(m_build_headers(&hdr_str, str_vals[3] /*ctype*/, + hdr_str.len = 1024; + if(m_build_headers(&hdr_str, str_vals[3] /*ctype*/, str_vals[0]/*from*/) < 0) - { - DBG("MSILO:m_dump: headers building failed!!!\n"); - if (msilo_dbf.free_result(db_con, db_res) < 0) - DBG("MSILO:m_dump: Error while freeing result of" + { + DBG("MSILO:m_dump: headers building failed!!!\n"); + if (msilo_dbf.free_result(db_con, db_res) < 0) + DBG("MSILO:m_dump: Error while freeing result of" " query\n"); - msg_list_set_flag(ml, mid, MS_MSG_ERRO); - goto error; - } + msg_list_set_flag(ml, mid, MS_MSG_ERRO); + goto error; + } - DBG("MSILO:m_dump: msg [%d-%d] for: %.*s\n", i+1, mid, + DBG("MSILO:m_dump: msg [%d-%d] for: %.*s\n", i+1, mid, pto->uri.len, pto->uri.s); - /** sending using TM function: t_uac */ - body_str.len = 1024; - rtime = - (time_t)RES_ROWS(db_res)[i].values[5/*inc time*/].val.int_val; - n = m_build_body(&body_str, rtime, str_vals[2/*body*/]); - if(n<0) - DBG("MSILO:m_dump: sending simple body\n"); - else - DBG("MSILO:m_dump: sending composed body\n"); + /** sending using TM function: t_uac */ + body_str.len = 1024; + rtime = + (time_t)RES_ROWS(db_res)[i].values[5/*inc time*/].val.int_val; + n = m_build_body(&body_str, rtime, str_vals[2/*body*/]); + if(n<0) + DBG("MSILO:m_dump: sending simple body\n"); + else + DBG("MSILO:m_dump: sending composed body\n"); - tmb.t_request(&msg_type, /* Type of the message */ + tmb.t_request(&msg_type, /* Type of the message */ &pto->uri, /* Request-URI */ &str_vals[1], /* To */ &str_vals[0], /* From */ @@ -809,6 +835,7 @@ m_tm_callback, /* Callback function */ (void*)(long)mid /* Callback parameter */ ); + } }
done: @@ -900,7 +927,7 @@ */ void m_tm_callback( struct cell *t, int type, struct tmcb_params *ps) { - DBG("MSILO:m_tm_callback: completed with status %d\n", ps->code); + DBG("MSILO:m_tm_callback: message %ld completed with status %d\n", (long)*ps->param, ps->code); if(!ps->param) { DBG("MSILO m_tm_callback: message id not received\n"); @@ -914,14 +941,155 @@ if(ps->code < 200 || ps->code >= 300) { DBG("MSILO:m_tm_callback: message <%ld> was not sent successfully\n", - (long)ps->param); - msg_list_set_flag(ml, (int)(long)ps->param, MS_MSG_ERRO); + (long)*ps->param); + msg_list_set_flag(ml, (int)(long)*ps->param, MS_MSG_ERRO); goto done; }
- msg_list_set_flag(ml, (int)(long)ps->param, MS_MSG_DONE); + msg_list_set_flag(ml, (int)(long)*ps->param, MS_MSG_DONE); done: return; }
+/* LabVoIP: m_send_ready + * It checks on database if there are any messages in time to be sent + * - giordanna + */ + +void m_send_ready () { + + struct to_body to, *pto = NULL; + db_key_t db_keys[2]; + db_key_t db_cols[7]; + db_res_t* db_res = NULL; + int i, db_no_cols = 7, mid, n; + char hdr_buf[1024], body_buf[1024]; + + str str_vals[4], hdr_str , body_str; + time_t rtime; + + /* init */ + db_keys[0]=sc_uri_user; + db_keys[1]=sc_uri_host; + db_cols[0]=sc_mid; + + db_cols[1]=sc_from; + db_cols[2]=sc_to; + db_cols[3]=sc_body; + db_cols[4]=sc_ctype; + db_cols[5]=sc_inc_time; + db_cols[6]=sc_sen_time; + + + DBG("MSILO:m_send_ready: ------------ Checking for messages to send! ------------\n"); + hdr_str.s=hdr_buf; + hdr_str.len=1024; + body_str.s=body_buf; + body_str.len=1024; + + + if (msilo_dbf.use_table(db_con, ms_db_table) < 0) + { + LOG(L_ERR, "MSILO:m_send_ready: Error in use_table\n"); + goto error; + } + + if((msilo_dbf.query(db_con,db_keys,NULL,NULL,db_cols,0, + db_no_cols, NULL,&db_res)!=0) || (RES_ROW_N(db_res) <= 0)) + { + DBG("MSILO:m_send_ready: no messages in database!\n"); + goto done; + } + + DBG("MSILO:m_send_ready: dumping [%d] messages!!!\n", RES_ROW_N(db_res)); + + + memset( &to , 0, sizeof(to) ); + + int cur_time = (int) time(NULL); + + /* Loop to send all the messages */ + for(i = 0; i < RES_ROW_N(db_res); i++) + { + // Getting message id + mid = RES_ROWS(db_res)[i].values[0].val.int_val; + + // If it is time to send... + if (RES_ROWS(db_res)[i].values[6].val.int_val > cur_time) { + DBG("MSILO:m_send_ready: message[%d] mid=%d not sent. Not ready!!!\nCurrent time: %d - Sending time: %d\n", i, mid, cur_time, RES_ROWS(db_res)[i].values[6].val.int_val); + } else { + + DBG("MSILO:m_send_ready: message[%d] mid=%d sent. Ready!!!\nCurrent time: %d - Sending time: %d\n", i, mid, cur_time, RES_ROWS(db_res)[i].values[6].val.int_val); + + // To field + to.uri.s = (char *) RES_ROWS(db_res)[i].values[2].val.string_val; + to.uri.len = strlen(RES_ROWS(db_res)[i].values[2].val.string_val); + if (to.uri.len <= 0) /* || to.error != PARSE_OK) */ + { + DBG("MSILO:m_send_ready: 'To' erro na atribui�o!\n"); + goto error; + } + pto = &to; + + if(msg_list_check_msg(ml, mid)) + { + DBG("MSILO:m_send_ready: message[%d] mid=%d already sent.\n", i, mid); + continue; + } + + memset(str_vals, 0, 4*sizeof(str)); + SET_STR_VAL(str_vals[0], db_res, i, 1); /* from */ + SET_STR_VAL(str_vals[1], db_res, i, 2); /* to */ + SET_STR_VAL(str_vals[2], db_res, i, 3); /* body */ + SET_STR_VAL(str_vals[3], db_res, i, 4); /* ctype */ + + hdr_str.len = 1024; + if(m_build_headers(&hdr_str, str_vals[3] /*ctype*/, + str_vals[0]/*from*/) < 0) + { + DBG("MSILO:m_send_ready: headers building failed!!!\n"); + if (msilo_dbf.free_result(db_con, db_res) < 0) + DBG("MSILO:m_send_ready: Error while freeing result of" + " query\n"); + msg_list_set_flag(ml, mid, MS_MSG_ERRO); + goto error; + } + + DBG("MSILO:m_send_ready: msg [%d-%d] for: %.*s\n", + i+1, mid, pto->uri.len, pto->uri.s); + + /** sending using TM function: t_uac */ + body_str.len = 1024; + rtime = + (time_t)RES_ROWS(db_res)[i].values[5/*inc time*/].val.int_val; + n = m_build_body(&body_str, rtime, str_vals[2/*body*/]); + if(n<0) + DBG("MSILO:m_send_ready: sending simple body\n"); + else + DBG("MSILO:m_send_ready: sending composed body\n"); + + tmb.t_request(&msg_type, /* Type of the message */ + &pto->uri, /* Request-URI */ + &str_vals[1], /* To */ + &str_vals[0], /* From */ + &hdr_str, /* Optional headers including CRLF */ + (n<0)?&str_vals[2]:&body_str, /* Message body */ + m_tm_callback, /* Callback function */ + (void*)(long) mid /* Callback parameter */ + ); + } + } + +done: + /** + * Free the result because we don't need it + * anymore + */ + if (db_res!=NULL && msilo_dbf.free_result(db_con, db_res) < 0) + DBG("MSILO:m_send_ready: Error while freeing result of query\n"); + + return; +error: + return; +} diff -urN msilo_orig/ms_msg_list.c msilo/ms_msg_list.c --- msilo_orig/ms_msg_list.c 2006-01-17 19:55:34.000000000 -0400 +++ msilo/ms_msg_list.c 2006-01-17 19:57:30.000000000 -0400 @@ -244,6 +244,37 @@ }
/** + * LabVoIP: + * get flag for message with mid + */ +int msg_list_get_flag(msg_list ml, int mid) +{ + msg_list_el p0; + + if(!ml || mid==0) + goto errorx; + + lock_get(&ml->sem_sent); + + p0 = ml->lsent; + while(p0) + { + if(p0->msgid==mid) + { + DBG("MSILO: msg_list_get_flag: mid:%d fl:%d\n", p0->msgid, p0->flag); + goto done; + } + p0 = p0->next; + } + +done: + lock_release(&ml->sem_sent); + return p0->flag; +errorx: + return -1; +} + +/** * check if the messages from list were sent */ int msg_list_check(msg_list ml) @@ -262,9 +293,9 @@ p0 = ml->lsent; while(p0) { - if(p0->flag & MS_MSG_DONE || p0->flag & MS_MSG_ERRO) + if(p0->flag & MS_MSG_DONE) /*|| p0->flag & MS_MSG_ERRO)*/ /* Messages with error will be maintained in sent_list*/ { - DBG("MSILO: msg_list_check: mid:%d got reply\n", p0->msgid); + DBG("MSILO: msg_list_check: mid:%d got positive reply\n", p0->msgid); if(p0->prev) (p0->prev)->next = p0->next; else diff -urN msilo_orig/ms_msg_list.h msilo/ms_msg_list.h --- msilo_orig/ms_msg_list.h 2006-01-17 19:55:34.000000000 -0400 +++ msilo/ms_msg_list.h 2006-01-17 19:57:33.000000000 -0400 @@ -70,6 +70,7 @@ void msg_list_free(msg_list); int msg_list_check_msg(msg_list, int); int msg_list_set_flag(msg_list, int, int); +int msg_list_get_flag(msg_list ml, int mid); /* LabVoIP */ int msg_list_check(msg_list); msg_list_el msg_list_reset(msg_list);
Hello Andrea,
the feature sounds nice, please register the patch into the tracker, in the patches section, so it is not lost in the mailbox. I will take a look at it and apply it in the next future.
Tracker link: http://sourceforge.net/tracker/?group_id=139143
As a feature I see good to add as well, is to be able to take the sending time (in format YYYYMMDDHHMMSS or similar) from an avp. If the avp is not present then the sending time is equal with receive time. With such functionality I can send a message as reminder to some prefix plus the date to store from my SIP client. Example of functionality with prefix *88:
Message to: sip:*8820060125140000@mydomain.sip will send me the message back on the 25th January at 2:00PM
Cheers, Daniel
On 01/18/06 08:39, Andréa Giordanna wrote:
Hi Daniel,
Thanks for all the informations. Based on those informations, Loide Mara (lmvj@dcc.ufam.edu.br mailto:lmvj@dcc.ufam.edu.br) and I have made changes on msilo module code to make it able to send messages at a time stored in the silo table.
Applying the patch patch-msilo-060117.diff the msilo module becomes able to send messages at the time stored on the table. Following the installation instructions for msilo module in http://openser.org/docs/modules/1.0.x/msilo.html#AEN199, it is just necessary to add a field in the silo table: sen_time (integer). This field will store the sending time of the stored messages. For offline messages, sending time equals incoming time.
It can be useful if users are interested in store messages to be sent to one or more different users at a given time. Reminders for meetings or special dates could be sent through it. Here is a patch if someone is interested in testing it. Any comments will be appreciated.
Regards, Andrea Giordanna
Yahoo! doce lar. Faça do Yahoo! sua homepage. http://us.rd.yahoo.com/mail/br/tagline/homepage_set/*http://br.yahoo.com/homepageset.html