📄 gsmsmsd.c
字号:
swHandshake = true;
break;
case 'I':
initString = optarg;
break;
case 't':
storeName = optarg;
break;
case 'd':
device = optarg;
break;
case 'C':
serviceCentreAddress = optarg;
break;
case 's':
spoolDir = optarg;
break;
case 'f':
flushSMS = true;
break;
case 'a':
action = optarg;
break;
case 'b':
baudrate = optarg;
break;
case 'v':
cerr << argv[0] << stringPrintf(_(": version %s [compiled %s]"),
VERSION, __DATE__) << endl;
exit(0);
break;
case 'h':
cerr << argv[0] << _(": [-a action][-b baudrate][-C sca][-d device]"
"[-f][-h][-I init string]\n"
" [-s spool dir][-t][-v]{sms_type}")
<< endl << endl
<< _(" -a, --action the action to execute when an SMS "
"arrives\n"
" (SMS is send to stdin of action)")
<< endl
<< _(" -b, --baudrate baudrate to use for device "
"(default: 38400)")
<< endl
<< _(" -C, --sca SMS service centre address") << endl
<< _(" -d, --device sets the device to connect to") << endl
<< _(" -D, --direct enable direct routing of SMSs") << endl
<< _(" -f, --flush flush SMS from store") << endl
<< _(" -h, --help prints this message") << endl
<< _(" -I, --init device AT init sequence") << endl
<< _(" -r, --requeststat request SMS status report") << endl
<< _(" -s, --spool spool directory for outgoing SMS")
<< endl
<< _(" -t, --store name of SMS store to use for flush\n"
" and/or temporary SMS storage") << endl
<< endl
<< _(" -v, --version prints version and exits") << endl
<< _(" -X, --xonxoff switch on software handshake") << endl
<< endl
<< _(" sms_type may be any combination of") << endl << endl
<< _(" sms, no_sms controls reception of normal SMS")
<< endl
<< _(" cb, no_cb controls reception of cell broadcast"
" messages") << endl
<< _(" stat, no_stat controls reception of status reports")
<< endl << endl
<< _(" default is \"sms cb stat\"") << endl << endl
<< _("If no action is given, the SMS is printed to stdout")
<< endl << endl;
exit(0);
break;
case '?':
throw GsmException(_("unknown option"), ParameterError);
break;
}
// find out which kind of message to route
for (int i = optind; i < argc; ++i)
{
string s = lowercase(argv[i]);
if (s == "sms")
enableSMS = true;
else if (s == "no_sms")
enableSMS = false;
else if (s == "cb")
enableCB = true;
else if (s == "no_cb")
enableCB = false;
else if (s == "stat")
enableStat = true;
else if (s == "no_stat")
enableStat = false;
}
// register signal handler for terminate signal
struct sigaction terminateAction;
terminateAction.sa_handler = terminateHandler;
sigemptyset(&terminateAction.sa_mask);
terminateAction.sa_flags = SA_RESTART;
if (sigaction(SIGINT, &terminateAction, NULL) != 0 ||
sigaction(SIGTERM, &terminateAction, NULL) != 0)
throw GsmException(
stringPrintf(_("error when calling sigaction() (errno: %d/%s)"),
errno, strerror(errno)),
OSError);
// open GSM device
MeTa m(new UnixSerialPort(device,
baudrate == "" ? DEFAULT_BAUD_RATE :
baudRateStrToSpeed(baudrate), initString,
swHandshake));
me = &m;
// if flush option is given get all SMS from store and dispatch them
if (flushSMS)
{
if (storeName == "")
throw GsmException(_("store name must be given for flush option"),
ParameterError);
SMSStoreRef store = me->getSMSStore(storeName);
for (SMSStore::iterator s = store->begin(); s != store->end(); ++s)
if (! s->empty())
{
string result = _("Type of message: ");
switch (s->message()->messageType())
{
case SMSMessage::SMS_DELIVER:
result += _("SMS message\n");
break;
case SMSMessage::SMS_SUBMIT_REPORT:
result += _("submit report message\n");
break;
case SMSMessage::SMS_STATUS_REPORT:
result += _("status report message\n");
break;
}
result += s->message()->toString();
doAction(action, result);
store->erase(s);
}
}
// set default SMS store if -t option was given
if (storeName != "")
m.setSMSStore(storeName, 3);
// switch message service level to 1
// this enables SMS routing to TA
m.setMessageService(1);
// switch on SMS routing
m.setSMSRoutingToTA(enableSMS, enableCB, enableStat,
onlyReceptionIndication);
// register event handler
m.setEventHandler(new EventHandler());
// wait for new messages
bool exitScheduled = false;
while (1)
{
struct timeval timeoutVal;
timeoutVal.tv_sec = 5;
timeoutVal.tv_usec = 0;
m.waitEvent(&timeoutVal);
// if it returns, there was an event or a timeout
while (newMessages.size() > 0)
{
// get first new message and remove it from the vector
SMSMessageRef newSMSMessage = newMessages.begin()->_newSMSMessage;
CBMessageRef newCBMessage = newMessages.begin()->_newCBMessage;
GsmEvent::SMSMessageType messageType =
newMessages.begin()->_messageType;
int index = newMessages.begin()->_index;
string storeName = newMessages.begin()->_storeName;
newMessages.erase(newMessages.begin());
// process the new message
string result = _("Type of message: ");
switch (messageType)
{
case GsmEvent::NormalSMS:
result += _("SMS message\n");
break;
case GsmEvent::CellBroadcastSMS:
result += _("cell broadcast message\n");
break;
case GsmEvent::StatusReportSMS:
result += _("status report message\n");
break;
}
if (! newSMSMessage.isnull())
result += newSMSMessage->toString();
else if (! newCBMessage.isnull())
result += newCBMessage->toString();
else
{
SMSStoreRef store = me->getSMSStore(storeName);
if (messageType == GsmEvent::CellBroadcastSMS)
result += (*store.getptr())[index].cbMessage()->toString();
else
result += (*store.getptr())[index].message()->toString();
store->erase(store->begin() + index);
}
// call the action
doAction(action, result);
}
// if no new SMS came in and program exit was scheduled, then exit
if (exitScheduled)
exit(0);
// handle terminate signal
if (terminateSent)
{
exitScheduled = true;
// switch off SMS routing
try
{
m.setSMSRoutingToTA(false, false, false);
}
catch (GsmException &ge)
{
// some phones (e.g. Motorola Timeport 260) don't allow to switch
// off SMS routing which results in an error. Just ignore this.
}
// the AT sequences involved in switching of SMS routing
// may yield more SMS events, so go round the loop one more time
}
// send spooled SMS
if (! terminateSent)
sendSMS(spoolDir, m.getAt());
}
}
catch (GsmException &ge)
{
cerr << argv[0] << _("[ERROR]: ") << ge.what() << endl;
if (ge.getErrorClass() == MeTaCapabilityError)
cerr << argv[0] << _("[ERROR]: ")
<< _("(try setting sms_type, please refer to gsmsmsd manpage)")
<< endl;
return 1;
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -