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

📄 smsc_at2.c

📁 gnu的专业网关smpp协议支持源代码。
💻 C
📖 第 1 页 / 共 5 页
字号:
{    SMSCConn *conn = arg;    PrivAT2data	*privdata = conn->data;    int l, wait = 0;    long idle_timeout, memory_poll_timeout = 0;    conn->status = SMSCCONN_CONNECTING;reconnect:    do {        if (wait) {            if (conn->status == SMSCCONN_ACTIVE) {                mutex_lock(conn->flow_mutex);                conn->status = SMSCCONN_RECONNECTING;                mutex_unlock(conn->flow_mutex);            }            info(0, "AT2[%s]: waiting for %d %s before trying to connect again",                  octstr_get_cstr(privdata->name), (wait < 60 ? wait : wait / 60),                 (wait < 60 ? "seconds" : "minutes"));            gwthread_sleep(wait);            wait = wait > (privdata->retry ? 3600 : 600) ?                 (privdata->retry ? 3600 : 600) : wait * 2;        } else            wait = 15;        /* If modems->speed is defined, try to use it, else autodetect */        if (privdata->speed == 0 && privdata->modem != NULL && 	    privdata->modem->speed != 0) {	    info(0, "AT2[%s]: trying to use speed <%ld> from modem definition", 	         octstr_get_cstr(privdata->name), privdata->modem->speed);	    if(0 == at2_test_speed(privdata, privdata->modem->speed)) { 		privdata->speed = privdata->modem->speed;		info(0, "AT2[%s]: speed is %ld", 		     octstr_get_cstr(privdata->name), privdata->speed);	    } else {		info(0, "AT2[%s]: speed in modem definition don't work, will autodetect", 		     octstr_get_cstr(privdata->name));	    }	}        if (privdata->speed == 0) {	    if (at2_detect_speed(privdata) == -1) {		if (!privdata->retry)		    return;		else		    continue;            }        }        if (privdata->modem == NULL) {            if (at2_detect_modem_type(privdata) == -1) {                if (!privdata->retry)                    return;                else                    continue;            }        }        if (at2_open_device(privdata)) {            error(errno, "AT2[%s]: at2_device_thread: open_at2_device failed. Terminating",                   octstr_get_cstr(privdata->name));            if (!privdata->retry)                return;            else                continue;        }        if (at2_init_device(privdata) != 0) {            error(0, "AT2[%s]: Opening failed. Terminating", octstr_get_cstr(privdata->name));            if (!privdata->retry) {                privdata->shutdown = 1;                //return;            } else                continue;        }        /* If we got here, then the device is opened */        break;    } while (privdata->retry && !privdata->shutdown);    conn->status = SMSCCONN_ACTIVE;    bb_smscconn_connected(conn);    idle_timeout = 0;    while (!privdata->shutdown) {        l = list_len(privdata->outgoing_queue);        if (l > 0) {            at2_send_messages(privdata);            idle_timeout = time(NULL);        } else            at2_wait_modem_command(privdata, 1, 0, NULL);        if (privdata->keepalive &&            idle_timeout + privdata->keepalive < time(NULL)) {            if (at2_send_modem_command(privdata,                 octstr_get_cstr(privdata->modem->keepalive_cmd), 5, 0) < 0) {                at2_close_device(privdata);                conn->status = SMSCCONN_RECONNECTING;                wait = 15;                goto reconnect;            }            idle_timeout = time(NULL);        }        if (privdata->sms_memory_poll_interval &&            memory_poll_timeout + privdata->sms_memory_poll_interval < time(NULL)) {            at2_read_sms_memory(privdata);            memory_poll_timeout = time(NULL);        }    }    at2_close_device(privdata);    conn->status = SMSCCONN_DISCONNECTED;    /* maybe some cleanup here? */    at2_destroy_modem(privdata->modem);    octstr_destroy(privdata->device);    octstr_destroy(privdata->ilb);    octstr_destroy(privdata->lines);    octstr_destroy(privdata->pin);    octstr_destroy(privdata->validityperiod);    octstr_destroy(privdata->my_number);    octstr_destroy(privdata->sms_center);    octstr_destroy(privdata->name);    octstr_destroy(privdata->configfile);    list_destroy(privdata->outgoing_queue, NULL);    gw_free(conn->data);    conn->data = NULL;    conn->why_killed = SMSCCONN_KILLED_SHUTDOWN;    conn->status = SMSCCONN_DEAD;    bb_smscconn_killed();}int at2_shutdown_cb(SMSCConn *conn, int finish_sending){    PrivAT2data *privdata = conn->data;    debug("bb.sms", 0, "AT2[%s]: Shutting down SMSCConn, %s",          octstr_get_cstr(privdata->name),          finish_sending ? "slow" : "instant");    /*      * Documentation claims this would have been done by smscconn.c,     * but isn't when this code is being written.      */    conn->why_killed = SMSCCONN_KILLED_SHUTDOWN;    privdata->shutdown = 1;     /*      * Separate from why_killed to avoid locking, as     * why_killed may be changed from outside?      */    if (finish_sending == 0) {        Msg *msg;        while ((msg = list_extract_first(privdata->outgoing_queue)) != NULL) {            bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN);        }    }    gwthread_wakeup(privdata->device_thread);    return 0;}long at2_queued_cb(SMSCConn *conn){    long ret;    PrivAT2data *privdata = conn->data;    if (conn->status == SMSCCONN_DEAD) /* I'm dead, why would you care ? */	return -1;	    ret = list_len(privdata->outgoing_queue);    /* use internal queue as load, maybe something else later */    conn->load = ret;    return ret;}void at2_start_cb(SMSCConn *conn){    PrivAT2data *privdata = conn->data;    if (conn->status == SMSCCONN_DISCONNECTED)        conn->status = SMSCCONN_ACTIVE;        /* in case there are messages in the buffer already */    gwthread_wakeup(privdata->device_thread);    debug("smsc.at2", 0, "AT2[%s]: start called", octstr_get_cstr(privdata->name));}int at2_add_msg_cb(SMSCConn *conn, Msg *sms){    PrivAT2data *privdata = conn->data;    Msg *copy;    copy = msg_duplicate(sms);    list_produce(privdata->outgoing_queue, copy);    gwthread_wakeup(privdata->device_thread);    return 0;}int smsc_at2_create(SMSCConn *conn, CfgGroup *cfg){    PrivAT2data	*privdata;    Octstr *modem_type_string;    privdata = gw_malloc(sizeof(PrivAT2data));    privdata->outgoing_queue = list_create();    privdata->configfile = cfg_get_configfile(cfg);    privdata->device = cfg_get(cfg, octstr_imm("device"));    if (privdata->device == NULL) {        error(0, "AT2[-]: 'device' missing in at2 configuration.");        goto error;    }    privdata->name = cfg_get(cfg, octstr_imm("smsc-id"));    if (privdata->name == NULL) {        privdata->name = octstr_duplicate(privdata->device);    }    privdata->speed = 0;    cfg_get_integer(&privdata->speed, cfg, octstr_imm("speed"));    privdata->keepalive = 0;    cfg_get_integer(&privdata->keepalive, cfg, octstr_imm("keepalive"));    cfg_get_bool(&privdata->sms_memory_poll_interval, cfg, octstr_imm("sim-buffering"));    if (privdata->sms_memory_poll_interval) {        if (privdata->keepalive)            privdata->sms_memory_poll_interval = privdata->keepalive;        else            privdata->sms_memory_poll_interval = AT2_DEFAULT_SMS_POLL_INTERVAL;    }    cfg_get_bool(&privdata->retry, cfg, octstr_imm("retry"));    privdata->my_number = cfg_get(cfg, octstr_imm("my-number"));    privdata->sms_center = cfg_get(cfg, octstr_imm("sms-center"));    modem_type_string = cfg_get(cfg, octstr_imm("modemtype"));    privdata->modem = NULL;    if (modem_type_string != NULL) {        if (octstr_compare(modem_type_string, octstr_imm("auto")) == 0 ||            octstr_compare(modem_type_string, octstr_imm("autodetect")) == 0)            O_DESTROY(modem_type_string);    }    if (octstr_len(modem_type_string) == 0) {        info(0, "AT2[%s]: configuration doesn't show modemtype. will autodetect",             octstr_get_cstr(privdata->name));    } else {        info(0, "AT2[%s]: configuration shows modemtype <%s>",             octstr_get_cstr(privdata->name),             octstr_get_cstr(modem_type_string));        privdata->modem = at2_read_modems(privdata, privdata->configfile,                                          modem_type_string, 0);        if (privdata->modem == NULL) {            info(0, "AT2[%s]: modemtype not found, revert to autodetect",                 octstr_get_cstr(privdata->name));        } else {            info(0, "AT2[%s]: read modem definition for <%s>",                 octstr_get_cstr(privdata->name),                 octstr_get_cstr(privdata->modem->name));        }        O_DESTROY(modem_type_string);    }    privdata->ilb = octstr_create("");    privdata->fd = -1;    privdata->lines = NULL;    privdata->pin = cfg_get(cfg, octstr_imm("pin"));    privdata->pin_ready = 0;    privdata->conn = conn;    privdata->phase2plus = 0;    privdata->validityperiod = cfg_get(cfg, octstr_imm("validityperiod"));    cfg_get_bool(&privdata->alt_dcs, cfg, octstr_imm("alt-dcs"));    conn->data = privdata;    conn->name = octstr_format("AT2[%s]", octstr_get_cstr(privdata->name));    privdata->shutdown = 0;    conn->status = SMSCCONN_CONNECTING;    conn->connect_time = time(NULL);    if ((privdata->device_thread = gwthread_create(at2_device_thread, conn)) == -1) {        privdata->shutdown = 1;        goto error;    }    conn->shutdown = at2_shutdown_cb;    conn->queued = at2_queued_cb;    conn->start_conn = at2_start_cb;    conn->send_msg = at2_add_msg_cb;    return 0;error:    error(0, "AT2[%s]: Failed to create at2 smsc connection",          octstr_len(privdata->name) ? octstr_get_cstr(privdata->name) : "");    if (privdata != NULL) {        list_destroy(privdata->outgoing_queue, NULL);    }    gw_free(privdata);    conn->why_killed = SMSCCONN_KILLED_CANNOT_CONNECT;    conn->status = SMSCCONN_DEAD;    info(0, "AT2[%s]: exiting", octstr_get_cstr(privdata->name));    return -1;}int at2_pdu_extract(PrivAT2data *privdata, Octstr **pdu, Octstr *line){    Octstr *buffer;    long len = 0;    int pos = 0;    int tmp;    buffer = octstr_duplicate(line);    /* find the beginning of a message from the modem*/    if ((pos = octstr_search(buffer, octstr_imm("+CDS:"), 0)) != -1) 	pos += 5;    else {	if ((pos = octstr_search(buffer, octstr_imm("+CMT:"), 0)) != -1)	    pos += 5;	else if ((pos = octstr_search(buffer, octstr_imm("+CMGR:"), 0)) != -1) {	    /* skip status field in +CMGR response */	    if ((pos = octstr_search(buffer, octstr_imm(","), pos + 6)) != -1) 		pos++;	    else		goto nomsg;	} else	    goto nomsg;	/* skip the next comma in CMGR and CMT responses */	tmp = octstr_search(buffer, octstr_imm(","), pos);	if (! privdata->modem->broken && tmp == -1)	    goto nomsg;	if (tmp != -1)	    pos = tmp + 1;    }    /* read the message length */    pos = octstr_parse_long(&len, buffer, pos, 10);    if (pos == -1)        goto nomsg;    /* skip the spaces and line return */    while (isspace(octstr_get_char(buffer, pos)))        pos++;    /* skip the SMSC address on some modem types */    if (!privdata->modem->no_smsc) {        tmp = at2_hexchar(octstr_get_char(buffer, pos)) * 16              + at2_hexchar(octstr_get_char(buffer, pos + 1));        if (tmp < 0)            goto nomsg;        tmp = 2 + tmp * 2;        pos += tmp;    }    /* check if the buffer is long enough to contain the full message */    if (!privdata->modem->broken && octstr_len(buffer) < len * 2 + pos)        goto nomsg;    if (privdata->modem->broken && octstr_len(buffer) < len * 2)        goto nomsg;    /* copy the PDU then remove it from the input buffer*/    *pdu = octstr_copy(buffer, pos, len * 2);    octstr_destroy(buffer);    return 1;nomsg:    octstr_destroy(buffer);    return 0;}int at2_hexchar(int hexc){    hexc = toupper(hexc) - 48;    return (hexc > 9) ? hexc - 7 : hexc;}Msg *at2_pdu_decode(Octstr *data, PrivAT2data *privdata){    int type;    Msg *msg = NULL;    /* Get the PDU type */    type = octstr_get_char(data, 1) & 3;    switch (type) {        case AT_DELIVER_SM:            msg = at2_pdu_decode_deliver_sm(data, privdata);            break;        case AT_STATUS_REPORT_SM:	    msg = at2_pdu_decode_report_sm(data, privdata);

⌨️ 快捷键说明

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