📄 gsmsmsd.cc
字号:
// *************************************************************************// * GSM TA/ME library// *// * File: gsmsmsd.cc// *// * Purpose: SMS receiver daemon// *// * Author: Peter Hofmann (software@pxh.de)// *// * Created: 5.6.1999// *************************************************************************#ifdef HAVE_CONFIG_H#include <gsm_config.h>#endif#include <gsmlib/gsm_nls.h>#include <string>#ifdef WIN32#include <io.h>#include <gsmlib/gsm_util.h>#include <gsmlib/gsm_win32_serial.h>#define popen _popen#define pclose _pclose#else#include <gsmlib/gsm_unix_serial.h>#include <unistd.h>#include <dirent.h>#include <syslog.h>#endif#if defined(HAVE_GETOPT_LONG) || defined(WIN32)#include <getopt.h>#endif#include <stdio.h>#include <errno.h>#include <stdlib.h>#include <signal.h>#include <fstream>#include <iostream>#include <gsmlib/gsm_me_ta.h>#include <gsmlib/gsm_event.h>using namespace std;using namespace gsmlib;#ifdef HAVE_GETOPT_LONGstatic struct option longOpts[] ={ {"requeststat", no_argument, (int*)NULL, 'r'}, {"direct", no_argument, (int*)NULL, 'D'}, {"xonxoff", no_argument, (int*)NULL, 'X'}, {"init", required_argument, (int*)NULL, 'I'}, {"store", required_argument, (int*)NULL, 't'}, {"device", required_argument, (int*)NULL, 'd'}, {"spool", required_argument, (int*)NULL, 's'}, {"sent", required_argument, (int*)NULL, 'S'}, {"failed", required_argument, (int*)NULL, 'F'}, {"priorities", required_argument, (int*)NULL, 'P'},#ifndef WIN32 {"syslog", no_argument, (int*)NULL, 'L'},#endif {"sca", required_argument, (int*)NULL, 'C'}, {"flush", no_argument, (int*)NULL, 'f'}, {"concatenate", required_argument, (int*)NULL, 'c'}, {"action", required_argument, (int*)NULL, 'a'}, {"baudrate", required_argument, (int*)NULL, 'b'}, {"help", no_argument, (int*)NULL, 'h'}, {"version", no_argument, (int*)NULL, 'v'}, {(char*)NULL, 0, (int*)NULL, 0}};#else#define getopt_long(argc, argv, options, longopts, indexptr) \ getopt(argc, argv, options)#endif// my MEstatic MeTa *me = NULL;string receiveStoreName; // store name for received SMSs// service centre address (set on command line)static string serviceCentreAddress;// ID if concatenated messages should be sentstatic int concatenatedMessageId = -1;// signal handler for terminate signalbool terminateSent = false;void terminateHandler(int signum){ terminateSent = true;}// local class to handle SMS eventsstruct IncomingMessage{ // used if new message is put into store int _index; // -1 means message want send directly string _storeName; // used if SMS message was sent directly to TA SMSMessageRef _newSMSMessage; // used if CB message was sent directly to TA CBMessageRef _newCBMessage; // used in both cases GsmEvent::SMSMessageType _messageType; IncomingMessage() : _index(-1) {}};vector<IncomingMessage> newMessages;class EventHandler : public GsmEvent{public: // inherited from GsmEvent void SMSReception(SMSMessageRef newMessage, SMSMessageType messageType); void CBReception(CBMessageRef newMessage); void SMSReceptionIndication(string storeName, unsigned int index, SMSMessageType messageType); virtual ~EventHandler() {}};void EventHandler::SMSReception(SMSMessageRef newMessage, SMSMessageType messageType){ IncomingMessage m; m._messageType = messageType; m._newSMSMessage = newMessage; newMessages.push_back(m);}void EventHandler::CBReception(CBMessageRef newMessage){ IncomingMessage m; m._messageType = GsmEvent::CellBroadcastSMS; m._newCBMessage = newMessage; newMessages.push_back(m);}void EventHandler::SMSReceptionIndication(string storeName, unsigned int index, SMSMessageType messageType){ IncomingMessage m; m._index = index; if (receiveStoreName != "" && ( storeName == "MT" || storeName == "mt")) m._storeName = receiveStoreName; else m._storeName = storeName; m._messageType = messageType; newMessages.push_back(m);}// execute action on stringvoid doAction(string action, string result){ if (action != "") { FILE *fd = popen(action.c_str(), "w"); if (fd == NULL) throw GsmException(stringPrintf(_("could not execute '%s'"), action.c_str()), OSError); fputs(result.c_str(), fd); if (ferror(fd)) throw GsmException(stringPrintf(_("error writing to '%s'"), action.c_str()), OSError); pclose(fd); } else // default if no action: output on stdout cout << result << endl;}// send all SMS messages in spool dirbool requestStatusReport = false;void sendSMS(string spoolDirBase, string sentDirBase, string failedDirBase, unsigned int priority, bool enableSyslog, Ref<GsmAt> at){ string spoolDir = spoolDirBase; string sentDir = sentDirBase; string failedDir = failedDirBase; if ( priority >= 1 ) { spoolDir = spoolDirBase + stringPrintf(_("%d"),priority); sentDir = sentDirBase + stringPrintf(_("%d"),priority); failedDir = failedDirBase + stringPrintf(_("%d"),priority); } if ( priority > 1 ) sendSMS(spoolDirBase, sentDirBase, failedDirBase, priority-1, enableSyslog, at); if (spoolDirBase != "") { // look into spoolDir for any outgoing SMS that should be sent#ifdef WIN32 struct _finddata_t fileInfo; long fileHandle; string pattern = spoolDir + "\\*"; fileHandle = _findfirst(pattern.c_str(), &fileInfo); bool moreFiles = fileHandle != -1L;#else DIR *dir = opendir(spoolDir.c_str()); if (dir == (DIR*)NULL) throw GsmException( stringPrintf(_("error when calling opendir('%s')" "(errno: %d/%s)"), spoolDir.c_str(), errno, strerror(errno)), OSError);#endif#ifdef WIN32 while (moreFiles) { if (strcmp(fileInfo.name, ".") != 0 && strcmp(fileInfo.name, "..") != 0)#else struct dirent *entry; while ((entry = readdir(dir)) != (struct dirent*)NULL) if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0)#endif { if ( priority > 1 ) sendSMS(spoolDirBase, sentDirBase, failedDirBase, priority-1, enableSyslog, at); // read in file // the first line is interpreted as the phone number // the rest is the message#ifdef WIN32 string filename = spoolDir + "\\" + fileInfo.name;#else string filename = spoolDir + "/" + entry->d_name;#endif ifstream ifs(filename.c_str()); if (! ifs)#ifndef WIN32 if (enableSyslog) { syslog(LOG_WARNING, "could not open SMS spool file %s", filename.c_str()); if (failedDirBase != "") { string failedfilename = failedDir + "/" + entry->d_name; rename(filename.c_str(),failedfilename.c_str()); } continue; } else#endif throw GsmException( stringPrintf(_("could not open SMS spool file %s"), filename.c_str()), ParameterError); char phoneBuf[1001]; ifs.getline(phoneBuf, 1000); for(int i=0;i<1000;i++) if(phoneBuf[i]=='\t' || phoneBuf[i]==0) { // ignore everything after a <TAB> in the phone number phoneBuf[i]=0; break; } string text; char c; while (ifs.get(c)) { if (c == 0) break; // workaround for libstdc++ bug (still necessary?) text += c; } ifs.close(); // remove trailing newline/linefeed while (text[text.length() - 1] == '\n' || text[text.length() - 1] == '\r') text = text.substr(0, text.length() - 1); // send the message string phoneNumber(phoneBuf); Ref<SMSSubmitMessage> submitSMS = new SMSSubmitMessage(); // set service centre address in new submit PDU if requested by user if (serviceCentreAddress != "") { Address sca(serviceCentreAddress); submitSMS->setServiceCentreAddress(sca); } submitSMS->setStatusReportRequest(requestStatusReport); Address destAddr(phoneNumber); submitSMS->setDestinationAddress(destAddr); try { if (concatenatedMessageId == -1) me->sendSMSs(submitSMS, text, true); else { // maximum for concatenatedMessageId is 255 if (concatenatedMessageId > 256) concatenatedMessageId = 0; me->sendSMSs(submitSMS, text, false, concatenatedMessageId++); }#ifndef WIN32 if (enableSyslog) syslog(LOG_NOTICE, "sent SMS to %s from file %s", phoneBuf, filename.c_str());#endif if (sentDirBase != "") {#ifdef WIN32 string sentfilename = sentDir + "\\" + fileInfo.name;#else string sentfilename = sentDir + "/" + entry->d_name;#endif rename(filename.c_str(),sentfilename.c_str()); } else { unlink(filename.c_str()); } } catch (GsmException &me) {#ifndef WIN32 if (enableSyslog) syslog(LOG_WARNING, "failed sending SMS to %s from file %s: %s", phoneBuf, filename.c_str(), me.what()); else#endif { cerr << "Failed sending SMS to " << phoneBuf << " from file " << filename << ": " << me.what() << endl; throw; } if (failedDirBase != "") {#ifdef WIN32 string failedfilename = failedDir + "\\" + fileInfo.name;#else string failedfilename = failedDir + "/" + entry->d_name;#endif rename(filename.c_str(),failedfilename.c_str()); } }#ifdef WIN32 } moreFiles = _findnext(fileHandle, &fileInfo) == 0; #endif }#ifdef WIN32 _findclose(fileHandle);#else closedir(dir);#endif }}#ifndef WIN32void syslogExit(int exitcode, void *dummy){ syslog(LOG_NOTICE, "exited with code %d",exitcode);}#endif// *** main programint main(int argc, char *argv[])
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -