📄 gsmsmsd.c
字号:
// *************************************************************************
// * 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>
#include <unistd.h>
#ifdef HAVE_GETOPT_LONG
#include <getopt.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <dirent.h>
#include <signal.h>
#include <fstream>
#include <iostream>
#include <gsmlib/gsm_me_ta.h>
#include <gsmlib/gsm_event.h>
#include <gsmlib/gsm_unix_serial.h>
using namespace std;
using namespace gsmlib;
#ifdef HAVE_GETOPT_LONG
static 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'},
{"sca", required_argument, (int*)NULL, 'C'},
{"flush", no_argument, (int*)NULL, 'f'},
{"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 ME
static MeTa *me;
// service centre address (set on command line)
static string serviceCentreAddress;
// signal handler for terminate signal
bool terminateSent = false;
void terminateHandler(int signum)
{
terminateSent = true;
}
// local class to handle SMS events
struct 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;
m._storeName = storeName;
m._messageType = messageType;
newMessages.push_back(m);
}
// execute action on string
void 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 dir
bool requestStatusReport = false;
void sendSMS(string spoolDir, Ref<GsmAt> at)
{
if (spoolDir != "")
{
// look into spoolDir for any outgoing SMS that should be sent
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);
struct dirent *entry;
while ((entry = readdir(dir)) != (struct dirent*)NULL)
if (strcmp(entry->d_name, ".") != 0 &&
strcmp(entry->d_name, ".."))
{
// read in file
// the first line is interpreted as the phone number
// the rest is the message
string filename = spoolDir + "/" + entry->d_name;
ifstream ifs(filename.c_str());
if (! ifs)
throw GsmException(
stringPrintf(_("count not open SMS spool file %s"),
filename.c_str()), ParameterError);
char phoneBuf[1001];
ifs.getline(phoneBuf, 1000);
string text;
while (! ifs.eof())
{
char c;
ifs.get(c);
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(text, phoneNumber);
// set service centre address in new submit PDU if requested by user
if (serviceCentreAddress != "")
{
Address sca(serviceCentreAddress);
submitSMS->setServiceCentreAddress(sca);
}
submitSMS->setStatusReportRequest(requestStatusReport);
submitSMS->setAt(at);
submitSMS->send();
unlink(filename.c_str());
}
closedir(dir);
}
}
// *** main program
int main(int argc, char *argv[])
{
try
{
string device = "/dev/mobilephone";
string action;
string baudrate;
bool enableSMS = true;
bool enableCB = true;
bool enableStat = true;
bool flushSMS = false;
bool onlyReceptionIndication = true;
string spoolDir;
string storeName;
string initString = DEFAULT_INIT_STRING;
bool swHandshake = false;
int opt;
int dummy;
while((opt = getopt_long(argc, argv, "C:I:t:fd:a:b:hvs:XDr",
longOpts, &dummy)) != -1)
switch (opt)
{
case 'r':
requestStatusReport = true;
break;
case 'D':
onlyReceptionIndication = false;
break;
case 'X':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -