Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed MT binary SMS #22

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Empty file modified AUTHORS
100644 → 100755
Empty file.
Empty file modified CLI/CLI.cpp
100644 → 100755
Empty file.
Empty file modified CLI/CLI.h
100644 → 100755
Empty file.
Empty file modified CLI/CLIBase.cpp
100644 → 100755
Empty file.
29 changes: 27 additions & 2 deletions CLI/CLICommands.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,6 @@ static CLIStatus sendsimple(int argc, char** argv, ostream& os)
static CLIStatus sendsms(int argc, char** argv, ostream& os)
{
if (argc<4) return BAD_NUM_ARGS;

char *IMSI = argv[1];
char *srcAddr = argv[2];
string rest = "";
Expand All @@ -500,7 +499,6 @@ static CLIStatus sendsms(int argc, char** argv, ostream& os)
os << "Invalid IMSI. Enter 15 digits only.";
return BAD_VALUE;
}

// We just use the IMSI, dont try to find a tmsi.
FullMobileId msid(IMSI);
Control::TranEntry *tran = Control::TranEntry::newMTSMS(
Expand All @@ -514,6 +512,32 @@ static CLIStatus sendsms(int argc, char** argv, ostream& os)
return SUCCESS;
}

/** Submit an USSD for delivery to an IMSI on this BTS. */
static CLIStatus sendss(int argc, char** argv, ostream& os)
{
if (argc<3) return BAD_NUM_ARGS;
char *IMSI = argv[1];
string rest = argv[2];
string type = argv[3];
if (!isIMSI(IMSI)) {
os << "Invalid IMSI. Enter 15 digits only.";
return BAD_VALUE;
}

if(type[0] != '0' && type[0] != '1' && type[0] != '2'){
os << "Type must be either 0 (Encapsulate msg as a unstructuredSSNotify type), 1 (EXPERT: Do not encapsulate msg. Send it as is), 2 (Notify x 100)\n";
return BAD_VALUE;
}

FullMobileId msid(IMSI);
Control::TranEntry *tran = Control::TranEntry::newMTSS(
msid,
rest, // message body
type); // 0, 1, 2
Control::gMMLayer.mmAddMT(tran);
os << "USSD submitted for delivery" << endl;
return SUCCESS;
}

/** Print current usage loads. */
static CLIStatus printStats(int argc, char** argv, ostream& os)
Expand Down Expand Up @@ -1717,6 +1741,7 @@ void Parser::addCommands()
addCommand("shutdown", nop, "[] -- shut down via upstart OpenBTS. If OpenBTS was not started via upstart, it is a no op.");
addCommand("tmsis", tmsis, tmsisHelp);
addCommand("sendsms", sendsms, "IMSI src# message... -- send direct SMS to IMSI on this BTS, addressed from source number src#.");
addCommand("sendss", sendss, "IMSI message type -- send direct MT USSD to IMSI on this BTS. Type must be either 0 (Encapsulate msg as a unstructuredSSNotify type), 1 (EXPERT: Do not encapsulate msg. Send it as is), 2 (Notify x 100)\n");
addCommand("sendsimple", sendsimple, "IMSI src# message... -- send SMS to IMSI via SIP interface, addressed from source number src#.");
addCommand("load", printStats, "-- print the current activity loads.");
addCommand("cellid", cellID, "[MCC MNC LAC CI] -- get/set location area identity (MCC, MNC, LAC) and cell ID (CI).");
Expand Down
6 changes: 3 additions & 3 deletions CLI/CLIServer.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,10 @@ void Parser::cliServer()
close(i);
continue; // go to next socket
}
if (len < (int) sizeof(len)) // should never get here
if (nread < (int) sizeof(len))
{
char buf[BUFSIZ];
sprintf(buf, "Unable to read complete length, s.b. %d bytes, got %d bytes\n", sizeof(len), len);
char buf[BUFSIZ]; // should never get *here
sprintf(buf, "Unable to read complete length, should be %d bytes, got %d bytes\n", sizeof(len), nread);
LOG(ERR) << buf;
gReports.incr("OpenBTS.CLI.Command.ResponseFailure");
break;
Expand Down
Empty file modified CLI/Makefile.am
100644 → 100755
Empty file.
Empty file modified CLI/README.CLI
100644 → 100755
Empty file.
Empty file modified COPYING
100644 → 100755
Empty file.
Empty file modified ChangeLog
100644 → 100755
Empty file.
Empty file modified Control/CBS.cpp
100644 → 100755
Empty file.
Empty file modified Control/CBS.h
100644 → 100755
Empty file.
Empty file modified Control/CodecSet.h
100644 → 100755
Empty file.
Empty file modified Control/ControlCommon.h
100644 → 100755
Empty file.
Empty file modified Control/ControlTransfer.cpp
100644 → 100755
Empty file.
Empty file modified Control/ControlTransfer.h
100644 → 100755
Empty file.
Empty file modified Control/DCCHDispatch.cpp
100644 → 100755
Empty file.
Empty file modified Control/L3CallControl.cpp
100644 → 100755
Empty file.
Empty file modified Control/L3CallControl.h
100644 → 100755
Empty file.
Empty file modified Control/L3Handover.cpp
100644 → 100755
Empty file.
Empty file modified Control/L3Handover.h
100644 → 100755
Empty file.
Empty file modified Control/L3LogicalChannel.cpp
100644 → 100755
Empty file.
Empty file modified Control/L3LogicalChannel.h
100644 → 100755
Empty file.
29 changes: 29 additions & 0 deletions Control/L3MMLayer.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "ControlCommon.h"
#include "L3TranEntry.h"
#include "L3SMSControl.h"
#include "L3SupServ.h"
#include <SIPDialog.h>

namespace Control {
Expand Down Expand Up @@ -80,13 +81,26 @@ void MMContext::startSMSTran(TranEntry *tran)
tran->lockAndStart();
}

void MMContext::startSSTran(TranEntry *tran)
{
{
ScopedLock lock(gMMLock,__FILE__,__LINE__); // Make sure.
LOG(INFO) << "new MTSS"<<LOGVAR(tran)<<LOGVAR2("chan",this);
// Tie the transaction to this channel.
devassert(this->mmGetTran(MMContext::TE_SS).isNULL());
this->mmConnectTran(MMContext::TE_SS,tran);
initMTSS(tran);
}
}

// (pat) WARNING: If this routine returns true it has performed the gMMLock.unlock() corresponding to a lock() in the caller.
// Setting the lock in one function and releasing it in another sucks and should be fixed.
bool MMUser::mmuServiceMTQueues() // arg redundant with mmuContext->channel.
{
devassert(gMMLock.lockcnt()); // Caller locked it.
//ScopedLock lock(mmuLock,__FILE__,__LINE__);
// TODO: check for blocks on our IMSI or TMSI?
//LOG(INFO) << "SS mmuServiceMTQueues()";

// TODO: Move this to the logical channel main thread.
// Service the MMC queues.
Expand Down Expand Up @@ -118,6 +132,15 @@ bool MMUser::mmuServiceMTQueues() // arg redundant with mmuContext->channel.
return true;
}
}
if (mmuContext->mmGetTran(MMContext::TE_SS).isNULL()) {
LOG(INFO) << "SS mmuContext->mmGetTran(MMContext::TE_SS).isNULL()";
if (mmuMTSSq.size()) {
TranEntry *tran = mmuMTSSq.pop_frontr();
gMMLock.unlock();
mmuContext->startSSTran(tran);
return true;
}
}
return false;
}

Expand Down Expand Up @@ -234,6 +257,9 @@ GSM::ChannelType MMUser::mmuGetInitialChanType() const
return GSM::SDCCHType;
}
}
if (mmuMTSSq.size()){
return GSM::SDCCHType;
}
devassert(mmuMTSMSq.size());
return GSM::SDCCHType;
}
Expand Down Expand Up @@ -716,6 +742,9 @@ void MMUser::mmuAddMT(TranEntry *tran)
case L3CMServiceType::MobileTerminatedShortMessage:
mmuMTSMSq.push_back(tran);
break;
case L3CMServiceType::SupplementaryService:
mmuMTSSq.push_back(tran);
break;
default:
assert(0);
}
Expand Down
2 changes: 2 additions & 0 deletions Control/L3MMLayer.h
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class MMUser : public MemCheckMMUser /*: public RefCntBase*/ {
typedef PtrList<TranEntry> MMUQueue_t;
MMUQueue_t mmuMTCq;
MMUQueue_t mmuMTSMSq;
MMUQueue_t mmuMTSSq;
friend class MMLayer;
MMState mmuState;
MMContext* mmuContext;
Expand Down Expand Up @@ -152,6 +153,7 @@ class MMContext : public MemCheckMMContext /*: public RefCntBase*/ {
unsigned mNextTI;
InterthreadQueue<const L3Message> mmcServiceRequests; // Incoming CM Service Request messages.
void startSMSTran(TranEntry *tran);
void startSSTran(TranEntry *tran);

void MMContextInit();
void mmcFree(TermCause cause); // This is the destructor. It is not public. Can only delete from gMMLayer because we must lock the MMUserMap first.
Expand Down
Empty file modified Control/L3MobilityManagement.cpp
100644 → 100755
Empty file.
Empty file modified Control/L3MobilityManagement.h
100644 → 100755
Empty file.
62 changes: 28 additions & 34 deletions Control/L3SMSControl.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -418,50 +418,44 @@ void startMOSMS(const GSM::L3MMMessage *l3msg, MMContext *mmchan)
// Return true on success.
bool MTSMSMachine::createRPData(RPData &rp_data)
{
// TODO: Read MIME Type from smqueue!!
const char *contentType = tran()->mContentType.c_str();
// OpenBTSCLI:
// rawconfig SMS.MIMEType text/plain

int dcs=0;
bool udhi=false;
const char *contentType = gConfig.getStr("SMS.MIMEType").c_str();
PROCLOG(DEBUG)<<LOGVAR(contentType)<<LOGVAR(tran()->mMessage);
if (strncmp(contentType,"text/plain",10)==0) {
TLAddress tlcalling = TLAddress(tran()->calling().digits());
TLUserData tlmessage = TLUserData(tran()->mMessage.c_str());
PROCLOG(DEBUG)<<LOGVAR(tlcalling)<<LOGVAR(tlmessage);
TLUserData tlmessage = TLUserData(tran()->mMessage.c_str());
rp_data = RPData(this->mRpduRef,
RPAddress(gConfig.getStr("SMS.FakeSrcSMSC").c_str()),
TLDeliver(tlcalling,tlmessage,0));
} else if (strncmp(contentType,"application/vnd.3gpp.sms",24)==0) {
BitVector2 RPDUbits(strlen(tran()->mMessage.c_str())*4);
if (!RPDUbits.unhex(tran()->mMessage.c_str())) {
LOG(WARNING) << "Message is zero length which is valid";
// This is valid continue
return true;
}
} else {

try { // I suspect this is here to catch the above FIXED crash when string is zero length
RLFrame RPDU(RPDUbits);
LOG(DEBUG) << "SMS RPDU: " << RPDU;
// OpenBTSCLI:
//rawconfig SMS.MIMEType "application/vnd.3gpp.sms"
//rawconfig SMS.DCS 0
//rawconfig SMS.UDHI 0

rp_data.parse(RPDU);
LOG(DEBUG) << "SMS RP-DATA " << rp_data;
}
catch (SMSReadError) {
LOG(WARNING) << "SMS parsing failed (above L3)";
// Cause 95, "semantically incorrect message".
//LCH->l2sendf(CPData(L3TI,RPError(95,this->mRpduRef)),3); if you ever use this, it should call l3sendSms
return false;
}
catch (GSM::L3ReadError) {
LOG(WARNING) << "SMS parsing failed (in L3)";
// TODO:: send error back to the phone
return false;
BitVector2 RPDUbits(strlen(tran()->mMessage.c_str())*4);
RPDUbits.unhex(tran()->mMessage.c_str()); // hex to binary string
RPDUbits.LSB8MSB(); // bit flip ready for Tx
TLAddress tlcalling = TLAddress(tran()->calling().digits());
const char *dcsStr = gConfig.getStr("SMS.DCS").c_str();
if (strncmp(dcsStr,"0",1)!=0) { // if NOT 7 bit...
dcs=atoi(dcsStr);
}
catch (...) {
LOG(ERR) << "Unexpected throw"; // cryptic, but should never happen.
return false;
const char *udhiStr = gConfig.getStr("SMS.UDHI").c_str();
if (strncmp(udhiStr,"1",1)==0) {
udhi=true; // PDU has UDH
}
} else {
LOG(WARNING) << "Unsupported content type (in incoming SIP MESSAGE) -- type: " << contentType;
return false;
}
TLUserData tlmessage = TLUserData(dcs,RPDUbits,strlen(tran()->mMessage.c_str())/2,udhi);
rp_data = RPData(this->mRpduRef,
RPAddress(gConfig.getStr("SMS.FakeSrcSMSC").c_str()),
TLDeliver(tlcalling,tlmessage,0));
}
LOG(DEBUG) << "contentType: " << contentType << "\nrp_data: " << rp_data;
return true;
}

Expand Down
Empty file modified Control/L3SMSControl.h
100644 → 100755
Empty file.
6 changes: 6 additions & 0 deletions Control/L3StateMachine.cpp
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
#include <RRLPServer.h>
#include <Globals.h>
#include <typeinfo>
#include <iostream>

using namespace std;
using namespace GSM;
namespace Control {

Expand Down Expand Up @@ -257,6 +259,8 @@ static void handleStatus(const L3Message *l3msg, MMContext *mmchan)
static bool handleCommonMessages(const L3Message *l3msg, MMContext *mmchan, bool *deletemsg)
{
*deletemsg = true;
LOG(INFO) << "USSD " << L3CASE_RAW(l3msg->PD(),l3msg->MTI());

switch (L3CASE_RAW(l3msg->PD(),l3msg->MTI())) {
case L3CASE_RR(L3RRMessage::PagingResponse):
NewPagingResponseHandler(dynamic_cast<const L3PagingResponse*>(l3msg),mmchan);
Expand Down Expand Up @@ -602,6 +606,8 @@ static void csl3HandleFrame(const GSM::L3Frame *frame, L3LogicalChannel *lch)
l3msg = parseL3(*frame);
if (l3msg) {
WATCHINFO(lch <<" received L3 message "<<*l3msg);
//print msg to console
LOG(INFO) << "USSD RX: " << *l3msg;
} else {
LOG(ERR) <<lch<< " received unparseable Layer3 frame "<<*frame;
// We pass unparseable messages through to machineRunState1 to provide an error indication to
Expand Down
Empty file modified Control/L3StateMachine.h
100644 → 100755
Empty file.
Loading