/**
	Process the RPDU.
	@param mobileID The sender's IMSI.
	@param RPDU The RPDU to process.
	@return true if successful.
*/
bool handleRPDU(TransactionEntry *transaction, const RLFrame& RPDU)
{
	LOG(DEBUG) << "SMS: handleRPDU MTI=" << RPDU.MTI();
	switch ((RPMessage::MessageType)RPDU.MTI()) {
		case RPMessage::Data: {
			string contentType = gConfig.getStr("SMS.MIMEType");
			ostringstream body;

			if (contentType == "text/plain") {
				// TODO: Clean this mess up!
				RPData data;
				data.parse(RPDU);
				TLSubmit submit;
				submit.parse(data.TPDU());
				
				body << submit.UD().decode();
			} else if (contentType == "application/vnd.3gpp.sms") {
				RPDU.hex(body);
			} else {
				LOG(ALERT) << "\"" << contentType << "\" is not a valid SMS payload type";
			}
			const char* address = NULL;
			if (gConfig.defines("SIP.SMSC")) address = gConfig.getStr("SIP.SMSC").c_str();

			/* The SMSC is not defined, we are using an older version */
			if (address == NULL) {
				RPData data;
				data.parse(RPDU);
				TLSubmit submit;
				submit.parse(data.TPDU());

				address = submit.DA().digits();
			}
			return sendSIP(transaction, address, body.str().data(),contentType.c_str());
		}
		case RPMessage::Ack:
		case RPMessage::SMMA:
			return true;
		case RPMessage::Error:
		default:
			return false;
	}
}
Example #2
0
// Return true on success.
bool MTSMSMachine::createRPData(RPData &rp_data)
{
	// TODO: Read MIME Type from smqueue!!
	const char *contentType = tran()->mContentType.c_str();
	PROCLOG(DEBUG)<<LOGVAR(contentType)<<LOGVAR(tran()->mMessage);
	if (strncmp(contentType,"text/plain",10)==0) {
		TLAddress tlcalling = TLAddress(tran()->calling().digits());
		TLUserData tlmessage = TLUserData(tran()->mMessage.c_str());
		PROCLOG(DEBUG)<<LOGVAR(tlcalling)<<LOGVAR(tlmessage);
		rp_data = RPData(this->mRpduRef,
			RPAddress(gConfig.getStr("SMS.FakeSrcSMSC").c_str()),
			TLDeliver(tlcalling,tlmessage,0));
	} else if (strncmp(contentType,"application/vnd.3gpp.sms",24)==0) {
		BitVector2 RPDUbits(strlen(tran()->mMessage.c_str())*4);
		if (!RPDUbits.unhex(tran()->mMessage.c_str())) {
			LOG(WARNING) << "Message is zero length which is valid";
			// This is valid continue
			return true;
		}

		try { // I suspect this is here to catch the above FIXED crash when string is zero length
			RLFrame RPDU(RPDUbits);
			LOG(DEBUG) << "SMS RPDU: " << RPDU;

			rp_data.parse(RPDU);
			LOG(DEBUG) << "SMS RP-DATA " << rp_data;
		}
		catch (SMSReadError) {
			LOG(WARNING) << "SMS parsing failed (above L3)";
			// Cause 95, "semantically incorrect message".
			//LCH->l2sendf(CPData(L3TI,RPError(95,this->mRpduRef)),3); if you ever use this, it should call l3sendSms
			return false;
		}
		catch (GSM::L3ReadError) {
			LOG(WARNING) << "SMS parsing failed (in L3)";
			// TODO:: send error back to the phone
			return false;
		}
		catch (...) {
			LOG(ERR) << "Unexpected throw";	// cryptic, but should never happen.
			return false;
		}
	} else {
		LOG(WARNING) << "Unsupported content type (in incoming SIP MESSAGE) -- type: " << contentType;
		return false;
	}
	return true;
}
Example #3
0
/**
	Process the incomming RPDU.
	@param mobileID The sender's IMSI.
	@param RPDU The RPDU to process.
	@return true if successful.
*/
bool MOSMSMachine::handleRPDU(const RLFrame& RPDU)
{
	LOG(DEBUG) << "SMS: handleRPDU MTI=" << RPDU.MTI();
	switch ((RPMessage::MessageType)RPDU.MTI()) {
		case RPMessage::Data: {
			string contentType = gConfig.getStr("SMS.MIMEType");
			ostringstream body;
			string toAddress = "";

			if (contentType == "text/plain") {
				RPData data;
				data.parse(RPDU);
				TLSubmit submit;
				submit.parse(data.TPDU());
				
				body << submit.UD().decode();	// (pat) TODO: efficiencize this.
				toAddress = string(submit.DA().digits());
			} else if (contentType == "application/vnd.3gpp.sms") {
				toAddress = "smsc";  // If encoded this is expected in destination address
				RPDU.hex(body);
			} else {
				LOG(ERR) << "\"" << contentType << "\" is not a valid SMS payload type";
			}
			// Steps:
			// 1 -- Complete transaction record.
			// 2 -- Send TL-SUBMIT to the server.
			// 3 -- Wait for response or timeout.
			// 4 -- Return true for OK or ACCEPTED, false otherwise.

			// Step 1 and 2 -- Complete the transaction record and send TL-SUMBIT to server.
			// Form the TLAddress into a CalledPartyNumber for the transaction.
			// Attach calledParty and message body to the transaction.
			SipDialog::newSipDialogMOSMS(tran()->tranID(), tran()->subscriber(), toAddress, body.str(), contentType);
			return true;
		}
		case RPMessage::Ack:
		case RPMessage::SMMA:
			return true;
		case RPMessage::Error:
		default:
			return false;
	}
}