📄 smsc_smpp.c
字号:
buffer = octstr_format("%02d%02d%02d%02d%02d%02d0%02d%1s", tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, gwqdiff, octstr_get_cstr(relation_UTC_time)); pdu->u.submit_sm.schedule_delivery_time = octstr_copy(buffer,0,16); octstr_destroy(buffer); } } /* ask for the delivery reports if needed */ if (DLR_IS_SUCCESS_OR_FAIL(msg->sms.dlr_mask)) pdu->u.submit_sm.registered_delivery = 1; else if (DLR_IS_FAIL(msg->sms.dlr_mask) && !DLR_IS_SUCCESS(msg->sms.dlr_mask)) pdu->u.submit_sm.registered_delivery = 2; octstr_destroy(relation_UTC_time); /* set priority */ if (smpp->priority >= 0 && smpp->priority <= 5) { pdu->u.submit_sm.priority_flag = smpp->priority; } else { /* default priority is 0 */ pdu->u.submit_sm.priority_flag = 0; } /* set more messages to send */ if (smpp->version > 0x33 && msg->sms.msg_left > 0) pdu->u.submit_sm.more_messages_to_send = 1; return pdu;}static void send_enquire_link(SMPP *smpp, Connection *conn, long *last_sent){ SMPP_PDU *pdu; Octstr *os; if (date_universal_now() - *last_sent < smpp->enquire_link_interval) return; *last_sent = date_universal_now(); pdu = smpp_pdu_create(enquire_link, counter_increase(smpp->message_id_counter)); dump_pdu("Sending enquire link:", smpp->conn->id, pdu); os = smpp_pdu_pack(pdu); if (os) conn_write(conn, os); /* Write errors checked by caller. */ octstr_destroy(os); smpp_pdu_destroy(pdu);}static void send_unbind(SMPP *smpp, Connection *conn){ SMPP_PDU *pdu; Octstr *os; pdu = smpp_pdu_create(unbind, counter_increase(smpp->message_id_counter)); dump_pdu("Sending unbind:", smpp->conn->id, pdu); os = smpp_pdu_pack(pdu); conn_write(conn, os); octstr_destroy(os); smpp_pdu_destroy(pdu);}static int send_pdu(Connection *conn, Octstr *id, SMPP_PDU *pdu){ Octstr *os; int ret; dump_pdu("Sending PDU:", id, pdu); os = smpp_pdu_pack(pdu); if (os) ret = conn_write(conn, os); /* Caller checks for write errors later */ else ret = -1; octstr_destroy(os); return ret;}static void send_messages(SMPP *smpp, Connection *conn, long *pending_submits){ Msg *msg; SMPP_PDU *pdu; Octstr *os; double delay = 0; if (*pending_submits == -1) return; if (smpp->conn->throughput > 0) { delay = 1.0 / smpp->conn->throughput; } while (*pending_submits < smpp->max_pending_submits) { /* Get next message, quit if none to be sent */ msg = list_extract_first(smpp->msgs_to_send); if (msg == NULL) break; /* Send PDU, record it as waiting for ack from SMS center */ pdu = msg_to_pdu(smpp, msg); if (pdu == NULL) { bb_smscconn_send_failed(smpp->conn, msg, SMSCCONN_FAILED_MALFORMED, octstr_create("MALFORMED SMS")); continue; } /* check for write errors */ if (send_pdu(conn, smpp->conn->id, pdu) == 0) { struct smpp_msg *smpp_msg = smpp_msg_create(msg); os = octstr_format("%ld", pdu->u.submit_sm.sequence_number); dict_put(smpp->sent_msgs, os, smpp_msg); smpp_pdu_destroy(pdu); octstr_destroy(os); ++(*pending_submits); /* * obey throughput speed limit, if any. */ if (smpp->conn->throughput) gwthread_sleep(delay); } else { /* write error occurs */ smpp_pdu_destroy(pdu); bb_smscconn_send_failed(smpp->conn, msg, SMSCCONN_FAILED_TEMPORARILY, NULL); break; } }}/* * Open transmission connection to SMS center. Return NULL for error, * open Connection for OK. Caller must set smpp->conn->status correctly * before calling this. */static Connection *open_transmitter(SMPP *smpp){ SMPP_PDU *bind; Connection *conn; conn = conn_open_tcp(smpp->host, smpp->transmit_port, smpp->conn->our_host ); if (conn == NULL) { error(0, "SMPP[%s]: Couldn't connect to server.", octstr_get_cstr(smpp->conn->id)); return NULL; } bind = smpp_pdu_create(bind_transmitter, counter_increase(smpp->message_id_counter)); bind->u.bind_transmitter.system_id = octstr_duplicate(smpp->username); bind->u.bind_transmitter.password = octstr_duplicate(smpp->password); if (smpp->system_type == NULL) bind->u.bind_transmitter.system_type = octstr_create("VMA"); else bind->u.bind_transmitter.system_type = octstr_duplicate(smpp->system_type); bind->u.bind_transmitter.interface_version = smpp->version; bind->u.bind_transmitter.address_range = octstr_duplicate(smpp->address_range); send_pdu(conn, smpp->conn->id, bind); smpp_pdu_destroy(bind); return conn; } /* * Open transceiver connection to SMS center. Return NULL for error, * open Connection for OK. Caller must set smpp->conn->status correctly * before calling this. */ static Connection *open_transceiver(SMPP *smpp) { SMPP_PDU *bind; Connection *conn; conn = conn_open_tcp(smpp->host, smpp->transmit_port, smpp->conn->our_host ); if (conn == NULL) { error(0, "SMPP[%s]: Couldn't connect to server.", octstr_get_cstr(smpp->conn->id)); return NULL; } bind = smpp_pdu_create(bind_transceiver, counter_increase(smpp->message_id_counter)); bind->u.bind_transmitter.system_id = octstr_duplicate(smpp->username); bind->u.bind_transmitter.password = octstr_duplicate(smpp->password); if (smpp->system_type == NULL) bind->u.bind_transmitter.system_type = octstr_create("VMA"); else bind->u.bind_transmitter.system_type = octstr_duplicate(smpp->system_type); bind->u.bind_transmitter.interface_version = smpp->version; bind->u.bind_transmitter.address_range = octstr_duplicate(smpp->address_range); send_pdu(conn, smpp->conn->id, bind); smpp_pdu_destroy(bind); return conn; } /* * Open reception connection to SMS center. Return NULL for error, * open Connection for OK. Caller must set smpp->conn->status correctly * before calling this. */ static Connection *open_receiver(SMPP *smpp){ SMPP_PDU *bind; Connection *conn; conn = conn_open_tcp(smpp->host, smpp->receive_port, smpp->conn->our_host ); if (conn == NULL) { error(0, "SMPP[%s]: Couldn't connect to server.", octstr_get_cstr(smpp->conn->id)); return NULL; } bind = smpp_pdu_create(bind_receiver, counter_increase(smpp->message_id_counter)); bind->u.bind_receiver.system_id = octstr_duplicate(smpp->username); bind->u.bind_receiver.password = octstr_duplicate(smpp->password); if (smpp->system_type == NULL) bind->u.bind_receiver.system_type = octstr_create("VMA"); else bind->u.bind_receiver.system_type = octstr_duplicate(smpp->system_type); bind->u.bind_receiver.interface_version = smpp->version; bind->u.bind_receiver.address_range = octstr_duplicate(smpp->address_range); send_pdu(conn, smpp->conn->id, bind); smpp_pdu_destroy(bind); return conn;}static Msg *handle_dlr(SMPP *smpp, SMPP_PDU *pdu){ Msg *dlrmsg = NULL; Octstr *respstr = NULL, *msgid = NULL, *tmp; int dlrstat = -1; /* first check for SMPP v3.4 and above */ if (smpp->version > 0x33 && pdu->u.deliver_sm.receipted_message_id) { msgid = pdu->u.deliver_sm.receipted_message_id; pdu->u.deliver_sm.receipted_message_id = NULL; switch(pdu->u.deliver_sm.message_state) { case 1: /* ENROUTE */ case 6: /* ACCEPTED */ dlrstat = DLR_BUFFERED; break; case 2: /* DELIVERED */ dlrstat = DLR_SUCCESS; break; case 3: /* EXPIRED */ case 4: /* DELETED */ case 5: /* UNDELIVERABLE */ case 7: /* UNKNOWN */ case 8: /* REJECTED */ dlrstat = DLR_FAIL; break; default: warning(0, "SMPP[%s]: Got DLR with unknown 'message_state' (%ld).", octstr_get_cstr(smpp->conn->id), pdu->u.deliver_sm.message_state); dlrstat = DLR_FAIL; break; } } /* check for SMPP v.3.4. and message_payload */ if (smpp->version > 0x33 && pdu->u.deliver_sm.sm_length == 0) respstr = pdu->u.deliver_sm.message_payload; else respstr = pdu->u.deliver_sm.short_message; /* still no msgid ? */ if (!msgid && respstr) { long curr = 0, vpos = 0; Octstr *stat = NULL; char id_cstr[65], stat_cstr[16], sub_d_cstr[13], done_d_cstr[13]; int sub, dlrvrd, ret; /* get server message id */ /* first try sscanf way if thus failed then old way */ ret = sscanf(octstr_get_cstr(respstr), "id:%64[^s] sub:%d dlvrd:%d submit date:%12[0-9] done date:%12[0-9] stat:%10[^t^e]", id_cstr, &sub, &dlrvrd, sub_d_cstr, done_d_cstr, stat_cstr); if (ret == 6) { msgid = octstr_create(id_cstr); octstr_strip_blanks(msgid); stat = octstr_create(stat_cstr); octstr_strip_blanks(stat); } else { debug("bb.sms.smpp", 0, "SMPP[%s]: Couldnot parse DLR string sscanf way," "fallback to old way. Please report!", octstr_get_cstr(smpp->conn->id)); if ((curr = octstr_search(respstr, octstr_imm("id:"), 0)) != -1) { vpos = octstr_search_char(respstr, ' ', curr); if ((vpos-curr >0) && (vpos != -1)) msgid = octstr_copy(respstr, curr+3, vpos-curr-3); } else { msgid = NULL; } /* get err & status code */ if ((curr = octstr_search(respstr, octstr_imm("stat:"), 0)) != -1) { vpos = octstr_search_char(respstr, ' ', curr); if ((vpos-curr >0) && (vpos != -1)) stat = octstr_copy(respstr, curr+5, vpos-curr-5); } else { stat = NULL; } } /* * we get the following status: * DELIVRD, ACCEPTD, EXPIRED, DELETED, UNDELIV, UNKNOWN, REJECTD * * Note: some buggy SMSC's send us immediately delivery notifications although * we doesn't requested these. */ if (stat != NULL && octstr_compare(stat, octstr_imm("DELIVRD")) == 0) dlrstat = DLR_SUCCESS; else if (stat != NULL && (octstr_compare(stat, octstr_imm("ACCEPTD")) == 0 || octstr_compare(stat, octstr_imm("ACKED")) == 0 || octstr_compare(stat, octstr_imm("BUFFRED")) == 0 || octstr_compare(stat, octstr_imm("ENROUTE")) == 0)) dlrstat = DLR_BUFFERED; else dlrstat = DLR_FAIL; if (stat != NULL) octstr_destroy(stat); } tmp = octstr_format("0"); if (msgid != NULL) { /* * Obey which SMPP msg_id type this SMSC is using, where we * have the following semantics for the variable smpp_msg_id: * * bit 1: type for submit_sm_resp, bit 2: type for deliver_sm * * if bit is set value is hex otherwise dec * * 0x00 deliver_sm dec, submit_sm_resp dec * 0x01 deliver_sm dec, submit_sm_resp hex * 0x02 deliver_sm hex, submit_sm_resp dec * 0x03 deliver_sm hex, submit_sm_resp hex * * Default behaviour is SMPP spec compliant, which means * msg_ids should be C strings and hence non modified.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -