From 0d4feb89b449c3083cf9e6ba1d52dfcb6ee16f15 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 19 Feb 2012 08:32:47 +0000 Subject: [PATCH] cleaned directory structure git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4962 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- plugins/VOIP/{ => gui}/AudioInputConfig.cpp | 0 plugins/VOIP/{ => gui}/AudioInputConfig.h | 0 plugins/VOIP/{ => gui}/AudioInputConfig.ui | 0 plugins/VOIP/{ => gui}/AudioStats.cpp | 0 plugins/VOIP/{ => gui}/AudioStats.h | 0 plugins/VOIP/{ => gui}/AudioStats.ui | 0 plugins/VOIP/{ => gui}/AudioWizard.cpp | 0 plugins/VOIP/{ => gui}/AudioWizard.h | 0 plugins/VOIP/{ => gui}/AudioWizard.ui | 0 plugins/VOIP/{ => gui}/SpeexProcessor.cpp | 0 plugins/VOIP/{ => gui}/SpeexProcessor.h | 0 plugins/VOIP/{ => gui}/VOIP_images.qrc | 0 plugins/VOIP/{ => gui}/audiodevicehelper.cpp | 0 plugins/VOIP/{ => gui}/audiodevicehelper.h | 0 .../VOIP/{ => gui}/images/deafened_self.svg | 0 plugins/VOIP/{ => gui}/images/muted_self.svg | 0 .../VOIP/{ => gui}/images/self_undeafened.svg | 0 plugins/VOIP/{ => gui}/images/talking_off.svg | 0 plugins/VOIP/{ => gui}/images/talking_on.svg | 0 plugins/VOIP/rsvoipitems.h | 20 - plugins/VOIP/service/p3vors.cc | 487 ++++++++++++++++++ plugins/VOIP/service/p3vors.h | 126 +++++ plugins/VOIP/service/rsvoipitems.cc | 373 ++++++++++++++ plugins/VOIP/service/rsvoipitems.h | 108 ++++ 24 files changed, 1094 insertions(+), 20 deletions(-) rename plugins/VOIP/{ => gui}/AudioInputConfig.cpp (100%) rename plugins/VOIP/{ => gui}/AudioInputConfig.h (100%) rename plugins/VOIP/{ => gui}/AudioInputConfig.ui (100%) rename plugins/VOIP/{ => gui}/AudioStats.cpp (100%) rename plugins/VOIP/{ => gui}/AudioStats.h (100%) rename plugins/VOIP/{ => gui}/AudioStats.ui (100%) rename plugins/VOIP/{ => gui}/AudioWizard.cpp (100%) rename plugins/VOIP/{ => gui}/AudioWizard.h (100%) rename plugins/VOIP/{ => gui}/AudioWizard.ui (100%) rename plugins/VOIP/{ => gui}/SpeexProcessor.cpp (100%) rename plugins/VOIP/{ => gui}/SpeexProcessor.h (100%) rename plugins/VOIP/{ => gui}/VOIP_images.qrc (100%) rename plugins/VOIP/{ => gui}/audiodevicehelper.cpp (100%) rename plugins/VOIP/{ => gui}/audiodevicehelper.h (100%) rename plugins/VOIP/{ => gui}/images/deafened_self.svg (100%) rename plugins/VOIP/{ => gui}/images/muted_self.svg (100%) rename plugins/VOIP/{ => gui}/images/self_undeafened.svg (100%) rename plugins/VOIP/{ => gui}/images/talking_off.svg (100%) rename plugins/VOIP/{ => gui}/images/talking_on.svg (100%) delete mode 100644 plugins/VOIP/rsvoipitems.h create mode 100644 plugins/VOIP/service/p3vors.cc create mode 100644 plugins/VOIP/service/p3vors.h create mode 100644 plugins/VOIP/service/rsvoipitems.cc create mode 100644 plugins/VOIP/service/rsvoipitems.h diff --git a/plugins/VOIP/AudioInputConfig.cpp b/plugins/VOIP/gui/AudioInputConfig.cpp similarity index 100% rename from plugins/VOIP/AudioInputConfig.cpp rename to plugins/VOIP/gui/AudioInputConfig.cpp diff --git a/plugins/VOIP/AudioInputConfig.h b/plugins/VOIP/gui/AudioInputConfig.h similarity index 100% rename from plugins/VOIP/AudioInputConfig.h rename to plugins/VOIP/gui/AudioInputConfig.h diff --git a/plugins/VOIP/AudioInputConfig.ui b/plugins/VOIP/gui/AudioInputConfig.ui similarity index 100% rename from plugins/VOIP/AudioInputConfig.ui rename to plugins/VOIP/gui/AudioInputConfig.ui diff --git a/plugins/VOIP/AudioStats.cpp b/plugins/VOIP/gui/AudioStats.cpp similarity index 100% rename from plugins/VOIP/AudioStats.cpp rename to plugins/VOIP/gui/AudioStats.cpp diff --git a/plugins/VOIP/AudioStats.h b/plugins/VOIP/gui/AudioStats.h similarity index 100% rename from plugins/VOIP/AudioStats.h rename to plugins/VOIP/gui/AudioStats.h diff --git a/plugins/VOIP/AudioStats.ui b/plugins/VOIP/gui/AudioStats.ui similarity index 100% rename from plugins/VOIP/AudioStats.ui rename to plugins/VOIP/gui/AudioStats.ui diff --git a/plugins/VOIP/AudioWizard.cpp b/plugins/VOIP/gui/AudioWizard.cpp similarity index 100% rename from plugins/VOIP/AudioWizard.cpp rename to plugins/VOIP/gui/AudioWizard.cpp diff --git a/plugins/VOIP/AudioWizard.h b/plugins/VOIP/gui/AudioWizard.h similarity index 100% rename from plugins/VOIP/AudioWizard.h rename to plugins/VOIP/gui/AudioWizard.h diff --git a/plugins/VOIP/AudioWizard.ui b/plugins/VOIP/gui/AudioWizard.ui similarity index 100% rename from plugins/VOIP/AudioWizard.ui rename to plugins/VOIP/gui/AudioWizard.ui diff --git a/plugins/VOIP/SpeexProcessor.cpp b/plugins/VOIP/gui/SpeexProcessor.cpp similarity index 100% rename from plugins/VOIP/SpeexProcessor.cpp rename to plugins/VOIP/gui/SpeexProcessor.cpp diff --git a/plugins/VOIP/SpeexProcessor.h b/plugins/VOIP/gui/SpeexProcessor.h similarity index 100% rename from plugins/VOIP/SpeexProcessor.h rename to plugins/VOIP/gui/SpeexProcessor.h diff --git a/plugins/VOIP/VOIP_images.qrc b/plugins/VOIP/gui/VOIP_images.qrc similarity index 100% rename from plugins/VOIP/VOIP_images.qrc rename to plugins/VOIP/gui/VOIP_images.qrc diff --git a/plugins/VOIP/audiodevicehelper.cpp b/plugins/VOIP/gui/audiodevicehelper.cpp similarity index 100% rename from plugins/VOIP/audiodevicehelper.cpp rename to plugins/VOIP/gui/audiodevicehelper.cpp diff --git a/plugins/VOIP/audiodevicehelper.h b/plugins/VOIP/gui/audiodevicehelper.h similarity index 100% rename from plugins/VOIP/audiodevicehelper.h rename to plugins/VOIP/gui/audiodevicehelper.h diff --git a/plugins/VOIP/images/deafened_self.svg b/plugins/VOIP/gui/images/deafened_self.svg similarity index 100% rename from plugins/VOIP/images/deafened_self.svg rename to plugins/VOIP/gui/images/deafened_self.svg diff --git a/plugins/VOIP/images/muted_self.svg b/plugins/VOIP/gui/images/muted_self.svg similarity index 100% rename from plugins/VOIP/images/muted_self.svg rename to plugins/VOIP/gui/images/muted_self.svg diff --git a/plugins/VOIP/images/self_undeafened.svg b/plugins/VOIP/gui/images/self_undeafened.svg similarity index 100% rename from plugins/VOIP/images/self_undeafened.svg rename to plugins/VOIP/gui/images/self_undeafened.svg diff --git a/plugins/VOIP/images/talking_off.svg b/plugins/VOIP/gui/images/talking_off.svg similarity index 100% rename from plugins/VOIP/images/talking_off.svg rename to plugins/VOIP/gui/images/talking_off.svg diff --git a/plugins/VOIP/images/talking_on.svg b/plugins/VOIP/gui/images/talking_on.svg similarity index 100% rename from plugins/VOIP/images/talking_on.svg rename to plugins/VOIP/gui/images/talking_on.svg diff --git a/plugins/VOIP/rsvoipitems.h b/plugins/VOIP/rsvoipitems.h deleted file mode 100644 index bf16b9e55..000000000 --- a/plugins/VOIP/rsvoipitems.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "rsvoip.h" - -const uint8_t RS_VOIP_SUBTYPE_RINGING = 0x01 ; -const uint8_t RS_VOIP_SUBTYPE_ACKNOWL = 0x02 ; -const uint8_t RS_VOIP_SUBTYPE_DATA = 0x03 ; - -class RsVoipItem: public RsItem -{ - public: - RsVoipItem(uint8_t turtle_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_VOIP_PLUGIN,voip_subtype) {} - - virtual bool serialize(void *data,uint32_t& size) = 0 ; // Isn't it better that items can serialize themselves ? - virtual uint32_t serial_size() = 0 ; // deserialise is handled using a constructor - - virtual void clear() {} -}; - -// to derive: hanshake items, data items etc. diff --git a/plugins/VOIP/service/p3vors.cc b/plugins/VOIP/service/p3vors.cc new file mode 100644 index 000000000..1bec880f8 --- /dev/null +++ b/plugins/VOIP/service/p3vors.cc @@ -0,0 +1,487 @@ +/* + * libretroshare/src/services p3vors.cc + * + * Voice Over Retroshare Service for RetroShare. + * + * Copyright 2011-2011 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 "util/rsdir.h" +#include "retroshare/rsiface.h" +#include "pqi/pqibin.h" +#include "pqi/pqinotify.h" +#include "pqi/pqistore.h" +#include "pqi/p3linkmgr.h" + +#include "services/p3vors.h" +#include "serialiser/rsvoipitems.h" + +#include + +/**** + * #define DEBUG_VORS 1 + ****/ + + +/* DEFINE INTERFACE POINTER! */ +RsVoip *rsVoip = NULL; + + +#define MAX_PONG_RESULTS 150 +#define VORS_PING_PERIOD 10 + +/************ IMPLEMENTATION NOTES ********************************* + * + * Voice over Retroshare ;) + * + * This will be a simple test VoIP system aimed at testing out the possibilities. + * + * Important things to test: + * 1) lag, and variability in data rate + * - To do this we time tag every packet..., the destination can use this info to calculate the results. + * - Like imixitup. Dt = clock_diff + lag. + * we expect clock_diff to be relatively constant, but lag to vary. + * lag cannot be negative, so minimal Dt is ~clock_diff, and delays on this are considered +lag. + * + * 2) we could directly measure lag. ping back and forth with Timestamps. + * + * 3) we also want to measure bandwidth... + * - not sure the best method? + * one way: send a ping, then a large amount of data (5 seconds worth), then another ping. + * the delta in timestamps should be a decent indication of bandwidth. + * say we have a 100kb/s connection... need 500kb. + * actually the amount of data should be based on a reasonable maximum that we require. + * what does decent video require? + * Audio we can test for 64kb/s - which seems like a decent rate: e.g. mono, 16bit 22k = 1 x 2 x 22k = 44 kilobytes/sec + * best to do this without a VoIP call going on ;) + * + * + */ + + + +#if 0 +class RsVorsLagItem: public RsItem +{ + public: + + uint32_t seqno; + uint32_t type; // REQUEST, RESPONSE. + double peerTs; + +}; + +class RsVorsDatatem: public RsItem +{ + public: + + uint32_t seqno; + uint32_t encoding; + uint32_t audiolength; // in 44.1 kbs samples. + uint32_t datalength; + void *data; +}; + +#endif + + +#ifdef WINDOWS_SYS +#include +#include +#endif + +static double getCurrentTS() +{ + +#ifndef WINDOWS_SYS + struct timeval cts_tmp; + gettimeofday(&cts_tmp, NULL); + double cts = (cts_tmp.tv_sec) + ((double) cts_tmp.tv_usec) / 1000000.0; +#else + struct _timeb timebuf; + _ftime( &timebuf); + double cts = (timebuf.time) + ((double) timebuf.millitm) / 1000.0; +#endif + return cts; +} + +static uint64_t convertTsTo64bits(double ts) +{ + uint32_t secs = (uint32_t) ts; + uint32_t usecs = (uint32_t) ((ts - (double) secs) * 1000000); + uint64_t bits = (((uint64_t) secs) << 32) + usecs; + return bits; +} + + +static double convert64bitsToTs(uint64_t bits) +{ + uint32_t usecs = (uint32_t) (bits & 0xffffffff); + uint32_t secs = (uint32_t) ((bits >> 32) & 0xffffffff); + double ts = (secs) + ((double) usecs) / 1000000.0; + + return ts; +} + + + + +p3VoRS::p3VoRS(p3LinkMgr *lm) + :p3Service(RS_SERVICE_TYPE_VOIP), /* p3Config(CONFIG_TYPE_VOIP), */ mVorsMtx("p3VoRS"), mLinkMgr(lm) +{ + addSerialType(new RsVoipSerialiser()); + + mSentPingTime = 0; + mCounter = 0; + +} + + +int p3VoRS::tick() +{ + processIncoming(); + sendPackets(); + + return 0; +} + +int p3VoRS::status() +{ + return 1; +} + + + +int p3VoRS::sendPackets() +{ + time_t now = time(NULL); + time_t pt; + { + RsStackMutex stack(mVorsMtx); /****** LOCKED MUTEX *******/ + pt = mSentPingTime; + } + + if (now - pt > VORS_PING_PERIOD) + { + sendPingMeasurements(); + + RsStackMutex stack(mVorsMtx); /****** LOCKED MUTEX *******/ + mSentPingTime = now; + } + return true ; +} + + + +void p3VoRS::sendPingMeasurements() +{ + + + /* we ping our peers */ + /* who is online? */ + std::list idList; + + mLinkMgr->getOnlineList(idList); + + double ts = getCurrentTS(); + +#ifdef DEBUG_VORS + std::cerr << "p3VoRS::sendPingMeasurements() @ts: " << ts; + std::cerr << std::endl; +#endif + + /* prepare packets */ + std::list::iterator it; + for(it = idList.begin(); it != idList.end(); it++) + { +#ifdef DEBUG_VORS + std::cerr << "p3VoRS::sendPingMeasurements() Pinging: " << *it; + std::cerr << std::endl; +#endif + + /* create the packet */ + RsVoipPingItem *pingPkt = new RsVoipPingItem(); + pingPkt->PeerId(*it); + pingPkt->mSeqNo = mCounter; + pingPkt->mPingTS = convertTsTo64bits(ts); + + storePingAttempt(*it, ts, mCounter); + +#ifdef DEBUG_VORS + std::cerr << "p3VoRS::sendPingMeasurements() With Packet:"; + std::cerr << std::endl; + pingPkt->print(std::cerr, 10); +#endif + + sendItem(pingPkt); + } + + RsStackMutex stack(mVorsMtx); /****** LOCKED MUTEX *******/ + mCounter++; +} + + + + +int p3VoRS::processIncoming() +{ + /* for each packet - pass to specific handler */ + RsItem *item = NULL; + while(NULL != (item = recvItem())) + { + switch(item->PacketSubType()) + { + default: + break; + case RS_PKT_SUBTYPE_VOIP_PING: + { + handlePing(item); + } + break; + case RS_PKT_SUBTYPE_VOIP_PONG: + { + handlePong(item); + } + break; + +#if 0 + /* THESE ARE ALL FUTURISTIC DATA TYPES */ + case RS_DATA_ITEM: + { + handleData(item); + } + break; + + case RS_BANDWIDTH_PING_ITEM: + { + handleBandwidthPing(item); + } + break; + + case RS_BANDWIDTH_PONG_ITEM: + { + handleBandwidthPong(item); + } + break; +#endif + } + + /* clean up */ + delete item; + } + return true ; +} + +int p3VoRS::handlePing(RsItem *item) +{ + /* cast to right type */ + RsVoipPingItem *ping = (RsVoipPingItem *) item; + +#ifdef DEBUG_VORS + std::cerr << "p3VoRS::handlePing() Recvd Packet from: " << ping->PeerId(); + std::cerr << std::endl; +#endif + + /* with a ping, we just respond as quickly as possible - they do all the analysis */ + RsVoipPongItem *pong = new RsVoipPongItem(); + + + pong->PeerId(ping->PeerId()); + pong->mPingTS = ping->mPingTS; + pong->mSeqNo = ping->mSeqNo; + + // add our timestamp. + double ts = getCurrentTS(); + pong->mPongTS = convertTsTo64bits(ts); + + +#ifdef DEBUG_VORS + std::cerr << "p3VoRS::handlePing() With Packet:"; + std::cerr << std::endl; + pong->print(std::cerr, 10); +#endif + + sendItem(pong); + return true ; +} + + +int p3VoRS::handlePong(RsItem *item) +{ + /* cast to right type */ + RsVoipPongItem *pong = (RsVoipPongItem *) item; + +#ifdef DEBUG_VORS + std::cerr << "p3VoRS::handlePong() Recvd Packet from: " << pong->PeerId(); + std::cerr << std::endl; + pong->print(std::cerr, 10); +#endif + + /* with a pong, we do the maths! */ + double recvTS = getCurrentTS(); + double pingTS = convert64bitsToTs(pong->mPingTS); + double pongTS = convert64bitsToTs(pong->mPongTS); + + double rtt = recvTS - pingTS; + double offset = pongTS - (recvTS - rtt / 2.0); // so to get to their time, we go ourTS + offset. + +#ifdef DEBUG_VORS + std::cerr << "p3VoRS::handlePong() Timing:"; + std::cerr << std::endl; + std::cerr << "\tpingTS: " << pingTS; + std::cerr << std::endl; + std::cerr << "\tpongTS: " << pongTS; + std::cerr << std::endl; + std::cerr << "\trecvTS: " << recvTS; + std::cerr << std::endl; + std::cerr << "\t ==> rtt: " << rtt; + std::cerr << std::endl; + std::cerr << "\t ==> offset: " << offset; + std::cerr << std::endl; +#endif + + storePongResult(pong->PeerId(), pong->mSeqNo, pingTS, rtt, offset); + return true ; +} + + + + +int p3VoRS::storePingAttempt(std::string id, double ts, uint32_t seqno) +{ + RsStackMutex stack(mVorsMtx); /****** LOCKED MUTEX *******/ + + /* find corresponding local data */ + VorsPeerInfo *peerInfo = locked_GetPeerInfo(id); + + peerInfo->mCurrentPingTS = ts; + peerInfo->mCurrentPingCounter = seqno; + + peerInfo->mSentPings++; + if (!peerInfo->mCurrentPongRecvd) + { + peerInfo->mLostPongs++; + } + + peerInfo->mCurrentPongRecvd = true; + + return 1; +} + + + +int p3VoRS::storePongResult(std::string id, uint32_t counter, double ts, double rtt, double offset) +{ + RsStackMutex stack(mVorsMtx); /****** LOCKED MUTEX *******/ + + /* find corresponding local data */ + VorsPeerInfo *peerInfo = locked_GetPeerInfo(id); + + if (peerInfo->mCurrentPingCounter != counter) + { +#ifdef DEBUG_VORS + std::cerr << "p3VoRS::storePongResult() ERROR Severly Delayed Measurements!" << std::endl; +#endif + } + else + { + peerInfo->mCurrentPongRecvd = true; + } + + peerInfo->mPongResults.push_back(RsVoipPongResult(ts, rtt, offset)); + + + while(peerInfo->mPongResults.size() > MAX_PONG_RESULTS) + { + peerInfo->mPongResults.pop_front(); + } + + /* should do calculations */ + return 1; +} + + +uint32_t p3VoRS::getPongResults(std::string id, int n, std::list &results) +{ + RsStackMutex stack(mVorsMtx); /****** LOCKED MUTEX *******/ + + VorsPeerInfo *peer = locked_GetPeerInfo(id); + + std::list::reverse_iterator it; + int i = 0; + for(it = peer->mPongResults.rbegin(); (it != peer->mPongResults.rend()) && (i < n); it++, i++) + { + /* reversing order - so its easy to trim later */ + results.push_back(*it); + } + return i ; +} + + + +VorsPeerInfo *p3VoRS::locked_GetPeerInfo(std::string id) +{ + std::map::iterator it; + it = mPeerInfo.find(id); + if (it == mPeerInfo.end()) + { + /* add it in */ + VorsPeerInfo pinfo; + + /* initialise entry */ + pinfo.initialisePeerInfo(id); + + mPeerInfo[id] = pinfo; + + it = mPeerInfo.find(id); + + } + + return &(it->second); +} + + + +bool VorsPeerInfo::initialisePeerInfo(std::string id) +{ + mId = id; + + /* reset variables */ + mCurrentPingTS = 0; + mCurrentPingCounter = 0; + mCurrentPongRecvd = true; + + mSentPings = 0; + mLostPongs = 0; + + mPongResults.clear(); + + return true; +} + + + + + + + + + + diff --git a/plugins/VOIP/service/p3vors.h b/plugins/VOIP/service/p3vors.h new file mode 100644 index 000000000..1db9e80d1 --- /dev/null +++ b/plugins/VOIP/service/p3vors.h @@ -0,0 +1,126 @@ +/* + * libretroshare/src/services/p3vors.h + * + * Tests for VoIP for RetroShare. + * + * Copyright 2011 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 SERVICE_RSVOIP_HEADER +#define SERVICE_RSVOIP_HEADER + +#include +#include + +#include "serialiser/rsvoipitems.h" +#include "services/p3service.h" +#include "retroshare/rsvoip.h" + +class p3LinkMgr; + +class VorsPeerInfo +{ + public: + + bool initialisePeerInfo(std::string id); + + std::string mId; + double mCurrentPingTS; + double mCurrentPingCounter; + bool mCurrentPongRecvd; + + uint32_t mLostPongs; + uint32_t mSentPings; + + std::list mPongResults; +}; + + +//!The RS VoIP Test service. + /** + * + * This is only used to test Latency for the moment. + */ + +class p3VoRS: public RsVoip, public p3Service +// Maybe we inherit from these later - but not needed for now. +//, public p3Config, public pqiMonitor +{ + public: + p3VoRS(p3LinkMgr *cm); + + /***** overloaded from rsVoip *****/ + +virtual uint32_t getPongResults(std::string id, int n, std::list &results); + + /***** overloaded from p3Service *****/ + /*! + * This retrieves all chat msg items and also (important!) + * processes chat-status items that are in service item queue. chat msg item requests are also processed and not returned + * (important! also) notifications sent to notify base on receipt avatar, immediate status and custom status + * : notifyCustomState, notifyChatStatus, notifyPeerHasNewAvatar + * @see NotifyBase + */ + virtual int tick(); + virtual int status(); + + + int sendPackets(); + void sendPingMeasurements(); + int processIncoming(); + + int handlePing(RsItem *item); + int handlePong(RsItem *item); + + int storePingAttempt(std::string id, double ts, uint32_t mCounter); + int storePongResult(std::string id, uint32_t counter, double ts, double rtt, double offset); + + + /*! + * This retrieves all public chat msg items + */ + //bool getPublicChatQueue(std::list &chats); + + /*************** pqiMonitor callback ***********************/ + //virtual void statusChange(const std::list &plist); + + + /************* from p3Config *******************/ + //virtual RsSerialiser *setupSerialiser() ; + //virtual bool saveList(bool& cleanup, std::list&) ; + //virtual void saveDone(); + //virtual bool loadList(std::list& load) ; + + private: + RsMutex mVorsMtx; + + VorsPeerInfo *locked_GetPeerInfo(std::string id); + + std::map mPeerInfo; + time_t mSentPingTime; + uint32_t mCounter; + + p3LinkMgr *mLinkMgr; + +}; + +#endif // SERVICE_RSVOIP_HEADER + diff --git a/plugins/VOIP/service/rsvoipitems.cc b/plugins/VOIP/service/rsvoipitems.cc new file mode 100644 index 000000000..258afbe81 --- /dev/null +++ b/plugins/VOIP/service/rsvoipitems.cc @@ -0,0 +1,373 @@ + +/* + * libretroshare/src/serialiser: rsvoipitems.cc + * + * RetroShare Serialiser. + * + * Copyright 2011 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/rsvoipitems.h" +#include "serialiser/rstlvbase.h" + +/*** +#define RSSERIAL_DEBUG 1 +***/ + +#include + +/*************************************************************************/ + + +RsVoipPingItem::~RsVoipPingItem() +{ + return; +} + +void RsVoipPingItem::clear() +{ + mSeqNo = 0; + mPingTS = 0; +} + +std::ostream& RsVoipPingItem::print(std::ostream &out, uint16_t indent) +{ + printRsItemBase(out, "RsVoipPingItem", indent); + uint16_t int_Indent = indent + 2; + printIndent(out, int_Indent); + out << "SeqNo: " << mSeqNo << std::endl; + + printIndent(out, int_Indent); + out << "PingTS: " << std::hex << mPingTS << std::dec << std::endl; + + printRsItemEnd(out, "RsVoipPingItem", indent); + return out; +} + + + + + +RsVoipPongItem::~RsVoipPongItem() +{ + return; +} + +void RsVoipPongItem::clear() +{ + mSeqNo = 0; + mPingTS = 0; + mPongTS = 0; +} + + +std::ostream& RsVoipPongItem::print(std::ostream &out, uint16_t indent) +{ + printRsItemBase(out, "RsVoipPongItem", indent); + uint16_t int_Indent = indent + 2; + printIndent(out, int_Indent); + out << "SeqNo: " << mSeqNo << std::endl; + + printIndent(out, int_Indent); + out << "PingTS: " << std::hex << mPingTS << std::dec << std::endl; + + printIndent(out, int_Indent); + out << "PongTS: " << std::hex << mPongTS << std::dec << std::endl; + + printRsItemEnd(out, "RsVoipPongItem", indent); + return out; +} + + +/*************************************************************************/ + + +uint32_t RsVoipSerialiser::sizeVoipPingItem(RsVoipPingItem */*item*/) +{ + uint32_t s = 8; /* header */ + s += 4; /* seqno */ + s += 8; /* pingTS */ + + return s; +} + +/* serialise the data to the buffer */ +bool RsVoipSerialiser::serialiseVoipPingItem(RsVoipPingItem *item, void *data, uint32_t *pktsize) +{ + uint32_t tlvsize = sizeVoipPingItem(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); + +#ifdef RSSERIAL_DEBUG + std::cerr << "RsVoipSerialiser::serialiseVoipPingItem() Header: " << ok << std::endl; + std::cerr << "RsVoipSerialiser::serialiseVoipPingItem() Size: " << tlvsize << std::endl; +#endif + + /* skip the header */ + offset += 8; + + /* add mandatory parts first */ + ok &= setRawUInt32(data, tlvsize, &offset, item->mSeqNo); + ok &= setRawUInt64(data, tlvsize, &offset, item->mPingTS); + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsVoipSerialiser::serialiseVoipPingItem() Size Error! " << std::endl; + } + + return ok; +} + +RsVoipPingItem *RsVoipSerialiser::deserialiseVoipPingItem(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_VOIP != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_VOIP_PING != 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 */ + RsVoipPingItem *item = new RsVoipPingItem(); + item->clear(); + + /* skip the header */ + offset += 8; + + /* get mandatory parts first */ + ok &= getRawUInt32(data, rssize, &offset, &(item->mSeqNo)); + ok &= getRawUInt64(data, rssize, &offset, &(item->mPingTS)); + + if (offset != rssize) + { + /* error */ + delete item; + return NULL; + } + + if (!ok) + { + delete item; + return NULL; + } + + return item; +} + +/*************************************************************************/ +/*************************************************************************/ + + +uint32_t RsVoipSerialiser::sizeVoipPongItem(RsVoipPongItem */*item*/) +{ + uint32_t s = 8; /* header */ + s += 4; /* seqno */ + s += 8; /* pingTS */ + s += 8; /* pongTS */ + + return s; +} + +/* serialise the data to the buffer */ +bool RsVoipSerialiser::serialiseVoipPongItem(RsVoipPongItem *item, void *data, uint32_t *pktsize) +{ + uint32_t tlvsize = sizeVoipPongItem(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); + +#ifdef RSSERIAL_DEBUG + std::cerr << "RsVoipSerialiser::serialiseVoipPongItem() Header: " << ok << std::endl; + std::cerr << "RsVoipSerialiser::serialiseVoipPongItem() Size: " << tlvsize << std::endl; +#endif + + /* skip the header */ + offset += 8; + + /* add mandatory parts first */ + ok &= setRawUInt32(data, tlvsize, &offset, item->mSeqNo); + ok &= setRawUInt64(data, tlvsize, &offset, item->mPingTS); + ok &= setRawUInt64(data, tlvsize, &offset, item->mPongTS); + + if (offset != tlvsize) + { + ok = false; + std::cerr << "RsVoipSerialiser::serialiseVoipPongItem() Size Error! " << std::endl; + } + + return ok; +} + +RsVoipPongItem *RsVoipSerialiser::deserialiseVoipPongItem(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_VOIP != getRsItemService(rstype)) || + (RS_PKT_SUBTYPE_VOIP_PONG != getRsItemSubType(rstype))) + { + return NULL; /* wrong type */ + } + + if (*pktsize < rssize) /* check size */ + return NULL; /* not enough data */ + + /* set the packet length */ + *pktsize = rssize; + + bool ok = true; + + /* ready to load */ + RsVoipPongItem *item = new RsVoipPongItem(); + item->clear(); + + /* skip the header */ + offset += 8; + + /* get mandatory parts first */ + ok &= getRawUInt32(data, rssize, &offset, &(item->mSeqNo)); + ok &= getRawUInt64(data, rssize, &offset, &(item->mPingTS)); + ok &= getRawUInt64(data, rssize, &offset, &(item->mPongTS)); + + if (offset != rssize) + { + /* error */ + delete item; + return NULL; + } + + if (!ok) + { + delete item; + return NULL; + } + + return item; +} + +/*************************************************************************/ + +uint32_t RsVoipSerialiser::size(RsItem *i) +{ + RsVoipPingItem *ping; + RsVoipPongItem *pong; + + if (NULL != (ping = dynamic_cast(i))) + { + return sizeVoipPingItem(ping); + } + else if (NULL != (pong = dynamic_cast(i))) + { + return sizeVoipPongItem(pong); + } + return 0; +} + +bool RsVoipSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize) +{ +#ifdef RSSERIAL_DEBUG + std::cerr << "RsMsgSerialiser::serialise()" << std::endl; +#endif + + RsVoipPingItem *ping; + RsVoipPongItem *pong; + + if (NULL != (ping = dynamic_cast(i))) + { + return serialiseVoipPingItem(ping, data, pktsize); + } + else if (NULL != (pong = dynamic_cast(i))) + { + return serialiseVoipPongItem(pong, data, pktsize); + } + return false; +} + +RsItem* RsVoipSerialiser::deserialise(void *data, uint32_t *pktsize) +{ +#ifdef RSSERIAL_DEBUG + std::cerr << "RsVoipSerialiser::deserialise()" << std::endl; +#endif + + /* get the type and size */ + uint32_t rstype = getRsItemId(data); + + if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || + (RS_SERVICE_TYPE_VOIP != getRsItemService(rstype))) + { + return NULL; /* wrong type */ + } + + switch(getRsItemSubType(rstype)) + { + case RS_PKT_SUBTYPE_VOIP_PING: + return deserialiseVoipPingItem(data, pktsize); + break; + case RS_PKT_SUBTYPE_VOIP_PONG: + return deserialiseVoipPongItem(data, pktsize); + break; + default: + return NULL; + break; + } + + return NULL; +} + + +/*************************************************************************/ + diff --git a/plugins/VOIP/service/rsvoipitems.h b/plugins/VOIP/service/rsvoipitems.h new file mode 100644 index 000000000..f62f21479 --- /dev/null +++ b/plugins/VOIP/service/rsvoipitems.h @@ -0,0 +1,108 @@ +#ifndef RS_VOIP_ITEMS_H +#define RS_VOIP_ITEMS_H + +/* + * libretroshare/src/serialiser: rsvoipitems.h + * + * RetroShare Serialiser. + * + * Copyright 2011 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 + +#include "serialiser/rsserviceids.h" +#include "serialiser/rsserial.h" +#include "serialiser/rstlvtypes.h" + +/**************************************************************************/ + +const uint8_t RS_PKT_SUBTYPE_VOIP_PING = 0x01; +const uint8_t RS_PKT_SUBTYPE_VOIP_PONG = 0x02; + +class RsVoipItem: public RsItem +{ + public: + RsVoipItem(uint8_t chat_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_VOIP,chat_subtype) + { setPriorityLevel(QOS_PRIORITY_RS_VOIP_PING) ;} // should be refined later. + + virtual ~RsVoipItem() {}; + virtual void clear() {}; + virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) = 0 ; +}; + +class RsVoipPingItem: public RsVoipItem +{ + public: + RsVoipPingItem() :RsVoipItem(RS_PKT_SUBTYPE_VOIP_PING) {} + + virtual ~RsVoipPingItem(); + virtual void clear(); + virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); + + uint32_t mSeqNo; + uint64_t mPingTS; +}; + +class RsVoipPongItem: public RsVoipItem +{ + public: + RsVoipPongItem() :RsVoipItem(RS_PKT_SUBTYPE_VOIP_PONG) {} + + virtual ~RsVoipPongItem(); + virtual void clear(); + virtual std::ostream& print(std::ostream &out, uint16_t indent = 0); + + uint32_t mSeqNo; + uint64_t mPingTS; + uint64_t mPongTS; +}; + + +class RsVoipSerialiser: public RsSerialType +{ + public: + RsVoipSerialiser() + :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_VOIP) + { return; } + +virtual ~RsVoipSerialiser() { return; } + +virtual uint32_t size(RsItem *); +virtual bool serialise (RsItem *item, void *data, uint32_t *size); +virtual RsItem * deserialise(void *data, uint32_t *size); + + private: + +virtual uint32_t sizeVoipPingItem(RsVoipPingItem *); +virtual bool serialiseVoipPingItem (RsVoipPingItem *item, void *data, uint32_t *size); +virtual RsVoipPingItem *deserialiseVoipPingItem(void *data, uint32_t *size); + +virtual uint32_t sizeVoipPongItem(RsVoipPongItem *); +virtual bool serialiseVoipPongItem (RsVoipPongItem *item, void *data, uint32_t *size); +virtual RsVoipPongItem *deserialiseVoipPongItem(void *data, uint32_t *size); + +}; + +/**************************************************************************/ + +#endif /* RS_VOIP_ITEMS_H */ + +