Major improvements to the serialiser to make it work with retroshare.

This is still a first draft - the message types will surely change.

-corrected ids and added service classes.
-Added disc/msg/chat/cache/file messages
-Extended serialiser to handle service extensions.
-corrected IpAddrPort code.
-More debugging code.
-Added some tests.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@270 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2007-12-12 00:54:42 +00:00
parent 9f76b1a313
commit e8ccb0b427
22 changed files with 3101 additions and 333 deletions

View File

@ -7,8 +7,10 @@ RS_TOP_DIR = ..
include $(RS_TOP_DIR)/scripts/config.mk
###############################################################
RSOBJ = rsserial.o rsbaseserial.o rstlvbase.o rstlvtypes.o rsbaseitems.o
RSOBJ += rstlvfileitem.o rstlvutil.o
RSOBJ = rsserial.o rsbaseserial.o rstlvbase.o rstlvtypes.o
RSOBJ += rstlvfileitem.o rstlvutil.o # TLV Objs
RSOBJ += rsbaseitems.o rsconfigitems.o rsdiscitems.o # RsItems
RSOBJ += rsmsgitems.o # RsItems
TESTOBJ = tlvbase_test.o tlvbase_test2.o tlvfileitem_test.o
TESTOBJ += tlvitems_test.o tlvstack_test.o tlvconfig_test.o
@ -18,7 +20,7 @@ TESTOBJ += rsserial_test.o
TESTS = tlvbase_test tlvbase_test2 tlvfileitem_test
TESTS += tlvitems_test tlvstack_test tlvconfig_test
TESTS += rsserial_test
TESTS += rsserial_test
#rsbaseitem_test

View File

@ -0,0 +1,191 @@
/*
* libretroshare/src/serialiser: rsbaseitem_test.cc
*
* RetroShare Serialiser.
*
* Copyright 2007-2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
/******************************************************************
* tlvfileitem test.
*
*
*/
#include <iostream>
#include <sstream>
#include "serialiser/rstlvtypes.h"
#include "serialiser/rstlvutil.h"
#include "util/utest.h"
INITTEST();
static int test_RsFileItem();
static int test_RsFileData();
int main()
{
std::cerr << "RsFile[Item/Data/...] Tests" << std::endl;
test_RsFileItem();
test_RsFileData();
FINALREPORT("RsTlvFile[Item/Data/...] Tests");
return TESTRESULT();
}
int test_RsTlvFileItem()
{
RsTlvFileItem i1;
RsTlvFileItem i2;
/* initialise */
i1.filesize = 101010;
i1.hash = "ABCDEFEGHE";
i1.name = "TestFile.txt";
i1.pop = 12;
i1.age = 456;
CHECK(test_SerialiseTlvItem(std::cerr, &i1, &i2));
/* check the data is the same */
CHECK(i1.filesize == i2.filesize);
CHECK(i1.hash == i2.hash);
CHECK(i1.name == i2.name);
CHECK(i1.path == i2.path);
CHECK(i1.pop == i2.pop);
CHECK(i1.age == i2.age);
/* do it again without optional data */
i1.filesize = 123;
i1.name = "";
i1.pop = 0;
i1.age = 0;
CHECK(test_SerialiseTlvItem(std::cerr, &i1, &i2));
/* check the data is the same */
CHECK(i1.filesize == i2.filesize);
CHECK(i1.hash == i2.hash);
CHECK(i1.name == i2.name);
CHECK(i1.path == i2.path);
CHECK(i1.pop == i2.pop);
CHECK(i1.age == i2.age);
/* one more time - long file name, some optional data */
i1.filesize = 123;
i1.name = "A Very Long File name that should fit in easily ??? with som $&%&^%* strange char (**$^%#&^$#*^%(&^ in there too!!!! ~~~!!$#(^$)$)(&%^)&\" oiyu thend";
i1.pop = 666;
i1.age = 0;
CHECK(test_SerialiseTlvItem(std::cerr, &i1, &i2));
/* check the data is the same */
CHECK(i1.filesize == i2.filesize);
CHECK(i1.hash == i2.hash);
CHECK(i1.name == i2.name);
CHECK(i1.path == i2.path);
CHECK(i1.pop == i2.pop);
CHECK(i1.age == i2.age);
REPORT("Serialise/Deserialise RsTlvFileItem");
return 1;
}
int test_RsTlvFileSet()
{
RsTlvFileSet s1;
RsTlvFileSet s2;
int i = 0;
for(i = 0; i < 15; i++)
{
RsTlvFileItem fi;
fi.filesize = 16 + i * i;
fi.hash = "ABCDEF";
std::ostringstream out;
out << "File" << i << "_inSet.txt";
fi.name = out.str();
if (i % 2 == 0)
{
fi.age = 10 * i;
}
else
{
fi.age = 0;
}
fi.pop = 0;
s1.items.push_back(fi);
}
CHECK(test_SerialiseTlvItem(std::cerr, &s1, &s2));
/* check the data is the same - TODO */
REPORT("Serialise/Deserialise RsTlvFileSet");
return 1;
}
int test_RsTlvFileData()
{
RsTlvFileData d1;
RsTlvFileData d2;
/* initialise */
d1.file.filesize = 101010;
d1.file.hash = "ABCDEFEGHE";
d1.file.name = "";
d1.file.age = 0;
d1.file.pop = 0;
char data[15];
d1.binData.setBinData(data, 15);
d1.file_offset = 222;
CHECK(test_SerialiseTlvItem(std::cerr, &d1, &d2));
/* check the data is the same */
CHECK(d1.file.filesize == d2.file.filesize);
CHECK(d1.file.hash == d2.file.hash);
CHECK(d1.file.name == d2.file.name);
CHECK(d1.file.path == d2.file.path);
CHECK(d1.file.pop == d2.file.pop);
CHECK(d1.file.age == d2.file.age);
CHECK(d1.file_offset == d2.file_offset);
CHECK(d1.binData.bin_len == d2.binData.bin_len);
REPORT("Serialise/Deserialise RsTlvFileData");
return 1;
}

View File

@ -30,32 +30,111 @@
#define RSSERIAL_DEBUG 1
#include <iostream>
RsFileItem::~RsFileItem()
/*************************************************************************/
uint32_t RsFileItemSerialiser::size(RsItem *i)
{
RsFileRequest *rfr;
RsFileData *rfd;
if (NULL != (rfr = dynamic_cast<RsFileRequest *>(i)))
{
return sizeReq(rfr);
}
else if (NULL != (rfd = dynamic_cast<RsFileData *>(i)))
{
return sizeData(rfd);
}
return 0;
}
/* serialise the data to the buffer */
bool RsFileItemSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
{
RsFileRequest *rfr;
RsFileData *rfd;
if (NULL != (rfr = dynamic_cast<RsFileRequest *>(i)))
{
return serialiseReq(rfr, data, pktsize);
}
else if (NULL != (rfd = dynamic_cast<RsFileData *>(i)))
{
return serialiseData(rfd, data, pktsize);
}
return false;
}
RsItem *RsFileItemSerialiser::deserialise(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) ||
(RS_PKT_CLASS_BASE != getRsItemClass(rstype)) ||
(RS_PKT_TYPE_FILE != getRsItemType(rstype)))
{
return NULL; /* wrong type */
}
switch(getRsItemSubType(rstype))
{
case RS_PKT_SUBTYPE_FI_REQUEST:
return deserialiseReq(data, pktsize);
break;
case RS_PKT_SUBTYPE_FI_DATA:
return deserialiseData(data, pktsize);
break;
default:
return NULL;
break;
}
return NULL;
}
/*************************************************************************/
RsFileRequest::~RsFileRequest()
{
return;
}
void RsFileItem::clear()
void RsFileRequest::clear()
{
file.TlvClear();
reqType = 0;
fileoffset = 0;
chunksize = 0;
}
uint32_t RsFileItemSerialiser::size(RsItem *i)
std::ostream &RsFileRequest::print(std::ostream &out, uint16_t indent)
{
RsFileItem *item = (RsFileItem *) i;
uint32_t s = 12; /* header + 4 for reqType */
printRsItemBase(out, "RsFileRequest", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "FileOffset: " << fileoffset << std::endl;
out << "ChunkSize: " << chunksize << std::endl;
file.print(out, int_Indent);
printRsItemEnd(out, "RsFileRequest", indent);
return out;
}
uint32_t RsFileItemSerialiser::sizeReq(RsFileRequest *item)
{
uint32_t s = 8; /* header */
s += 8; /* offset */
s += 4; /* chunksize */
s += item->file.TlvSize();
return s;
}
/* serialise the data to the buffer */
bool RsFileItemSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
bool RsFileItemSerialiser::serialiseReq(RsFileRequest *item, void *data, uint32_t *pktsize)
{
RsFileItem *item = (RsFileItem *) i;
uint32_t tlvsize = size(item);
uint32_t tlvsize = sizeReq(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
@ -67,21 +146,30 @@ bool RsFileItemSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsiz
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
std::cerr << "RsFileItemSerialiser::serialise() Header: " << ok << std::endl;
std::cerr << "RsFileItemSerialiser::serialiseReq() Header: " << ok << std::endl;
std::cerr << "RsFileItemSerialiser::serialiseReq() Size: " << tlvsize << std::endl;
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, item->reqType);
std::cerr << "RsFileItemSerialiser::serialise() RawUInt32: " << ok << std::endl;
ok &= setRawUInt64(data, tlvsize, &offset, item->fileoffset);
std::cerr << "RsFileItemSerialiser::serialiseReq() Fileoffset: " << ok << std::endl;
ok &= setRawUInt32(data, tlvsize, &offset, item->chunksize);
std::cerr << "RsFileItemSerialiser::serialiseReq() Chunksize: " << ok << std::endl;
ok &= item->file.SetTlv(data, tlvsize, &offset);
std::cerr << "RsFileItemSerialiser::serialise() FileItem: " << ok << std::endl;
std::cerr << "RsFileItemSerialiser::serialiseReq() FileItem: " << ok << std::endl;
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsFileItemSerialiser::serialiseReq() Size Error! " << std::endl;
}
return ok;
}
RsItem *RsFileItemSerialiser::deserialise(void *data, uint32_t *pktsize)
RsFileRequest *RsFileItemSerialiser::deserialiseReq(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
@ -92,8 +180,8 @@ RsItem *RsFileItemSerialiser::deserialise(void *data, uint32_t *pktsize)
if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) ||
(RS_PKT_CLASS_BASE != getRsItemClass(rstype)) ||
(RS_PKT_TYPE_FILE_ITEM != getRsItemType(rstype)) ||
(0 != getRsItemSubType(rstype)))
(RS_PKT_TYPE_FILE != getRsItemType(rstype)) ||
(RS_PKT_SUBTYPE_FI_REQUEST != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
@ -107,16 +195,24 @@ RsItem *RsFileItemSerialiser::deserialise(void *data, uint32_t *pktsize)
bool ok = true;
/* ready to load */
RsFileItem *item = new RsFileItem();
RsFileRequest *item = new RsFileRequest();
item->clear();
/* skip the header */
offset += 8;
/* get mandatory parts first */
ok &= getRawUInt32(data, rssize, &offset, &(item->reqType));
ok &= getRawUInt64(data, rssize, &offset, &(item->fileoffset));
ok &= getRawUInt32(data, rssize, &offset, &(item->chunksize));
ok &= item->file.GetTlv(data, rssize, &offset);
if (offset != rssize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
@ -127,4 +223,505 @@ RsItem *RsFileItemSerialiser::deserialise(void *data, uint32_t *pktsize)
}
/*************************************************************************/
RsFileData::~RsFileData()
{
return;
}
void RsFileData::clear()
{
fd.TlvClear();
}
std::ostream &RsFileData::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsFileData", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
fd.print(out, int_Indent);
printRsItemEnd(out, "RsFileData", indent);
return out;
}
uint32_t RsFileItemSerialiser::sizeData(RsFileData *item)
{
uint32_t s = 8; /* header */
s += item->fd.TlvSize();
return s;
}
/* serialise the data to the buffer */
bool RsFileItemSerialiser::serialiseData(RsFileData *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeData(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
std::cerr << "RsFileItemSerialiser::serialiseData() Header: " << ok << std::endl;
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= item->fd.SetTlv(data, tlvsize, &offset);
std::cerr << "RsFileItemSerialiser::serialiseData() TlvFileData: " << ok << std::endl;
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsFileItemSerialiser::serialiseData() Size Error! " << std::endl;
}
return ok;
}
RsFileData *RsFileItemSerialiser::deserialiseData(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) ||
(RS_PKT_CLASS_BASE != getRsItemClass(rstype)) ||
(RS_PKT_TYPE_FILE != getRsItemType(rstype)) ||
(RS_PKT_SUBTYPE_FI_DATA != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
if (*pktsize < rssize) /* check size */
return NULL; /* not enough data */
/* set the packet length */
*pktsize = rssize;
bool ok = true;
/* ready to load */
RsFileData *item = new RsFileData();
item->clear();
/* skip the header */
offset += 8;
/* get mandatory parts first */
ok &= item->fd.GetTlv(data, rssize, &offset);
if (offset != rssize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
return NULL;
}
return item;
}
/*************************************************************************/
/*************************************************************************/
uint32_t RsCacheItemSerialiser::size(RsItem *i)
{
RsCacheRequest *rfr;
RsCacheItem *rfi;
if (NULL != (rfr = dynamic_cast<RsCacheRequest *>(i)))
{
return sizeReq(rfr);
}
else if (NULL != (rfi = dynamic_cast<RsCacheItem *>(i)))
{
return sizeItem(rfi);
}
return 0;
}
/* serialise the data to the buffer */
bool RsCacheItemSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
{
RsCacheRequest *rfr;
RsCacheItem *rfi;
if (NULL != (rfr = dynamic_cast<RsCacheRequest *>(i)))
{
return serialiseReq(rfr, data, pktsize);
}
else if (NULL != (rfi = dynamic_cast<RsCacheItem *>(i)))
{
return serialiseItem(rfi, data, pktsize);
}
return false;
}
RsItem *RsCacheItemSerialiser::deserialise(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) ||
(RS_PKT_CLASS_BASE != getRsItemClass(rstype)) ||
(RS_PKT_TYPE_CACHE != getRsItemType(rstype)))
{
return NULL; /* wrong type */
}
switch(getRsItemSubType(rstype))
{
case RS_PKT_SUBTYPE_CACHE_REQUEST:
return deserialiseReq(data, pktsize);
break;
case RS_PKT_SUBTYPE_CACHE_ITEM:
return deserialiseItem(data, pktsize);
break;
default:
return NULL;
break;
}
return NULL;
}
/*************************************************************************/
RsCacheRequest::~RsCacheRequest()
{
return;
}
void RsCacheRequest::clear()
{
cacheType = 0;
cacheSubId = 0;
file.TlvClear();
}
std::ostream &RsCacheRequest::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsCacheRequest", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "CacheId: " << cacheType << "/" << cacheSubId << std::endl;
file.print(out, int_Indent);
printRsItemEnd(out, "RsCacheRequest", indent);
return out;
}
uint32_t RsCacheItemSerialiser::sizeReq(RsCacheRequest *item)
{
uint32_t s = 8; /* header */
s += 4; /* type/subid */
s += item->file.TlvSize();
return s;
}
/* serialise the data to the buffer */
bool RsCacheItemSerialiser::serialiseReq(RsCacheRequest *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeReq(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
std::cerr << "RsCacheItemSerialiser::serialiseReq() Header: " << ok << std::endl;
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt16(data, tlvsize, &offset, item->cacheType);
std::cerr << "RsCacheItemSerialiser::serialiseReq() cacheType: " << ok << std::endl;
ok &= setRawUInt16(data, tlvsize, &offset, item->cacheSubId);
std::cerr << "RsCacheItemSerialiser::serialiseReq() cacheSubId: " << ok << std::endl;
ok &= item->file.SetTlv(data, tlvsize, &offset);
std::cerr << "RsCacheItemSerialiser::serialiseReq() FileItem: " << ok << std::endl;
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsFileItemSerialiser::serialiseReq() Size Error! " << std::endl;
}
return ok;
}
RsCacheRequest *RsCacheItemSerialiser::deserialiseReq(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) ||
(RS_PKT_CLASS_BASE != getRsItemClass(rstype)) ||
(RS_PKT_TYPE_CACHE != getRsItemType(rstype)) ||
(RS_PKT_SUBTYPE_CACHE_REQUEST != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
if (*pktsize < rssize) /* check size */
return NULL; /* not enough data */
/* set the packet length */
*pktsize = rssize;
bool ok = true;
/* ready to load */
RsCacheRequest *item = new RsCacheRequest();
item->clear();
/* skip the header */
offset += 8;
/* get mandatory parts first */
ok &= getRawUInt16(data, rssize, &offset, &(item->cacheType));
ok &= getRawUInt16(data, rssize, &offset, &(item->cacheSubId));
ok &= item->file.GetTlv(data, rssize, &offset);
if (offset != rssize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
return NULL;
}
return item;
}
/*************************************************************************/
RsCacheItem::~RsCacheItem()
{
return;
}
void RsCacheItem::clear()
{
cacheType = 0;
cacheSubId = 0;
file.TlvClear();
}
std::ostream &RsCacheItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsCacheItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "CacheId: " << cacheType << "/" << cacheSubId << std::endl;
file.print(out, int_Indent);
printRsItemEnd(out, "RsCacheItem", indent);
return out;
}
uint32_t RsCacheItemSerialiser::sizeItem(RsCacheItem *item)
{
uint32_t s = 8; /* header */
s += 4; /* type/subid */
s += item->file.TlvSize();
return s;
}
/* serialise the data to the buffer */
bool RsCacheItemSerialiser::serialiseItem(RsCacheItem *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeItem(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
std::cerr << "RsCacheItemSerialiser::serialiseItem() Header: " << ok << std::endl;
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt16(data, tlvsize, &offset, item->cacheType);
std::cerr << "RsCacheItemSerialiser::serialiseItem() cacheType: " << ok << std::endl;
ok &= setRawUInt16(data, tlvsize, &offset, item->cacheSubId);
std::cerr << "RsCacheItemSerialiser::serialiseItem() cacheSubId: " << ok << std::endl;
ok &= item->file.SetTlv(data, tlvsize, &offset);
std::cerr << "RsCacheItemSerialiser::serialiseItem() FileItem: " << ok << std::endl;
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsFileItemSerialiser::serialiseItem() Size Error! " << std::endl;
}
return ok;
}
RsCacheItem *RsCacheItemSerialiser::deserialiseItem(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) ||
(RS_PKT_CLASS_BASE != getRsItemClass(rstype)) ||
(RS_PKT_TYPE_CACHE != getRsItemType(rstype)) ||
(RS_PKT_SUBTYPE_CACHE_ITEM != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
if (*pktsize < rssize) /* check size */
return NULL; /* not enough data */
/* set the packet length */
*pktsize = rssize;
bool ok = true;
/* ready to load */
RsCacheItem *item = new RsCacheItem();
item->clear();
/* skip the header */
offset += 8;
/* get mandatory parts first */
ok &= getRawUInt16(data, rssize, &offset, &(item->cacheType));
ok &= getRawUInt16(data, rssize, &offset, &(item->cacheSubId));
ok &= item->file.GetTlv(data, rssize, &offset);
if (offset != rssize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
return NULL;
}
return item;
}
/*************************************************************************/
/*************************************************************************/
uint32_t RsServiceSerialiser::size(RsItem *i)
{
RsRawItem *item = dynamic_cast<RsRawItem *>(i);
if (item)
{
return item->getRawLength();
}
return 0;
}
/* serialise the data to the buffer */
bool RsServiceSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
{
RsRawItem *item = dynamic_cast<RsRawItem *>(i);
if (!item)
{
return false;
}
uint32_t tlvsize = item->getRawLength();
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
if (tlvsize > getRsPktMaxSize())
return false; /* packet too big */
*pktsize = tlvsize;
/* its serialised already!!! */
memcpy(data, item->getRawData(), tlvsize);
return true;
}
RsItem *RsServiceSerialiser::deserialise(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
if (RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype))
{
return NULL; /* wrong type */
}
if (*pktsize < rssize) /* check size */
return NULL; /* not enough data */
if (rssize > getRsPktMaxSize())
return NULL; /* packet too big */
/* set the packet length */
*pktsize = rssize;
RsRawItem *item = new RsRawItem(rstype, rssize);
void *item_data = item->getRawData();
memcpy(item_data, data, rssize);
return item;
}

View File

@ -31,42 +31,35 @@
#include "serialiser/rsserial.h"
#include "serialiser/rstlvtypes.h"
const uint8_t RS_PKT_TYPE_FILE_ITEM = 0x01;
const uint8_t RS_PKT_TYPE_FILE_DATA = 0x02;
const uint8_t RS_PKT_TYPE_CHAT = 0x03;
const uint8_t RS_PKT_TYPE_MESSAGE = 0x04;
const uint8_t RS_PKT_TYPE_STATUS = 0x05;
const uint8_t RS_PKT_TYPE_FILE = 0x01;
const uint8_t RS_PKT_TYPE_CACHE = 0x02;
const uint8_t RS_PKT_SUBTYPE_FI_REQUEST = 0x01;
const uint8_t RS_PKT_SUBTYPE_FI_DATA = 0x02;
const uint8_t RS_PKT_SUBTYPE_FI_TRANSFER = 0x03;
const uint8_t RS_PKT_SUBTYPE_CACHE_ITEM = 0x01;
const uint8_t RS_PKT_SUBTYPE_CACHE_REQUEST = 0x02;
/**************************************************************************/
class RsFileItem: public RsItem
class RsFileRequest: public RsItem
{
public:
RsFileItem()
RsFileRequest()
:RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_BASE,
RS_PKT_TYPE_FILE_ITEM, 0)
RS_PKT_TYPE_FILE,
RS_PKT_SUBTYPE_FI_REQUEST)
{ return; }
virtual ~RsFileItem();
virtual ~RsFileRequest();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
uint32_t reqType; /* a request / result etc */
uint64_t fileoffset; /* start of data requested */
uint32_t chunksize; /* size of data requested */
RsTlvFileItem file; /* file information */
};
class RsFileItemSerialiser: public RsSerialType
{
public:
RsFileItemSerialiser()
:RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_BASE,
RS_PKT_TYPE_FILE_ITEM)
{ return; }
virtual ~RsFileItemSerialiser() { return; }
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
};
/**************************************************************************/
class RsFileData: public RsItem
@ -74,98 +67,120 @@ class RsFileData: public RsItem
public:
RsFileData()
:RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_BASE,
RS_PKT_TYPE_FILE_DATA, 0)
RS_PKT_TYPE_FILE,
RS_PKT_SUBTYPE_FI_DATA)
{ return; }
virtual ~RsFileData();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
RsTlvFileItem file;
RsTlvFileData data;
RsTlvFileData fd;
};
class RsFileDataSerialiser: public RsSerialType
/**************************************************************************/
class RsFileItemSerialiser: public RsSerialType
{
public:
RsFileDataSerialiser()
RsFileItemSerialiser()
:RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_BASE,
RS_PKT_TYPE_FILE_DATA)
RS_PKT_TYPE_FILE)
{ return; }
virtual ~RsFileDataSerialiser() { return; }
virtual ~RsFileItemSerialiser() { return; }
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
private:
/* sub types */
virtual uint32_t sizeReq(RsFileRequest *);
virtual bool serialiseReq (RsFileRequest *item, void *data, uint32_t *size);
virtual RsFileRequest * deserialiseReq(void *data, uint32_t *size);
virtual uint32_t sizeData(RsFileData *);
virtual bool serialiseData (RsFileData *item, void *data, uint32_t *size);
virtual RsFileData * deserialiseData(void *data, uint32_t *size);
};
/**************************************************************************/
class RsChatItem: public RsItem
class RsCacheRequest: public RsItem
{
public:
RsChatItem()
RsCacheRequest()
:RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_BASE,
RS_PKT_TYPE_CHAT, 0)
RS_PKT_TYPE_CACHE,
RS_PKT_SUBTYPE_CACHE_REQUEST)
{ return; }
virtual ~RsChatItem();
virtual ~RsCacheRequest();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
uint32_t chatFlags;
uint32_t sendTime;
std::string message;
};
class RsChatItemSerialiser: public RsSerialType
{
public:
RsChatItemSerialiser()
:RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_BASE,
RS_PKT_TYPE_CHAT)
{ return; }
virtual ~RsChatItemSerialiser();
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
uint16_t cacheType;
uint16_t cacheSubId;
RsTlvFileItem file; /* file information */
};
/**************************************************************************/
class RsMessageItem: public RsItem
class RsCacheItem: public RsItem
{
public:
RsMessageItem()
RsCacheItem()
:RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_BASE,
RS_PKT_TYPE_MESSAGE, 0)
RS_PKT_TYPE_CACHE,
RS_PKT_SUBTYPE_CACHE_ITEM)
{ return; }
virtual ~RsMessageItem();
virtual ~RsCacheItem();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
uint32_t msgFlags;
uint32_t sendTime;
uint32_t recvTime;
std::string subject;
std::string message;
RsTlvPeerIdSet msgto;
RsTlvPeerIdSet msgcc;
RsTlvPeerIdSet msgbcc;
RsTlvFileSet attachment;
uint16_t cacheType;
uint16_t cacheSubId;
RsTlvFileItem file; /* file information */
};
class RsMessageItemSerialiser: public RsSerialType
/**************************************************************************/
class RsCacheItemSerialiser: public RsSerialType
{
public:
RsMessageItemSerialiser()
RsCacheItemSerialiser()
:RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_BASE,
RS_PKT_TYPE_MESSAGE)
RS_PKT_TYPE_CACHE)
{ return; }
virtual ~RsCacheItemSerialiser() { return; }
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
private:
/* sub types */
virtual uint32_t sizeReq(RsCacheRequest *);
virtual bool serialiseReq (RsCacheRequest *item, void *data, uint32_t *size);
virtual RsCacheRequest * deserialiseReq(void *data, uint32_t *size);
virtual uint32_t sizeItem(RsCacheItem *);
virtual bool serialiseItem (RsCacheItem *item, void *data, uint32_t *size);
virtual RsCacheItem * deserialiseItem(void *data, uint32_t *size);
};
/**************************************************************************/
class RsServiceSerialiser: public RsSerialType
{
public:
RsServiceSerialiser()
:RsSerialType(RS_PKT_VERSION_SERVICE, 0, 0)
{ return; }
virtual ~RsServiceSerialiser()
{ return; }
virtual ~RsMessageItemSerialiser();
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
@ -175,42 +190,5 @@ virtual RsItem * deserialise(void *data, uint32_t *size);
/**************************************************************************/
class RsStatus: public RsItem
{
public:
RsStatus()
:RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_BASE,
RS_PKT_TYPE_STATUS, 0)
{ return; }
virtual ~RsStatus();
virtual void clear();
/* status */
uint32_t status;
RsTlvServiceIdSet services;
};
class RsStatusSerialiser: public RsSerialType
{
public:
RsStatusSerialiser()
:RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_BASE,
RS_PKT_TYPE_STATUS)
{ return; }
virtual ~RsStatusSerialiser();
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
};
/**************************************************************************/
/**************************************************************************/
/* BELOW HERE to be fully defined */
/**************************************************************************/
#endif

View File

@ -28,6 +28,46 @@
#include "serialiser/rsbaseserial.h"
/* UInt16 get/set */
bool getRawUInt16(void *data, uint32_t size, uint32_t *offset, uint16_t *out)
{
/* first check there is space */
if (size < *offset + 2)
{
return false;
}
void *buf = (void *) &(((uint8_t *) data)[*offset]);
/* extract the data */
uint16_t netorder_num;
memcpy(&netorder_num, buf, sizeof(uint16_t));
(*out) = ntohs(netorder_num);
(*offset) += 2;
return true;
}
bool setRawUInt16(void *data, uint32_t size, uint32_t *offset, uint16_t in)
{
/* first check there is space */
if (size < *offset + 2)
{
return false;
}
void *buf = (void *) &(((uint8_t *) data)[*offset]);
/* convert the data to the right format */
uint16_t netorder_num = htons(in);
/* pack it in */
memcpy(buf, &netorder_num, sizeof(uint16_t));
(*offset) += 2;
return true;
}
/* UInt32 get/set */
bool getRawUInt32(void *data, uint32_t size, uint32_t *offset, uint32_t *out)
@ -68,9 +108,47 @@ bool setRawUInt32(void *data, uint32_t size, uint32_t *offset, uint32_t in)
return true;
}
/* UInt64 get/set */
bool getRawUInt64(void *data, uint32_t size, uint32_t *offset, uint64_t *out)
{
/* first check there is space */
if (size < *offset + 8)
{
return false;
}
void *buf = (void *) &(((uint8_t *) data)[*offset]);
/* extract the data */
uint64_t netorder_num;
memcpy(&netorder_num, buf, sizeof(uint64_t));
//(*out) = ntohll(netorder_num);
(*out) = netorder_num;
(*offset) += 8;
return true;
}
bool setRawUInt64(void *data, uint32_t size, uint32_t *offset, uint64_t in)
{
/* first check there is space */
if (size < *offset + 8)
{
return false;
}
void *buf = (void *) &(((uint8_t *) data)[*offset]);
/* convert the data to the right format */
//uint64_t netorder_num = htonll(in);
uint64_t netorder_num = in;
/* pack it in */
memcpy(buf, &netorder_num, sizeof(uint64_t));
(*offset) += 8;
return true;
}

View File

@ -46,8 +46,14 @@
******************************************************************/
bool getRawUInt16(void *data, uint32_t size, uint32_t *offset, uint16_t *out);
bool setRawUInt16(void *data, uint32_t size, uint32_t *offset, uint16_t in);
bool getRawUInt32(void *data, uint32_t size, uint32_t *offset, uint32_t *out);
bool setRawUInt32(void *data, uint32_t size, uint32_t *offset, uint32_t in);
bool getRawUInt64(void *data, uint32_t size, uint32_t *offset, uint64_t *out);
bool setRawUInt64(void *data, uint32_t size, uint32_t *offset, uint64_t in);
#endif

View File

@ -0,0 +1,287 @@
/*
* libretroshare/src/serialiser: rsconfigitems.cc
*
* RetroShare Serialiser.
*
* Copyright 2007-2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "serialiser/rsbaseserial.h"
#include "serialiser/rsconfigitems.h"
#define RSSERIAL_DEBUG 1
#include <iostream>
/*************************************************************************/
uint32_t RsFileTransferSerialiser::size(RsItem *i)
{
RsFileTransfer *rft;
if (NULL != (rft = dynamic_cast<RsFileTransfer *>(i)))
{
return sizeTransfer(rft);
}
return 0;
}
/* serialise the data to the buffer */
bool RsFileTransferSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
{
RsFileTransfer *rft;
if (NULL != (rft = dynamic_cast<RsFileTransfer *>(i)))
{
return serialiseTransfer(rft, data, pktsize);
}
return false;
}
RsItem *RsFileTransferSerialiser::deserialise(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) ||
(RS_PKT_CLASS_CONFIG != getRsItemClass(rstype)) ||
(RS_PKT_TYPE_FILE_CONFIG != getRsItemType(rstype)))
{
return NULL; /* wrong type */
}
switch(getRsItemSubType(rstype))
{
case RS_PKT_SUBTYPE_DEFAULT:
return deserialiseTransfer(data, pktsize);
break;
default:
return NULL;
break;
}
return NULL;
}
/*************************************************************************/
RsFileTransfer::~RsFileTransfer()
{
return;
}
void RsFileTransfer::clear()
{
file.TlvClear();
allPeerIds.TlvClear();
cPeerId = "";
state = 0;
in = false;
transferred = 0;
crate = 0;
trate = 0;
lrate = 0;
ltransfer = 0;
}
std::ostream &RsFileTransfer::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsFileTransfer", indent);
uint16_t int_Indent = indent + 2;
file.print(out, int_Indent);
allPeerIds.print(out, int_Indent);
printIndent(out, int_Indent);
out << "cPeerId: " << cPeerId << std::endl;
printIndent(out, int_Indent);
out << "State: " << state << std::endl;
printIndent(out, int_Indent);
out << "In/Out: " << in << std::endl;
printIndent(out, int_Indent);
out << "Transferred: " << transferred << std::endl;
printIndent(out, int_Indent);
out << "crate: " << crate << std::endl;
printIndent(out, int_Indent);
out << "trate: " << trate << std::endl;
printIndent(out, int_Indent);
out << "lrate: " << lrate << std::endl;
printIndent(out, int_Indent);
out << "ltransfer: " << ltransfer << std::endl;
printRsItemEnd(out, "RsFileTransfer", indent);
return out;
}
uint32_t RsFileTransferSerialiser::sizeTransfer(RsFileTransfer *item)
{
uint32_t s = 8; /* header */
s += item->file.TlvSize();
s += item->allPeerIds.TlvSize();
s += GetTlvStringSize(item->cPeerId);
s += 2; /* state */
s += 2; /* in/out */
s += 8; /* transferred */
s += 4; /* crate */
s += 4; /* trate */
s += 4; /* lrate */
s += 4; /* ltransfer */
return s;
}
bool RsFileTransferSerialiser::serialiseTransfer(RsFileTransfer *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeTransfer(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() Header: " << ok << std::endl;
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() Size: " << tlvsize << std::endl;
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= item->file.SetTlv(data, tlvsize, &offset);
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() FileItem: " << ok << std::endl;
ok &= item->allPeerIds.SetTlv(data, tlvsize, &offset);
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() allPeerIds: " << ok << std::endl;
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_PEERID, item->cPeerId);
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() cId: " << ok << std::endl;
ok &= setRawUInt16(data, tlvsize, &offset, item->state);
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() State: " << ok << std::endl;
ok &= setRawUInt16(data, tlvsize, &offset, item->in);
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() In/Out: " << ok << std::endl;
ok &= setRawUInt64(data, tlvsize, &offset, item->transferred);
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() Transferred: " << ok << std::endl;
ok &= setRawUInt32(data, tlvsize, &offset, item->crate);
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() crate: " << ok << std::endl;
ok &= setRawUInt32(data, tlvsize, &offset, item->trate);
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() trate: " << ok << std::endl;
ok &= setRawUInt32(data, tlvsize, &offset, item->lrate);
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() lrate: " << ok << std::endl;
ok &= setRawUInt32(data, tlvsize, &offset, item->ltransfer);
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() ltransfer: " << ok << std::endl;
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() Size Error! " << std::endl;
}
return ok;
}
RsFileTransfer *RsFileTransferSerialiser::deserialiseTransfer(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION1 != getRsItemVersion(rstype)) ||
(RS_PKT_CLASS_CONFIG != getRsItemClass(rstype)) ||
(RS_PKT_TYPE_FILE_CONFIG != getRsItemType(rstype)) ||
(RS_PKT_SUBTYPE_DEFAULT != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
if (*pktsize < rssize) /* check size */
return NULL; /* not enough data */
/* set the packet length */
*pktsize = rssize;
bool ok = true;
/* ready to load */
RsFileTransfer *item = new RsFileTransfer();
item->clear();
/* skip the header */
offset += 8;
/* get mandatory parts first */
ok &= item->file.GetTlv(data, rssize, &offset);
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() FileItem: " << ok << std::endl;
ok &= item->allPeerIds.GetTlv(data, rssize, &offset);
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() allPeerIds: " << ok << std::endl;
/* string */
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_PEERID, item->cPeerId);
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() cId: " << ok << std::endl;
/* data */
ok &= getRawUInt16(data, rssize, &offset, &(item->state));
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() State: " << ok << std::endl;
ok &= getRawUInt16(data, rssize, &offset, &(item->in));
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() In/Out: " << ok << std::endl;
ok &= getRawUInt64(data, rssize, &offset, &(item->transferred));
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() Transferred: " << ok << std::endl;
ok &= getRawUInt32(data, rssize, &offset, &(item->crate));
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() crate: " << ok << std::endl;
ok &= getRawUInt32(data, rssize, &offset, &(item->trate));
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() trate: " << ok << std::endl;
ok &= getRawUInt32(data, rssize, &offset, &(item->lrate));
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() lrate: " << ok << std::endl;
ok &= getRawUInt32(data, rssize, &offset, &(item->ltransfer));
std::cerr << "RsFileTransferSerialiser::serialiseTransfer() ltransfer: " << ok << std::endl;
if (offset != rssize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
return NULL;
}
return item;
}
/*************************************************************************/

View File

@ -28,8 +28,13 @@
#include <map>
#include "serialiser/rsserial.h"
#include "serialiser/rstlvbase.h"
#include "serialiser/rstlvtypes.h"
const uint8_t RS_PKT_TYPE_PEER_CONFIG = 0x01;
const uint8_t RS_PKT_TYPE_CACHE_CONFIG = 0x02;
const uint8_t RS_PKT_TYPE_FILE_CONFIG = 0x03;
/**************************************************************************/
@ -38,17 +43,19 @@ class RsPeerConfig: public RsItem
public:
RsPeerConfig()
:RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG,
RS_PKT_TYPE_PEER_CONFIG, 0)
RS_PKT_TYPE_PEER_CONFIG,
RS_PKT_SUBTYPE_DEFAULT)
{ return; }
virtual ~RsPeerConfig();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
RsTlvPeerId peerid; /* Mandatory */
RsTlvPeerFingerprint fpr; /* Mandatory */
//RsTlvPeerId peerid; /* Mandatory */
//RsTlvPeerFingerprint fpr; /* Mandatory */
struct sockaddr_in lastaddr; /* Mandatory */
struct sockaddr_in localaddr; /* Mandatory */
struct sockaddr_in serveraddr; /* Mandatory */
//struct sockaddr_in lastaddr; /* Mandatory */
//struct sockaddr_in localaddr; /* Mandatory */
//struct sockaddr_in serveraddr; /* Mandatory */
uint32_t status; /* Mandatory */
@ -82,12 +89,14 @@ class RsCacheConfig: public RsItem
public:
RsCacheConfig()
:RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG,
RS_PKT_TYPE_CACHE_CONFIG, 0)
RS_PKT_TYPE_CACHE_CONFIG,
RS_PKT_SUBTYPE_DEFAULT)
{ return; }
virtual ~RsCacheConfig();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
RsTlvPeerId peerid; /* Mandatory */
//RsTlvPeerId peerid; /* Mandatory */
uint32_t cacheid; /* Mandatory */
std::string path; /* Mandatory */
@ -116,4 +125,65 @@ virtual RsItem * deserialise(void *data, uint32_t *size);
/**************************************************************************/
#define FT_STATE_FAILED 0
#define FT_STATE_OKAY 1
#define FT_STATE_WAITING 2
#define FT_STATE_DOWNLOADING 3
#define FT_STATE_COMPLETE 4
class RsFileTransfer: public RsItem
{
public:
RsFileTransfer()
:RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG,
RS_PKT_TYPE_FILE_CONFIG,
RS_PKT_SUBTYPE_DEFAULT)
{ return; }
virtual ~RsFileTransfer();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
RsTlvFileItem file;
RsTlvPeerIdSet allPeerIds;
std::string cPeerId;
uint16_t state;
uint16_t in;
uint64_t transferred;
uint32_t crate;
uint32_t trate;
uint32_t lrate;
uint32_t ltransfer;
};
/**************************************************************************/
class RsFileTransferSerialiser: public RsSerialType
{
public:
RsFileTransferSerialiser()
:RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_CONFIG,
RS_PKT_TYPE_FILE_CONFIG)
{ return; }
virtual ~RsFileTransferSerialiser() { return; }
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
private:
virtual uint32_t sizeTransfer(RsFileTransfer *);
virtual bool serialiseTransfer(RsFileTransfer *item, void *data, uint32_t *size);
virtual RsFileTransfer * deserialiseTransfer(void *data, uint32_t *size);
};
/**************************************************************************/
#endif /* RS_CONFIG_ITEMS_SERIALISER_H */

View File

@ -0,0 +1,447 @@
/*
* libretroshare/src/serialiser: rsdiscitems.cc
*
* RetroShare Serialiser.
*
* Copyright 2007-2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "serialiser/rsbaseserial.h"
#include "serialiser/rsbaseserial.h"
#include "serialiser/rsserviceids.h"
#include "serialiser/rsdiscitems.h"
#include "serialiser/rstlvbase.h"
#include "serialiser/rstlvtypes.h"
#define RSSERIAL_DEBUG 1
#include <iostream>
/*************************************************************************/
uint32_t RsDiscSerialiser::size(RsItem *i)
{
RsDiscItem *rdi;
RsDiscReply *rdr;
/* do reply first - as it is derived from Item */
if (NULL != (rdr = dynamic_cast<RsDiscReply *>(i)))
{
return sizeReply(rdr);
}
else if (NULL != (rdi = dynamic_cast<RsDiscItem *>(i)))
{
return sizeItem(rdi);
}
return 0;
}
/* serialise the data to the buffer */
bool RsDiscSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
{
RsDiscItem *rdi;
RsDiscReply *rdr;
/* do reply first - as it is derived from Item */
if (NULL != (rdr = dynamic_cast<RsDiscReply *>(i)))
{
return serialiseReply(rdr, data, pktsize);
}
else if (NULL != (rdi = dynamic_cast<RsDiscItem *>(i)))
{
return serialiseItem(rdi, data, pktsize);
}
return false;
}
RsItem *RsDiscSerialiser::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_DISC != getRsItemService(rstype)))
{
std::cerr << "RsDiscSerialiser::deserialise() Wrong Type" << std::endl;
return NULL; /* wrong type */
}
switch(getRsItemSubType(rstype))
{
case RS_PKT_SUBTYPE_DISC_REPLY:
return deserialiseReply(data, pktsize);
break;
case RS_PKT_SUBTYPE_DISC_ITEM:
return deserialiseItem(data, pktsize);
break;
default:
return NULL;
break;
}
return NULL;
}
/*************************************************************************/
RsDiscItem::~RsDiscItem()
{
return;
}
void RsDiscItem::clear()
{
memset(&laddr, 0, sizeof(laddr));
memset(&saddr, 0, sizeof(laddr));
connect_tr = 0;
receive_tr = 0;
discFlags = 0;
}
std::ostream &RsDiscItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsDiscItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "Local Address: " << inet_ntoa(laddr.sin_addr);
out << " Port: " << ntohs(laddr.sin_port) << std::endl;
printIndent(out, int_Indent);
out << "Server Address: " << inet_ntoa(saddr.sin_addr);
out << " Port: " << ntohs(saddr.sin_port) << std::endl;
printIndent(out, int_Indent);
out << "C/R Tr: " << connect_tr;
out << " / " << receive_tr << std::endl;
printIndent(out, int_Indent);
out << "DiscFlags: " << discFlags << std::endl;
printRsItemEnd(out, "RsDiscItem", indent);
return out;
}
uint32_t RsDiscSerialiser::sizeItem(RsDiscItem *item)
{
uint32_t s = 8; /* header */
s += GetTlvIpAddrPortV4Size(); /* laddr */
s += GetTlvIpAddrPortV4Size(); /* saddr */
s += 2; /* connect_tr */
s += 2; /* receive_tr */
s += 4; /* discFlags */
return s;
}
/* serialise the data to the buffer */
bool RsDiscSerialiser::serialiseItem(RsDiscItem *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeItem(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
std::cerr << "RsDiscSerialiser::serialiseItem() Header: " << ok << std::endl;
std::cerr << "RsDiscSerialiser::serialiseItem() Size: " << tlvsize << std::endl;
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= SetTlvIpAddrPortV4(data, tlvsize, &offset,
TLV_TYPE_IPV4_LOCAL, &(item->laddr));
std::cerr << "RsDiscSerialiser::serialiseItem() laddress: " << ok << std::endl;
ok &= SetTlvIpAddrPortV4(data, tlvsize, &offset,
TLV_TYPE_IPV4_SERVER, &(item->saddr));
std::cerr << "RsDiscSerialiser::serialiseItem() saddress: " << ok << std::endl;
ok &= setRawUInt16(data, tlvsize, &offset, item->connect_tr);
std::cerr << "RsDiscSerialiser::serialiseItem() connect_tr: " << ok << std::endl;
ok &= setRawUInt16(data, tlvsize, &offset, item->receive_tr);
std::cerr << "RsDiscSerialiser::serialiseItem() receive_tr: " << ok << std::endl;
ok &= setRawUInt32(data, tlvsize, &offset, item->discFlags);
std::cerr << "RsDiscSerialiser::serialiseItem() discFlags: " << ok << std::endl;
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsDiscSerialiser::serialiseItem() Size Error! " << std::endl;
}
return ok;
}
RsDiscItem *RsDiscSerialiser::deserialiseItem(void *data, uint32_t *pktsize)
{
/* 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_DISC != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_DISC_ITEM != getRsItemSubType(rstype)))
{
std::cerr << "RsDiscSerialiser::deserialiseItem() Wrong Type" << std::endl;
return NULL; /* wrong type */
}
if (*pktsize < rssize) /* check size */
{
std::cerr << "RsDiscSerialiser::deserialiseItem() Not Enough Space" << std::endl;
return NULL; /* not enough data */
}
/* set the packet length */
*pktsize = rssize;
bool ok = true;
/* ready to load */
RsDiscItem *item = new RsDiscItem();
item->clear();
/* skip the header */
offset += 8;
/* get mandatory parts first */
ok &= GetTlvIpAddrPortV4(data, rssize, &offset,
TLV_TYPE_IPV4_LOCAL, &(item->laddr));
std::cerr << "RsDiscSerialiser::deserialiseItem() laddress: " << ok << std::endl;
ok &= GetTlvIpAddrPortV4(data, rssize, &offset,
TLV_TYPE_IPV4_SERVER, &(item->saddr));
std::cerr << "RsDiscSerialiser::deserialiseItem() saddress: " << ok << std::endl;
ok &= getRawUInt16(data, rssize, &offset, &(item->connect_tr));
std::cerr << "RsDiscSerialiser::deserialiseItem() connect_tr: " << ok << std::endl;
ok &= getRawUInt16(data, rssize, &offset, &(item->receive_tr));
std::cerr << "RsDiscSerialiser::deserialiseItem() receive_tr: " << ok << std::endl;
ok &= getRawUInt32(data, rssize, &offset, &(item->discFlags));
std::cerr << "RsDiscSerialiser::deserialiseItem() discFlags: " << ok << std::endl;
if (offset != rssize)
{
std::cerr << "RsDiscSerialiser::deserialiseItem() offset != rssize" << std::endl;
/* error */
delete item;
return NULL;
}
if (!ok)
{
std::cerr << "RsDiscSerialiser::deserialiseItem() ok = false" << std::endl;
delete item;
return NULL;
}
return item;
}
/*************************************************************************/
RsDiscReply::~RsDiscReply()
{
return;
}
void RsDiscReply::clear()
{
memset(&laddr, 0, sizeof(laddr));
memset(&saddr, 0, sizeof(laddr));
connect_tr = 0;
receive_tr = 0;
discFlags = 0;
certDER.TlvClear();
}
std::ostream &RsDiscReply::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsDiscReply", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "Local Address: " << inet_ntoa(laddr.sin_addr);
out << " Port: " << ntohs(laddr.sin_port) << std::endl;
printIndent(out, int_Indent);
out << "Server Address: " << inet_ntoa(saddr.sin_addr);
out << " Port: " << ntohs(saddr.sin_port) << std::endl;
printIndent(out, int_Indent);
out << "C/R Tr: " << connect_tr;
out << " / " << receive_tr << std::endl;
printIndent(out, int_Indent);
out << "DiscFlags: " << discFlags << std::endl;
certDER.print(out, int_Indent);
printRsItemEnd(out, "RsDiscReply", indent);
return out;
}
uint32_t RsDiscSerialiser::sizeReply(RsDiscReply *item)
{
uint32_t s = 8; /* header */
s += GetTlvIpAddrPortV4Size(); /* laddr */
s += GetTlvIpAddrPortV4Size(); /* saddr */
s += 2; /* connect_tr */
s += 2; /* receive_tr */
s += 4; /* discFlags */
s += item->certDER.TlvSize();
return s;
}
/* serialise the data to the buffer */
bool RsDiscSerialiser::serialiseReply(RsDiscReply *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeReply(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
std::cerr << "RsDiscSerialiser::serialiseReply() Header: " << ok << std::endl;
std::cerr << "RsDiscSerialiser::serialiseReply() Size: " << tlvsize << std::endl;
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= SetTlvIpAddrPortV4(data, tlvsize, &offset,
TLV_TYPE_IPV4_LOCAL, &(item->laddr));
std::cerr << "RsDiscSerialiser::serialiseReply() laddress: " << ok << std::endl;
ok &= SetTlvIpAddrPortV4(data, tlvsize, &offset,
TLV_TYPE_IPV4_SERVER, &(item->saddr));
std::cerr << "RsDiscSerialiser::serialiseReply() saddress: " << ok << std::endl;
ok &= setRawUInt16(data, tlvsize, &offset, item->connect_tr);
std::cerr << "RsDiscSerialiser::serialiseReply() connect_tr: " << ok << std::endl;
ok &= setRawUInt16(data, tlvsize, &offset, item->receive_tr);
std::cerr << "RsDiscSerialiser::serialiseReply() receive_tr: " << ok << std::endl;
ok &= setRawUInt32(data, tlvsize, &offset, item->discFlags);
std::cerr << "RsDiscSerialiser::serialiseReply() discFlags: " << ok << std::endl;
ok &= item->certDER.SetTlv(data, tlvsize, &offset);
std::cerr << "RsDiscSerialiser::serialiseReply() discFlags: " << ok << std::endl;
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsDiscSerialiser::serialiseReply() Size Error! " << std::endl;
}
return ok;
}
RsDiscReply *RsDiscSerialiser::deserialiseReply(void *data, uint32_t *pktsize)
{
/* 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_DISC != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_DISC_REPLY != getRsItemSubType(rstype)))
{
std::cerr << "RsDiscSerialiser::deserialiseReply() Wrong Type" << std::endl;
return NULL; /* wrong type */
}
if (*pktsize < rssize) /* check size */
{
std::cerr << "RsDiscSerialiser::deserialiseReply() pktsize != rssize" << std::endl;
return NULL; /* not enough data */
}
/* set the packet length */
*pktsize = rssize;
bool ok = true;
/* ready to load */
RsDiscReply *item = new RsDiscReply();
item->clear();
/* skip the header */
offset += 8;
/* get mandatory parts first */
ok &= GetTlvIpAddrPortV4(data, rssize, &offset,
TLV_TYPE_IPV4_LOCAL, &(item->laddr));
std::cerr << "RsDiscSerialiser::deserialiseReply() laddress: " << ok << std::endl;
ok &= GetTlvIpAddrPortV4(data, rssize, &offset,
TLV_TYPE_IPV4_SERVER, &(item->saddr));
std::cerr << "RsDiscSerialiser::deserialiseReply() saddress: " << ok << std::endl;
ok &= getRawUInt16(data, rssize, &offset, &(item->connect_tr));
std::cerr << "RsDiscSerialiser::deserialiseReply() connect_tr: " << ok << std::endl;
ok &= getRawUInt16(data, rssize, &offset, &(item->receive_tr));
std::cerr << "RsDiscSerialiser::deserialiseReply() receive_tr: " << ok << std::endl;
ok &= getRawUInt32(data, rssize, &offset, &(item->discFlags));
std::cerr << "RsDiscSerialiser::deserialiseReply() discFlags: " << ok << std::endl;
ok &= item->certDER.GetTlv(data, rssize, &offset);
std::cerr << "RsDiscSerialiser::deserialiseReply() certDER: " << ok << std::endl;
if (offset != rssize)
{
std::cerr << "RsDiscSerialiser::deserialiseReply() offset != rssize" << std::endl;
/* error */
delete item;
return NULL;
}
if (!ok)
{
std::cerr << "RsDiscSerialiser::deserialiseReply() ok = false" << std::endl;
delete item;
return NULL;
}
return item;
}
/*************************************************************************/

View File

@ -0,0 +1,113 @@
/*
* libretroshare/src/serialiser: rsdiscitems.h
*
* Serialiser for RetroShare.
*
* Copyright 2004-2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef RS_DISC_ITEMS_H
#define RS_DISC_ITEMS_H
#include "serialiser/rsserial.h"
#include "serialiser/rstlvbase.h"
#include "serialiser/rstlvtypes.h"
#include "serialiser/rsserviceids.h"
const uint8_t RS_PKT_SUBTYPE_DISC_ITEM = 0x01;
const uint8_t RS_PKT_SUBTYPE_DISC_REPLY = 0x02;
class RsDiscItem: public RsItem
{
protected:
RsDiscItem(uint8_t subtype)
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DISC,
subtype)
{ return; }
public:
RsDiscItem()
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DISC,
RS_PKT_SUBTYPE_DISC_ITEM)
{ return; }
virtual ~RsDiscItem();
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent = 0);
struct sockaddr_in laddr;
struct sockaddr_in saddr;
// time frame of recent connections.
uint16_t connect_tr;
uint16_t receive_tr;
// flags...
uint32_t discFlags;
};
class RsDiscReply: public RsDiscItem
{
public:
RsDiscReply()
:RsDiscItem(RS_PKT_SUBTYPE_DISC_REPLY),
certDER(TLV_TYPE_CERT_XPGP_DER)
{ return; }
virtual ~RsDiscReply();
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent = 0);
RsTlvBinaryData certDER;
};
class RsDiscSerialiser: public RsSerialType
{
public:
RsDiscSerialiser()
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_DISC)
{ return; }
virtual ~RsDiscSerialiser() { return; }
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
private:
virtual uint32_t sizeItem(RsDiscItem *);
virtual bool serialiseItem (RsDiscItem *item, void *data, uint32_t *size);
virtual RsDiscItem *deserialiseItem(void *data, uint32_t *size);
virtual uint32_t sizeReply(RsDiscReply *);
virtual bool serialiseReply (RsDiscReply *item, void *data, uint32_t *size);
virtual RsDiscReply *deserialiseReply(void *data, uint32_t *size);
};
#endif // RS_DISC_ITEMS_H

View File

@ -0,0 +1,394 @@
/*
* libretroshare/src/serialiser: rsbaseitems.cc
*
* RetroShare Serialiser.
*
* Copyright 2007-2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "serialiser/rsbaseserial.h"
#include "serialiser/rsmsgitems.h"
#include "serialiser/rstlvbase.h"
#define RSSERIAL_DEBUG 1
#include <iostream>
/*************************************************************************/
RsChatItem::~RsChatItem()
{
return;
}
void RsChatItem::clear()
{
chatFlags = 0;
sendTime = 0;
message = "";
}
std::ostream &RsChatItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsChatItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "chatFlags: " << chatFlags << std::endl;
printIndent(out, int_Indent);
out << "sendTime: " << sendTime << std::endl;
printIndent(out, int_Indent);
out << "msg: " << message << std::endl;
printRsItemEnd(out, "RsChatItem", indent);
return out;
}
uint32_t RsChatSerialiser::sizeItem(RsChatItem *item)
{
uint32_t s = 8; /* header */
s += 4; /* chatFlags */
s += 4; /* sendTime */
s += GetTlvStringSize(item->message);
return s;
}
/* serialise the data to the buffer */
bool RsChatSerialiser::serialiseItem(RsChatItem *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeItem(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
std::cerr << "RsChatSerialiser::serialiseItem() Header: " << ok << std::endl;
std::cerr << "RsChatSerialiser::serialiseItem() Size: " << tlvsize << std::endl;
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, item->chatFlags);
std::cerr << "RsChatSerialiser::serialiseItem() chatFlags: " << ok << std::endl;
ok &= setRawUInt32(data, tlvsize, &offset, item->sendTime);
std::cerr << "RsChatSerialiser::serialiseItem() sendTime: " << ok << std::endl;
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_MSG, item->message);
std::cerr << "RsChatSerialiser::serialiseItem() Message: " << ok << std::endl;
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsChatSerialiser::serialiseItem() Size Error! " << std::endl;
}
return ok;
}
RsChatItem *RsChatSerialiser::deserialiseItem(void *data, uint32_t *pktsize)
{
/* 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_CHAT != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_DEFAULT != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
if (*pktsize < rssize) /* check size */
return NULL; /* not enough data */
/* set the packet length */
*pktsize = rssize;
bool ok = true;
/* ready to load */
RsChatItem *item = new RsChatItem();
item->clear();
/* skip the header */
offset += 8;
/* get mandatory parts first */
ok &= getRawUInt32(data, rssize, &offset, &(item->chatFlags));
ok &= getRawUInt32(data, rssize, &offset, &(item->sendTime));
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_MSG, item->message);
if (offset != rssize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
return NULL;
}
return item;
}
uint32_t RsChatSerialiser::size(RsItem *item)
{
return sizeItem((RsChatItem *) item);
}
bool RsChatSerialiser::serialise(RsItem *item, void *data, uint32_t *pktsize)
{
return serialiseItem((RsChatItem *) item, data, pktsize);
}
RsItem *RsChatSerialiser::deserialise(void *data, uint32_t *pktsize)
{
return deserialiseItem(data, pktsize);
}
/*************************************************************************/
RsMsgItem::~RsMsgItem()
{
return;
}
void RsMsgItem::clear()
{
msgId = 0;
msgFlags = 0;
sendTime = 0;
recvTime = 0;
subject = "";
message = "";
msgto.TlvClear();
msgcc.TlvClear();
msgbcc.TlvClear();
attachment.TlvClear();
}
std::ostream &RsMsgItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsMsgItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "msgId (not serialised): " << msgId << std::endl;
printIndent(out, int_Indent);
out << "msgFlags: " << msgFlags << std::endl;
printIndent(out, int_Indent);
out << "sendTime: " << sendTime << std::endl;
printIndent(out, int_Indent);
out << "recvTime: " << recvTime << std::endl;
printIndent(out, int_Indent);
out << "Message To: " << std::endl;
msgto.print(out, int_Indent);
printIndent(out, int_Indent);
out << "Message CC: " << std::endl;
msgcc.print(out, int_Indent);
printIndent(out, int_Indent);
out << "Message BCC: " << std::endl;
msgbcc.print(out, int_Indent);
printIndent(out, int_Indent);
out << "subject: " << subject << std::endl;
printIndent(out, int_Indent);
out << "msg: " << message << std::endl;
printIndent(out, int_Indent);
out << "Attachment: " << std::endl;
attachment.print(out, int_Indent);
printRsItemEnd(out, "RsMsgItem", indent);
return out;
}
uint32_t RsMsgSerialiser::sizeItem(RsMsgItem *item)
{
uint32_t s = 8; /* header */
s += 4; /* msgFlags */
s += 4; /* sendTime */
s += 4; /* recvTime */
s += GetTlvStringSize(item->subject);
s += GetTlvStringSize(item->message);
s += item->msgto.TlvSize();
s += item->msgcc.TlvSize();
s += item->msgbcc.TlvSize();
s += item->attachment.TlvSize();
return s;
}
/* serialise the data to the buffer */
bool RsMsgSerialiser::serialiseItem(RsMsgItem *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeItem(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
std::cerr << "RsMsgSerialiser::serialiseItem() Header: " << ok << std::endl;
std::cerr << "RsMsgSerialiser::serialiseItem() Size: " << tlvsize << std::endl;
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, item->msgFlags);
std::cerr << "RsMsgSerialiser::serialiseItem() msgFlags: " << ok << std::endl;
ok &= setRawUInt32(data, tlvsize, &offset, item->sendTime);
std::cerr << "RsMsgSerialiser::serialiseItem() sendTime: " << ok << std::endl;
ok &= setRawUInt32(data, tlvsize, &offset, item->recvTime);
std::cerr << "RsMsgSerialiser::serialiseItem() recvTime: " << ok << std::endl;
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_SUBJECT, item->subject);
std::cerr << "RsMsgSerialiser::serialiseItem() Subject: " << ok << std::endl;
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_MSG, item->message);
std::cerr << "RsMsgSerialiser::serialiseItem() Message: " << ok << std::endl;
ok &= item->msgto.SetTlv(data, tlvsize, &offset);
std::cerr << "RsMsgSerialiser::serialiseItem() MsgTo: " << ok << std::endl;
ok &= item->msgcc.SetTlv(data, tlvsize, &offset);
std::cerr << "RsMsgSerialiser::serialiseItem() MsgCC: " << ok << std::endl;
ok &= item->msgbcc.SetTlv(data, tlvsize, &offset);
std::cerr << "RsMsgSerialiser::serialiseItem() MsgBCC: " << ok << std::endl;
ok &= item->attachment.SetTlv(data, tlvsize, &offset);
std::cerr << "RsMsgSerialiser::serialiseItem() Attachment: " << ok << std::endl;
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsMsgSerialiser::serialiseItem() Size Error! " << std::endl;
}
return ok;
}
RsMsgItem *RsMsgSerialiser::deserialiseItem(void *data, uint32_t *pktsize)
{
/* 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_MSG != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_DEFAULT != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
if (*pktsize < rssize) /* check size */
return NULL; /* not enough data */
/* set the packet length */
*pktsize = rssize;
bool ok = true;
/* ready to load */
RsMsgItem *item = new RsMsgItem();
item->clear();
/* skip the header */
offset += 8;
/* get mandatory parts first */
ok &= getRawUInt32(data, rssize, &offset, &(item->msgFlags));
ok &= getRawUInt32(data, rssize, &offset, &(item->sendTime));
ok &= getRawUInt32(data, rssize, &offset, &(item->recvTime));
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_SUBJECT, item->message);
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_MSG, item->message);
ok &= item->msgto.GetTlv(data, rssize, &offset);
ok &= item->msgcc.GetTlv(data, rssize, &offset);
ok &= item->msgbcc.GetTlv(data, rssize, &offset);
ok &= item->attachment.GetTlv(data, rssize, &offset);
if (offset != rssize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
return NULL;
}
return item;
}
uint32_t RsMsgSerialiser::size(RsItem *item)
{
return sizeItem((RsMsgItem *) item);
}
bool RsMsgSerialiser::serialise(RsItem *item, void *data, uint32_t *pktsize)
{
return serialiseItem((RsMsgItem *) item, data, pktsize);
}
RsItem *RsMsgSerialiser::deserialise(void *data, uint32_t *pktsize)
{
return deserialiseItem(data, pktsize);
}
/*************************************************************************/

View File

@ -0,0 +1,142 @@
#ifndef RS_MSG_ITEMS_H
#define RS_MSG_ITEMS_H
/*
* libretroshare/src/serialiser: rsmsgitems.h
*
* RetroShare Serialiser.
*
* Copyright 2007-2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include <map>
#include "serialiser/rsserviceids.h"
#include "serialiser/rsserial.h"
#include "serialiser/rstlvtypes.h"
/**************************************************************************/
/* chat Flags */
const uint32_t RS_CHAT_FLAG_PRIVATE = 0x0001;
class RsChatItem: public RsItem
{
public:
RsChatItem()
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_CHAT,
RS_PKT_SUBTYPE_DEFAULT)
{ return; }
virtual ~RsChatItem();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
uint32_t chatFlags;
uint32_t sendTime;
std::string message;
/* not serialised */
uint32_t recvTime;
};
class RsChatSerialiser: public RsSerialType
{
public:
RsChatSerialiser()
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_CHAT)
{ return; }
virtual ~RsChatSerialiser()
{ return; }
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
private:
virtual uint32_t sizeItem(RsChatItem *);
virtual bool serialiseItem (RsChatItem *item, void *data, uint32_t *size);
virtual RsChatItem *deserialiseItem(void *data, uint32_t *size);
};
/**************************************************************************/
const uint32_t RS_MSG_FLAGS_OUTGOING = 0x0001;
const uint32_t RS_MSG_FLAGS_PENDING = 0x0002;
const uint32_t RS_MSG_FLAGS_DRAFT = 0x0004;
const uint32_t RS_MSG_FLAGS_NEW = 0x0010;
class RsMsgItem: public RsItem
{
public:
RsMsgItem()
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_MSG,
RS_PKT_SUBTYPE_DEFAULT)
{ return; }
virtual ~RsMsgItem();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
uint32_t msgFlags;
uint32_t msgId;
uint32_t sendTime;
uint32_t recvTime;
std::string subject;
std::string message;
RsTlvPeerIdSet msgto;
RsTlvPeerIdSet msgcc;
RsTlvPeerIdSet msgbcc;
RsTlvFileSet attachment;
};
class RsMsgSerialiser: public RsSerialType
{
public:
RsMsgSerialiser()
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_MSG)
{ return; }
virtual ~RsMsgSerialiser() { return; }
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
private:
virtual uint32_t sizeItem(RsMsgItem *);
virtual bool serialiseItem (RsMsgItem *item, void *data, uint32_t *size);
virtual RsMsgItem *deserialiseItem(void *data, uint32_t *size);
};
/**************************************************************************/
#endif /* RS_MSG_ITEMS_H */

View File

@ -33,6 +33,7 @@
#ifdef RSSERIAL_DEBUG
#include <iostream>
#include <sstream>
#endif
RsItem::RsItem(uint32_t t)
@ -82,6 +83,19 @@ uint8_t RsItem::PacketSubType()
}
/* For Service Packets */
RsItem::RsItem(uint8_t ver, uint16_t service, uint8_t subtype)
{
type = (ver << 24) + (service << 8) + subtype;
return;
}
uint16_t RsItem::PacketService()
{
return (type >> 8) & 0xFFFF;
}
RsSerialType::RsSerialType(uint32_t t)
:type(t & 0xFFFFFF00)
@ -95,6 +109,11 @@ RsSerialType::RsSerialType(uint8_t ver, uint8_t cls, uint8_t t)
return;
}
RsSerialType::RsSerialType(uint8_t ver, uint16_t service)
{
type = (ver << 24) + (service << 8);
return;
}
RsSerialType::~RsSerialType()
{
@ -182,19 +201,31 @@ uint32_t RsSerialiser::size(RsItem *item)
if (serialisers.end() == (it = serialisers.find(type)))
{
/* remove 8 more bits -> try again */
type &= 0xFFFF0000;
if (serialisers.end() == (it = serialisers.find(type)))
{
/* one more try */
type &= 0xFF000000;
if (serialisers.end() == (it = serialisers.find(type)))
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsSerialiser::size() serialiser missing!";
std::cerr << std::endl;
std::cerr << "RsSerialiser::size() serialiser missing!";
std::cerr << std::endl;
#endif
return 0;
return 0;
}
}
}
#ifdef RSSERIAL_DEBUG
std::cerr << "RsSerialiser::serialise() Found type: " << type;
std::cerr << std::endl;
std::ostringstream out;
out << std::hex << "RsSerialiser::size() Item->PacketId(): " << item->PacketId();
out << " matched to Serialiser Type: " << type;
std::cerr << out.str() << std::endl;
#endif
return (it->second)->size(item);
}
@ -206,16 +237,29 @@ bool RsSerialiser::serialise (RsItem *item, void *data, uint32_t *size)
if (serialisers.end() == (it = serialisers.find(type)))
{
/* remove 8 more bits -> try again */
type &= 0xFFFF0000;
if (serialisers.end() == (it = serialisers.find(type)))
{
/* one more try */
type &= 0xFF000000;
if (serialisers.end() == (it = serialisers.find(type)))
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsSerialiser::serialise() serialiser missing!";
std::cerr << std::endl;
std::cerr << "RsSerialiser::serialise() serialiser missing!";
std::cerr << std::endl;
#endif
return false;
return false;
}
}
}
#ifdef RSSERIAL_DEBUG
std::cerr << "RsSerialiser::serialise() Found type: " << type;
std::cerr << std::endl;
std::ostringstream out;
out << std::hex << "RsSerialiser::serialise() Item->PacketId(): " << item->PacketId();
out << " matched to Serialiser Type: " << type;
std::cerr << out.str() << std::endl;
#endif
return (it->second)->serialise(item, data, size);
@ -253,16 +297,31 @@ RsItem * RsSerialiser::deserialise(void *data, uint32_t *size)
std::map<uint32_t, RsSerialType *>::iterator it;
if (serialisers.end() == (it = serialisers.find(type)))
{
/* remove 8 more bits -> try again */
type &= 0xFFFF0000;
if (serialisers.end() == (it = serialisers.find(type)))
{
/* one more try */
type &= 0xFF000000;
if (serialisers.end() == (it = serialisers.find(type)))
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsSerialiser::deserialise() deserialiser missing!";
std::cerr << std::endl;
std::cerr << "RsSerialiser::deserialise() deserialiser missing!";
std::cerr << std::endl;
#endif
return NULL;
return NULL;
}
}
}
RsItem *item = (it->second)->deserialise(data, &pkt_size);
if (!item)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsSerialiser::deserialise() Failed!";
std::cerr << std::endl;
#endif
return NULL;
}
@ -329,6 +388,46 @@ uint8_t getRsItemSubType(uint32_t type)
return (type & 0xFF);
}
uint16_t getRsItemService(uint32_t type)
{
return (type >> 8) & 0xFFFF;
}
std::ostream &printRsItemBase(std::ostream &out, std::string clsName, uint16_t indent)
{
printIndent(out, indent);
out << "RsItem: " << clsName << " ####################################";
out << std::endl;
return out;
}
std::ostream &printRsItemEnd(std::ostream &out, std::string clsName, uint16_t indent)
{
printIndent(out, indent);
out << "###################### " << clsName << " #####################";
out << std::endl;
return out;
}
std::ostream &RsRawItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsRawItem", indent);
printIndent(out, indent);
out << "Size: " << len << std::endl;
printRsItemEnd(out, "RsRawItem", indent);
return out;
}
uint32_t getRsPktMaxSize()
{
return 65535; /* 2^16 */
}
uint32_t getRsPktBaseSize()
{
return 8; /* 4 + 4 */
}

View File

@ -27,6 +27,7 @@
*/
#include <map>
#include <iosfwd>
/*******************************************************************
@ -51,12 +52,13 @@
* 8 bits: SubType
******************************************************************/
const uint8_t RS_PKT_VERSION1 = 0x01;
const uint8_t RS_PKT_VERSION1 = 0x01;
const uint8_t RS_PKT_VERSION_SERVICE = 0x02;
const uint8_t RS_PKT_CLASS_BASE = 0x01;
const uint8_t RS_PKT_CLASS_SERVICE = 0x02;
const uint8_t RS_PKT_CLASS_SERV_INIT = 0x03;
const uint8_t RS_PKT_CLASS_CONFIG = 0x11;
const uint8_t RS_PKT_CLASS_CONFIG = 0x02;
const uint8_t RS_PKT_SUBTYPE_DEFAULT = 0x01; /* if only one subtype */
class RsItem
@ -67,6 +69,11 @@ class RsItem
virtual ~RsItem();
virtual void clear() = 0;
virtual std::ostream &print(std::ostream &out, uint16_t indent = 0) = 0;
/* source / destination id */
std::string PeerId() { return peerId; }
void PeerId(std::string id) { peerId = id; }
/* complete id */
uint32_t PacketId();
@ -77,8 +84,13 @@ uint8_t PacketClass();
uint8_t PacketType();
uint8_t PacketSubType();
/* For Service Packets */
RsItem(uint8_t ver, uint16_t service, uint8_t subtype);
uint16_t PacketService(); /* combined Packet class/type (mid 16bits) */
private:
uint32_t type;
std::string peerId;
};
@ -87,6 +99,7 @@ class RsSerialType
public:
RsSerialType(uint32_t t); /* only uses top 24bits */
RsSerialType(uint8_t ver, uint8_t cls, uint8_t t);
RsSerialType(uint8_t ver, uint16_t service);
virtual ~RsSerialType();
@ -127,6 +140,46 @@ uint8_t getRsItemClass(uint32_t type);
uint8_t getRsItemType(uint32_t type);
uint8_t getRsItemSubType(uint32_t type);
uint16_t getRsItemService(uint32_t type);
/* size constants */
uint32_t getRsPktBaseSize();
uint32_t getRsPktMaxSize();
/* helper fns for printing */
std::ostream &printRsItemBase(std::ostream &o, std::string n, uint16_t i);
std::ostream &printRsItemEnd(std::ostream &o, std::string n, uint16_t i);
/* defined in rstlvtypes.cc - redeclared here for ease */
std::ostream &printIndent(std::ostream &out, uint16_t indent);
/* Wrapper class for data that is serialised somewhere else */
class RsRawItem: public RsItem
{
public:
RsRawItem(uint32_t t, uint32_t size)
:RsItem(t), len(size) { data = malloc(len); }
virtual ~RsRawItem()
{
if (data)
free(data);
data = NULL;
len = 0;
}
uint32_t getRawLength() { return len; }
void * getRawData() { return data; }
virtual void clear() { return; } /* what can it do? */
virtual std::ostream &print(std::ostream &out, uint16_t indent = 0);
private:
void *data;
uint32_t len;
};

View File

@ -60,7 +60,7 @@ int test_RsFileItem()
/* make a serialisable FileItem */
RsSerialiser srl;
RsFileItem rsfi;
RsFileRequest rsfi;
/* initialise */
rsfi.file.filesize = 101010;
@ -104,7 +104,7 @@ int test_RsFileItem()
CHECK(output != NULL);
CHECK(sersize2 == sersize);
RsFileItem *outfi = dynamic_cast<RsFileItem *>(output);
RsFileRequest *outfi = dynamic_cast<RsFileRequest *>(output);
CHECK(outfi != NULL);
@ -127,7 +127,7 @@ int test_RsFileItem()
displayRawPacket(std::cerr, (void *) buffer, 16 * 8 + sersize2);
REPORT("Serialise/Deserialise RsFileItem");
REPORT("Serialise/Deserialise RsFileRequest");
return 1;
}

View File

@ -0,0 +1,63 @@
#ifndef RS_SERVICE_IDS_H
#define RS_SERVICE_IDS_H
/*
* libretroshare/src/serialiser: rsserviceids.h
*
* RetroShare Serialiser.
*
* Copyright 2007-2008 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include <inttypes.h>
/* Single place for Cache/Service Ids (uint16_t)
* to 64K of them....
*
* Some Services/Caches are only msgs or caches...
* but they need to be combined so that the messages/caches
* can easily be aligned.
*
*/
/* These are Cache Only */
const uint16_t RS_SERVICE_TYPE_FILE_INDEX = 0x0001;
/* These are Services only */
const uint16_t RS_SERVICE_TYPE_DISC = 0x0011;
const uint16_t RS_SERVICE_TYPE_STATUS = 0x0012;
const uint16_t RS_SERVICE_TYPE_CHAT = 0x0013;
const uint16_t RS_SERVICE_TYPE_MSG = 0x0014;
const uint16_t RS_SERVICE_TYPE_CHANNEL_MSG = 0x0015;
const uint16_t RS_SERVICE_TYPE_PROXY_MSG = 0x0016;
/* Combined Cache/Service ids */
#endif /* RS_SERVICE_IDS_H */

View File

@ -28,50 +28,7 @@
#include <map>
const uint8_t RS_PKT_TYPE_DISC_MSG = 0x01;
const uint8_t RS_PKT_TYPE_CHANNEL_MSG = 0x02;
const uint8_t RS_PKT_TYPE_PROXY_MSG = 0x03;
/**************************************************************************/
class RsDiscMsg: public RsItem
{
public:
RsDiscMsg()
:RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_SERVICE,
RS_PKT_TYPE_DISC_MSG, 0)
{ return; }
virtual ~RsDiscMsg();
virtual void clear();
uint32_t discType;
uint32_t discFlags;
uint32_t connect_tr;
uint32_t receive_tr;
struct sockaddr_in laddr;
struct sockaddr_in saddr;
RsTlvBinaryData cert;
};
class RsDiscMsgSerialiser: public RsSerialType
{
public:
RsDiscMsgSerialiser()
:RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_SERVICE,
RS_PKT_TYPE_DISC_MSG)
{ return; }
virtual ~RsDiscMsgSerialiser();
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
};
#include "serialiser/rsserviceids.h"
/**************************************************************************/
@ -79,8 +36,8 @@ class RsChannelMsg: public RsItem
{
public:
RsChannelMsg()
:RsItem(RS_PKT_VERSION1, RS_PKT_CLASS_SERVICE,
RS_PKT_TYPE_CHANNEL_MSG, 0)
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_CHANNEL,
RS_PKT_SUBTYPE_DEFAULT)
{ return; }
virtual ~RsChannelMsg();
virtual void clear();
@ -94,8 +51,7 @@ class RsChannelMsgSerialiser: public RsSerialType
{
public:
RsChannelMsgSerialiser()
:RsSerialType(RS_PKT_VERSION1, RS_PKT_CLASS_SERVICE,
RS_PKT_TYPE_CHANNEL_MSG)
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_CHANNEL)
{ return; }
virtual ~RsChannelMsgSerialiser();
@ -106,8 +62,115 @@ virtual RsItem * deserialise(void *data, uint32_t *size);
};
/**************************************************************************/
class RsChatItem: public RsItem
{
public:
RsChatItem()
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_CHAT,
RS_PKT_SUBTYPE_DEFAULT)
{ return; }
virtual ~RsChatItem();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent);
uint32_t chatFlags;
uint32_t sendTime;
std::string message;
};
class RsChatItemSerialiser: public RsSerialType
{
public:
RsChatItemSerialiser()
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_CHAT)
{ return; }
virtual ~RsChatItemSerialiser();
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
};
/**************************************************************************/
class RsMessageItem: public RsItem
{
public:
RsMessageItem()
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_MSG,
RS_PKT_SUBTYPE_DEFAULT)
{ return; }
virtual ~RsMessageItem();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent);
uint32_t msgFlags;
uint32_t sendTime;
uint32_t recvTime;
std::string subject;
std::string message;
RsTlvPeerIdSet msgto;
RsTlvPeerIdSet msgcc;
RsTlvPeerIdSet msgbcc;
RsTlvFileSet attachment;
};
class RsMessageItemSerialiser: public RsSerialType
{
public:
RsMessageItemSerialiser()
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_MSG)
{ return; }
virtual ~RsMessageItemSerialiser();
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
};
/**************************************************************************/
class RsStatus: public RsItem
{
public:
RsStatus()
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_STATUS,
RS_PKT_SUBTYPE_DEFAULT)
{ return; }
virtual ~RsStatus();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent);
/* status */
uint32_t status;
RsTlvServiceIdSet services;
};
class RsStatusSerialiser: public RsSerialType
{
public:
RsStatusSerialiser()
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_STATUS)
{ return; }
virtual ~RsStatusSerialiser();
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
};
/**************************************************************************/
#endif /* RS_SERVICE_ITEMS_H */

View File

@ -24,7 +24,6 @@
*
*/
#include <netinet/in.h>
#include <iostream>
#include "serialiser/rstlvbase.h"
@ -239,27 +238,125 @@ bool GetTlvUInt32(void *data, uint32_t size, uint32_t *offset,
return false;
}
uint32_t *intdata = (uint32_t *) right_shift_void_pointer(tlvstart, 4);
*in = ntohl(*intdata);
*offset += 4; /* step past header */
*offset += tlvsize; /* step along */
return true;
bool ok = true;
ok &= getRawUInt32(data, tlvend, offset, in);
return ok;
}
uint32_t GetTlvUInt64Size() {
return 4 + 8;
}
uint32_t GetTlvUInt32Size() {
return 8;
return 4 + 4;
}
uint32_t GetTlvUInt16Size() {
return sizeof(uint16_t);
return 4 + sizeof(uint16_t);
}
uint32_t GetTlvUInt8Size() {
return sizeof(uint8_t);
return 4 + sizeof(uint8_t);
}
bool SetTlvUInt64(void *data, uint32_t size, uint32_t *offset, uint16_t type,
uint64_t out)
{
if (!data)
return false;
uint16_t tlvsize = GetTlvUInt64Size();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
{
#ifdef TLV_BASE_DEBUG
std::cerr << "SetTlvUInt64() FAILED - not enough space. (or earlier)" << std::endl;
std::cerr << "SetTlvUInt64() size: " << size << std::endl;
std::cerr << "SetTlvUInt64() tlvsize: " << tlvsize << std::endl;
std::cerr << "SetTlvUInt64() tlvend: " << tlvend << std::endl;
#endif
return false;
}
bool ok = true;
/* Now use the function we got to set the TlvHeader */
/* function shifts offset to the new start for the next data */
ok &= SetTlvBase(data, tlvend, offset, type, tlvsize);
#ifdef TLV_BASE_DEBUG
if (!ok)
{
std::cerr << "SetTlvUInt64() SetTlvBase FAILED (or earlier)" << std::endl;
}
#endif
/* now set the UInt64 ( in rsbaseserial.h???) */
ok &= setRawUInt64(data, tlvend, offset, out);
#ifdef TLV_BASE_DEBUG
if (!ok)
{
std::cerr << "SetTlvUInt64() setRawUInt64 FAILED (or earlier)" << std::endl;
}
#endif
return ok;
}
bool GetTlvUInt64(void *data, uint32_t size, uint32_t *offset,
uint16_t type, uint64_t *in)
{
if (!data)
return false;
if (size < *offset + 4)
return false;
/* extract the type and size */
void *tlvstart = right_shift_void_pointer(data, *offset);
uint16_t tlvtype = GetTlvType(tlvstart);
uint16_t tlvsize = GetTlvSize(tlvstart);
/* check that there is size */
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
{
#ifdef TLV_BASE_DEBUG
std::cerr << "GetTlvUInt64() FAILED - not enough space." << std::endl;
std::cerr << "GetTlvUInt64() size: " << size << std::endl;
std::cerr << "GetTlvUInt64() tlvsize: " << tlvsize << std::endl;
std::cerr << "GetTlvUInt64() tlvend: " << tlvend << std::endl;
#endif
return false;
}
if (type != tlvtype)
{
#ifdef TLV_BASE_DEBUG
std::cerr << "GetTlvUInt64() FAILED - Type mismatch" << std::endl;
std::cerr << "GetTlvUInt64() type: " << type << std::endl;
std::cerr << "GetTlvUInt64() tlvtype: " << tlvtype << std::endl;
#endif
return false;
}
*offset += 4; /* step past header */
bool ok = true;
ok &= getRawUInt64(data, tlvend, offset, in);
return ok;
}
bool SetTlvString(void *data, uint32_t size, uint32_t *offset,
uint16_t type, std::string out)
{
@ -349,33 +446,36 @@ uint32_t GetTlvStringSize(std::string &in) {
return 4 + in.size();
}
//How to handle structure sockaddr_in? Convert it to void*?
bool SetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset,
uint16_t type, struct sockaddr_in *out) {
if (!data)
return false;
if (size < *offset + sizeof(uint16_t)*2+ sizeof(sockaddr_in))
uint16_t tlvsize = GetTlvIpAddrPortV4Size();
uint32_t tlvend = *offset + tlvsize; /* where the data will extend to */
if (size < tlvend)
{
#ifdef TLV_BASE_DEBUG
std::cerr << "SetTlvIpAddrPortV4() FAILED - not enough space" << std::endl;
std::cerr << "SetTlvIpAddrPortV4() size: " << size << std::endl;
std::cerr << "SetTlvIpAddrPortV4() tlvsize: " << tlvsize << std::endl;
std::cerr << "SetTlvIpAddrPortV4() tlvend: " << tlvend << std::endl;
#endif
return false;
}
// struct sockaddr_in out_n = *out;
// out_n. sin_port = htons(out_n.sin_port);
// out_n.sin_addr = htonl(out_n.sin_addr);
bool ok = true;
ok &= SetTlvBase(data, tlvend, offset, type, tlvsize);
void * to = right_shift_void_pointer(data, *offset);
memcpy(to, (void *)&type, sizeof(uint16_t));
/* now add the data .... (its already in network order) - so flip */
uint32_t ipaddr = out->sin_addr.s_addr;
ok &= setRawUInt32(data, tlvend, offset, ntohl(ipaddr));
to = right_shift_void_pointer(to, sizeof(uint16_t));
uint16_t len = sizeof(sockaddr_in);
memcpy(to, (void*)&len, sizeof(uint16_t));
to = right_shift_void_pointer(to, sizeof(uint16_t));
memcpy(to, (void *)out, sizeof(sockaddr_in));
*offset += sizeof(uint16_t)*2+ sizeof(sockaddr_in);
return true;
uint16_t port = out->sin_port;
ok &= setRawUInt16(data, tlvend, offset, ntohs(port));
return ok;
}
bool GetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset,
@ -383,64 +483,63 @@ bool GetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset,
if (!data)
return false;
if (size < *offset + sizeof(uint16_t)*2+ sizeof(sockaddr_in))
if (size < *offset + 4)
{
#ifdef TLV_BASE_DEBUG
std::cerr << "GetIpAddrPortV4() FAILED - not enough space" << std::endl;
std::cerr << "GetIpAddrPortV4() size: " << size << std::endl;
std::cerr << "GetIpAddrPortV4() *offset: " << *offset << std::endl;
#endif
return false;
}
void * from = right_shift_void_pointer(data, *offset +2);
/* extract the type and size */
void *tlvstart = right_shift_void_pointer(data, *offset);
uint16_t tlvtype = GetTlvType(tlvstart);
uint16_t tlvsize = GetTlvSize(tlvstart);
uint16_t len;
memcpy((void *)&len, from, sizeof(uint16_t));
len = ntohs(len);
if (len != sizeof(sockaddr_in))
/* check that there is size */
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
{
#ifdef TLV_BASE_DEBUG
std::cerr << "GetIpAddrPortV4() FAILED - not enough space" << std::endl;
std::cerr << "GetIpAddrPortV4() size: " << size << std::endl;
std::cerr << "GetIpAddrPortV4() tlvsize: " << tlvsize << std::endl;
std::cerr << "GetIpAddrPortV4() tlvend: " << tlvend << std::endl;
#endif
return false;
}
from = right_shift_void_pointer(from, sizeof(uint16_t));
if (type != tlvtype)
{
#ifdef TLV_BASE_DEBUG
std::cerr << "GetIpAddrPortV4() FAILED - invalid type" << std::endl;
std::cerr << "GetIpAddrPortV4() type: " << type << std::endl;
std::cerr << "GetIpAddrPortV4() tlvtype: " << tlvtype << std::endl;
#endif
return false;
}
memcpy((void*)in, from, sizeof(sockaddr_in));
*offset += 4; /* skip header */
*offset += sizeof(uint16_t)*2+ len;
return true;
bool ok = true;
/* now get the data .... (its already in network order) - so flip */
uint32_t ipaddr;
ok &= getRawUInt32(data, tlvend, offset, &ipaddr);
in->sin_family = AF_INET; /* set FAMILY */
in->sin_addr.s_addr = htonl(ipaddr);
uint16_t port;
ok &= getRawUInt16(data, tlvend, offset, &port);
in->sin_port = htons(port);
return ok;
}
//intention?
bool GetTlvIpAddrPortV4Size() {
return sizeof(uint16_t)*2+ sizeof(sockaddr_in);
uint32_t GetTlvIpAddrPortV4Size() {
return 4 + 4 + 2; /* header + 4 (IP) + 2 (Port) */
}
bool SetRawUInt32(void* data, uint32_t size, uint32_t* offset, uint32_t out) {
if (!data)
return false;
if (size < *offset + sizeof(uint32_t))
return false;
uint32_t out_n = htonl(out);
memcpy(right_shift_void_pointer(data, *offset), (void*)&out_n,
sizeof(uint32_t));
*offset += sizeof(uint32_t);
return true;
}
// additional serializer of data
/*
bool SetTlvBinData(void* data, uint32_t size, uint32_t* offset, uint16_t type, void* data_bin, uint32_t len_tlv)
{
if (!data)
return false;
if (size < *offset + len)
return false;
setTlvBase(data, size, offset, TLV_TYPE_DATA, len_tlv);
memcpy(right_shift_void_pointer(data, *offset), data_bin,
len);
*offset += len;
return true;
}
*/

View File

@ -59,14 +59,17 @@
******************************************************************/
#include <string>
#include "util/rsnet.h"
/* 0b 0000 0000 0001 XXXX UInt8 */
/* 0b 0000 0000 0010 XXXX UInt16 */
/* 0b 0000 0000 0011 XXXX UInt32 */
/* 0b 0000 0000 0100 XXXX UInt64 */
/* 0b 0000 0000 0101 XXXX String */
/* 0b 0000 0000 0110 XXXX IP:Port V4 */
/* 0b 0000 0000 0111 XXXX ?????? */
/* 0b 0000 0000 0001 XXXX UInt32 */
/* 0b 0000 0000 0010 XXXX String */
/* 0b 0000 0000 0011 XXXX IP:Port V4 */
/* 0b 0000 0000 0011 XXXX IP:Port V4 */
/******* BINARY TYPES ****************/
/******* BINARY TYPES *****************/
/* 0b 0000 0000 1000 XXXX CERT */
/* 0b 0000 0000 1001 XXXX Priv Key */
/* 0b 0000 0000 1010 XXXX Pub Key */
@ -74,29 +77,37 @@
/* 0b 0001 XXXX XXXX XXXX Compound */
const uint16_t TLV_TYPE_UINT32_SIZE = 0x0010;
const uint16_t TLV_TYPE_UINT32_POP = 0x0011;
const uint16_t TLV_TYPE_UINT32_AGE = 0x0012;
const uint16_t TLV_TYPE_UINT32_OFFSET = 0x0013;
const uint16_t TLV_TYPE_UINT32_SERID = 0x0014;
const uint16_t TLV_TYPE_UINT8_SERID = 0x0010;
const uint16_t TLV_TYPE_STR_HASH = 0x0020;
const uint16_t TLV_TYPE_STR_NAME = 0x0021;
const uint16_t TLV_TYPE_STR_PATH = 0x0022;
const uint16_t TLV_TYPE_STR_PEERID = 0x0023;
const uint16_t TLV_TYPE_STR_KEY = 0x0024;
const uint16_t TLV_TYPE_STR_VALUE = 0x0025;
const uint16_t TLV_TYPE_STR_COMMENT = 0x0026;
const uint16_t TLV_TYPE_STR_TITLE = 0x0027;
const uint16_t TLV_TYPE_UINT16_SERID = 0x0020;
const uint16_t TLV_TYPE_UINT8_SERID = 0x0028;
const uint16_t TLV_TYPE_UINT32_SIZE = 0x0030;
const uint16_t TLV_TYPE_UINT32_POP = 0x0031;
const uint16_t TLV_TYPE_UINT32_AGE = 0x0032;
const uint16_t TLV_TYPE_UINT32_OFFSET = 0x0033;
const uint16_t TLV_TYPE_UINT32_SERID = 0x0034;
const uint16_t TLV_TYPE_IPV4_LOCAL = 0x0030;
const uint16_t TLV_TYPE_IPV4_SERVER = 0x0031;
const uint16_t TLV_TYPE_IPV4_LAST = 0x0032;
const uint16_t TLV_TYPE_UINT64_SIZE = 0x0040;
const uint16_t TLV_TYPE_UINT64_OFFSET = 0x0041;
const uint16_t TLV_TYPE_STR_HASH = 0x0050;
const uint16_t TLV_TYPE_STR_NAME = 0x0051;
const uint16_t TLV_TYPE_STR_PATH = 0x0052;
const uint16_t TLV_TYPE_STR_PEERID = 0x0053;
const uint16_t TLV_TYPE_STR_KEY = 0x0054;
const uint16_t TLV_TYPE_STR_VALUE = 0x0055;
const uint16_t TLV_TYPE_STR_COMMENT = 0x0056;
const uint16_t TLV_TYPE_STR_TITLE = 0x0057;
const uint16_t TLV_TYPE_STR_MSG = 0x0058;
const uint16_t TLV_TYPE_STR_SUBJECT = 0x0059;
const uint16_t TLV_TYPE_IPV4_LOCAL = 0x0060;
const uint16_t TLV_TYPE_IPV4_SERVER = 0x0061;
const uint16_t TLV_TYPE_IPV4_LAST = 0x0062;
/**** Binary Types ****/
const uint16_t TLV_TYPE_CERT_XPGP = 0x0080;
const uint16_t TLV_TYPE_CERT_XPGP_DER = 0x0080;
const uint16_t TLV_TYPE_CERT_X509 = 0x0081;
const uint16_t TLV_TYPE_CERT_OPENPGP = 0x0082;
@ -133,18 +144,22 @@ bool SetTlvSize(void *data, uint32_t size, uint16_t len);
* so we include a type parameter in the arguments
*/
bool SetTlvUInt8(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint8_t out);
bool GetTlvUInt8(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint8_t *in);
bool SetTlvUInt16(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint16_t out);
bool GetTlvUInt16(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint16_t *in);
bool SetTlvUInt32(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint32_t out);
bool GetTlvUInt32(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint32_t *in);
uint32_t GetTlvUInt32Size();
uint32_t GetTlvUInt16Size();
uint32_t GetTlvUInt8Size();
/* additiona numerical set and Get Routine to be added
bool SetTlvUInt16(...)
bool SetTlvUInt8(...)
bool GetTlvUInt16(...)
bool GetTlvUInt8(...)
............................could above just be templated? */
bool SetTlvUInt64(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint64_t out);
bool GetTlvUInt64(void *data, uint32_t size, uint32_t *offset, uint16_t type, uint64_t *in);
uint32_t GetTlvUInt8Size();
uint32_t GetTlvUInt16Size();
uint32_t GetTlvUInt32Size();
uint32_t GetTlvUInt64Size();
bool SetTlvString(void *data, uint32_t size, uint32_t *offset, uint16_t type, std::string out);
@ -153,7 +168,7 @@ uint32_t GetTlvStringSize(std::string &in);
bool SetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset, uint16_t type, struct sockaddr_in *out);
bool GetTlvIpAddrPortV4(void *data, uint32_t size, uint32_t *offset, uint16_t type, struct sockaddr_in *in);
bool GetTlvIpAddrPortV4Size();
uint32_t GetTlvIpAddrPortV4Size();
/* additional function to be added

View File

@ -46,7 +46,8 @@ void RsTlvFileItem::TlvClear()
uint16_t RsTlvFileItem::TlvSize()
{
uint32_t s = 8; /* header + 4 for size */
uint32_t s = 4; /* header */
s += 8; /* filesize */
s += GetTlvStringSize(hash);
#ifdef TLV_FI_DEBUG
std::cerr << "RsTlvFileItem::TlvSize() 8 + Hash: " << s << std::endl;
@ -126,7 +127,7 @@ bool RsTlvFileItem::SetTlv(void *data, uint32_t size, uint32_t *offset)
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvend, offset, filesize);
ok &= setRawUInt64(data, tlvend, offset, filesize);
#ifdef TLV_FI_DEBUG
if (!ok)
@ -235,7 +236,7 @@ bool RsTlvFileItem::GetTlv(void *data, uint32_t size, uint32_t *offset)
(*offset) += 4;
/* get mandatory parts first */
ok &= getRawUInt32(data, tlvend, offset, &filesize);
ok &= getRawUInt64(data, tlvend, offset, &filesize);
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_HASH, hash);
/* while there is more TLV (optional part) */
@ -503,7 +504,7 @@ uint16_t RsTlvFileData::TlvSize()
/* collect sizes for both uInts and data length */
s+= file.TlvSize();
s+= GetTlvUInt32Size();
s+= GetTlvUInt64Size();
s+= binData.TlvSize();
return s;
@ -526,8 +527,8 @@ bool RsTlvFileData::SetTlv(void *data, uint32_t size, uint32_t *offset) /* seria
/* add mandatory part */
ok &= file.SetTlv(data, size, offset);
ok &= SetTlvUInt32(data,size,offset,
TLV_TYPE_UINT32_OFFSET,file_offset);
ok &= SetTlvUInt64(data,size,offset,
TLV_TYPE_UINT64_OFFSET,file_offset);
ok &= binData.SetTlv(data, size, offset);
return ok;
@ -561,8 +562,8 @@ bool RsTlvFileData::GetTlv(void *data, uint32_t size, uint32_t *offset) /* seria
(*offset) += 4;
ok &= file.GetTlv(data, size, offset);
ok &= GetTlvUInt32(data,size,offset,
TLV_TYPE_UINT32_OFFSET,&file_offset);
ok &= GetTlvUInt64(data,size,offset,
TLV_TYPE_UINT64_OFFSET,&file_offset);
ok &= binData.GetTlv(data, size, offset);
return ok;

View File

@ -82,7 +82,7 @@ virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* seriali
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
virtual std::ostream &print(std::ostream &out, uint16_t indent);
uint32_t filesize; /* Mandatory */
uint64_t filesize; /* Mandatory */
std::string hash; /* Mandatory */
std::string name; /* Optional */
std::string path; /* Optional */
@ -119,7 +119,7 @@ virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deseria
virtual std::ostream &print(std::ostream &out, uint16_t indent);
RsTlvFileItem file; /* Mandatory */
uint32_t file_offset; /* Mandatory */
uint64_t file_offset; /* Mandatory */
RsTlvBinaryData binData; /* Mandatory */
};

View File

@ -36,11 +36,13 @@
#include "serialiser/rstlvbase.h"
#include "serialiser/rstlvutil.h"
#include "util/utest.h"
#include "util/rsnet.h"
INITTEST();
static int test_RsTlvString();
static int test_RsTlvUInt32();
static int test_RsTlvIPAddr();
int main()
{
@ -48,6 +50,7 @@ int main()
test_RsTlvString();
test_RsTlvUInt32();
test_RsTlvIPAddr();
FINALREPORT("RsTlvBase Tests");
@ -87,6 +90,7 @@ int test_OneString(std::string input, uint16_t type)
std::string OutString;
std::cerr << "test_OneString() Testing ... Print/Serialise/Deserialise";
std::cerr << std::endl;
/* start with SetTlvString() */
uint16_t initsize = GetTlvStringSize(input);
@ -117,5 +121,71 @@ int test_OneString(std::string input, uint16_t type)
return 1;
}
int test_IpAddr(struct sockaddr_in *addr, uint16_t type);
static int test_RsTlvIPAddr()
{
struct sockaddr_in addr;
inet_aton("10.0.0.111", &(addr.sin_addr));
addr.sin_port = htons(1111);
test_IpAddr(&addr, 1234);
inet_aton("255.255.255.1", &(addr.sin_addr));
addr.sin_port = htons(9999);
test_IpAddr(&addr, 1234);
inet_aton("128.255.255.1", &(addr.sin_addr));
addr.sin_port = htons(0);
test_IpAddr(&addr, 1234);
return 1;
}
int test_IpAddr(struct sockaddr_in *addr, uint16_t type)
{
/* an array to work from */
char tlvdata[2048];
struct sockaddr_in outaddr;
std::cerr << "test_IpAddr() Testing ... Print/Serialise/Deserialise";
std::cerr << std::endl;
/* start with SetTlvString() */
uint16_t initsize = GetTlvIpAddrPortV4Size();
uint32_t outOffset = 0;
uint32_t inOffset = 0;
std::cerr << "Serialising IPAddr: " << inet_ntoa(addr->sin_addr) << std::endl;
std::cerr << " Port : " << ntohs(addr->sin_port) << std::endl;
CHECK(SetTlvIpAddrPortV4((void*)tlvdata, 2048, &outOffset, type, addr));
std::cerr << "Init Size: " << initsize << std::endl;
std::cerr << "Serialised Size: " << outOffset << std::endl;
displayRawPacket(std::cerr, tlvdata, outOffset);
CHECK(outOffset == initsize); /* check that the offset matches the size */
std::cerr << "DeSerialising" << std::endl;
/* fails if type is wrong! */
CHECK(0 == GetTlvIpAddrPortV4((void*)tlvdata, outOffset, &inOffset, type-1, &outaddr));
CHECK(GetTlvIpAddrPortV4((void*)tlvdata, outOffset, &inOffset, type, &outaddr));
CHECK(initsize == inOffset); /* check that the offset matches the size */
CHECK(addr->sin_addr.s_addr == outaddr.sin_addr.s_addr); /* check that IP match */
CHECK(addr->sin_port == outaddr.sin_port); /* check that Port match */
std::cerr << "Deserialised: Size: " << inOffset << std::endl;
std::cerr << "Deserialised IPAddr: " << inet_ntoa(outaddr.sin_addr) << std::endl;
std::cerr << " Port : " << ntohs(outaddr.sin_port) << std::endl;
REPORT("Serialise OneIP/Port");
return 1;
}