added logic for file list item exchange requests

This commit is contained in:
MrAlice 2016-08-23 21:23:58 +02:00
parent 76831348e6
commit 99ea8af015
5 changed files with 140 additions and 65 deletions

View File

@ -26,7 +26,9 @@ class DirectoryStorage
virtual int searchHash(const RsFileHash& hash, std::list<EntryIndex> &results) const ; virtual int searchHash(const RsFileHash& hash, std::list<EntryIndex> &results) const ;
virtual int searchBoolExp(Expression * exp, std::list<EntryIndex> &results) const { NOT_IMPLEMENTED() ; return 0; } virtual int searchBoolExp(Expression * exp, std::list<EntryIndex> &results) const { NOT_IMPLEMENTED() ; return 0; }
bool getUpdateTS(EntryIndex index,time_t& recurs_max_modf_TS,time_t& last_update_TS) ; bool getUpdateTS(EntryIndex index,time_t& recurs_max_modf_TS,time_t& local_update_TS) ;
bool setUpdateTS(EntryIndex index,time_t recurs_max_modf_TS,time_t local_update_TS) ;
uint32_t getEntryType(const EntryIndex& indx) ; // returns DIR_TYPE_*, not the internal directory storage stuff. uint32_t getEntryType(const EntryIndex& indx) ; // returns DIR_TYPE_*, not the internal directory storage stuff.
virtual bool extractData(const EntryIndex& indx,DirDetails& d); virtual bool extractData(const EntryIndex& indx,DirDetails& d);

View File

@ -555,6 +555,7 @@ bool p3FileDatabase::search(const RsFileHash &hash, FileSearchFlags hintflags, F
NOT_IMPLEMENTED(); NOT_IMPLEMENTED();
return false; return false;
} }
return false;
} }
int p3FileDatabase::filterResults(const std::list<EntryIndex>& firesults,std::list<DirDetails>& results,FileSearchFlags flags,const RsPeerId& peer_id) const int p3FileDatabase::filterResults(const std::list<EntryIndex>& firesults,std::list<DirDetails>& results,FileSearchFlags flags,const RsPeerId& peer_id) const
@ -628,9 +629,9 @@ void p3FileDatabase::tickRecv()
{ {
switch(item->PacketSubType()) switch(item->PacketSubType())
{ {
case RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM: handleDirSyncRequest( dynamic_cast<RsFileListsSyncReqItem*>(item) ) ; case RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM: handleDirSyncRequest( dynamic_cast<RsFileListsSyncRequestItem*>(item) ) ;
break ; break ;
case RS_PKT_SUBTYPE_FILELISTS_SYNC_DIR_ITEM: handleDirSyncContent( dynamic_cast<RsFileListsSyncDirItem*>(item) ) ; case RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM: handleDirSyncResponse( dynamic_cast<RsFileListsSyncResponseItem*>(item) ) ;
break ; break ;
default: default:
std::cerr << "(EE) unhandled packet subtype " << item->PacketSubType() << " in " << __PRETTY_FUNCTION__ << std::endl; std::cerr << "(EE) unhandled packet subtype " << item->PacketSubType() << " in " << __PRETTY_FUNCTION__ << std::endl;
@ -645,59 +646,119 @@ void p3FileDatabase::tickSend()
// go through the list of out requests and send them to the corresponding friends, if they are online. // go through the list of out requests and send them to the corresponding friends, if they are online.
} }
void p3FileDatabase::handleDirSyncRequest(RsFileListsSyncReqItem *item) void p3FileDatabase::handleDirSyncRequest(RsFileListsSyncRequestItem *item)
{ {
RsFileListsSyncResponseItem *ritem = new RsFileListsSyncResponseItem;
// look at item TS. If local is newer, send the full directory content. // look at item TS. If local is newer, send the full directory content.
time_t recurs_max_modf_TS, last_update_TS;
P3FILELISTS_DEBUG() << "Received directory sync request. index=" << item->entry_index << ", flags=" << (void*)(intptr_t)item->flags << ", request id: " << std::hex << item->request_id << std::dec << ", last known TS: " << item->last_known_recurs_modf_TS << std::endl;
if(!mLocalSharedDirs->getUpdateTS(item->entry_index,recurs_max_modf_TS,last_update_TS))
{ {
std::cerr << "(EE) Cannot get update TS for entry " << item->entry_index << " in local dir, asked by " << item->PeerId() << std::endl; RS_STACK_MUTEX(mFLSMtx) ;
return ;
P3FILELISTS_DEBUG() << "Received directory sync request. index=" << item->entry_index << ", flags=" << (void*)(intptr_t)item->flags << ", request id: " << std::hex << item->request_id << std::dec << ", last known TS: " << item->last_known_recurs_modf_TS << std::endl;
uint32_t entry_type = mLocalSharedDirs->getEntryType(item->entry_index) ;
ritem->PeerId(item->PeerId()) ;
ritem->request_id = item->request_id;
ritem->entry_index = item->entry_index ;
if(entry_type != DIR_TYPE_DIR)
{
P3FILELISTS_DEBUG() << " Directory does not exist anymore, or is not a directory. Answering with proper flags." << std::endl;
ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | RsFileListsItem::FLAGS_ENTRY_WAS_REMOVED ;
}
else
{
time_t local_recurs_max_time,local_update_time;
mLocalSharedDirs->getUpdateTS(item->entry_index,local_recurs_max_time,local_update_time);
if(item->last_known_recurs_modf_TS < local_recurs_max_time)
{
P3FILELISTS_DEBUG() << " Directory is more recent than what the friend knows. Sending full dir content as response." << std::endl;
ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | RsFileListsItem::FLAGS_SYNC_DIR_CONTENT;
ritem->last_known_recurs_modf_TS = local_recurs_max_time;
mLocalSharedDirs->serialiseDirEntry(item->entry_index,ritem->directory_content_data) ;
}
else
{
P3FILELISTS_DEBUG() << " Directory is up to date w.r.t. what the friend knows. Sending ACK." << std::endl;
ritem->flags = RsFileListsItem::FLAGS_SYNC_RESPONSE | RsFileListsItem::FLAGS_ENTRY_UP_TO_DATE ;
ritem->last_known_recurs_modf_TS = local_update_time ;
}
}
} }
if(item->last_known_recurs_modf_TS < recurs_max_modf_TS) // sends the response.
{
// send full update of directory content sendItem(ritem);
}
else
{
// send last recurs update TS.
}
} }
void p3FileDatabase::handleDirSyncContent(RsFileListsSyncDirItem *item) void p3FileDatabase::handleDirSyncResponse(RsFileListsSyncResponseItem *item)
{ {
// update the directory content for the specified friend. // find the correct friend entry
// set the update TS, and the remote modif TS accordingly uint32_t fi = 0 ;
// notify the GUI if the hierarchy has changed P3FILELISTS_DEBUG() << "Handling sync response for directory with index " << item->entry_index << std::endl;
{
RS_STACK_MUTEX(mFLSMtx) ;
fi = locked_getFriendIndex(item->PeerId());
// make sure we have a remote directory for that friend.
if(mRemoteDirectories.size() <= fi)
mRemoteDirectories.resize(fi+1,NULL) ;
if(mRemoteDirectories[fi] == NULL)
mRemoteDirectories[fi] = new RemoteDirectoryStorage(item->PeerId(),makeRemoteFileName(item->PeerId()));
}
if(item->flags & RsFileListsItem::FLAGS_ENTRY_WAS_REMOVED)
{
P3FILELISTS_DEBUG() << " removing directory with index " << item->entry_index << " because it does not exist." << std::endl;
mRemoteDirectories[fi]->removeDirectory(item->entry_index);
}
else if(item->flags & RsFileListsItem::FLAGS_ENTRY_UP_TO_DATE)
{
P3FILELISTS_DEBUG() << " Directory is up to date. Setting local TS." << std::endl;
mRemoteDirectories[fi]->setUpdateTS(item->entry_index,item->last_known_recurs_modf_TS,time(NULL));
}
else if(item->flags & RsFileListsItem::FLAGS_SYNC_DIR_CONTENT)
{
P3FILELISTS_DEBUG() << " Item contains directory data. Uptating." << std::endl;
mRemoteDirectories[fi]->deserialiseUpdateEntry(item->entry_index,item->directory_content_data) ;
mRemoteDirectories[fi]->setUpdateTS(item->entry_index,item->last_known_recurs_modf_TS,time(NULL));
#warning should notify the GUI here
// notify the GUI if the hierarchy has changed
}
} }
void p3FileDatabase::locked_recursSweepRemoteDirectory(RemoteDirectoryStorage *rds,DirectoryStorage::EntryIndex e) void p3FileDatabase::locked_recursSweepRemoteDirectory(RemoteDirectoryStorage *rds,DirectoryStorage::EntryIndex e)
{ {
time_t now = time(NULL) ; time_t now = time(NULL) ;
// get the info for this entry
// compare TS
// if not up to date, request update, and return (content is not certified, so no need to recurs yet). // if not up to date, request update, and return (content is not certified, so no need to recurs yet).
// if up to date, return, because TS is about the last modif TS below, so no need to recurs either. // if up to date, return, because TS is about the last modif TS below, so no need to recurs either.
time_t recurs_max_modf_TS,last_update_TS ; // get the info for this entry
if(!rds->getUpdateTS(e,recurs_max_modf_TS,last_update_TS)) time_t recurs_max_modf_TS_remote_time,local_update_TS;
if(!rds->getUpdateTS(e,recurs_max_modf_TS_remote_time,local_update_TS))
{ {
std::cerr << "(EE) Cannot get update TS for entry " << e << " in remote dir from " << rds->peerId() << std::endl; std::cerr << "(EE) lockec_recursSweepRemoteDirectory(): cannot get update TS for directory with index " << e << ". This is a consistency bug." << std::endl;
return ; return;
} }
if(now > last_update_TS + DELAY_BETWEEN_REMOTE_DIRECTORY_SYNC_REQ) // compare TS
if(now > local_update_TS + DELAY_BETWEEN_REMOTE_DIRECTORY_SYNC_REQ) // we need to compare local times only. We cannot compare local (now) with remote time.
{ {
// check if a request already exists and is not too old either: no need to re-ask. // check if a request already exists and is not too old either: no need to re-ask.
@ -707,11 +768,11 @@ void p3FileDatabase::locked_recursSweepRemoteDirectory(RemoteDirectoryStorage *r
if(it != mPendingSyncRequests.end()) if(it != mPendingSyncRequests.end())
{ {
std::cerr << "Not asking for sync of directory " << e << " to friend " << rds->peerId() << " because a recent pending request still exists." << std::endl; P3FILELISTS_DEBUG() << "Not asking for sync of directory " << e << " to friend " << rds->peerId() << " because a recent pending request still exists." << std::endl;
return ; return ;
} }
std::cerr << "Asking for sync of directory " << e << " because it's " << (now - last_update_TS) << " secs old since last check." << std::endl; P3FILELISTS_DEBUG() << "Asking for sync of directory " << e << " because it's " << (now - local_update_TS) << " secs old since last check." << std::endl;
DirSyncRequestData data ; DirSyncRequestData data ;
@ -719,13 +780,24 @@ void p3FileDatabase::locked_recursSweepRemoteDirectory(RemoteDirectoryStorage *r
mPendingSyncRequests[sync_req_id] = data ; mPendingSyncRequests[sync_req_id] = data ;
RsFileListsSyncReqItem *item = new RsFileListsSyncReqItem ; RsFileListsSyncRequestItem *item = new RsFileListsSyncRequestItem ;
item->entry_index = e ; item->entry_index = e ;
item->last_known_recurs_modf_TS = recurs_max_modf_TS ; item->flags = RsFileListsItem::FLAGS_SYNC_REQUEST ;
item->request_id = sync_req_id ;
item->last_known_recurs_modf_TS = recurs_max_modf_TS_remote_time ;
item->PeerId(rds->peerId()) ; item->PeerId(rds->peerId()) ;
sendItem(item) ; sendItem(item) ;
// Dont recurs into sub-directories, since we dont know yet were to go.
return ; return ;
} }
for(DirectoryStorage::DirIterator it(rds,e);it;++it)
locked_recursSweepRemoteDirectory(rds,*it);
} }

View File

@ -37,8 +37,8 @@ class LocalDirectoryUpdater ;
class RemoteDirectoryStorage ; class RemoteDirectoryStorage ;
class LocalDirectoryStorage ; class LocalDirectoryStorage ;
class RsFileListsSyncReqItem ; class RsFileListsSyncRequestItem ;
class RsFileListsSyncDirItem ; class RsFileListsSyncResponseItem ;
class HashStorage ; class HashStorage ;
@ -167,8 +167,8 @@ class p3FileDatabase: public p3Service, public p3Config, public ftSearch //, pub
uint32_t locked_getFriendIndex(const RsPeerId& pid); uint32_t locked_getFriendIndex(const RsPeerId& pid);
const RsPeerId& locked_getFriendFromIndex(uint32_t indx) const; const RsPeerId& locked_getFriendFromIndex(uint32_t indx) const;
void handleDirSyncRequest(RsFileListsSyncReqItem *) ; void handleDirSyncRequest (RsFileListsSyncRequestItem *) ;
void handleDirSyncContent(RsFileListsSyncDirItem *) ; void handleDirSyncResponse (RsFileListsSyncResponseItem *) ;
std::map<RsPeerId,uint32_t> mFriendIndexMap ; std::map<RsPeerId,uint32_t> mFriendIndexMap ;
std::vector<RsPeerId> mFriendIndexTab; std::vector<RsPeerId> mFriendIndexTab;

View File

@ -15,8 +15,8 @@ RsItem* RsFileListsSerialiser::deserialise(void *data, uint32_t *size)
switch(getRsItemSubType(rstype)) switch(getRsItemSubType(rstype))
{ {
case RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM: return deserialFileListsSyncReqItem(data, size); case RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM: return deserialFileListsSyncRequestItem(data, size);
case RS_PKT_SUBTYPE_FILELISTS_SYNC_DIR_ITEM: return deserialFileListsSyncDirItem(data, size); case RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM: return deserialFileListsSyncResponseItem(data, size);
case RS_PKT_SUBTYPE_FILELISTS_CONFIG_ITEM: return deserialFileListsConfigItem (data, size); case RS_PKT_SUBTYPE_FILELISTS_CONFIG_ITEM: return deserialFileListsConfigItem (data, size);
default: default:
@ -77,7 +77,7 @@ bool RsFileListsItem::serialise_header(void *data,uint32_t& pktsize,uint32_t& tl
return true ; return true ;
} }
bool RsFileListsSyncReqItem::serialise(void *data, uint32_t& size) const bool RsFileListsSyncRequestItem::serialise(void *data, uint32_t& size) const
{ {
uint32_t tlvsize,offset=0; uint32_t tlvsize,offset=0;
bool ok = true; bool ok = true;
@ -113,7 +113,7 @@ bool RsFileListsSyncReqItem::serialise(void *data, uint32_t& size) const
return ok; return ok;
} }
bool RsFileListsSyncDirItem::serialise(void *data, uint32_t& size) const bool RsFileListsSyncResponseItem::serialise(void *data, uint32_t& size) const
{ {
uint32_t tlvsize,offset=0; uint32_t tlvsize,offset=0;
bool ok = true; bool ok = true;
@ -154,12 +154,12 @@ bool RsFileListsSyncDirItem::serialise(void *data, uint32_t& size) const
// Deserialisation // // Deserialisation //
//============================================================================================================================// //============================================================================================================================//
RsFileListsSyncReqItem* RsFileListsSerialiser::deserialFileListsSyncReqItem(void *data, uint32_t *size) RsFileListsSyncRequestItem* RsFileListsSerialiser::deserialFileListsSyncRequestItem(void *data, uint32_t *size)
{ {
bool ok = checkItemHeader(data,size,RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM); bool ok = checkItemHeader(data,size,RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM);
uint32_t offset = 8; uint32_t offset = 8;
RsFileListsSyncReqItem* item = new RsFileListsSyncReqItem(); RsFileListsSyncRequestItem* item = new RsFileListsSyncRequestItem();
ok &= getRawUInt32(data, *size, &offset, &item->entry_index); ok &= getRawUInt32(data, *size, &offset, &item->entry_index);
ok &= getRawUInt32(data, *size, &offset, &item->flags); ok &= getRawUInt32(data, *size, &offset, &item->flags);
@ -187,12 +187,12 @@ RsFileListsSyncReqItem* RsFileListsSerialiser::deserialFileListsSyncReqItem(void
return item; return item;
} }
RsFileListsSyncDirItem* RsFileListsSerialiser::deserialFileListsSyncDirItem(void *data, uint32_t *size) RsFileListsSyncResponseItem* RsFileListsSerialiser::deserialFileListsSyncResponseItem(void *data, uint32_t *size)
{ {
bool ok = checkItemHeader(data,size,RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM); bool ok = checkItemHeader(data,size,RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM);
uint32_t offset = 8; uint32_t offset = 8;
RsFileListsSyncDirItem* item = new RsFileListsSyncDirItem(); RsFileListsSyncResponseItem* item = new RsFileListsSyncResponseItem();
uint32_t entry_index ; // index of the directory to sync uint32_t entry_index ; // index of the directory to sync
uint32_t flags; // used to say that it's a request or a response, say that the directory has been removed, ask for further update, etc. uint32_t flags; // used to say that it's a request or a response, say that the directory has been removed, ask for further update, etc.
@ -262,7 +262,7 @@ bool RsFileListsSerialiser::checkItemHeader(void *data,uint32_t *size,uint8_t su
// Sizes // // Sizes //
//============================================================================================================================// //============================================================================================================================//
uint32_t RsFileListsSyncReqItem::serial_size()const uint32_t RsFileListsSyncRequestItem::serial_size()const
{ {
uint32_t s = 8; //header size uint32_t s = 8; //header size
@ -275,7 +275,7 @@ uint32_t RsFileListsSyncReqItem::serial_size()const
return s; return s;
} }
uint32_t RsFileListsSyncDirItem::serial_size()const uint32_t RsFileListsSyncResponseItem::serial_size()const
{ {
uint32_t s = 8; //header size uint32_t s = 8; //header size
@ -289,14 +289,14 @@ uint32_t RsFileListsSyncDirItem::serial_size()const
return s; return s;
} }
void RsFileListsSyncReqItem::clear() void RsFileListsSyncRequestItem::clear()
{ {
} }
void RsFileListsSyncDirItem::clear() void RsFileListsSyncResponseItem::clear()
{ {
directory_content_data.TlvClear(); directory_content_data.TlvClear();
} }
std::ostream& RsFileListsSyncReqItem::print(std::ostream &out, uint16_t indent) std::ostream& RsFileListsSyncRequestItem::print(std::ostream &out, uint16_t indent)
{ {
printRsItemBase(out, "RsFileListsSyncReqItem", indent); printRsItemBase(out, "RsFileListsSyncReqItem", indent);
uint16_t int_Indent = indent + 2; uint16_t int_Indent = indent + 2;
@ -311,7 +311,7 @@ std::ostream& RsFileListsSyncReqItem::print(std::ostream &out, uint16_t indent)
return out; return out;
} }
std::ostream& RsFileListsSyncDirItem::print(std::ostream &out, uint16_t indent) std::ostream& RsFileListsSyncResponseItem::print(std::ostream &out, uint16_t indent)
{ {
printRsItemBase(out, "RsFileListsSyncDirItem", indent); printRsItemBase(out, "RsFileListsSyncDirItem", indent);
uint16_t int_Indent = indent + 2; uint16_t int_Indent = indent + 2;

View File

@ -38,7 +38,7 @@
// These items have "flag type" numbers, but this is not used. // These items have "flag type" numbers, but this is not used.
const uint8_t RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM = 0x01; const uint8_t RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM = 0x01;
const uint8_t RS_PKT_SUBTYPE_FILELISTS_SYNC_DIR_ITEM = 0x02; const uint8_t RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM = 0x02;
const uint8_t RS_PKT_SUBTYPE_FILELISTS_CONFIG_ITEM = 0x03; const uint8_t RS_PKT_SUBTYPE_FILELISTS_CONFIG_ITEM = 0x03;
/*! /*!
@ -64,18 +64,19 @@ public:
static const uint32_t FLAGS_SYNC_REQUEST = 0x0001 ; static const uint32_t FLAGS_SYNC_REQUEST = 0x0001 ;
static const uint32_t FLAGS_SYNC_RESPONSE = 0x0002 ; static const uint32_t FLAGS_SYNC_RESPONSE = 0x0002 ;
static const uint32_t FLAGS_ENTRY_UP_TO_DATE = 0x0004 ; static const uint32_t FLAGS_SYNC_DIR_CONTENT = 0x0004 ;
static const uint32_t FLAGS_ENTRY_WAS_REMOVED = 0x0008 ; static const uint32_t FLAGS_ENTRY_UP_TO_DATE = 0x0008 ;
static const uint32_t FLAGS_ENTRY_WAS_REMOVED = 0x0010 ;
}; };
/*! /*!
* Use to request synchronization on a specific directory. Also used to respond that the directory is up to date. * Use to request synchronization on a specific directory. Also used to respond that the directory is up to date.
*/ */
class RsFileListsSyncReqItem : public RsFileListsItem class RsFileListsSyncRequestItem : public RsFileListsItem
{ {
public: public:
RsFileListsSyncReqItem() : RsFileListsItem(RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM) {} RsFileListsSyncRequestItem() : RsFileListsItem(RS_PKT_SUBTYPE_FILELISTS_SYNC_REQ_ITEM) {}
virtual void clear(); virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent); virtual std::ostream &print(std::ostream &out, uint16_t indent);
@ -89,11 +90,11 @@ public:
uint64_t request_id; // use to determine if changes that have occured since last hash uint64_t request_id; // use to determine if changes that have occured since last hash
}; };
class RsFileListsSyncDirItem : public RsFileListsItem class RsFileListsSyncResponseItem : public RsFileListsItem
{ {
public: public:
RsFileListsSyncDirItem() : RsFileListsItem(RS_PKT_SUBTYPE_FILELISTS_SYNC_DIR_ITEM) {} RsFileListsSyncResponseItem() : RsFileListsItem(RS_PKT_SUBTYPE_FILELISTS_SYNC_RSP_ITEM) {}
virtual void clear(); virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent); virtual std::ostream &print(std::ostream &out, uint16_t indent);
@ -122,9 +123,9 @@ public:
virtual RsItem* deserialise(void *data, uint32_t *size); virtual RsItem* deserialise(void *data, uint32_t *size);
private: private:
RsFileListsSyncReqItem *deserialFileListsSyncReqItem(void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_GRP */ RsFileListsSyncRequestItem *deserialFileListsSyncRequestItem(void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_GRP */
RsFileListsSyncDirItem *deserialFileListsSyncDirItem(void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_GRP */ RsFileListsSyncResponseItem *deserialFileListsSyncResponseItem(void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_GRP */
RsFileListsSyncDirItem *deserialFileListsConfigItem (void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_GRP */ RsFileListsSyncResponseItem *deserialFileListsConfigItem (void *data, uint32_t *size); /* RS_PKT_SUBTYPE_SYNC_GRP */
bool checkItemHeader(void *data, uint32_t *size, uint8_t subservice_type); bool checkItemHeader(void *data, uint32_t *size, uint8_t subservice_type);
}; };