/** * 构造Mx消息(sms-deliver). * * @param dpc * @param opc * @param cd - sccp called * @param cg - sccp calling * @param smsc - SMSC * @param sender - calling * @param receiver - called * @param content - short message content * @return MSU码流 */ public byte[] encodecMxFsm( boolean mt, int dpc, int opc, String cd, String cg, String smsc, String receiver, String sender, String content) { byte[] msu = new byte[276]; int pos = 0; // fill SIO msu[pos++] = (byte) 0x83; // fill DPC and OPC msu[pos++] = (byte) (dpc & 0xFF); msu[pos++] = (byte) ((dpc >> 8) & 0xFF); msu[pos++] = (byte) ((dpc >> 16) & 0xFF); msu[pos++] = (byte) (opc & 0xFF); msu[pos++] = (byte) ((opc >> 8) & 0xFF); msu[pos++] = (byte) ((opc >> 16) & 0xFF); // fill SLS,MSGID,PROTOCAL_CLASS msu[pos++] = (byte) 0x00; // 0-15 msu[pos++] = (byte) 0x09; msu[pos++] = (byte) 0x80; // 80,81,01 // fill 3 pointers msu[pos++] = (byte) 0x03; int zq_pos1_cg = pos; // keep the positon of cg pointer msu[pos++] = (byte) 0x0e; // cg len: temp value 0d,0e,0f msu[pos++] = (byte) 0x19; // content len: temp value 19,17 // fill sccp cd and sg byte[] zq_sms_sccpCd = cd.getBytes(); byte[] zq_rnm_sccpCg = cg.getBytes(); byte[] zq_send = sender.getBytes(); int zq_tid = 0x8080; byte[] ZQ_DIALOG_MT_LIST_V2 = { 0x6b, 0x1E, // FALG,LEN1 0x28, 0x1C, // FALG,LEN=LEN1-2 0x06, 0x07, // FALG,LEN 0x00, 0x11, (byte) 0x86, 0x05, 0x01, 0x01, 0x01, (byte) 0xA0, 0x11, // FALG,LEN 0x60, 0x0F, // FALG,LEN (byte) 0x80, 0x02, 0X07, (byte) 0X80, (byte) 0xA1, 0x09, // FALG,LEN 0x06, 0x07, // FALG,LEN 0x04, 0x00, 0x00, 0x01, 0x00, 0x19, 0x03 // 0.4.0.0.1.0.25.x : x=[2,3]在wireshark中的info显示: invoke forwardSM(2)/mt-forwardSM(3) }; // sccp cd(msc address) boolean zq_even = (cd.length() % 2) == 0; byte[] cdBcd = ISOUtil.str2bigbcd(cd + (zq_even ? "" : "F"), false); int cdBcdLen = (cdBcd.length * 2) - (zq_even ? 0 : 1); msu[pos++] = (byte) (5 + cdBcd.length); // Fill length msu[pos++] = (byte) 0x12; // routing on GT 12,52 msu[pos++] = (byte) 0x08; // MSC msu[pos++] = (byte) 0x00; // 00 if (zq_even) { msu[pos++] = (byte) 0x12; // E164,EVEN digit } else { msu[pos++] = (byte) 0x11; // E164,ODD digit } msu[pos++] = (byte) 0x04; // International number System.arraycopy(cdBcd, 0, msu, pos, cdBcd.length); // Fill digits pos = pos + cdBcd.length; int zq_pos2_cg = pos; // keep the offset of cg part // put cg to MSU zq_even = (cg.length() % 2) == 0; byte[] cgBcd = ISOUtil.str2bigbcd(cg + (zq_even ? "" : "F"), false); int cgBcdLen = (cgBcd.length * 2) - (zq_even ? 0 : 1); msu[pos++] = (byte) (5 + cgBcd.length); // Fill length msu[pos++] = (byte) 0x12; // routing on GT 12,52 msu[pos++] = (byte) 0x08; // SMSC msu[pos++] = (byte) 0x00; // 00 if (zq_even) { msu[pos++] = (byte) 0x12; // E164,EVEN digit } else { msu[pos++] = (byte) 0x11; // E164,ODD digit } msu[pos++] = (byte) 0x04; // International number System.arraycopy(cgBcd, 0, msu, pos, cgBcd.length); // Fill digits pos = pos + cgBcd.length; int zq_pos3_content = pos; // keep the offset of content part // Adjust cg pointer and content ptr msu[zq_pos1_cg] = (byte) (zq_pos2_cg - zq_pos1_cg); // cg len msu[zq_pos1_cg + 1] = (byte) (zq_pos3_content - zq_pos1_cg - 1); // content len // convert smsc zq_even = (smsc.length() % 2) == 0; byte[] smscBcd = ISOUtil.str2bigbcd(smsc + (zq_even ? "" : "F"), false); int smscBcdLen = (smscBcd.length * 2) - (zq_even ? 0 : 1); // convert receiver zq_even = (receiver.length() % 2) == 0; byte[] receiverBcd = ISOUtil.str2bigbcd(receiver + (zq_even ? "" : "F"), false); int receiverBcdLen = (receiverBcd.length * 2) - (zq_even ? 0 : 1); // convert sender zq_even = (sender.length() % 2) == 0; byte[] senderBcd = ISOUtil.str2bigbcd(sender + (zq_even ? "" : "F"), false); int senderBcdLen = (senderBcd.length * 2) - (zq_even ? 0 : 1); // fill sccp part // fill sccp's length int zq_pos_sccp = pos; // keep sccp length position // short message content boolean isChinese = ISOUtil.isChinese(content); byte[] _content = isChinese ? PduUtils.encodeUcs2UserData(content) : PduUtils.unencodedSeptetsToEncodedSeptets(PduUtils.stringToUnencodedSeptets(content)); byte[] ZQ_UI = new byte[10 + _content.length]; ZQ_UI[0] = 0x00; ZQ_UI[1] = (byte) (isChinese ? 0x08 : 0x00); // 0x00-7bit, 0x04-8bit, 0x08-UCS2(16bit) ZQ_UI[2] = 0x21; // YY-12 ZQ_UI[3] = (byte) 0x80; // MM-08 ZQ_UI[4] = 0x61; // DD-16 ZQ_UI[5] = 0x41; // HH-14 ZQ_UI[6] = 0x10; // MM-01 ZQ_UI[7] = 0x30; // SS-30 ZQ_UI[8] = 0x23; // ZONE GTM+8 ZQ_UI[9] = (byte) (isChinese ? _content.length : content.length()); // SMS's len: isChinese?字节数:字符数 System.arraycopy(_content, 0, ZQ_UI, 10, _content.length); // short format msu[pos++] = (byte) (8 + ZQ_DIALOG_MT_LIST_V2.length + 12 + 2 + receiverBcd.length + 2 + 3 + smscBcd.length + 3 + senderBcd.length + ZQ_UI.length); msu[pos++] = (byte) 0x62; // short format msu[pos++] = (byte) (6 + ZQ_DIALOG_MT_LIST_V2.length + 12 + 2 + receiverBcd.length + 2 + 3 + smscBcd.length + 3 + senderBcd.length + ZQ_UI.length); msu[pos++] = (byte) 0x48; msu[pos++] = (byte) 0x04; // OTID related to last msu[pos++] = (byte) ((zq_tid >> 24) & 0xFF); msu[pos++] = (byte) ((zq_tid >> 16) & 0xFF); msu[pos++] = (byte) ((zq_tid >> 8) & 0xFF); msu[pos++] = (byte) ((zq_tid) & 0xFF); // copy DIALOG part System.arraycopy(ZQ_DIALOG_MT_LIST_V2, 0, msu, pos, ZQ_DIALOG_MT_LIST_V2.length); pos = pos + ZQ_DIALOG_MT_LIST_V2.length; // copy COMPONENT part msu[pos++] = (byte) 0x6c; // not used temperily msu[pos++] = (byte) (2 + 8 + 2 + receiverBcd.length + 3 + smscBcd.length + 2 + 3 + senderBcd.length + ZQ_UI.length); msu[pos++] = (byte) 0xa1; // not used temperily msu[pos++] = (byte) (8 + 2 + receiverBcd.length + 3 + smscBcd.length + 2 + 3 + senderBcd.length + ZQ_UI.length); // fill invoke id msu[pos++] = (byte) 0x02; msu[pos++] = (byte) 0x01; msu[pos++] = (byte) 0x01; // fill op code msu[pos++] = (byte) 0x02; msu[pos++] = (byte) 0x01; msu[pos++] = mt ? (byte) 0x2c : (byte) 0x2e; // P44_MT(0x2c),P46_MO(0x2e) // fill sequence msu[pos++] = (byte) 0x30; // not used temperily msu[pos++] = (byte) (2 + receiverBcd.length + 3 + smscBcd.length + 2 + 3 + senderBcd.length + ZQ_UI.length); // fill RPDA:Xmsi msu[pos++] = (byte) 0x80; // 80-IMSI,81-LMSI msu[pos++] = (byte) receiverBcd.length; // (cdBcd.length +1); // msu[pos++] = (byte) 0x91; System.arraycopy(receiverBcd, 0, msu, pos, receiverBcd.length); pos = pos + receiverBcd.length; // fill RPOA:smsc msu[pos++] = (byte) 0x84; // msu[pos++] = (byte) (smscBcd.length + 1); msu[pos++] = (byte) 0x91; System.arraycopy(smscBcd, 0, msu, pos, smscBcd.length); pos = pos + smscBcd.length; // fill RP_DATA msu[pos++] = (byte) 0x04; // TP_OA:sender msu[pos++] = (byte) (3 + senderBcd.length + ZQ_UI.length); msu[pos++] = (byte) 0x24; msu[pos++] = (byte) (senderBcdLen); msu[pos++] = (byte) 0xa1; System.arraycopy(senderBcd, 0, msu, pos, senderBcd.length); pos = pos + senderBcd.length; // msu[pos++] = (byte) (ZQ_UI.length); // fill UI System.arraycopy(ZQ_UI, 0, msu, pos, ZQ_UI.length); pos = pos + ZQ_UI.length; // return real msu byte[] _msu = new byte[pos]; System.arraycopy(msu, 0, _msu, 0, _msu.length); return _msu; }
@Override public String getPduUserData() { return PduUtils.bytesToPdu(getDataBytes()); }