ReturnCode AB::decode(NetworkBuffer& buffer) { SPDU::control(buffer); if (sli() == 0) return OK; ReturnCode rc = OK; while (buffer.hasRemaining()) { buffer.markit(); byte code = buffer.get(); switch (code) { case PI::PI_TDISC: { TDISC* pi = new TDISC(buffer); ab_disconnect = pi->getValue(); addMask(SMASK_AB_DISC); } break; case PI::PI_REFLECT: { REFLECT* pi = new REFLECT(buffer); int length = 0; memcpy(ab_reflect, pi->getValue(length), length); addMask(SMASK_AB_REFL); } break; case PI::PI_ENCLOSE: { ENCLOSE* pi = new ENCLOSE(buffer); setEnclose(pi->getValue()); addMask(SMASK_ENCLOSE); } break; case PI::PI_UDATA: { UDATA* pi = new UDATA(buffer); int length = 0; const byte* data; data = pi->getValue(length); setData(length, data); addMask(SMASK_ENCLOSE); } break; default: buffer.reset(); goto EXIT; } } EXIT: return rc; }
ReturnCode AEA::decode(NetworkBuffer& tsdu) { ReturnCode rc = OK; rc = SPDU::control(tsdu); if (sli() == 0) return OK; while (tsdu.hasRemaining()) { tsdu.markit(); byte code = tsdu.get(); switch (code) { case PI::PI_SERIAL: { SERIAL pi(tsdu); aea_serial = pi.getValue(); addMask(SMASK_AEA_SERIAL); } break; case PI::PI_ENCLOSE: { ENCLOSE pi(tsdu); setEnclose(pi.getValue()); addMask(SMASK_ENCLOSE); } break; case PI::PI_UDATA: { UDATA pi(tsdu); int cc = 0; const byte* data = pi.getValue(cc); setData(cc, data); } break; default: tsdu.reset(); goto EXIT; } } EXIT: return rc; }
ReturnCode CN_AC::decode(NetworkBuffer& tsdu) { SPDU::control(tsdu); if (sli() == 0) return OK; ReturnCode rc = OK; while (tsdu.hasRemaining()) { /* switch (code) { case PI_UDATA: if (!bool(pmask & PMASK_UDATA) || li() > 512) spkt.spdu_errno = SC_PROTOCOL; break; case PI_XDATA: if (!bool(pmask & PMASK_XDATA) || li() <= 512) spkt.spdu_errno = SC_PROTOCOL; break; default: if (bool(code < pi_table.length) && bool(pi_table[code]) && !bool(pmask & pi_table[code])) spkt.spdu_errno = SC_PROTOCOL; break; } if (code < pi_table.length && bool(pi_table[code])&& !bool(pi_table[code] & PMASK_PGI)) { if (li() > 0) { if (bool(pi_table[code] & PMASK_VARLEN)) { if (li() > pi_length[code]) { spkt.spdu_errno = SC_PROTOCOL; // break; } } else if (li() != pi_length[code]) { spkt.spdu_errno = SC_PROTOCOL; // break; } } } */ tsdu.markit(); byte code = tsdu.get() & 0xFF; switch (code) { case PGI::PGI_CN_ID: { CN_ID pi(*this, tsdu); addMask(SMASK_CN_REF); } break; case PGI::PGI_CN_ITEMS: { CN_ITEMS pgi(*this, tsdu); addMask(SMASK_CN_REF); } break; case PI::PI_CALLED_SS: { CALLED_SS pi(tsdu); int length = 0; const byte* data = pi.getValue(length); cn_reference.udata(length, data); addMask(SMASK_CN_REF); } break; case PI::PI_CALLING_SS: { // case PI_AR_CALLED: // case PI_AR_CALLING: CALLING_SS pi(tsdu); int length = 0; const byte* data = pi.getValue(length); cn_reference.udata(length, data); addMask(SMASK_CN_REF); } break; case PI::PI_COMMON_REF: { // case PI_AR_COMMON: COMMON_REF pi(tsdu); int length = 0; const byte* data = pi.getValue(length); cn_reference.cdata(length, data); addMask(SMASK_CN_REF); } break; case PI::PI_ADD_INFO: { // case PI_AR_ADDT: ADD_INFO pi(tsdu); int length = 0; const byte* data = pi.getValue(length); cn_reference.adata(length, data); addMask(SMASK_CN_REF); } break; case PI::PI_VERSION: { VERSION pi(tsdu); cn_version = pi.getValue(); addMask(SMASK_CN_VRSN); } break; case PI::PI_USER_REQ: { USER_REQ pi(tsdu); cn_require = pi.getValue(); addMask(SMASK_CN_REQ); } break; case PI::PI_ISN: { ISN pi(tsdu); cn_isn = pi.getValue(); addMask(SMASK_CN_ISN); } break; case PI::PI_TOKEN: { if (si() != SPDU_AC) { //FIXME throw exception } TOKEN pi(tsdu); ac_token = pi.getValue(); addMask(SMASK_AC_TOKEN); } break; case PI::PI_TOISN: {/* not supported yet */ } break; case PI::PI_SSAP_CALLING: { SSAP_CALLING pi(tsdu); int length = 0; const byte* data = pi.getValue(length); cn_callinglen = pi.pli(); //FIXME check cn_callinglen == length memcpy(cn_calling, data, min(cn_callinglen, sizeof(cn_calling))); addMask(SMASK_CN_CALLING); } break; case PI::PI_SSAP_CALLED: { SSAP_CALLED pi(tsdu); int length = 0; const byte* data = pi.getValue(length); cn_calledlen = pi.pli(); //FIXME check cn_callinglen == length memcpy(cn_called, data, min(cn_calledlen, sizeof(cn_calling))); addMask(SMASK_CN_CALLED); } break; case PI::PI_UDATA: { UDATA pi(tsdu); addMask(SMASK_UDATA_PGI); if (pi.pli() > 0) { // if (si() == SPDU_AB && !spkt.hasMask(SMASK_SPDU_AB)) { // throw SSAPException(SC_PROTOCOL); // } else if (pi.pli() > MAX_CONNECT_DATA_SIZE) { throw Exception(AbortCode::SC_PROTOCOL); } int length = 0; const byte* data = pi.getValue(length); setData(length, data); } } break; case PI::PI_XDATA: { XDATA pi(tsdu); addMask(SMASK_UDATA_PGI); if (pi.pli() > 0) { // if (si() == SPDU_AB && !spkt.hasMask(SMASK_SPDU_AB)) { // throw SSAPException(SC_PROTOCOL); // } else if (pi.pli() > MAX_CONNECT_DATA_SIZE) { throw Exception(AbortCode::SC_PROTOCOL); } int length = 0; const byte* data = pi.getValue(length); setData(length, data); } } break; default: tsdu.reset(); goto EXIT; } } EXIT: return rc; }