⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smsc_smpp.c

📁 gnu的专业网关smpp协议支持源代码。
💻 C
📖 第 1 页 / 共 4 页
字号:
/*  * smsc_smpp.c - SMPP v3.3 and v3.4 implementation  *  * Lars Wirzenius  */   /* XXX check SMSCConn conformance */ /* XXX UDH reception */ /* XXX check UDH sending fields esm_class and data_coding from GSM specs */ /* XXX charset conversions on incoming messages (didn't work earlier,         either) */ /* XXX numbering plans and type of number: check spec */   #include "gwlib/gwlib.h" #include "msg.h" #include "smsc_p.h" #include "smpp_pdu.h" #include "smscconn_p.h" #include "bb_smscconn_cb.h" #include "sms.h" #include "dlr.h"  /*  * Select these based on whether you want to dump SMPP PDUs as they are   * sent and received or not. Not dumping should be the default in at least  * stable releases.  */ #define DEBUG 1#ifndef DEBUG /* This version doesn't dump. */ static void dump_pdu(const char *msg, Octstr *id, SMPP_PDU *pdu) { } #else /* This version does dump. */ static void dump_pdu(const char *msg, Octstr *id, SMPP_PDU *pdu) {     debug("bb.sms.smpp", 0, "SMPP[%s]: %s",           octstr_get_cstr(id), msg);     smpp_pdu_dump(pdu); } #endif   /*   * Some defaults. */  #define SMPP_ENQUIRE_LINK_INTERVAL  30.0 #define SMPP_MAX_PENDING_SUBMITS    10 #define SMPP_RECONNECT_DELAY	    10.0 #define SMPP_DEFAULT_VERSION        0x34#define SMPP_DEFAULT_PRIORITY       0#define SMPP_THROTTLING_SLEEP_TIME  15/* * Some SMPP error messages we come across */enum {    SMPP_ESME_RMSGQFUL   = 0x00000014,    SMPP_ESME_RTHROTTLED = 0x00000058} SMPP_ERROR_MESSAGES;  /***********************************************************************  * Implementation of the actual SMPP protocol: reading and writing  * PDUs in the correct order.  */   typedef struct {     long transmitter;     long receiver;     List *msgs_to_send;     Dict *sent_msgs;     List *received_msgs;     Counter *message_id_counter;     Octstr *host;     Octstr *system_type;     Octstr *username;     Octstr *password;     Octstr *address_range;     Octstr *our_host;     Octstr *my_number;     int source_addr_ton;     int source_addr_npi;     int dest_addr_ton;     int dest_addr_npi;    int alt_dcs;    int transmit_port;     int receive_port;     int quitting;     long enquire_link_interval;    long max_pending_submits;    long reconnect_delay;    int version;    int priority;       /* set default priority for messages */        time_t throttling_err_time;    int smpp_msg_id_type;  /* msg id in C string, hex or decimal */    int autodetect_addr;    SMSCConn *conn; } SMPP;   static SMPP *smpp_create(SMSCConn *conn, Octstr *host, int transmit_port,      	    	    	 int receive_port, Octstr *system_type,                           Octstr *username, Octstr *password,     	    	    	 Octstr *address_range, Octstr *our_host,                           int source_addr_ton, int source_addr_npi,                           int dest_addr_ton, int dest_addr_npi,                          int alt_dcs, int enquire_link_interval,                          int max_pending_submits, int reconnect_delay,                         int version, int priority, Octstr *my_number,                         int smpp_msg_id_type, int autodetect_addr) {     SMPP *smpp;          smpp = gw_malloc(sizeof(*smpp));     smpp->transmitter = -1;     smpp->receiver = -1;     smpp->msgs_to_send = list_create();     smpp->sent_msgs = dict_create(16, NULL);     list_add_producer(smpp->msgs_to_send);     smpp->received_msgs = list_create();     smpp->message_id_counter = counter_create();     smpp->host = octstr_duplicate(host);     smpp->system_type = octstr_duplicate(system_type);     smpp->username = octstr_duplicate(username);     smpp->password = octstr_duplicate(password);     smpp->address_range = octstr_duplicate(address_range);     smpp->source_addr_ton = source_addr_ton;     smpp->source_addr_npi = source_addr_npi;     smpp->dest_addr_ton = dest_addr_ton;     smpp->dest_addr_npi = dest_addr_npi;     smpp->alt_dcs = alt_dcs;    smpp->our_host = octstr_duplicate(our_host);     smpp->my_number = octstr_duplicate(my_number);     smpp->transmit_port = transmit_port;     smpp->receive_port = receive_port;     smpp->enquire_link_interval = enquire_link_interval;    smpp->max_pending_submits = max_pending_submits;     smpp->reconnect_delay = reconnect_delay;    smpp->quitting = 0;     smpp->version = version;    smpp->priority = priority;    smpp->conn = conn;     smpp->throttling_err_time = 0;     smpp->smpp_msg_id_type = smpp_msg_id_type;        smpp->autodetect_addr = autodetect_addr;     return smpp; }   static void smpp_destroy(SMPP *smpp) {     if (smpp != NULL) { 	list_destroy(smpp->msgs_to_send, msg_destroy_item); 	dict_destroy(smpp->sent_msgs); 	list_destroy(smpp->received_msgs, msg_destroy_item); 	counter_destroy(smpp->message_id_counter); 	octstr_destroy(smpp->host); 	octstr_destroy(smpp->username); 	octstr_destroy(smpp->password); 	octstr_destroy(smpp->system_type); 	octstr_destroy(smpp->address_range); 	octstr_destroy(smpp->our_host); 	gw_free(smpp);     } }   /*  * Try to read an SMPP PDU from a Connection. Return -1 for error (caller  * should close the connection), 0 for no PDU to ready yet, or 1 for PDU  * read and unpacked. Return a pointer to the PDU in `*pdu'. Use `*len'  * to store the length of the PDU to read (it may be possible to read the  * length, but not the rest of the PDU - we need to remember the lenght  * for the next call). `*len' should be zero at the first call.  */ static int read_pdu(SMPP *smpp, Connection *conn, long *len, SMPP_PDU **pdu) {     Octstr *os;      if (*len == 0) {         *len = smpp_pdu_read_len(conn);         if (*len == -1) {             error(0, "SMPP[%s]: Server sent garbage, ignored.",                  octstr_get_cstr(smpp->conn->id));             return -1;         } else if (*len == 0) {             if (conn_eof(conn) || conn_read_error(conn))                 return -1;             return 0;         }     }          os = smpp_pdu_read_data(conn, *len);     if (os == NULL) {         if (conn_eof(conn) || conn_read_error(conn))             return -1;         return 0;     }     *len = 0;          *pdu = smpp_pdu_unpack(os);     if (*pdu == NULL) {         error(0, "SMPP[%s]: PDU unpacking failed.",              octstr_get_cstr(smpp->conn->id));         debug("bb.sms.smpp", 0, "SMPP[%s]: Failed PDU follows.",              octstr_get_cstr(smpp->conn->id));         octstr_dump(os, 0);         octstr_destroy(os);         return -1;     }          octstr_destroy(os);     return 1; }   static Msg *pdu_to_msg(SMPP_PDU *pdu) {     Msg *msg;      gw_assert(pdu->type == deliver_sm);          msg = msg_create(sms);     msg->sms.sender = pdu->u.deliver_sm.source_addr;     pdu->u.deliver_sm.source_addr = NULL;     msg->sms.receiver = pdu->u.deliver_sm.destination_addr;     pdu->u.deliver_sm.destination_addr = NULL;     msg->sms.msgdata = pdu->u.deliver_sm.short_message;     pdu->u.deliver_sm.short_message = NULL;     charset_gsm_to_latin1(msg->sms.msgdata);     msg->sms.pid = pdu->u.deliver_sm.protocol_id;     dcs_to_fields(&msg, pdu->u.deliver_sm.data_coding);      return msg; }   static long smpp_status_to_smscconn_failure_reason(long status) {     switch(status) {        case SMPP_ESME_RMSGQFUL:            return SMSCCONN_FAILED_TEMPORARILY;            break;        case SMPP_ESME_RTHROTTLED:            return SMSCCONN_FAILED_TEMPORARILY;             break;        default:            return SMSCCONN_FAILED_REJECTED;     }}   static SMPP_PDU *msg_to_pdu(SMPP *smpp, Msg *msg) {     SMPP_PDU *pdu;     Octstr *buffer;    Octstr *relation_UTC_time = NULL;    struct tm gmtime, localtime, tm;    int gwqdiff;    pdu = smpp_pdu_create(submit_sm,      	    	    	  counter_increase(smpp->message_id_counter));     	    	        pdu->u.submit_sm.source_addr = octstr_duplicate(msg->sms.sender);     pdu->u.submit_sm.destination_addr = octstr_duplicate(msg->sms.receiver);       /* Check for manual override of source ton and npi values */     if(smpp->source_addr_ton > -1 && smpp->source_addr_npi > -1) {         pdu->u.submit_sm.source_addr_ton = smpp->source_addr_ton;         pdu->u.submit_sm.source_addr_npi = smpp->source_addr_npi;         debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced source addr ton = %d, source add npi = %d",               octstr_get_cstr(smpp->conn->id), smpp->source_addr_ton,               smpp->source_addr_npi);     } else {         /* setup default values */         pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */         pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */     }    if (smpp->autodetect_addr) {        /* lets see if its international or alphanumeric sender */         if (octstr_get_char(pdu->u.submit_sm.source_addr,0) == '+') {             if (!octstr_check_range(pdu->u.submit_sm.source_addr, 1, 256, gw_isdigit)) {                 pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC; /* alphanum */                 pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;    /* short code */             } else {                /* numeric sender address with + in front -> international (remove the +) */                octstr_delete(pdu->u.submit_sm.source_addr, 0, 1);                pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_INTERNATIONAL;     	    }         } else {             if (!octstr_check_range(pdu->u.submit_sm.source_addr,0, 256, gw_isdigit)) {                 pdu->u.submit_sm.source_addr_ton = GSM_ADDR_TON_ALPHANUMERIC;                 pdu->u.submit_sm.source_addr_npi = GSM_ADDR_NPI_UNKNOWN;             }         }     }      /* Check for manual override of destination ton and npi values */     if (smpp->dest_addr_ton > -1 && smpp->dest_addr_npi > -1) {         pdu->u.submit_sm.dest_addr_ton = smpp->dest_addr_ton;         pdu->u.submit_sm.dest_addr_npi = smpp->dest_addr_npi;         debug("bb.sms.smpp", 0, "SMPP[%s]: Manually forced dest addr ton = %d, source add npi = %d",               octstr_get_cstr(smpp->conn->id), smpp->dest_addr_ton,               smpp->dest_addr_npi);     } else {         pdu->u.submit_sm.dest_addr_ton = GSM_ADDR_TON_NATIONAL; /* national */         pdu->u.submit_sm.dest_addr_npi = GSM_ADDR_NPI_E164; /* ISDN number plan */     }      /*      * if its a international number starting with +, lets remove the      * '+' and set number type to international instead       */     if (octstr_get_char(pdu->u.submit_sm.destination_addr,0) == '+') { 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -