328
336
struct termios tio;
330
tcgetattr(modem_handle, &tio);
332
338
if (command && command[0])
334
if (tio.c_cflag & CRTSCTS)
336
ioctl(modem_handle, TIOCMGET, &status);
337
while (!(status & TIOCM_CTS))
341
ioctl(modem_handle, TIOCMGET, &status);
342
if (timeoutcounter>timeout)
345
printf("\nModem is not clear to send.\n");
348
writelogfile0(LOG_ERR, 1, tb_sprintf("Modem is not clear to send"));
349
alarm_handler0(LOG_ERR, tb);
356
341
writelogfile(LOG_DEBUG, 0, "-> %s",command);
359
if (DEVICE.send_delay < 1)
344
if (DEVICE.send_handshake_select)
361
if (write(modem_handle, command, strlen(command)) != strlen(command))
363
writelogfile0(LOG_ERR, 1, tb_sprintf("Could not send string, cause: %s", strerror(errno)));
364
alarm_handler0(LOG_ERR, tb);
353
bs = (DEVICE.send_delay < 1) ? n : 1;
354
got = write(modem_handle, command + r, bs);
362
writelogfile0(LOG_ERR, 1, tb_sprintf("write_to_modem: error %d: %s", errno, strerror(errno)));
363
alarm_handler0(LOG_ERR, tb);
367
writelogfile0(LOG_DEBUG, 0, tb_sprintf("write_to_modem: device busy, waiting"));
368
alarm_handler0(LOG_DEBUG, tb);
370
FD_SET(modem_handle, &writefds);
371
select(modem_handle + 1, NULL, &writefds, NULL, NULL);
378
if (DEVICE.send_delay > 0)
379
usleep(DEVICE.send_delay * 1000);
381
tcdrain(modem_handle);
368
if (DEVICE.send_delay < 0)
369
tcdrain(modem_handle);
373
for(x=0;x<strlen(command);x++)
386
tcgetattr(modem_handle, &tio);
388
if (!DEVICE_IS_SOCKET && tio.c_cflag & CRTSCTS)
375
if (write(modem_handle, command +x, 1) < 1)
390
ioctl(modem_handle, TIOCMGET, &status);
391
while (!(status & TIOCM_CTS))
378
printf("\nCould not send character %c, cause: %s\n",command[x],strerror(errno));
395
ioctl(modem_handle, TIOCMGET, &status);
396
if (timeoutcounter>timeout)
381
writelogfile0(LOG_ERR, 1, tb_sprintf("Could not send character %c, cause: %s", command[x], strerror(errno)));
382
alarm_handler0(LOG_ERR, tb);
399
printf("\nModem is not clear to send.\n");
402
writelogfile0(LOG_ERR, 1, tb_sprintf("Modem is not clear to send"));
403
alarm_handler0(LOG_ERR, tb);
411
if (DEVICE.send_delay < 1)
413
if ((size_t)write(modem_handle, command, strlen(command)) != strlen(command))
415
writelogfile0(LOG_ERR, 1, tb_sprintf("Could not send string, cause: %s", strerror(errno)));
416
alarm_handler0(LOG_ERR, tb);
386
usleep(DEVICE.send_delay *1000);
387
tcdrain(modem_handle);
420
if (DEVICE.send_delay < 0)
421
tcdrain(modem_handle);
425
for(x=0;(size_t)x<strlen(command);x++)
427
if (write(modem_handle, command +x, 1) < 1)
430
printf("\nCould not send character %c, cause: %s\n",command[x],strerror(errno));
433
writelogfile0(LOG_ERR, 1, tb_sprintf("Could not send character %c, cause: %s", command[x], strerror(errno)));
434
alarm_handler0(LOG_ERR, tb);
438
usleep(DEVICE.send_delay *1000);
439
tcdrain(modem_handle);
649
void handlephonecall_clip(char *answer)
651
char *p, *e_start, *e_end;
653
char entry_number[SIZE_PB_ENTRY];
659
if ((p = strstr(answer, "+CLIP:")))
661
if ((e_start = strchr(p, '"')))
664
if ((e_end = strchr(e_start, '"')))
666
if ((len = e_end -e_start) < SIZE_PB_ENTRY)
668
sprintf(entry_number, "%.*s", len, e_start);
669
cutspaces(entry_number);
670
if (*entry_number == '+')
671
memmove(entry_number, entry_number +1, strlen(entry_number +1) +1);
673
if (strlen(e_end) >= 3)
676
writelogfile(LOG_INFO, 0, "Got phonecall from %s", entry_number);
677
savephonecall(entry_number, atoi(e_end), "");
564
685
// 3.1beta7: Not waiting any answer if answer is NULL. Return value is then 1/0.
565
686
// 3.1.5: In case of timeout return value is -2.
566
688
int put_command(char *command, char *answer, int max, int timeout_count, char *expect)
691
return put_command0(command, answer, max, timeout_count, expect, 0);
694
int put_command0(char *command, char *answer, int max, int timeout_count, char *expect, int silent)
568
696
char loganswer[SIZE_LOG_LINE];
697
char tmpanswer[SIZE_LOG_LINE];
569
698
int timeoutcounter = 0;
571
700
int got_timeout = 0;
606
735
if (!i && *loganswer && DEVICE.detect_unexpected_input)
608
cutspaces(loganswer);
609
cut_emptylines(loganswer);
739
cutspaces(loganswer);
740
cut_emptylines(loganswer);
611
if (log_single_lines)
612
change_crlf(loganswer, ' ');
742
if (log_single_lines)
743
change_crlf(loganswer, ' ');
616
748
// Some modems send unsolicited result code even when status report is stored for future
617
749
// reading. This and SMS-DELIVER indication is not logged.
618
750
if (!strstr(loganswer, "+CDSI:") && !strstr(loganswer, "+CMTI:"))
619
writelogfile(LOG_ERR, DEVICE.unexpected_input_is_trouble, "Unexpected input: %s", loganswer);
751
if (!(strstr(loganswer, "+CLIP:") && DEVICE.phonecalls == 2))
752
writelogfile(LOG_ERR, DEVICE.unexpected_input_is_trouble, "Unexpected input: %s", loganswer);
621
754
if (strstr(loganswer, "RING"))
623
756
if (DEVICE.hangup_incoming_call == 1 ||
624
(DEVICE.hangup_incoming_call == -1 && hangup_incoming_call == 1))
757
(DEVICE.hangup_incoming_call == -1 && hangup_incoming_call == 1) ||
758
DEVICE.phonecalls == 2)
626
760
char *command = "AT+CHUP\r";
628
if (DEVICE.voicecall_hangup_ath)
762
if (DEVICE.voicecall_hangup_ath == 1 ||
763
(DEVICE.voicecall_hangup_ath == -1 && voicecall_hangup_ath == 1))
629
764
command = "ATH\r";
631
766
writelogfile(LOG_NOTICE, 0, "Ending incoming call: %s", loganswer);
954
1128
writelogfile(LOG_INFO, 0, "Checking if modem needs PIN");
955
1129
// 3.1.5: timeout from 50 to 100:
956
1130
put_command("AT+CPIN?\r", answer, sizeof(answer), 2, cpin_expect);
1132
// 3.1.7: Some modems include quotation marks in the answer, like +CPIN: "READY".
1133
while ((p = strchr(answer, '"')))
1134
memmove(p, p +1, strlen(p +1) +1);
1136
// 3.1.7: Some modems may leave a space away after +CPIN:
1137
if (!strncmp(answer, "+CPIN:", 6) && strncmp(answer, "+CPIN: ", 7))
1139
if ((p = strdup(answer)))
1141
snprintf(answer, sizeof(answer), "+CPIN: %s", p + 6);
957
1146
if (strstr(answer,"+CPIN: SIM PIN") && !strstr(answer, "PIN2"))
1238
1438
// -----------------------------------------------------------------------------------------------
1439
// 3.1.7: Report details of device once:
1440
if (DEVICE.report_device_details)
1442
int save_log_single_lines = log_single_lines;
1445
char *commands[] = {
1446
"AT+CGMI", "Manufacturer identification",
1447
"AT+CGMM", "Model identification",
1448
"AT+CGMR", "Revision identification",
1449
"AT+CNMI=?", "New message indications, list of supported modes",
1450
"AT+CNMI?", "New message indications, current settings",
1451
"AT+CPMS=?", "Preferred message storage, list of supported mem's",
1452
//"AT+CPMS?", "Preferred message storage, current mem's and counters",
1453
"AT+CPBS=?", "Phonebook storage, available mem's",
1454
//"AT+CPBS?", "Phonebook storage, current storage and counters",
1455
"AT+CMGL=?", "List messages, list of supported stat's",
1456
"AT+CMGD=?", "Delete message, list of supported values",
1457
"AT+CPAS=?", "Phone activity status, list of supported stat's",
1458
"AT+CSCS=?", "TE character set, list of supported charset's",
1459
"AT+CSCS?", "TE character set, current setting",
1463
DEVICE.report_device_details = 0;
1464
log_single_lines = 0;
1465
change_loglevel(LOG_DEBUG);
1467
writelogfile(LOG_DEBUG, 0, "## Start of device details");
1469
for (i = 0; commands[i][0]; i += 2)
1474
snprintf(tmp, sizeof(tmp), "# %s:", commands[i + 1]);
1475
writelogfile(LOG_DEBUG, 0, tmp);
1476
sprintf(command, "%s\r", commands[i]);
1477
put_command0(command, answer, sizeof(answer), 1, "(OK)|(ERROR)", 1);
1480
writelogfile(LOG_DEBUG, 0, "## End of device details");
1482
log_single_lines = save_log_single_lines;
1486
// -----------------------------------------------------------------------------------------------
1239
1487
// TODO: Check if AT+CMGD=? is supported.
1251
1499
return initmodem("", 1);
1502
#ifndef DISABLE_INET_SOCKET
1504
/* Start Changes by Hubert Gilch, SEP Logistik AG
1506
* 2 functions for connecting to a socket instead of a serial device
1507
* in order to use ethernet GPRS-modems
1509
* Code was "stolen" from interceptty by Scott W. Gifford
1513
struct sockaddr_in inet_resolve(const char *sockname)
1515
struct sockaddr_in sa;
1516
char *hostname, *netport;
1519
if (!(hostname = strdup(sockname)))
1520
writelogfile(LOG_CRIT, 0, "Couldn't dup string: %s", strerror(errno));
1522
netport = strchr(hostname, ':');
1526
sa.sin_family = AF_INET;
1528
if (!(he = gethostbyname(hostname)))
1529
writelogfile(LOG_ERR, 0, "Couldn't resolve name '%s': %s.", hostname,
1530
(h_errno == HOST_NOT_FOUND) ? "Host not found" :
1531
((h_errno == NO_ADDRESS) || (h_errno == NO_DATA)) ? "No data available" :
1532
(h_errno == NO_RECOVERY) ? "A non-recoverable name server error occured" : (h_errno == TRY_AGAIN) ? "A temporary error occured." : "An unknown error occured");
1534
memcpy(&(sa.sin_addr), he->h_addr, he->h_length);
1537
if (!(se = getservbyname(netport)))
1538
writelogfile(LOG_ERR, 0, "Couldn't resolve port.");
1540
host_port = htons(se->s_port);
1543
if (!(sa.sin_port = htons(atoi(netport))))
1544
writelogfile(LOG_ERR, 0, "Couldn't figure out port number.");
1551
int open_inet_socket(char *backend)
1553
struct sockaddr_in sa;
1558
sa = inet_resolve(backend + 1); // cut first character @
1559
if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 3)
1561
tb_sprintf("Couldn't open socket: %s: %s", backend, strerror(errno));
1562
writelogfile0(LOG_ERR, 0, tb);
1563
alarm_handler0(LOG_ERR, tb);
1567
while (connect(fd, (struct sockaddr *) &sa, sizeof(sa)) != 0)
1571
if (terminate || (DEVICE.socket_connection_retries != -1 && retries > DEVICE.socket_connection_retries))
1574
return (terminate)? -2 : -1;
1577
tb_sprintf("Couldn't connect socket %s, error: %s, waiting %i sec.", backend, strerror(errno), DEVICE.socket_connection_errorsleeptime);
1579
if (retries - 1 == DEVICE.socket_connection_alarm_after)
1581
writelogfile0(LOG_ERR, 0, tb);
1582
alarm_handler0(LOG_ERR, tb);
1586
// Do not log the first failure:
1588
writelogfile(LOG_INFO, 0, tb);
1591
sleep(DEVICE.socket_connection_errorsleeptime);
1594
socketflags = fcntl(fd, F_GETFL);
1595
fcntl(fd, F_SETFL, socketflags | O_NONBLOCK);
1601
* End Changes by Hubert Gilch
1254
1606
int openmodem()
1257
modem_handle = open(DEVICE.device, O_RDWR | O_NOCTTY | O_NONBLOCK);
1611
//modem_handle = open(DEVICE.device, O_RDWR | O_NOCTTY | O_NONBLOCK);
1614
* if devicename starts with "@" it is not a serial device but
1615
* a socket, so open a socket instead a device file
1617
* Change by Hubert Gilch, SEP Logistik AG
1619
#ifndef DISABLE_INET_SOCKET
1620
if (DEVICE_IS_SOCKET)
1621
modem_handle = open_inet_socket(DEVICE.device);
1625
while ((modem_handle = open(DEVICE.device, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0)
1629
if (terminate || (DEVICE.device_open_retries != -1 && retries > DEVICE.device_open_retries))
1632
tb_sprintf("Couldn't open serial port %s, error: %s, waiting %i sec.", DEVICE.device, strerror(errno), DEVICE.device_open_errorsleeptime);
1634
if (retries - 1 == DEVICE.device_open_alarm_after)
1636
writelogfile0(LOG_ERR, 0, tb);
1637
alarm_handler0(LOG_ERR, tb);
1640
writelogfile(LOG_INFO, 0, tb);
1642
sleep(DEVICE.device_open_errorsleeptime);
1258
1645
if (modem_handle < 0)
1260
writelogfile0(LOG_ERR, 1, tb_sprintf("Cannot open serial port %s, error: %s",
1261
DEVICE.device, strerror(errno)));
1262
alarm_handler0(LOG_ERR, tb);
1647
if (modem_handle == -1)
1649
writelogfile0(LOG_ERR, 1, tb_sprintf((DEVICE_IS_SOCKET)? "Cannot open socket %s, error: %s" : "Cannot open serial port %s, error: %s", DEVICE.device, strerror(errno)));
1650
alarm_handler0(LOG_ERR, tb);
1265
1655
if (strstr(smsd_version, "beta"))
1266
writelogfile(LOG_INFO, 0, "Serial port %s opened as %i, rtscts: %i, baudrate: %i",
1267
DEVICE.device, modem_handle, DEVICE.rtscts, DEVICE.baudrate);
1657
if (DEVICE_IS_SOCKET)
1658
writelogfile(LOG_INFO, 0, "Socket %s opened as %i", DEVICE.device, modem_handle);
1660
writelogfile(LOG_INFO, 0, "Serial port %s opened as %i, rtscts: %i, baudrate: %i", DEVICE.device, modem_handle, DEVICE.rtscts, DEVICE.baudrate);
1268
1663
return modem_handle;