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

📄 modeminit.c

📁 GSM猫管理程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*SMS Server Tools 3Copyright (C) Keijo Kasvihttp://smstools3.kekekasvi.com/Based on SMS Server Tools 2 from Stefan Fringshttp://www.meinemullemaus.de/This program is free software unless you got it under another license directlyfrom the author. You can redistribute it and/or modify it under the terms ofthe GNU General Public License as published by the Free Software Foundation.Either version 2 of the License, or (at your option) any later version.*/#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <termios.h>#include <regex.h>#include "logging.h"#include "alarm.h"#ifdef SOLARIS#include <sys/filio.h>#include <strings.h> // for bzero().#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <syslog.h>#include <sys/ioctl.h>#include <errno.h>#include "extras.h"#include "modeminit.h"#include "smsd_cfg.h"#include "version.h"// Define a dummy if the OS does not support hardware handshake#ifndef CRTSCTS#define CRTSCTS 0#endiftypedef struct {  int code;  char *text;} _gsm_general_error; _gsm_general_error gsm_cme_errors[] ={  // 3GPP TS 07.07 version 7.8.0 Release 1998 (page 90) ETSI TS 100 916 V7.8.0 (2003-03)  {0,	"phone failure"},  {1,	"no connection to phone"},  {2,	"phone-adaptor link reserved"},  {3,	"operation not allowed"},  {4,	"operation not supported"},  {5,	"PH-SIM PIN required"},  {6,	"PH-FSIM PIN required"},  {7,	"PH-FSIM PUK required"},  {10,	"SIM not inserted"},  {11,	"SIM PIN required"},  {12,	"SIM PUK required"},  {13,	"SIM failure"},  {14,	"SIM busy"},  {15,	"SIM wrong"},  {16,	"incorrect password"},  {17,	"SIM PIN2 required"},  {18,	"SIM PUK2 required"},  {20,	"memory full"},  {21,	"invalid index"},  {22,	"not found"},  {23,	"memory failure"},  {24,	"text string too long"},  {25,	"invalid characters in text string"},  {26,	"dial string too long"},  {27,	"invalid characters in dial string"},  {30,	"no network service"},  {31,	"network timeout"},  {32,	"network not allowed - emergency calls only"},  {40,	"network personalisation PIN required"},  {41,	"network personalisation PUK required"},  {42,	"network subset personalisation PIN required"},  {43,	"network subset personalisation PUK required"},  {44,	"service provider personalisation PIN required"},  {45,	"service provider personalisation PUK required"},  {46,	"corporate personalisation PIN required"},  {47,	"corporate personalisation PUK required"},  {100,	"unknown"}// Some other possible errors (source document?)://CME ERROR: 48  PH-SIM PUK required//CME ERROR: 256 Operation temporarily not allowed//CME ERROR: 257 Call barred//CME ERROR: 258 Phone is busy//CME ERROR: 259 User abort//CME ERROR: 260 Invalid dial string//CME ERROR: 261 SS not executed//CME ERROR: 262 SIM Blocked};_gsm_general_error gsm_cms_errors[] ={  // Table 8.4/GSM 04.11 (part 1):  {1,	"Unassigned (unallocated) number"},  {8,	"Operator determined barring"},  {10,	"Call barred"},  {21,	"Short message transfer rejected"},  {27,	"Destination out of order"},  {28,	"Unindentified subscriber"},  {29,	"Facility rejected"},  {30,	"Unknown subscriber"},  {38,	"Network out of order"},  {41,	"Temporary failure"},  {42,	"Congestion"},  {47,	"Recources unavailable, unspecified"},  {50,	"Requested facility not subscribed"},  {69,	"Requested facility not implemented"},  {81,	"Invalid short message transfer reference value"},  {95,	"Semantically incorrect message"},  {96,	"Invalid mandatory information"},  {97,	"Message type non-existent or not implemented"},  {98,	"Message not compatible with short message protocol state"},  {99,	"Information element non-existent or not implemented"},  {111,	"Protocol error, unspecified"},  {127,	"Internetworking , unspecified"},  // Table 8.4/GSM 04.11 (part 2):  {22,	"Memory capacity exceeded"},  // GSM 03.40 subclause 9.2.3.22 values.  {128,	"Telematic internetworking not supported"},  {129,	"Short message type 0 not supported"},  {130,	"Cannot replace short message"},  {143,	"Unspecified TP-PID error"},  {144,	"Data code scheme (alphabet) not supported"},  {145,	"Message class not supported"},  {159,	"Unspecified TP-DCS error"},  {160,	"Command cannot be actioned"},  {161,	"Command unsupported"},  {175,	"Unspecified TP-Command error"},  {176,	"Transfer Protocol Data Unit (TPDU) not supported"},  {192,	"Service Center (SC) busy"},  {193,	"No SC subscription"},  {194,	"SC System failure"},  {195,	"Invalid Short Message Entity (SME) address"},  {196,	"Destination SME barred"},  {197,	"SM Rejected-Duplicate SM"},  {198,	"Validity Period Format (TP-VPF) not supported"},  {199,	"Validity Period) TP-VP not supported"},  {208,	"SIM SMS Storage full"},  {209,	"No SMS Storage capability in SIM"},  {210,	"Error in MS"},  {211,	"Memory capacity exceeded"},  {212,	"Sim Application Toolkit busy"},  {213,	"SIM data download error"},  {255,	"Unspecified error cause"},  // 3GPP TS 27.005 subclause 3.2.5 values /3/.  {300,	"ME Failure"},  {301,	"SMS service of ME reserved"},  {302,	"Operation not allowed"},  {303,	"Operation not supported"},  {304,	"Invalid PDU mode parameter"},  {305,	"Invalid Text mode parameter"},  {310,	"(U)SIM not inserted"},  {311,	"(U)SIM PIN required"},  {312,	"PH-(U)SIM PIN required"},  {313,	"(U)SIM failure"},  {314,	"(U)SIM busy"},  {315,	"(U)SIM wrong"},  {316,	"(U)SIM PUK required"},  {317,	"(U)SIM PIN2 required"},  {318,	"(U)SIM PUK2 required"},  {320,	"Memory failure"},  {321,	"Invalid memory index"},  {322,	"Memory full"},  {330,	"SMSC address unknown"},  {331,	"No network service"},  {332,	"Network timeout"},  {340,	"No +CNMA acknowledgement expected"},  {500,	"Unknown error"}};char *get_gsm_cme_error(int code){  int i;  int m = sizeof gsm_cme_errors / sizeof *gsm_cme_errors;  for (i = 0; i < m; i++)    if (code == gsm_cme_errors[i].code)      return gsm_cme_errors[i].text;  return "";}char *get_gsm_cms_error(int code){  int i;  int m = sizeof gsm_cms_errors / sizeof *gsm_cms_errors;  for (i = 0; i < m; i++)    if (code == gsm_cms_errors[i].code)      return gsm_cms_errors[i].text;  return "";}char *get_gsm_error(char *answer){  char *p;  if (answer && *answer)  {    if ((p = strstr(answer, "+CME ERROR: ")))      return get_gsm_cme_error(atoi(p +12));    if ((p = strstr(answer, "+CMS ERROR: ")))      return get_gsm_cms_error(atoi(p +12));  }  return "";}int write_to_modem(int modem, char *modemname, int send_delay, char *command, int timeout, int log_command, int print_error){  int status=0;  int timeoutcounter=0;  int x=0;  struct termios tio;  tcgetattr(modem,&tio);  if (command && command[0])  {    if (tio.c_cflag & CRTSCTS)    {      ioctl(modem,TIOCMGET,&status);      while (!(status & TIOCM_CTS))      {        usleep(100000);        timeoutcounter++;        ioctl(modem,TIOCMGET,&status);        if (timeoutcounter>timeout)        {          if (print_error)            printf("\nModem is not clear to send.\n");          else          {            writelogfile0(LOG_ERR,modemname, tb_sprintf("Modem is not clear to send"));            alarm_handler0(LOG_ERR,modemname, tb);          }          return 0;        }      }    }    if (log_command)      writelogfile(LOG_DEBUG,modemname,"-> %s",command);    for(x=0;x<strlen(command);x++)    {      if (write(modem,command+x,1)<1)      {        if (print_error)          printf("\nCould not send character %c, cause: %s\n",command[x],strerror(errno));        else        {          writelogfile0(LOG_ERR,modemname, tb_sprintf("Could not send character %c, cause: %s", command[x], strerror(errno)));          alarm_handler0(LOG_ERR,modemname, tb);        }        return 0;      }      if (send_delay)        usleep(send_delay*1000);      tcdrain(modem);    }  }  return 1;}// Read max characters from modem. The function returns when it received at // least 1 character and then the modem is quiet for timeout*0.1s.// The answer might contain already a string. In this case, the answer // gets appended to this string.int read_from_modem(int modem, char *modemname, int send_delay, char *answer, int max, int timeout){  int count=0;  int got=0;  int timeoutcounter=0;  int success=0;  int toread=0;    // Cygwin does not support TIOC functions, so we cannot use it.  // ioctl(modem,FIONREAD,&available);	// how many bytes are available to read?  do   {    // How many bytes do I want to read maximum? Not more than buffer size -1 for termination character.    count=strlen(answer);    toread=max-count-1;    if (toread<=0)      break;    // read data    got=read(modem,answer+count,toread);    // if nothing received ...    if (got<=0)    {      // wait a litte bit and then repeat this loop      got=0;      usleep(100000);      timeoutcounter++;    }    else      {      // restart timout counter      timeoutcounter=0;      // append a string termination character      answer[count+got]=0;      success=1;          }  }  while (timeoutcounter < timeout);  return success;}// 3.1beta7: Not waiting any answer if answer is NULL. Return value is then 1/0.int put_command(int modem, char *modemname, int send_delay, char *command, char *answer, int max, int timeout, char *expect){  char loganswer[2048];  int timeoutcounter = 0;  regex_t re;  int got_timeout = 1;  int regex_allocated = 0;  // compile regular expressions  if (expect && expect[0])  {    if (regcomp(&re, expect, REG_EXTENDED|REG_NOSUB) != 0)    {	        fprintf(stderr, "Programming error: Expected answer %s is not a valid regepr\n", expect);      writelogfile(LOG_CRIT, modemname, "Programming error: Expected answer %s is not a valid regepr", expect);      exit(1);    }    regex_allocated = 1;  }    // clean input buffer  // It seems that this command does not do anything because actually it   // does not clear the input buffer. However I do not remove it until I   // know why it does not work.  tcflush(modem,TCIFLUSH);    // send command  if (write_to_modem(modem, modemname, send_delay, command, 30, 1, 0) == 0)  {    t_sleep(errorsleeptime);    // Free memory used by regexp    if (regex_allocated)      regfree(&re);    return 0;  }   if (!answer)    writelogfile(LOG_DEBUG, modemname, "Command is sent");  else  {    writelogfile(LOG_DEBUG, modemname, "Command is sent, waiting for the answer");    // wait for the modem-answer     answer[0] = 0;    timeoutcounter = 0;    do    {      read_from_modem(modem, modemname, send_delay, answer, max, 2);  // One read attempt is 200ms      // check if it's the expected answer      if (expect && expect[0] && (regexec(&re, answer, (size_t) 0, NULL, 0) == 0))      {        got_timeout = 0;        put_command_timeouts = 0;        break;      }      timeoutcounter += 2;    }    // repeat until timout    while (timeoutcounter < timeout);    if (got_timeout)    {          put_command_timeouts++;      if (expect && expect[0])        writelogfile(LOG_DEBUG, modemname, "put_command expected %s, timeout occurred.", expect);    }    strncpy(loganswer, answer, sizeof(loganswer) -1);    loganswer[sizeof(loganswer) -1] = 0;    cutspaces(loganswer);    cut_emptylines(loganswer);    writelogfile(LOG_DEBUG, modemname, "<- %s", loganswer);  }  // Free memory used by regexp  if (regex_allocated)    regfree(&re);  if (answer)    return strlen(answer);  return 1;}void setmodemparams(int modem, char* modemname, int rtscts,int baudrate) /* setup serial port */{  struct termios newtio;  bzero(&newtio, sizeof(newtio));  newtio.c_cflag = CS8 | CLOCAL | CREAD | O_NDELAY | O_NONBLOCK;  if (rtscts)    newtio.c_cflag |= CRTSCTS;  newtio.c_iflag = IGNPAR;  newtio.c_oflag = 0;  newtio.c_lflag = 0;  newtio.c_cc[VTIME]    = 0;  newtio.c_cc[VMIN]     = 0;  switch (baudrate)  {    case 300:    baudrate=B300; break;    case 1200:   baudrate=B1200; break;    case 2400:   baudrate=B2400; break;    case 9600:   baudrate=B9600; break;    case 19200:  baudrate=B19200; break;    case 38400:  baudrate=B38400; break;

⌨️ 快捷键说明

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