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

📄 smsc_smasi.c

📁 gnu的专业网关smpp协议支持源代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
            }            break;        case LogonConf:            *pending_submits = 0;            smasi->conn->status = SMSCCONN_ACTIVE;            smasi->conn->connect_time = time(NULL);            bb_smscconn_connected(smasi->conn);            info(0, "SMASI[%s]: connection to SMSC established.",                 octstr_get_cstr(smasi->conn->id));            break;        case LogonRej:            if (octstr_len(pdu->u.LogonRej.Reason) > 0) {                error(0, "SMASI[%s]: SMSC rejected login with reason <%s>",                      octstr_get_cstr(smasi->conn->id),                      octstr_get_cstr(pdu->u.LogonRej.Reason));            } else {                error(0, "SMASI[%s]: SMSC rejected login without reason",                      octstr_get_cstr(smasi->conn->id));            }            break;        case LogoffConf:            info(0, "SMASI[%s]: SMSC confirmed logoff.",                 octstr_get_cstr(smasi->conn->id));            smasi->logged_off = 1;            break;        default:            warning(0, "SMASI[%s]: Unknown PDU type <%s>, ignored.",                    octstr_get_cstr(smasi->conn->id), pdu->type_name);            break;    }    if (resp != NULL) {        send_pdu(conn, smasi->conn->id, resp);        smasi_pdu_destroy(resp);    }}/************************************************************************//* SMASI CONNECTION HANDLING                                            *//************************************************************************//* * Open transmission connection to SMS center. Return NULL for error, * open connection for OK. Caller must set smasi->conn->status correctly * before calling this. */static Connection *open_connection(SMASI *smasi) {    Connection *conn = conn_open_tcp(smasi->host, smasi->port, NULL);    if (conn == NULL) {        error(0, "SMASI[%s]: Couldn't connect to server.",              octstr_get_cstr(smasi->conn->id));        return NULL;    } else {        SMASI_PDU *logon = smasi_pdu_create(LogonReq);        logon->u.LogonReq.Name = octstr_duplicate(smasi->username);        logon->u.LogonReq.Password = octstr_duplicate(smasi->password);        counter_increase(smasi->message_id_counter);        send_pdu(conn, smasi->conn->id, logon);        smasi_pdu_destroy(logon);    }    return conn;} static void send_messages(SMASI *smasi, Connection *conn,                           long *pending_submits) {    if (*pending_submits == -1) return;    while (*pending_submits < MAX_PENDING_SUBMITS) {        SMASI_PDU *pdu = NULL;        /* Get next message, quit if none to be sent. */        Msg * msg = list_extract_first(smasi->msgs_to_send);        if (msg == NULL) break;        /* Send PDU, record it as waiting for ack from SMSC. */        pdu = msg_to_pdu(smasi, msg);        if (pdu->u.SubmitReq.Sequence)            dict_put(smasi->sent_msgs, pdu->u.SubmitReq.Sequence, msg);        send_pdu(conn, smasi->conn->id, pdu);        smasi_pdu_destroy(pdu);        ++(*pending_submits);    }}/* * This is the main function for the background thread for doing I/O on * one SMASI connection (the one for transmitting or receiving messages). * It makes the initial connection to the SMASI server and re-connects * if there are I/O errors or other errors that require it. */static void smasi_thread(void *arg) {    long pending_submits;    long len;    SMASI_PDU *pdu;    SMASI *smasi;    int logoff_already_sent = 0;    int ret;    Connection *conn;    long last_enquire_sent;     double timeout;     smasi = arg;    while (!smasi->quitting) {        conn = open_connection(smasi);        if (conn == NULL) {            error(0, "SMASI[%s]: Could not connect to SMSC center " \                  "(retrying in %ld seconds).",                  octstr_get_cstr(smasi->conn->id), smasi->reconnect_delay);            gwthread_sleep(smasi->reconnect_delay);            smasi->conn->status = SMSCCONN_RECONNECTING;            continue;        }        last_enquire_sent = date_universal_now();         pending_submits = -1;        len = 0;        for (;;) {            timeout = last_enquire_sent + smasi->enquire_link_interval                        - date_universal_now();             /* Send logoff request if module is shutting down. */            if (smasi->quitting && !logoff_already_sent) {                send_logoff(smasi, conn);                logoff_already_sent = 1;            }             /* send an enquire link */            send_enquire_link(smasi, conn, &last_enquire_sent);             /* Receive incoming PDUs. */            while ((ret = read_pdu(smasi, conn, &pdu)) == 1) {                /* Deal with the PDU we just got */                 dump_pdu("Got PDU:", smasi->conn->id, pdu);                /* Process the received PDU. */                handle_pdu(smasi, conn, pdu, &pending_submits);                smasi_pdu_destroy(pdu);                /* Bail out if logoff confirmed. */                if (smasi->logged_off) break;                /* Make sure we send even if we read a lot. */                if ((!smasi->throttling_err_time ||                    ((time(NULL) - smasi->throttling_err_time) >                     SMASI_THROTTLING_SLEEP_TIME                      && !(smasi->throttling_err_time = 0))))                    send_messages(smasi, conn, &pending_submits);            }             /* Check if connection broken. */            if (ret == -1 || conn_wait(conn, -1) == -1) {                error(0, "SMASI[%s]: I/O error or other error. Re-connecting.",                      octstr_get_cstr(smasi->conn->id));                break;            }             /* Bail out if logoff confirmed. */            if (smasi->logged_off) break;            if ((!smasi->throttling_err_time ||                ((time(NULL) - smasi->throttling_err_time) >                 SMASI_THROTTLING_SLEEP_TIME                  && !(smasi->throttling_err_time = 0))))                send_messages(smasi, conn, &pending_submits);        }         conn_destroy(conn);        conn = NULL;    } } /************************************************************************//* SMSCCONN INTERFACE                                                   *//************************************************************************/static long queued_cb(SMSCConn *conn) {    SMASI *smasi = conn->data;    conn->load = (smasi ? (conn->status != SMSCCONN_DEAD ?                     list_len(smasi->msgs_to_send) : 0) : 0);    return conn->load;} static int send_msg_cb(SMSCConn *conn, Msg *msg) {    SMASI *smasi = conn->data;    list_produce(smasi->msgs_to_send, msg_duplicate(msg));    gwthread_wakeup(smasi->thread_handle);    return 0;}static int shutdown_cb(SMSCConn *conn, int finish_sending) {    SMASI *smasi = NULL;    debug("bb.sms.smasi", 0, "Shutting down SMSCConn %s (%s)",          octstr_get_cstr(conn->name), finish_sending ? "slow" : "instant");    conn->why_killed = SMSCCONN_KILLED_SHUTDOWN;    smasi = conn->data;    smasi->quitting = 1;    gwthread_wakeup(smasi->thread_handle);    gwthread_join(smasi->thread_handle);    smasi_destroy(smasi);    debug("bb.sms.smasi", 0, "SMSCConn %s shut down.",          octstr_get_cstr(conn->name));    conn->status = SMSCCONN_DEAD;    bb_smscconn_killed();    /* Clean up. */    octstr_destroy(colon);    octstr_destroy(assign);    octstr_destroy(comma);    octstr_destroy(cr);    octstr_destroy(lf);    return 0;}/* * Configures the SMASI structure according to the configuration. * * @return 0 on complete success. -1 if failed due to missing or invalid * configuration entry. */static int init_configuration(SMASI *smasi, CfgGroup *config) {    /* Read mandatory entries. */    smasi->host = cfg_get(config, octstr_imm("host"));    smasi->username = cfg_get(config, octstr_imm("smsc-username"));    smasi->password = cfg_get(config, octstr_imm("smsc-password"));    /* Check configuration. */    if (smasi->host == NULL) {        error(0,"SMASI: Configuration file doesn't specify host");        return -1;    }    if (smasi->username == NULL) {        error(0, "SMASI: Configuration file doesn't specify username.");        return -1;    }    if (smasi->password == NULL) {        error(0, "SMASI: Configuration file doesn't specify password.");        return -1;    }    /* Read optional entries. Set default values if not set. */    smasi->my_number = cfg_get(config, octstr_imm("my-number"));    if (cfg_get_integer(&smasi->port, config, octstr_imm("port")) == -1)        smasi->port = SMASI_DEFAULT_PORT;    if (cfg_get_integer(&smasi->reconnect_delay, config,      octstr_imm("reconnect-delay")) == -1)        smasi->reconnect_delay = SMASI_RECONNECT_DELAY;    if (cfg_get_integer(&smasi->source_addr_ton, config,      octstr_imm("source-addr-ton")) == -1)        smasi->source_addr_ton = SMASI_OVERRIDE_SOURCE_TON;    if (cfg_get_integer(&smasi->source_addr_npi, config,      octstr_imm("source-addr-npi")) == -1)        smasi->source_addr_npi = SMASI_OVERRIDE_SOURCE_NPI;    if (cfg_get_integer(&smasi->dest_addr_ton, config,      octstr_imm("dest-addr-ton")) == -1)        smasi->source_addr_ton = SMASI_OVERRIDE_DEST_TON;    if (cfg_get_integer(&smasi->dest_addr_npi, config,      octstr_imm("dest-addr-npi")) == -1)        smasi->source_addr_npi = SMASI_OVERRIDE_DEST_NPI;    if (cfg_get_integer(&smasi->priority, config,      octstr_imm("priority")) == -1)        smasi->priority = SMASI_DEFAULT_PRIORITY;    if (cfg_get_integer(&smasi->enquire_link_interval, config,      octstr_imm("enquire-link-interval")) == -1)        smasi->enquire_link_interval = SMASI_ENQUIRE_LINK_INTERVAL;       /* Configure SMSC connection. */    smasi->conn->data = smasi;    smasi->conn->name = octstr_format("SMASI:%S:%d:%S",        smasi->host, smasi->port, smasi->username);    smasi->conn->id = cfg_get(config, octstr_imm("smsc-id"));    if (smasi->conn->id == NULL)      smasi->conn->id = octstr_duplicate(smasi->conn->name);    return 0;} int smsc_smasi_create(SMSCConn *conn, CfgGroup *config) {    SMASI *smasi = NULL;    /* Initialize data encoding subsystem. */    colon = octstr_create(":3a");    assign = octstr_create(":3d");    comma = octstr_create(":2c");    cr = octstr_create(":0a");    lf = octstr_create(":0d");    /* Create main SMASI structure and initialize it with configuration     * settings.     */    smasi = smasi_create(conn);    if (init_configuration(smasi, config) != 0)        panic(0, "SMASI SMSC module configuration invalid.");    conn->status = SMSCCONN_CONNECTING;    /* Port is always set to a configured value or defaults to 21500.     * Therefore, threads are always started.     */    smasi->thread_handle = gwthread_create(smasi_thread, smasi);    if (smasi->thread_handle == -1) {        error(0, "SMASI[%s]: Couldn't start SMASI thread.",              octstr_get_cstr(smasi->conn->id));        smasi_destroy(conn->data);        return -1;    }     /* Setup control function pointers. */    conn->shutdown = shutdown_cb;    conn->queued = queued_cb;    conn->send_msg = send_msg_cb;    return 0;}

⌨️ 快捷键说明

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