#include <ctype.h>#include <time.h>#include <errno.h>#include <limits.h>#include <string.h>#include <unistd.h>#include "gwlib/gwlib.h"#include "sms.h"#include "dlr.h"#include "dlr_p.h"Include dependency graph for dlr.c:

Go to the source code of this file.
Defines | |
| #define | O_DELETE(a) { if (a) octstr_destroy(a); a = NULL; } |
| #define | O_DELETE(a) { if (a) octstr_destroy(a); a = NULL; } |
| #define | O_SET(x, val) if (octstr_len(val) > 0) { x = val; val = NULL; } |
Functions | |
| dlr_entry * | dlr_entry_create (void) |
| dlr_entry * | dlr_entry_duplicate (const struct dlr_entry *dlr) |
| void | dlr_entry_destroy (struct dlr_entry *dlr) |
| dlr_db_fields * | dlr_db_fields_create (CfgGroup *grp) |
| void | dlr_db_fields_destroy (struct dlr_db_fields *fields) |
| void | dlr_init (Cfg *cfg) |
| void | dlr_shutdown () |
| long | dlr_messages (void) |
| const char * | dlr_type (void) |
| void | dlr_add (const Octstr *smsc, const Octstr *ts, const Msg *msg) |
| Msg * | dlr_find (const Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ) |
| void | dlr_flush (void) |
| Msg * | create_dlr_from_msg (const Octstr *smsc, const Msg *msg, const Octstr *reply, long stat) |
Variables | |
| dlr_storage * | handles = NULL |
|
|
|
|
|
Referenced by dlr_db_fields_destroy(), and dlr_entry_destroy(). |
|
|
Referenced by dlr_find(). |
|
||||||||||||||||||||
|
Definition at line 448 of file dlr.c. References debug(), gw_assert, msg_create, octstr_duplicate, octstr_get_cstr, and sms. Referenced by bb_smscconn_send_failed(), and bb_smscconn_sent(). 00449 {
00450 Msg *dlrmsg;
00451
00452 if (msg == NULL)
00453 return NULL;
00454
00455 /* generate DLR */
00456 debug("dlr.dlr", 0,"SMSC[%s]: creating DLR message",
00457 (smsc ? octstr_get_cstr(smsc) : "UNKNOWN"));
00458
00459 dlrmsg = msg_create(sms);
00460 gw_assert(dlrmsg != NULL);
00461
00462 dlrmsg->sms.service = octstr_duplicate(msg->sms.service);
00463 dlrmsg->sms.dlr_mask = stat;
00464 dlrmsg->sms.sms_type = report_mo;
00465 dlrmsg->sms.smsc_id = octstr_duplicate(smsc ? smsc : msg->sms.smsc_id);
00466 dlrmsg->sms.sender = octstr_duplicate(msg->sms.sender);
00467 dlrmsg->sms.receiver = octstr_duplicate(msg->sms.receiver);
00468 dlrmsg->sms.dlr_url = octstr_duplicate(msg->sms.dlr_url);
00469 dlrmsg->sms.msgdata = octstr_duplicate(reply);
00470 dlrmsg->sms.boxc_id = octstr_duplicate(msg->sms.boxc_id);
00471 time(&dlrmsg->sms.time);
00472
00473 debug("dlr.dlr", 0,"SMSC[%s]: DLR = %s",
00474 (smsc ? octstr_get_cstr(smsc) : "UNKNOWN"),
00475 (dlrmsg->sms.dlr_url ? octstr_get_cstr(dlrmsg->sms.dlr_url) : ""));
00476
00477 return dlrmsg;
00478 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 314 of file dlr.c. References dlr_entry::boxc_id, debug(), dlr_entry::destination, dlr_storage::dlr_add, dlr_entry_create(), DLR_IS_ENABLED, dlr_type(), gw_assert, handles, dlr_entry::mask, octstr_create, octstr_duplicate, octstr_get_cstr, octstr_len(), dlr_entry::service, dlr_entry::smsc, dlr_entry::source, dlr_entry::timestamp, dlr_entry::url, and warning(). Referenced by add_msg_cb(), at2_send_one_message(), cgw_handle_op(), cimd2_submit_msg(), clickatell_parse_reply(), emi2_handle_smscreq(), handle_pdu(), kannel_parse_reply(), oisd_submit_msg(), soap_read_response(), and xidris_parse_reply(). 00315 {
00316 struct dlr_entry *dlr = NULL;
00317
00318 if(octstr_len(smsc) == 0) {
00319 warning(0, "DLR[%s]: Can't add a dlr without smsc-id", dlr_type());
00320 return;
00321 }
00322
00323 /* sanity check */
00324 if (handles == NULL || handles->dlr_add == NULL || msg == NULL)
00325 return;
00326
00327 /* check if delivery receipt requested */
00328 if (!DLR_IS_ENABLED(msg->sms.dlr_mask))
00329 return;
00330
00331 /* allocate new struct dlr_entry struct */
00332 dlr = dlr_entry_create();
00333 gw_assert(dlr != NULL);
00334
00335 /* now copy all values, we are interested in */
00336 dlr->smsc = (smsc ? octstr_duplicate(smsc) : octstr_create(""));
00337 dlr->timestamp = (ts ? octstr_duplicate(ts) : octstr_create(""));
00338 dlr->source = (msg->sms.sender ? octstr_duplicate(msg->sms.sender) : octstr_create(""));
00339 dlr->destination = (msg->sms.receiver ? octstr_duplicate(msg->sms.receiver) : octstr_create(""));
00340 dlr->service = (msg->sms.service ? octstr_duplicate(msg->sms.service) : octstr_create(""));
00341 dlr->url = (msg->sms.dlr_url ? octstr_duplicate(msg->sms.dlr_url) : octstr_create(""));
00342 dlr->boxc_id = (msg->sms.boxc_id ? octstr_duplicate(msg->sms.boxc_id) : octstr_create(""));
00343 dlr->mask = msg->sms.dlr_mask;
00344
00345 debug("dlr.dlr", 0, "DLR[%s]: Adding DLR smsc=%s, ts=%s, src=%s, dst=%s, mask=%d, boxc=%s",
00346 dlr_type(), octstr_get_cstr(dlr->smsc), octstr_get_cstr(dlr->timestamp),
00347 octstr_get_cstr(dlr->source), octstr_get_cstr(dlr->destination), dlr->mask, octstr_get_cstr(dlr->boxc_id));
00348
00349 /* call registered function */
00350 handles->dlr_add(dlr);
00351 }
|
Here is the call graph for this function:

|
|
Definition at line 166 of file dlr.c. References cfg_get, gw_assert, octstr_imm(), and panic. Referenced by dlr_init_mysql(), and dlr_init_pgsql(). 00167 {
00168 struct dlr_db_fields *ret = NULL;
00169
00170 ret = gw_malloc(sizeof(*ret));
00171 gw_assert(ret != NULL);
00172 memset(ret, 0, sizeof(*ret));
00173
00174 if (!(ret->table = cfg_get(grp, octstr_imm("table"))))
00175 panic(0, "DLR: DB: directive 'table' is not specified!");
00176 if (!(ret->field_smsc = cfg_get(grp, octstr_imm("field-smsc"))))
00177 panic(0, "DLR: DB: directive 'field-smsc' is not specified!");
00178 if (!(ret->field_ts = cfg_get(grp, octstr_imm("field-timestamp"))))
00179 panic(0, "DLR: DB: directive 'field-timestamp' is not specified!");
00180 if (!(ret->field_src = cfg_get(grp, octstr_imm("field-source"))))
00181 panic(0, "DLR: DB: directive 'field-source' is not specified!");
00182 if (!(ret->field_dst = cfg_get(grp, octstr_imm("field-destination"))))
00183 panic(0, "DLR: DB: directive 'field-destination' is not specified!");
00184 if (!(ret->field_serv = cfg_get(grp, octstr_imm("field-service"))))
00185 panic(0, "DLR: DB: directive 'field-service' is not specified!");
00186 if (!(ret->field_url = cfg_get(grp, octstr_imm("field-url"))))
00187 panic(0, "DLR: DB: directive 'field-url' is not specified!");
00188 if (!(ret->field_mask = cfg_get(grp, octstr_imm("field-mask"))))
00189 panic(0, "DLR: DB: directive 'field-mask' is not specified!");
00190 if (!(ret->field_status = cfg_get(grp, octstr_imm("field-status"))))
00191 panic(0, "DLR: DB: directive 'field-status' is not specified!");
00192 if (!(ret->field_boxc = cfg_get(grp, octstr_imm("field-boxc-id"))))
00193 panic(0, "DLR: DB: directive 'field-boxc-id' is not specified!");
00194
00195 return ret;
00196 }
|
Here is the call graph for this function:

|
|
Definition at line 198 of file dlr.c. References dlr_db_fields::field_boxc, dlr_db_fields::field_dst, dlr_db_fields::field_mask, dlr_db_fields::field_serv, dlr_db_fields::field_smsc, dlr_db_fields::field_src, dlr_db_fields::field_status, dlr_db_fields::field_ts, dlr_db_fields::field_url, fields, O_DELETE, and dlr_db_fields::table. Referenced by dlr_mysql_shutdown(), and dlr_pgsql_shutdown(). 00199 {
00200 /* sanity check */
00201 if (fields == NULL)
00202 return;
00203
00204 #define O_DELETE(a) { if (a) octstr_destroy(a); a = NULL; }
00205
00206 O_DELETE(fields->table);
00207 O_DELETE(fields->field_smsc);
00208 O_DELETE(fields->field_ts);
00209 O_DELETE(fields->field_src);
00210 O_DELETE(fields->field_dst);
00211 O_DELETE(fields->field_serv);
00212 O_DELETE(fields->field_url);
00213 O_DELETE(fields->field_mask);
00214 O_DELETE(fields->field_status);
00215 O_DELETE(fields->field_boxc);
00216
00217 #undef O_DELETE
00218
00219 gw_free(fields);
00220 }
|
|
|
Definition at line 100 of file dlr.c. References gw_assert. Referenced by dlr_add(), dlr_entry_duplicate(), dlr_mysql_get(), and dlr_pgsql_get(). 00101 {
00102 struct dlr_entry *dlr;
00103
00104 dlr = gw_malloc(sizeof(*dlr));
00105 gw_assert(dlr != NULL);
00106
00107 /* set all values to NULL */
00108 memset(dlr, 0, sizeof(*dlr));
00109
00110 return dlr;
00111 }
|
|
|
Definition at line 139 of file dlr.c. References dlr_entry::boxc_id, dlr_entry::destination, dlr_entry::mask, O_DELETE, dlr_entry::service, dlr_entry::smsc, dlr_entry::source, dlr_entry::timestamp, and dlr_entry::url. Referenced by dlr_find(), dlr_mem_remove(), dlr_mem_shutdown(), dlr_mysql_add(), and dlr_pgsql_add(). 00140 {
00141 /* sanity check */
00142 if (dlr == NULL)
00143 return;
00144
00145 #define O_DELETE(a) { if (a) octstr_destroy(a); a = NULL; }
00146
00147 O_DELETE(dlr->smsc);
00148 O_DELETE(dlr->timestamp);
00149 O_DELETE(dlr->source);
00150 O_DELETE(dlr->destination);
00151 O_DELETE(dlr->service);
00152 O_DELETE(dlr->url);
00153 O_DELETE(dlr->boxc_id);
00154
00155 #undef O_DELETE
00156
00157 dlr->mask = 0;
00158 gw_free(dlr);
00159 }
|
|
|
Definition at line 116 of file dlr.c. References dlr_entry::boxc_id, dlr_entry::destination, dlr_entry_create(), dlr_entry::mask, octstr_duplicate, dlr_entry::service, dlr_entry::smsc, dlr_entry::source, dlr_entry::timestamp, and dlr_entry::url. Referenced by dlr_mem_get(). 00117 {
00118 struct dlr_entry *ret;
00119
00120 if (dlr == NULL)
00121 return NULL;
00122
00123 ret = dlr_entry_create();
00124 ret->smsc = octstr_duplicate(dlr->smsc);
00125 ret->timestamp = octstr_duplicate(dlr->timestamp);
00126 ret->source = octstr_duplicate(dlr->source);
00127 ret->destination = octstr_duplicate(dlr->destination);
00128 ret->service = octstr_duplicate(dlr->service);
00129 ret->url = octstr_duplicate(dlr->url);
00130 ret->boxc_id = octstr_duplicate(dlr->boxc_id);
00131 ret->mask = dlr->mask;
00132
00133 return ret;
00134 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 358 of file dlr.c. References dlr_entry::boxc_id, debug(), dlr_entry::destination, dlr_entry_destroy(), dlr_storage::dlr_get, dlr_storage::dlr_remove, dlr_type(), dlr_storage::dlr_update, handles, dlr_entry::mask, msg_create, O_SET, octstr_get_cstr, octstr_len(), dlr_entry::service, sms, dlr_entry::smsc, dlr_entry::source, dlr_entry::url, and warning(). Referenced by at2_pdu_decode_report_sm(), cgw_handle_op(), cimd2_accept_delivery_report_message(), clickatell_receive_sms(), handle_dlr(), handle_operation(), kannel_receive_sms(), main_connection_loop(), oisd_accept_delivery_report_message(), soap_parse_dlr(), and xidris_receive_sms(). 00359 {
00360 Msg *msg = NULL;
00361 struct dlr_entry *dlr = NULL;
00362
00363 if(octstr_len(smsc) == 0) {
00364 warning(0, "DLR[%s]: Can't find a dlr without smsc-id", dlr_type());
00365 return NULL;
00366 }
00367
00368 /* check if we have handler registered */
00369 if (handles == NULL || handles->dlr_get == NULL)
00370 return NULL;
00371
00372 debug("dlr.dlr", 0, "DLR[%s]: Looking for DLR smsc=%s, ts=%s, dst=%s, type=%d",
00373 dlr_type(), octstr_get_cstr(smsc), octstr_get_cstr(ts), octstr_get_cstr(dst), typ);
00374
00375 dlr = handles->dlr_get(smsc, ts, dst);
00376 if (dlr == NULL) {
00377 warning(0, "DLR[%s]: DLR from SMSC<%s> for DST<%s> not found.",
00378 dlr_type(), octstr_get_cstr(smsc), octstr_get_cstr(dst));
00379 return NULL;
00380 }
00381
00382 #define O_SET(x, val) if (octstr_len(val) > 0) { x = val; val = NULL; }
00383
00384 if ((typ & dlr->mask) > 0) {
00385 /* its an entry we are interested in */
00386 msg = msg_create(sms);
00387 msg->sms.sms_type = report_mo;
00388 msg->sms.dlr_mask = typ;
00389 O_SET(msg->sms.service, dlr->service);
00390 O_SET(msg->sms.smsc_id, dlr->smsc);
00391 O_SET(msg->sms.receiver, dlr->destination);
00392 O_SET(msg->sms.sender, dlr->source);
00393 /* if dlr_url was present, recode it here again */
00394 O_SET(msg->sms.dlr_url, dlr->url);
00395 /*
00396 * insert original message to the data segment
00397 * later in the smsc module
00398 */
00399 msg->sms.msgdata = NULL;
00400 /*
00401 * If a boxc_id is available, then instruct bearerbox to
00402 * route this msg back to originating smsbox
00403 */
00404 O_SET(msg->sms.boxc_id, dlr->boxc_id);
00405
00406 time(&msg->sms.time);
00407 debug("dlr.dlr", 0, "DLR[%s]: created DLR message for URL <%s>",
00408 dlr_type(), (msg->sms.dlr_url?octstr_get_cstr(msg->sms.dlr_url):""));
00409 } else {
00410 debug("dlr.dlr", 0, "DLR[%s]: Ignoring DLR message because of mask type=%d dlr->mask=%d", dlr_type(), typ, dlr->mask);
00411 /* ok that was a status report but we where not interested in having it */
00412 msg = NULL;
00413 }
00414
00415 #undef O_SET
00416
00417 /* check for end status and if so remove from storage */
00418 if ((typ & DLR_BUFFERED) && ((dlr->mask & DLR_SUCCESS) || (dlr->mask & DLR_FAIL))) {
00419 debug("dlr.dlr", 0, "DLR[%s]: DLR not destroyed, still waiting for other delivery report", dlr_type());
00420 /* update dlr entry status if function defined */
00421 if (handles != NULL && handles->dlr_update != NULL)
00422 handles->dlr_update(smsc, ts, dst, typ);
00423 } else {
00424 if (handles != NULL && handles->dlr_remove != NULL) {
00425 /* it's not good for internal storage, but better for all others */
00426 handles->dlr_remove(smsc, ts, dst);
00427 } else {
00428 warning(0, "DLR[%s]: Storage don't have remove operation defined", dlr_type());
00429 }
00430 }
00431
00432 /* destroy struct dlr_entry */
00433 dlr_entry_destroy(dlr);
00434
00435 return msg;
00436 }
|
Here is the call graph for this function:

|
|
Definition at line 438 of file dlr.c. References dlr_storage::dlr_flush, dlr_messages(), dlr_type(), handles, and info(). Referenced by bb_flush_dlr(). 00439 {
00440 info(0, "Flushing all %ld queued DLR messages in %s storage", dlr_messages(),
00441 dlr_type());
00442
00443 if (handles != NULL && handles->dlr_flush != NULL)
00444 handles->dlr_flush();
00445 }
|
Here is the call graph for this function:

|
|
Definition at line 227 of file dlr.c. References cfg_get, cfg_get_single_group(), dlr_storage::dlr_add, dlr_storage::dlr_get, dlr_init_mem(), dlr_init_mysql(), dlr_init_oracle(), dlr_init_pgsql(), dlr_init_sdb(), dlr_storage::dlr_remove, dlr_type(), handles, info(), octstr_compare(), octstr_destroy(), octstr_get_cstr, octstr_imm(), panic, dlr_storage::type, and warning(). Referenced by main(). 00228 {
00229 CfgGroup *grp;
00230 Octstr *dlr_type;
00231
00232 /* check which DLR storage type we are using */
00233 grp = cfg_get_single_group(cfg, octstr_imm("core"));
00234 if(grp == NULL)
00235 panic(0, "DLR: can't find group core");
00236
00237 dlr_type = cfg_get(grp, octstr_imm("dlr-storage"));
00238
00239 /*
00240 * assume we are using internal memory in case no directive
00241 * has been specified, warn the user anyway
00242 */
00243 if (dlr_type == NULL) {
00244 dlr_type = octstr_imm("internal");
00245 warning(0, "DLR: using default 'internal' for storage type.");
00246 }
00247
00248 /* call the sub-init routine */
00249 if (octstr_compare(dlr_type, octstr_imm("mysql")) == 0) {
00250 handles = dlr_init_mysql(cfg);
00251 } else if (octstr_compare(dlr_type, octstr_imm("sdb")) == 0) {
00252 handles = dlr_init_sdb(cfg);
00253 } else if (octstr_compare(dlr_type, octstr_imm("oracle")) == 0) {
00254 handles = dlr_init_oracle(cfg);
00255 } else if (octstr_compare(dlr_type, octstr_imm("internal")) == 0) {
00256 handles = dlr_init_mem(cfg);
00257 } else if (octstr_compare(dlr_type, octstr_imm("pgsql")) == 0) {
00258 handles = dlr_init_pgsql(cfg);
00259 }
00260
00261 /*
00262 * add aditional types here
00263 */
00264
00265 if (handles == NULL) {
00266 panic(0, "DLR: storage type '%s' is not supported!", octstr_get_cstr(dlr_type));
00267 }
00268
00269 /* check needed function pointers */
00270 if (handles->dlr_add == NULL || handles->dlr_get == NULL || handles->dlr_remove == NULL)
00271 panic(0, "DLR: storage type '%s' don't implement needed functions", octstr_get_cstr(dlr_type));
00272
00273 /* get info from storage */
00274 info(0, "DLR using storage type: %s", handles->type);
00275
00276 /* cleanup */
00277 octstr_destroy(dlr_type);
00278 }
|
Here is the call graph for this function:

|
|
Definition at line 292 of file dlr.c. References dlr_storage::dlr_messages, and handles. Referenced by bb_print_status(), and dlr_flush(). 00293 {
00294 if (handles != NULL && handles->dlr_messages != NULL)
00295 return handles->dlr_messages();
00296
00297 return -1;
00298 }
|
|
|
Definition at line 283 of file dlr.c. References dlr_storage::dlr_shutdown, and handles. Referenced by main(). 00284 {
00285 if (handles != NULL && handles->dlr_shutdown != NULL)
00286 handles->dlr_shutdown();
00287 }
|
|
|
Definition at line 303 of file dlr.c. References handles, and dlr_storage::type. Referenced by bb_print_status(), dlr_add(), dlr_find(), dlr_flush(), and dlr_init(). 00304 {
00305 if (handles != NULL && handles->type != NULL)
00306 return handles->type;
00307
00308 return "unknown";
00309 }
|
|
|
Definition at line 94 of file dlr.c. Referenced by dlr_add(), dlr_find(), dlr_flush(), dlr_init(), dlr_messages(), dlr_shutdown(), and dlr_type(). |