📄 smsc_at.c
字号:
gwthread_sleep(1); ++write_count; } else if (s > 0) { data_written += s; write_count = 0; } else break; } if (s < 0) { error(errno, "AT2[%s]: Couldnot write to device.", octstr_get_cstr(privdata->name)); tcflush(privdata->fd, TCOFLUSH); return s; } tcdrain(privdata->fd); gwthread_sleep((double) (privdata->modem == NULL ? 100 : privdata->modem->sendline_sleep) / 1000); return s;}static void at2_flush_buffer(PrivAT2data *privdata){ at2_read_buffer(privdata); octstr_destroy(privdata->ilb); privdata->ilb = octstr_create("");}static int at2_init_device(PrivAT2data *privdata){ int ret; Octstr *setpin; info(0, "AT2[%s]: init device", octstr_get_cstr(privdata->name)); at2_set_speed(privdata, privdata->speed); /* sleep 10 ms in order to get device some time to accept speed */ gwthread_sleep(0.10); /* reset the modem */ if (at2_send_modem_command(privdata, "ATZ", 0, 0) == -1) { error(0, "AT2[%s]: Wrong or no answer to ATZ, ignoring", octstr_get_cstr(privdata->name)); } /* check if the modem responded */ if (at2_send_modem_command(privdata, "AT", 0, 0) == -1) { error(0, "AT2[%s]: Wrong or no answer to AT. Trying again", octstr_get_cstr(privdata->name)); if (at2_send_modem_command(privdata, "AT", 0, 0) == -1) { error(0, "AT2[%s]: Second attempt to send AT failed", octstr_get_cstr(privdata->name)); return -1; } } at2_flush_buffer(privdata); if (at2_send_modem_command(privdata, "AT&F", 7, 0) == -1) { error(0, "AT2[%s]: No answer to AT&F. Trying again", octstr_get_cstr(privdata->name)); if (at2_send_modem_command(privdata, "AT&F", 7, 0) == -1) { return -1; } } at2_flush_buffer(privdata); /* check if the modem responded */ if (at2_send_modem_command(privdata, "ATE0", 0, 0) == -1) { error(0, "AT2[%s]: Wrong or no answer to ATE0. Trying again", octstr_get_cstr(privdata->name)); if (at2_send_modem_command(privdata, "ATE0", 0, 0) == -1) { error(0, "AT2[%s]: Second attempt to send ATE0 failed", octstr_get_cstr(privdata->name)); return -1; } } at2_flush_buffer(privdata); /* enable hardware handshake */ if (octstr_len(privdata->modem->enable_hwhs)) { if (at2_send_modem_command(privdata, octstr_get_cstr(privdata->modem->enable_hwhs), 0, 0) == -1) info(0, "AT2[%s]: cannot enable hardware handshake", octstr_get_cstr(privdata->name)); } /* * Check does the modem require a PIN and, if so, send it. * This is not supported by the Nokia Premicell */ if (!privdata->modem->no_pin) { ret = at2_send_modem_command(privdata, "AT+CPIN?", 10, 0); if (!privdata->pin_ready) { if (ret == 2) { if (privdata->pin == NULL) return -1; setpin = octstr_format("AT+CPIN=\"%s\"", octstr_get_cstr(privdata->pin)); ret = at2_send_modem_command(privdata, octstr_get_cstr(setpin), 0, 0); octstr_destroy(setpin); if (ret != 0 ) return -1; } else if (ret == -1) return -1; } /* * we have to wait until +CPIN: READY appears before issuing * the next command. 10 sec should be suficient */ if (!privdata->pin_ready) { at2_wait_modem_command(privdata, 10, 0, NULL); if (!privdata->pin_ready) { at2_send_modem_command(privdata, "AT+CPIN?", 10, 0); if (!privdata->pin_ready) { return -1; /* give up */ } } } } /* * Set the GSM SMS message center address if supplied */ if (octstr_len(privdata->sms_center)) { Octstr *temp; temp = octstr_create("AT+CSCA="); octstr_append_char(temp, 34); octstr_append(temp, privdata->sms_center); octstr_append_char(temp, 34); /* * XXX If some modem don't process the +, remove it and add ",145" * and ",129" to national numbers */ ret = at2_send_modem_command(privdata, octstr_get_cstr(temp), 0, 0); octstr_destroy(temp); if (ret == -1) return -1; if (ret > 0) { info(0, "AT2[%s]: Cannot set SMS message center, continuing", octstr_get_cstr(privdata->name)); } } /* 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 = gwlist_search(vals, octstr_imm("1"), (void*) octstr_item_match); if (ts) privdata->phase2plus = 1; gwlist_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 */ if (at2_set_message_storage(privdata, privdata->modem->message_storage) != 0) return -1; } info(0, "AT2[%s]: AT SMSC successfully opened.", octstr_get_cstr(privdata->name)); return 0;}static 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);}static int at2_wait_modem_command(PrivAT2data *privdata, time_t timeout, int gt_flag, int *output){ Octstr *line = NULL; Octstr *line2 = NULL; Octstr *pdu = NULL; Octstr *smsc_number = 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(""); smsc_number = octstr_create(""); while (time(&cur_time) <= end_time) { O_DESTROY(line); if ((line = at2_read_line(privdata, gt_flag))) { 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 (octstr_search(line, octstr_imm("+CMS ERROR"), 0) != -1) { int errcode; error(0, "AT2[%s]: CMS ERROR: %s", octstr_get_cstr(privdata->name), octstr_get_cstr(line)); if (sscanf(octstr_get_cstr(line), "+CMS ERROR: %d", &errcode) == 1) error(0, "AT2[%s]: CMS ERROR: %s (%d)", octstr_get_cstr(privdata->name), at2_error_string(errcode), errcode); ret = 1; goto end; } if (octstr_search(line, octstr_imm("+CMTI:"), 0) != -1 || octstr_search(line, octstr_imm("+CDSI:"), 0) != -1) { /* * we received an incoming message indication * put it in the pending_incoming_messages queue for later retrieval */ debug("bb.smsc.at2", 0, "AT2[%s]: +CMTI incoming SMS indication: %s", octstr_get_cstr(privdata->name), octstr_get_cstr(line)); gwlist_append(privdata->pending_incoming_messages, line); line = NULL; continue; } 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, smsc_number); 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); msg->sms.smsc_number = octstr_duplicate(smsc_number); bb_smscconn_receive(privdata->conn, msg); } else { error(0, "AT2[%s]: could not decode PDU to a message.", octstr_get_cstr(privdata->name)); } 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; } /* finally check if we received a generic error */ if (octstr_search(line, octstr_imm("ERROR"), 0) != -1) { int errcode; error(0, "AT2[%s]: Generic error: %s", octstr_get_cstr(privdata->name), octstr_get_cstr(line)); if (sscanf(octstr_get_cstr(line), "ERROR: %d", &errcode) == 1) error(0, "AT2[%s]: Generic error: %s (%d)", octstr_get_cstr(privdata->name), at2_error_string(errcode), errcode); 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); O_DESTROY(smsc_number); return -1; /* timeout */end: O_DESTROY(smsc_number); octstr_append(privdata->lines, line); octstr_append_cstr(privdata->lines, "\n"); O_DESTROY(line); O_DESTROY(line2); O_DESTROY(pdu); return ret;}static int at2_read_delete_message(PrivAT2data* privdata, int message_number){ char cmd[20]; int message_count = 0; sprintf(cmd, "AT+CMGR=%d", message_number); /* 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), message_number); return 0; /* failed to read the message - skip to next message */ } /* no need to delete if no message collected */ if (!message_count) { debug("bb.smsc.at2", 0, "AT2[%s]: not deleted.", octstr_get_cstr(privdata->name)); return 0; } sprintf(cmd, "AT+CMGD=%d", message_number); /* delete the message we just read */ /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -