/* Copyright (C) 2010 Srivats P. This file is part of "Ostinato" This is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see */ #include "llc.h" LlcProtocol::LlcProtocol(StreamBase *stream, AbstractProtocol *parent) : AbstractProtocol(stream, parent) { } LlcProtocol::~LlcProtocol() { } AbstractProtocol* LlcProtocol::createInstance(StreamBase *stream, AbstractProtocol *parent) { return new LlcProtocol(stream, parent); } quint32 LlcProtocol::protocolNumber() const { return OstProto::Protocol::kLlcFieldNumber; } void LlcProtocol::protoDataCopyInto(OstProto::Protocol &protocol) const { protocol.MutableExtension(OstProto::llc)->CopyFrom(data); protocol.mutable_protocol_id()->set_id(protocolNumber()); } void LlcProtocol::protoDataCopyFrom(const OstProto::Protocol &protocol) { if (protocol.protocol_id().id() == protocolNumber() && protocol.HasExtension(OstProto::llc)) data.MergeFrom(protocol.GetExtension(OstProto::llc)); } QString LlcProtocol::name() const { return QString("802.3 Logical Link Control"); } QString LlcProtocol::shortName() const { return QString("LLC"); } AbstractProtocol::ProtocolIdType LlcProtocol::protocolIdType() const { return ProtocolIdLlc; } int LlcProtocol::fieldCount() const { return llc_fieldCount; } AbstractProtocol::FieldFlags LlcProtocol::fieldFlags(int index) const { AbstractProtocol::FieldFlags flags; flags = AbstractProtocol::fieldFlags(index); switch (index) { case llc_dsap: case llc_ssap: case llc_ctl: break; case llc_is_override_dsap: case llc_is_override_ssap: case llc_is_override_ctl: flags &= ~FrameField; flags |= MetaField; break; default: break; } return flags; } QVariant LlcProtocol::fieldData(int index, FieldAttrib attrib, int streamIndex) const { quint32 id; quint8 dsap, ssap, ctl; id = payloadProtocolId(ProtocolIdLlc); dsap = data.is_override_dsap() ? data.dsap() : (id >> 16) & 0xFF; ssap = data.is_override_ssap() ? data.ssap() : (id >> 8) & 0xFF; ctl = data.is_override_ctl() ? data.ctl() : (id >> 0) & 0xFF; switch (index) { case llc_dsap: switch(attrib) { case FieldName: return QString("DSAP"); case FieldValue: return dsap; case FieldTextValue: return QString("%1").arg(dsap, 2, BASE_HEX, QChar('0')); case FieldFrameValue: return QByteArray(1, (char)(dsap)); default: break; } break; case llc_ssap: switch(attrib) { case FieldName: return QString("SSAP"); case FieldValue: return ssap; case FieldTextValue: return QString("%1").arg(ssap, 2, BASE_HEX, QChar('0')); case FieldFrameValue: return QByteArray(1, (char)(ssap)); default: break; } break; case llc_ctl: switch(attrib) { case FieldName: return QString("Control"); case FieldValue: return ctl; case FieldTextValue: return QString("%1").arg(ctl, 2, BASE_HEX, QChar('0')); case FieldFrameValue: return QByteArray(1, (char)(ctl)); default: break; } break; // Meta fields case llc_is_override_dsap: { switch(attrib) { case FieldValue: return data.is_override_dsap(); default: break; } break; } case llc_is_override_ssap: { switch(attrib) { case FieldValue: return data.is_override_ssap(); default: break; } break; } case llc_is_override_ctl: { switch(attrib) { case FieldValue: return data.is_override_ctl(); default: break; } break; } default: qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, index); break; } return AbstractProtocol::fieldData(index, attrib, streamIndex); } bool LlcProtocol::setFieldData(int index, const QVariant &value, FieldAttrib attrib) { bool isOk = false; if (attrib != FieldValue) return false; switch (index) { case llc_dsap: { uint dsap = value.toUInt(&isOk) & 0xFF; if (isOk) data.set_dsap(dsap); break; } case llc_ssap: { uint ssap = value.toUInt(&isOk) & 0xFF; if (isOk) data.set_ssap(ssap); break; } case llc_ctl: { uint ctl = value.toUInt(&isOk) & 0xFF; if (isOk) data.set_ctl(ctl); break; } case llc_is_override_dsap: { bool ovr = value.toBool(); data.set_is_override_dsap(ovr); isOk = true; break; } case llc_is_override_ssap: { bool ovr = value.toBool(); data.set_is_override_ssap(ovr); isOk = true; break; } case llc_is_override_ctl: { bool ovr = value.toBool(); data.set_is_override_ctl(ovr); isOk = true; break; } default: qFatal("%s: unimplemented case %d in switch", __PRETTY_FUNCTION__, index); break; } return isOk; }