📄 smsc_smpp.c
字号:
} /* * we get the following status: * DELIVRD, ACCEPTD, EXPIRED, DELETED, UNDELIV, UNKNOWN, REJECTD */ if ((stat != NULL) && ((octstr_compare(stat, octstr_imm("DELIVRD")) == 0) || (octstr_compare(stat, octstr_imm("ACCEPTD")) == 0))) dlrstat = DLR_SUCCESS; else dlrstat = DLR_FAIL; if (msgid != NULL) { Octstr *tmp; /* * 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. */ if (smpp->smpp_msg_id_type == -1) { /* the default, C string */ tmp = octstr_duplicate(msgid); } else { if (smpp->smpp_msg_id_type & 0x02) { tmp = octstr_format("%ld", strtol(octstr_get_cstr(msgid), NULL, 16)); } else { tmp = octstr_format("%ld", strtol(octstr_get_cstr(msgid), NULL, 10)); } } dlrmsg = dlr_find(octstr_get_cstr(smpp->conn->id), octstr_get_cstr(tmp), /* smsc message id */ octstr_get_cstr(pdu->u.deliver_sm.destination_addr), /* destination */ dlrstat); octstr_destroy(tmp); } if (dlrmsg != NULL) { /* * we found the delivery report in our storage, so recode the * message structure. * The DLR trigger URL is indicated by msg->sms.dlr_url. */ dlrmsg->sms.msgdata = octstr_duplicate(respstr); dlrmsg->sms.sms_type = report; bb_smscconn_receive(smpp->conn, dlrmsg); } else { error(0,"SMPP[%s]: got DLR but could not find message or was not interested in it", octstr_get_cstr(smpp->conn->id)); } resp = smpp_pdu_create(deliver_sm_resp, pdu->u.deliver_sm.sequence_number); if (msgid != NULL) octstr_destroy(msgid); if (stat != NULL) octstr_destroy(stat); } else /* MO-SMS */ { /* ensure the smsc-id is set */ msg = pdu_to_msg(pdu); /* Replace MO destination number with my-number */ if (octstr_len(smpp->my_number)) { octstr_destroy(msg->sms.receiver); msg->sms.receiver = octstr_duplicate(smpp->my_number); } time(&msg->sms.time); msg->sms.smsc_id = octstr_duplicate(smpp->conn->id); (void) bb_smscconn_receive(smpp->conn, msg); resp = smpp_pdu_create(deliver_sm_resp, pdu->u.deliver_sm.sequence_number); } break; case enquire_link: resp = smpp_pdu_create(enquire_link_resp, pdu->u.enquire_link.sequence_number); break; case enquire_link_resp: break; case submit_sm_resp: os = octstr_format("%ld", pdu->u.submit_sm.sequence_number); msg = dict_remove(smpp->sent_msgs, os); octstr_destroy(os); if (msg == NULL) { warning(0, "SMPP[%s]: SMSC sent submit_sm_resp " "with wrong sequence number 0x%08lx", octstr_get_cstr(smpp->conn->id), pdu->u.submit_sm.sequence_number); } else if (pdu->u.submit_sm_resp.command_status != 0) { error(0, "SMPP[%s]: SMSC returned error code 0x%08lx " "in response to submit_sm.", octstr_get_cstr(smpp->conn->id), pdu->u.submit_sm_resp.command_status); reason = smpp_status_to_smscconn_failure_reason( pdu->u.submit_sm.command_status); /* * check to see if we got a "throttling error", in which case we'll just * sleep for a while */ if (pdu->u.submit_sm.command_status == SMPP_ESME_RTHROTTLED) time(&(smpp->throttling_err_time)); else smpp->throttling_err_time = 0; /* gen DLR_SMSC_FAIL */ if (reason == SMSCCONN_FAILED_REJECTED && (msg->sms.dlr_mask & (DLR_SMSC_FAIL|DLR_FAIL))) { Octstr *reply; reply = octstr_format("0x%08lx", pdu->u.submit_sm_resp.command_status); /* generate DLR */ info(0,"SMPP[%s]: creating DLR message", octstr_get_cstr(smpp->conn->id)); dlrmsg = msg_create(sms); dlrmsg->sms.service = octstr_duplicate(msg->sms.service); dlrmsg->sms.dlr_mask = DLR_SMSC_FAIL; dlrmsg->sms.sms_type = report; dlrmsg->sms.smsc_id = octstr_duplicate(smpp->conn->id); dlrmsg->sms.sender = octstr_duplicate(msg->sms.receiver); dlrmsg->sms.receiver = octstr_create("000"); dlrmsg->sms.dlr_url = octstr_duplicate(msg->sms.dlr_url); dlrmsg->sms.msgdata = reply; time(&dlrmsg->sms.time); info(0,"SMPP[%s]: DLR = %s", octstr_get_cstr(smpp->conn->id), octstr_get_cstr(dlrmsg->sms.dlr_url)); bb_smscconn_receive(smpp->conn, dlrmsg); } bb_smscconn_send_failed(smpp->conn, msg, reason); --(*pending_submits); } else { Octstr *tmp; /* check if msg_id is C string, decimal or hex for this SMSC */ if (smpp->smpp_msg_id_type == -1) { /* the default, C string */ tmp = octstr_duplicate(pdu->u.submit_sm_resp.message_id); } else { if (smpp->smpp_msg_id_type & 0x01) { tmp = octstr_format("%ld", strtol( /* hex */ octstr_get_cstr(pdu->u.submit_sm_resp.message_id), NULL, 16)); } else { tmp = octstr_format("%ld", strtol( /* decimal */ octstr_get_cstr(pdu->u.submit_sm_resp.message_id), NULL, 10)); } } /* SMSC ACK.. now we have the message id. */ if (msg->sms.dlr_mask & (DLR_SMSC_SUCCESS|DLR_SUCCESS|DLR_FAIL|DLR_BUFFERED)) dlr_add(octstr_get_cstr(smpp->conn->id), octstr_get_cstr(tmp), octstr_get_cstr(msg->sms.sender), octstr_get_cstr(msg->sms.receiver), octstr_get_cstr(msg->sms.service), octstr_get_cstr(msg->sms.dlr_url), msg->sms.dlr_mask); /* gen DLR_SMSC_SUCCESS */ if (msg->sms.dlr_mask & DLR_SMSC_SUCCESS) { Octstr *reply; reply = octstr_format("0x%08lx", pdu->u.submit_sm_resp.command_status); dlrmsg = dlr_find(octstr_get_cstr(smpp->conn->id), octstr_get_cstr(tmp), /* smsc message id */ octstr_get_cstr(msg->sms.receiver), /* destination */ (DLR_SMSC_SUCCESS|((msg->sms.dlr_mask & (DLR_SUCCESS|DLR_FAIL)) ? DLR_BUFFERED : 0))); if (dlrmsg != NULL) { octstr_append_char(reply, '/'); dlrmsg->sms.msgdata = octstr_duplicate(reply); octstr_destroy(reply); bb_smscconn_receive(smpp->conn, dlrmsg); } else error(0,"SMPP[%s]: Got SMSC_ACK but could not find message", octstr_get_cstr(smpp->conn->id)); } octstr_destroy(tmp); bb_smscconn_sent(smpp->conn, msg); --(*pending_submits); } /* end if for SMSC ACK */ break; case bind_transmitter_resp: if (pdu->u.bind_transmitter_resp.command_status != 0) { error(0, "SMPP[%s]: SMSC rejected login to transmit, " "code 0x%08lx.", octstr_get_cstr(smpp->conn->id), pdu->u.bind_transmitter_resp.command_status); } else { *pending_submits = 0; smpp->conn->status = SMSCCONN_ACTIVE; smpp->conn->connect_time = time(NULL); bb_smscconn_connected(smpp->conn); } break; case bind_transceiver_resp: if (pdu->u.bind_transceiver_resp.command_status != 0) { error(0, "SMPP[%s]: SMSC rejected login to transmit, " "code 0x%08lx.", octstr_get_cstr(smpp->conn->id), pdu->u.bind_transceiver_resp.command_status); } else { *pending_submits = 0; smpp->conn->status = SMSCCONN_ACTIVE; smpp->conn->connect_time = time(NULL); bb_smscconn_connected(smpp->conn); } break; case bind_receiver_resp: if (pdu->u.bind_receiver_resp.command_status != 0) { error(0, "SMPP[%s]: SMSC rejected login to receive, " "code 0x%08lx.", octstr_get_cstr(smpp->conn->id), pdu->u.bind_receiver_resp.command_status); } else { /* set only resceive status if no transmitt is bind */ if (smpp->conn->status != SMSCCONN_ACTIVE) { smpp->conn->status = SMSCCONN_ACTIVE_RECV; smpp->conn->connect_time = time(NULL); } } break; case unbind: break; case unbind_resp: break; default: error(0, "SMPP[%s]: Unknown PDU type 0x%08lx, ignored.", octstr_get_cstr(smpp->conn->id), pdu->type); break; } if (resp != NULL) { send_pdu(conn, smpp->conn->id, resp); smpp_pdu_destroy(resp); } } struct io_arg { SMPP *smpp; int transmitter; }; static struct io_arg *io_arg_create(SMPP *smpp, int transmitter) { struct io_arg *io_arg; io_arg = gw_malloc(sizeof(*io_arg)); io_arg->smpp = smpp; io_arg->transmitter = transmitter; return io_arg; } /* * This is the main function for the background thread for doing I/O on * one SMPP connection (the one for transmitting or receiving messages). * It makes the initial connection to the SMPP server and re-connects * if there are I/O errors or other errors that require it. */ static void io_thread(void *arg) { SMPP *smpp; struct io_arg *io_arg; int transmitter; Connection *conn; int ret; long last_enquire_sent; long pending_submits; long len; SMPP_PDU *pdu; double timeout; io_arg = arg; smpp = io_arg->smpp; transmitter = io_arg->transmitter; gw_free(io_arg); conn = NULL; while (!smpp->quitting) { if (transmitter == 1) conn = open_transmitter(smpp); else if (transmitter == 2) conn = open_transceiver(smpp); else conn = open_receiver(smpp); if (conn == NULL) { error(0, "SMPP[%s]: Couldn't connect to SMS center (retrying in %ld seconds).", octstr_get_cstr(smpp->conn->id), smpp->reconnect_delay); gwthread_sleep(smpp->reconnect_delay); smpp->conn->status = SMSCCONN_RECONNECTING; continue; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -