Example #1
0
  /**
   * 构造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());
 }