本文整理汇总了C++中TransactionEntry类的典型用法代码示例。如果您正苦于以下问题:C++ TransactionEntry类的具体用法?C++ TransactionEntry怎么用?C++ TransactionEntry使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了TransactionEntry类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: assert
void Control::AssignmentCompleteHandler(const L3AssignmentComplete *confirm, TCHFACCHLogicalChannel *TCH)
{
// The assignment complete handler is used to
// tie together split transactions across a TCH assignment
// in non-VEA call setup.
assert(TCH);
assert(confirm);
LOG(DEBUG) << *confirm;
// Check the transaction table to know what to do next.
TransactionEntry transaction;
if (!gTransactionTable.find(TCH->transactionID(),transaction)) {
LOG(WARN) << "Assignment Complete with no transaction record for ID " << TCH->transactionID();
throw UnexpectedMessage();
}
LOG(INFO) << "service="<<transaction.service().type();
// These "controller" functions don't return until the call is cleared.
switch (transaction.service().type()) {
case L3CMServiceType::MobileOriginatedCall:
MOCController(transaction,TCH);
break;
case L3CMServiceType::MobileTerminatedCall:
MTCController(transaction,TCH);
break;
default:
LOG(WARN) << "unsupported service " << transaction.service();
throw UnsupportedMessage(transaction.ID());
}
// If we got here, the call is cleared.
}
开发者ID:LucaBongiorni,项目名称:FuzzingProject,代码行数:32,代码来源:RadioResource.cpp
示例2: clearTransactionHistory
void Control::clearTransactionHistory( TransactionEntry& transaction )
{
SIP::SIPEngine& engine = transaction.SIP();
LOG(DEBUG) << engine.callID()<<" "<< transaction.ID();
gSIPInterface.removeCall(engine.callID());
gTransactionTable.remove(transaction.ID());
}
开发者ID:EricYoel,项目名称:openbts-2.6,代码行数:7,代码来源:ControlCommon.cpp
示例3: frames
/**
Check GSM signalling.
Can block for up to 52 GSM L1 frames (240 ms) because LCH::send is blocking.
@param transaction The call's TransactionEntry.
@param LCH The call's logical channel (TCH/FACCH or SDCCH).
@return true If the call was cleared.
*/
bool updateGSMSignalling(TransactionEntry &transaction, LogicalChannel *LCH, unsigned timeout=0)
{
if (transaction.Q931State()==TransactionEntry::NullState) return true;
// Any Q.931 timer expired?
if (transaction.timerExpired()) {
// Cause 0x66, "recover on timer expiry"
abortCall(transaction,LCH,L3Cause(0x66));
return true;
}
// Look for a control message from MS side.
if (L3Frame *l3 = LCH->recv(timeout)) {
// Check for lower-layer error.
if (l3->primitive() == ERROR) return true;
// Parse and dispatch.
L3Message *l3msg = parseL3(*l3);
delete l3;
bool cleared = false;
if (l3msg) {
LOG(DEBUG) << "received " << *l3msg;
cleared = callManagementDispatchGSM(transaction, LCH, l3msg);
delete l3msg;
}
return cleared;
}
// If we are here, we have timed out, but assume the call is still running.
return false;
}
开发者ID:0x7678,项目名称:openbts-uhd,代码行数:37,代码来源:CallControl.cpp
示例4: addID
void Pager::addID(const FuzzingL3MobileIdentity& newID, ChannelType chanType,
TransactionEntry& transaction, unsigned wLife)
{
transaction.Q931State(TransactionEntry::Paging);
transaction.T3113().set(wLife);
gTransactionTable.update(transaction);
// Add a mobile ID to the paging list for a given lifetime.
mLock.lock();
// If this ID is already in the list, just reset its timer.
// Uhg, another linear time search.
// This would be faster if the paging list were ordered by ID.
// But the list should usually be short, so it may not be worth the effort.
for (PagingEntryList::iterator lp = mPageIDs.begin(); lp != mPageIDs.end(); ++lp) {
if (lp->FuzzingID()==newID) {
LOG(DEBUG) << newID << " already in table";
lp->renew(wLife);
mPageSignal.signal();
mLock.unlock();
return;
}
}
// If this ID is new, put it in the list.
mPageIDs.push_back(PagingEntry(newID,chanType,transaction.ID(),wLife));
LOG(INFO) << newID << " added to table";
mPageSignal.signal();
mLock.unlock();
}
开发者ID:LucaBongiorni,项目名称:FuzzingProject,代码行数:27,代码来源:RadioResource.cpp
示例5: callManagementLoop
/**
This is the standard call manangement loop, regardless of the origination type.
This function returns when the call is cleared and the channel is released.
@param transaction The transaction record for this call, will be cleared on exit.
@param TCH The TCH+FACCH for the call.
*/
void callManagementLoop(TransactionEntry &transaction, TCHFACCHLogicalChannel* TCH)
{
LOG(INFO) << transaction.subscriber() << " call connected";
transaction.SIP().FlushRTP();
// poll everything until the call is cleared
while (!pollInCall(transaction,TCH)) { }
clearTransactionHistory(transaction);
}
开发者ID:0x7678,项目名称:openbts-uhd,代码行数:14,代码来源:CallControl.cpp
示例6: forceSIPClearing
/**
Force clearing on the SIP side.
@param transaction The call transaction record.
*/
void forceSIPClearing(TransactionEntry& transaction)
{
LOG(INFO) << "SIP state " << transaction.SIP().state();
if (transaction.SIP().state()==SIP::Cleared) return;
if (transaction.SIP().state()!=SIP::Clearing) {
// This also changes the SIP state to "clearing".
transaction.SIP().MODSendBYE();
} else {
transaction.SIP().MODResendBYE();
}
transaction.SIP().MODWaitForOK();
gTransactionTable.update(transaction);
}
开发者ID:0x7678,项目名称:openbts-uhd,代码行数:17,代码来源:CallControl.cpp
示例7: update
void TransactionTable::update(const TransactionEntry& value)
{
// ID==0 is a non-valid special case.
assert(value.ID());
mLock.lock();
if (mTable.find(value.ID())==mTable.end()) {
mLock.unlock();
LOG(WARN) << "attempt to update non-existent transaction entry with key " << value.ID();
return;
}
mTable[value.ID()]=value;
mLock.unlock();
}
开发者ID:EricYoel,项目名称:openbts-2.6,代码行数:13,代码来源:ControlCommon.cpp
示例8: add
void TransactionTable::add(const TransactionEntry& value)
{
LOG(INFO) << "new transaction " << value;
mLock.lock();
mTable[value.ID()]=value;
mLock.unlock();
}
开发者ID:EricYoel,项目名称:openbts-2.6,代码行数:7,代码来源:ControlCommon.cpp
示例9: updateCallTraffic
/**
Update vocoder data transfers in both directions.
@param transaction The transaction object for this call.
@param TCH The traffic channel for this call.
@return True if anything was transferred.
*/
bool updateCallTraffic(TransactionEntry &transaction, TCHFACCHLogicalChannel *TCH)
{
bool activity = false;
SIPEngine& engine = transaction.SIP();
// Transfer in the downlink direction (RTP->GSM).
// Blocking call. On average returns 1 time per 20 ms.
// Returns non-zero if anything really happened.
// Make the rxFrame buffer big enough for G.711.
unsigned char rxFrame[160];
if (engine.RxFrame(rxFrame)) {
activity = true;
TCH->sendTCH(rxFrame);
}
// Transfer in the uplink direction (GSM->RTP).
// Flush FIFO to limit latency.
unsigned maxQ = gConfig.getNum("GSM.MaxSpeechLatency");
while (TCH->queueSize()>maxQ) delete[] TCH->recvTCH();
if (unsigned char *txFrame = TCH->recvTCH()) {
activity = true;
// Send on RTP.
engine.TxFrame(txFrame);
delete[] txFrame;
}
// Return a flag so the caller will know if anything transferred.
return activity;
}
开发者ID:0x7678,项目名称:openbts-uhd,代码行数:37,代码来源:CallControl.cpp
示例10: forceGSMClearing
/**
Force clearing on the GSM side.
@param transaction The call transaction record.
@param LCH The logical channel.
@param cause The L3 abort cause.
*/
void forceGSMClearing(TransactionEntry& transaction, LogicalChannel *LCH, const L3Cause& cause)
{
LOG(INFO) << "Q.931 state " << transaction.Q931State();
if (transaction.Q931State()==TransactionEntry::NullState) return;
if (!transaction.clearing()) {
LCH->send(L3Disconnect(1-transaction.TIFlag(),transaction.TIValue(),cause));
}
LCH->send(L3ReleaseComplete(1-transaction.TIFlag(),transaction.TIValue()));
LCH->send(L3ChannelRelease());
transaction.resetTimers();
transaction.Q931State(TransactionEntry::NullState);
LCH->send(RELEASE);
gTransactionTable.update(transaction);
}
开发者ID:0x7678,项目名称:openbts-uhd,代码行数:20,代码来源:CallControl.cpp
示例11: assert
void Control::MOSMSController(const GSM::L3CMServiceRequest *req, GSM::LogicalChannel *LCH)
{
assert(req);
assert(req->serviceType().type() == GSM::L3CMServiceType::ShortMessage);
assert(LCH);
assert(LCH->type() != GSM::SACCHType);
LOG(INFO) << "MOSMS, req " << *req;
// If we got a TMSI, find the IMSI.
// Note that this is a copy, not a reference.
GSM::L3MobileIdentity mobileID = req->mobileID();
resolveIMSI(mobileID,LCH);
// Create a transaction record.
TransactionEntry *transaction = new TransactionEntry(gConfig.getStr("SIP.Proxy.SMS").c_str(),mobileID,LCH);
gTransactionTable.add(transaction);
LOG(DEBUG) << "MOSMS: transaction: " << *transaction;
// See GSM 04.11 Arrow Diagram A5 for the transaction
// Step 1 MS->Network CP-DATA containing RP-DATA
// Step 2 Network->MS CP-ACK
// Step 3 Network->MS CP-DATA containing RP-ACK
// Step 4 MS->Network CP-ACK
// LAPDm operation, from GSM 04.11, Annex F:
// """
// Case A: Mobile originating short message transfer, no parallel call:
// The mobile station side will initiate SAPI 3 establishment by a SABM command
// on the DCCH after the cipher mode has been set. If no hand over occurs, the
// SAPI 3 link will stay up until the last CP-ACK is received by the MSC, and
// the clearing procedure is invoked.
// """
// FIXME: check provisioning
if (gConfig.getNum("GSM.Authentication")||gConfig.getNum("GSM.Encryption")) {
AuthenticationParameters authParams(mobileID);
registerIMSI(authParams, LCH);
authenticate(authParams, LCH);
}
// Let the phone know we're going ahead with the transaction.
if (LCH->isDecrypting()) {
LOG(INFO) << "Decryption ACTIVE for:" << mobileID << " CMServiceAccept NOT sent, because CipherModeCommand implies it.";
}
else {
LOG(INFO) << "Decryption NOT active for: " << mobileID << " Sending CMServiceAccept";
LCH->send(GSM::L3CMServiceAccept());
}
// Wait for SAP3 to connect.
// The first read on SAP3 is the ESTABLISH primitive.
delete getFrameSMS(LCH,GSM::ESTABLISH);
// Step 1
// Now get the first message.
// Should be CP-DATA, containing RP-DATA.
GSM::L3Frame *CM = getFrameSMS(LCH);
LOG(DEBUG) << "data from MS " << *CM;
if (CM->MTI()!=CPMessage::DATA) {
LOG(NOTICE) << "unexpected SMS CP message with TI=" << CM->MTI();
delete CM;
throw UnexpectedMessage();
}
unsigned L3TI = CM->TI() | 0x08;
transaction->L3TI(L3TI);
// Step 2
// Respond with CP-ACK.
// This just means that we got the message.
LOG(INFO) << "sending CPAck";
LCH->send(CPAck(L3TI),3);
// Parse the message in CM and process RP part.
// This is where we actually parse the message and send it out.
// FIXME -- We need to set the message ref correctly,
// even if the parsing fails.
// The compiler gives a warning here. Let it. It will remind someone to fix it.
unsigned ref;
bool success = false;
try {
CPData data;
data.parse(*CM);
LOG(INFO) << "CPData " << data;
// Transfer out the RPDU -> TPDU -> delivery.
ref = data.RPDU().reference();
// This handler invokes higher-layer parsers, too.
success = handleRPDU(transaction,data.RPDU());
}
catch (SMSReadError) {
LOG(WARNING) << "SMS parsing failed (above L3)";
// Cause 95, "semantically incorrect message".
LCH->send(CPData(L3TI,RPError(95,ref)),3);
delete CM;
throw UnexpectedMessage();
}
catch (GSM::L3ReadError) {
LOG(WARNING) << "SMS parsing failed (in L3)";
//.........这里部分代码省略.........
开发者ID:vulkan-telecom,项目名称:openbts-2.8,代码行数:101,代码来源:SMSControl.cpp
示例12: assert
void Control::PagingResponseHandler(const L3PagingResponse* resp, LogicalChannel* DCCH)
{
assert(resp);
assert(DCCH);
LOG(INFO) << *resp;
// If we got a TMSI, find the IMSI.
L3MobileIdentity mobileID = resp->mobileIdentity();
if (mobileID.type()==TMSIType) {
const char *IMSI = gTMSITable.IMSI(mobileID.TMSI());
if (IMSI) mobileID = L3MobileIdentity(IMSI);
else {
// Don't try too hard to resolve.
// The handset is supposed to respond with the same ID type as in the request.
LOG(NOTICE) << "Paging Reponse with non-valid TMSI";
// Cause 0x60 "Invalid mandatory information"
DCCH->send(L3ChannelRelease(0x60));
return;
}
}
// Delete the Mobile ID from the paging list to free up CCCH bandwidth.
// ... if it was not deleted by a timer already ...
gBTS.pager().removeID(mobileID);
// Find the transction table entry that was created when the phone was paged.
// We have to look up by mobile ID since the paging entry may have been
// erased before this handler was called. That's too bad.
// HACK -- We also flush stray transactions until we find what we
// are looking for.
TransactionEntry transaction;
while (true) {
if (!gTransactionTable.find(mobileID,transaction)) {
LOG(WARN) << "Paging Reponse with no transaction record for " << mobileID;
// Cause 0x41 means "call already cleared".
DCCH->send(L3ChannelRelease(0x41));
return;
}
// We are looking for a mobile-terminated transaction.
// The transaction controller will take it from here.
switch (transaction.service().type()) {
case L3CMServiceType::MobileTerminatedCall:
MTCStarter(transaction, DCCH, mobileID);
return;
case L3CMServiceType::TestCall:
TestCall(transaction, DCCH);
return;
case L3CMServiceType::MobileTerminatedShortMessage:
MTSMSController(transaction, DCCH);
return;
default:
// Flush stray MOC entries.
// There should not be any, but...
LOG(WARN) << "flushing stray " << transaction.service().type() << " transaction entry";
gTransactionTable.remove(transaction.ID());
continue;
}
}
// The transaction may or may not be cleared,
// depending on the assignment type.
}
开发者ID:tomaskopsa,项目名称:OpenBTS,代码行数:61,代码来源:RadioResource.cpp
示例13: LOG
bool SIPInterface::checkInvite( osip_message_t * msg )
{
LOG(DEBUG);
// Is there even a method?
const char *method = msg->sip_method;
if (!method) return false;
// Check for INVITE or MESSAGE methods.
GSM::ChannelType requiredChannel;
bool channelAvailable = false;
bool shouldPage = true;
GSM::L3CMServiceType serviceType;
if (strcmp(method,"INVITE") == 0) {
// INVITE is for MTC.
// Set the required channel type to match the assignment style.
if (gConfig.defines("GSM.VEA")) {
// Very early assignment.
requiredChannel = GSM::TCHFType;
channelAvailable = gBTS.TCHAvailable();
} else {
// Early assignment
requiredChannel = GSM::SDCCHType;
channelAvailable = gBTS.SDCCHAvailable() && gBTS.TCHAvailable();
}
serviceType = L3CMServiceType::MobileTerminatedCall;
}
else if (strcmp(method,"MESSAGE") == 0) {
// MESSAGE is for MTSMS or USSD
if ( strcmp(gConfig.getStr("USSD.SIP.user"), msg->from->url->username)==0
&& strcmp(gConfig.getStr("USSD.SIP.domain"), msg->from->url->host)==0)
{
LOG(INFO) << "received MESSAGE is USSD from: "
<< msg->from->url->username << "@" << msg->from->url->host;
requiredChannel = GSM::SDCCHType;
// TODO:: Understand how to behave when we need to page?
channelAvailable = true; //gBTS.SDCCHAvailable();
serviceType = L3CMServiceType::SupplementaryService;
}
else
{
LOG(INFO) << "received MESSAGE is SMS from: "
<< msg->from->url->username << "@" << msg->from->url->host;
requiredChannel = GSM::SDCCHType;
channelAvailable = gBTS.SDCCHAvailable();
serviceType = L3CMServiceType::MobileTerminatedShortMessage;
}
}
else {
// We must not handle this method.
LOG(DEBUG) << "non-initiating SIP method " << method;
return false;
}
// Check gBTS for channel availability.
if (!channelAvailable) {
// FIXME -- Send 503 "Service Unavailable" response on SIP interface.
LOG(NOTICE) << "MTC CONGESTION, no " << requiredChannel << " availble for assignment";
return false;
}
LOG(INFO) << "set up MTC paging for channel=" << requiredChannel;
// Get call_id from invite message.
if (!msg->call_id) {
// FIXME -- Send appropriate error on SIP interface.
LOG(WARN) << "Incoming INVITE/MESSAGE with no call ID";
return false;
}
// Don't free call_id_num. It points into msg->call_id.
const char * call_id_num = osip_call_id_get_number(msg->call_id);
// Get request username (IMSI) from invite.
// Form of the name is IMSI<digits>, and it should always be 19 char.
const char * IMSI = msg->req_uri->username;
LOG(INFO) << msg->sip_method << " to "<< IMSI;
// IMSIs are 14 or 15 char + "IMSI" prefix
unsigned namelen = strlen(IMSI);
if ((namelen>19)||(namelen<18)) {
LOG(WARN) << "INVITE/MESSAGE with malformed username \"" << IMSI << "\"";
return false;
}
// Skip first 4 char "IMSI".
IMSI+=4;
// Make the mobile id we need for transaction and paging entries.
L3MobileIdentity mobile_id(IMSI);
// Check SIP map. Repeated entry? Page again.
// Skip this for USSD.
if ( mSIPMap.map().readNoBlock(call_id_num) != NULL) {
TransactionEntry transaction;
if (!gTransactionTable.find(mobile_id,transaction)) {
// FIXME -- Send "call leg non-existent" response on SIP interface.
LOG(WARN) << "repeated INVITE/MESSAGE with no transaction record";
// Delete the bogus FIFO.
mSIPMap.remove(call_id_num);
return false;
}
LOG(INFO) << "repeated SIP INVITE/MESSAGE, repaging for transaction " << transaction;
gBTS.pager().addID(mobile_id,requiredChannel,transaction);
//.........这里部分代码省略.........
开发者ID:0x7678,项目名称:openbts-uhd,代码行数:101,代码来源:SIPInterface.cpp
示例14: assert
/**
This function starts MOC on the SDCCH to the point of TCH assignment.
@param req The CM Service Request that started all of this.
@param LCH The logical used to initiate call setup.
*/
void Control::MOCStarter(const GSM::L3CMServiceRequest* req, GSM::LogicalChannel *LCH)
{
assert(LCH);
assert(req);
LOG(INFO) << *req;
// Determine if very early assignment already happened.
bool veryEarly = (LCH->type()==GSM::FACCHType);
// If we got a TMSI, find the IMSI.
// Note that this is a copy, not a reference.
GSM::L3MobileIdentity mobileID = req->mobileID();
resolveIMSI(mobileID,LCH);
// FIXME -- At this point, verify the that subscriber has access to this service.
// If the subscriber isn't authorized, send a CM Service Reject with
// cause code, 0x41, "requested service option not subscribed",
// followed by a Channel Release with cause code 0x6f, "unspecified".
// Otherwise, proceed to the next section of code.
// For now, we are assuming that the phone won't make a call if it didn't
// get registered.
// Allocate a TCH for the call, if we don't have it already.
GSM::TCHFACCHLogicalChannel *TCH = NULL;
if (!veryEarly) {
TCH = allocateTCH(dynamic_cast<GSM::LogicalChannel*>(LCH));
// It's OK to just return on failure; allocateTCH cleaned up already,
// and the SIP side and transaction record don't exist yet.
if (TCH==NULL) return;
}
// Let the phone know we're going ahead with the transaction.
LOG(INFO) << "sending CMServiceAccept";
LCH->send(GSM::L3CMServiceAccept());
// Get the Setup message.
// GSM 04.08 5.2.1.2
GSM::L3Message* msg_setup = getMessage(LCH);
const GSM::L3Setup *setup = dynamic_cast<const GSM::L3Setup*>(msg_setup);
if (!setup) {
if (msg_setup) {
LOG(WARNING) << "Unexpected message " << *msg_setup;
delete msg_setup;
}
throw UnexpectedMessage();
}
LOG(INFO) << *setup;
// Pull out the L3 short transaction information now.
// See GSM 04.07 11.2.3.1.3.
// Set the high bit, since this TI came from the MS.
unsigned L3TI = setup->TI() | 0x08;
if (!setup->haveCalledPartyBCDNumber()) {
// FIXME -- This is quick-and-dirty, not following GSM 04.08 5.
LOG(WARNING) << "MOC setup with no number";
// Cause 0x60 "Invalid mandatory information"
LCH->send(GSM::L3ReleaseComplete(L3TI,0x60));
LCH->send(GSM::L3ChannelRelease());
// The SIP side and transaction record don't exist yet.
// So we're done.
delete msg_setup;
return;
}
LOG(DEBUG) << "SIP start engine";
// Get the users sip_uri by pulling out the IMSI.
//const char *IMSI = mobileID.digits();
// Pull out Number user is trying to call and use as the sip_uri.
const char *bcdDigits = setup->calledPartyBCDNumber().digits();
// Create a transaction table entry so the TCH controller knows what to do later.
// The transaction on the TCH will be a continuation of this one.
TransactionEntry *transaction = new TransactionEntry(
gConfig.getStr("SIP.Proxy.Speech").c_str(),
mobileID,
LCH,
req->serviceType(),
L3TI,
setup->calledPartyBCDNumber());
LOG(DEBUG) << "transaction: " << *transaction;
gTransactionTable.add(transaction);
// At this point, we have enough information start the SIP call setup.
// We also have a SIP side and a transaction that will need to be
// cleaned up on abort or clearing.
// Now start a call by contacting asterisk.
// Engine methods will return their current state.
// The remote party will start ringing soon.
LOG(DEBUG) << "starting SIP (INVITE) Calling "<<bcdDigits;
unsigned basePort = allocateRTPPorts();
transaction->MOCSendINVITE(bcdDigits,gConfig.getStr("SIP.Local.IP").c_str(),basePort,SIP::RTPGSM610);
LOG(DEBUG) << "transaction: " << *transaction;
// Once we can start SIP call setup, send Call Proceeding.
//.........这里部分代码省略.........
开发者ID:haristiantosp,项目名称:BBB,代码行数:101,代码来源:CallControl.cpp
示例15: LOG
void Control::MTCController(TransactionEntry& transaction, TCHFACCHLogicalChannel* TCH)
{
// Early Assignment Mobile Terminated Call.
// Transaction table in 04.08 7.3.3 figure 7.10a
LOG(DEBUG) << "transaction: " << transaction;
unsigned L3TI = transaction.TIValue();
assert(transaction.TIFlag()==1);
assert(TCH);
// Get the alerting message.
LOG(INFO) << "waiting for GSM Alerting and Connect";
while (transaction.Q931State()!=TransactionEntry::Active) {
if (updateGSMSignalling(transaction,TCH,1000)) return;
if (transaction.Q931State()==TransactionEntry::Active) break;
if (transaction.Q931State()==TransactionEntry::CallReceived) {
LOG(DEBUG) << "sending SIP Ringing";
transaction.SIP().MTCSendRinging();
}
// Check for SIP cancel, too.
if (transaction.SIP().MTCWaitForACK()==SIP::Fail) {
return abortCall(transaction,TCH,L3Cause(0x7F));
}
}
gTransactionTable.update(transaction);
LOG(INFO) << "allocating port and sending SIP OKAY";
unsigned RTPPorts = allocateRTPPorts();
SIPState state = transaction.SIP().MTCSendOK(RTPPorts,SIP::RTPGSM610);
while (state!=SIP::Active) {
LOG(DEBUG) << "wait for SIP OKAY-ACK";
if (updateGSMSignalling(transaction,TCH)) return;
state = transaction.SIP().MTCWaitForACK();
LOG(DEBUG) << "SIP call state "<< state;
switch (state) {
case SIP::Active:
break;
case SIP::Fail:
return abortCall(transaction,TCH,L3Cause(0x7F));
case SIP::Timeout:
state = transaction.SIP().MTCSendOK(RTPPorts,SIP::RTPGSM610);
break;
case SIP::Connecting:
break;
default:
LOG(NOTICE) << "SIP unexpected state " << state;
break;
}
}
transaction.SIP().MTCInitRTP();
gTransactionTable.update(transaction);
// Send Connect Ack to make it all official.
LOG(DEBUG) << "MTC send GSM Connect Acknowledge";
TCH->send(L3ConnectAcknowledge(0,L3TI));
// At this point, everything is ready to run for the call.
// The radio link should have been cleared with the call.
gTransactionTable.update(transaction);
callManagementLoop(transaction,TCH);
}
开发者ID:0x7678,项目名称:openbts-uhd,代码行数:61,代码来源:CallControl.cpp
示例16: assert
void Control::MTCStarter(TransactionEntry& transaction, LogicalChannel *LCH)
{
assert(LCH);
LOG(INFO) << "MTC on " << LCH->type() << " transaction: "<< transaction;
// Determine if very early assigment already happened.
bool veryEarly = false;
if (LCH->type()==FACCHType) veryEarly=true;
// Allocate a TCH for the call.
TCHFACCHLogicalChannel *TCH = NULL;
if (!veryEarly) {
TCH = allocateTCH(dynamic_cast<SDCCHLogicalChannel*>(LCH));
// It's OK to just return on failure; allocateTCH cleaned up already.
// The orphaned transaction will be cleared automatically later.
if (TCH==NULL) return;
}
// Get transaction identifiers.
// This transaction was created by the SIPInterface when it
// processed the INVITE that started this call.
if (!veryEarly) TCH->transactionID(transaction.ID());
LCH->transactionID(transaction.ID());
unsigned L3TI = transaction.TIValue();
assert(transaction.TIFlag()==1);
// GSM 04.08 5.2.2.1
LOG(INFO) << "sending GSM Setup to call " << transaction.calling();
LCH->send(L3Setup(0,L3TI,L3CallingPartyBCDNumber(transaction.calling())));
transaction.T303().set();
transaction.Q931State(TransactionEntry::CallPresent);
gTransactionTable.update(transaction);
// Wait for Call Confirmed message.
LOG(DEBUG) << "wait for GSM Call Confirmed";
while (transaction.Q931State()!=TransactionEntry::MTCConfirmed) {
if (transaction.SIP().MTCSendTrying()==SIP::Fail) {
LOG(NOTICE) << "call failed on SIP side";
LCH->send(RELEASE);
// Cause 0x03 is "no route to destination"
return abortCall(transaction,LCH,L3Cause(0x03));
}
// FIXME -- What's the proper timeout here?
// It's the SIP TRYING timeout, whatever that is.
if (updateGSMSignalling(transaction,LCH,1000)) {
LOG(INFO) << "Release from GSM side";
LCH->send(RELEASE);
return;
}
// Check for SIP cancel, too.
if (transaction.SIP().MTCWaitForACK()==SIP::Fail) {
LOG(NOTICE) << "call failed on SIP side";
LCH->send(RELEASE);
// Cause 0x10 is "normal clearing"
return abortCall(transaction,LCH,L3Cause(0x10));
}
}
// The transaction is moving to the MTCController.
// Once this update happens, don't change the transaction object again in this function.
gTransactionTable.update(transaction);
LOG(DEBUG) << "transaction: " << transaction;
if (veryEarly) {
// For very early assignment, we need a mode change.
static const L3ChannelMode mode(L3ChannelMode::SpeechV1);
LCH->send(L3ChannelModeModify(LCH->channelDescription(),mode));
L3Message* msg_ack = getMessage(LCH);
const L3ChannelModeModifyAcknowledge *ack =
dynamic_cast<L3ChannelModeModifyAcknowledge*>(msg_ack);
if (!ack) {
if (msg_ack) {
LOG(WARN) << "Unexpected message " << *msg_ack;
delete msg_ack;
}
throw UnexpectedMessage(transaction.ID());
}
// Cause 0x06 is "channel unacceptable"
bool modeOK = (ack->mode()==mode);
delete msg_ack;
if (!modeOK) return abortCall(transaction,LCH,L3Cause(0x06));
MTCController(transaction,dynamic_cast<TCHFACCHLogicalChannel*>(LCH));
}
else {
// For late assignment, send the TCH assignment now.
// This dispatcher on the next channel will continue the transaction.
assignTCHF(transaction,dynamic_cast<SDCCHLogicalChannel*>(LCH),TCH);
}
}
开发者ID:0x7678,项目名称:openbts-uhd,代码行数:89,代码来源:CallControl.cpp
示例17: assert
void Control::MTSMSController(TransactionEntry& transaction,
LogicalChannel *LCH)
{
assert(LCH);
// HACK: At this point if the message starts with "RRLP" then we don't do SMS at all,
// but instead to an RRLP transaction over the already allocated LogicalChannel.
const char* m = transaction.message(); // NOTE - not very nice, my way of checking.
if ((strlen(m) > 4) && (std::string("RRLP") == std::string(m, m+4))) {
const char *transaction_hex = transaction.message() + 4;
BitVector rrlp_position_request(strlen(transaction_hex)*4);
rrlp_position_request.unhex(transaction_hex);
LOG(INFO) << "MTSMS: Sending RRLP";
// TODO - how to get mobID here?
L3MobileIdentity mobID = L3MobileIdentity("000000000000000");
RRLP::PositionResult pr = GSM::RRLP::doRRLPQuery(mobID, LCH, rrlp_position_request);
if (pr.mValid) // in this case we only want to log the results which contain lat/lon
logMSInfo(LCH, pr, mobID);
LOG(INFO) << "MTSMS: Closing channel after RRLP";
LCH->send(L3ChannelRelease());
clearTransactionHistory(transaction);
return;
}
// See GSM 04.11 Arrow Diagram A5 for the transaction
// Step 1 Network->MS CP-DATA containing RP-DATA
// Step 2 MS->Network CP-ACK
// Step 3 MS->Network CP-DATA containing RP-ACK
// Step 4 Network->MS CP-ACK
// LAPDm operation, from GSM 04.11, Annex F:
// """
// Case B: Mobile terminating short message transfer, no parallel call:
// The network side, i.e. the BSS will initiate SAPI3 establishment by a
// SABM command on the SDCCH when the first CP-Data message is received
// from the MSC. If no hand over occurs, the link will stay up until the
// MSC has given the last CP-ack and invokes the clearing procedure.
// """
LOG(INFO) << "MTSMS: transaction: "<< transaction;
LCH->transactionID(transaction.ID());
SIPEngine& engine = transaction.SIP();
// Update transaction state.
transaction.Q931State(TransactionEntry::SMSDelivering);
gTransactionTable.update(transaction);
try {
bool success = deliverSMSToMS(transaction.calling().digits(),transaction.message(),random()%7,LCH);
// Close the Dm channel.
LOG(INFO) << "MTSMS: closing";
LCH->send(L3ChannelRelease());
// Ack in SIP domain and update transaction state.
if (success) {
engine.MTSMSSendOK();
clearTransactionHistory(transaction);
}
}
catch (UnexpectedMessage) {
// TODO -- MUST SEND PERMANENT ERROR HERE!!!!!!!!!
engine.MTSMSSendOK();
LCH->send(L3ChannelRelease());
clearTransactionHistory(transaction);
}
catch (UnsupportedMessage) {
// TODO -- MUST SEND PERMANENT ERROR HERE!!!!!!!!!
engine.MTSMSSendOK();
LCH->send(L3ChannelRelease());
clearTransactionHistory(transaction);
}
}
开发者ID:0x7678,项目名称:openbts-uhd,代码行数:73,代码来源:SMSControl.cpp
示例18: LOG
bool SIPInterface::checkInvite( osip_message_t * msg)
{
LOG(DEBUG);
// This code dispatches new transactions coming from the network-side SIP interface.
// All transactions originating here are going to be mobile-terminated.
// Yes, this method is too long and needs to be broken up into smaller steps.
// Is there even a method?
const char *method = msg->sip_method;
if (!method) return false;
// Check for INVITE or MESSAGE methods.
// Check channel availability now, too.
GSM::ChannelType requiredChannel;
bool channelAvailable = false;
GSM::L3CMServiceType serviceType;
// pretty sure strings are garbage collected
string proxy = get_return_address(msg);
if (strcmp(method,"INVITE") == 0) {
// INVITE is for MTC.
// Set the required channel type to match the assignment style.
if (gConfig.defines("Control.VEA")) {
// Very early assignment.
requiredChannel = GSM::TCHFType;
channelAvailable = gBTS.TCHAvailable();
} else {
// Early assignment
requiredChannel = GSM::SDCCHType;
channelAvailable = gBTS.SDCCHAvailable() && gBTS.TCHAvailable();
}
serviceType = L3CMServiceType::MobileTerminatedCall;
}
else if (strcmp(method,"MESSAGE") == 0) {
// MESSAGE is for MTSMS.
requiredChannel = GSM::SDCCHType;
channelAvailable = gBTS.SDCCHAvailable();
serviceType = L3CMServiceType::MobileTerminatedShortMessage;
}
else {
// Not a method handled here.
LOG(DEBUG) << "non-initiating SIP method " << method;
return false;
}
// Get request username (IMSI) from invite.
const char* IMSI = extractIMSI(msg);
if (!IMSI) {
// FIXME -- Send appropriate error (404) on SIP interface.
LOG(WARNING) << "Incoming INVITE/MESSAGE with no IMSI";
return false;
}
L3MobileIdentity mobileID(IMSI);
// Get the SIP call ID.
const char * callIDNum = extractCallID(msg);
if (!callIDNum) {
// FIXME -- Send appropriate error on SIP interface.
LOG(WARNING) << "Incoming INVITE/MESSAGE with no call ID";
return false;
}
// Find any active transaction for this IMSI with an assigned TCH or SDCCH.
GSM::LogicalChannel *chan = gTransactionTable.findChannel(mobileID);
if (chan) {
// If the type is TCH and the service is SMS, get the SACCH.
// Otherwise, for now, just say chan=NULL.
if (serviceType==L3CMServiceType::MobileTerminatedShortMessage && chan->type()==FACCHType) {
chan = chan->SACCH();
} else {
// FIXME -- This will change to support multiple transactions.
chan = NULL;
}
}
// Check SIP map. Repeated entry? Page again.
if (mSIPMap.map().readNoBlock(callIDNum) != NULL) {
TransactionEntry* transaction= gTransactionTable.find(mobileID,callIDNum);
// There's a FIFO but no trasnaction record?
if (!transaction) {
LOG(WARNING) << "repeated INVITE/MESSAGE with no transaction record";
// Delete the bogus FIFO.
mSIPMap.remove(callIDNum);
return false;
}
// There is transaction already. Send trying, if appropriate.
if (serviceType!=L3CMServiceType::MobileTerminatedShortMessage) transaction->MTCSendTrying();
// And if no channel is established yet, page again.
if (!chan) {
LOG(INFO) << "repeated SIP INVITE/MESSAGE, repaging for transaction " << *transaction;
gBTS.pager().addID(mobileID,requiredChannel,*transaction);
}
return false;
}
// So we will need a new channel.
// Check gBTS for channel availability.
if (!chan && !channelAvailable) {
// FIXME -- Send 503 "Service Unavailable" response on SIP interface.
//.........这里部分代码省略.........
开发者ID:5728136cs,项目名称:Mobile_Netze_HM_OpenBTS_Handover,代码行数:101,代码来源:SIPInterface.cpp
示例19: callManagementDispatchGSM
/**
Process a message received from the phone during a call.
This function processes all deviations from the "call connected" state.
For now, we handle call clearing and politely reject everything else.
@param transaction The transaction record for this call.
@param LCH The logical channel for the transaction.
@param message A pointer to the receiver message.
@return true If the call has been cleared and the channel released.
*/
bool callManagementDispatchGSM(TransactionEntry& transaction, LogicalChannel* LCH, const L3Message *message)
{
LOG(DEBUG) << "from " << transaction.subscriber() << " message " << *message;
// FIXME -- This dispatch section should be something more efficient with PD and MTI swtiches.
// Actually check state before taking action.
//if (transaction.SIP().state()==SIP::Cleared) return true;
//if (transaction.Q931State()==TransactionEntry::NullState) return true;
// Call connection steps.
// Connect Acknowledge
if (dynamic_cast<const L3ConnectAcknowledge*>(message)) {
LOG(INFO) << "GSM Connect Acknowledge " << transaction.subscriber();
transaction.resetTimers();
transaction.Q931State(TransactionEntry::Active);
gTransactionTable.update(transaction);
return false;
}
// Connect
// GSM 04.08 5.2.2.5 and 5.2.2.6
if (dynamic_cast<const L3Connect*>(message)) {
LOG(INFO) << "GSM Connect " << transaction.subscriber();
transaction.resetTimers();
transaction.Q931State(TransactionEntry::Active);
gTransactionTable.update(transaction);
return false;
}
// Call Confirmed
// GSM 04.08 5.2.2.3.2
// "Call Confirmed" is the GSM MTC counterpart to "Call Proceeding"
if (dynamic_cast<const L3CallConfirmed*>(message)) {
LOG(INFO) << "GSM Call Confirmed " << transaction.subscriber();
transaction.T303().reset();
transaction.T310().set();
transaction.Q931State(TransactionEntry::MTCConfirmed);
gTransactionTable.update(transaction);
return false;
}
// Alerting
// GSM 04.08 5.2.2.3.2
if (dynamic_cast<const L3Alerting*>(message)) {
LOG(INFO) << "GSM Alerting " << transaction.subscriber();
transaction.T310().reset();
transaction.T301().set();
transaction.Q931State(TransactionEntry::CallReceived);
gTransactionTable.update(transaction);
return false;
}
// Call clearing steps.
// Good diagrams in GSM 04.08 7.3.4
// FIXME -- We should be checking TI values against the transaction object.
// Disconnect (1st step of MOD)
// GSM 04.08 5.4.3.2
if (dynamic_cast<const L3Disconnect*>(message)) {
LOG(INFO) << "GSM Disconnect " << transaction.subscriber();
transaction.resetTimers();
LCH->send(L3Release(1-transaction.TIFlag(),transaction.TIValue()));
transaction.T308().set();
transaction.Q931State(TransactionEntry::ReleaseRequest);
transaction.SIP().MODSendBYE();
gTransactionTable.update(transaction);
return false;
}
// Release (2nd step of MTD)
if (dynamic_cast<const L3Release*>(message)) {
LOG(INFO) << "GSM Release " << transaction.subscriber();
transaction.resetTimers();
LCH->send(L3ReleaseComplete(1-transaction.TIFlag(),transaction.TIValue()));
LCH->send(L3ChannelRelease());
transaction.Q931State(TransactionEntry::NullState);
transaction.SIP().MTDSendOK();
gTransactionTable.update(transaction);
return true;
}
// Release
|
请发表评论