コード例 #1
0
void serialTranslateCapsule_Actor::rtsBehavior( int signalIndex, int portIndex )
{
	for( int stateIndex = getCurrentState(); ; stateIndex = rtg_parent_state[ stateIndex - 1 ] )
		switch( stateIndex )
		{
		case 1:
			// {{{RME state ':TOP'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					chain1_Initial();
					return;
				default:
					break;
				}
				break;
			default:
				break;
			}
			unexpectedMessage();
			return;
			// }}}RME
		case 2:
			// {{{RME state ':TOP:S1'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			case 1:
				// {{{RME port 'serialRaw'
				switch( signalIndex )
				{
				case serialRawProtocol::Conjugate::rti_dataReceived:
					chain2_dataReceived();
					return;
				case serialRawProtocol::Conjugate::rti_comOpened:
					chain4_comOpened();
					return;
				case serialRawProtocol::Conjugate::rti_comError:
					chain5_comError();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			case 2:
				// {{{RME port 'serialOut'
				switch( signalIndex )
				{
				case serialProtocol::Base::rti_sendCommand:
					chain3_sendCommand();
					return;
				case serialProtocol::Base::rti_commandLength:
					chain6_lengthReceived();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			default:
				break;
			}
			break;
			// }}}RME
		default:
			unexpectedState();
			return;
		}
}
コード例 #2
0
ファイル: roombaProgram.cpp プロジェクト: K-4U/ese_project4y5
void roombaProgram_Actor::rtsBehavior( int signalIndex, int portIndex )
{
	for( int stateIndex = getCurrentState(); ; stateIndex = rtg_parent_state[ stateIndex - 1 ] )
		switch( stateIndex )
		{
		case 1:
			// {{{RME state ':TOP'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					chain5_Initial();
					return;
				default:
					break;
				}
				break;
			default:
				break;
			}
			unexpectedMessage();
			return;
			// }}}RME
		case 2:
			// {{{RME state ':TOP:roombaWaitForStart'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			case 1:
				// {{{RME port 'Roomba'
				switch( signalIndex )
				{
				case programProtocol::Base::rti_start:
					chain1_Start();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			default:
				break;
			}
			break;
			// }}}RME
		case 3:
			// {{{RME state ':TOP:roombaStart'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			case 1:
				// {{{RME port 'Roomba'
				switch( signalIndex )
				{
				case programProtocol::Base::rti_bumpersTriggered:
					chain4_bumperTriggered();
					return;
				case programProtocol::Base::rti_stop:
					chain7_Stop();
					return;
				case programProtocol::Base::rti_sideBrushOverCurrent:
					chain11_noOverCurrent();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			default:
				break;
			}
			break;
			// }}}RME
		case 4:
			// {{{RME state ':TOP:rotating'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			case 1:
				// {{{RME port 'Roomba'
				switch( signalIndex )
				{
				case programProtocol::Base::rti_bumpersTriggered:
					chain9_bumperTriggered();
					return;
				case programProtocol::Base::rti_stop:
					chain6_Stop();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			case 2:
				// {{{RME port 'timer'
				switch( signalIndex )
				{
				case Timing::Base::rti_timeout:
					chain8_doneRotating();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			default:
				break;
			}
			break;
			// }}}RME
		case 5:
			// {{{RME state ':TOP:CheckWhereWeAre'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			case 1:
				// {{{RME port 'Roomba'
				switch( signalIndex )
				{
				case programProtocol::Base::rti_isCharging:
					chain10_Start();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			default:
				break;
			}
			break;
			// }}}RME
		default:
			unexpectedState();
			return;
		}
}
コード例 #3
0
void Local_Controller_Actor::rtsBehavior( int signalIndex, int portIndex )
{
	for( int stateIndex = getCurrentState(); ; stateIndex = rtg_parent_state[ stateIndex - 1 ] )
		switch( stateIndex )
		{
		case 1:
			// {{{RME state ':TOP'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					chain1_Initial();
					return;
				default:
					break;
				}
				break;
			default:
				break;
			}
			////unexpectedMessage();
			return;
			// }}}RME
		case 2:
			// {{{RME state ':TOP:Ready'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			case 2:
				// {{{RME port 'Updater'
				switch( signalIndex )
				{
				case Timing::Base::rti_timeout:
					chain5_Update();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			case 3:
				// {{{RME port 'Elevator_Request_Line_OUT'
				switch( signalIndex )
				{
				case Elevator_Request_Protocol::Conjugate::rti_Add_Floor_Request:
					chain2_Handle_Floor_Request_Internal();
					return;
				case Elevator_Request_Protocol::Conjugate::rti_Open_Doors:
					chain8_Open_Doors();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			case 4:
				// {{{RME port 'Central_IN'
				switch( signalIndex )
				{
				case Elevator_Request_Protocol::Conjugate::rti_Add_Floor_Request:
					chain6_Handle_Floor_Request_External();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			case 5:
				// {{{RME port 'Elevator_Internals_OUT'
				switch( signalIndex )
				{
				case Elevator_Internals::Base::rti_Arrived_Target:
					chain3_Arrive_at_Floor();
					return;
				case Elevator_Internals::Base::rti_New_Current_Floor:
					chain4_New_Current_Floor();
					return;
				case Elevator_Internals::Base::rti_E_Brake_Engaged:
					chain7_E_BRAKE();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			default:
				break;
			}
			break;
			// }}}RME
		default:
			unexpectedState();
			return;
		}
}
コード例 #4
0
void ElevatorDoor_Actor::rtsBehavior( int signalIndex, int portIndex )
{
	for( int stateIndex = getCurrentState(); ; stateIndex = rtg_parent_state[ stateIndex - 1 ] )
		switch( stateIndex )
		{
		case 1:
			// {{{RME state ':TOP'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					chain1_Initial();
					return;
				default:
					break;
				}
				break;
			default:
				break;
			}
			unexpectedMessage();
			return;
			// }}}RME
		case 2:
			// {{{RME state ':TOP:Closed'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			case 1:
				// {{{RME port 'LEDPort'
				switch( signalIndex )
				{
				case LEDProtocol::Base::rti_init:
					chain4_init();
					return;
				case LEDProtocol::Base::rti_openDoor:
					chain2_openDoor();
					return;
				case LEDProtocol::Base::rti_closeDoor:
					chain5_ignore();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			case 2:
				// {{{RME port 'EDDSPort'
				switch( signalIndex )
				{
				case EDDSProtocol::Conjugate::rti_impede:
					chain5_ignore();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			default:
				break;
			}
			break;
			// }}}RME
		case 3:
			// {{{RME state ':TOP:Opened'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			case 1:
				// {{{RME port 'LEDPort'
				switch( signalIndex )
				{
				case LEDProtocol::Base::rti_openDoor:
					chain10_ignore();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			case 2:
				// {{{RME port 'EDDSPort'
				switch( signalIndex )
				{
				case EDDSProtocol::Conjugate::rti_impede:
					chain10_ignore();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			case 3:
				// {{{RME port 'doorTimer'
				switch( signalIndex )
				{
				case Timing::Base::rti_timeout:
					chain3_closeDoor();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			case 4:
				// {{{RME port 'closeTimer'
				switch( signalIndex )
				{
				case Timing::Base::rti_timeout:
					chain10_ignore();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			default:
				break;
			}
			break;
			// }}}RME
		case 4:
			// {{{RME state ':TOP:Closing'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			case 1:
				// {{{RME port 'LEDPort'
				switch( signalIndex )
				{
				case LEDProtocol::Base::rti_openDoor:
					chain11_openDoor();
					return;
				case LEDProtocol::Base::rti_closeDoor:
					chain12_ignoreClose();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			case 2:
				// {{{RME port 'EDDSPort'
				switch( signalIndex )
				{
				case EDDSProtocol::Conjugate::rti_impede:
					chain9_impede();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			case 4:
				// {{{RME port 'closeTimer'
				switch( signalIndex )
				{
				case Timing::Base::rti_timeout:
					chain8_doorClosed();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			default:
				break;
			}
			break;
			// }}}RME
		case 5:
			// {{{RME state ':TOP:Opening'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			case 1:
				// {{{RME port 'LEDPort'
				switch( signalIndex )
				{
				case LEDProtocol::Base::rti_openDoor:
					chain7_ignore();
					return;
				case LEDProtocol::Base::rti_closeDoor:
					chain7_ignore();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			case 2:
				// {{{RME port 'EDDSPort'
				switch( signalIndex )
				{
				case EDDSProtocol::Conjugate::rti_impede:
					chain7_ignore();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			case 3:
				// {{{RME port 'doorTimer'
				switch( signalIndex )
				{
				case Timing::Base::rti_timeout:
					chain6_doorOpened();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			default:
				break;
			}
			break;
			// }}}RME
		default:
			unexpectedState();
			return;
		}
}
コード例 #5
0
void DoorSensor_Actor::rtsBehavior( int signalIndex, int portIndex )
{
	for( int stateIndex = getCurrentState(); ; stateIndex = rtg_parent_state[ stateIndex - 1 ] )
		switch( stateIndex )
		{
		case 1:
			// {{{RME state ':TOP'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					chain1_Initial();
					return;
				default:
					break;
				}
				break;
			default:
				break;
			}
			unexpectedMessage();
			return;
			// }}}RME
		case 2:
			// {{{RME state ':TOP:Ready'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			case 1:
				// {{{RME port 'EDDSPort'
				switch( signalIndex )
				{
				case EDDSProtocol::Base::rti_init:
					chain2_init();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			case 2:
				// {{{RME port 'UDSPort'
				switch( signalIndex )
				{
				case UDSProtocol::Base::rti_impede:
					chain3_impede();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			default:
				break;
			}
			break;
			// }}}RME
		default:
			unexpectedState();
			return;
		}
}
コード例 #6
0
ファイル: L3SMSControl.cpp プロジェクト: BrzTit/openbts
MachineStatus MTSMSMachine::machineRunState1(int state,const L3Frame*frame,const L3Message*l3msg, const SIP::DialogMessage*sipmsg)
{
		// Step 1	Network->MS	CP-DATA containing RP-DATA with message
		// Step 2	MS->Network	CP-ACK
			// 4.11 6.2.2 State wait-to-send-RP-ACK, timer TR2M
		// Step 3	MS->Network	CP-DATA containing RP-ACK or RP-Error
		// Step 4	Network->MS	CP-ACK
		//			Network->SIP response.

	PROCLOG2(DEBUG,state)<<LOGVAR(l3msg)<<LOGVAR(sipmsg)<<LOGVAR2("imsi",tran()->subscriber());
	switch(state) {
		case stateStart: {
			// There is no dialog for a SMS initiated on this BTS.
			if (getDialog() && getDialog()->isFinished()) {
				// SIP side closed already.
				// We can no longer inform the SIP side whether we succeed or not.
				// Should we continue and deliver the message to the MS or not?
				return MachineStatus::QuitTran(TermCause::Local(L3Cause::SMS_Timeout));	// could be a sip internal error?
			}
			timerStart(TR2M,TR2Mms,TimerAbortTran);

			// Allocate Transaction Identifier
			unsigned l3ti = channel()->chanGetContext(true)->mmGetNextTI();
			tran()->setL3TI(l3ti);
			setGSMState(CCState::SMSDelivering);

			this->mRpduRef = random() % 255;

			gReports.incr("OpenBTS.GSM.SMS.MTSMS.Start");

			// pat 6-2014.  We just send the ESTABLISH_REQUEST no matter what now.
			// The LAPDm will respond with ESTABLISH_INDICATION immediately if 
			SAPI_t sap = getSmsSap();
			//L3LogicalChannel *smschan = getSmsChannel();
			//if (smschan->multiframeMode(3)) { goto step1; }		// If already established.
			// if (channel()->multiframeMode(sap)) { goto step1; }		// If already established.

			// Start ABM in SAP3.
			//smschan->l3sendp(GSM::L3_ESTABLISH_REQUEST,SAPI3);
			channel()->l3sendp(GSM::L3_ESTABLISH_REQUEST,sap);
			// Wait for SAP3 ABM to connect.
			// The next read on SAP3 should be the ESTABLISH primitive.
			// This won't return NULL.  It will throw an exception if it fails.
			// (pat) WARNING: Previous code waited for a return ESTABLISH,
			// but I think the l3sendp(ESTABLISH) will hang until this happens so it is now a no-op.
			// delete getFrameSMS(LCH,GSM::ESTABLISH);
			LOG(DEBUG) << "case start returning, after sending ESTABLISH";
			return MachineStatusOK;	// Wait for the ESTABLISH on the uplink.
		}

		// We use ESTABLISH_INDICATION instead of ESTABLISH_CONFIRM to indicate establishment.
		// We would have to accept both ESTABLISH_CONFIRM and ESTABLISH_INDICATION here anyway in case
		// SABM was started by us and handset simultaneously, so we just dont bother with making ESTABLISH_CONFIRM separate.
		case L3CASE_PRIMITIVE(L3_ESTABLISH_INDICATION):
		case L3CASE_PRIMITIVE(L3_ESTABLISH_CONFIRM): {
			// Step 1
			// Send the first message.
			// CP-DATA, containing RP-DATA.

			RPData rp_data;
			int l3ti = getL3TI();
			if (! createRPData(rp_data)) { // NULL can be returned
				l3sendSms(CPData(l3ti,RPError(95,this->mRpduRef)));
				// TODO: Is this correct? 
				// TODO: Make sure MachineStatusQuitTran sends a failure code to SIP.
				if (getDialog()) getDialog()->MTSMSReply(400, "Bad Request");
				return MachineStatus::QuitTran(TermCause::Local(L3Cause::SMS_Error));
			}

			CPData deliver(l3ti,rp_data);
			PROCLOG(INFO) << "sending " << deliver;
	// WORKING: MS Does not respond to this message.
	// (pat) FIXME: The MS may send a DELIVER_REPORT which is discarded by parseTPDU.
			l3sendSms(deliver);
			LOG(DEBUG) << "case ESTABLISH returning, after receiving ESTABLISH";
			return MachineStatusOK; // Wait for CP-ACK message.
		}

		// Step 2
		// Get the CP-ACK.
		case L3CASE_SMS(ACK): {
			// FIXME -- Check reference and check for RPError.
			return MachineStatusOK;	// Now we are waiting for CP-DATA.
		}

		// Step 3
		// Get CP-DATA containing RP-ACK and message reference.
		case L3CASE_SMS(DATA): {
			timerStop(TR2M);
			PROCLOG(DEBUG) << "MTSMS: data from MS " << *l3msg;
			// FIXME -- Check L3 TI.

			// Parse to check for RP-ACK.
			// We already called parsel3 on the message.
			//CPData data;
			//try {
			//	data.parse(*CM);
			//	LOG(DEBUG) << "CPData " << data;
			//}
			//catch (SMSReadError) {
			//	LOG(WARNING) << "SMS parsing failed (above L3)";
			//	// Cause 95, "semantically incorrect message".
			//	LCH->l2sendf(CPError(L3TI,95),3);
			//	throw UnexpectedMessage();
			//}
			//catch (GSM::L3ReadError) {
			//	LOG(WARNING) << "SMS parsing failed (in L3)";
			//	throw UnsupportedMessage();
			//}
			//delete CM;

			const CPData *cpdata = dynamic_cast<typeof(cpdata)>(l3msg);

			// FIXME -- Check SMS reference.

			bool success = true;
			if (cpdata->RPDU().MTI()!=RPMessage::Ack) {
				PROCLOG(WARNING) << "unexpected RPDU " << cpdata->RPDU();
				success = false;
			}

			gReports.incr("OpenBTS.GSM.SMS.MTSMS.Complete");

			// Step 4
			// Send CP-ACK to the MS.
			PROCLOG(INFO) << "MTSMS: sending CPAck";
			l3sendSms(CPAck(getL3TI()));

			// Ack in SIP domain.
			if (!getDialog()) {
				LOG(DEBUG) << "No dialog found for MTSMS; could be welcome message, CLI SMS, or Dialog pre-destroyed error";
			} else if (success) {
				getDialog()->MTSMSReply(200,"OK");
			} else {
				getDialog()->MTSMSReply(400, "Bad Request");
			}

			LOG(DEBUG) << "case DATA returning";
			return MachineStatus::QuitTran(TermCause::Local(L3Cause::SMS_Success));	// Finished.
		}
		default:
			return unexpectedState(state,l3msg);
	}
}
コード例 #7
0
ファイル: L3SMSControl.cpp プロジェクト: BrzTit/openbts
// see: Control::MOSMSController
MachineStatus MOSMSMachine::machineRunState(int state, const GSM::L3Message *l3msg, const SIP::DialogMessage *sipmsg)
{
		// See GSM 04.11 Arrow Diagram A5 for the transaction  (pat) NO, A5 is for GPRS.  Closest diagram is F1.
		//			SIP->Network message.
		// Step 1	MS->Network	CP-DATA containing RP-DATA with message
		// Step 2	Network->MS	CP-ACK
			// 4.11 6.2.2 State wait-for-RP-ACK, timer TR1M
		// Step 3	Network->MS	CP-DATA containing RP-ACK or RP-Error
		// 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.
		// """

	WATCHF("MOSMS state=%x\n",state);
	PROCLOG2(DEBUG,state)<<LOGVAR(l3msg)<<LOGVAR(sipmsg)<<LOGVAR2("imsi",tran()->subscriber());
	switch (state) {
		case L3CASE_MM(CMServiceRequest): {
			timerStart(TCancel,30*1000,TimerAbortTran);	// Just in case.
			// This is both the start state and a request to start a new MO SMS when one is already in progress, as per GSM 4.11 5.4
			const L3CMServiceRequest *req = dynamic_cast<typeof(req)>(l3msg);
			const GSM::L3MobileIdentity &mobileID = req->mobileID();	// Reference ok - the SM is going to copy it.

			// FIXME: We only identify this the FIRST time.
			// The L3IdentifySM can check the MM state and just return.
			// FIXME: check provisioning
			return machPush(new L3IdentifyMachine(tran(),mobileID, &mIdentifyResult), stateIdentResult);
		}
		case stateIdentResult: {
			if (! mIdentifyResult) {
				//const L3CMServiceReject reject = L3CMServiceReject(L3RejectCause::Invalid_Mandatory_Information);
				// (pat 6-2014) I think this is wrong, based on comment below, so changing it to the main channel:
				// l3sendSms(L3CMServiceReject(L3RejectCause::Invalid_Mandatory_Information),SAPI0);
				MMRejectCause rejectCause = L3RejectCause::Invalid_Mandatory_Information;
				channel()->l3sendm(L3CMServiceReject(rejectCause),L3_DATA,SAPI0);
				return MachineStatus::QuitTran(TermCause::Local(rejectCause));
			}

			// Let the phone know we're going ahead with the transaction.
			// The CMServiceReject is on SAPI 0, not SAPI 3.
			PROCLOG(DEBUG) << "sending CMServiceAccept";
			// Update 8-6-2013: The nokia does not accept this message on SACCH SAPI 0 for in-call SMS;
			// so I am trying moving it to the main channel.
			//l3sendSms(GSM::L3CMServiceAccept(),SAPI0);
			channel()->l3sendm(GSM::L3CMServiceAccept(),L3_DATA,SAPI0);

			gReports.incr("OpenBTS.GSM.SMS.MOSMS.Start");
			return MachineStatusOK;
		}

#if FIXME
		case L3CASE_ERROR: {
			// (pat) TODO: Call this on parsel3 error...
			// TODO: Also send an error code to the sip side, if any.

			l3sendSms(CPError(getL3TI()));
			return MachineStatusQuitTran;
		}
#endif

		case L3CASE_SMS(DATA): {
			timerStop(TCancel);
			timerStart(TR1M,TR1Mms,TimerAbortTran);
			// Step 0: Wait for SAP3 to connect.
			// The first read on SAP3 is the ESTABLISH primitive.
			// That was done by our caller.
			//delete getFrameSMS(LCH,GSM::ESTABLISH);

			// Step 1: This is the first message: CP-DATA, containing RP-DATA.
			unsigned L3TI = l3msg->TI() | 0x08;
			tran()->setL3TI(L3TI);

			const CPData *cpdata = dynamic_cast<typeof(cpdata)>(l3msg);
			if (cpdata == NULL) {	// Currently this is impossible, but maybe someone will change the code later.
				l3sendSms(CPError(L3TI));
				return MachineStatus::QuitTran(TermCause::Local(L3Cause::SMS_Error));
			}

			// Step 2: Respond with CP-ACK.
			// This just means that we got the message and could parse it.
			PROCLOG(DEBUG) << "sending CPAck";
			l3sendSms(CPAck(L3TI));

			// (pat) The SMS message has already been through L3Message:parseL3, which called SMS::parseSMS(source), which manufactured
			// a CPMessage::CPData and called L3Message::parse() which called CPData::parseBody which called L3Message::parseLV,
			// which called CPUserData::parseV to leave the result in L3Message::CPMessage::CPData::mData.
			// As the mathemetician said after filling 3 blackboards with formulas: It is obvious!

			// 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.
			// (pat) Update: If we cant parse far enough to get the ref we send a CPError that does not need the ref.
#if 0
			unsigned ref;
			bool success = false;
			try {
				// (pat) hierarchy is L3Message::CPMessage::CPData;  L3Message::parse calls CPData::parseBody.
				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->l3sendf(CPData(L3TI,RPError(95,ref)),3);  if you ever use this, it should call l3sendSms
				delete CM;
				throw UnexpectedMessage();
			}
			catch (GSM::L3ReadError) {
				LOG(WARNING) << "SMS parsing failed (in L3)";
				delete CM;
				throw UnsupportedMessage();
			}
			delete CM;
#endif

			// Step 3
			// Send CP-DATA containing message ref and either RP-ACK or RP-Error.
			// If we cant parse the message, we send RP-Error immeidately, otherwise we wait for the dialog to finish one way or the other.
			const RLFrame &rpdu = cpdata->data().RPDU();
			this->mRpduRef = rpdu.reference();
			bool success = false;
			try {
				// This creates the outgoing SipDialog to send the message.
				success = handleRPDU(rpdu);
			} catch (...) {
				LOG(WARNING) << "SMS parsing failed (above L3)";
			}
			
			if (! success) {
				PROCLOG(INFO) << "sending RPError in CPData";
				// Cause 95 is "semantically incorrect message"
				l3sendSms(CPData(L3TI,RPError(95,mRpduRef)));
			}
			mSmsState = MoSmsWaitForAck;
			LOG(DEBUG) << "case DATA returning";
			return MachineStatusOK;
		}

		case L3CASE_SIP(dialogBye): {	// SIPDialog sends this when the MESSAGE clears.
			PROCLOG(INFO) << "SMS peer did not respond properly to dialog message; sending RPAck in CPData";
			l3sendSms(CPData(getL3TI(),RPAck(mRpduRef)));
			LOG(DEBUG) << "case dialogBye returning";
		}
		case L3CASE_SIP(dialogFail): {
			PROCLOG(INFO) << "sending RPError in CPData";
			// TODO: Map the dialog failure state to an RPError state.
			// Cause 127 is "internetworking error, unspecified".
			// See GSM 04.11 8.2.5.4 Table 8.4.
			l3sendSms(CPData(getL3TI(),RPError(127,mRpduRef)));
			LOG(DEBUG) << "case dialogFail returning";
		}

		case L3CASE_SMS(ACK): {
			timerStop(TR1M);
			// Step 4: Get CP-ACK from the MS.
			const CPAck *cpack = dynamic_cast<typeof(cpack)>(l3msg);
			PROCLOG(INFO) << "CPAck " << cpack;

			gReports.incr("OpenBTS.GSM.SMS.MOSMS.Complete");

			/* MOSMS RLLP request */
			//if (gConfig.getBool("Control.SMS.QueryRRLP")) {
				// Query for RRLP
				//if (!sendRRLP(mobileID, LCH)) {
				//	LOG(INFO) << "RRLP request failed";
				//}
			//}

			// Done.
			mSmsState = MoSmsMMConnection;
			// TODO: if (set) set->mmCallFinished();
			LOG(DEBUG) << "case ACK returning";
			// This attach causes any pending MT transactions to start now.
			gMMLayer.mmAttachByImsi(channel(),tran()->subscriberIMSI());
			return MachineStatus::QuitTran(TermCause::Local(L3Cause::SMS_Success));
		}

		default:
			LOG(DEBUG) << "unexpected state";
			return unexpectedState(state,l3msg);
	}
}
コード例 #8
0
void serialCommunicationCapsule_Actor::rtsBehavior( int signalIndex, int portIndex )
{
	for( int stateIndex = getCurrentState(); ; stateIndex = rtg_parent_state[ stateIndex - 1 ] )
		switch( stateIndex )
		{
		case 1:
			// {{{RME state ':TOP'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					chain1_Initial();
					return;
				default:
					break;
				}
				break;
			default:
				break;
			}
			unexpectedMessage();
			return;
			// }}}RME
		case 2:
			// {{{RME state ':TOP:Ready'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			case 2:
				// {{{RME port 'timer'
				switch( signalIndex )
				{
				case Timing::Base::rti_timeout:
					chain5_timer();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			default:
				break;
			}
			break;
			// }}}RME
		case 3:
			// {{{RME state ':TOP:Error'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			default:
				break;
			}
			break;
			// }}}RME
		case 4:
			// {{{RME state ':TOP:pollData'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			default:
				break;
			}
			break;
			// }}}RME
		case 5:
			// {{{RME state ':TOP:SetBaud'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			default:
				break;
			}
			break;
			// }}}RME
		default:
			unexpectedState();
			return;
		}
}
コード例 #9
0
void ACacaoreservoir_Actor::rtsBehavior( int signalIndex, int portIndex )
{
	for( int stateIndex = getCurrentState(); ; stateIndex = rtg_parent_state[ stateIndex - 1 ] )
		switch( stateIndex )
		{
		case 1:
			// {{{RME state ':TOP'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					chain1_Initial();
					return;
				default:
					break;
				}
				break;
			case 1:
				// {{{RME port 'pReservoir'
				switch( signalIndex )
				{
				case PReservoir::Base::rti_vraagVoorraad:
					chain2_geefVoorraadTerug();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			default:
				break;
			}
			unexpectedMessage();
			return;
			// }}}RME
		case 2:
			// {{{RME state ':TOP:klepDicht'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			case 1:
				// {{{RME port 'pReservoir'
				switch( signalIndex )
				{
				case PReservoir::Base::rti_startLeverProduct:
					chain3_klepOpen();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			default:
				break;
			}
			break;
			// }}}RME
		case 3:
			// {{{RME state ':TOP:klepOpen'
			switch( portIndex )
			{
			case 0:
				switch( signalIndex )
				{
				case 1:
					return;
				default:
					break;
				}
				break;
			case 1:
				// {{{RME port 'pReservoir'
				switch( signalIndex )
				{
				case PReservoir::Base::rti_stopLeverProduct:
					chain4_klepDicht();
					return;
				default:
					break;
				}
				break;
				// }}}RME
			default:
				break;
			}
			break;
			// }}}RME
		default:
			unexpectedState();
			return;
		}
}