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

📄 smsc_at2.c

📁 gnu的专业网关smpp协议支持源代码。
💻 C
📖 第 1 页 / 共 5 页
字号:
    }    /* Set the modem to PDU mode and autodisplay of new messages */    ret = at2_send_modem_command(privdata, "AT+CMGF=0", 0, 0);    if (ret != 0 )        return -1;    /* lets see if it supports GSM SMS 2+ mode */    ret = at2_send_modem_command(privdata, "AT+CSMS=?", 0, 0);    if (ret != 0) {        /* if it doesnt even understand the command, I'm sure it wont support it */        privdata->phase2plus = 0;     } else {        /* we have to take a part a string like +CSMS: (0,1,128) */        Octstr *ts;        int i;        List *vals;        ts = privdata->lines;        privdata->lines = NULL;        i = octstr_search_char(ts, '(', 0);        if (i > 0) {            octstr_delete(ts, 0, i + 1);        }        i = octstr_search_char(ts, ')', 0);        if (i > 0) {            octstr_truncate(ts, i);        }        vals = octstr_split(ts, octstr_imm(","));        octstr_destroy(ts);        ts = list_search(vals, octstr_imm("1"), (void*) octstr_item_match);        if (ts)            privdata->phase2plus = 1;        list_destroy(vals, octstr_destroy_item);    }    if (privdata->phase2plus) {        info(0, "AT2[%s]: Phase 2+ is supported", octstr_get_cstr(privdata->name));        ret = at2_send_modem_command(privdata, "AT+CSMS=1", 0, 0);        if (ret != 0)            return -1;    }    /* send init string */    ret = at2_send_modem_command(privdata, octstr_get_cstr(privdata->modem->init_string), 0, 0);    if (ret != 0)        return -1;    if (privdata->sms_memory_poll_interval && privdata->modem->message_storage) {        /* set message storage location for "SIM buffering" using the CPMS command */        Octstr *temp;        temp = octstr_create("AT+CPMS=");        octstr_append_char(temp, 34);        octstr_append(temp, privdata->modem->message_storage);        octstr_append_char(temp, 34);        ret = at2_send_modem_command(privdata, octstr_get_cstr(temp), 0, 0);        octstr_destroy(temp);        if (ret != 0)            return -1;    }    info(0, "AT2[%s]: AT SMSC successfully opened.", octstr_get_cstr(privdata->name));    return 0;}int at2_send_modem_command(PrivAT2data *privdata, char *cmd, time_t timeout, int gt_flag){    at2_write_line(privdata, cmd);    return at2_wait_modem_command(privdata, timeout, gt_flag, NULL);}int at2_wait_modem_command(PrivAT2data *privdata, time_t timeout, int gt_flag,                            int *output){    Octstr *line = NULL;    Octstr *line2 = NULL;    Octstr *pdu = NULL;    int ret;    time_t end_time;    time_t cur_time;    Msg	*msg;    int len;    int cmgr_flag = 0;    time(&end_time);    if (timeout == 0)        timeout = 3;    end_time += timeout;    if (privdata->lines != NULL)        octstr_destroy(privdata->lines);    privdata->lines = octstr_create("");    while (time(&cur_time) <= end_time) {        O_DESTROY(line);        line = at2_read_line(privdata, gt_flag);        if (line) {            octstr_append(privdata->lines, line);            octstr_append_cstr(privdata->lines, "\n");            if (octstr_search(line, octstr_imm("SIM PIN"), 0) != -1) {                ret = 2;                goto end;            }            if (octstr_search(line, octstr_imm("OK"), 0) != -1) {                ret = 0;                goto end;            }            if ((gt_flag ) && (octstr_search(line, octstr_imm(">"), 0) != -1)) {                ret = 1;                goto end;            }            if (octstr_search(line, octstr_imm("RING"), 0) != -1) {                at2_write_line(privdata, "ATH0");                continue;            }            if (octstr_search(line, octstr_imm("+CPIN: READY"), 0) != -1) {                privdata->pin_ready = 1;                continue;            }            if ( -1 != octstr_search(line, octstr_imm("+CMS ERROR"), 0)) {                error(0, "AT2[%s]: CMS ERROR: %s", octstr_get_cstr(privdata->name),                       octstr_get_cstr(line));                ret = 1;                goto end;            }            if (octstr_search(line, octstr_imm("+CMT:"), 0) != -1 ||		octstr_search(line, octstr_imm("+CDS:"), 0) != -1 ||                ((octstr_search(line, octstr_imm("+CMGR:"), 0) != -1) && (cmgr_flag = 1)) ) {                line2 = at2_wait_line(privdata, 1, 0);                if (line2 == NULL) {                    error(0, "AT2[%s]: got +CMT but waiting for next line timed out",                           octstr_get_cstr(privdata->name));                } else {                    octstr_append_cstr(line, "\n");                    octstr_append(line, line2);                    O_DESTROY(line2);                    at2_pdu_extract(privdata, &pdu, line);                    if (pdu == NULL) {                        error(0, "AT2[%s]: got +CMT but pdu_extract failed",                               octstr_get_cstr(privdata->name));                    } else {                        /* count message even if I can't decode it */                        if (output)                            ++(*output);                        msg = at2_pdu_decode(pdu, privdata);                        if (msg != NULL) {                            msg->sms.smsc_id = octstr_duplicate(privdata->conn->id);                            bb_smscconn_receive(privdata->conn, msg);                        }                        if (!cmgr_flag) {                            if (privdata->phase2plus)                                at2_write_line(privdata, "AT+CNMA");                        }                        O_DESTROY(pdu);                    }                }                continue;            }            if ((octstr_search(line, octstr_imm("+CMGS:"),0) != -1) && (output)) {		/* found response to a +CMGS command, read the message id and return it in output */		long temp;		if (octstr_parse_long(&temp, line, octstr_search(line, octstr_imm("+CMGS:"),0)+6,10) == -1)		    error(0,"AT2[%s]: got +CMGS but failed to read message id", octstr_get_cstr(privdata->name));		else		    *output = temp;            }            if ( -1 != octstr_search(line, octstr_imm("ERROR"), 0)) {                ret = -1;                goto end;            }        }    }    len = octstr_len(privdata->ilb);    /*    error(0,"AT2[%s]: timeout. received <%s> until now, buffer size is %d, buf=%s",          octstr_get_cstr(privdata->name),          privdata->lines ? octstr_get_cstr(privdata->lines) : "<nothing>", len,          privdata->ilb ? octstr_get_cstr(privdata->ilb) : "<nothing>");    */    O_DESTROY(line);    O_DESTROY(line2);    O_DESTROY(pdu);    return -1; /* timeout */end:    octstr_append(privdata->lines, line);    octstr_append_cstr(privdata->lines, "\n");    O_DESTROY(line);    O_DESTROY(line2);    O_DESTROY(pdu);    return ret;}void at2_read_sms_memory(PrivAT2data* privdata){    char cmd[20];    /* get memory status */    if (at2_check_sms_memory(privdata) == -1) {        debug("bb.smsc.at2", 0, "AT2[%s]: memory check error", octstr_get_cstr(privdata->name));        return ;    }    if (privdata->sms_memory_usage) {         /*         * that is - greater then 0, meaning there are some messages to fetch         * now - I used to just loop over the first input_mem_sms_used locations,          * but it doesn't hold, since under load, messages may be received while          * we're in the loop, and get stored in locations towards the end of the list,          * thus creating 'holes' in the memory.          *          * There are two ways we can fix this :          *   (a) Just read the last message location, delete it and return.         *       It's not a complete solution since holes can still be created if messages          *       are recieved between the memory check and the delete command,          *       and anyway - it will slow us down and won't hold well under pressure         *   (b) Just scan the entire memory each call, bottom to top.          *       This will be slow too, but it'll be reliable.         *         * We can massivly improve performance by stopping after input_mem_sms_used messages         * have been read, but send_modem_command returns 0 for no message as well as for a          * message read, and the only other way to implement it is by doing memory_check          * after each read and stoping when input_mem_sms_used get to 0. This is slow          * (modem commands take time) so we improve speed only if there are less then 10          * messages in memory.         *         * I implemented the alternative - changed at2_wait_modem_command to return the          * number of messages it collected.         */        int i;        int message_count = 0; /* cound number of messages collected */        debug("bb.smsc.at2", 0, "AT2[%s]: %d messages waiting in memory",               octstr_get_cstr(privdata->name), privdata->sms_memory_usage);        /*         * loop till end of memory or collected enouch messages         */        for (i = 1; i <= privdata->sms_memory_capacity &&             message_count < privdata->sms_memory_usage; ++i) {             int old_message_count = message_count;            sprintf(cmd, "AT+CMGR=%d", i);            /* read one message from memory */            at2_write_line(privdata, cmd);            if (at2_wait_modem_command(privdata, 0, 0, &message_count) != 0) {                debug("bb.smsc.at2", 0, "AT2[%s]: failed to get message %d.",                       octstr_get_cstr(privdata->name), i);                continue; /* failed to read the message - skip to next message */            }            /* no need to delete if no message collected */            if (old_message_count == message_count) {                 debug("bb.smsc.at2", 0, "AT2[%s]: not deleted.",                       octstr_get_cstr(privdata->name));                continue;            }            sprintf(cmd, "AT+CMGD=%d", i); /* delete the message we just read */            /*              * 3 seconds is not enough with some modems if the message is large,             * so we'll give it 7 seconds              */            if (at2_send_modem_command(privdata, cmd, 7, 0) != 0) {                  /*                  * failed to delete the message, we'll just ignore it for now,                  * this is bad, since if the message really didn't get deleted                 * we'll see it next time around.                  */                                debug("bb.smsc.at2", 0, "AT2[%s]: failed to delete message %d.",                       octstr_get_cstr(privdata->name), i);                continue;             }        }    }    /*    at2_send_modem_command(privdata, ModemTypes[privdata->modemid].init1, 0, 0);    */}int at2_check_sms_memory(PrivAT2data *privdata){    long values[4]; /* array to put response data in */    int pos; /* position of parser in data stream */    int ret;    Octstr* search_cpms = NULL;    /* select memory type and get report */    if ((ret = at2_send_modem_command(privdata, "AT+CPMS?", 0, 0)) != 0) {         debug("bb.smsc.at2.memory_check", 0, "failed to send mem select command to modem %d", ret);        return -1;    }    search_cpms = octstr_create("+CPMS:");    if ((pos = octstr_search(privdata->lines, search_cpms, 0)) != -1) {        /* got back a +CPMS response */        int index = 0; /* index in values array */        pos += 6; /* position of parser in the stream - start after header */        /* skip memory indication */        pos = octstr_search(privdata->lines, octstr_imm(","), pos) + 1;         /* find all the values */        while (index < 4 && pos < octstr_len(privdata->lines) &&               (pos = octstr_parse_long(&values[index], privdata->lines, pos, 10)) != -1) {             ++pos; /* skip number seperator */            ++index; /* increment array index */            if (index == 2)                /* skip second memory indication */                pos = octstr_search(privdata->lines, octstr_imm(","), pos) + 1;         }        if (index < 4) {             /* didn't get all memory data - I don't why, so I'll bail */            debug("bb.smsc.at2", 0, "AT2[%s]: couldn't parse all memory locations : %d:'%s'.",                  octstr_get_cstr(privdata->name), index,                   &(octstr_get_cstr(privdata->lines)[pos]));            O_DESTROY(search_cpms);            return -1;        }        privdata->sms_memory_usage = values[0];        privdata->sms_memory_capacity = values[1];        /*        privdata->output_mem_sms_used = values[2];        privdata->output_mem_sms_capacity = values[3];        */        /* everything's cool */        ret = 0;         /*  clear the buffer */        O_DESTROY(privdata->lines);    } else {        debug("bb.smsc.at2", 0, "AT2[%s]: no correct header for CPMS response.",               octstr_get_cstr(privdata->name));        /* didn't get a +CPMS response - this is clearly an error */        ret = -1;     }    O_DESTROY(search_cpms);    return ret;}void at2_set_speed(PrivAT2data *privdata, int bps){    struct termios tios;    int ret;    int	speed;    tcgetattr(privdata->fd, &tios);    switch (bps) {    case 300:        speed = B300;        break;    case 1200:        speed = B1200;        break;    case 2400:        speed = B2400;        break;    case 4800:        speed = B4800;        break;    case 9600:        speed = B9600;        break;    case 19200:        speed = B19200;        break;    case 38400:        speed = B38400;        break;#ifdef B57600    case 57600:        speed = B57600;        break;#endif    default:        speed = B9600;    }    cfsetospeed(&tios, speed);    cfsetispeed(&tios, speed);    ret = tcsetattr(privdata->fd, TCSANOW, &tios); /* apply changes now */    if (ret == -1) {        error(errno, "AT2[%s]: at_data_link: fail to set termios attribute",              octstr_get_cstr(privdata->name));    }    tcflush(privdata->fd, TCIOFLUSH);    info(0, "AT2[%s]: speed set to %d", octstr_get_cstr(privdata->name), bps);}void at2_device_thread(void *arg)

⌨️ 快捷键说明

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