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

📄 smsc_at.c

📁 gateway-1.3.2.tar.gz WAP gw code
💻 C
📖 第 1 页 / 共 5 页
字号:
            continue;        }        if ((pos = octstr_parse_long(&location, line, ++pos, 10)) == -1) {            /* there was an error parsing the message id. next! */            error(2, "AT2[%s]: error parsing memory location in CMTI notification",                octstr_get_cstr(privdata->name));		O_DESTROY(line);		octstr_destroy(cmti_storage);            continue;        }        /* check if we need to change storage location before issuing the read command */        if (!current_storage || (octstr_compare(current_storage, cmti_storage) != 0)) {	    octstr_destroy(current_storage);	    current_storage = octstr_duplicate(cmti_storage);            at2_set_message_storage(privdata, cmti_storage);	}                if (!at2_read_delete_message(privdata, location)) {            error(1,"AT2[%s]: CMTI notification received, but no message found in memory!",                octstr_get_cstr(privdata->name));        }                octstr_destroy(line);        octstr_destroy(cmti_storage);    }    /* set prefered message storage back to what configured */    if (current_storage && privdata->modem->message_storage && (octstr_compare(privdata->modem->message_storage, current_storage) != 0))	at2_set_message_storage(privdata, privdata->modem->message_storage);    octstr_destroy(current_storage);}static int at2_read_sms_memory(PrivAT2data* privdata){    /* 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 -1;    }    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) { 	    /* if (meanwhile) there are pending CMTI notifications, process these first	     * to not let CMTI and sim buffering sit in each others way */	    while (list_len(privdata->pending_incoming_messages) > 0) {		    at2_read_pending_incoming_messages(privdata);	    }	    /* read the message and delete it */            message_count += at2_read_delete_message(privdata, i);        }    }    /*    at2_send_modem_command(privdata, ModemTypes[privdata->modemid].init1, 0, 0);    */    return 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#ifdef B115200    case 115200:        speed = B115200;        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){    SMSCConn *conn = arg;    PrivAT2data	*privdata = conn->data;    int l, reconnecting = 0, error_count = 0;    long idle_timeout, memory_poll_timeout = 0;    conn->status = SMSCCONN_CONNECTING;    /* Make sure we log into our own log-file if defined */    log_thread_to(conn->log_idx);reconnect:    do {        if (reconnecting) {            if (conn->status == SMSCCONN_ACTIVE) {                mutex_lock(conn->flow_mutex);                conn->status = SMSCCONN_RECONNECTING;                mutex_unlock(conn->flow_mutex);            }            error(0, "AT2[%s]: Couldn't connect (retrying in %ld seconds).",                     octstr_get_cstr(privdata->name), conn->reconnect_delay);            gwthread_sleep(conn->reconnect_delay);        }        /* 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 && at2_detect_speed(privdata) == -1) {            continue;        }        if (privdata->modem == NULL && at2_detect_modem_type(privdata) == -1) {            continue;        }        if (at2_open_device(privdata)) {            error(errno, "AT2[%s]: at2_device_thread: open_at2_device failed. Terminating",                   octstr_get_cstr(privdata->name));            continue;        }        if (privdata->max_error_count > 0 && error_count > privdata->max_error_count &&             privdata->modem != NULL && privdata->modem->reset_string != NULL) {            error_count = 0;            if (at2_send_modem_command(privdata,                 octstr_get_cstr(privdata->modem->reset_string), 0, 0) != 0) {                error(0, "AT2[%s]: Reset of modem failed.", octstr_get_cstr(privdata->name));                at2_close_device(privdata);                continue;            }            else {                info(0, "AT2[%s]: Modem reseted.", octstr_get_cstr(privdata->name));            }        }        if (at2_init_device(privdata) != 0) {            error(0, "AT2[%s]: Opening failed. Terminating", octstr_get_cstr(privdata->name));            at2_close_device(privdata);            error_count++;            continue;        }        else            error_count = 0;        /* If we got here, then the device is opened */        break;    } while (!privdata->shutdown);    mutex_lock(conn->flow_mutex);    conn->status = SMSCCONN_ACTIVE;    conn->connect_time = time(NULL);    mutex_unlock(conn->flow_mutex);    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);	while (list_len(privdata->pending_incoming_messages) > 0) {		at2_read_pending_incoming_messages(privdata);	}        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);                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);    list_destroy(privdata->outgoing_queue, NULL);    list_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();}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, NULL);        }    }    gwthread_wakeup(privdata->device_thread);    return 0;}

⌨️ 快捷键说明

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