commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r10095 - in openbts/branches/developers/dburgess00/sms


From: dburgess00
Subject: [Commit-gnuradio] r10095 - in openbts/branches/developers/dburgess00/smswork: . Control GSM SIP SMS Transceiver apps
Date: Sun, 30 Nov 2008 00:36:34 -0700 (MST)

Author: dburgess00
Date: 2008-11-30 00:36:33 -0700 (Sun, 30 Nov 2008)
New Revision: 10095

Added:
   openbts/branches/developers/dburgess00/smswork/Control/DCCHDispatch.cpp
   openbts/branches/developers/dburgess00/smswork/Control/SMSControl.cpp
   openbts/branches/developers/dburgess00/smswork/SMS/SMSCommon.h
Removed:
   openbts/branches/developers/dburgess00/smswork/Control/FACCHDispatch.cpp
   openbts/branches/developers/dburgess00/smswork/Control/SDCCHDispatch.cpp
   openbts/branches/developers/dburgess00/smswork/SMS/README.SMS
   openbts/branches/developers/dburgess00/smswork/SMS/RLMessage.cpp
   openbts/branches/developers/dburgess00/smswork/SMS/RLMessage.h
   openbts/branches/developers/dburgess00/smswork/Transceiver/TODO
Modified:
   openbts/branches/developers/dburgess00/smswork/Control/CallControl.cpp
   openbts/branches/developers/dburgess00/smswork/Control/ControlCommon.cpp
   openbts/branches/developers/dburgess00/smswork/Control/ControlCommon.h
   openbts/branches/developers/dburgess00/smswork/Control/Makefile.am
   openbts/branches/developers/dburgess00/smswork/Control/MobilityManagement.cpp
   openbts/branches/developers/dburgess00/smswork/Control/PagerTest.cpp
   openbts/branches/developers/dburgess00/smswork/Control/RadioResource.cpp
   openbts/branches/developers/dburgess00/smswork/GSM/GSMCommon.cpp
   openbts/branches/developers/dburgess00/smswork/GSM/GSMCommon.h
   openbts/branches/developers/dburgess00/smswork/GSM/GSML2LAPDm.cpp
   openbts/branches/developers/dburgess00/smswork/GSM/GSML3Message.cpp
   openbts/branches/developers/dburgess00/smswork/GSM/GSML3Message.h
   openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRElements.cpp
   openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRElements.h
   openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRMessages.cpp
   openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRMessages.h
   openbts/branches/developers/dburgess00/smswork/GSM/GSMLogicalChannel.cpp
   openbts/branches/developers/dburgess00/smswork/Makefile.common
   openbts/branches/developers/dburgess00/smswork/SIP/SIPInterface.cpp
   openbts/branches/developers/dburgess00/smswork/SMS/Makefile.am
   openbts/branches/developers/dburgess00/smswork/SMS/SMSMessages.cpp
   openbts/branches/developers/dburgess00/smswork/SMS/SMSMessages.h
   openbts/branches/developers/dburgess00/smswork/SMS/SMSTransfer.cpp
   openbts/branches/developers/dburgess00/smswork/SMS/SMSTransfer.h
   openbts/branches/developers/dburgess00/smswork/apps/Makefile.am
   openbts/branches/developers/dburgess00/smswork/apps/OpenBTS850.cpp
   openbts/branches/developers/dburgess00/smswork/apps/OpenBTS900.cpp
Log:
More steps toward SMS support.
 * moving SMS control to its own file
 * consolidating all SMS-related messages in one file
 * changing architecture of SMS from threaded processors to control functions
 * more Makefile.am changes for new files



Modified: openbts/branches/developers/dburgess00/smswork/Control/CallControl.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/Control/CallControl.cpp      
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/Control/CallControl.cpp      
2008-11-30 07:36:33 UTC (rev 10095)
@@ -27,8 +27,6 @@
        MOC -- Mobile Originated Connect (mobile calling out)
        MTD -- Mobile Terminated Disconnect (other party hangs up)
        MOD -- Mobile Originated Disconnect (mobile hangs up)
-       MOSMS -- Mobile Originated Short Message Service (mobile sends text 
message)
-       MTSMS -- Mobile Terminated Short Message Service (mobile received text 
message)
 */
 
 
@@ -39,23 +37,11 @@
 #include "GSML3CCMessages.h"
 #include "GSMConfig.h"
 
-#define DEBUG 1
 
 using namespace std;
 using namespace GSM;
 using namespace Control;
 
-#ifdef SMS
-#include "SMSTransfer.h"
-#include "CMMessage.h"
-#include "RLMessage.h"
-#include "TLMessage.h"
-#include "CMProcessor.h"
-#include "RLProcessor.h"
-#include "TLProcessor.h"
-using namespace SMS;
-#endif
-
 #include "SIPInterface.h"
 #include "SIPUtility.h"
 #include "SIPMessage.h"
@@ -456,15 +442,20 @@
 
 
 /**
-       This function starts MOC to the point of TCH assignment. 
+       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 SDCCH The SDCCH used to initiate call setup.
+       @param LCH The logical used to initiate call setup.
 */
-void Control::MOCStarter(const L3CMServiceRequest* req, SDCCHLogicalChannel 
*SDCCH)
+void Control::MOCStarter(const L3CMServiceRequest* req, LogicalChannel *LCH)
 {
+       assert(LCH);
        assert(req);
        CLDCOUT("MOC: " << *req);
 
+       // Determine if very early assignment already happened.
+       bool veryEarly=false;
+       if (LCH->type()==FACCHType) veryEarly=true;
+
        // 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",
@@ -478,25 +469,28 @@
                // FIXME -- This is quick-and-dirty, not following GSM 04.08 5.
                CERR("WARNING -- (ControlLayer) MOC setup with no IMSI");
                // Cause 0x60 "Invalid mandatory information"
-               SDCCH->send(L3CMServiceReject(L3RejectCause(0x60)));
-               SDCCH->send(L3ChannelRelease());
+               LCH->send(L3CMServiceReject(L3RejectCause(0x60)));
+               LCH->send(L3ChannelRelease());
                // The SIP side and transaction record don't exist yet.
                // So we're done.
                return;
        }
 
-       // Allocate a TCH for the call.
-       TCHFACCHLogicalChannel *TCH = allocateTCH(SDCCH);
-       // It's OK to just return on failure; allocateTCH cleaned up already.
-       if (TCH==NULL) return;
+       // Allocate a TCH for the call, if we don't have it already.
+       TCHFACCHLogicalChannel *TCH = NULL;
+       if (!veryEarly) {
+               TCH = allocateTCH(dynamic_cast<SDCCHLogicalChannel*>(LCH));
+               // It's OK to just return on failure; allocateTCH cleaned up 
already.
+               if (TCH==NULL) return;
+       }
 
        // Let the phone know we're going ahead with the transaction.
        CLDCOUT("MOC: sending CMServiceAccept")
-       SDCCH->send(L3CMServiceAccept());
+       LCH->send(L3CMServiceAccept());
 
        // Get the Setup message.
        // GSM 04.08 5.2.1.2
-       const L3Setup *setup = dynamic_cast<const L3Setup*>(getMessage(SDCCH));
+       const L3Setup *setup = dynamic_cast<const L3Setup*>(getMessage(LCH));
        if (setup==NULL) throw UnexpectedMessage();
        CLDCOUT("MOC: " << *setup);
        // Pull out the L3 short transaction information now.
@@ -506,8 +500,8 @@
                // FIXME -- This is quick-and-dirty, not following GSM 04.08 5.
                CERR("WARNING -- (ControlLayer) MOC setup with no number");
                // Cause 0x60 "Invalid mandatory information"
-               SDCCH->send(L3ReleaseComplete(0,L3TI,L3Cause(0x60)));
-               SDCCH->send(L3ChannelRelease());
+               LCH->send(L3ReleaseComplete(0,L3TI,L3Cause(0x60)));
+               LCH->send(L3ChannelRelease());
                // The SIP side and transaction record don't exist yet.
                // So we're done.
                return;
@@ -527,16 +521,16 @@
                setup->calledPartyBCDNumber());
        transaction.SIP().User(IMSI);
        transaction.Q931State(TransactionEntry::MOCInitiated);
-       SDCCH->transactionID(transaction.ID());
-       TCH->transactionID(transaction.ID());
+       LCH->transactionID(transaction.ID());
+       if (!veryEarly) TCH->transactionID(transaction.ID());
        CLDCOUT("MOC: transaction: " << transaction);
        gTransactionTable.add(transaction);
 
        // At this point, we have enough information start the SIP call setup.
        // We have 2 seconds to repsond to the MS.  ITU-T Q.931 Table 9-1, T303.
 
-       // Now start a call by contacting asterisk. engine methods will return 
their 
-       // current state.       
+       // Now start a call by contacting asterisk.
+       // Engine methods will return their current state.      
        // The remote party will start ringing soon.
        CLDCOUT("MOC: starting SIP (INVITE) Calling "<<bcd_digits);
        unsigned basePort = allocateRTPPorts();
@@ -548,14 +542,30 @@
        delete setup;
 
        // The transaction is moving on to the MOCController.
+       // If we need a TCH assignment, we do it here.
        gTransactionTable.update(transaction);
        CLDCOUT("MOC: transaction: " << transaction);
-       // This call also opens the TCH.
-       assignTCHF(SDCCH,TCH);
+       if (veryEarly) {
+               // For very early assignment, we need a mode change.
+               static const L3ChannelMode mode(L3ChannelMode::SpeechV1);
+               LCH->send(L3ChannelModeModify(LCH->channelDescription(),mode));
+               const L3ChannelModeModifyAcknowledge *ack =
+                       
dynamic_cast<L3ChannelModeModifyAcknowledge*>(getMessage(LCH));
+               if (!ack) throw UnexpectedMessage();
+               // Cause 0x06 is "channel unacceptable"
+               if (ack->mode() != mode) return 
abortCall(transaction,LCH,L3Cause(0x06));
+               
MOCController(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(dynamic_cast<SDCCHLogicalChannel*>(LCH),TCH);
+       }
 }
 
 
 
+
+
 /**
        Continue MOC process on the TCH.
        @param transaction The call state and SIP interface.
@@ -565,6 +575,7 @@
 {
        CLDCOUT("MOC: transaction: " << transaction);
        unsigned L3TI = transaction.TIValue();
+       assert(TCH);
 
        // Once we can start SIP call setup, send Call Proceeding.
        CLDCOUT("MOC: Sending Call Proceeding ");
@@ -682,16 +693,24 @@
 
 
 
-void Control::MTCStarter(const L3PagingResponse *resp, 
-                                               SDCCHLogicalChannel *SDCCH)
+void Control::MTCStarter(const L3PagingResponse *resp, LogicalChannel *LCH)
 {
        assert(resp);
-       CLDCOUT("MTC: " << *resp);
+       assert(LCH);
+       CLDCOUT("MTC on " << LCH->type() << ": " << *resp);
 
+       // Determine if very early assigment already happened.
+       bool veryEarly = false;
+       if (LCH->type()==FACCHType) veryEarly=true;
+
        // Allocate a TCH for the call.
-       TCHFACCHLogicalChannel *TCH = allocateTCH(SDCCH);
-       // The orphaned transaction will be cleared at the next findByMobileID 
call.
-       if (TCH==NULL) return;
+       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 at the next 
findByMobileID call.
+               if (TCH==NULL) return;
+       }
 
        // Find the transction table entry that was created when the phone was 
paged.
        CLDCOUT("MTC: find TransactionEntry for " << resp->mobileIdentity());
@@ -701,13 +720,13 @@
                return;
        }
        CLDCOUT("MTC: transaction: "<< transaction);
-       TCH->transactionID(transaction.ID());   
-       SDCCH->transactionID(transaction.ID()); 
+       if (!veryEarly) TCH->transactionID(transaction.ID());   
+       LCH->transactionID(transaction.ID());   
        unsigned L3TI = transaction.TIValue();
 
        // GSM 04.08 5.2.2.1
        CLDCOUT("MTC: sending GSM Setup");
-       SDCCH->send(L3Setup(0,L3TI));
+       LCH->send(L3Setup(0,L3TI));
        transaction.T303().set();
        transaction.Q931State(TransactionEntry::CallPresent);
 
@@ -715,31 +734,47 @@
        CLDCOUT("MTC: wait for GSM Call Confirmed")
        while (transaction.Q931State()!=TransactionEntry::MTCConfirmed) {
                if (transaction.SIP().MTCSendTrying()==SIP::Fail) {
-                       TCH->send(RELEASE);
-                       return abortCall(transaction,SDCCH,L3Cause(0x7F));
+                       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,SDCCH,1000)) {
+               if (updateGSMSignalling(transaction,LCH,1000)) {
                        CLDCOUT("MTC: Release from GSM side");
-                       TCH->send(RELEASE);
+                       LCH->send(RELEASE);
                        return;
                }
                // Check for SIP cancel, too.
                if (transaction.SIP().MTCWaitForACK()==SIP::Fail) {
-                       TCH->send(RELEASE);
-                       return abortCall(transaction,SDCCH,L3Cause(0x7F));
+                       LCH->send(RELEASE);
+                       // Cause 0x10 is "normal clearing"
+                       return abortCall(transaction,LCH,L3Cause(0x10));
                }
        }
 
        // The transaction is moving to the MTCController.
        gTransactionTable.update(transaction);
        CLDCOUT("MTC: transaction: " << transaction);
-       assignTCHF(SDCCH,TCH);
+       if (veryEarly) {
+               // For very early assignment, we need a mode change.
+               static const L3ChannelMode mode(L3ChannelMode::SpeechV1);
+               LCH->send(L3ChannelModeModify(LCH->channelDescription(),mode));
+               const L3ChannelModeModifyAcknowledge *ack =
+                       
dynamic_cast<L3ChannelModeModifyAcknowledge*>(getMessage(LCH));
+               if (!ack) throw UnexpectedMessage();
+               // Cause 0x06 is "channel unacceptable"
+               if (ack->mode() != mode) 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(dynamic_cast<SDCCHLogicalChannel*>(LCH),TCH);
+       }
 }
 
 
-
 void Control::MTCController(TransactionEntry& transaction, 
TCHFACCHLogicalChannel* TCH)
 {
        // Early Assignment Mobile Terminated Call. 
@@ -747,6 +782,7 @@
 
        CLDCOUT("MTC: transaction: " << transaction);
        unsigned L3TI = transaction.TIValue();
+       assert(TCH);
 
        // Get the alerting message.
        CLDCOUT("MTC:: waiting for GSM Alerting and Connect");
@@ -797,45 +833,6 @@
 }
 
 
-void Control::ShortMessageServiceStarter(const L3CMServiceRequest*resp, 
-                                               SDCCHLogicalChannel *SDCCH)
 
-{
-#ifdef SMS
-       SDCCH->openSAPI3();
-       CLDCOUT("SMS-Starter Sending CMServiceAccept ")
 
-       SDCCH->send(L3CMServiceAccept());
-
-       CMProcessor cm_proc;
-       RLProcessor rl_proc;
-       TLProcessor tl_proc;
-
-       cm_proc.TIFlag(0);
-       cm_proc.TIValue(3);
-       cm_proc.downstream(SDCCH);      
-       cm_proc.upstream(&rl_proc);
-       cm_proc.mState = CMProcessor::MO_Idle;
-       cm_proc.open();
-
-       rl_proc.downstream(&cm_proc);
-       rl_proc.upstream(&tl_proc);
-       rl_proc.open();
-
-       tl_proc.downstream(&rl_proc);
-       
-       sleep(1);
-       TLMessage * msg = tl_proc.mUplinkFIFO.read();
-       CLDCOUT(" ControlLayer SMS = "<<*msg)
-       sleep(1);
-       tl_proc.writeHighSide( SubmitReport("08162312394401"), SM_RL_REPORT_REQ 
);
-       
-
-
-       while(1){ sleep(1); };
-#endif
-}
-
-
-
 // vim: ts=4 sw=4

Modified: 
openbts/branches/developers/dburgess00/smswork/Control/ControlCommon.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/Control/ControlCommon.cpp    
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/Control/ControlCommon.cpp    
2008-11-30 07:36:33 UTC (rev 10095)
@@ -38,10 +38,8 @@
 using namespace GSM;
 using namespace Control;
 
-#define DEBUG 1
 
 
-
 // The global transaction table.
 TransactionTable gTransactionTable;
 

Modified: openbts/branches/developers/dburgess00/smswork/Control/ControlCommon.h
===================================================================
--- openbts/branches/developers/dburgess00/smswork/Control/ControlCommon.h      
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/Control/ControlCommon.h      
2008-11-30 07:36:33 UTC (rev 10095)
@@ -47,6 +47,7 @@
 #include <GSML3CommonElements.h>
 #include <GSML3MMElements.h>
 #include <GSML3CCElements.h>
+#include <GSML3RRMessages.h>
 #include <SIPEngine.h>
 
 
@@ -142,33 +143,45 @@
 
 /address@hidden Functions for mobility manangement operations. */
 //@{
-void CMServiceResponder(const GSM::L3CMServiceRequest* cmsrq, 
GSM::SDCCHLogicalChannel* SDCCH);
+void CMServiceResponder(const GSM::L3CMServiceRequest* cmsrq, 
GSM::LogicalChannel* DCCH);
 void IMSIDetachController(const GSM::L3IMSIDetachIndication* idi, 
GSM::SDCCHLogicalChannel* SDCCH);
 void LocationUpdatingController(const GSM::L3LocationUpdatingRequest* lur, 
GSM::SDCCHLogicalChannel* SDCCH);
 //@}
 
 /address@hidden Functions for radio resource operations. */
 //@{
+/** Decode RACH bits and send an immediate assignment. */
 void AccessGrantResponder(unsigned requestReference, const GSM::Time& when);
-void PagingResponseHandler(const GSM::L3PagingResponse*, 
GSM::SDCCHLogicalChannel*);
+/** Find and compelte the in-process transaction associated with a paging 
repsonse. */
+void PagingResponseHandler(const GSM::L3PagingResponse*, GSM::LogicalChannel*);
+/** Find and compelte the in-process transaction associated with a completed 
assignment. */
+void AssignmentCompleteHandler(const GSM::L3AssignmentComplete*, 
GSM::TCHFACCHLogicalChannel*);
 //@}
 
 /address@hidden Functions for call control operations. */
 //@{
 /address@hidden MOC */
 //@{
-void MOCStarter(const GSM::L3CMServiceRequest* req, GSM::SDCCHLogicalChannel 
*SDCCH);
-void MOCController(TransactionEntry& transaction, GSM::TCHFACCHLogicalChannel* 
TCHFACCH);
+/** Run the MOC to the point of alerting, doing early assignment if needed. */
+void MOCStarter(const GSM::L3CMServiceRequest*, GSM::LogicalChannel*);
+/** Complete the MOC connection. */
+void MOCController(TransactionEntry&, GSM::TCHFACCHLogicalChannel*);
 //@}
 /address@hidden MTC */
 //@{
-void MTCStarter(const GSM::L3PagingResponse *resp, GSM::SDCCHLogicalChannel 
*SDCCH);
-void MTCController(TransactionEntry& transaction, GSM::TCHFACCHLogicalChannel* 
TCHFACCH);
+/** Run the MTC to the point of alerting, doing early assignment if needed. */
+void MTCStarter(const GSM::L3PagingResponse*, GSM::LogicalChannel*);
+/** Complete the MTC connection. */
+void MTCController(TransactionEntry&, GSM::TCHFACCHLogicalChannel*);
 //@}
-/address@hidden MOSMS */
+/address@hidden SMS */
 //@{
-void ShortMessageServiceStarter(const GSM::L3CMServiceRequest*resp, 
+/** MOSMS */
+void MOSMSController(const GSM::L3CMServiceRequest*resp, 
                                                GSM::SDCCHLogicalChannel 
*SDCCH);
+/** MTSMS */
+void MTSMSController(const GSM::L3CMServiceRequest*resp, 
+                                               GSM::SDCCHLogicalChannel 
*SDCCH);
 //@}
 
 
@@ -186,6 +199,7 @@
 //@{
 void FACCHDispatcher(GSM::TCHFACCHLogicalChannel *TCHFACCH);
 void SDCCHDispatcher(GSM::SDCCHLogicalChannel *SDCCH);
+void DCCHDispatcher(GSM::LogicalChannel *DCCH);
 //@}
 
 
@@ -199,6 +213,7 @@
        private:
 
        // FIXME -- We need to support channel type.  See tracker item #316.
+       GSM::ChannelType mType;                 ///< The needed channel type.
        GSM::L3MobileIdentity mID;              ///< The mobile ID.
        Timeval mExpiration;                    ///< The expiration time for 
this entry.
 
@@ -209,13 +224,16 @@
                @param wID The ID to be paged.
                @param wLife The number of milliseconds to keep paging.
        */
-       PagingEntry(const GSM::L3MobileIdentity& wID, unsigned wLife)
-               :mID(wID),mExpiration(wLife)
+       PagingEntry(const GSM::L3MobileIdentity& wID, GSM::ChannelType wType, 
unsigned wLife)
+               :mID(wID),mType(wType),mExpiration(wLife)
        {}
 
        /** Access the ID. */
        const GSM::L3MobileIdentity& ID() const { return mID; }
 
+       /** Access the channel type needed. */
+       const GSM::ChannelType type() const { return mType; }
+
        /** Renew the timer. */
        void renew(unsigned wLife) { mExpiration = Timeval(wLife); }
 
@@ -252,9 +270,10 @@
        /**
                Add a mobile ID to the paging list.
                @param addID The mobile ID to be paged.
+               @param chanType The channel type to be requested.
                @param wLife The paging duration in ms, default based on SIP 
INVITE retry preiod.
        */
-       void addID(const GSM::L3MobileIdentity& addID, unsigned wLife=4000);
+       void addID(const GSM::L3MobileIdentity& addID, GSM::ChannelType 
chanType, unsigned wLife=4000);
 
        private:
 

Copied: openbts/branches/developers/dburgess00/smswork/Control/DCCHDispatch.cpp 
(from rev 10090, openbts/trunk/Control/DCCHDispatch.cpp)
===================================================================
--- openbts/branches/developers/dburgess00/smswork/Control/DCCHDispatch.cpp     
                        (rev 0)
+++ openbts/branches/developers/dburgess00/smswork/Control/DCCHDispatch.cpp     
2008-11-30 07:36:33 UTC (rev 10095)
@@ -0,0 +1,179 @@
+/address@hidden Idle-mode dispatcher for dedicated control channels. */
+
+/*
+* Copyright 2008 Free Software Foundation, Inc.
+*
+* This software is distributed under the terms of the GNU Public License.
+* See the COPYING file in the main directory for details.
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+
+
+#include "ControlCommon.h"
+#include <GSMLogicalChannel.h>
+#include <GSML3MMMessages.h>
+#include <GSML3RRMessages.h>
+#include <SIPUtility.h>
+#include <SIPInterface.h>
+
+using namespace std;
+using namespace GSM;
+using namespace Control;
+
+
+
+
+/**
+       Dispatch the appropriate controller for a Mobility Management message.
+       @param req A pointer to the initial message.
+       @param DCCH A pointer to the logical channel for the transaction.
+*/
+void DCCHDispatchMM(const L3MMMessage* req, LogicalChannel *DCCH)
+{
+       assert(req);
+       L3MMMessage::MessageType MTI = (L3MMMessage::MessageType)req->MTI();
+       switch (MTI) {
+               case L3MMMessage::LocationUpdatingRequest:
+                       LocationUpdatingController(dynamic_cast<const 
L3LocationUpdatingRequest*>(req),
+                                                                       
dynamic_cast<SDCCHLogicalChannel*>(DCCH));
+                       break;
+               case L3MMMessage::IMSIDetachIndication:
+                       IMSIDetachController(dynamic_cast<const 
L3IMSIDetachIndication*>(req),
+                                                                       
dynamic_cast<SDCCHLogicalChannel*>(DCCH));
+                       break;
+               case L3MMMessage::CMServiceRequest:
+                       CMServiceResponder(dynamic_cast<const 
L3CMServiceRequest*>(req),DCCH);
+                       break;
+               default:
+                       CERR("NOTICE -- (ControlLayer) unhandled MM message " 
<< MTI << " on " << DCCH->type());
+                       throw UnsupportedMessage();
+       }
+}
+
+
+/**
+       Dispatch the appropriate controller for a Radio Resource message.
+       @param req A pointer to the initial message.
+       @param DCCH A pointer to the logical channel for the transaction.
+*/
+void DCCHDispatchRR(const L3RRMessage* req, LogicalChannel *DCCH)
+{
+       CLDCOUT("DCCHDispatchRR: cheking MTI"<< 
(L3RRMessage::MessageType)req->MTI() )
+
+       assert(req);
+       L3RRMessage::MessageType MTI = (L3RRMessage::MessageType)req->MTI();
+       switch (MTI) {
+               case L3RRMessage::PagingResponse:
+                       PagingResponseHandler(dynamic_cast<const 
L3PagingResponse*>(req),DCCH);
+                       break;
+               case L3RRMessage::AssignmentComplete:
+                       AssignmentCompleteHandler(dynamic_cast<const 
L3AssignmentComplete*>(req),
+                                                                               
dynamic_cast<TCHFACCHLogicalChannel*>(DCCH));
+                       break;
+               default:
+                       CERR("NOTICE -- (ControlLayer) unhandled RR message " 
<< MTI << " on " << DCCH->type());
+                       throw UnsupportedMessage();
+       }
+}
+
+
+
+
+
+
+/** Example of a closed-loop, persistent-thread control function for the DCCH. 
*/
+void Control::DCCHDispatcher(LogicalChannel *DCCH)
+{
+       while (1) {
+               try {
+                       // Wait for a transaction to start.
+                       CLDCOUT("DCCHDisptacher waiting for " << DCCH->type() 
<< " ESTABLISH");
+                       while (!waitForPrimitive(DCCH,ESTABLISH)) {}
+                       // Pull the first message and dispatch a new 
transaction.
+                       const L3Message *message = getMessage(DCCH);
+                       CLDCOUT("DCCHDispatcher got " << *message);
+                       // Each protocol has it's own sub-dispatcher.
+                       switch (message->PD()) {
+                               case L3MobilityManagementPD:
+                                       DCCHDispatchMM(dynamic_cast<const 
L3MMMessage*>(message),DCCH);
+                                       break;
+                               case L3RadioResourcePD:
+                                       DCCHDispatchRR(dynamic_cast<const 
L3RRMessage*>(message),DCCH);
+                                       break;
+                               default:
+                                       CERR("NOTICE -- (ControlLayer) 
unhandled protocol " 
+                                               << message->PD() << " on DCCH");
+                                       throw UnsupportedMessage();
+                       }
+                       delete message;
+               }
+
+               // Catch the various error cases.
+
+               catch (ChannelReadTimeout except) {
+                       clearTransactionHistory(except.transactionID());
+                       CERR("NOTICE -- ChannelReadTimeout");
+                       // Cause 0x03 means "abnormal release, timer expired".
+                       DCCH->send(L3ChannelRelease(0x03));
+               }
+               catch (UnexpectedPrimitive except) {
+                       clearTransactionHistory(except.transactionID());
+                       CERR("NOTICE -- UnexpectedPrimitive");
+                       // Cause 0x62 means "message type not not compatible 
with protocol state".
+                       DCCH->send(L3ChannelRelease(0x62));
+               }
+               catch (UnexpectedMessage except) {
+                       clearTransactionHistory(except.transactionID());
+                       CERR("NOTICE -- UnexpectedMessage");
+                       // Cause 0x62 means "message type not not compatible 
with protocol state".
+                       DCCH->send(L3ChannelRelease(0x62));
+               }
+               catch (UnsupportedMessage except) {
+                       clearTransactionHistory(except.transactionID());
+                       CERR("NOTICE -- UnsupportedMessage");
+                       // Cause 0x61 means "message type not implemented".
+                       DCCH->send(L3ChannelRelease(0x61));
+               }
+               catch (Q931TimerExpired except) {
+                       clearTransactionHistory(except.transactionID());
+                       CERR("NOTICE -- Q.931 T3xx timer expired");
+                       // Cause 0x03 means "abnormal release, timer expired".
+                       DCCH->send(L3ChannelRelease(0x03));
+               }
+               catch (SIP::SIPTimeout) {
+                       CERR("NOTICE -- Uncaught SIP Timeout");
+                       // Cause 0x03 means "abnormal release, timer expired".
+                       DCCH->send(L3ChannelRelease(0x03));
+               }
+               catch (SIP::SIPError) {
+                       CERR("NOTICE -- Uncaught SIP Error");
+                       // Cause 0x01 means "abnormal release, unspecified".
+                       DCCH->send(L3ChannelRelease(0x01));
+               }
+
+               CLDCOUT("DCCHDisptacher waiting for " << DCCH->type() << " 
RELEASE");
+               //FIXME -- What's the GSM 04.08 Txxx value for this?
+               // Probably N200 * T200
+               waitForPrimitive(DCCH,RELEASE,20000);
+       }
+}
+
+
+
+
+// vim: ts=4 sw=4

Deleted: 
openbts/branches/developers/dburgess00/smswork/Control/FACCHDispatch.cpp

Modified: openbts/branches/developers/dburgess00/smswork/Control/Makefile.am
===================================================================
--- openbts/branches/developers/dburgess00/smswork/Control/Makefile.am  
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/Control/Makefile.am  
2008-11-30 07:36:33 UTC (rev 10095)
@@ -30,11 +30,11 @@
 
 libcontrol_la_SOURCES = \
        CallControl.cpp \
+       SMSControl.cpp \
        ControlCommon.cpp \
-       FACCHDispatch.cpp \
        MobilityManagement.cpp \
        RadioResource.cpp \
-       SDCCHDispatch.cpp
+       DCCHDispatch.cpp
 
 PagerTest_SOURCES = PagerTest.cpp
 PagerTest_LDADD = \
@@ -42,6 +42,7 @@
        $(COMMON_LA) \
        $(GSM_LA) \
        $(SIP_LA) \
+       $(SMS_LA) \
        $(TRX_LA) \
        $(OSIP_LIBS) \
        $(ORTP_LIBS)

Modified: 
openbts/branches/developers/dburgess00/smswork/Control/MobilityManagement.cpp
===================================================================
--- 
openbts/branches/developers/dburgess00/smswork/Control/MobilityManagement.cpp   
    2008-11-30 04:13:24 UTC (rev 10094)
+++ 
openbts/branches/developers/dburgess00/smswork/Control/MobilityManagement.cpp   
    2008-11-30 07:36:33 UTC (rev 10095)
@@ -52,24 +52,22 @@
 
 
 /** Controller for CM Service requests, dispatches out to multiple possible 
transaction controllers. */
-void Control::CMServiceResponder(const L3CMServiceRequest* cmsrq, 
SDCCHLogicalChannel* SDCCH)
+void Control::CMServiceResponder(const L3CMServiceRequest* cmsrq, 
LogicalChannel* DCCH)
 {
        assert(cmsrq);
        CLDCOUT("CMServiceResponder " << *cmsrq);
        switch (cmsrq->serviceType().type()) {
                case L3CMServiceType::MobileOriginatedCall:
-                       MOCStarter(cmsrq,SDCCH);
+                       MOCStarter(cmsrq,DCCH);
                        break;
-#ifdef SMS
                case L3CMServiceType::ShortMessage:
-                       ShortMessageServiceStarter(cmsrq, SDCCH);
+                       MOSMSController(cmsrq, 
dynamic_cast<SDCCHLogicalChannel*>(DCCH));
                        break;
-#endif
                default:
                        CLDCOUT("CMServiceResponder service not supported");
                        // Cause 0x20 means "serivce not supported".
-                       SDCCH->send(L3CMServiceReject(0x20));
-                       SDCCH->send(L3ChannelRelease());
+                       DCCH->send(L3CMServiceReject(0x20));
+                       DCCH->send(L3ChannelRelease());
        }
 }
 

Modified: openbts/branches/developers/dburgess00/smswork/Control/PagerTest.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/Control/PagerTest.cpp        
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/Control/PagerTest.cpp        
2008-11-30 07:36:33 UTC (rev 10095)
@@ -59,9 +59,9 @@
        pager.start();
 
        while (1) {
-               pager.addID(L3MobileIdentity(random()));
-               pager.addID(L3MobileIdentity(random()));
-               pager.addID(L3MobileIdentity("123456789012345"));
+               pager.addID(L3MobileIdentity(random()),GSM::AnyDCCHType);
+               pager.addID(L3MobileIdentity(random()),GSM::AnyDCCHType);
+               
pager.addID(L3MobileIdentity("123456789012345"),GSM::AnyDCCHType);
                sleep(random() % 2);
        }
 }

Modified: 
openbts/branches/developers/dburgess00/smswork/Control/RadioResource.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/Control/RadioResource.cpp    
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/Control/RadioResource.cpp    
2008-11-30 07:36:33 UTC (rev 10095)
@@ -75,6 +75,52 @@
 //@}
 
 
+/**
+       Determine the channel type needed.
+       This is based on GSM 04.08 Table 9.3 and 9.3a.
+       The following is assumed about the global BTS capabilities:
+       - We do not support "new establishment causes" and NECI is 0.
+       - We do not support call reestablishment.
+       - We do not support GPRS.
+       @param RA The request reference from the channel request message.
+       @return channel type code, undefined if not a supported service
+*/
+ChannelType decodeChannelNeeded(unsigned RA)
+{
+       // These values assume NECI is 0.
+       // This code is formatted so that it lines up easily with GSM 04.08 
Table 9.9.
+       //
+       if ((RA>>5) == 0x05) return TCHFType;                   // emergency 
call
+       //
+       // skip re-establishment cases
+       //
+       // "Answer to paging"
+       if ((RA>>5) == 0x04) return SDCCHType;                  // answer to 
paging, any channel
+       if ((RA>>4) == 0x01) return SDCCHType;                  // answer to 
paging, SDCCH
+       if ((RA>>4) == 0x02) return TCHFType;                   // answer to 
paging, TCH/F
+       if ((RA>>4) == 0x03) return TCHFType;                   // answer to 
paging, TCH/F or TCH/H
+       //
+       if ((RA>>5) == 0x07) return SDCCHType;                  // MOC or SDCCH 
procedures
+       //
+       if ((RA>>4) == 0x04) return TCHFType;                   // MOC
+       //
+       // skip originating data call cases
+       //
+       if ((RA>>5) == 0x00) return SDCCHType;                  // location 
updating
+       //
+       if ((RA>>4) == 0x00) return SDCCHType;                  // location 
updating
+       //
+       // skip packet (GPRS) cases
+       //
+       // skip LMU case
+       //
+       // skip reserved cases
+       //
+       // Anything else falls through to here.
+       return UndefinedCHType;
+}
+
+
 void Control::AccessGrantResponder(unsigned RA, const GSM::Time& when)
 {
        // RR Establishment.
@@ -82,35 +128,31 @@
        // GSM 04.08 3.3.1.1.3.
        // Given a request reference, try to allocate a channel
        // and send the assignment to the handset on the CCCH.
+       // This GSM's version of medium access control.
        // Papa Legba, open that door...
 
        CLDCOUT("AccessGrantResponder RA=" << RA << " when=" << when);
 
        // FIXME -- Check "when" against current clock to see if we're too late.
 
-       // Check the request type to see if it's a service we don't even 
support.
+       // Determine the channel type needed.
+       ChannelType chanNeeded = decodeChannelNeeded(RA);
+
+       // Allocate the channel.
+       LogicalChannel *LCH = NULL;
+       if (chanNeeded==TCHFType) LCH = gBTS.getTCH();
+       if (chanNeeded==SDCCHType) LCH = gBTS.getSDCCH();
        // If we don't support it, ignore it.
-       if ((RA&0xe0)==0x70) return;    // GPRS
-       if ((RA&0xe0)==0x60) return;    // TCH/H reestablishment & some 
reserved codes
-       if (RA==0x67) return;                   // LMU
-       if (RA==0xef) return;                   // reserved
+       if (LCH==NULL) return;
 
        // Get an AGCH to send on.
        CCCHLogicalChannel *AGCH = gBTS.getAGCH();
        assert(AGCH);
 
-       // FIXME -- We are ASSUMING that SDCCH is OK.
-       // The truth is that we should decode according GSM 04.08 9.1.8, Table 
9.9a.
-
-       // Get an SDCCH to assign to.
-       SDCCHLogicalChannel *SDCCH = gBTS.getSDCCH();
-
        // Nothing available?
-       if (!SDCCH) {
+       if (!LCH) {
                // Rejection, GSM 04.08 3.3.1.1.3.2.
-               // Emergency calls are not subject to T3122 hold-off.
-               // They are not handled as a special case because the
-               // MS will ignore the T3122 setting.
+               // BTW, emergency calls are not subject to T3122 hold-off.
                CERR("NOTICE -- Access Grant CONGESTION");
                unsigned waitTime = curT3122()/1000;
                CLDCOUT("AccessGrantResponder: assginment reject, wait time " 
<< waitTime);
@@ -123,10 +165,10 @@
        // Assignment, GSM 04.08 3.3.1.1.3.1.
        // Create the ImmediateAssignment message.
        // For most of the message, default IE values are correct.
-       const L3ImmediateAssignment 
assign(L3RequestReference(RA,when),SDCCH->channelDescription());
+       const L3ImmediateAssignment 
assign(L3RequestReference(RA,when),LCH->channelDescription());
        CLDCOUT("AccessGrantResponder sending " << assign);
        AGCH->send(assign);
-       SDCCH->open();
+       // This was opened by the gBTS.getXXX() method.  LCH->open();
 
        // Reset exponential back-off upon successful allocation.
        restoreT3122();
@@ -136,8 +178,10 @@
 
 
 
-void Control::PagingResponseHandler(const L3PagingResponse* resp, 
SDCCHLogicalChannel* SDCCH)
+void Control::PagingResponseHandler(const L3PagingResponse* resp, 
LogicalChannel* DCCH)
 {
+       assert(resp);
+       assert(DCCH);
        CLDCOUT("PagingResponseHandler " << *resp);
 
        // FIXME -- Delete the Mobile ID from the paging list to free up CCCH 
bandwidth.
@@ -146,9 +190,10 @@
        // if not a legitimate reason, need to release the channel.
 
        // FIXME -- Check the transaction table to see if the call is still 
valid.
+
 #ifndef PAGERTEST
        // For now, assume MTC.
-       MTCStarter(resp, SDCCH);
+       MTCStarter(resp, DCCH);
 #else
        COUT("starting MTC...");
 #endif
@@ -156,12 +201,42 @@
 
 
 
+void Control::AssignmentCompleteHandler(const L3AssignmentComplete *confirm, 
TCHFACCHLogicalChannel *TCH)
+{
+       assert(TCH);
+       assert(confirm);
 
+       // Check the transaction table to know what to do next.
+       TransactionEntry transaction;
+       if (!gTransactionTable.find(TCH->transactionID(),transaction)) {
+               CLDCOUT("NOTICE -- Assignment Complete from channel with no 
transaction");
+               throw UnexpectedMessage();
+       }
+       CLDCOUT("AssignmentCompleteHandler 
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:
+                       CLDCOUT("NOTICE -- request for unsupported service " << 
transaction.service());
+                       throw UnsupportedMessage();
+       }
+       // If we got here, the call is cleared.
+       clearTransactionHistory(TCH->transactionID());
+}
 
 
 
 
-void Pager::addID(const L3MobileIdentity& newID, unsigned wLife)
+
+
+
+
+void Pager::addID(const L3MobileIdentity& newID, ChannelType chanType, 
unsigned wLife)
 {
        // Add a mobile ID to the paging list for a given lifetime.
 
@@ -180,7 +255,7 @@
        }
        // If this ID is new, put it in the list.
        if (!renewed) {
-               mPageIDs.push_back(PagingEntry(newID,wLife));
+               mPageIDs.push_back(PagingEntry(newID,chanType,wLife));
                CLDCOUT("Pager::addID " << newID << " added to table");
        }
        // Signal in case the paging loop is waiting for new entries.
@@ -210,22 +285,25 @@
        // Page remaining entries, two at a time if possible.
        list<PagingEntry>::iterator lp = mPageIDs.begin();
        while (lp != mPageIDs.end()) {
-               // HACK -- Just pick the minimum load channel.
-               // FIXME -- This completely ignores the paging goups, GSM 04.08 
10.5.2.11 and GSM 05.02 6.5.2.
-               GSM::CCCHLogicalChannel *PCH = gBTS.getPCH();
+               // FIXME -- This completely ignores the paging groups, GSM 
04.08 10.5.2.11 and GSM 05.02 6.5.2.
+               CCCHLogicalChannel *PCH = gBTS.getPCH();
                assert(PCH);
-               const L3MobileIdentity& id1 = lp->ID(); ++lp;
+               const L3MobileIdentity& id1 = lp->ID();
+               ChannelType type1 = lp->type();
+               ++lp;
                if (lp==mPageIDs.end()) {
                        // Just one ID left?
                        //CLDCOUT("Pager::pageAll paging " << id1);
-                       PCH->send(L3PagingRequestType1(id1));
+                       PCH->send(L3PagingRequestType1(id1,type1));
                        numPaged++;
                        break;
                }
                // Page by pairs when possible.
-               const L3MobileIdentity& id2 = lp->ID(); ++lp;
+               const L3MobileIdentity& id2 = lp->ID();
+               ChannelType type2 = lp->type();
+               ++lp;
                //CLDCOUT("Pager::pageAll paging " << id1 << " and " << id2);
-               PCH->send(L3PagingRequestType1(id1,id2));
+               PCH->send(L3PagingRequestType1(id1,type1,id2,type2));
                numPaged += 2;
        }
        

Deleted: 
openbts/branches/developers/dburgess00/smswork/Control/SDCCHDispatch.cpp

Added: openbts/branches/developers/dburgess00/smswork/Control/SMSControl.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/Control/SMSControl.cpp       
                        (rev 0)
+++ openbts/branches/developers/dburgess00/smswork/Control/SMSControl.cpp       
2008-11-30 07:36:33 UTC (rev 10095)
@@ -0,0 +1,66 @@
+/address@hidden GSM/SIP Call Control -- GSM 04.08, ISDN ITU-T Q.931, SIP IETF 
RFC-3261, RTP IETF RFC-3550. */
+/*
+* Copyright 2008 Free Software Foundation, Inc.
+*
+* This software is distributed under the terms of the GNU Public License.
+* See the COPYING file in the main directory for details.
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+/*
+       Abbreviations:
+       MTC -- Mobile Terminated Connect (someone calling the mobile)
+       MOC -- Mobile Originated Connect (mobile calling out)
+       MTD -- Mobile Terminated Disconnect (other party hangs up)
+       MOD -- Mobile Originated Disconnect (mobile hangs up)
+       MOSMS -- Mobile Originated Short Message Service (mobile sends text 
message)
+       MTSMS -- Mobile Terminated Short Message Service (mobile received text 
message)
+*/
+
+
+#include "ControlCommon.h"
+#include "GSMLogicalChannel.h"
+
+
+using namespace std;
+using namespace GSM;
+using namespace Control;
+
+#include "SMSMessages.h"
+#include "SMSCommon.h"
+using namespace SMS;
+
+#include "SIPInterface.h"
+#include "SIPUtility.h"
+#include "SIPMessage.h"
+#include "SIPEngine.h"
+using namespace SIP;
+
+
+
+
+
+
+void Control::MOSMSController(const L3CMServiceRequest*resp, 
+                                               SDCCHLogicalChannel *SDCCH)
+{
+
+}
+
+
+
+// vim: ts=4 sw=4

Modified: openbts/branches/developers/dburgess00/smswork/GSM/GSMCommon.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/GSM/GSMCommon.cpp    
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/GSM/GSMCommon.cpp    
2008-11-30 07:36:33 UTC (rev 10095)
@@ -274,8 +274,10 @@
                case SACCHType: os << "SACCH"; break;
                case TCHFType: os << "TCH/F"; break;
                case TCHHType: os << "TCH/H"; break;
-               case LoopbackFullType: os << "LoopbackFull"; break;
-               case LoopbackHalfType: os << "LoopbackHalf"; break;
+               case AnyTCHType: os << "any TCH"; break;
+               case LoopbackFullType: os << "Loopback Full"; break;
+               case LoopbackHalfType: os << "Loopback Half"; break;
+               case AnyDCCHType: os << "any DCCH"; break;
                default: os << "?" << (int)val << "?";
        }
        return os;

Modified: openbts/branches/developers/dburgess00/smswork/GSM/GSMCommon.h
===================================================================
--- openbts/branches/developers/dburgess00/smswork/GSM/GSMCommon.h      
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/GSM/GSMCommon.h      
2008-11-30 07:36:33 UTC (rev 10095)
@@ -185,12 +185,14 @@
        //@{
        TCHFType,               ///< full-rate traffic
        TCHHType,               ///< half-rate traffic
+       AnyTCHType,             ///< any TCH type
        //@}
        ///@name Special internal channel types.
        //@{
        LoopbackFullType,               ///< loopback testing
        LoopbackHalfType,               ///< loopback testing
-       UndefinedCHType,        ///< undefined
+       AnyDCCHType,                    ///< any dedicated control channel
+       UndefinedCHType,                ///< undefined
        //@}
 };
 

Modified: openbts/branches/developers/dburgess00/smswork/GSM/GSML2LAPDm.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/GSM/GSML2LAPDm.cpp   
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/GSM/GSML2LAPDm.cpp   
2008-11-30 07:36:33 UTC (rev 10095)
@@ -43,6 +43,7 @@
 using namespace std;
 using namespace GSM;
 
+//#define NDEBUG
 
 
 ostream& GSM::operator<<(ostream& os, L2LAPDm::LAPDState state)

Modified: openbts/branches/developers/dburgess00/smswork/GSM/GSML3Message.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/GSM/GSML3Message.cpp 
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/GSM/GSML3Message.cpp 
2008-11-30 07:36:33 UTC (rev 10095)
@@ -27,11 +27,9 @@
 #include "GSML3CCMessages.h"
 
 
-#ifdef SMS
-#include "SMSTransfer.h"
-#include "CMMessage.h"
+#include <SMSTransfer.h>
+#include <SMSMessages.h>
 using namespace SMS;
-#endif
 
 
 using namespace std;
@@ -146,9 +144,7 @@
                        case L3RadioResourcePD: return parseL3RR(source);
                        case L3MobilityManagementPD: return parseL3MM(source);
                        case L3CallControlPD: return parseL3CC(source);
-#ifdef SMS
                        case L3SMSPD: return parseSMS(source);
-#endif
                        default:
                                CERR("NOTICE -- L3 parsing failed for 
unsupported protocol " << PD);
                                return NULL;

Modified: openbts/branches/developers/dburgess00/smswork/GSM/GSML3Message.h
===================================================================
--- openbts/branches/developers/dburgess00/smswork/GSM/GSML3Message.h   
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/GSM/GSML3Message.h   
2008-11-30 07:36:33 UTC (rev 10095)
@@ -102,7 +102,7 @@
                It can't be pure virtual because it is not needed by all 
subclasses.
        */
        virtual void writeBody(L3Frame& dest, size_t &writePosition) const
-       { abort(); }
+       { CERR("unimplemented L3Message::writeBody"); abort(); }
 
        /**
                The parseBody() method starts processing at the first byte 
following the
@@ -111,7 +111,7 @@
                It can't be pure virtual because it is not needed by all 
subclasses.
        */
        virtual void parseBody(const L3Frame& source, size_t &readPosition)
-       { abort(); }
+       { CERR("unimplemented L3Message::parseBody"); abort(); }
 
 
        public:
@@ -201,7 +201,7 @@
          @param rp Bit index of read position (updated by read).
        */
        virtual void parseV(const L3Frame& src, size_t &rp )
-       { abort(); }
+       { CERR("unimplemented L3ProtocolElement::parseV"); abort(); }
 
        /**
          The parseV method decodes L3 message bits from variable-length value 
parts.
@@ -213,7 +213,7 @@
          @param expectedLength Length of available field, in bytes.
        */
        virtual void parseV(const L3Frame& src, size_t &rp, size_t 
expectedLength)
-       { abort(); }
+       { CERR("unimplemented L3ProtocolElement::parseV"); abort(); }
 
 
        /**
@@ -250,7 +250,7 @@
                @param wp The write index (updated by write).
        */
        virtual void writeV(L3Frame& dest, size_t &wp) const
-       { abort(); }
+       { CERR("unimplemented L3ProtocolElement::writeV"); abort(); }
 
        /**
                Write LV format.

Modified: openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRElements.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRElements.cpp      
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRElements.cpp      
2008-11-30 07:36:33 UTC (rev 10095)
@@ -111,6 +111,7 @@
 }
 
 
+
 void L3ControlChannelDescription::text(ostream& os) const
 {
        os << "ATT=" << mATT;
@@ -298,6 +299,7 @@
 
 void L3ChannelDescription::writeV( L3Frame &dest, size_t &wp ) const 
 {
+       // GSM 04.08 10.5.2.5
 //                                     Channel Description Format (non-hopping)
 //                     7      6      5      4      3     2      1      0
 //       [         TSC       ][ H=0 ][ SPARE(0,0)][ ARFCN[9:8] ]  Octet 3
@@ -305,7 +307,7 @@
 //
 
        // HACK -- Hard code for non-hopping.
-
+       assert(mHFlag==0);
        dest.writeField(wp,mTypeAndOffset,5);
        dest.writeField(wp,mTN,3);
        dest.writeField(wp,mTSC,3);
@@ -314,6 +316,24 @@
 }
 
 
+
+void L3ChannelDescription::parseV(const L3Frame& src, size_t &rp)
+{
+       // GSM 04.08 10.5.2.5
+       mTypeAndOffset = (TypeAndOffset)src.readField(rp,5);
+       mTN = src.readField(rp,3);
+       mTSC = src.readField(rp,3);
+       mHFlag = src.readField(rp,1);
+       if (mHFlag) {
+               mMAIO = src.readField(rp,6);
+               mHSN = src.readField(rp,6);
+       } else {
+               rp += 2;        // skip 2 spare bits
+               mARFCN = src.readField(rp,10);
+       }
+}
+
+
 void L3ChannelDescription::text(std::ostream& os) const
 {
 
@@ -405,6 +425,13 @@
        dest.writeField(wp, mMode, 8);
 }
 
+void L3ChannelMode::parseV(const L3Frame& src, size_t& rp)
+{
+       mMode = (Mode)src.readField(rp,8);
+}
+
+
+
 ostream& GSM::operator<<(ostream& os, L3ChannelMode::Mode mode)
 {
        switch (mode) {

Modified: openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRElements.h
===================================================================
--- openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRElements.h        
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRElements.h        
2008-11-30 07:36:33 UTC (rev 10095)
@@ -100,7 +100,7 @@
        unsigned mCELL_RESELECT_HYSTERESIS;
        unsigned mMS_TXPWR_MAX_CCH;
        unsigned mACS;
-       unsigned mNECI;
+       static const unsigned mNECI = 0;        // new establishment causes not 
supported
        unsigned mRXLEV_ACCESS_MIN;
 
        public:
@@ -112,7 +112,6 @@
                mCELL_RESELECT_HYSTERESIS=6;            // 8 dB reselect
                mMS_TXPWR_MAX_CCH=0;                            // a high power 
level in all bands
                mACS=0;                                                         
// no additional relesect parameters
-               mNECI=0;                                                        
// new establishment causes not supported
                mRXLEV_ACCESS_MIN=0;                            // lowest 
allowed access level
        }
 
@@ -388,10 +387,18 @@
                mARFCN(wARFCN),
                mMAIO(0),mHSN(0)
        { }
+
+       /** Blank initializer */
+       L3ChannelDescription()
+               :mTypeAndOffset(TDMA_MISC),
+               mTN(0),mTSC(0),mHFlag(0),mARFCN(0),mMAIO(0),mHSN(0)
+       { }
        
 
        void writeV( L3Frame &dest, size_t &wp ) const;
 
+       void parseV(const L3Frame& src, size_t &rp);
+
        size_t lengthV() const  { return 3; }
 
        void text(std::ostream&) const;
@@ -538,7 +545,11 @@
                mMode(wMode)
        {}
 
+       bool operator==(const L3ChannelMode& other) const { return 
mMode==other.mMode; }
+       bool operator!=(const L3ChannelMode& other) const { return 
mMode!=other.mMode; }
+
        void writeV(L3Frame& dest, size_t &wp) const;
+       void parseV(const L3Frame& src, size_t& wp);
        size_t lengthV() const { return 1; }
        void text(std::ostream&) const;
 

Modified: openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRMessages.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRMessages.cpp      
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRMessages.cpp      
2008-11-30 07:36:33 UTC (rev 10095)
@@ -121,6 +121,7 @@
                case L3RRMessage::AssignmentFailure: return new 
L3AssignmentFailure();
                case L3RRMessage::RRStatus: return new L3RRStatus();
                case L3RRMessage::PagingResponse: return new L3PagingResponse();
+               case L3RRMessage::ChannelModeModifyAcknowledge: return new 
L3ChannelModeModifyAcknowledge();
                default:
                        CERR("WARNING -- no L3 RR factory support for " << MTI);
                        return NULL;
@@ -143,6 +144,23 @@
 
 
 
+/**
+This is a local function to map the GSM::ChannelType enum
+to one of the codes from GMS 04.07 10.5.2.8.
+*/
+unsigned channelNeededCode(ChannelType wType)
+{
+       switch (wType) {
+               case AnyDCCHType: return 0;
+               case SDCCHType: return 1;
+               case TCHFType: return 2;
+               case AnyTCHType: return 3;
+               default: abort();
+       }
+}
+
+
+
 size_t L3PagingRequestType1::bodyLength() const
 {
        int sz = mMobileIDs.size();
@@ -154,14 +172,25 @@
 }
 
 
+
 void L3PagingRequestType1::writeBody(L3Frame& dest, size_t &wp) const
 {
+       // See GSM 04.08 9.1.22.
+       // Page Mode Page Mode M V 1/2 10.5.2.26    
+       // Channels Needed  M V 1/2 
+       // Mobile Identity 1 M LV 2-9 10.5.1.4    
+       // 0x17 Mobile Identity 2 O TLV  3-10 10.5.1.4    
+
        int sz = mMobileIDs.size();
        assert(sz<=2);
-       // Remember for reverse orders of 1/2-octet fields.
+       // Remember to reverse orders of 1/2-octet fields.
        // Because GSM transmits LSB-first within each byte.
-       dest.writeField(wp,0x0,4);              // "any channel", GSM 04.08 
Table 10.5.29
-       dest.writeField(wp,0x0,4);              // "normal paging", GSM 04.08 
Table 10.5.63
+       // channel needed codes
+       dest.writeField(wp,channelNeededCode(mChannelsNeeded[1]),2);
+       dest.writeField(wp,channelNeededCode(mChannelsNeeded[0]),2);
+       // "normal paging", GSM 04.08 Table 10.5.63
+       dest.writeField(wp,0x0,4);
+       // the actual mobile IDs
        mMobileIDs[0].writeLV(dest,wp);
        if (sz>1) mMobileIDs[1].writeTLV(0x17,dest,wp);
 }
@@ -172,7 +201,7 @@
        L3RRMessage::text(os);
        os << " mobileIDs=(";
        for (unsigned i=0; i<mMobileIDs.size(); i++) {
-               os << "(" << mMobileIDs[i] << "),";
+               os << "(" << mMobileIDs[i] << "," << mChannelsNeeded[i] << "),";
        }
        os << ")";
 }
@@ -500,5 +529,34 @@
 
 
 
+void L3ChannelModeModify::writeBody(L3Frame &dest, size_t& wp) const
+{
+       mDescription.writeV(dest,wp);
+       mMode.writeV(dest,wp);
+}
 
+
+void L3ChannelModeModify::text(ostream& os) const
+{
+       L3RRMessage::text(os);
+       os << "description=(" << mDescription << ")";
+       os << " mode=(" << mMode << ")";
+}
+
+
+void L3ChannelModeModifyAcknowledge::parseBody(const L3Frame &src, size_t& rp)
+{
+       mDescription.parseV(src,rp);
+       mMode.parseV(src,rp);
+}
+
+
+void L3ChannelModeModifyAcknowledge::text(ostream& os) const
+{
+       L3RRMessage::text(os);
+       os << "description=(" << mDescription << ")";
+       os << " mode=(" << mMode << ")";
+}
+
+
 // vim: ts=4 sw=4

Modified: openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRMessages.h
===================================================================
--- openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRMessages.h        
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/GSM/GSML3RRMessages.h        
2008-11-30 07:36:33 UTC (rev 10095)
@@ -95,12 +95,12 @@
                ///@name miscellaneous
                //@{
                ChannelModeModify=0x10,
+               RRStatus=0x12,
+               ChannelModeModifyAcknowledge=0x17,
                ClassmarkChange=0x16,
+               MeasurementReport = 0x15,
                GPRSSuspensionRequest=0x34,
-               RRStatus=0x12,
                //@}
-               /// reporting
-               MeasurementReport = 0x15,
                ///@name special cases -- assigned >8-bit codes to avoid 
conflicts
                //@{
                SynchronizationChannelInformation=0x100,
@@ -141,6 +141,7 @@
        private:
 
        std::vector<L3MobileIdentity> mMobileIDs;
+       ChannelType mChannelsNeeded[2];
 
 
        public:
@@ -150,19 +151,30 @@
        {
                // The empty paging request is a single untyped mobile ID.
                mMobileIDs.push_back(L3MobileIdentity());
+               mChannelsNeeded[0]=AnyDCCHType;
+               mChannelsNeeded[1]=AnyDCCHType;
        }
 
-       L3PagingRequestType1(const L3MobileIdentity& wId)
+       L3PagingRequestType1(const L3MobileIdentity& wId, ChannelType wType)
                :L3RRMessage()
-       { mMobileIDs.push_back(wId); }
+       {
+               mMobileIDs.push_back(wId);
+               mChannelsNeeded[0]=wType;
+               mChannelsNeeded[1]=AnyDCCHType;
+       }
 
-       L3PagingRequestType1(const L3MobileIdentity& wId1, const 
L3MobileIdentity& wId2)
+       L3PagingRequestType1(const L3MobileIdentity& wId1, ChannelType wType1,
+                       const L3MobileIdentity& wId2, ChannelType wType2)
                :L3RRMessage()
        {
                mMobileIDs.push_back(wId1);
+               mChannelsNeeded[0]=wType1;
                mMobileIDs.push_back(wId2);
+               mChannelsNeeded[1]=wType2;
        }
 
+       unsigned chanCode(ChannelType) const;
+
        size_t bodyLength() const;
 
        int MTI() const { return PagingRequestType1; }
@@ -672,7 +684,60 @@
 
 
 
+/** GSM 04.08 9.1.5 */
+class L3ChannelModeModify : public L3RRMessage {
 
+       private:
+
+       L3ChannelDescription mDescription;
+       L3ChannelMode mMode;
+
+       public:
+
+       L3ChannelModeModify(const L3ChannelDescription& wDescription,
+                                               const L3ChannelMode& wMode)
+               :L3RRMessage(),
+               mDescription(wDescription),
+               mMode(wMode)
+       {}
+
+       int MTI() const { return (int) ChannelModeModify; }
+
+       size_t bodyLength() const
+               { return mDescription.lengthV() + mMode.lengthV(); }
+
+       void writeBody(L3Frame&, size_t&) const;
+
+       void text(std::ostream&) const;
+};
+
+
+/** GSM 04.08 9.1.6 */
+class L3ChannelModeModifyAcknowledge : public L3RRMessage {
+
+       private:
+
+       L3ChannelDescription mDescription;
+       L3ChannelMode mMode;
+
+       public:
+
+       const L3ChannelDescription& description() const { return mDescription; }
+       const L3ChannelMode& mode() const { return mMode; }
+
+       int MTI() const { return (int) ChannelModeModifyAcknowledge; }
+
+       size_t bodyLength() const
+               { return mDescription.lengthV() + mMode.lengthV(); }
+
+       void parseBody(const L3Frame&, size_t&);
+
+       void text(std::ostream&) const;
+};
+
+
+
+
 }; // GSM
 
 

Modified: 
openbts/branches/developers/dburgess00/smswork/GSM/GSMLogicalChannel.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/GSM/GSMLogicalChannel.cpp    
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/GSM/GSMLogicalChannel.cpp    
2008-11-30 07:36:33 UTC (rev 10095)
@@ -141,7 +141,7 @@
        // SAP0 is RR/MM/CC, SAP3 is SMS
        // SAP1 and SAP2 are not used.
        mL2[0] = new SDCCHL2(1,0);
-       //mL2[3] = new SDCCHL2(1,3);
+       mL2[3] = new SDCCHL2(1,3);
        mSACCH = new SACCHLogicalChannel(wTN,wMapping.SACCH());
        connect();
 }
@@ -155,9 +155,10 @@
                const MappingPair& wMapping)
 {
        mL1 = new SACCHL1FEC(wTN,wMapping);
+       // SAP0 is RR, SAP3 is SMS
+       // SAP1 and SAP2 are not used.
        mL2[0] = new SACCHL2(1,0);
-       // SACCH SAP3 is used for in-call SMS.
-       //mL2[3] = new SACCHL2(1,3);
+       mL2[3] = new SACCHL2(1,3);
        connect();
        assert(mSACCH==NULL);
 }
@@ -206,8 +207,10 @@
 {
        mTCHL1 = new TCHFACCHL1FEC(wTN,wMapping.LCH());
        mL1 = mTCHL1;
+       // SAP0 is RR/MM/CC, SAP3 is SMS
+       // SAP1 and SAP2 are not used.
        mL2[0] = new FACCHL2(1,0);
-       //mL2[3] = new FACCHL2(1,3);
+       mL2[3] = new FACCHL2(1,3);
        mSACCH = new SACCHLogicalChannel(wTN,wMapping.SACCH());
        connect();
 }

Modified: openbts/branches/developers/dburgess00/smswork/Makefile.common
===================================================================
--- openbts/branches/developers/dburgess00/smswork/Makefile.common      
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/Makefile.common      
2008-11-30 07:36:33 UTC (rev 10095)
@@ -22,6 +22,7 @@
 CONTROL_INCLUDEDIR = $(top_srcdir)/Control
 GSM_INCLUDEDIR = $(top_srcdir)/GSM
 SIP_INCLUDEDIR = $(top_srcdir)/SIP
+SMS_INCLUDEDIR = $(top_srcdir)/SMS
 TRX_INCLUDEDIR = $(top_srcdir)/TRXManager
 
 STD_DEFINES_AND_INCLUDES = \
@@ -29,11 +30,13 @@
        -I$(CONTROL_INCLUDEDIR) \
        -I$(GSM_INCLUDEDIR) \
        -I$(SIP_INCLUDEDIR) \
+       -I$(SMS_INCLUDEDIR) \
        -I$(TRX_INCLUDEDIR)
 
 COMMON_LA = $(top_builddir)/CommonLibs/libcommon.la
 GSM_LA = $(top_builddir)/GSM/libGSM.la
 SIP_LA = $(top_builddir)/SIP/libSIP.la
+SMS_LA = $(top_builddir)/SMS/libSMS.la
 TRX_LA = $(top_builddir)/TRXManager/libtrxmanager.la
 CONTROL_LA = $(top_builddir)/Control/libcontrol.la
 

Modified: openbts/branches/developers/dburgess00/smswork/SIP/SIPInterface.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/SIP/SIPInterface.cpp 
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/SIP/SIPInterface.cpp 
2008-11-30 07:36:33 UTC (rev 10095)
@@ -43,9 +43,17 @@
 using namespace Control;
 
 
+/**
+       The channel type to request in paging.
+       Request SDCCHType for early assignment or
+       TCHFType for very early assignment.
+*/
+const GSM::ChannelType RequiredChannel = GSM::TCHFType;
+//const GSM::ChannelType RequiredChannel = GSM::SDCCHType;
 
 
 
+
 // SIPMessageMap method definitions.
 
 void SIPMessageMap::write(const std::string& call_id, osip_message_t * msg)
@@ -193,7 +201,7 @@
        if(msg->sip_method == NULL){ return false; }
        if( strcmp(msg->sip_method,"INVITE") != 0) {return false;}
 
-       // FIXME -- Check gBTS for TCH and SDCCH availability.  Bug #130.
+       // FIXME -- Check gBTS for TCH availability, bug #330.
        // Respond with a congestion message if none are available.
 
        // Get call_id from invite message.
@@ -219,18 +227,13 @@
                        return false;
                }
                DCOUT("SIPInterface::checkInvite: repeated SIP invite, 
repaging") 
-               gBTS.pager().addID(mobile_id);  
+               gBTS.pager().addID(mobile_id,RequiredChannel);  
                transaction.T3113().set();
                gTransactionTable.update(transaction);
                osip_free(to_uri);
                return false;
        }
 
-       // FIXME -- At this point, check for the mobile_id in the transaction 
table.
-       // Bug #131.
-       // If it's there, it could mean the phone's already busy, depending on 
the state.
-       // Respond with Busy.
-
        // Add an entry to the SIP Map.
        mSIPMap.add(call_id_string);
 
@@ -254,7 +257,7 @@
        
        // Add to paging list.
        DCOUT("SIPInterface::checkInvite: new SIP invite, initial paging") 
-       gBTS.pager().addID(mobile_id);  
+       gBTS.pager().addID(mobile_id,RequiredChannel);  
 
        osip_free(to_uri);
        return true;

Modified: openbts/branches/developers/dburgess00/smswork/SMS/Makefile.am
===================================================================
--- openbts/branches/developers/dburgess00/smswork/SMS/Makefile.am      
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/SMS/Makefile.am      
2008-11-30 07:36:33 UTC (rev 10095)
@@ -25,23 +25,10 @@
 noinst_LTLIBRARIES = libSMS.la
 
 libSMS_la_SOURCES = \
-       CMMessage.cpp \
-       CMProcessor.cpp \
-       RLMessage.cpp \
-       RLProcessor.cpp \
        SMSMessages.cpp \
-       SMSProcessors.cpp \
-       SMSTransfer.cpp \
-       TLMessage.cpp \
-       TLProcessor.cpp
+       SMSTransfer.cpp
 
 noinst_HEADERS = \
-       CMMessage.h \
-       CMProcessor.h \
-       RLMessage.h \
-       RLProcessor.h \
        SMSMessages.h \
-       SMSProcessors.h \
        SMSTransfer.h \
-       TLMessage.h \
-       TLProcessor.h
+       SMSCommon.h

Deleted: openbts/branches/developers/dburgess00/smswork/SMS/README.SMS

Deleted: openbts/branches/developers/dburgess00/smswork/SMS/RLMessage.cpp

Deleted: openbts/branches/developers/dburgess00/smswork/SMS/RLMessage.h

Added: openbts/branches/developers/dburgess00/smswork/SMS/SMSCommon.h
===================================================================
--- openbts/branches/developers/dburgess00/smswork/SMS/SMSCommon.h              
                (rev 0)
+++ openbts/branches/developers/dburgess00/smswork/SMS/SMSCommon.h      
2008-11-30 07:36:33 UTC (rev 10095)
@@ -0,0 +1,44 @@
+/*
+* Copyright 2008 Free Software Foundation, Inc.
+*
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+* This software is distributed under the terms of the GNU Public License.
+* See the COPYING file in the main directory for details.
+*/
+
+
+
+#ifndef SMS_COMMON_H
+#define SMS_COMMON_H
+
+namespace SMS { 
+
+/// All possible states depicted in GSM 04.11 Annex B SDL-19 -> SDL-24 
+enum CMState {
+       MO_Idle,
+       MO_WaitForRPAck,
+       MO_WaitForCPAck,
+       MT_Idle,
+       MT_WaitForCPAck,
+       MT_WaitForCPData
+};
+
+
+}; //namespace SMS
+#endif
+
+
+// vim: ts=4 sw=4

Modified: openbts/branches/developers/dburgess00/smswork/SMS/SMSMessages.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/SMS/SMSMessages.cpp  
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/SMS/SMSMessages.cpp  
2008-11-30 07:36:33 UTC (rev 10095)
@@ -21,16 +21,15 @@
 
 
 
-#include "GSML3Message.h"
-#include "SMSTransfer.h"
-#include "CMMessage.h"
+#include "SMSMessages.h"
 
 using namespace std;
 using namespace GSM;
 using namespace SMS;
 
-#define DEBUG 1
 
+
+
 ostream& SMS::operator<<(ostream& os, CPMessage::MessageType val)
 {
        switch(val) {
@@ -135,4 +134,26 @@
 }
 
 
+
+
+ostream& SMS::operator<<(ostream& os, RPMessage::MessageType val)
+{
+       switch(val) {
+               case RPMessage::Data:
+                       os<<"RP-Data"; break;
+               case RPMessage::Ack:
+                       os<<"RP-Ack"; break;
+               case RPMessage::Error:
+                       os<<"RP-Error"; break;
+               case RPMessage::SMMA:
+                       os<<"RP-SMMA"; break;
+               default :
+                       os<<hex<<"0x"<<(int)val<<dec; break;
+       }
+
+       return os;
+}
+
+
+
 // vim: ts=4 sw=4

Modified: openbts/branches/developers/dburgess00/smswork/SMS/SMSMessages.h
===================================================================
--- openbts/branches/developers/dburgess00/smswork/SMS/SMSMessages.h    
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/SMS/SMSMessages.h    
2008-11-30 07:36:33 UTC (rev 10095)
@@ -24,71 +24,228 @@
 #ifndef CM_MESSAGE_H
 #define CM_MESSAGE_H
 
+#include "SMSTransfer.h"
 #include <GSML3Message.h>
+#include <GSML3CCElements.h>
 
 
 namespace SMS {
 
+
+/address@hidden Elements for SMS RP (RL Layer) */
+//@{
+
+/** A common class for RP addresses, GSM 04.11 8.2.5 */
+class RPAddress : public GSM::L3CalledPartyBCDNumber { };
+
+/** GSM 04.11 8.2.5.3 */
+class RPUserData : public GSM::L3ProtocolElement {
+
+       private:
+
+       // The BitVector is a placeholder for a higher-layer object.
+       BitVector mTPDU;
+
+       public:
+
+       RPUserData()
+               :L3ProtocolElement(),
+               mTPDU()
+       {}
+
+       RPUserData(const BitVector& wTPDU)
+               :L3ProtocolElement(),
+               mTPDU(wTPDU)
+       {}
+
+       size_t lengthV() const { return mTPDU.size()/8; }
+
+       void parseV(const RLFrame& src, size_t &rp, size_t expectedLength);
+
+       void writeV(RLFrame& dest, size_t &wp) const;
+
+       void text(std::ostream& os) const { os << mTPDU; }
+};
+
+
 /**
-       A virtual class for SMS CM-layer messages.
-       See GSM 04.11 7.
-       This is probably nearly the same as GSM::L3CCMessage,
-       but with different message types.
+       GSM 04.11 8.2.5.4.
+       We ignore the diagnostics field.
 */
+class RPCause : public GSM::L3ProtocolElement {
 
-class CPMessage : public GSM::L3Message 
-{
+
        private:
 
-       /address@hidden Header information ref. Figure 8. GSM 04.11 */
-       //@{
-       unsigned mTIFlag;       ///< 0 for originating side, see GSM 04.07 
11.2.3.1.3
-       unsigned mTIValue;      ///< short transaction ID, GSM 04.07 11.2.3.1.3
-       //@}
+       unsigned mValue;
 
+       public:
 
+       RPCause(unsigned wValue)
+               :L3ProtocolElement(),
+               mValue(wValue)
+       {}
+
+       size_t lengthV() const { return 1; }
+
+       void parseV(const RLFrame& src, size_t &rp, size_t expectedLength)
+               { mValue = src.peekField(rp,8); rp += expectedLength*8; }
+
+       void writeV(RLFrame& dest, size_t &wp) const
+               { dest.writeField(wp,mValue,8); }
+
+       void text(std::ostream& os) const
+               { os << std::hex << "0x" << mValue << std::dec; }
+};
+
+//@}
+
+
+
+
+
+/address@hidden Messages for SMS RP (RL Layer) */
+//@{
+
+/** The L4 RP message, GSM 04.11 7.3, 8.2. */
+class RPMessage {
+
        public:
 
-       /** Message type defined in GSM 04.11 8.1.3 Table 8.1 */
+       unsigned mMessageReference;
+
+       /// Table 8.3 GSM 04.11, add 1 for downlink
        enum MessageType {
-               Data=0x01,
-               Ack=0x04,
-               Error=0x10
+               Data=0x0,
+               Ack=0x2,
+               Error=0x4,
+               SMMA=0x6
        };
 
+       virtual ~RPMessage(){}
 
-       CPMessage( unsigned wTIFlag, unsigned wTIValue )
-               :L3Message(),
-               mTIFlag(wTIFlag), mTIValue(wTIValue)
+       virtual int MTI() const=0;
+
+       virtual size_t bodyLength() const = 0;
+
+       virtual size_t length() { return bodyLength()+2; }
+
+       size_t bitsNeeded() const { return bodyLength()*8; }
+
+       virtual void parse( const RLFrame& frame );
+       virtual void parseBody( const RLFrame& frame, size_t &rp) {abort();} 
+
+       /** For the network side, the write method adds 1 to the MTI. */
+       virtual void write( RLFrame& frame ) const;
+       virtual void writeBody( RLFrame& frame, size_t &rp) const {abort();} 
+
+};
+
+
+std::ostream& operator<<(std::ostream& os, RPMessage::MessageType val);
+
+
+/** GSM 04.11 7.3.1 */
+class RPData : public RPMessage {
+
+       private:
+
+       RPAddress mOriginator;                  ///< originating SMSC
+       RPAddress mDestination;                 ///< destination SMSC
+       RPUserData mUserData;                   ///< payload
+
+       public:
+
+       int MTI() const { return Data; }
+       //void parseBody( const RLFrame& frame, size_t &rp);            
+       //void writeBody( RLFrame & frame, size_t &wp ) const;
+
+       size_t bodyLength() const
+               { return mOriginator.lengthLV() + mDestination.lengthLV() + 
mUserData.lengthLV(); }
+};
+
+
+/** GSM 04.11 7.3.2 */
+class RPSMMA : public RPMessage {
+
+       public:
+
+       int MTI() const { return SMMA; }
+       //void parseBody( const RLFrame& frame, size_t &rp);            
+       //void writeBody( RLFrame & frame, size_t &wp ) const;
+
+       size_t bodyLength() const { return 0; }
+};
+
+
+/** GSM 04.11 7.3.3 */
+class RPAck : public RPMessage {
+
+       private:
+
+       bool mHaveUserData;
+       RPUserData mUserData;
+
+       public:
+       
+       RPAck()
+               :RPMessage(),
+               mHaveUserData(false)
        {}
 
-       /** Override the write method to include transaction identifiers in 
header. */
-       void write(GSM::L3Frame& dest) const;
+       RPAck(const RPUserData& wUserData)
+               :RPMessage(),
+               mHaveUserData(true),mUserData(wUserData)
+       {}
 
-       GSM::L3PD PD() const { return GSM::L3SMSPD; }
+       int MTI() const { return Ack; }
 
-       unsigned TIValue() const { return mTIValue; }
-       void TIValue(unsigned wTIValue){ mTIValue=wTIValue; }
+       //void writeBody( RLFrame & frame, size_t &wp )const;
+       size_t length() const { return 0; }
+};
+
+
+/** GSM 04.11 7.3.4 */
+class RPError : public RPMessage {
+
+       private:
+
+       RPCause mCause;
+       bool mHaveUserData;
+       RPUserData mUserData;
+
+       public:
        
-       unsigned TIFlag() const { return mTIFlag; }
-       void TIFlag( unsigned wTIFlag) { mTIFlag=wTIFlag; }
-       
-       void text(std::ostream&) const;
+       RPError(const RPCause& wCause)
+               :RPMessage(),
+               mCause(wCause),
+               mHaveUserData(false)
+       {}
 
+       RPError(const RPCause& wCause, const RPUserData& wUserData)
+               :RPMessage(),
+               mCause(wCause),
+               mHaveUserData(true),mUserData(wUserData)
+       {}
+
+       int MTI() const { return Ack; }
+
+       //void writeBody( RLFrame & frame, size_t &wp )const;
+       size_t length() const { return 0; }
 };
 
 
-std::ostream& operator<<(std::ostream& os, CPMessage::MessageType MTI);
+RPMessage* RPFactory(RPMessage::MessageType MTI);
 
-/** Parse a complete SMS L3 (CM) message. */
-CPMessage * parseSMS( const GSM::L3Frame& frame );
+RPMessage* parseRP(const RLFrame& frame);
 
-/** A factory method for SMS L3 (CM) messages. */
-CPMessage * CPFactory( CPMessage::MessageType MTI );
 
+//@}
 
 
-/address@hidden CP Elements for SMS */
+
+
+/address@hidden Elements for SMS CP (CM Layer) */
 //@{
 
 /** GSM 04.11 8.1.4.2 */
@@ -150,6 +307,72 @@
 //@} // CP Elements
 
 
+
+/address@hidden Messages for SMS CP (SMS CM layer) */
+//@{
+
+/**
+       A virtual class for SMS CM-layer messages.
+       See GSM 04.11 7.
+       This is probably nearly the same as GSM::L3CCMessage,
+       but with different message types.
+*/
+
+class CPMessage : public GSM::L3Message 
+{
+       private:
+
+       /address@hidden Header information ref. Figure 8. GSM 04.11 */
+       //@{
+       unsigned mTIFlag;       ///< 0 for originating side, see GSM 04.07 
11.2.3.1.3
+       unsigned mTIValue;      ///< short transaction ID, GSM 04.07 11.2.3.1.3
+       //@}
+
+
+       public:
+
+       /** Message type defined in GSM 04.11 8.1.3 Table 8.1 */
+       enum MessageType {
+               Data=0x01,
+               Ack=0x04,
+               Error=0x10
+       };
+
+
+       CPMessage( unsigned wTIFlag, unsigned wTIValue )
+               :L3Message(),
+               mTIFlag(wTIFlag), mTIValue(wTIValue)
+       {}
+
+       /** Override the write method to include transaction identifiers in 
header. */
+       void write(GSM::L3Frame& dest) const;
+
+       GSM::L3PD PD() const { return GSM::L3SMSPD; }
+
+       unsigned TIValue() const { return mTIValue; }
+       void TIValue(unsigned wTIValue){ mTIValue=wTIValue; }
+       
+       unsigned TIFlag() const { return mTIFlag; }
+       void TIFlag( unsigned wTIFlag) { mTIFlag=wTIFlag; }
+       
+       void text(std::ostream&) const;
+
+};
+
+
+std::ostream& operator<<(std::ostream& os, CPMessage::MessageType MTI);
+
+/**
+       Parse a complete SMS L3 (CM) message.
+       This is the top-level SMS parser, called along side other L3 parsers.
+*/
+CPMessage * parseSMS( const GSM::L3Frame& frame );
+
+/** A factory method for SMS L3 (CM) messages. */
+CPMessage * CPFactory( CPMessage::MessageType MTI );
+
+
+
 /** GSM 04.11 7.2.1 */
 class CPAck : public CPMessage 
 {      
@@ -208,9 +431,10 @@
        void text(std::ostream&) const;
 };
 
+//@} // CP messages
 
 
-}; // namespace SMS {
+}; // namespace SMS
 
 #endif
 

Modified: openbts/branches/developers/dburgess00/smswork/SMS/SMSTransfer.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/SMS/SMSTransfer.cpp  
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/SMS/SMSTransfer.cpp  
2008-11-30 07:36:33 UTC (rev 10095)
@@ -21,7 +21,7 @@
 
 
 
-#include <BitVector.>
+#include <BitVector.h>
 #include "SMSTransfer.h"
 
 using namespace std;

Modified: openbts/branches/developers/dburgess00/smswork/SMS/SMSTransfer.h
===================================================================
--- openbts/branches/developers/dburgess00/smswork/SMS/SMSTransfer.h    
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/SMS/SMSTransfer.h    
2008-11-30 07:36:33 UTC (rev 10095)
@@ -24,6 +24,8 @@
 #ifndef SMS_TRANSFER_H
 #define SMS_TRANSFER_H
 
+#include <BitVector.h>
+#include <ostream>
 
 namespace SMS {
 

Deleted: openbts/branches/developers/dburgess00/smswork/Transceiver/TODO

Modified: openbts/branches/developers/dburgess00/smswork/apps/Makefile.am
===================================================================
--- openbts/branches/developers/dburgess00/smswork/apps/Makefile.am     
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/apps/Makefile.am     
2008-11-30 07:36:33 UTC (rev 10095)
@@ -33,6 +33,7 @@
        $(GSM_LA) \
        $(TRX_LA) \
        $(CONTROL_LA) \
+       $(SMS_LA) \
        $(OSIP_LIBS) \
        $(ORTP_LIBS)
 
@@ -43,5 +44,6 @@
        $(GSM_LA) \
        $(TRX_LA) \
        $(CONTROL_LA) \
+       $(SMS_LA) \
        $(OSIP_LIBS) \
        $(ORTP_LIBS)

Modified: openbts/branches/developers/dburgess00/smswork/apps/OpenBTS850.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/apps/OpenBTS850.cpp  
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/apps/OpenBTS850.cpp  
2008-11-30 07:36:33 UTC (rev 10095)
@@ -116,7 +116,7 @@
                SDCCH[i].downstream(radio);
                SDCCH[i].open();
                gBTS.addSDCCH(&SDCCH[i]);
-               
SDCCHControlThread[i].start((void*(*)(void*))Control::SDCCHDispatcher,&SDCCH[i]);
+               
SDCCHControlThread[i].start((void*(*)(void*))Control::DCCHDispatcher,&SDCCH[i]);
        }
 
        // TCHs
@@ -134,7 +134,7 @@
                TCH[i].downstream(radio);
                TCH[i].open();
                gBTS.addTCH(&TCH[i]);
-               
TCHControlThread[i].start((void*(*)(void*))Control::FACCHDispatcher,&TCH[i]);
+               
TCHControlThread[i].start((void*(*)(void*))Control::DCCHDispatcher,&TCH[i]);
        }
 
        // Set up the pager.

Modified: openbts/branches/developers/dburgess00/smswork/apps/OpenBTS900.cpp
===================================================================
--- openbts/branches/developers/dburgess00/smswork/apps/OpenBTS900.cpp  
2008-11-30 04:13:24 UTC (rev 10094)
+++ openbts/branches/developers/dburgess00/smswork/apps/OpenBTS900.cpp  
2008-11-30 07:36:33 UTC (rev 10095)
@@ -114,7 +114,7 @@
        Thread SDCCHControlThread[4];
        for (int i=0; i<4; i++) {
                SDCCH[i].downstream(radio);
-               
SDCCHControlThread[i].start((void*(*)(void*))Control::SDCCHDispatcher,&SDCCH[i]);
+               
SDCCHControlThread[i].start((void*(*)(void*))Control::DCCHDispatcher,&SDCCH[i]);
                SDCCH[i].open();
                gBTS.addSDCCH(&SDCCH[i]);
        }
@@ -132,7 +132,7 @@
        Thread TCHControlThread[7];
        for (int i=0; i<7; i++) {
                TCH[i].downstream(radio);
-               
TCHControlThread[i].start((void*(*)(void*))Control::FACCHDispatcher,&TCH[i]);
+               
TCHControlThread[i].start((void*(*)(void*))Control::DCCHDispatcher,&TCH[i]);
                TCH[i].open();
                gBTS.addTCH(&TCH[i]);
        }





reply via email to

[Prev in Thread] Current Thread [Next in Thread]