sms_report.c

Go to the documentation of this file.
00001 /*
00002  * $Id: sms_report.c 4518 2008-07-28 15:39:28Z henningw $
00003  *
00004  * Copyright (C) 2001-2003 FhG Fokus
00005  *
00006  * This file is part of Kamailio, a free SIP server.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  */
00022 
00023 #include <time.h>
00024 #include <unistd.h>
00025 #include "../../mem/shm_mem.h"
00026 #include "../../timer.h"
00027 #include "sms_report.h"
00028 #include "sms_funcs.h"
00029 
00030 #define REPORT_TIMEOUT     1*60*60   // one hour
00031 #define START_ERR_MSG      "Your message (or part of it) couldn't be "\
00032                            "delivered. The SMS Center said: "
00033 #define START_ERR_MSG_LEN  (strlen(START_ERR_MSG))
00034 #define END_ERR_MSG        ". The message was: "
00035 #define END_ERR_MSG_LEN    (strlen( END_ERR_MSG))
00036 
00037 struct report_cell {
00038    int             status;
00039    time_t          timeout;
00040    char            *text;
00041    unsigned int    text_len;
00042    struct sms_msg  *sms;
00043 };
00044 
00045 struct report_cell *report_queue=0;
00046 typedef time_t (get_time_func)(void);
00047 get_time_func  *get_time;
00048 
00049 
00050 
00051 
00052 /*-------------- Function to set time - from ser or system ------------------*/
00053 
00054 /* gets the time from ser */
00055 static time_t get_time_ser(void)
00056 {
00057    return  get_ticks();
00058 }
00059 /* gets the time from system */
00060 static time_t get_time_sys(void)
00061 {
00062    return time(0);
00063 }
00064 /* detects if the ser time function get_ticks works, and depending of that
00065    sets the correct time function to be used */
00066 void set_gettime_function(void)
00067 {
00068    unsigned int t1,t2;
00069 
00070    t1 = get_ticks();
00071    sleep(2);
00072    t2 = get_ticks();
00073    if (!t1 && !t2) {
00074       get_time = get_time_sys;
00075       LM_INFO("using system time func.\n");
00076    } else {
00077       get_time = get_time_ser;
00078       LM_INFO("using ser time func.\n");
00079    }
00080 }
00081 
00082 
00083 
00084 
00085 inline void free_report_cell(struct report_cell *cell)
00086 {
00087    if (!cell)
00088       return;
00089    if (cell->sms && !(--(cell->sms->ref)))
00090       shm_free(cell->sms);
00091    cell->sms = 0;
00092    cell->status = 0;
00093    cell->timeout = 0;
00094    cell->text = 0;
00095    cell->text_len = 0;
00096 }
00097 
00098 
00099 
00100 
00101 int init_report_queue(void)
00102 {
00103    report_queue = (struct report_cell*)
00104       shm_malloc(NR_CELLS*sizeof(struct report_cell));
00105    if (!report_queue) {
00106       LM_ERR("no more pkg memory!\n");
00107       return -1;
00108    }
00109    memset( report_queue , 0 , NR_CELLS*sizeof(struct report_cell) );
00110    return 1;
00111 }
00112 
00113 
00114 
00115 
00116 void destroy_report_queue(void)
00117 {
00118    int i;
00119 
00120    if (report_queue){
00121       for(i=0;i<NR_CELLS;i++)
00122          if (report_queue[i].sms)
00123             free_report_cell(&(report_queue[i]));
00124       shm_free(report_queue);
00125       report_queue = 0;
00126    }
00127 }
00128 
00129 
00130 
00131 
00132 void add_sms_into_report_queue(int id, struct sms_msg *sms, char *p, int l)
00133 {
00134    if (report_queue[id].sms){
00135       LM_INFO("old message still waiting for report at location %d"
00136             " -> discarding\n",id);
00137       free_report_cell(&(report_queue[id]));
00138    }
00139 
00140    sms->ref++;
00141    report_queue[id].status = -1;
00142    report_queue[id].sms = sms;
00143    report_queue[id].text = p;
00144    report_queue[id].text_len = l;
00145    report_queue[id].timeout = get_time() + REPORT_TIMEOUT;
00146 }
00147 
00148 
00149 
00150 
00151 int  relay_report_to_queue(int id, char *phone, int status, int *old_status)
00152 {
00153    struct report_cell *cell;
00154    int    ret_code;
00155 
00156    cell = &(report_queue[id]);
00157    ret_code = 0;
00158 
00159    /* first, do we have a match into the sms queue? */
00160    if (!cell->sms) {
00161       LM_INFO("report received for cell %d,"
00162             "  but the sms was already trashed from queue!\n",id);
00163       goto done;
00164    }
00165    if (strlen(phone)!=cell->sms->to.len ||
00166    strncmp(phone,cell->sms->to.s,cell->sms->to.len)) {
00167       LM_INFO("report received for cell %d, but the phone nr is different"
00168             "->old report->ignored\n",id);
00169       goto done;
00170    }
00171 
00172    if (old_status)
00173       *old_status = cell->status;
00174    cell->status = status;
00175    if (status>=0 && status<32) {
00176       LM_DBG("sms %d confirmed with code %d\n", id, status);
00177       ret_code = 2; /* success */
00178    } else if (status<64) {
00179       /* provisional report */
00180       LM_DBG("sms %d received prov. report with"
00181          " code %d\n",id, status);
00182       ret_code = 1; /* provisional */
00183    } else {
00184       LM_DBG("sms %d received error report with code %d\n",id, status);
00185       ret_code = 3; /* error */
00186    }
00187 
00188 done:
00189    return ret_code;
00190 }
00191 
00192 
00193 
00194 
00195 void check_timeout_in_report_queue(void)
00196 {
00197    int i;
00198    time_t current_time;
00199 
00200    current_time = get_time();
00201    for(i=0;i<NR_CELLS;i++)
00202       if (report_queue[i].sms && report_queue[i].timeout<=current_time) {
00203          LM_INFO("[%lu,%lu] record %d is discarded (timeout), having status"
00204             " %d\n", (long unsigned int)current_time,
00205             (long unsigned int)report_queue[i].timeout,
00206             i,report_queue[i].status);
00207          free_report_cell(&(report_queue[i]));
00208       }
00209 }
00210 
00211 
00212 
00213 
00214 void remove_sms_from_report_queue(int id)
00215 {
00216    free_report_cell(&(report_queue[id]));
00217 }
00218 
00219 
00220 
00221 
00222 str* get_text_from_report_queue(int id)
00223 {
00224    static str text;
00225 
00226    text.s = report_queue[id].text;
00227    text.len = report_queue[id].text_len;
00228    return &text;
00229 }
00230 
00231 
00232 
00233 
00234 struct sms_msg* get_sms_from_report_queue(int id)
00235 {
00236    return ( report_queue[id].sms);
00237 }
00238 
00239 
00240 
00241 
00242 str* get_error_str(int status)
00243 {
00244    static str err_str;
00245 
00246    switch (status) {
00247       /*
00248       case 0: strcat(sms->ascii,"Ok,short message received by the SME");
00249          break;
00250       case 1: strcat(sms->ascii,"Ok,short message forwarded by the SC to"
00251          " the SME but the SC is unable to confirm delivery");
00252          break;
00253       case 2: strcat(sms->ascii,"Ok,short message replaced by the SC");
00254          break;
00255       case 32: strcat(sms->ascii,"Still trying,congestion");
00256          break;
00257       case 33: strcat(sms->ascii,"Still trying,SME busy");
00258          break;
00259       case 34: strcat(sms->ascii,"Still trying,no response from SME");
00260          break;
00261       case 35: strcat(sms->ascii,"Still trying,service rejected");
00262          break;
00263       case 36: strcat(sms->ascii,"Still trying,quality of service not"
00264          " available");
00265          break;
00266       case 37: strcat(sms->ascii,"Still trying,error in SME");
00267          break;
00268       case 48:
00269          err_str.s =
00270          START_ERR_MSG"Delivery is not possible"END_ERR_MSG;
00271          err_str.len = 24 + START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00272          break;
00273       */
00274       case 64:
00275          err_str.s =
00276          START_ERR_MSG"Error, remote procedure error"END_ERR_MSG;
00277          err_str.len = 29 + START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00278          break;
00279       case 65: 
00280          err_str.s =
00281          START_ERR_MSG"Error,incompatible destination"END_ERR_MSG;
00282          err_str.len = 30 + START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00283          break;
00284       case 66: 
00285          err_str.s =
00286          START_ERR_MSG"Error,connection rejected by SME"END_ERR_MSG;
00287          err_str.len = 32 + START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00288          break;
00289       case 67:
00290          err_str.s = START_ERR_MSG"Error,not obtainable"END_ERR_MSG;
00291          err_str.len = 20 + START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00292          break;
00293       case 68:
00294          err_str.s =
00295          START_ERR_MSG"Error,quality of service not available"END_ERR_MSG;
00296          err_str.len = 38 + START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00297          break;
00298       case 69:
00299          err_str.s =
00300          START_ERR_MSG"Error,no interworking available"END_ERR_MSG;
00301          err_str.len = 31 + START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00302          break;
00303       case 70:
00304          err_str.s =
00305          START_ERR_MSG"Error,SM validity period expired"END_ERR_MSG;
00306          err_str.len = 32 + START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00307          break;
00308       case 71:
00309          err_str.s =
00310          START_ERR_MSG"Error,SM deleted by originating SME"END_ERR_MSG;
00311          err_str.len = 35 + START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00312          break;
00313       case 72:
00314          err_str.s =
00315          START_ERR_MSG"Error,SM deleted by SC administration"END_ERR_MSG;
00316          err_str.len = 37+ START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00317          break;
00318       case 73:
00319          err_str.s = START_ERR_MSG"Error,SM does not exist"END_ERR_MSG;
00320          err_str.len = 29+ START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00321          break;
00322       case 96:
00323          err_str.s = START_ERR_MSG"Error,congestion"END_ERR_MSG;
00324          err_str.len = 23+ START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00325          break;
00326       case 97:
00327          err_str.s = START_ERR_MSG"Error,SME busy"END_ERR_MSG;
00328          err_str.len = 14+ START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00329          break;
00330       case 98:
00331          err_str.s = START_ERR_MSG"Error,no response from SME"END_ERR_MSG;
00332          err_str.len = 26+ START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00333          break;
00334       case 99:
00335          err_str.s = START_ERR_MSG"Error,service rejected"END_ERR_MSG;
00336          err_str.len = 22+ START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00337          break;
00338       case 100:
00339          err_str.s =
00340          START_ERR_MSG"Error,quality of service not available"END_ERR_MSG;
00341          err_str.len = 38+ START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00342          break;
00343       case 101:
00344          err_str.s = START_ERR_MSG"Error,error in SME"END_ERR_MSG;
00345          err_str.len = 18+ START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00346          break;
00347       default:
00348          err_str.s = START_ERR_MSG"Unknown error code"END_ERR_MSG;
00349          err_str.len = 18+ START_ERR_MSG_LEN + END_ERR_MSG_LEN;
00350    }
00351    return &err_str;
00352 }

Generated on Thu May 24 12:00:31 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6