pduutils.java

来自「发送短信 接收短信 多种接口com/net/modem 开发库」· Java 代码 · 共 1,073 行 · 第 1/3 页

JAVA
1,073
字号

	// TP-UDHI  x0xxxxxx = no UDH
	//          x1xxxxxx = UDH present
	public static final int TP_UDHI_MASK = 0xBF;

	public static final int TP_UDHI_NO_UDH = 0x00;

	public static final int TP_UDHI_WITH_UDH = 0x40;

	// ==================================================
	// ADDRESS-TYPE CONSTANTS 
	// ==================================================
	// some typical ones used for sending, though receiving may get other types
	// usually 1 001 0001 (0x91) international format 
	//         1 000 0001 (0x81) (unknown) short number (e.g. access codes)
	//         1 101 0000 (0xD0) alphanumeric (e.g. access code names like PasaLoad)
	public static final int ADDRESS_NUMBER_PLAN_ID_MASK = 0x0F;

	public static final int ADDRESS_NUMBER_PLAN_ID_UNKNOWN = 0x00;

	public static final int ADDRESS_NUMBER_PLAN_ID_TELEPHONE = 0x01;

	public static final int ADDRESS_TYPE_MASK = 0x70;

	public static final int ADDRESS_TYPE_UNKNOWN = 0x00;

	public static final int ADDRESS_TYPE_INTERNATIONAL = 0x10;

	public static final int ADDRESS_TYPE_ALPHANUMERIC = 0x50;

	public static int getAddressTypeFor(String address)
	{
		boolean international = false;
		// strip any + to simplify checks
		// but presence of + automatically assumes an
		// international style address
		if (address.startsWith("+"))
		{
			international = true;
			address = address.substring(1);
		}
		for (int i = 0; i < address.length(); i++)
		{
			if (!Character.isDigit(address.charAt(i)))
			{
				// check if alphanumeric
				return createAddressType(ADDRESS_TYPE_ALPHANUMERIC);
			}
		}
		// check if 12 digits or plus is used
		// 12 digits is the max length and anything number 
		// with this length is already international format
		// if the length is less, the presence of the plus
		// will determine international format or not
		if ((address.length() == 12) || (international))
		{
			return createAddressType(ADDRESS_TYPE_INTERNATIONAL | ADDRESS_NUMBER_PLAN_ID_TELEPHONE);
		}
		else
		{
			return createAddressType(ADDRESS_TYPE_UNKNOWN | ADDRESS_NUMBER_PLAN_ID_TELEPHONE);
		}
	}

	public static int extractAddressType(int addressType)
	{
		return addressType & ADDRESS_TYPE_MASK;
	}

	public static int extractNumberPlan(int addressType)
	{
		return addressType & ADDRESS_NUMBER_PLAN_ID_MASK;
	}

	public static int createAddressType(int addressType)
	{
		// last bit is always set
		return 0x80 | addressType;
	}

	// ==================================================
	// DCS ENCODING CONSTANTS 
	// ==================================================
	public static final int DCS_CODING_GROUP_MASK = 0x0F;

	public static final int DCS_CODING_GROUP_DATA = 0xF0;

	public static final int DCS_CODING_GROUP_GENERAL = 0xC0;

	public static final int DCS_ENCODING_MASK = 0xF3;

	public static final int DCS_ENCODING_7BIT = 0x00;

	public static final int DCS_ENCODING_8BIT = 0x04;

	public static final int DCS_ENCODING_UCS2 = 0x08;

	public static final int DCS_MESSAGE_CLASS_MASK = 0xEC;

	public static final int DCS_MESSAGE_CLASS_NONE = 0x00;

	public static final int DCS_MESSAGE_CLASS_FLASH = 0x10;

	public static final int DCS_MESSAGE_CLASS_ME = 0x11;

	public static final int DCS_MESSAGE_CLASS_SIM = 0x12;

	public static final int DCS_MESSAGE_CLASS_TE = 0x13;

	public static int extractDcsEncoding(int dataCodingScheme)
	{
		return dataCodingScheme & ~PduUtils.DCS_ENCODING_MASK;
	}

	public static int extractDcsClass(int dataCodingScheme)
	{
		return dataCodingScheme & ~DCS_MESSAGE_CLASS_MASK;
	}

	public static int extractDcsFlash(int dataCodingScheme)
	{
		// this is only useful if DCS != 0
		return dataCodingScheme & ~DCS_MESSAGE_CLASS_MASK;
	}

	public static int extractDcsCodingGroup(int dataCodingScheme)
	{
		return dataCodingScheme & ~DCS_CODING_GROUP_MASK;
	}

	// ==================================================
	// ENCODING/DECODING utility methods 
	// ==================================================
	private static Integer getTpField(Pdu pdu, String fieldName)
	{
		try
		{
			Method m = pdu.getClass().getMethod("get" + fieldName);
			return (Integer) m.invoke(pdu);
		}
		catch (Exception e)
		{
		}
		return null;
	}

	private static Boolean hasTpField(Pdu pdu, String fieldName)
	{
		try
		{
			Method m = pdu.getClass().getMethod("has" + fieldName);
			return (Boolean) m.invoke(pdu);
		}
		catch (Exception e)
		{
		}
		return null;
	}

	public static String decodeFirstOctet(Pdu pdu)
	{
		// Use reflection to check for method signatures hasTpXXX() and getTpXXX()
		// that are specific to a particular type in actual object 
		StringBuffer sb = new StringBuffer();
		sb.append("First Octet: " + PduUtils.byteToPdu(pdu.getFirstOctet()));
		sb.append(" [");
		// TP-MTI
		switch (pdu.getTpMti())
		{
			case PduUtils.TP_MTI_SMS_DELIVER:
				sb.append("TP-MTI: (SMS-DELIVER)");
				break;
			case PduUtils.TP_MTI_SMS_STATUS_REPORT:
				sb.append("TP-MTI: (SMS-STATUS REPORT)");
				break;
			case PduUtils.TP_MTI_SMS_SUBMIT:
				sb.append("TP-MTI: (SMS-SUBMIT)");
				break;
			default:
				throw new RuntimeException("Invalid message type");
		}
		// TP-MMS
		if (hasTpField(pdu, "TpMms") != null)
		{
			if (hasTpField(pdu, "TpMms"))
			{
				sb.append(", TP-MMS: (Has more messages)");
			}
			else
			{
				sb.append(", TP-MMS: (has no messages)");
			}
		}
		//TP-RD
		if (hasTpField(pdu, "TpRd") != null)
		{
			if (hasTpField(pdu, "TpRd"))
			{
				sb.append(", TP-RD: (Reject duplicates)");
			}
			else
			{
				sb.append(", TP-RD: (allow duplicates)");
			}
		}
		//TP-VPF
		if ((hasTpField(pdu, "TpVpf") != null) && (hasTpField(pdu, "TpVpf") != false))
		{
			switch (getTpField(pdu, "TpVpf"))
			{
				case PduUtils.TP_VPF_INTEGER:
					sb.append(", TP-VPF: (validity format, integer");
					break;
				case PduUtils.TP_VPF_TIMESTAMP:
					sb.append(", TP-VPF: (validity format, timestamp");
					break;
				case PduUtils.TP_VPF_NONE:
					sb.append(", TP-VPF: (validity format, none)");
					break;
			}
		}
		// TP-SRI
		if (hasTpField(pdu, "TpSri") != null)
		{
			if (hasTpField(pdu, "TpSri"))
			{
				sb.append(", TP-SRI: (Requests Status Report)");
			}
			else
			{
				sb.append(", TP-SRI: (No Status Report)");
			}
		}
		// TP-SRR
		if (hasTpField(pdu, "TpSrr") != null)
		{
			if (hasTpField(pdu, "TpSrr"))
			{
				sb.append(", TP-SRR: (Requests Status Report)");
			}
			else
			{
				sb.append(", TP-SRR: (No Status Report)");
			}
		}
		//TP-UDHI
		if (pdu.hasTpUdhi())
		{
			sb.append(", TP-UDHI: (has UDH)");
		}
		else
		{
			sb.append(", TP-UDHI: (no UDH)");
		}
		sb.append("]");
		sb.append("\n");
		return sb.toString();
	}

	public static String decodeDataCodingScheme(Pdu pdu)
	{
		StringBuffer sb = new StringBuffer();
		switch (PduUtils.extractDcsEncoding(pdu.getDataCodingScheme()))
		{
			case PduUtils.DCS_ENCODING_7BIT:
				sb.append("7-bit GSM Alphabet");
				break;
			case PduUtils.DCS_ENCODING_8BIT:
				sb.append("8-bit encoding");
				break;
			case PduUtils.DCS_ENCODING_UCS2:
				sb.append("UCS2 encoding");
				break;
		}
		// are flash messages are only applicable to general coding group?
		if ((pdu.getDataCodingScheme() & ~PduUtils.DCS_CODING_GROUP_GENERAL) == 0)
		{
			switch (PduUtils.extractDcsClass(pdu.getDataCodingScheme()))
			{
				case PduUtils.DCS_MESSAGE_CLASS_FLASH:
					sb.append(", (Flash Message)");
					break;
				case PduUtils.DCS_MESSAGE_CLASS_ME:
					sb.append(", (Class1 ME Message)");
					break;
				case PduUtils.DCS_MESSAGE_CLASS_SIM:
					sb.append(", (Class2 SIM Message)");
					break;
				case PduUtils.DCS_MESSAGE_CLASS_TE:
					sb.append(", (Class3 TE Message)");
					break;
			}
		}
		return sb.toString();
	}

	public static byte[] encode8bitUserData(String text)
	{
		try
		{
			return text.getBytes("ISO8859_1");
		}
		catch (Exception e)
		{
			throw new RuntimeException(e);
		}
	}

	public static byte[] encodeUcs2UserData(String text)
	{
		try
		{
			// UTF-16 Big-Endian, no Byte Order Marker at start
			return text.getBytes("UTF-16BE");
		}
		catch (Exception e)
		{
			throw new RuntimeException(e);
		}
	}

	public static byte[] encode7bitUserData(byte[] udhOctets, byte[] textSeptets)
	{
		// UDH octets and text have to be encoded together in a single pass
		// UDH octets will need to be converted to unencoded septets in order
		// to properly pad the data
		if (udhOctets == null)
		{
			// convert string to uncompressed septets
			return unencodedSeptetsToEncodedSeptets(textSeptets);
		}
		else
		{
			// convert UDH octets as if they were encoded septets
			// NOTE: DO NOT DISCARD THE LAST SEPTET IF IT IS ZERO
			byte[] udhSeptets = PduUtils.encodedSeptetsToUnencodedSeptets(udhOctets, false);
			// combine the two arrays and encode them as a whole
			byte[] combined = new byte[udhSeptets.length + textSeptets.length];
			System.arraycopy(udhSeptets, 0, combined, 0, udhSeptets.length);
			System.arraycopy(textSeptets, 0, combined, udhSeptets.length, textSeptets.length);
			// convert encoded byte[] to a PDU string
			return unencodedSeptetsToEncodedSeptets(combined);
		}
	}

	public static String decode7bitEncoding(byte[] encodedPduData)
	{
		return decode7bitEncoding(null, encodedPduData);
	}

	public static String decode7bitEncoding(byte[] udhData, byte[] encodedPduData)
	{
		int udhLength = ((udhData == null) ? 0 : udhData.length);
		if (udhLength == 0)
		{
			// just process the whole pdu as one thing
			return unencodedSeptetsToString(encodedSeptetsToUnencodedSeptets(encodedPduData));
		}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?