sms_report.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00053
00054
00055 static time_t get_time_ser(void)
00056 {
00057 return get_ticks();
00058 }
00059
00060 static time_t get_time_sys(void)
00061 {
00062 return time(0);
00063 }
00064
00065
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
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;
00178 } else if (status<64) {
00179
00180 LM_DBG("sms %d received prov. report with"
00181 " code %d\n",id, status);
00182 ret_code = 1;
00183 } else {
00184 LM_DBG("sms %d received error report with code %d\n",id, status);
00185 ret_code = 3;
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
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
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 }