diff --git a/plugins/VOIP/services/p3vors.cc b/plugins/VOIP/services/p3vors.cc index 7a139a888..49a4002ea 100644 --- a/plugins/VOIP/services/p3vors.cc +++ b/plugins/VOIP/services/p3vors.cc @@ -526,7 +526,7 @@ bool p3VoRS::loadList(std::list& load) RsSerialiser *p3VoRS::setupSerialiser() { RsSerialiser *rsSerialiser = new RsSerialiser(); -// rsSerialiser->addSerialType(new RsVoipSerialiser()); + rsSerialiser->addSerialType(new RsVoipSerialiser()); rsSerialiser->addSerialType(new RsGeneralConfigSerialiser()); return rsSerialiser ; diff --git a/plugins/VOIP/services/rsvoipitems.cc b/plugins/VOIP/services/rsvoipitems.cc index f5202aa5b..b23c76c68 100644 --- a/plugins/VOIP/services/rsvoipitems.cc +++ b/plugins/VOIP/services/rsvoipitems.cc @@ -24,6 +24,7 @@ * */ +#include #include "serialiser/rsbaseserial.h" #include "serialiser/rstlvbase.h" @@ -37,18 +38,6 @@ /*************************************************************************/ - -RsVoipPingItem::~RsVoipPingItem() -{ - return; -} - -void RsVoipPingItem::clear() -{ - mSeqNo = 0; - mPingTS = 0; -} - std::ostream& RsVoipPingItem::print(std::ostream &out, uint16_t indent) { printRsItemBase(out, "RsVoipPingItem", indent); @@ -63,23 +52,6 @@ std::ostream& RsVoipPingItem::print(std::ostream &out, uint16_t indent) return out; } - - - - -RsVoipPongItem::~RsVoipPongItem() -{ - return; -} - -void RsVoipPongItem::clear() -{ - mSeqNo = 0; - mPingTS = 0; - mPongTS = 0; -} - - std::ostream& RsVoipPongItem::print(std::ostream &out, uint16_t indent) { printRsItemBase(out, "RsVoipPongItem", indent); @@ -99,9 +71,24 @@ std::ostream& RsVoipPongItem::print(std::ostream &out, uint16_t indent) /*************************************************************************/ +uint32_t RsVoipDataItem::serial_size() const +{ + uint32_t s = 8; /* header */ + s += 4; /* flags */ + s += 4; /* data_size */ + s += data_size; /* data */ + return s; +} +uint32_t RsVoipProtocolItem::serial_size() const +{ + uint32_t s = 8; /* header */ + s += 4; /* flags */ + s += 4; /* protocol */ -uint32_t RsVoipSerialiser::sizeVoipPingItem(RsVoipPingItem */*item*/) + return s; +} +uint32_t RsVoipPingItem::serial_size() const { uint32_t s = 8; /* header */ s += 4; /* seqno */ @@ -109,21 +96,91 @@ uint32_t RsVoipSerialiser::sizeVoipPingItem(RsVoipPingItem */*item*/) return s; } - -/* serialise the data to the buffer */ -bool RsVoipSerialiser::serialiseVoipPingItem(RsVoipPingItem *item, void *data, uint32_t *pktsize) +bool RsVoipProtocolItem::serialise(void *data, uint32_t& pktsize) { - uint32_t tlvsize = sizeVoipPingItem(item); + uint32_t tlvsize = serial_size() ; uint32_t offset = 0; - if (*pktsize < tlvsize) + if (pktsize < tlvsize) return false; /* not enough space */ - *pktsize = tlvsize; + pktsize = tlvsize; bool ok = true; - ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize); + +#ifdef RSSERIAL_DEBUG + std::cerr << "RsVoipSerialiser::serialiseVoipDataItem() Header: " << ok << std::endl; + std::cerr << "RsVoipSerialiser::serialiseVoipDataItem() Size: " << tlvsize << std::endl; +#endif + + /* skip the header */ + offset += 8; + + /* add mandatory parts first */ + ok &= setRawUInt32(data, tlvsize, &offset, protocol); + ok &= setRawUInt32(data, tlvsize, &offset, flags); + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsVoipSerialiser::serialiseVoipPingItem() Size Error! " << std::endl; + } + + return ok; +} +/* serialise the data to the buffer */ +bool RsVoipDataItem::serialise(void *data, uint32_t& pktsize) +{ + uint32_t tlvsize = serial_size() ; + uint32_t offset = 0; + + if (pktsize < tlvsize) + return false; /* not enough space */ + + pktsize = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize); + +#ifdef RSSERIAL_DEBUG + std::cerr << "RsVoipSerialiser::serialiseVoipDataItem() Header: " << ok << std::endl; + std::cerr << "RsVoipSerialiser::serialiseVoipDataItem() Size: " << tlvsize << std::endl; +#endif + + /* skip the header */ + offset += 8; + + /* add mandatory parts first */ + ok &= setRawUInt32(data, tlvsize, &offset, flags); + ok &= setRawUInt32(data, tlvsize, &offset, data_size); + memcpy(data,voip_data,data_size) ; + offset += data_size ; + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsVoipSerialiser::serialiseVoipPingItem() Size Error! " << std::endl; + } + + return ok; +} +/* serialise the data to the buffer */ +bool RsVoipPingItem::serialise(void *data, uint32_t& pktsize) +{ + uint32_t tlvsize = serial_size() ; + uint32_t offset = 0; + + if (pktsize < tlvsize) + return false; /* not enough space */ + + pktsize = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize); #ifdef RSSERIAL_DEBUG std::cerr << "RsVoipSerialiser::serialiseVoipPingItem() Header: " << ok << std::endl; @@ -134,8 +191,8 @@ bool RsVoipSerialiser::serialiseVoipPingItem(RsVoipPingItem *item, void *dat offset += 8; /* add mandatory parts first */ - ok &= setRawUInt32(data, tlvsize, &offset, item->mSeqNo); - ok &= setRawUInt64(data, tlvsize, &offset, item->mPingTS); + ok &= setRawUInt32(data, tlvsize, &offset, mSeqNo); + ok &= setRawUInt64(data, tlvsize, &offset, mPingTS); if (offset != tlvsize) { @@ -146,7 +203,38 @@ bool RsVoipSerialiser::serialiseVoipPingItem(RsVoipPingItem *item, void *dat return ok; } -RsVoipPingItem *RsVoipSerialiser::deserialiseVoipPingItem(void *data, uint32_t *pktsize) +RsVoipProtocolItem::RsVoipProtocolItem(void *data, uint32_t pktsize) + : RsVoipItem(RS_PKT_SUBTYPE_VOIP_PROTOCOL) +{ + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); + + uint32_t offset = 0; + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_TYPE_VOIP != getRsItemService(rstype)) || (RS_PKT_SUBTYPE_VOIP_PING != getRsItemSubType(rstype))) + throw std::runtime_error("Wrong packet type!") ; + + if (pktsize < rssize) /* check size */ + throw std::runtime_error("Not enough size!") ; + + bool ok = true; + + /* skip the header */ + offset += 8; + + /* get mandatory parts first */ + ok &= getRawUInt32(data, rssize, &offset, &protocol); + ok &= getRawUInt32(data, rssize, &offset, &flags); + + if (offset != rssize) + throw std::runtime_error("Deserialisation error!") ; + + if (!ok) + throw std::runtime_error("Deserialisation error!") ; +} +RsVoipPingItem::RsVoipPingItem(void *data, uint32_t pktsize) + : RsVoipItem(RS_PKT_SUBTYPE_VOIP_PING) { /* get the type and size */ uint32_t rstype = getRsItemId(data); @@ -155,53 +243,33 @@ RsVoipPingItem *RsVoipSerialiser::deserialiseVoipPingItem(void *data, uint32_t * uint32_t offset = 0; - if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_VOIP != getRsItemService(rstype)) || - (RS_PKT_SUBTYPE_VOIP_PING != getRsItemSubType(rstype))) - { - return NULL; /* wrong type */ - } + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_TYPE_VOIP != getRsItemService(rstype)) || (RS_PKT_SUBTYPE_VOIP_PING != getRsItemSubType(rstype))) + throw std::runtime_error("Wrong packet type!") ; - if (*pktsize < rssize) /* check size */ - return NULL; /* not enough data */ - - /* set the packet length */ - *pktsize = rssize; + if (pktsize < rssize) /* check size */ + throw std::runtime_error("Not enough size!") ; bool ok = true; - /* ready to load */ - RsVoipPingItem *item = new RsVoipPingItem(); - item->clear(); - /* skip the header */ offset += 8; /* get mandatory parts first */ - ok &= getRawUInt32(data, rssize, &offset, &(item->mSeqNo)); - ok &= getRawUInt64(data, rssize, &offset, &(item->mPingTS)); + ok &= getRawUInt32(data, rssize, &offset, &mSeqNo); + ok &= getRawUInt64(data, rssize, &offset, &mPingTS); if (offset != rssize) - { - /* error */ - delete item; - return NULL; - } + throw std::runtime_error("Deserialisation error!") ; if (!ok) - { - delete item; - return NULL; - } - - return item; + throw std::runtime_error("Deserialisation error!") ; } /*************************************************************************/ /*************************************************************************/ -uint32_t RsVoipSerialiser::sizeVoipPongItem(RsVoipPongItem */*item*/) +uint32_t RsVoipPongItem::serial_size() const { uint32_t s = 8; /* header */ s += 4; /* seqno */ @@ -212,19 +280,19 @@ uint32_t RsVoipSerialiser::sizeVoipPongItem(RsVoipPongItem */*item*/) } /* serialise the data to the buffer */ -bool RsVoipSerialiser::serialiseVoipPongItem(RsVoipPongItem *item, void *data, uint32_t *pktsize) +bool RsVoipPongItem::serialise(void *data, uint32_t& pktsize) { - uint32_t tlvsize = sizeVoipPongItem(item); + uint32_t tlvsize = serial_size() ; uint32_t offset = 0; - if (*pktsize < tlvsize) + if (pktsize < tlvsize) return false; /* not enough space */ - *pktsize = tlvsize; + pktsize = tlvsize; bool ok = true; - ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize); #ifdef RSSERIAL_DEBUG std::cerr << "RsVoipSerialiser::serialiseVoipPongItem() Header: " << ok << std::endl; @@ -235,9 +303,9 @@ bool RsVoipSerialiser::serialiseVoipPongItem(RsVoipPongItem *item, void *dat offset += 8; /* add mandatory parts first */ - ok &= setRawUInt32(data, tlvsize, &offset, item->mSeqNo); - ok &= setRawUInt64(data, tlvsize, &offset, item->mPingTS); - ok &= setRawUInt64(data, tlvsize, &offset, item->mPongTS); + ok &= setRawUInt32(data, tlvsize, &offset, mSeqNo); + ok &= setRawUInt64(data, tlvsize, &offset, mPingTS); + ok &= setRawUInt64(data, tlvsize, &offset, mPongTS); if (offset != tlvsize) { @@ -247,8 +315,8 @@ bool RsVoipSerialiser::serialiseVoipPongItem(RsVoipPongItem *item, void *dat return ok; } - -RsVoipPongItem *RsVoipSerialiser::deserialiseVoipPongItem(void *data, uint32_t *pktsize) +RsVoipDataItem::RsVoipDataItem(void *data, uint32_t pktsize) + : RsVoipItem(RS_PKT_SUBTYPE_VOIP_DATA) { /* get the type and size */ uint32_t rstype = getRsItemId(data); @@ -256,88 +324,65 @@ RsVoipPongItem *RsVoipSerialiser::deserialiseVoipPongItem(void *data, uint32_t * uint32_t offset = 0; + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_TYPE_VOIP != getRsItemService(rstype)) || (RS_PKT_SUBTYPE_VOIP_DATA != getRsItemSubType(rstype))) + throw std::runtime_error("Wrong packet subtype") ; - if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_VOIP != getRsItemService(rstype)) || - (RS_PKT_SUBTYPE_VOIP_PONG != getRsItemSubType(rstype))) - { - return NULL; /* wrong type */ - } - - if (*pktsize < rssize) /* check size */ - return NULL; /* not enough data */ - - /* set the packet length */ - *pktsize = rssize; + if (pktsize < rssize) /* check size */ + throw std::runtime_error("Not enough space") ; bool ok = true; - /* ready to load */ - RsVoipPongItem *item = new RsVoipPongItem(); - item->clear(); - /* skip the header */ offset += 8; /* get mandatory parts first */ - ok &= getRawUInt32(data, rssize, &offset, &(item->mSeqNo)); - ok &= getRawUInt64(data, rssize, &offset, &(item->mPingTS)); - ok &= getRawUInt64(data, rssize, &offset, &(item->mPongTS)); + ok &= getRawUInt32(data, rssize, &offset, &flags); + ok &= getRawUInt32(data, rssize, &offset, &data_size); + + voip_data = malloc(data_size) ; + memcpy(voip_data,&((uint8_t*)data)[offset],data_size) ; + offset += data_size ; if (offset != rssize) - { - /* error */ - delete item; - return NULL; - } + throw std::runtime_error("Serialization error.") ; if (!ok) - { - delete item; - return NULL; - } + throw std::runtime_error("Serialization error.") ; +} +RsVoipPongItem::RsVoipPongItem(void *data, uint32_t pktsize) + : RsVoipItem(RS_PKT_SUBTYPE_VOIP_PONG) +{ + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + uint32_t rssize = getRsItemSize(data); - return item; + uint32_t offset = 0; + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_TYPE_VOIP != getRsItemService(rstype)) || (RS_PKT_SUBTYPE_VOIP_PONG != getRsItemSubType(rstype))) + throw std::runtime_error("Wrong packet subtype") ; + + if (pktsize < rssize) /* check size */ + throw std::runtime_error("Not enough space") ; + + bool ok = true; + + /* skip the header */ + offset += 8; + + /* get mandatory parts first */ + ok &= getRawUInt32(data, rssize, &offset, &mSeqNo); + ok &= getRawUInt64(data, rssize, &offset, &mPingTS); + ok &= getRawUInt64(data, rssize, &offset, &mPongTS); + + if (offset != rssize) + throw std::runtime_error("Serialization error.") ; + + if (!ok) + throw std::runtime_error("Serialization error.") ; } /*************************************************************************/ -uint32_t RsVoipSerialiser::size(RsItem *i) -{ - RsVoipPingItem *ping; - RsVoipPongItem *pong; - - if (NULL != (ping = dynamic_cast(i))) - { - return sizeVoipPingItem(ping); - } - else if (NULL != (pong = dynamic_cast(i))) - { - return sizeVoipPongItem(pong); - } - return 0; -} - -bool RsVoipSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize) -{ -#ifdef RSSERIAL_DEBUG - std::cerr << "RsMsgSerialiser::serialise()" << std::endl; -#endif - - RsVoipPingItem *ping; - RsVoipPongItem *pong; - - if (NULL != (ping = dynamic_cast(i))) - { - return serialiseVoipPingItem(ping, data, pktsize); - } - else if (NULL != (pong = dynamic_cast(i))) - { - return serialiseVoipPongItem(pong, data, pktsize); - } - return false; -} - RsItem* RsVoipSerialiser::deserialise(void *data, uint32_t *pktsize) { #ifdef RSSERIAL_DEBUG @@ -347,26 +392,27 @@ RsItem* RsVoipSerialiser::deserialise(void *data, uint32_t *pktsize) /* get the type and size */ uint32_t rstype = getRsItemId(data); - if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || - (RS_SERVICE_TYPE_VOIP != getRsItemService(rstype))) + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_TYPE_VOIP != getRsItemService(rstype))) + return NULL ; + + try { - return NULL; /* wrong type */ - } + switch(getRsItemSubType(rstype)) + { + case RS_PKT_SUBTYPE_VOIP_PING: return new RsVoipPingItem(data, *pktsize); + case RS_PKT_SUBTYPE_VOIP_PONG: return new RsVoipPongItem(data, *pktsize); + case RS_PKT_SUBTYPE_VOIP_PROTOCOL: return new RsVoipProtocolItem(data, *pktsize); + case RS_PKT_SUBTYPE_VOIP_DATA: return new RsVoipDataItem(data, *pktsize); - switch(getRsItemSubType(rstype)) + default: + return NULL; + } + } + catch(std::exception& e) { - case RS_PKT_SUBTYPE_VOIP_PING: - return deserialiseVoipPingItem(data, pktsize); - break; - case RS_PKT_SUBTYPE_VOIP_PONG: - return deserialiseVoipPongItem(data, pktsize); - break; - default: - return NULL; - break; + std::cerr << "RsVoipSerialiser: deserialization error: " << e.what() << std::endl; + return NULL; } - - return NULL; } diff --git a/plugins/VOIP/services/rsvoipitems.h b/plugins/VOIP/services/rsvoipitems.h index f62f21479..c7f22a068 100644 --- a/plugins/VOIP/services/rsvoipitems.h +++ b/plugins/VOIP/services/rsvoipitems.h @@ -34,37 +34,93 @@ /**************************************************************************/ -const uint8_t RS_PKT_SUBTYPE_VOIP_PING = 0x01; -const uint8_t RS_PKT_SUBTYPE_VOIP_PONG = 0x02; +const uint8_t RS_PKT_SUBTYPE_VOIP_PING = 0x01; +const uint8_t RS_PKT_SUBTYPE_VOIP_PONG = 0x02; +const uint8_t RS_PKT_SUBTYPE_VOIP_PROTOCOL= 0x03 ; +const uint8_t RS_PKT_SUBTYPE_VOIP_DATA = 0x04 ; + +const uint8_t QOS_PRIORITY_RS_VOIP = 9 ; class RsVoipItem: public RsItem { public: - RsVoipItem(uint8_t chat_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_VOIP,chat_subtype) - { setPriorityLevel(QOS_PRIORITY_RS_VOIP_PING) ;} // should be refined later. + RsVoipItem(uint8_t voip_subtype) + : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_VOIP,voip_subtype) + { + setPriorityLevel(QOS_PRIORITY_RS_VOIP) ; + } virtual ~RsVoipItem() {}; virtual void clear() {}; virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) = 0 ; + + virtual bool serialise(void *data,uint32_t& size) = 0 ; // Isn't it better that items can serialise themselves ? + virtual uint32_t serial_size() const = 0 ; // deserialise is handled using a constructor }; class RsVoipPingItem: public RsVoipItem { public: RsVoipPingItem() :RsVoipItem(RS_PKT_SUBTYPE_VOIP_PING) {} + RsVoipPingItem(void *data,uint32_t size) ; - virtual ~RsVoipPingItem(); - virtual void clear(); + virtual bool serialise(void *data,uint32_t& size) ; + virtual uint32_t serial_size() const ; + + virtual ~RsVoipPingItem() {} virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); uint32_t mSeqNo; uint64_t mPingTS; }; +class RsVoipDataItem: public RsVoipItem +{ + public: + RsVoipDataItem() :RsVoipItem(RS_PKT_SUBTYPE_VOIP_DATA) {} + RsVoipDataItem(void *data,uint32_t size) ; + + virtual bool serialise(void *data,uint32_t& size) ; + virtual uint32_t serial_size() const ; + + virtual ~RsVoipDataItem() + { + free(voip_data) ; + voip_data = NULL ; + } + virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); + + uint32_t flags ; + uint32_t data_size ; + void *voip_data ; +}; + +class RsVoipProtocolItem: public RsVoipItem +{ + public: + RsVoipProtocolItem() :RsVoipItem(RS_PKT_SUBTYPE_VOIP_PROTOCOL) {} + RsVoipProtocolItem(void *data,uint32_t size) ; + + enum { VoipProtocol_Ring = 1, VoipProtocol_Ackn = 2, VoipProtocol_Close = 3 } ; + + virtual bool serialise(void *data,uint32_t& size) ; + virtual uint32_t serial_size() const ; + + virtual ~RsVoipProtocolItem() {} + virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); + + uint32_t protocol ; + uint32_t flags ; +}; + class RsVoipPongItem: public RsVoipItem { public: RsVoipPongItem() :RsVoipItem(RS_PKT_SUBTYPE_VOIP_PONG) {} + RsVoipPongItem(void *data,uint32_t size) ; + + virtual bool serialise(void *data,uint32_t& size) ; + virtual uint32_t serial_size() const ; virtual ~RsVoipPongItem(); virtual void clear(); @@ -75,30 +131,25 @@ class RsVoipPongItem: public RsVoipItem uint64_t mPongTS; }; - class RsVoipSerialiser: public RsSerialType { public: - RsVoipSerialiser() - :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_VOIP) - { return; } - -virtual ~RsVoipSerialiser() { return; } - -virtual uint32_t size(RsItem *); -virtual bool serialise (RsItem *item, void *data, uint32_t *size); -virtual RsItem * deserialise(void *data, uint32_t *size); + RsVoipSerialiser() + :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_VOIP) + { + } + virtual ~RsVoipSerialiser() {} - private: - -virtual uint32_t sizeVoipPingItem(RsVoipPingItem *); -virtual bool serialiseVoipPingItem (RsVoipPingItem *item, void *data, uint32_t *size); -virtual RsVoipPingItem *deserialiseVoipPingItem(void *data, uint32_t *size); - -virtual uint32_t sizeVoipPongItem(RsVoipPongItem *); -virtual bool serialiseVoipPongItem (RsVoipPongItem *item, void *data, uint32_t *size); -virtual RsVoipPongItem *deserialiseVoipPongItem(void *data, uint32_t *size); + virtual uint32_t size (RsItem *item) + { + return dynamic_cast(item)->serial_size() ; + } + virtual bool serialise (RsItem *item, void *data, uint32_t *size) + { + return dynamic_cast(item)->serialise(data,*size) ; + } + virtual RsItem *deserialise(void *data, uint32_t *size); }; /**************************************************************************/