📄 smsc_smpp.c
字号:
pdu->u.data_sm.receipted_message_id, pdu->u.data_sm.message_state); if (dlrmsg != NULL) reason = bb_smscconn_receive(smpp->conn, dlrmsg); else reason = SMSCCONN_SUCCESS; resp->u.data_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason); } else { /* MO message */ msg = data_sm_to_msg(smpp, pdu, &reason); if (msg == NULL || reason != SMPP_ESME_ROK) { resp->u.data_sm_resp.command_status = reason; break; } /* 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); reason = bb_smscconn_receive(smpp->conn, msg); resp->u.data_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason); } break; case deliver_sm: /* * If SMSCConn stopped then send temp. error code */ mutex_lock(smpp->conn->flow_mutex); if (smpp->conn->is_stopped) { mutex_unlock(smpp->conn->flow_mutex); resp = smpp_pdu_create(deliver_sm_resp, pdu->u.deliver_sm.sequence_number); resp->u.deliver_sm.command_status = SMPP_ESME_RX_T_APPN; break; } mutex_unlock(smpp->conn->flow_mutex); /* got a deliver ack (DLR)? * NOTE: following SMPP v3.4. spec. we are interested * only on bits 2-5 (some SMSC's send 0x44, and it's * spec. conforme) */ if (pdu->u.deliver_sm.esm_class & (0x04|0x08)) { debug("bb.sms.smpp",0,"SMPP[%s] handle_pdu, got DLR", octstr_get_cstr(smpp->conn->id)); dlrmsg = handle_dlr(smpp, pdu->u.deliver_sm.source_addr, pdu->u.deliver_sm.short_message, pdu->u.deliver_sm.message_payload, pdu->u.deliver_sm.receipted_message_id, pdu->u.deliver_sm.message_state); resp = smpp_pdu_create(deliver_sm_resp, pdu->u.deliver_sm.sequence_number); if (dlrmsg != NULL) reason = bb_smscconn_receive(smpp->conn, dlrmsg); else reason = SMSCCONN_SUCCESS; resp->u.deliver_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason); } else {/* MO-SMS */ resp = smpp_pdu_create(deliver_sm_resp, pdu->u.deliver_sm.sequence_number); /* ensure the smsc-id is set */ msg = pdu_to_msg(smpp, pdu, &reason); if (msg == NULL) { resp->u.deliver_sm_resp.command_status = reason; break; } /* 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); reason = bb_smscconn_receive(smpp->conn, msg); resp->u.deliver_sm_resp.command_status = smscconn_failure_reason_to_smpp_status(reason); } 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_resp.sequence_number); smpp_msg = dict_remove(smpp->sent_msgs, os); octstr_destroy(os); if (smpp_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_resp.sequence_number); break; } msg = smpp_msg->msg; smpp_msg_destroy(smpp_msg, 0); if (pdu->u.submit_sm_resp.command_status != 0) { error(0, "SMPP[%s]: SMSC returned error code 0x%08lx (%s) " "in response to submit_sm.", octstr_get_cstr(smpp->conn->id), pdu->u.submit_sm_resp.command_status, smpp_error_to_string(pdu->u.submit_sm_resp.command_status)); reason = smpp_status_to_smscconn_failure_reason( pdu->u.submit_sm_resp.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_resp.command_status == SMPP_ESME_RTHROTTLED) time(&(smpp->throttling_err_time)); else smpp->throttling_err_time = 0; bb_smscconn_send_failed(smpp->conn, msg, reason, octstr_format("%ld/%s", pdu->u.submit_sm_resp.command_status, smpp_error_to_string(pdu->u.submit_sm_resp.command_status))); --(*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) || (!octstr_check_range(pdu->u.submit_sm_resp.message_id, 0, octstr_len(pdu->u.submit_sm_resp.message_id), gw_isdigit))) { tmp = octstr_format("%lu", strtoll( /* hex */ octstr_get_cstr(pdu->u.submit_sm_resp.message_id), NULL, 16)); } else { tmp = octstr_format("%lu", strtoll( /* decimal */ octstr_get_cstr(pdu->u.submit_sm_resp.message_id), NULL, 10)); } } /* SMSC ACK.. now we have the message id. */ if (DLR_IS_ENABLED_DEVICE(msg->sms.dlr_mask)) dlr_add(smpp->conn->id, tmp, msg); octstr_destroy(tmp); bb_smscconn_sent(smpp->conn, msg, NULL); --(*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 (%s).", octstr_get_cstr(smpp->conn->id), pdu->u.bind_transmitter_resp.command_status, smpp_error_to_string(pdu->u.bind_transmitter_resp.command_status)); if (pdu->u.bind_transmitter_resp.command_status == SMPP_ESME_RINVSYSID || pdu->u.bind_transmitter_resp.command_status == SMPP_ESME_RINVPASWD) smpp->quitting = 1; } else { *pending_submits = 0; mutex_lock(smpp->conn->flow_mutex); smpp->conn->status = SMSCCONN_ACTIVE; smpp->conn->connect_time = time(NULL); mutex_unlock(smpp->conn->flow_mutex); 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 (%s).", octstr_get_cstr(smpp->conn->id), pdu->u.bind_transceiver_resp.command_status, smpp_error_to_string(pdu->u.bind_transceiver_resp.command_status)); if (pdu->u.bind_transceiver_resp.command_status == SMPP_ESME_RINVSYSID || pdu->u.bind_transceiver_resp.command_status == SMPP_ESME_RINVPASWD) smpp->quitting = 1; } else { *pending_submits = 0; mutex_lock(smpp->conn->flow_mutex); smpp->conn->status = SMSCCONN_ACTIVE; smpp->conn->connect_time = time(NULL); mutex_unlock(smpp->conn->flow_mutex); 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 (%s).", octstr_get_cstr(smpp->conn->id), pdu->u.bind_receiver_resp.command_status, smpp_error_to_string(pdu->u.bind_receiver_resp.command_status)); if (pdu->u.bind_receiver_resp.command_status == SMPP_ESME_RINVSYSID || pdu->u.bind_receiver_resp.command_status == SMPP_ESME_RINVPASWD) smpp->quitting = 1; } else { /* set only resceive status if no transmitt is bind */ mutex_lock(smpp->conn->flow_mutex); if (smpp->conn->status != SMSCCONN_ACTIVE) { smpp->conn->status = SMSCCONN_ACTIVE_RECV; smpp->conn->connect_time = time(NULL); } mutex_unlock(smpp->conn->flow_mutex); } break; case unbind: resp = smpp_pdu_create(unbind_resp, pdu->u.unbind.sequence_number); mutex_lock(smpp->conn->flow_mutex); smpp->conn->status = SMSCCONN_DISCONNECTED; mutex_unlock(smpp->conn->flow_mutex); break; case unbind_resp: mutex_lock(smpp->conn->flow_mutex); smpp->conn->status = SMSCCONN_DISCONNECTED; mutex_unlock(smpp->conn->flow_mutex); break; case generic_nack: cmd_stat = pdu->u.generic_nack.command_status; os = octstr_format("%ld", pdu->u.generic_nack.sequence_number); smpp_msg = dict_remove(smpp->sent_msgs, os); octstr_destroy(os); if (smpp_msg == NULL) { error(0, "SMPP[%s]: SMSC rejected last command" "code 0x%08lx (%s).", octstr_get_cstr(smpp->conn->id), cmd_stat, smpp_error_to_string(cmd_stat)); } else { msg = smpp_msg->msg; smpp_msg_destroy(smpp_msg, 0); error(0, "SMPP[%s]: SMSC returned error code 0x%08lx (%s) " "in response to submit_sm.", octstr_get_cstr(smpp->conn->id), cmd_stat, smpp_error_to_string(cmd_stat)); /* * check to see if we got a "throttling error", in which case we'll just * sleep for a while */ if (cmd_stat == SMPP_ESME_RTHROTTLED) time(&(smpp->throttling_err_time)); else smpp->throttling_err_time = 0; reason = smpp_status_to_smscconn_failure_reason(cmd_stat); bb_smscconn_send_failed(smpp->conn, msg, reason, octstr_format("%ld/%s", cmd_stat, smpp_error_to_string(cmd_stat))); --(*pending_submits); } break; default: error(0, "SMPP[%s]: Unknown PDU type 0x%08lx, ignored.", octstr_get_cstr(smpp->conn->id), pdu->type); /* send gnack , see smpp3.4 spec., section 3.3 because we doesn't know what kind of pdu received, we assume generick_nack_resp (header always the same) */ resp = smpp_pdu_create(generic_nack, pdu->u.generic_nack.sequence_number); resp->u.generic_nack.command_status = SMPP_ESME_RINVCMDID; 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;}/* * sent queue cleanup. * @return 1 if io_thread should reconnect; 0 if not */static int do_queue_cleanup(SMPP *smpp, long *pending_submits, int action){ List *keys; Octstr *key; struct smpp_msg *smpp_msg; time_t now = time(NULL); if (*pending_submits <= 0) return 0; /* check if action set to wait ack for ever */ if (action == SMPP_WAITACK_NEVER_EXPIRE) return 0; keys = dict_keys(smpp->sent_msgs); if (keys == NULL) return 0; while ((key = gwlist_extract_first(keys)) != NULL) { smpp_msg = dict_get(smpp->sent_msgs, key); if (smpp_msg != NULL && difftime(now, smpp_msg->sent_time) > smpp->wait_ack) { switch(action) { case SMPP_WAITACK_RECONNECT: /* reconnect */ /* found at least one not acked msg */ warning(0, "SMPP[%s]: Not ACKED message found, reconnecting.", octstr_get_cstr(smpp->conn->id)); octstr_destroy(key); gwlist_destroy(keys, octstr_destroy_item); return 1; /* io_thread will reconnect */ case SMPP_WAITACK_REQUEUE: /* requeue */ smpp_msg = dict_remove(smpp->sent_msgs, ke
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -