📄 smsc_at.c
字号:
void at2_flush_buffer(PrivAT2data *privdata){ at2_read_buffer(privdata); octstr_destroy(privdata->ilb); privdata->ilb = octstr_create("");}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) return -1; /* check if the modem responded */ if (at2_send_modem_command(privdata, "AT", 0, 0) == -1) { error(0, "AT2[%s]: no answer from modem", octstr_get_cstr(privdata->name)); return -1; } at2_flush_buffer(privdata); if (at2_send_modem_command(privdata, "AT&F", 0, 0) == -1) return -1; if (at2_send_modem_command(privdata, "ATE0", 0, 0) == -1) 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 = 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 */ 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;}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("+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)); list_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); 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); } 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; } 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;}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 */ /* * 3 seconds (default timeout of send_modem_command()) 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. */ error(2, "AT2[%s]: failed to delete message %d.", octstr_get_cstr(privdata->name), message_number); } return 1;}/* * This function loops through the pending_incoming_messages queue for CMTI * notifications. * Every notification is parsed and the messages are read (and deleted) * accordingly.*/void at2_read_pending_incoming_messages(PrivAT2data* privdata){ Octstr *current_storage = NULL; if (privdata->modem->message_storage) { current_storage = octstr_duplicate(privdata->modem->message_storage); } while (list_len(privdata->pending_incoming_messages) > 0) { int pos; long location; Octstr *cmti_storage = NULL, *line = NULL; line = list_extract_first(privdata->pending_incoming_messages); /* message memory starts after the first quote in the string */ if ((pos = octstr_search_char(line, '"', 0)) != -1) { /* grab memory storage name */ int next_quote = octstr_search_char(line, '"', ++pos); if (next_quote == -1) { /* no second qoute - this line must be broken somehow */ O_DESTROY(line); continue; } /* store notification storage location for reference */ cmti_storage = octstr_copy(line, pos, next_quote - pos); } else /* reset pos for the next lookup which would start from the beginning if no memory * location was found */ pos = 0; /* if no message storage is set in configuration - set now */ if (!privdata->modem->message_storage && cmti_storage) { info(2, "AT2[%s]: CMTI received, but no message-storage is set in confiuration." "setting now to <%s>", octstr_get_cstr(privdata->name), octstr_get_cstr(cmti_storage)); privdata->modem->message_storage = octstr_duplicate(cmti_storage); current_storage = octstr_duplicate(cmti_storage); at2_set_message_storage(privdata, cmti_storage); } /* find the message id from the line, which should appear after the first comma */ if ((pos = octstr_search_char(line, ',', pos)) == -1) { /* this CMTI notification is probably broken */ error(2, "AT2[%s]: failed to find memory location in CMTI notification", octstr_get_cstr(privdata->name)); O_DESTROY(line); octstr_destroy(cmti_storage);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -