问题描述
所以我有一个restcomm/jss7的分叉版本,其中我实现了为MAP v1定义的SendParameters SS7命令,因为我分叉的版本当时没有实现(不要认为它已实现)仍然)。这不是我在JSS7中实现的第一个命令。问题是,我非常确定自己的编码/解码遵循09.02规范,但是当我构造一个给定TMSI而不是IMAGESIDS的invokeSendParameters消息(在SubscriberId部分中)时,它在Wirehark中显示为msisdn且未正确解析。这是Wireshark的问题还是我的实现有错?我的SendParametersRequestImpl和SubscriberIdImpl供参考:
public class SendParameterRequestImp extends mobilityMessageImpl implements SendParametersRequest {
private static final int _TAG_SUBSCRIBER_ID = 0;
private static final int _TAG_REQUESTED_ParaMETER = 1;
private SubscriberId subscriberId;
private static final String _PrimitiveName = "SendParameterRequestImp";
private ArrayList<RequestParameter> requestParameterList;
public SendParameterRequestImp(SubscriberId subscriberId,ArrayList<RequestParameter> requestParameters) {
this.subscriberId = subscriberId;
this.requestParameterList = requestParameters;
}
public SendParameterRequestImp() {
}
@Override
public ArrayList<RequestParameter> getRequestParameterList() {
return requestParameterList;
}
@Override
public SubscriberId getSubscriberId() {
return subscriberId;
}
public void setSubscriberId(SubscriberId subscriberId) {
this.subscriberId = subscriberId;
}
@Override
public MAPMessageType getMessageType() {
return MAPMessageType.sendParameter_Request;
}
@Override
public int getoperationCode() {
return MAPOperationCode.sendParameters;
}
@Override
public int getTag() throws MAPException {
return Tag.SEQUENCE;
}
@Override
public int getTagClass() {
return Tag.CLASS_UNIVERSAL;
}
@Override
public boolean getIsPrimitive() {
return false;
}
@Override
public void decodeAll(AsnInputStream ansIS) throws MAPParsingComponentException {
try {
int length = ansIS.readLength();
this._decode(ansIS,length);
} catch (IOException e) {
throw new MAPParsingComponentException("IOException when decoding " + _PrimitiveName + ": " + e.getMessage(),e,MAPParsingComponentExceptionReason.MistypedParameter);
} catch (AsnException e) {
throw new MAPParsingComponentException("AsnException when decoding " + _PrimitiveName + ": " + e.getMessage(),MAPParsingComponentExceptionReason.MistypedParameter);
}
}
private void _decode(AsnInputStream ansIS,int length) throws IOException,AsnException,MAPParsingComponentException {
AsnInputStream ais = ansIS.readSequenceStreamData(length);
while (true) {
if (ais.available() == 0)
break;
int tag = ais.readTag();
switch (ais.getTagClass()) {
case Tag.CLASS_CONTEXT_SPECIFIC:
this.subscriberId = new SubscriberIdImpl();
((SubscriberIdImpl) this.subscriberId).decodeAll(ais);
break;
case Tag.CLASS_UNIVERSAL:
switch (tag) {
case Tag.SEQUENCE:
this.requestParameterList = new ArrayList<RequestParameter>();
AsnInputStream ais3 = ais.readSequenceStream();
while (true) {
if (ais3.available() == 0)
break;
int tag2 = ais3.readTag();
if (tag2 != Tag.ENUMERATED)
throw new MAPParsingComponentException("Error while decoding " + _PrimitiveName
+ ": bad tag or tagClass or is not primitive when decoding plmnClientList",MAPParsingComponentExceptionReason.MistypedParameter);
int code = (int) ais3.readInteger();
RequestParameter elem = RequestParameter.getInstance(code);
this.requestParameterList.add(elem);
}
break;
default:
ais.advanceElement();
break;
}
break;
default:
ais.advanceElement();
break;
}
}
}
@Override
public void decodeData(AsnInputStream ansIS,int length) throws MAPParsingComponentException {
try {
this._decode(ansIS,MAPParsingComponentExceptionReason.MistypedParameter);
}
}
@Override
public void encodeAll(AsnOutputStream asnOs) throws MAPException {
this.encodeAll(asnOs,this.getTagClass(),this.getTag());
}
@Override
public void encodeAll(AsnOutputStream asnOs,int tagClass,int tag) throws MAPException {
try {
asnOs.writeTag(tagClass,this.getIsPrimitive(),tag);
int pos = asnOs.StartContentDefiniteLength();
this.encodeData(asnOs);
asnOs.FinalizeContent(pos);
} catch (AsnException e) {
throw new MAPException("AsnException when encoding " + _PrimitiveName + ": " + e.getMessage(),e);
}
}
@Override
public void encodeData(AsnOutputStream asnOs) throws MAPException {
if (this.subscriberId == null || this.requestParameterList == null) {
throw new MAPException("Error while encoding " + _PrimitiveName
+ " the mandatory parameter subscriberId and requestParameterList is not defined");
}
((SubscriberIdImpl) this.subscriberId).encodeAll(asnOs);
try {
asnOs.writeTag(Tag.CLASS_UNIVERSAL,false,Tag.SEQUENCE);
int pos = asnOs.StartContentDefiniteLength();
for (RequestParameter requestParameter : this.requestParameterList)
asnOs.writeInteger(Tag.CLASS_UNIVERSAL,Tag.ENUMERATED,requestParameter.getCode());
asnOs.FinalizeContent(pos);
} catch (IOException e) {
e.printstacktrace();
} catch (AsnException e) {
e.printstacktrace();
}
}
@Override
public String toString() {
return "SendParameterRequestImp{" +
"subscriberId=" + subscriberId +
",requestParameterList=" + requestParameterList +
'}';
}
}
public class SubscriberIdImpl implements SubscriberId,MAPAsnPrimitive {
private TMSI tmsi;
private imsI imsi;
private static final int _TAG_imsI = 0;
private static final int _TAG_TMSI = 1;
private static final String _PrimitiveName = "SubscriberId";
public SubscriberIdImpl() {
}
public SubscriberIdImpl(TMSI tmsi) {
this.tmsi = tmsi;
}
public SubscriberIdImpl(imsI imsi) {
this.imsi = imsi;
}
@Override
public TMSI getTmsi() {
return tmsi;
}
@Override
public imsI getimsi() {
return imsi;
}
@Override
public int getTag() throws MAPException {
if (this.imsi != null) {
return _TAG_imsI;
} else {
return _TAG_TMSI;
}
}
@Override
public int getTagClass() {
return Tag.CLASS_CONTEXT_SPECIFIC;
}
@Override
public boolean getIsPrimitive() {
return true;
}
@Override
public void decodeAll(AsnInputStream ansIS) throws MAPParsingComponentException {
try {
int length = ansIS.readLength();
this._decode(ansIS,length);
} catch (IOException e) {
throw new MAPParsingComponentException("IOException when decoding " + _PrimitiveName + ": ",MAPParsingComponentExceptionReason.MistypedParameter);
}
}
private void _decode(AsnInputStream asnIS,int length) throws MAPParsingComponentException {
if (asnIS.getTagClass() != Tag.CLASS_CONTEXT_SPECIFIC || !asnIS.isTagPrimitive())
throw new MAPParsingComponentException("Error while decoding " + _PrimitiveName
+ ": bad tag class or is not primitive: TagClass=" + asnIS.getTagClass(),MAPParsingComponentExceptionReason.MistypedParameter);
switch (asnIS.getTag()) {
case _TAG_imsI:
this.imsi = new imsIImpl();
((imsIImpl) this.imsi).decodeData(asnIS,length);
break;
case _TAG_TMSI:
this.tmsi = new TMSIImpl();
((TMSIImpl) this.tmsi).decodeData(asnIS,length);
break;
default:
throw new MAPParsingComponentException("Error while decoding " + _PrimitiveName
+ ": Expexted imsi [0] imsI or msisdn [1] ISDN-Addressstring,but found " + asnIS.getTag(),MAPParsingComponentExceptionReason.MistypedParameter);
}
}
@Override
public void decodeData(AsnInputStream ansIS,int length) throws MAPParsingComponentException {
this._decode(ansIS,length);
}
@Override
public void encodeAll(AsnOutputStream asnOs) throws MAPException {
this.encodeAll(asnOs,this.getTag());
}
@Override
public void encodeAll(AsnOutputStream asnOs,e);
}
}
@Override
public void encodeData(AsnOutputStream asnOs) throws MAPException {
if (this.imsi == null && this.tmsi == null)
throw new MAPException("Error while encoding " + _PrimitiveName + ": all choices must not be null");
if (this.imsi != null && this.tmsi != null)
throw new MAPException("Error while encoding " + _PrimitiveName + ": all choices must not be not null");
if (this.imsi != null) {
((imsIImpl) this.imsi).encodeData(asnOs);
} else {
((TMSIImpl) this.tmsi).encodeData(asnOs);
}
}
@Override
public String toString() {
return "SubscriberIdImpl{" +
"tmsi=" + tmsi +
",imsi=" + imsi +
'}';
}
}
ASN.1规范如下:
MAP V1: SendParametersArg ::= SEQUENCE { subscriberId SubscriberId,requestParameterList RequestParameterList}
requestParameterList SEQUENCE SIZE (1..2) OF RequestParameter
SubscriberId ::= CHOICE { imsi [0] imsI,tmsi [1] TMSI}
解决方法
在查看了asn.1的wireshark源代码分解器之后,它们似乎为SendParametersArg使用了SubscriberIdentity而不是SubscriberId。区别在于前者是IMSI和MSISDN之间的选择,而后者是IMSI和TMSI之间的选择。