📄 smsc_smpp.c
字号:
*/ 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(smpp->conn->id, tmp, /* smsc message id */ pdu->u.deliver_sm.destination_addr, /* destination */ dlrstat); octstr_destroy(msgid); } 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_mo; } else { error(0,"SMPP[%s]: got DLR but could not find message or was not interested" "in it ts<%s> dst<%s>, type<%d>", octstr_get_cstr(smpp->conn->id), octstr_get_cstr(tmp), octstr_get_cstr(pdu->u.deliver_sm.destination_addr), dlrstat); } octstr_destroy(tmp); return dlrmsg;}static void handle_pdu(SMPP *smpp, Connection *conn, SMPP_PDU *pdu, long *pending_submits){ SMPP_PDU *resp; Octstr *os; Msg *msg, *dlrmsg = NULL; long reason; long cmd_stat; struct smpp_msg *smpp_msg = NULL; resp = NULL; switch (pdu->type) { 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); /* * bb_smscconn_receive can fail, but we ignore that since we * have no way to usefull tell the SMS center about this * (no suitable error code for the deliver_sm_resp is defined) */ /* 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 & ~0xC3) == 0x04) { debug("bb.sms.smpp",0,"SMPP[%s] handle_pdu, got DLR", octstr_get_cstr(smpp->conn->id)); dlrmsg = handle_dlr(smpp, pdu); 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; switch(reason) { case SMSCCONN_SUCCESS: resp->u.deliver_sm_resp.command_status = SMPP_ESME_ROK; break; case SMSCCONN_FAILED_REJECTED: resp->u.deliver_sm_resp.command_status = SMPP_ESME_RX_R_APPN; break; default: resp->u.deliver_sm_resp.command_status = SMPP_ESME_RX_T_APPN; break; } } 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); switch(reason) { case SMSCCONN_SUCCESS: resp->u.deliver_sm_resp.command_status = SMPP_ESME_ROK; break; case SMSCCONN_FAILED_REJECTED: resp->u.deliver_sm_resp.command_status = SMPP_ESME_RX_R_APPN; break; default: resp->u.deliver_sm_resp.command_status = SMPP_ESME_RX_T_APPN; break; } } 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) { 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 (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;}/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -