/* * Add new dlr entry into dlr storage */ void dlr_add(const Octstr *smsc, const Octstr *ts, Msg *msg) { struct dlr_entry *dlr = NULL; /* Add the foreign_id so all SMSC modules can use it. * Obey also the original message in the split_parts list. */ if (msg->sms.foreign_id != NULL) octstr_destroy(msg->sms.foreign_id); msg->sms.foreign_id = octstr_duplicate(ts); if (msg->sms.split_parts != NULL) { struct split_parts *split = msg->sms.split_parts; if (split->orig->sms.foreign_id != NULL) octstr_destroy(split->orig->sms.foreign_id); split->orig->sms.foreign_id = octstr_duplicate(ts); } if(octstr_len(smsc) == 0) { warning(0, "DLR[%s]: Can't add a dlr without smsc-id", dlr_type()); return; } /* sanity check */ if (handles == NULL || handles->dlr_add == NULL || msg == NULL) return; /* check if delivery receipt requested */ if (!DLR_IS_ENABLED(msg->sms.dlr_mask)) return; /* allocate new struct dlr_entry struct */ dlr = dlr_entry_create(); gw_assert(dlr != NULL); /* now copy all values, we are interested in */ dlr->smsc = (smsc ? octstr_duplicate(smsc) : octstr_create("")); dlr->timestamp = (ts ? octstr_duplicate(ts) : octstr_create("")); dlr->source = (msg->sms.sender ? octstr_duplicate(msg->sms.sender) : octstr_create("")); dlr->destination = (msg->sms.receiver ? octstr_duplicate(msg->sms.receiver) : octstr_create("")); dlr->service = (msg->sms.service ? octstr_duplicate(msg->sms.service) : octstr_create("")); dlr->url = (msg->sms.dlr_url ? octstr_duplicate(msg->sms.dlr_url) : octstr_create("")); dlr->boxc_id = (msg->sms.boxc_id ? octstr_duplicate(msg->sms.boxc_id) : octstr_create("")); dlr->mask = msg->sms.dlr_mask; debug("dlr.dlr", 0, "DLR[%s]: Adding DLR smsc=%s, ts=%s, src=%s, dst=%s, mask=%d, boxc=%s", dlr_type(), octstr_get_cstr(dlr->smsc), octstr_get_cstr(dlr->timestamp), octstr_get_cstr(dlr->source), octstr_get_cstr(dlr->destination), dlr->mask, octstr_get_cstr(dlr->boxc_id)); /* call registered function */ handles->dlr_add(dlr); }
void dlr_flush(void) { info(0, "Flushing all %ld queued DLR messages in %s storage", dlr_messages(), dlr_type()); if (handles != NULL && handles->dlr_flush != NULL) handles->dlr_flush(); }
/* * Return Msg* if dlr entry found in DB, otherwise NULL. * NOTE: If typ is end status (e.g. DELIVERED) then dlr entry * will be removed from DB. */ Msg *dlr_find(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int typ) { Msg *msg = NULL; struct dlr_entry *dlr = NULL; if(octstr_len(smsc) == 0) { warning(0, "DLR[%s]: Can't find a dlr without smsc-id", dlr_type()); return NULL; } /* check if we have handler registered */ if (handles == NULL || handles->dlr_get == NULL) return NULL; debug("dlr.dlr", 0, "DLR[%s]: Looking for DLR smsc=%s, ts=%s, dst=%s, type=%d", dlr_type(), octstr_get_cstr(smsc), octstr_get_cstr(ts), octstr_get_cstr(dst), typ); dlr = handles->dlr_get(smsc, ts, dst); if (dlr == NULL) { warning(0, "DLR[%s]: DLR from SMSC<%s> for DST<%s> not found.", dlr_type(), octstr_get_cstr(smsc), octstr_get_cstr(dst)); return NULL; } #define O_SET(x, val) if (octstr_len(val) > 0) { x = val; val = NULL; } if ((typ & dlr->mask) > 0) { /* its an entry we are interested in */ msg = msg_create(sms); msg->sms.sms_type = report_mo; msg->sms.dlr_mask = typ; O_SET(msg->sms.service, dlr->service); O_SET(msg->sms.smsc_id, dlr->smsc); O_SET(msg->sms.receiver, dlr->destination); O_SET(msg->sms.sender, dlr->source); /* if dlr_url was present, recode it here again */ O_SET(msg->sms.dlr_url, dlr->url); /* add the foreign_id */ msg->sms.foreign_id = octstr_duplicate(ts); /* * insert original message to the data segment * later in the smsc module */ msg->sms.msgdata = NULL; /* * If a boxc_id is available, then instruct bearerbox to * route this msg back to originating smsbox */ O_SET(msg->sms.boxc_id, dlr->boxc_id); time(&msg->sms.time); debug("dlr.dlr", 0, "DLR[%s]: created DLR message for URL <%s>", dlr_type(), (msg->sms.dlr_url?octstr_get_cstr(msg->sms.dlr_url):"")); } else { debug("dlr.dlr", 0, "DLR[%s]: Ignoring DLR message because of mask type=%d dlr->mask=%d", dlr_type(), typ, dlr->mask); /* ok that was a status report but we where not interested in having it */ msg = NULL; } #undef O_SET /* check for end status and if so remove from storage */ if ((typ & DLR_BUFFERED) && ((dlr->mask & DLR_SUCCESS) || (dlr->mask & DLR_FAIL))) { debug("dlr.dlr", 0, "DLR[%s]: DLR not destroyed, still waiting for other delivery report", dlr_type()); /* update dlr entry status if function defined */ if (handles != NULL && handles->dlr_update != NULL) handles->dlr_update(smsc, ts, dst, typ); } else { if (handles != NULL && handles->dlr_remove != NULL) { /* it's not good for internal storage, but better for all others */ handles->dlr_remove(smsc, ts, dst); } else { warning(0, "DLR[%s]: Storage don't have remove operation defined", dlr_type()); } } /* destroy struct dlr_entry */ dlr_entry_destroy(dlr); return msg; }
Octstr *bb_print_status(int status_type) { char *s, *lb; char *frmt, *footer; Octstr *ret, *str, *version; time_t t; if ((lb = bb_status_linebreak(status_type)) == NULL) return octstr_create("Un-supported format"); t = time(NULL) - start_time; if (bb_status == BB_RUNNING) s = "running"; else if (bb_status == BB_ISOLATED) s = "isolated"; else if (bb_status == BB_SUSPENDED) s = "suspended"; else if (bb_status == BB_FULL) s = "filled"; else s = "going down"; version = version_report_string("bearerbox"); if (status_type == BBSTATUS_HTML) { frmt = "%s</p>\n\n" " <p>Status: %s, uptime %ldd %ldh %ldm %lds</p>\n\n" " <p>WDP: received %ld (%ld queued), sent %ld " "(%ld queued)</p>\n\n" " <p>SMS: received %ld (%ld queued), sent %ld " "(%ld queued), store size %ld<br>\n" " SMS: inbound (%.2f,%.2f,%.2f) msg/sec, " "outbound (%.2f,%.2f,%.2f) msg/sec</p>\n\n" " <p>DLR: received %ld, sent %ld<br>\n" " DLR: inbound (%.2f,%.2f,%.2f) msg/sec, outbound (%.2f,%.2f,%.2f) msg/sec<br>\n" " DLR: %ld queued, using %s storage</p>\n\n"; footer = "<p>"; } else if (status_type == BBSTATUS_WML) { frmt = "%s</p>\n\n" " <p>Status: %s, uptime %ldd %ldh %ldm %lds</p>\n\n" " <p>WDP: received %ld (%ld queued)<br/>\n" " WDP: sent %ld (%ld queued)</p>\n\n" " <p>SMS: received %ld (%ld queued)<br/>\n" " SMS: sent %ld (%ld queued)<br/>\n" " SMS: store size %ld<br/>\n" " SMS: inbound (%.2f,%.2f,%.2f) msg/sec<br/>\n" " SMS: outbound (%.2f,%.2f,%.2f) msg/sec</p>\n" " <p>DLR: received %ld<br/>\n" " DLR: sent %ld<br/>\n" " DLR: inbound (%.2f,%.2f,%.2f) msg/sec<br/>\n" " DLR: outbound (%.2f,%.2f,%.2f) msg/sec<br/>\n" " DLR: %ld queued<br/>\n" " DLR: using %s storage</p>\n\n"; footer = "<p>"; } else if (status_type == BBSTATUS_XML) { frmt = "<version>%s</version>\n" "<status>%s, uptime %ldd %ldh %ldm %lds</status>\n" "\t<wdp>\n\t\t<received><total>%ld</total><queued>%ld</queued>" "</received>\n\t\t<sent><total>%ld</total><queued>%ld</queued>" "</sent>\n\t</wdp>\n" "\t<sms>\n\t\t<received><total>%ld</total><queued>%ld</queued>" "</received>\n\t\t<sent><total>%ld</total><queued>%ld</queued>" "</sent>\n\t\t<storesize>%ld</storesize>\n\t\t" "<inbound>%.2f,%.2f,%.2f</inbound>\n\t\t" "<outbound>%.2f,%.2f,%.2f</outbound>\n\t\t" "</sms>\n" "\t<dlr>\n\t\t<received><total>%ld</total></received>\n\t\t" "<sent><total>%ld</total></sent>\n\t\t" "<inbound>%.2f,%.2f,%.2f</inbound>\n\t\t" "<outbound>%.2f,%.2f,%.2f</outbound>\n\t\t" "<queued>%ld</queued>\n\t\t<storage>%s</storage>\n\t</dlr>\n"; footer = ""; } else { frmt = "%s\n\nStatus: %s, uptime %ldd %ldh %ldm %lds\n\n" "WDP: received %ld (%ld queued), sent %ld (%ld queued)\n\n" "SMS: received %ld (%ld queued), sent %ld (%ld queued), store size %ld\n" "SMS: inbound (%.2f,%.2f,%.2f) msg/sec, " "outbound (%.2f,%.2f,%.2f) msg/sec\n\n" "DLR: received %ld, sent %ld\n" "DLR: inbound (%.2f,%.2f,%.2f) msg/sec, outbound (%.2f,%.2f,%.2f) msg/sec\n" "DLR: %ld queued, using %s storage\n\n"; footer = ""; } ret = octstr_format(frmt, octstr_get_cstr(version), s, t/3600/24, t/3600%24, t/60%60, t%60, counter_value(incoming_wdp_counter), gwlist_len(incoming_wdp) + boxc_incoming_wdp_queue(), counter_value(outgoing_wdp_counter), gwlist_len(outgoing_wdp) + udp_outgoing_queue(), counter_value(incoming_sms_counter), gwlist_len(incoming_sms), counter_value(outgoing_sms_counter), gwlist_len(outgoing_sms), store_messages(), load_get(incoming_sms_load,0), load_get(incoming_sms_load,1), load_get(incoming_sms_load,2), load_get(outgoing_sms_load,0), load_get(outgoing_sms_load,1), load_get(outgoing_sms_load,2), counter_value(incoming_dlr_counter), counter_value(outgoing_dlr_counter), load_get(incoming_dlr_load,0), load_get(incoming_dlr_load,1), load_get(incoming_dlr_load,2), load_get(outgoing_dlr_load,0), load_get(outgoing_dlr_load,1), load_get(outgoing_dlr_load,2), dlr_messages(), dlr_type()); octstr_destroy(version); append_status(ret, str, boxc_status, status_type); append_status(ret, str, smsc2_status, status_type); octstr_append_cstr(ret, footer); return ret; }