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

📄 smsc_at.c

📁 主要包括sms网关和wap网关实现说明和源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                at2_close_device(privdata);                reconnecting = 1;                goto reconnect;            }            idle_timeout = time(NULL);        }        if (privdata->sms_memory_poll_interval &&            memory_poll_timeout + privdata->sms_memory_poll_interval < time(NULL)) {            if (at2_read_sms_memory(privdata) == -1) {                at2_close_device(privdata);                reconnecting = 1;                goto reconnect;            }            memory_poll_timeout = time(NULL);        }    }    at2_close_device(privdata);    mutex_lock(conn->flow_mutex);    conn->status = SMSCCONN_DISCONNECTED;    mutex_unlock(conn->flow_mutex);    /* 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);    gw_prioqueue_destroy(privdata->outgoing_queue, NULL);    gwlist_destroy(privdata->pending_incoming_messages, octstr_destroy_item);    gw_free(conn->data);    conn->data = NULL;    mutex_lock(conn->flow_mutex);    conn->why_killed = SMSCCONN_KILLED_SHUTDOWN;    conn->status = SMSCCONN_DEAD;    mutex_unlock(conn->flow_mutex);    bb_smscconn_killed();}static 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 = gw_prioqueue_remove(privdata->outgoing_queue)) != NULL) {            bb_smscconn_send_failed(conn, msg, SMSCCONN_FAILED_SHUTDOWN, NULL);        }    }    gwthread_wakeup(privdata->device_thread);    return 0;}static 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 = gw_prioqueue_len(privdata->outgoing_queue);    /* use internal queue as load, maybe something else later */    conn->load = ret;    return ret;}static 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));}static int at2_add_msg_cb(SMSCConn *conn, Msg *sms){    PrivAT2data *privdata = conn->data;    Msg *copy;    copy = msg_duplicate(sms);    gw_prioqueue_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;    long portno;   /* has to be long because of cfg_get_integer */    privdata = gw_malloc(sizeof(PrivAT2data));    privdata->outgoing_queue = gw_prioqueue_create(sms_priority_compare);    privdata->pending_incoming_messages = gwlist_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;    }        if (octstr_str_compare(privdata->device, "rawtcp") == 0) {        privdata->rawtcp_host = cfg_get(cfg, octstr_imm("host"));        if (privdata->rawtcp_host == NULL) {            error(0, "AT2[-]: 'host' missing in at2 rawtcp configuration.");            goto error;        }        if (cfg_get_integer(&portno, cfg, octstr_imm("port")) == -1) {            error(0, "AT2[-]: 'port' missing in at2 rawtcp configuration.");            goto error;        }        privdata->rawtcp_port = portno;        privdata->is_serial = 0;    } else {        privdata->is_serial = 1;    }    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;    }    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"));    if (cfg_get_integer((long*) &privdata->max_error_count, cfg, octstr_imm("max-error-count")) == -1)        privdata->max_error_count = -1;    conn->data = privdata;    conn->name = octstr_format("AT2[%s]", octstr_get_cstr(privdata->name));    conn->status = SMSCCONN_CONNECTING;    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) {        gw_prioqueue_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;}static int at2_pdu_extract(PrivAT2data *privdata, Octstr **pdu, Octstr *line, Octstr *smsc_number){    Octstr *buffer;    long len = 0;    int pos = 0;    int tmp;	Octstr *numtmp;	Octstr *tmp2;	    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++;	octstr_truncate(smsc_number,0);    /* 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;               numtmp = octstr_create_from_data(octstr_get_cstr(buffer)+pos+2,tmp * 2);	/* we now have the hexchars of the SMSC in GSM encoding */		octstr_hex_to_binary(numtmp);		tmp2 = gsm2number(numtmp);		debug("bb.smsc.at2", 0, "AT2[%s]: received message from SMSC: %s", octstr_get_cstr(privdata->name), octstr_get_cstr(tmp2));		octstr_destroy(numtmp);		octstr_append(smsc_number,tmp2);		octstr_destroy(tmp2);        pos += 2 + tmp * 2;    }    /* 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;}static unsigned char	nibble2hex(unsigned char b){	if(b < 0x0A)		return '0'+ b;	else		return 'A'+ b - 0x0A;}static Octstr *gsm2number(Octstr *pdu){    Octstr *tmp = NULL;    unsigned char c;	unsigned char a;	unsigned char b;	int ton;	int npi;    int len;	int pos;	pos=0;    len = octstr_len(pdu);	    ton = octstr_get_char(pdu,pos++);    npi = ton & 0x0F;    ton =  (ton >> 4) & 0x07;	switch(ton)	{	case 0: /* unknown */		tmp = octstr_create("");		break;	case 1: /* international */		tmp = octstr_create("+");		break;	case 2: /* national */		tmp = octstr_create("0");		break;	case 3: /* network-specific */	default:		tmp = octstr_create("");		break;	}	while(--len)	{	    c = octstr_get_char(pdu,pos++);		a =  c & 0x0F;		b =  ((c & 0xF0) >> 4);			if((b == 0x0F) && (len < 2))		{			octstr_append_char(tmp, nibble2hex(a));		}		else		{			octstr_append_char(tmp, nibble2hex(a));			octstr_append_char(tmp, nibble2hex(b));		}	}	return tmp;}static int at2_hexchar(int hexc){    hexc = toupper(hexc) - 48;    return (hexc > 9) ? hexc - 7 : hexc;}static Msg *at2_pdu_decode(Octstr *data, PrivAT2data *privdata){    int type;    Msg *msg = NULL;    /* Get the PDU type */

⌨️ 快捷键说明

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