From d01c61fde8e85f11fd680d3592181689f66d2ea1 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 11 May 2016 17:59:42 -0400 Subject: [PATCH] added items for encoding subscription requests and the logic to create them from GUI calls --- libretroshare/src/retroshare/rsgxscircles.h | 1 - .../src/serialiser/rsgxscircleitems.cc | 143 ++++++++++++++++++ .../src/serialiser/rsgxscircleitems.h | 32 +++- libretroshare/src/services/p3gxschannels.cc | 2 +- libretroshare/src/services/p3gxscircles.cc | 56 +++---- retroshare-gui/src/gui/Identity/IdDialog.cpp | 12 +- 6 files changed, 203 insertions(+), 43 deletions(-) diff --git a/libretroshare/src/retroshare/rsgxscircles.h b/libretroshare/src/retroshare/rsgxscircles.h index 5fa3d280f..e3e20b74c 100644 --- a/libretroshare/src/retroshare/rsgxscircles.h +++ b/libretroshare/src/retroshare/rsgxscircles.h @@ -78,7 +78,6 @@ public: RsGxsCircleId mInternalCircle; // if Originator == ownId, otherwise blank. }; - class RsGxsCircleGroup { public: diff --git a/libretroshare/src/serialiser/rsgxscircleitems.cc b/libretroshare/src/serialiser/rsgxscircleitems.cc index 0132c358e..c81de0b06 100644 --- a/libretroshare/src/serialiser/rsgxscircleitems.cc +++ b/libretroshare/src/serialiser/rsgxscircleitems.cc @@ -104,6 +104,25 @@ RsItem* RsGxsCircleSerialiser::deserialise(void* data, uint32_t* size) /*****************************************************************************************/ /*****************************************************************************************/ +void RsGxsCircleSubscriptionRequestItem::clear() +{ + time_stamp = 0 ; + time_out = 0 ; + subscription_type = SUBSCRIPTION_REQUEST_UNKNOWN; +} + +std::ostream& RsGxsCircleSubscriptionRequestItem::print(std::ostream& out, uint16_t indent) +{ + printRsItemBase(out, "RsGxsCircleSubscriptionRequestItem", indent); + uint16_t int_Indent = indent + 2; + + printRsItemBase(out, "time stmp: ", indent); out << time_stamp ; + printRsItemBase(out, "time out : ", indent); out << time_out ; + printRsItemBase(out, "Subs type: ", indent); out << subscription_type ; + + printRsItemEnd(out ,"RsGxsCircleSubscriptionRequestItem", indent); + return out; +} void RsGxsCircleGroupItem::clear() { @@ -176,6 +195,16 @@ std::ostream& RsGxsCircleGroupItem::print(std::ostream& out, uint16_t indent) return out; } +uint32_t RsGxsCircleSerialiser::sizeGxsCircleSubscriptionRequestItem(RsGxsCircleSubscriptionRequestItem *item) +{ + uint32_t s=8 ; // header + + s += 4 ; // time_stamp serialised as uint32_t; + s += 4 ; // time_out serialised as uint32_t; + s += 1 ; // subscription_type ; + + return s ; +} uint32_t RsGxsCircleSerialiser::sizeGxsCircleGroupItem(RsGxsCircleGroupItem *item) { @@ -188,6 +217,54 @@ uint32_t RsGxsCircleSerialiser::sizeGxsCircleGroupItem(RsGxsCircleGroupItem *ite return s; } +bool RsGxsCircleSerialiser::serialiseGxsCircleSubscriptionRequestItem(RsGxsCircleSubscriptionRequestItem *item, void *data, uint32_t *size) +{ + +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleSubscriptionRequestItem()" << std::endl; +#endif + + uint32_t tlvsize = sizeGxsCircleSubscriptionRequestItem(item); + uint32_t offset = 0; + + if(*size < tlvsize) + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleSubscriptionRequestItem()" << std::endl; +#endif + return false; + } + + *size = tlvsize; + + bool ok = true; + + ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize); + + /* skip the header */ + offset += 8; + + /* GxsCircleGroupItem */ + ok &= setRawUInt32(data,tlvsize,&offset,item->time_stamp) ; + ok &= setRawUInt32(data,tlvsize,&offset,item->time_out) ; + ok &= setRawUInt8(data,tlvsize,&offset,item->subscription_type) ; + + if(offset != tlvsize) + { + //#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleSubscriptionRequestItem() FAIL Size Error! " << std::endl; + //#endif + ok = false; + } + + //#ifdef CIRCLE_DEBUG + if (!ok) + std::cerr << "RsGxsCircleSerialiser::serialiseGxsCircleSubscriptionRequestItem() NOK" << std::endl; + //#endif + + return ok; +} + bool RsGxsCircleSerialiser::serialiseGxsCircleGroupItem(RsGxsCircleGroupItem *item, void *data, uint32_t *size) { @@ -238,6 +315,72 @@ bool RsGxsCircleSerialiser::serialiseGxsCircleGroupItem(RsGxsCircleGroupItem *it return ok; } +RsGxsCircleSubscriptionRequestItem *RsGxsCircleSerialiser::deserialiseGxsCircleSubscriptionRequestItem(void *data, uint32_t *size) +{ + +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleSubscriptionRequestItem()" << std::endl; +#endif + /* 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_GXS_TYPE_GXSCIRCLE != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_GXSCIRCLE_SUBSCRIPTION_REQUEST_ITEM != getRsItemSubType(rstype))) + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleSubscriptionRequestItem() FAIL wrong type" << std::endl; +#endif + return NULL; /* wrong type */ + } + + if (*size < rssize) /* check size */ + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleSubscriptionRequestItem() FAIL wrong size" << std::endl; +#endif + return NULL; /* not enough data */ + } + + /* set the packet length */ + *size = rssize; + + bool ok = true; + + RsGxsCircleSubscriptionRequestItem* item = new RsGxsCircleSubscriptionRequestItem(); + /* skip the header */ + offset += 8; + + uint32_t tmp ; + ok &= getRawUInt32(data,rssize,&offset,&tmp) ; item->time_stamp = tmp ; + ok &= getRawUInt32(data,rssize,&offset,&tmp) ; item->time_out = tmp ; + ok &= getRawUInt8(data,rssize,&offset,&item->subscription_type) ; + + if (offset != rssize) + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleSubscriptionRequestItem() FAIL size mismatch" << std::endl; +#endif + /* error */ + delete item; + return NULL; + } + + if (!ok) + { +#ifdef CIRCLE_DEBUG + std::cerr << "RsGxsCircleSerialiser::deserialiseGxsCircleSubscriptionRequestItem() NOK" << std::endl; +#endif + delete item; + return NULL; + } + + return item; +} RsGxsCircleGroupItem* RsGxsCircleSerialiser::deserialiseGxsCircleGroupItem(void *data, uint32_t *size) { diff --git a/libretroshare/src/serialiser/rsgxscircleitems.h b/libretroshare/src/serialiser/rsgxscircleitems.h index 4590bd62d..4ae4e7109 100644 --- a/libretroshare/src/serialiser/rsgxscircleitems.h +++ b/libretroshare/src/serialiser/rsgxscircleitems.h @@ -37,13 +37,16 @@ #include "rsgxsitems.h" #include "retroshare/rsgxscircles.h" -const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM = 0x02; -const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM = 0x03; +const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM = 0x02; +const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM = 0x03; +const uint8_t RS_PKT_SUBTYPE_GXSCIRCLE_SUBSCRIPTION_REQUEST_ITEM = 0x04; const uint16_t GXSCIRCLE_PGPIDSET = 0x0001; const uint16_t GXSCIRCLE_GXSIDSET = 0x0002; const uint16_t GXSCIRCLE_SUBCIRCLESET = 0x0003; +// These classes are a mess. Needs proper item serialisation etc. + class RsGxsCircleGroupItem : public RsGxsGrpItem { @@ -83,6 +86,27 @@ public: RsGxsCircleMsg msg; }; +class RsGxsCircleSubscriptionRequestItem: public RsGxsMsgItem +{ +public: + + RsGxsCircleSubscriptionRequestItem() : RsGxsMsgItem(RS_SERVICE_GXS_TYPE_GXSCIRCLE, RS_PKT_SUBTYPE_GXSCIRCLE_SUBSCRIPTION_REQUEST_ITEM) { } + virtual ~RsGxsCircleSubscriptionRequestItem() {} + + void clear(); + std::ostream &print(std::ostream &out, uint16_t indent = 0); + + enum { + SUBSCRIPTION_REQUEST_UNKNOWN = 0x00, + SUBSCRIPTION_REQUEST_SUBSCRIBE = 0x01, + SUBSCRIPTION_REQUEST_UNSUBSCRIBE = 0x02 + }; + + time_t time_stamp ; + time_t time_out ; + uint8_t subscription_type ; +}; + class RsGxsCircleSerialiser : public RsSerialType { public: @@ -98,6 +122,10 @@ public: private: + uint32_t sizeGxsCircleSubscriptionRequestItem(RsGxsCircleSubscriptionRequestItem *item); + bool serialiseGxsCircleSubscriptionRequestItem (RsGxsCircleSubscriptionRequestItem *item, void *data, uint32_t *size); + RsGxsCircleSubscriptionRequestItem * deserialiseGxsCircleSubscriptionRequestItem(void *data, uint32_t *size); + uint32_t sizeGxsCircleGroupItem(RsGxsCircleGroupItem *item); bool serialiseGxsCircleGroupItem (RsGxsCircleGroupItem *item, void *data, uint32_t *size); RsGxsCircleGroupItem * deserialiseGxsCircleGroupItem(void *data, uint32_t *size); diff --git a/libretroshare/src/services/p3gxschannels.cc b/libretroshare/src/services/p3gxschannels.cc index 3bc03eeb3..eeab2b29b 100644 --- a/libretroshare/src/services/p3gxschannels.cc +++ b/libretroshare/src/services/p3gxschannels.cc @@ -993,7 +993,7 @@ std::string SSGxsChannelGroup::save() const if(!mDownloadDirectory.empty()) { std::string encoded_str ; - Radix64::encode(mDownloadDirectory.c_str(),mDownloadDirectory.length(),encoded_str); + Radix64::encode((unsigned char*)mDownloadDirectory.c_str(),mDownloadDirectory.length(),encoded_str); output += " {P:" + encoded_str + "}"; } diff --git a/libretroshare/src/services/p3gxscircles.cc b/libretroshare/src/services/p3gxscircles.cc index b71c7fc68..c7de88ec9 100644 --- a/libretroshare/src/services/p3gxscircles.cc +++ b/libretroshare/src/services/p3gxscircles.cc @@ -27,6 +27,8 @@ #include "serialiser/rsgxscircleitems.h" #include "retroshare/rsgxsflags.h" #include "util/rsrandom.h" +#include "util/rsdir.h" +#include "util/radix64.h" #include "util/rsstring.h" #include "pgp/pgpauxutils.h" @@ -1867,52 +1869,32 @@ bool p3GxsCircles::pushCircleMembershipRequest(const RsGxsId& own_gxsid,const Rs // Create a subscribe item - RsGxsCircleSubscriptionRequestItem s ; + RsGxsCircleSubscriptionRequestItem *s = new RsGxsCircleSubscriptionRequestItem ; - s.time_stamp = time(NULL) ; - s.subscription_request = RsGxsCircleSubscriptionRequestItem::SUBSCRIPTION_REQUEST_SUBSCRIBE ; - s.circle_id = id ; - s.time_out = 0 ; // means never + s->time_stamp = time(NULL) ; + s->time_out = 0 ; // means never + s->subscription_type = RsGxsCircleSubscriptionRequestItem::SUBSCRIPTION_REQUEST_SUBSCRIBE ; // Serialise it into a base64 string - uint32_t pktsize = s.serial_size() ; - - RsTemporaryMemory mem(s.serial_size()) ; + RsTemporaryMemory tmpmem(circle_id.serial_size() + own_gxsid.serial_size()) ; - if(!mem) - return false ; + uint32_t off = 0 ; + circle_id.serialise(tmpmem,tmpmem.size(),off) ; + own_gxsid.serialise(tmpmem+off,tmpmem.size(),off) ; - s.serialise(mem,pktsize) ; - - std::string msg ; - Radix64::encode(mem,pktsize,msg) ; - - // Create the group message to store and publish it - - RsTemporaryMemory tmpmem(RsGxsCircleId::SIZE_IN_BYTES + RsGxsId::SIZE_IN_BYTES) ; - - if(!tmpmem) - return false ; - - circle_id.serialise(tmpmem,tmpmem.size()) ; - own_gxsid.serialise(tmpmem+RsGxsCircleId::SIZE_IN_BYTES,(int)tmpmem.size()-(int)RsGxsCircleId::SIZE_IN_BYTES) ; - - RsGxsCircleMsgItem* msgItem = new RsGxsCircleMsgItem(); - msgItem->mMsg = msg; - - msgItem->meta.mGroupId = id ; - msgItem->meta.mMsgId.clear(); - msgItem->meta.mThreadId = sha1sum(tmpmem,tmpmem.size()); // make the ID from the hash of the cirle ID and the author ID - msgItem->meta.mAuthorId = own_id; + s->meta.mGroupId = RsGxsGroupId(circle_id) ; + s->meta.mMsgId.clear(); + s->meta.mThreadId = RsDirUtil::sha1sum(tmpmem,tmpmem.size()); // make the ID from the hash of the cirle ID and the author ID + s->meta.mAuthorId = own_gxsid; // msgItem->meta.mParentId = ; // leave these blank // msgItem->meta.mOrigMsgId= ; std::cerr << "p3GxsCircles::publishSubscribeRequest()" << std::endl; std::cerr << " GroupId : " << circle_id << std::endl; - std::cerr << " AuthorId : " << msgItem->meta.mAuthorId << std::endl; - std::cerr << " ThreadId : " << msgItem->meta.mThreadId << std::endl; + std::cerr << " AuthorId : " << s->meta.mAuthorId << std::endl; + std::cerr << " ThreadId : " << s->meta.mThreadId << std::endl; #warning Would be nice to wait for a few seconds before publishing, so that the user can potentially cancel a wrong request before it gets piped into the system //RsGenExchange::publishMsg(token, msgItem); @@ -1921,11 +1903,11 @@ bool p3GxsCircles::pushCircleMembershipRequest(const RsGxsId& own_gxsid,const Rs bool p3GxsCircles::requestCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id) { - return pushCircleMembershipRequest(own_id,circle_id,RsGxsCircleSubscriptionRequestItem::SUBSCRIPTION_REQUEST_SUBSCRIBE) ; + return pushCircleMembershipRequest(own_gxsid,circle_id,RsGxsCircleSubscriptionRequestItem::SUBSCRIPTION_REQUEST_SUBSCRIBE) ; } -bool p3GxsCircles::cancelCircleMembership(const RsGxsId& own_id,const RsGxsCircleId& id) +bool p3GxsCircles::cancelCircleMembership(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id) { - return pushCircleMembershipRequest(own_id,circle_id,RsGxsCircleSubscriptionRequestItem::SUBSCRIPTION_REQUEST_UNSUBSCRIBE) ; + return pushCircleMembershipRequest(own_gxsid,circle_id,RsGxsCircleSubscriptionRequestItem::SUBSCRIPTION_REQUEST_UNSUBSCRIBE) ; } diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 1017a501b..d005dd3ba 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -621,10 +621,14 @@ void IdDialog::acceptCircleSubscription() if (!item) return ; +#warning we have to find a way to get the correct own id here. + + RsGxsId own_id ; + QString coltext = item->text(CIRCLEGROUP_CIRCLE_COL_GROUPID); RsGxsCircleId circle_id ( coltext.toStdString()) ; - rsGxsCircles->requestCircleMembership(circle_id) ; + rsGxsCircles->requestCircleMembership(own_id,circle_id) ; } void IdDialog::refuseCircleSubscription() @@ -633,11 +637,15 @@ void IdDialog::refuseCircleSubscription() if (!item) return ; + +#warning we have to find a way to get the correct own id here. + RsGxsId own_id ; + QString coltext = item->text(CIRCLEGROUP_CIRCLE_COL_GROUPID); RsGxsCircleId circle_id ( coltext.toStdString()) ; - rsGxsCircles->cancelCircleMembership(circle_id) ; + rsGxsCircles->cancelCircleMembership(own_id,circle_id) ; } void IdDialog::CircleListCustomPopupMenu( QPoint )