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

📄 smsc_at.c

📁 gateway-1.3.2.tar.gz WAP gw code
💻 C
📖 第 1 页 / 共 5 页
字号:
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->pending_incoming_messages = 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;    }    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) {        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;        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;}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);	    break;            /* Add other message types here: */    }    return msg;}Msg *at2_pdu_decode_deliver_sm(Octstr *data, PrivAT2data *privdata){    int len, pos, i, ntype;    int udhi, dcs, udhlen, pid;    Octstr *origin = NULL;    Octstr *udh = NULL;    Octstr *text = NULL, *tmpstr;    Octstr *pdu = NULL;    Msg *message = NULL;    struct universaltime mtime; /* time structure */    long stime; /* time in seconds */    int timezone; /* timezone in 15 minutes jumps from GMT */    /*      * Note: some parts of the PDU are not decoded because they are     * not needed for the Msg type.      */    /* convert the pdu to binary format for ease of processing */    pdu = at2_convertpdu(data);    /* UDH Indicator */    udhi = (octstr_get_char(pdu, 0) & 64) >> 6;    /* originating address */    len = octstr_get_char(pdu, 1);    if (len > 20) /* maximum valid number of semi-octets in Address-Value field */        goto msg_error;    ntype = octstr_get_char(pdu, 2);    pos = 3;    if ((ntype & 0xD0) == 0xD0) {        /* Alphanumeric sender */        origin = octstr_create("");        tmpstr = octstr_copy(pdu, 3, len);        at2_decode7bituncompressed(tmpstr, (((len - 1) * 4 - 3) / 7) + 1, origin, 0);        octstr_destroy(tmpstr);        debug("bb.smsc.at2", 0, "AT2[%s]: Alphanumeric sender <%s>",               octstr_get_cstr(privdata->name), octstr_get_cstr(origin));        pos += (len + 1) / 2;    } else {        origin = octstr_create("");        if ((ntype & 0x90) == 0x90) {            /* International number */            octstr_append_char(origin, '+');        }        for (i = 0; i < len; i += 2, pos++) {            octstr_append_char(origin, (octstr_get_char(pdu, pos) & 15) + 48);            if (i + 1 < len)                octstr_append_char(origin, (octstr_get_char(pdu, pos) >> 4) + 48);        }        debug("bb.smsc.at2", 0, "AT2[%s]: Numeric sender %s <%s>",               octstr_get_cstr(privdata->name), ((ntype & 0x90) == 0x90 ? "(international)" : ""),               octstr_get_cstr(origin));    }    if (pos > octstr_len(pdu))        goto msg_error;    /* PID */    pid = octstr_get_char(pdu, pos);    pos++;    /* DCS */    dcs = octstr_get_char(pdu, pos);    pos++;    /* get the timestamp */    mtime.year = swap_nibbles(octstr_get_char(pdu, pos));    pos++;    mtime.year += (mtime.year < 70 ? 2000 : 1900);    mtime.month = swap_nibbles(octstr_get_char(pdu, pos));    mtime.month--;        pos++;    mtime.day = swap_nibbles(octstr_get_char(pdu, pos));    pos++;    mtime.hour = swap_nibbles(octstr_get_char(pdu, pos));    pos++;    mtime.minute = swap_nibbles(octstr_get_char(pdu, pos));    pos++;    mtime.second = swap_nibbles(octstr_get_char(pdu, pos));    pos++;    /*      * time zone:      *     * time zone is "swapped nibble", with the MSB as the sign (1 is negative).       */    timezone = swap_nibbles(octstr_get_char(pdu, pos));    pos++;    timezone = ((timezone >> 7) ? -1 : 1) * (timezone & 127);    /*      * Ok, that was the time zone as read from the PDU. Now how to interpert it?      * All the handsets I tested send the timestamp of their local time and the      * timezone as GMT+0. I assume that the timestamp is the handset's local time,      * so we need to apply the timezone in reverse to get GM time:      */    /*      * time in PDU is handset's local time and timezone is handset's time zone      * difference from GMT      */    mtime.hour -= timezone / 4;    mtime.minute -= 15 * (timezone % 4);    stime = date_convert_universal(&mtime);    /* get data length     * XXX: Is it allowed to have length = 0 ??? (alex)     */    len = octstr_get_char(pdu, pos);    pos++;    debug("bb.smsc.at2", 0, "AT2[%s]: User data length read as (%d)", octstr_get_cstr(privdata->name), len);    /* if there is a UDH */    udhlen = 0;    if (udhi && len > 0) {        udhlen = octstr_get_char(pdu, pos);        pos++;        if (udhlen + 1 > len)            goto msg_error;        udh = octstr_copy(pdu, pos, udhlen);        pos += udhlen;        len -= udhlen + 1;    } else if (len <= 0) /* len < 0 is impossible, but sure is sure */        udhi = 0;    debug("bb.smsc.at2", 0, "AT2[%s]: Udh decoding done len=%d udhi=%d udhlen=%d udh='%s'",          octstr_get_cstr(privdata->name), len, udhi, udhlen, (udh?octstr_get_cstr(udh):""));    if (pos > octstr_len(pdu) || len < 0)        goto msg_error;    /* build the message */    message = msg_create(sms);    if (!dcs_to_fields(&message, dcs)) {        /* XXX Should reject this message? */        debug("bb.smsc.at2", 0, "AT2[%s]: Invalid DCS",              octstr_get_cstr(privdata->name));        dcs_to_fields(&message, 0);    }

⌨️ 快捷键说明

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