Esempio n. 1
0
void TLUserData::write(TLFrame& dest, size_t& wp) const
{
#if 1
	// First write TP-User-Data-Length
	dest.writeField(wp,mLength,8);

	// Then write TP-User-Data
	// This tail() works because UD is always the last field in the PDU.
	BitVector ud_dest = dest.tail(wp);
	mRawData.copyTo(ud_dest);
	ud_dest.LSB8MSB();
#else
	// Stuff we don't support...
	assert(!mUDHI);
	assert(mDCS==0);
	unsigned numChar = strlen(mData);
	dest.writeField(wp,numChar,8);
	// This tail() works because UD is always the last field in the PDU.
	BitVector chars = dest.tail(wp);
	chars.zero();
	for (unsigned i=0; i<numChar; i++) {
		char gsm = encodeGSMChar(mData[i]);
		dest.writeFieldReversed(wp,gsm,7);
	}
	chars.LSB8MSB();
#endif
}
Esempio n. 2
0
void TLAddress::write(TLFrame& dest, size_t& wp) const
{
	dest.writeField(wp,mDigits.size(),8);
	dest.writeField(wp, 0x01, 1);
	dest.writeField(wp, mType, 3);
	dest.writeField(wp, mPlan, 4);
	mDigits.write(dest,wp);
}
Esempio n. 3
0
void TLDeliver::writeBody(TLFrame& dest, size_t& wp) const
{
	writeMMS(dest);
	writeRP(dest);
	writeUDHI(dest, mUD.UDHI());
	writeSRI(dest);
	mOA.write(dest,wp);
	dest.writeField(wp,mPID,8);
	dest.writeField(wp,mUD.DCS(),8);
	mSCTS.write(dest,wp);
	writeUnused(dest);
	mUD.write(dest,wp);
}
Esempio n. 4
0
// (pat) See 3GPP 3.40 9.2.2
void TLDeliver::writeBody(TLFrame& dest, size_t& wp) const
{
	writeMMS(dest);		// more messages to send bit.
	writeRP(dest);		// reply path bit.
	writeUDHI(dest, mUD.UDHI());	// User-data-header-indicator bit
	writeSRI(dest);		// status-report-indication bit
	mOA.write(dest,wp);	// originating address
	dest.writeField(wp,mPID,8);		// protocol id
	dest.writeField(wp,mUD.DCS(),8);	// Data-coding-scheme
	mSCTS.write(dest,wp);		// service-centre-time-stamp
	writeUnused(dest);			// user-data-length.  (pat) Why empty?
	mUD.write(dest,wp);			// user data.
}
Esempio n. 5
0
/** Parse a TL address field, including length. */
void TLAddress::parse(const TLFrame& src, size_t& rp)
{
	// GSM 03.40.
	// This is different from the BCD formats in GSM 04.08,
	// even though it looks very similar.
	// The difference is in the encoding of the length field.

	size_t numDigits = src.readField(rp,8);
	size_t length = numDigits/2 + (numDigits % 2);
	if (src.readField(rp, 1) != 1) SMS_READ_ERROR;	
	mType = (TypeOfNumber)src.readField(rp, 3);
	mPlan = (NumberingPlan)src.readField(rp, 4);
	mDigits.parse(src,rp,length);
}
Esempio n. 6
0
void TLUserData::parse(const TLFrame& src, size_t& rp)
{
	// The DCS is defined in GSM 03.38 4.
	assert(mDCS<0x100);	// Someone forgot to initialize the DCS.
	// TP-User-Data-Length
	mLength = src.readField(rp,8);
#if 1
	// This tail() works because UD is always the last field in the PDU.
	mRawData.clone(src.tail(rp));
	// Should we do this here?
	mRawData.LSB8MSB();
#else
	assert(!mUDHI);		// We don't support user headers.
	switch (mDCS) {
		case 0:
		case 244:
		case 245:
		case 246:
		case 247:
		{
			// GSM 7-bit encoding, GSM 03.38 6.
			// Check bounds.
			if (numChar*7 > (src.size()-rp)) {
				LOG(NOTICE) << "badly formatted TL-UD";
				SMS_READ_ERROR;
			}
			BitVector chars(src.tail(rp));
			chars.LSB8MSB();
			size_t crp=0;
			for (unsigned i=0; i<numChar; i++) {
				char gsm = chars.readFieldReversed(crp,7);
				mData[i] = decodeGSMChar(gsm);
			}
			mData[numChar]='\0';
			if (crp%8) crp += 8 - crp%8;
			rp += crp;
			return;
		}
		default:
		{
			rp += numChar;
			sprintf(mData,"unsupported DCS 0x%x", mDCS);
			LOG(NOTICE) << mData;
			SMS_READ_ERROR;
		}
	}
#endif
}
Esempio n. 7
0
void TLMessage::write(TLFrame& dest) const
{
	dest.resize(bitsNeeded());
	size_t wp=8;
	writeMTI(dest);
	writeBody(dest,wp);
}
void TLSubmit::parseBody(const TLFrame& src, size_t& rp)
{
	parseRD(src);
	parseVPF(src);
	parseRP(src);
	parseUDHI(src);
	parseSRR(src);
	mMR = src.readField(rp,8);
	mDA.parse(src,rp);
	mPI = src.readField(rp,8);
	mDCS = src.readField(rp,8);
	mVP.VPF(mVPF);
	mVP.parse(src,rp);
	mUD.DCS(mDCS);
	mUD.parse(src,rp);
}
void TLUserData::write(TLFrame& dest, size_t& wp) const
{
	// Stuff we don't support...
	assert(!mUDHI);
	assert(mDCS==0);
	unsigned numChar = strlen(mData);
	dest.writeField(wp,numChar,8);
	// This tail() works because UD is always the last field in the PDU.
	BitVector chars = dest.tail(wp);
	chars.zero();
	for (unsigned i=0; i<numChar; i++) {
		char gsm = encodeGSMChar(mData[i]);
		dest.writeFieldReversed(wp,gsm,7);
	}
	chars.LSB8MSB();
}
Esempio n. 10
0
void TLDeliver::parseBody(const TLFrame &src, size_t &rp)
{
	// Note that offset is reversed, i'=7-i.
	// Ignore MTI, we already know it is DELIVER.
	// Note that these header fields come from src ignoring rp.
	parseMMS(src);
	parseRP(src);
	parseUDHI(src);
	parseSRI(src);
	// Now the 'body'
	assert(rp == 8);
	mOA.parse(src,rp);			// originating address.
	mPID = src.readField(rp,8);	// protocol id
	mUD.DCS(src.readField(rp,8));	// data coding scheme, stored in the TLUserData.
	mSCTS.parse(src,rp);		// time stamp
	mUD.parse(src,rp);			// user data.
}
Esempio n. 11
0
void TLSubmit::parseBody(const TLFrame& src, size_t& rp)
{
	bool udhi;

	parseRD(src);
	parseVPF(src);
	parseRP(src);
	udhi = parseUDHI(src);
	parseSRR(src);
	mMR = src.readField(rp,8);
	mDA.parse(src,rp);
	//LOG(DEBUG) << "Destination " << mDA.digits();
	mPI = src.readField(rp,8);
	mDCS = src.readField(rp,8);
	mVP.VPF(mVPF);
	mVP.parse(src,rp);
	mUD.DCS(mDCS);
	mUD.UDHI(udhi);
	mUD.parse(src,rp);
}
void TLUserData::parse(const TLFrame& src, size_t& rp)
{
	assert(!mUDHI);		// We don't support user headers.
	// The DCS is defined in GSM 03.38 4.
	assert(mDCS<0x100);	// Someone forgot to initialize the DCS.
	unsigned numChar = src.readField(rp,8);
	switch (mDCS) {
		case 0:
		case 244:
		case 245:
		case 246:
		case 247:
		{
			// GSM 7-bit encoding, GSM 03.38 6.
			// Check bounds.
			if (numChar*7 > (src.size()-rp)) {
				LOG(NOTICE) << "badly formatted TL-UD";
				SMS_READ_ERROR;
			}
			BitVector chars(src.tail(rp));
			chars.LSB8MSB();
			size_t crp=0;
			for (unsigned i=0; i<numChar; i++) {
				char gsm = chars.readFieldReversed(crp,7);
				mData[i] = decodeGSMChar(gsm);
			}
			mData[numChar]='\0';
			if (crp%8) crp += 8 - crp%8;
			rp += crp;
			return;
		}
		default:
		{
			rp += numChar;
			sprintf(mData,"unsupported DCS 0x%x", mDCS);
			LOG(NOTICE) << mData;
			SMS_READ_ERROR;
		}
	}
}
Esempio n. 13
0
void TLValidityPeriod::write(TLFrame& dest, size_t& wp) const
{
	if (mVPF==0) return;
	// We only support VPF==1.
	assert(mVPF==1);
	int seconds = mExpiration.seconds() - time(NULL);
	int minutes = seconds/60;
	if (minutes<1) minutes=1;
	unsigned vp;
	if (minutes<=720) vp = (minutes-1)/5;
	else if (minutes<1440) vp = 143 + (minutes-720)/30;
	else if (minutes<43200) vp = 166 + minutes/(24*60);
	else vp = 192 + minutes/(7*24*60);
	if (vp>255) vp=255;
	dest.writeField(wp,vp,8);
}
Esempio n. 14
0
void TLValidityPeriod::parse(const TLFrame& src, size_t& rp)
{
	// FIXME -- Check remaining message length before reading!!
	LOG(DEBUG) << "SMS: TLValidityPeriod::parse VPF=" << mVPF;
	switch (mVPF) {
		case 2: {
			// Relative format.
			// GSM 03.40 9.2.3.12.1
			unsigned vp = src.readField(rp,8);
			unsigned minutes = 0;
			if (vp<144) minutes = (vp+1)*5;
			else if (vp<168) minutes = 12*60 + (vp-143)*30;
			else if (vp<197) minutes = 24*60*(vp-166);
			else minutes = 7*24*60*(vp-192);
			mExpiration = Timeval();
			mExpiration.addMinutes(minutes);
			return;
		}
		case 3: {
			// Absolute format, borrowed from GSM 04.08 MM
			// GSM 03.40 9.2.3.12.2
			L3TimeZoneAndTime decoder;
			decoder.parseV((TLFrame)(BitVector)src,rp);
			mExpiration = decoder.time();
			return;
		}
		case 1:
			// Enhanced format.
			// GSM 03.40 9.2.3.12.3
			LOG(NOTICE) << "SMS: ignoring grossly complex \"enhanced\" TP-VP and assuming 1 week.";
			rp += 7;
			// fall through...
		case 0:
			// No validity period field.
			LOG(DEBUG) << "SMS: no validity period, assuming 1 week";
			mExpiration = Timeval(7*24*60*60*1000);
			return;
		default: assert(0);		// someone forgot to initialize the VPF
	}
}