~ubuntu-branches/debian/jessie/smstools/jessie

« back to all changes in this revision

Viewing changes to src/modeminit.c

  • Committer: Bazaar Package Importer
  • Author(s): Jan Wagner
  • Date: 2010-06-21 10:19:52 UTC
  • mfrom: (1.1.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20100621101952-pz5h5zctan8vumbi
Tags: 3.1.10-0.1
* Non-maintainer upload, as requested by maintainer
* New Upstream version (Closes: #586643)
* Bump Standards to 3.8.4, no changes needed
* Define source format 1.0 in debian/source/format
* Add $remote_fs as dependency for Required-Start and Required-Stop in the
  init script, removed $local_fs, which is implicit

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
#include <syslog.h>
36
36
#include <sys/ioctl.h>
37
37
#include <errno.h>
 
38
 
 
39
#ifndef DISABLE_INET_SOCKET
 
40
// HG
 
41
#include <sys/socket.h>
 
42
#include <netinet/in.h>
 
43
#include <netdb.h>
 
44
#endif
 
45
 
38
46
#include "extras.h"
39
47
#include "modeminit.h"
40
48
#include "smsd_cfg.h"
327
335
  int x=0;
328
336
  struct termios tio;
329
337
 
330
 
  tcgetattr(modem_handle, &tio);
331
 
 
332
338
  if (command && command[0])
333
339
  {
334
 
    if (tio.c_cflag & CRTSCTS)
335
 
    {
336
 
      ioctl(modem_handle, TIOCMGET, &status);
337
 
      while (!(status & TIOCM_CTS))
338
 
      {
339
 
        usleep(100000);
340
 
        timeoutcounter++;
341
 
        ioctl(modem_handle, TIOCMGET, &status);
342
 
        if (timeoutcounter>timeout)
343
 
        {
344
 
          if (print_error)
345
 
            printf("\nModem is not clear to send.\n");
346
 
          else
347
 
          {
348
 
            writelogfile0(LOG_ERR, 1, tb_sprintf("Modem is not clear to send"));
349
 
            alarm_handler0(LOG_ERR, tb);
350
 
          }
351
 
          return 0;
352
 
        }
353
 
      }
354
 
    }
355
340
    if (log_command)
356
341
      writelogfile(LOG_DEBUG, 0, "-> %s",command);
357
342
 
358
 
    // 3.1.5:
359
 
    if (DEVICE.send_delay < 1)
 
343
    // 3.1.9:
 
344
    if (DEVICE.send_handshake_select)
360
345
    {
361
 
      if (write(modem_handle, command, strlen(command)) != strlen(command))
 
346
      size_t r = 0, bs, n;
 
347
      ssize_t got;
 
348
      fd_set writefds;
 
349
 
 
350
      n = strlen(command);
 
351
      while (n > 0)
362
352
      {
363
 
        writelogfile0(LOG_ERR, 1, tb_sprintf("Could not send string, cause: %s", strerror(errno)));
364
 
        alarm_handler0(LOG_ERR, tb);
365
 
        return 0;
 
353
        bs = (DEVICE.send_delay < 1) ? n : 1;
 
354
        got = write(modem_handle, command + r, bs);
 
355
        if (got < 0)
 
356
        {
 
357
          if (errno == EINTR)
 
358
            continue;
 
359
 
 
360
          if (errno != EAGAIN)
 
361
          {
 
362
            writelogfile0(LOG_ERR, 1, tb_sprintf("write_to_modem: error %d: %s", errno, strerror(errno)));
 
363
            alarm_handler0(LOG_ERR, tb);
 
364
            return 0;
 
365
          }
 
366
 
 
367
          writelogfile0(LOG_DEBUG, 0, tb_sprintf("write_to_modem: device busy, waiting"));
 
368
          alarm_handler0(LOG_DEBUG, tb);
 
369
          FD_ZERO(&writefds);
 
370
          FD_SET(modem_handle, &writefds);
 
371
          select(modem_handle + 1, NULL, &writefds, NULL, NULL);
 
372
          continue;
 
373
        }
 
374
 
 
375
        n -= got;
 
376
        r += got;
 
377
 
 
378
        if (DEVICE.send_delay > 0)
 
379
          usleep(DEVICE.send_delay * 1000);
 
380
 
 
381
        tcdrain(modem_handle);
366
382
      }
367
 
 
368
 
      if (DEVICE.send_delay < 0)
369
 
        tcdrain(modem_handle);
370
383
    }
371
384
    else
372
385
    {
373
 
      for(x=0;x<strlen(command);x++)
 
386
      tcgetattr(modem_handle, &tio);
 
387
 
 
388
      if (!DEVICE_IS_SOCKET && tio.c_cflag & CRTSCTS)
374
389
      {
375
 
        if (write(modem_handle, command +x, 1) < 1)
 
390
        ioctl(modem_handle, TIOCMGET, &status);
 
391
        while (!(status & TIOCM_CTS))
376
392
        {
377
 
          if (print_error)
378
 
            printf("\nCould not send character %c, cause: %s\n",command[x],strerror(errno));
379
 
          else
 
393
          usleep(100000);
 
394
          timeoutcounter++;
 
395
          ioctl(modem_handle, TIOCMGET, &status);
 
396
          if (timeoutcounter>timeout)
380
397
          {
381
 
            writelogfile0(LOG_ERR, 1, tb_sprintf("Could not send character %c, cause: %s", command[x], strerror(errno)));
382
 
            alarm_handler0(LOG_ERR, tb);
 
398
            if (print_error)
 
399
              printf("\nModem is not clear to send.\n");
 
400
            else
 
401
            {
 
402
              writelogfile0(LOG_ERR, 1, tb_sprintf("Modem is not clear to send"));
 
403
              alarm_handler0(LOG_ERR, tb);
 
404
            }
 
405
            return 0;
383
406
          }
 
407
        }
 
408
      }
 
409
 
 
410
      // 3.1.5:
 
411
      if (DEVICE.send_delay < 1)
 
412
      {
 
413
        if ((size_t)write(modem_handle, command, strlen(command)) != strlen(command))
 
414
        {
 
415
          writelogfile0(LOG_ERR, 1, tb_sprintf("Could not send string, cause: %s", strerror(errno)));
 
416
          alarm_handler0(LOG_ERR, tb);
384
417
          return 0;
385
418
        }
386
 
        usleep(DEVICE.send_delay *1000);
387
 
        tcdrain(modem_handle);
 
419
 
 
420
        if (DEVICE.send_delay < 0)
 
421
          tcdrain(modem_handle);
 
422
      }
 
423
      else
 
424
      {
 
425
        for(x=0;(size_t)x<strlen(command);x++)
 
426
        {
 
427
          if (write(modem_handle, command +x, 1) < 1)
 
428
          {
 
429
            if (print_error)
 
430
              printf("\nCould not send character %c, cause: %s\n",command[x],strerror(errno));
 
431
            else
 
432
              {
 
433
              writelogfile0(LOG_ERR, 1, tb_sprintf("Could not send character %c, cause: %s", command[x], strerror(errno)));
 
434
              alarm_handler0(LOG_ERR, tb);
 
435
            }
 
436
            return 0;
 
437
          }
 
438
          usleep(DEVICE.send_delay *1000);
 
439
          tcdrain(modem_handle);
 
440
        }
388
441
      }
389
442
    }
390
443
  }
 
444
 
391
445
  return 1;
392
446
}
393
447
 
425
479
    }
426
480
    else  
427
481
    {
 
482
      // 3.1.9
 
483
#ifdef DEBUGMSG
 
484
      log_read_from_modem = 1;
 
485
#endif
 
486
      if (log_read_from_modem)
 
487
      {
 
488
        char tmp[SIZE_LOG_LINE];
 
489
        int i;
 
490
 
 
491
        snprintf(tmp, sizeof(tmp), "read_from_modem: count=%i, got=%i:", count, got);
 
492
        for (i = count; i < count + got; i++)
 
493
        {
 
494
          if (strlen(tmp) >= sizeof(tmp) - 6)
 
495
          {
 
496
            strcpy(tmp, "ERROR: too much data");
 
497
            break;
 
498
          }
 
499
 
 
500
          sprintf(strchr(tmp, 0), " %02X[%c]", (unsigned char) answer[i], ((unsigned char) answer[i] >= ' ') ? answer[i] : '.');
 
501
        }
 
502
 
 
503
        writelogfile(LOG_CRIT, 0, tmp);
 
504
      }
 
505
 
428
506
      // restart timout counter
429
507
      timeoutcounter=0;
430
508
      // append a string termination character
477
555
 
478
556
    if (p1)
479
557
    {
480
 
      writelogfile(LOG_ERR, DEVICE.unexpected_input_is_trouble, "Routed %s detected:\n%s", (is_sr)? "status report" : "message", p1);
481
 
      send_ack = 1;
 
558
      if (!is_sr || !DEVICE.using_routed_status_report)
 
559
        writelogfile(LOG_ERR, DEVICE.unexpected_input_is_trouble, "Routed %s detected:\n%s", (is_sr) ? "status report" : "message", p1);
 
560
 
 
561
      if (DEVICE.routed_status_report_cnma)
 
562
        send_ack = 1;
482
563
 
483
564
      while (p1)
484
565
      {
523
604
        p = (is_sr)? "status report" : "message";
524
605
        if (can_handle)
525
606
        {
526
 
          writelogfile0(LOG_ERR, 0, tb_sprintf("Saved routed %s for later handling. However, you MUST DISABLE %s routing with modem settings.", p, p));
527
 
          alarm_handler0(LOG_ERR, tb);
 
607
          if (is_sr && DEVICE.using_routed_status_report)
 
608
            writelogfile0(LOG_INFO, 0, tb_sprintf("Saved routed %s for later handling.", p));
 
609
          else
 
610
          {
 
611
            writelogfile0(LOG_ERR, 0, tb_sprintf("Saved routed %s for later handling. However, you MUST DISABLE %s routing with modem settings.", p, p));
 
612
            alarm_handler0(LOG_ERR, tb);
 
613
          }
528
614
        }
529
615
        else
530
616
        {
546
632
      char loganswer[1024];
547
633
 
548
634
      writelogfile(LOG_DEBUG, 0, "Sending acknowledgement");
549
 
      if (write_to_modem("AT+CNMA\r", 30, 1, 0) == 0)
550
 
        ;
 
635
      write_to_modem("AT+CNMA\r", 30, 1, 0);
551
636
 
552
637
      *loganswer = 0;
553
638
      read_from_modem(loganswer, sizeof(loganswer), 2);
561
646
  return result;
562
647
}
563
648
 
 
649
void handlephonecall_clip(char *answer)
 
650
{
 
651
        char *p, *e_start, *e_end;
 
652
        int len;
 
653
        char entry_number[SIZE_PB_ENTRY];
 
654
        int entry_type;
 
655
 
 
656
        *entry_number = 0;
 
657
        entry_type = 0;
 
658
 
 
659
        if ((p = strstr(answer, "+CLIP:")))
 
660
        {
 
661
                if ((e_start = strchr(p, '"')))
 
662
                {
 
663
                        e_start++;
 
664
                        if ((e_end = strchr(e_start, '"')))
 
665
                        {
 
666
                                if ((len = e_end -e_start) < SIZE_PB_ENTRY)
 
667
                                {
 
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);
 
672
 
 
673
                                        if (strlen(e_end) >= 3)
 
674
                                        {
 
675
                                                e_end += 2;
 
676
                                                writelogfile(LOG_INFO, 0, "Got phonecall from %s", entry_number);
 
677
                                                savephonecall(entry_number, atoi(e_end), "");
 
678
                                        }
 
679
                                }
 
680
                        }
 
681
                }
 
682
        }
 
683
}
 
684
 
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.
 
687
 
566
688
int put_command(char *command, char *answer, int max, int timeout_count, char *expect)
567
689
{
 
690
 
 
691
  return put_command0(command, answer, max, timeout_count, expect, 0);
 
692
}
 
693
 
 
694
int put_command0(char *command, char *answer, int max, int timeout_count, char *expect, int silent)
 
695
{
568
696
  char loganswer[SIZE_LOG_LINE];
 
697
  char tmpanswer[SIZE_LOG_LINE];
569
698
  int timeoutcounter = 0;
570
699
  regex_t re;
571
700
  int got_timeout = 0;
605
734
 
606
735
    if (!i && *loganswer && DEVICE.detect_unexpected_input)
607
736
    {
608
 
      cutspaces(loganswer);
609
 
      cut_emptylines(loganswer);
 
737
      if (!log_unmodified)
 
738
      {
 
739
        cutspaces(loganswer);
 
740
        cut_emptylines(loganswer);
610
741
 
611
 
      if (log_single_lines)
612
 
        change_crlf(loganswer, ' ');
 
742
        if (log_single_lines)
 
743
          change_crlf(loganswer, ' ');
 
744
      }
613
745
 
614
746
      if (*loganswer)
615
747
      {
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);
620
753
 
621
754
        if (strstr(loganswer, "RING"))
622
755
        {
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)
625
759
          {
626
760
            char *command = "AT+CHUP\r";
627
761
 
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";
630
765
 
631
766
            writelogfile(LOG_NOTICE, 0, "Ending incoming call: %s", loganswer);
633
768
            write_to_modem(command, 30, 1, 0);
634
769
 
635
770
            timeoutcounter = 0;
636
 
            *loganswer = 0;
 
771
            *tmpanswer = 0;
637
772
 
638
773
            do
639
774
            {
640
 
              read_from_modem(loganswer, sizeof(loganswer), 2);  // One read attempt is 200ms
 
775
              read_from_modem(tmpanswer, sizeof(tmpanswer), 2);  // One read attempt is 200ms
641
776
 
642
777
              // Any answer is ok:
643
 
              if (*loganswer)
 
778
              if (*tmpanswer)
644
779
                break;
645
780
 
646
781
              timeoutcounter++;;
647
782
            }
648
783
            while (timeoutcounter < 5);
649
784
 
650
 
            cutspaces(loganswer);
651
 
            cut_emptylines(loganswer);
652
 
 
653
 
            if (log_single_lines)
654
 
              change_crlf(loganswer, ' ');
655
 
 
656
 
            writelogfile(LOG_DEBUG, 0, "<- %s", loganswer);
 
785
            if (!log_unmodified)
 
786
            {
 
787
              cutspaces(tmpanswer);
 
788
              cut_emptylines(tmpanswer);
 
789
 
 
790
              if (log_single_lines)
 
791
                change_crlf(tmpanswer, ' ');
 
792
            }
 
793
 
 
794
            writelogfile(LOG_DEBUG, 0, "<- %s", tmpanswer);
657
795
 
658
796
            last_command_ended = time_usec();
659
797
 
662
800
                usleep_until(last_command_ended +DEVICE.communication_delay *1000);
663
801
          }
664
802
        }
 
803
 
 
804
        if (strstr(loganswer, "+CLIP:") && DEVICE.phonecalls == 2)
 
805
                handlephonecall_clip(loganswer);
 
806
 
665
807
      }
666
808
    }
667
809
  }
685
827
  }
686
828
 
687
829
  if (!answer)
688
 
    writelogfile(LOG_DEBUG, 0, "Command is sent");
 
830
  {
 
831
    if (!silent)
 
832
      writelogfile(LOG_DEBUG, 0, "Command is sent");
 
833
  }
689
834
  else
690
835
  {
691
 
    writelogfile(LOG_DEBUG, 0, "Command is sent, waiting for the answer");
 
836
    if (!silent)
 
837
      writelogfile(LOG_DEBUG, 0, "Command is sent, waiting for the answer");
692
838
 
693
839
    // wait for the modem-answer 
694
840
    answer[0] = 0;
743
889
 
744
890
    // 3.1.5: Some modems (like Westermo GDW-11) start answer with extra <CR><LF>, check and remove it:
745
891
    while (!got_timeout && !strncmp(answer, "\r\n", 2))
746
 
      strcpy(answer, answer +2);
 
892
      memmove(answer, answer +2, strlen(answer +2) +1);
747
893
 
748
894
    // 3.1.4: error explanation should be included in the answer.
749
895
    if (!got_timeout && strstr(answer, "ERROR"))
756
902
          sprintf(strchr(answer, 0), " (%s)", p);
757
903
    }
758
904
 
759
 
    strncpy(loganswer, answer, sizeof(loganswer) -1);
760
 
    loganswer[sizeof(loganswer) -1] = 0;
761
 
    cutspaces(loganswer);
762
 
    cut_emptylines(loganswer);
763
 
 
764
 
    // 3.1:
765
 
    if (log_single_lines)
766
 
      change_crlf(loganswer, ' ');
 
905
    snprintf(loganswer, sizeof(loganswer), "%s", answer);
 
906
 
 
907
    if (!log_unmodified)
 
908
    {
 
909
      cutspaces(loganswer);
 
910
      cut_emptylines(loganswer);
 
911
 
 
912
      if (log_single_lines)
 
913
        change_crlf(loganswer, ' ');
 
914
    }
767
915
 
768
916
    writelogfile(LOG_DEBUG, 0, "<- %s", loganswer);
769
917
  }
786
934
  struct termios newtio;
787
935
  int baudrate;
788
936
 
 
937
  if (DEVICE_IS_SOCKET)
 
938
    return;
 
939
 
789
940
  bzero(&newtio, sizeof(newtio));
790
941
  newtio.c_cflag = CS8 | CLOCAL | CREAD | O_NDELAY | O_NONBLOCK;
791
942
  if (DEVICE.rtscts)
896
1047
  int retries=0;
897
1048
  char *p;
898
1049
  char *pre_initstring = "ATE0+CMEE=1\r";
 
1050
  char *pre_initstring_clip = "ATE0+CMEE=1;+CLIP=1\r";
899
1051
  static int reading_checked = 0;
900
1052
 
901
1053
  STATISTICS->last_init = time(0);
904
1056
 
905
1057
  // -----------------------------------------------------------------------------------------------
906
1058
  writelogfile(LOG_INFO, 0, "Checking if modem is ready");
 
1059
 
 
1060
  // 3.1.7: After being idle, some modems do not answer to the first AT command.
 
1061
  // With BenQ M32, there can be OK answer, but in many times there is not.
 
1062
  // To avoid error messages, first send AT and read the answer if it's available.
 
1063
  if (DEVICE.needs_wakeup_at)
 
1064
  {
 
1065
    put_command("AT\r", 0, 0, 1, 0);
 
1066
    usleep(100000);
 
1067
    read_from_modem(answer, sizeof(answer), 2);
 
1068
  }
 
1069
 
907
1070
  retries=0;
908
1071
  do
909
1072
  {
922
1085
      if (terminate)
923
1086
        return 7;
924
1087
    }
 
1088
 
 
1089
    // 3.1.7: If it looks like modem does not respond, try to close and open the port:
 
1090
    if (retries >= 5 && !strstr(answer, "OK"))
 
1091
    {
 
1092
      try_closemodem(1);
 
1093
      sleep(1);
 
1094
 
 
1095
      // If open fails, nothing can be done. Error is already logged. Will return 1.
 
1096
      if (!try_openmodem())
 
1097
        break;
 
1098
    }
925
1099
  }
926
1100
  while (retries <= 10 && !strstr(answer,"OK"));
927
1101
  if (!strstr(answer,"OK"))
939
1113
  if (DEVICE.pre_init > 0)
940
1114
  {
941
1115
    writelogfile(LOG_INFO, 0, "Pre-initializing modem");
942
 
    put_command(pre_initstring, answer, sizeof(answer), 2, "(OK)|(ERROR)");
 
1116
    put_command((DEVICE.phonecalls == 2)? pre_initstring_clip : pre_initstring, answer, sizeof(answer), 2, "(OK)|(ERROR)");
943
1117
    if (!strstr(answer,"OK"))
944
1118
      writelogfile(LOG_ERR, 1, "Modem did not accept the pre-init string");
945
1119
  }
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);
 
1131
 
 
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);
 
1135
 
 
1136
    // 3.1.7: Some modems may leave a space away after +CPIN:
 
1137
    if (!strncmp(answer, "+CPIN:", 6) && strncmp(answer, "+CPIN: ", 7))
 
1138
    {
 
1139
      if ((p = strdup(answer)))
 
1140
      {
 
1141
        snprintf(answer, sizeof(answer), "+CPIN: %s", p + 6);
 
1142
        free(p);
 
1143
      }
 
1144
    }
 
1145
 
957
1146
    if (strstr(answer,"+CPIN: SIM PIN") && !strstr(answer, "PIN2"))
958
1147
    {
959
1148
      // 3.1.1:
1061
1250
    }
1062
1251
    // 3.1.5:
1063
1252
    else
1064
 
      explain_csq(LOG_NOTICE, 0, answer);
 
1253
      explain_csq(LOG_INFO, 0, answer);
1065
1254
  }
1066
1255
 
1067
1256
  // -----------------------------------------------------------------------------------------------
1087
1276
        STATISTICS->ber = atoi(p +1);
1088
1277
      else
1089
1278
        STATISTICS->ber = -2;
 
1279
 
 
1280
      // 3.1.7: Explain signal quality to the log:
 
1281
      explain_csq(LOG_INFO, 0, answer);
1090
1282
    }
1091
1283
    else
1092
1284
    {
1137
1329
  if (new_smsc[0] || DEVICE.smsc[0])
1138
1330
  {
1139
1331
    writelogfile(LOG_INFO, 0, "Changing SMSC");
1140
 
    sprintf(command, "AT+CSCA=\"+%s\"\r", (new_smsc[0])? new_smsc : DEVICE.smsc);
 
1332
 
 
1333
    // 3.1.7: clean + character(s) from the setting:
 
1334
    //sprintf(command, "AT+CSCA=\"+%s\"\r", (new_smsc[0]) ? new_smsc : DEVICE.smsc);
 
1335
    snprintf(answer, sizeof(answer), "%s", (new_smsc[0]) ? new_smsc : DEVICE.smsc);
 
1336
    while (*answer == '+')
 
1337
      memmove(answer, answer + 1, strlen(answer + 1) + 1);
 
1338
    sprintf(command, "AT+CSCA=\"+%s\"\r", answer);
 
1339
 
1141
1340
    retries=0;
1142
1341
    do
1143
1342
    {
1170
1369
    // 3.1.5: do not remove ERROR text:
1171
1370
    if (!strstr(DEVICE.identity, "ERROR"))
1172
1371
      while (DEVICE.identity[0] && !isdigit(DEVICE.identity[0]))
1173
 
        strcpy(DEVICE.identity, DEVICE.identity +1);
 
1372
        memmove(DEVICE.identity, DEVICE.identity +1, strlen(DEVICE.identity +1) +1);
1174
1373
 
1175
1374
    // 3.1beta7: If CIMI is not supported, try CGSN (Product Serial Number)
1176
1375
    // TODO: is IMSI title still good?
1181
1380
 
1182
1381
      // 3.1:
1183
1382
      while (DEVICE.identity[0] && !isdigit(DEVICE.identity[0]))
1184
 
        strcpy(DEVICE.identity, DEVICE.identity +1);
 
1383
        memmove(DEVICE.identity, DEVICE.identity +1, strlen(DEVICE.identity +1) +1);
1185
1384
    }
1186
1385
    else
1187
1386
    {
1191
1390
 
1192
1391
      if (!strstr(answer, "ERROR"))
1193
1392
        while (answer[0] && !isdigit(answer[0]))
1194
 
          strcpy(answer, answer +1);
 
1393
          memmove(answer, answer +1, strlen(answer +1) +1);
1195
1394
 
1196
1395
      if ((p = strstr(answer, "OK")))
1197
1396
        *p = 0;
1214
1413
 
1215
1414
  // -----------------------------------------------------------------------------------------------
1216
1415
  // 3.1.5: Check once if reading of messages is not supported:
1217
 
  if (!reading_checked)
 
1416
  // 3.1.7: Do not check if not reading incoming messages:
 
1417
  if (DEVICE.incoming && !reading_checked)
1218
1418
  {
1219
1419
    reading_checked = 1;
1220
1420
    writelogfile(LOG_INFO, 0, "Checking if reading of messages is supported");
1236
1436
  }
1237
1437
 
1238
1438
  // -----------------------------------------------------------------------------------------------
 
1439
  // 3.1.7: Report details of device once:
 
1440
  if (DEVICE.report_device_details)
 
1441
  {
 
1442
    int save_log_single_lines = log_single_lines;
 
1443
    int i;
 
1444
    char tmp[256];
 
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",
 
1460
      "" // end marker
 
1461
    };
 
1462
 
 
1463
    DEVICE.report_device_details = 0;
 
1464
    log_single_lines = 0;
 
1465
    change_loglevel(LOG_DEBUG);
 
1466
 
 
1467
    writelogfile(LOG_DEBUG, 0, "## Start of device details");
 
1468
 
 
1469
    for (i = 0; commands[i][0]; i += 2)
 
1470
    {
 
1471
      if (terminate)
 
1472
        break;
 
1473
 
 
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);
 
1478
    }
 
1479
 
 
1480
    writelogfile(LOG_DEBUG, 0, "## End of device details");
 
1481
 
 
1482
    log_single_lines = save_log_single_lines;
 
1483
    restore_loglevel();
 
1484
  }
 
1485
 
 
1486
  // -----------------------------------------------------------------------------------------------
1239
1487
  // TODO: Check if AT+CMGD=? is supported.
1240
1488
 
1241
1489
  return 0;
1251
1499
  return initmodem("", 1);
1252
1500
}
1253
1501
 
 
1502
#ifndef DISABLE_INET_SOCKET
 
1503
 
 
1504
/* Start Changes by Hubert Gilch, SEP Logistik AG
 
1505
 *
 
1506
 * 2 functions for connecting to a socket instead of a serial device
 
1507
 * in order to use ethernet GPRS-modems
 
1508
 *
 
1509
 * Code was "stolen" from interceptty by Scott W. Gifford
 
1510
 *
 
1511
 */
 
1512
 
 
1513
struct sockaddr_in inet_resolve(const char *sockname)
 
1514
{
 
1515
  struct sockaddr_in sa;
 
1516
  char *hostname, *netport;
 
1517
  struct hostent *he;
 
1518
 
 
1519
  if (!(hostname = strdup(sockname)))
 
1520
    writelogfile(LOG_CRIT, 0, "Couldn't dup string: %s", strerror(errno));
 
1521
 
 
1522
  netport = strchr(hostname, ':');
 
1523
  *netport = '\0';
 
1524
  netport++;
 
1525
 
 
1526
  sa.sin_family = AF_INET;
 
1527
 
 
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");
 
1533
 
 
1534
  memcpy(&(sa.sin_addr), he->h_addr, he->h_length);
 
1535
 
 
1536
#if 0
 
1537
  if (!(se = getservbyname(netport)))
 
1538
    writelogfile(LOG_ERR, 0, "Couldn't resolve port.");
 
1539
 
 
1540
  host_port = htons(se->s_port);
 
1541
#endif
 
1542
 
 
1543
  if (!(sa.sin_port = htons(atoi(netport))))
 
1544
    writelogfile(LOG_ERR, 0, "Couldn't figure out port number.");
 
1545
 
 
1546
  free(hostname);
 
1547
 
 
1548
  return sa;
 
1549
}
 
1550
 
 
1551
int open_inet_socket(char *backend)
 
1552
{
 
1553
  struct sockaddr_in sa;
 
1554
  int fd;
 
1555
  int socketflags;
 
1556
  int retries = 0;
 
1557
 
 
1558
  sa = inet_resolve(backend + 1);       // cut first character @
 
1559
  if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 3)
 
1560
  {
 
1561
    tb_sprintf("Couldn't open socket: %s: %s", backend, strerror(errno));
 
1562
    writelogfile0(LOG_ERR, 0, tb);
 
1563
    alarm_handler0(LOG_ERR, tb);
 
1564
    return -1;
 
1565
  }
 
1566
 
 
1567
  while (connect(fd, (struct sockaddr *) &sa, sizeof(sa)) != 0)
 
1568
  {
 
1569
    retries++;
 
1570
 
 
1571
    if (terminate || (DEVICE.socket_connection_retries != -1 && retries > DEVICE.socket_connection_retries))
 
1572
    {
 
1573
      close(fd);
 
1574
      return (terminate)? -2 : -1;
 
1575
    }
 
1576
 
 
1577
    tb_sprintf("Couldn't connect socket %s, error: %s, waiting %i sec.", backend, strerror(errno), DEVICE.socket_connection_errorsleeptime);
 
1578
 
 
1579
    if (retries - 1 == DEVICE.socket_connection_alarm_after)
 
1580
    {
 
1581
      writelogfile0(LOG_ERR, 0, tb);
 
1582
      alarm_handler0(LOG_ERR, tb);
 
1583
    }
 
1584
    else
 
1585
    {
 
1586
      // Do not log the first failure:
 
1587
      if (retries > 1)
 
1588
        writelogfile(LOG_INFO, 0, tb);
 
1589
    }
 
1590
 
 
1591
    sleep(DEVICE.socket_connection_errorsleeptime);
 
1592
  }
 
1593
 
 
1594
  socketflags = fcntl(fd, F_GETFL);
 
1595
  fcntl(fd, F_SETFL, socketflags | O_NONBLOCK);
 
1596
 
 
1597
  return fd;
 
1598
}
 
1599
 
 
1600
/*
 
1601
 * End Changes by Hubert Gilch
 
1602
 */
 
1603
 
 
1604
#endif
 
1605
 
1254
1606
int openmodem()
1255
1607
{
1256
 
 
1257
 
  modem_handle = open(DEVICE.device, O_RDWR | O_NOCTTY | O_NONBLOCK);
 
1608
  int retries = 0;
 
1609
 
 
1610
  // 3.1.7:
 
1611
  //modem_handle = open(DEVICE.device, O_RDWR | O_NOCTTY | O_NONBLOCK);
 
1612
 
 
1613
  /*
 
1614
   * if devicename starts with "@" it is not a serial device but
 
1615
   * a socket, so open a socket instead a device file
 
1616
   *
 
1617
   * Change by Hubert Gilch, SEP Logistik AG
 
1618
   */
 
1619
#ifndef DISABLE_INET_SOCKET
 
1620
  if (DEVICE_IS_SOCKET)
 
1621
    modem_handle = open_inet_socket(DEVICE.device);
 
1622
  else
 
1623
#endif
 
1624
    // 3.1.7:
 
1625
    while ((modem_handle = open(DEVICE.device, O_RDWR | O_NOCTTY | O_NONBLOCK)) < 0)
 
1626
    {
 
1627
      retries++;
 
1628
 
 
1629
      if (terminate || (DEVICE.device_open_retries != -1 && retries > DEVICE.device_open_retries))
 
1630
        break;
 
1631
 
 
1632
      tb_sprintf("Couldn't open serial port %s, error: %s, waiting %i sec.", DEVICE.device, strerror(errno), DEVICE.device_open_errorsleeptime);
 
1633
 
 
1634
      if (retries - 1 == DEVICE.device_open_alarm_after)
 
1635
      {
 
1636
        writelogfile0(LOG_ERR, 0, tb);
 
1637
        alarm_handler0(LOG_ERR, tb);
 
1638
      }
 
1639
      else
 
1640
        writelogfile(LOG_INFO, 0, tb);
 
1641
 
 
1642
      sleep(DEVICE.device_open_errorsleeptime);
 
1643
    }
 
1644
 
1258
1645
  if (modem_handle < 0)
1259
1646
  {
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)
 
1648
    {
 
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);
 
1651
    }
1263
1652
    return -1;
1264
1653
  }
 
1654
 
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);
 
1656
  {
 
1657
    if (DEVICE_IS_SOCKET)
 
1658
      writelogfile(LOG_INFO, 0, "Socket %s opened as %i", DEVICE.device, modem_handle);
 
1659
    else
 
1660
      writelogfile(LOG_INFO, 0, "Serial port %s opened as %i, rtscts: %i, baudrate: %i", DEVICE.device, modem_handle, DEVICE.rtscts, DEVICE.baudrate);
 
1661
  }
 
1662
 
1268
1663
  return modem_handle;
1269
1664
}
1270
1665
 
1418
1813
 
1419
1814
    // 3.1.1: Some modem include spaces in the response:
1420
1815
    while ((p = strchr(answer, ' ')))
1421
 
      strcpy(p, p +1);
 
1816
      memmove(p, p +1, strlen(p +1) +1);
1422
1817
 
1423
1818
    // 3.1.1: Drop additional fields:
1424
1819
    if ((p = strchr(answer, ',')))
1427
1822
 
1428
1823
    // 3.1.1: Some modem (Motorola) gives values using three digits like "000,001":
1429
1824
    if ((p = strstr(answer, ",00")))
1430
 
      strcpy(p +1, p +3);
 
1825
      memmove(p +1, p +3, strlen(p +3) +1);
1431
1826
 
1432
1827
    // 3.1:
1433
1828
    // Second field is tested.
1509
1904
 
1510
1905
  if (modem_handle >= 0 && !keep_open)
1511
1906
  {
1512
 
    if (0 && strstr(smsd_version, "beta"))
 
1907
    if (1 && strstr(smsd_version, "beta"))
1513
1908
    {
1514
 
      writelogfile(LOG_INFO, 0, "Serial port %s (%i) closed", DEVICE.device, modem_handle);
 
1909
      writelogfile(LOG_INFO, 0, "Device %s (%i) closed", DEVICE.device, modem_handle);
1515
1910
      writelogfile(LOG_INFO, 0, "***********");
1516
1911
    }
1517
1912
#ifdef DEBUGMSG
1518
 
  printf("!! Closing serial port %s\n", DEVICE.device);
 
1913
  printf("!! Closing device %s\n", DEVICE.device);
1519
1914
#endif 
1520
1915
    close(modem_handle);
1521
1916
    modem_handle = -2;
1531
1926
  if (modem_handle >= 0)
1532
1927
  {
1533
1928
#ifdef DEBUGMSG
1534
 
  printf("!! Opening serial port %s: already open\n", DEVICE.device);
 
1929
  printf("!! Opening device %s: already open\n", DEVICE.device);
1535
1930
#endif 
1536
1931
    return 1;
1537
1932
  }
1538
1933
 
1539
1934
#ifdef DEBUGMSG
1540
 
  printf("!! Opening serial port %s\n", DEVICE.device);
 
1935
  printf("!! Opening device %s\n", DEVICE.device);
1541
1936
#endif 
1542
1937
  if (openmodem() == -1)
1543
1938
  {