<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                          License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "precomp.hpp"

using namespace cv;

Ptr<Feature2D> Feature2D::create( const String& feature2DType )
{
    return Algorithm::create<Feature2D>("Feature2D." + feature2DType);
}

/////////////////////// AlgorithmInfo for various detector & descriptors ////////////////////////////

/* NOTE!!!
   All the AlgorithmInfo-related stuff should be in the same file as initModule_features2d().
   Otherwise, linker may throw away some seemingly unused stuff.
*/

CV_INIT_ALGORITHM(BRISK, "Feature2D.BRISK",
                   obj.info()->addParam(obj, "thres", obj.threshold);
                   obj.info()->addParam(obj, "octaves", obj.octaves));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(BriefDescriptorExtractor, "Feature2D.BRIEF",
                  obj.info()->addParam(obj, "bytes", obj.bytes_));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(FastFeatureDetector, "Feature2D.FAST",
                  obj.info()->addParam(obj, "threshold", obj.threshold);
                  obj.info()->addParam(obj, "nonmaxSuppression", obj.nonmaxSuppression);
                  obj.info()->addParam(obj, "type", obj.type));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(StarDetector, "Feature2D.STAR",
                  obj.info()->addParam(obj, "maxSize", obj.maxSize);
                  obj.info()->addParam(obj, "responseThreshold", obj.responseThreshold);
                  obj.info()->addParam(obj, "lineThresholdProjected", obj.lineThresholdProjected);
                  obj.info()->addParam(obj, "lineThresholdBinarized", obj.lineThresholdBinarized);
                  obj.info()->addParam(obj, "suppressNonmaxSize", obj.suppressNonmaxSize));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(MSER, "Feature2D.MSER",
                  obj.info()->addParam(obj, "delta", obj.delta);
                  obj.info()->addParam(obj, "minArea", obj.minArea);
                  obj.info()->addParam(obj, "maxArea", obj.maxArea);
                  obj.info()->addParam(obj, "maxVariation", obj.maxVariation);
                  obj.info()->addParam(obj, "minDiversity", obj.minDiversity);
                  obj.info()->addParam(obj, "maxEvolution", obj.maxEvolution);
                  obj.info()->addParam(obj, "areaThreshold", obj.areaThreshold);
                  obj.info()->addParam(obj, "minMargin", obj.minMargin);
                  obj.info()->addParam(obj, "edgeBlurSize", obj.edgeBlurSize));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(ORB, "Feature2D.ORB",
                  obj.info()->addParam(obj, "nFeatures", obj.nfeatures);
                  obj.info()->addParam(obj, "scaleFactor", obj.scaleFactor);
                  obj.info()->addParam(obj, "nLevels", obj.nlevels);
                  obj.info()->addParam(obj, "firstLevel", obj.firstLevel);
                  obj.info()->addParam(obj, "edgeThreshold", obj.edgeThreshold);
                  obj.info()->addParam(obj, "patchSize", obj.patchSize);
                  obj.info()->addParam(obj, "WTA_K", obj.WTA_K);
                  obj.info()->addParam(obj, "scoreType", obj.scoreType));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(FREAK, "Feature2D.FREAK",
                  obj.info()->addParam(obj, "orientationNormalized", obj.orientationNormalized);
                  obj.info()->addParam(obj, "scaleNormalized", obj.scaleNormalized);
                  obj.info()->addParam(obj, "patternScale", obj.patternScale);
                  obj.info()->addParam(obj, "nbOctave", obj.nOctaves));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(GFTTDetector, "Feature2D.GFTT",
                  obj.info()->addParam(obj, "nfeatures", obj.nfeatures);
                  obj.info()->addParam(obj, "qualityLevel", obj.qualityLevel);
                  obj.info()->addParam(obj, "minDistance", obj.minDistance);
                  obj.info()->addParam(obj, "useHarrisDetector", obj.useHarrisDetector);
                  obj.info()->addParam(obj, "k", obj.k));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(SimpleBlobDetector, "Feature2D.SimpleBlob",
                  obj.info()->addParam(obj, "thresholdStep",    obj.params.thresholdStep);
                  obj.info()->addParam(obj, "minThreshold",     obj.params.minThreshold);
                  obj.info()->addParam(obj, "maxThreshold",     obj.params.maxThreshold);
                  obj.info()->addParam_(obj, "minRepeatability", (sizeof(size_t) == sizeof(uint64))?Param::UINT64 : Param::UNSIGNED_INT, &obj.params.minRepeatability, false, 0, 0);
                  obj.info()->addParam(obj, "minDistBetweenBlobs", obj.params.minDistBetweenBlobs);
                  obj.info()->addParam(obj, "filterByColor",    obj.params.filterByColor);
                  obj.info()->addParam(obj, "blobColor",        obj.params.blobColor);
                  obj.info()->addParam(obj, "filterByArea",     obj.params.filterByArea);
                  obj.info()->addParam(obj, "maxArea",          obj.params.maxArea);
                  obj.info()->addParam(obj, "filterByCircularity", obj.params.filterByCircularity);
                  obj.info()->addParam(obj, "maxCircularity",   obj.params.maxCircularity);
                  obj.info()->addParam(obj, "filterByInertia",  obj.params.filterByInertia);
                  obj.info()->addParam(obj, "maxInertiaRatio",  obj.params.maxInertiaRatio);
                  obj.info()->addParam(obj, "filterByConvexity", obj.params.filterByConvexity);
                  obj.info()->addParam(obj, "maxConvexity",     obj.params.maxConvexity);
                  );

///////////////////////////////////////////////////////////////////////////////////////////////////////////

class CV_EXPORTS HarrisDetector : public GFTTDetector
{
public:
    HarrisDetector( int maxCorners=1000, double qualityLevel=0.01, double minDistance=1,
                    int blockSize=3, bool useHarrisDetector=true, double k=0.04 );
    AlgorithmInfo* info() const;
};

inline HarrisDetector::HarrisDetector( int _maxCorners, double _qualityLevel, double _minDistance,
                    int _blockSize, bool _useHarrisDetector, double _k )
    : GFTTDetector( _maxCorners, _qualityLevel, _minDistance, _blockSize, _useHarrisDetector, _k ) {}

CV_INIT_ALGORITHM(HarrisDetector, "Feature2D.HARRIS",
                  obj.info()->addParam(obj, "nfeatures", obj.nfeatures);
                  obj.info()->addParam(obj, "qualityLevel", obj.qualityLevel);
                  obj.info()->addParam(obj, "minDistance", obj.minDistance);
                  obj.info()->addParam(obj, "useHarrisDetector", obj.useHarrisDetector);
                  obj.info()->addParam(obj, "k", obj.k));

////////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(DenseFeatureDetector, "Feature2D.Dense",
                  obj.info()->addParam(obj, "initFeatureScale", obj.initFeatureScale);
                  obj.info()->addParam(obj, "featureScaleLevels", obj.featureScaleLevels);
                  obj.info()->addParam(obj, "featureScaleMul", obj.featureScaleMul);
                  obj.info()->addParam(obj, "initXyStep", obj.initXyStep);
                  obj.info()->addParam(obj, "initImgBound", obj.initImgBound);
                  obj.info()->addParam(obj, "varyXyStepWithScale", obj.varyXyStepWithScale);
                  obj.info()->addParam(obj, "varyImgBoundWithScale", obj.varyImgBoundWithScale));

CV_INIT_ALGORITHM(GridAdaptedFeatureDetector, "Feature2D.Grid",
                  obj.info()->addParam<FeatureDetector>(obj, "detector", obj.detector, false, 0, 0, "Detector algorithm."); // Extra params added to avoid VS2013 fatal error in opencv2/core.hpp (decl. of addParam)
                  obj.info()->addParam(obj, "maxTotalKeypoints", obj.maxTotalKeypoints);
                  obj.info()->addParam(obj, "gridRows", obj.gridRows);
                  obj.info()->addParam(obj, "gridCols", obj.gridCols));

////////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(BFMatcher, "DescriptorMatcher.BFMatcher",
                  obj.info()->addParam(obj, "normType", obj.normType);
                  obj.info()->addParam(obj, "crossCheck", obj.crossCheck));

CV_INIT_ALGORITHM(FlannBasedMatcher, "DescriptorMatcher.FlannBasedMatcher",);

///////////////////////////////////////////////////////////////////////////////////////////////////////////

bool cv::initModule_features2d(void)
{
    bool all = true;
    all &= !BriefDescriptorExtractor_info_auto.name().empty();
    all &= !BRISK_info_auto.name().empty();
    all &= !FastFeatureDetector_info_auto.name().empty();
    all &= !StarDetector_info_auto.name().empty();
    all &= !MSER_info_auto.name().empty();
    all &= !FREAK_info_auto.name().empty();
    all &= !ORB_info_auto.name().empty();
    all &= !GFTTDetector_info_auto.name().empty();
    all &= !HarrisDetector_info_auto.name().empty();
    all &= !DenseFeatureDetector_info_auto.name().empty();
    all &= !GridAdaptedFeatureDetector_info_auto.name().empty();
    all &= !BFMatcher_info_auto.name().empty();
    all &= !FlannBasedMatcher_info_auto.name().empty();

    return all;
}
<commit_msg>Minimized the number of arguments required to workaround the MSVC2013 compiler bug.<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                          License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#include "precomp.hpp"

using namespace cv;

Ptr<Feature2D> Feature2D::create( const String& feature2DType )
{
    return Algorithm::create<Feature2D>("Feature2D." + feature2DType);
}

/////////////////////// AlgorithmInfo for various detector & descriptors ////////////////////////////

/* NOTE!!!
   All the AlgorithmInfo-related stuff should be in the same file as initModule_features2d().
   Otherwise, linker may throw away some seemingly unused stuff.
*/

CV_INIT_ALGORITHM(BRISK, "Feature2D.BRISK",
                   obj.info()->addParam(obj, "thres", obj.threshold);
                   obj.info()->addParam(obj, "octaves", obj.octaves));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(BriefDescriptorExtractor, "Feature2D.BRIEF",
                  obj.info()->addParam(obj, "bytes", obj.bytes_));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(FastFeatureDetector, "Feature2D.FAST",
                  obj.info()->addParam(obj, "threshold", obj.threshold);
                  obj.info()->addParam(obj, "nonmaxSuppression", obj.nonmaxSuppression);
                  obj.info()->addParam(obj, "type", obj.type));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(StarDetector, "Feature2D.STAR",
                  obj.info()->addParam(obj, "maxSize", obj.maxSize);
                  obj.info()->addParam(obj, "responseThreshold", obj.responseThreshold);
                  obj.info()->addParam(obj, "lineThresholdProjected", obj.lineThresholdProjected);
                  obj.info()->addParam(obj, "lineThresholdBinarized", obj.lineThresholdBinarized);
                  obj.info()->addParam(obj, "suppressNonmaxSize", obj.suppressNonmaxSize));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(MSER, "Feature2D.MSER",
                  obj.info()->addParam(obj, "delta", obj.delta);
                  obj.info()->addParam(obj, "minArea", obj.minArea);
                  obj.info()->addParam(obj, "maxArea", obj.maxArea);
                  obj.info()->addParam(obj, "maxVariation", obj.maxVariation);
                  obj.info()->addParam(obj, "minDiversity", obj.minDiversity);
                  obj.info()->addParam(obj, "maxEvolution", obj.maxEvolution);
                  obj.info()->addParam(obj, "areaThreshold", obj.areaThreshold);
                  obj.info()->addParam(obj, "minMargin", obj.minMargin);
                  obj.info()->addParam(obj, "edgeBlurSize", obj.edgeBlurSize));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(ORB, "Feature2D.ORB",
                  obj.info()->addParam(obj, "nFeatures", obj.nfeatures);
                  obj.info()->addParam(obj, "scaleFactor", obj.scaleFactor);
                  obj.info()->addParam(obj, "nLevels", obj.nlevels);
                  obj.info()->addParam(obj, "firstLevel", obj.firstLevel);
                  obj.info()->addParam(obj, "edgeThreshold", obj.edgeThreshold);
                  obj.info()->addParam(obj, "patchSize", obj.patchSize);
                  obj.info()->addParam(obj, "WTA_K", obj.WTA_K);
                  obj.info()->addParam(obj, "scoreType", obj.scoreType));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(FREAK, "Feature2D.FREAK",
                  obj.info()->addParam(obj, "orientationNormalized", obj.orientationNormalized);
                  obj.info()->addParam(obj, "scaleNormalized", obj.scaleNormalized);
                  obj.info()->addParam(obj, "patternScale", obj.patternScale);
                  obj.info()->addParam(obj, "nbOctave", obj.nOctaves));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(GFTTDetector, "Feature2D.GFTT",
                  obj.info()->addParam(obj, "nfeatures", obj.nfeatures);
                  obj.info()->addParam(obj, "qualityLevel", obj.qualityLevel);
                  obj.info()->addParam(obj, "minDistance", obj.minDistance);
                  obj.info()->addParam(obj, "useHarrisDetector", obj.useHarrisDetector);
                  obj.info()->addParam(obj, "k", obj.k));

///////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(SimpleBlobDetector, "Feature2D.SimpleBlob",
                  obj.info()->addParam(obj, "thresholdStep",    obj.params.thresholdStep);
                  obj.info()->addParam(obj, "minThreshold",     obj.params.minThreshold);
                  obj.info()->addParam(obj, "maxThreshold",     obj.params.maxThreshold);
                  obj.info()->addParam_(obj, "minRepeatability", (sizeof(size_t) == sizeof(uint64))?Param::UINT64 : Param::UNSIGNED_INT, &obj.params.minRepeatability, false, 0, 0);
                  obj.info()->addParam(obj, "minDistBetweenBlobs", obj.params.minDistBetweenBlobs);
                  obj.info()->addParam(obj, "filterByColor",    obj.params.filterByColor);
                  obj.info()->addParam(obj, "blobColor",        obj.params.blobColor);
                  obj.info()->addParam(obj, "filterByArea",     obj.params.filterByArea);
                  obj.info()->addParam(obj, "maxArea",          obj.params.maxArea);
                  obj.info()->addParam(obj, "filterByCircularity", obj.params.filterByCircularity);
                  obj.info()->addParam(obj, "maxCircularity",   obj.params.maxCircularity);
                  obj.info()->addParam(obj, "filterByInertia",  obj.params.filterByInertia);
                  obj.info()->addParam(obj, "maxInertiaRatio",  obj.params.maxInertiaRatio);
                  obj.info()->addParam(obj, "filterByConvexity", obj.params.filterByConvexity);
                  obj.info()->addParam(obj, "maxConvexity",     obj.params.maxConvexity);
                  );

///////////////////////////////////////////////////////////////////////////////////////////////////////////

class CV_EXPORTS HarrisDetector : public GFTTDetector
{
public:
    HarrisDetector( int maxCorners=1000, double qualityLevel=0.01, double minDistance=1,
                    int blockSize=3, bool useHarrisDetector=true, double k=0.04 );
    AlgorithmInfo* info() const;
};

inline HarrisDetector::HarrisDetector( int _maxCorners, double _qualityLevel, double _minDistance,
                    int _blockSize, bool _useHarrisDetector, double _k )
    : GFTTDetector( _maxCorners, _qualityLevel, _minDistance, _blockSize, _useHarrisDetector, _k ) {}

CV_INIT_ALGORITHM(HarrisDetector, "Feature2D.HARRIS",
                  obj.info()->addParam(obj, "nfeatures", obj.nfeatures);
                  obj.info()->addParam(obj, "qualityLevel", obj.qualityLevel);
                  obj.info()->addParam(obj, "minDistance", obj.minDistance);
                  obj.info()->addParam(obj, "useHarrisDetector", obj.useHarrisDetector);
                  obj.info()->addParam(obj, "k", obj.k));

////////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(DenseFeatureDetector, "Feature2D.Dense",
                  obj.info()->addParam(obj, "initFeatureScale", obj.initFeatureScale);
                  obj.info()->addParam(obj, "featureScaleLevels", obj.featureScaleLevels);
                  obj.info()->addParam(obj, "featureScaleMul", obj.featureScaleMul);
                  obj.info()->addParam(obj, "initXyStep", obj.initXyStep);
                  obj.info()->addParam(obj, "initImgBound", obj.initImgBound);
                  obj.info()->addParam(obj, "varyXyStepWithScale", obj.varyXyStepWithScale);
                  obj.info()->addParam(obj, "varyImgBoundWithScale", obj.varyImgBoundWithScale));

CV_INIT_ALGORITHM(GridAdaptedFeatureDetector, "Feature2D.Grid",
                  obj.info()->addParam<FeatureDetector>(obj, "detector", obj.detector, false, 0, 0); // Extra params added to avoid VS2013 fatal error in opencv2/core.hpp (decl. of addParam)
                  obj.info()->addParam(obj, "maxTotalKeypoints", obj.maxTotalKeypoints);
                  obj.info()->addParam(obj, "gridRows", obj.gridRows);
                  obj.info()->addParam(obj, "gridCols", obj.gridCols));

////////////////////////////////////////////////////////////////////////////////////////////////////////////

CV_INIT_ALGORITHM(BFMatcher, "DescriptorMatcher.BFMatcher",
                  obj.info()->addParam(obj, "normType", obj.normType);
                  obj.info()->addParam(obj, "crossCheck", obj.crossCheck));

CV_INIT_ALGORITHM(FlannBasedMatcher, "DescriptorMatcher.FlannBasedMatcher",);

///////////////////////////////////////////////////////////////////////////////////////////////////////////

bool cv::initModule_features2d(void)
{
    bool all = true;
    all &= !BriefDescriptorExtractor_info_auto.name().empty();
    all &= !BRISK_info_auto.name().empty();
    all &= !FastFeatureDetector_info_auto.name().empty();
    all &= !StarDetector_info_auto.name().empty();
    all &= !MSER_info_auto.name().empty();
    all &= !FREAK_info_auto.name().empty();
    all &= !ORB_info_auto.name().empty();
    all &= !GFTTDetector_info_auto.name().empty();
    all &= !HarrisDetector_info_auto.name().empty();
    all &= !DenseFeatureDetector_info_auto.name().empty();
    all &= !GridAdaptedFeatureDetector_info_auto.name().empty();
    all &= !BFMatcher_info_auto.name().empty();
    all &= !FlannBasedMatcher_info_auto.name().empty();

    return all;
}
<|endoftext|>


<commit_before>/*
 Flexisip, a flexible SIP proxy server with media capabilities.
 Copyright (C) 2012  Belledonne Communications SARL.

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as
 published by the Free Software Foundation, either version 3 of the
 License, or (at your option) any later version.

 This program 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 Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "forkcallcontext.hh"
#include "common.hh"
#include <algorithm>
#include <sofia-sip/sip_status.h>

using namespace ::std;

template<typename T>
static bool contains(const list<T> &l, T value) {
	return find(l.cbegin(), l.cend(), value) != l.cend();
}

ForkCallContext::ForkCallContext(Agent *agent, const std::shared_ptr<RequestSipEvent> &event, shared_ptr<ForkContextConfig> cfg, ForkContextListener* listener) :
		ForkContext(agent, event,cfg, listener), mShortTimer(NULL), mPushTimer(NULL), mCancelled(false) {
	LOGD("New ForkCallContext %p", this);
	mLog=event->getEventLog<CallLog>();
	mActivePushes = 0;
}

ForkCallContext::~ForkCallContext() {
	LOGD("Destroy ForkCallContext %p", this);
	if (mShortTimer){
		su_timer_destroy(mShortTimer);
		mShortTimer=NULL;
	}
	if (mPushTimer){
		su_timer_destroy(mPushTimer);
		mPushTimer=NULL;
	}
}

void ForkCallContext::onCancel() {
	mLog->setCancelled();
	mLog->setCompleted();
	mCancelled=true;
	cancelOthers(shared_ptr<BranchInfo>());
}

void ForkCallContext::cancelOthers(const shared_ptr<BranchInfo> & br) {
	list<shared_ptr<BranchInfo>> branches=getBranches();
	for (auto it = branches.begin(); it != branches.end();++it) {
		shared_ptr<BranchInfo> brit=*it;
		if (brit != br) {
			shared_ptr<OutgoingTransaction> tr = brit->mTransaction;
			removeBranch(brit);
			if (brit->getStatus()<200)
				tr->cancel();
		}
	}
}

const int ForkCallContext::sUrgentCodesWithout603[]={401,407,415,420,484,488,606,0};

const int * ForkCallContext::getUrgentCodes(){
	return mCfg->mTreatDeclineAsUrgent ? ForkContext::sUrgentCodes : sUrgentCodesWithout603;
}

void ForkCallContext::onResponse(const shared_ptr<BranchInfo> & br, const shared_ptr<ResponseSipEvent> &event) {
	const shared_ptr<MsgSip> &ms = event->getMsgSip();
	sip_t *sip = ms->getSip();
	int code=sip->sip_status->st_status;

	if (code>=300){
		/*in fork-late mode, we must not consider that 503 resonse code (which are send by sofia in case of i/o error) are branches that are answered)
		 * Instead we must wait for the duration of the fork for new registers*/
		if (allBranchesAnswered(mCfg->mForkLate)){
			shared_ptr<BranchInfo> best=findBestBranch(getUrgentCodes());
			if (best) logResponse(forwardResponse(best));
			return;
		}
		if (isUrgent(code,getUrgentCodes()) && mShortTimer==NULL){
			mShortTimer=su_timer_create(su_root_task(mAgent->getRoot()), 0);
			su_timer_set_interval(mShortTimer, &ForkCallContext::sOnShortTimer, this, (su_duration_t)mCfg->mUrgentTimeout*1000);
			return;
		}
		if (code>=600){
			/*6xx response are normally treated as global faillures */
			if (!mCfg->mForkNoGlobalDecline){
				logResponse(forwardResponse(br));
				cancelOthers(br);
			}
		}
	}else if (code>=200){
		logResponse(forwardResponse(br));
		cancelOthers(br);
	}else if (code>=100){
		logResponse(forwardResponse(br));
	}
}

//This is actually called when we want to simulate a ringing event, for example when a push notification is sent to a device.
void ForkCallContext::sendRinging(){
	int code=getLastResponseCode();
	if (code<180){
		shared_ptr<MsgSip> msgsip(mIncoming->createResponse(SIP_180_RINGING));
		shared_ptr<ResponseSipEvent> ev(new ResponseSipEvent(dynamic_pointer_cast<OutgoingAgent>(mAgent->shared_from_this()), msgsip));
		//add a to tag, no set by sofia here.
		if (!mCfg->mRemoveToTag) {
			const char *totag=nta_agent_newtag(msgsip->getHome(),"%s",mAgent->getSofiaAgent());
			sip_to_tag(msgsip->getHome(), msgsip->getSip()->sip_to, totag);
		}
		if (mPushTimer) su_timer_destroy(mPushTimer), mPushTimer=NULL;
		if (mCfg->mPushResponseTimeout > 0) {
			mPushTimer=su_timer_create(su_root_task(mAgent->getRoot()), 0);
			su_timer_set_interval(mPushTimer, &ForkCallContext::sOnPushTimer, this, (su_duration_t)mCfg->mPushResponseTimeout*1000);
		}
		forwardResponse(ev);
	}
}

void ForkCallContext::logResponse(const shared_ptr<ResponseSipEvent> &ev){
	if (ev){
		sip_t *sip=ev->getMsgSip()->getSip();
		mLog->setStatusCode(sip->sip_status->st_status,sip->sip_status->st_phrase);
		if (sip->sip_status->st_status>=200)
			mLog->setCompleted();
		ev->setEventLog(mLog);
	}
}

bool ForkCallContext::onNewRegister(const url_t *url, const string &uid){
	if (isCompleted()) return false;
	return ForkContext::onNewRegister(url,uid);
}

bool ForkCallContext::isCompleted()const{
	if (getLastResponseCode()>=200 || mCancelled) return true;
	return false;
}

void ForkCallContext::onShortTimer(){
	LOGD("ForkCallContext [%p]: time to send urgent replies",this);
	/*first stop the timer, it has to be one shot*/
	su_timer_destroy(mShortTimer);
	mShortTimer=NULL;

	if (getLastResponseCode()>=180) return; /*it's ringing somewhere*/
	auto br=findBestBranch(getUrgentCodes());
	if (br){
		logResponse(forwardResponse(br));
	}
}

void ForkCallContext::onLateTimeout() {
	auto br=findBestBranch(getUrgentCodes());
	if (!br || br->getStatus()==0 || br->getStatus()==503){
		shared_ptr<MsgSip> msgsip(mIncoming->createResponse(SIP_408_REQUEST_TIMEOUT));
		shared_ptr<ResponseSipEvent> ev(new ResponseSipEvent(dynamic_pointer_cast<OutgoingAgent>(mAgent->shared_from_this()), msgsip));
		logResponse(forwardResponse(ev));
	}else{
		logResponse(forwardResponse(br));
	}
	/*cancel all possibly pending outgoing transactions*/
	cancelOthers(shared_ptr<BranchInfo>());
}

void ForkCallContext::sOnShortTimer(su_root_magic_t *magic, su_timer_t *t, su_timer_arg_t *arg){
	ForkCallContext *zis=static_cast<ForkCallContext*>(arg);
	zis->onShortTimer();
}

void ForkCallContext::onPushTimer(){
	if (!isCompleted() && getLastResponseCode()<180) {
		SLOGD << "ForkCallContext " << this << " push timer : no uac response";
	}
	su_timer_destroy(mPushTimer);
	mPushTimer=NULL;
}

void ForkCallContext::sOnPushTimer(su_root_magic_t *magic, su_timer_t *t, su_timer_arg_t *arg){
	ForkCallContext *zis=static_cast<ForkCallContext*>(arg);
	zis->onPushTimer();
}
void ForkCallContext::onPushInitiated(const string &key) {
	++mActivePushes;
}

void ForkCallContext::onPushError(const string &key, const string &errormsg) {
	--mActivePushes;
	if (mActivePushes != 0) return;
	SLOGD << "Early fail due to all push requests having failed";
	onPushTimer();
}

<commit_msg>fix bug in forkcallcontext<commit_after>/*
 Flexisip, a flexible SIP proxy server with media capabilities.
 Copyright (C) 2012  Belledonne Communications SARL.

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as
 published by the Free Software Foundation, either version 3 of the
 License, or (at your option) any later version.

 This program 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 Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "forkcallcontext.hh"
#include "common.hh"
#include <algorithm>
#include <sofia-sip/sip_status.h>

using namespace ::std;

template<typename T>
static bool contains(const list<T> &l, T value) {
	return find(l.cbegin(), l.cend(), value) != l.cend();
}

ForkCallContext::ForkCallContext(Agent *agent, const std::shared_ptr<RequestSipEvent> &event, shared_ptr<ForkContextConfig> cfg, ForkContextListener* listener) :
		ForkContext(agent, event,cfg, listener), mShortTimer(NULL), mPushTimer(NULL), mCancelled(false) {
	LOGD("New ForkCallContext %p", this);
	mLog=event->getEventLog<CallLog>();
	mActivePushes = 0;
}

ForkCallContext::~ForkCallContext() {
	LOGD("Destroy ForkCallContext %p", this);
	if (mShortTimer){
		su_timer_destroy(mShortTimer);
		mShortTimer=NULL;
	}
	if (mPushTimer){
		su_timer_destroy(mPushTimer);
		mPushTimer=NULL;
	}
}

void ForkCallContext::onCancel() {
	mLog->setCancelled();
	mLog->setCompleted();
	mCancelled=true;
	cancelOthers(shared_ptr<BranchInfo>());
}

void ForkCallContext::cancelOthers(const shared_ptr<BranchInfo> & br) {
	list<shared_ptr<BranchInfo>> branches=getBranches();
	for (auto it = branches.begin(); it != branches.end();++it) {
		shared_ptr<BranchInfo> brit=*it;
		if (brit != br) {
			shared_ptr<OutgoingTransaction> tr = brit->mTransaction;
			if (brit->getStatus()<200 && tr)
				tr->cancel();
			removeBranch(brit);

		}
	}
}

const int ForkCallContext::sUrgentCodesWithout603[]={401,407,415,420,484,488,606,0};

const int * ForkCallContext::getUrgentCodes(){
	return mCfg->mTreatDeclineAsUrgent ? ForkContext::sUrgentCodes : sUrgentCodesWithout603;
}

void ForkCallContext::onResponse(const shared_ptr<BranchInfo> & br, const shared_ptr<ResponseSipEvent> &event) {
	const shared_ptr<MsgSip> &ms = event->getMsgSip();
	sip_t *sip = ms->getSip();
	int code=sip->sip_status->st_status;

	if (code>=300){
		/*in fork-late mode, we must not consider that 503 resonse code (which are send by sofia in case of i/o error) are branches that are answered)
		 * Instead we must wait for the duration of the fork for new registers*/
		if (allBranchesAnswered(mCfg->mForkLate)){
			shared_ptr<BranchInfo> best=findBestBranch(getUrgentCodes());
			if (best) logResponse(forwardResponse(best));
			return;
		}
		if (isUrgent(code,getUrgentCodes()) && mShortTimer==NULL){
			mShortTimer=su_timer_create(su_root_task(mAgent->getRoot()), 0);
			su_timer_set_interval(mShortTimer, &ForkCallContext::sOnShortTimer, this, (su_duration_t)mCfg->mUrgentTimeout*1000);
			return;
		}
		if (code>=600){
			/*6xx response are normally treated as global faillures */
			if (!mCfg->mForkNoGlobalDecline){
				logResponse(forwardResponse(br));
				cancelOthers(br);
			}
		}
	}else if (code>=200){
		logResponse(forwardResponse(br));
		cancelOthers(br);
	}else if (code>=100){
		logResponse(forwardResponse(br));
	}
}

//This is actually called when we want to simulate a ringing event, for example when a push notification is sent to a device.
void ForkCallContext::sendRinging(){
	int code=getLastResponseCode();
	if (code<180){
		shared_ptr<MsgSip> msgsip(mIncoming->createResponse(SIP_180_RINGING));
		shared_ptr<ResponseSipEvent> ev(new ResponseSipEvent(dynamic_pointer_cast<OutgoingAgent>(mAgent->shared_from_this()), msgsip));
		//add a to tag, no set by sofia here.
		if (!mCfg->mRemoveToTag) {
			const char *totag=nta_agent_newtag(msgsip->getHome(),"%s",mAgent->getSofiaAgent());
			sip_to_tag(msgsip->getHome(), msgsip->getSip()->sip_to, totag);
		}
		if (mPushTimer) su_timer_destroy(mPushTimer), mPushTimer=NULL;
		if (mCfg->mPushResponseTimeout > 0) {
			mPushTimer=su_timer_create(su_root_task(mAgent->getRoot()), 0);
			su_timer_set_interval(mPushTimer, &ForkCallContext::sOnPushTimer, this, (su_duration_t)mCfg->mPushResponseTimeout*1000);
		}
		forwardResponse(ev);
	}
}

void ForkCallContext::logResponse(const shared_ptr<ResponseSipEvent> &ev){
	if (ev){
		sip_t *sip=ev->getMsgSip()->getSip();
		mLog->setStatusCode(sip->sip_status->st_status,sip->sip_status->st_phrase);
		if (sip->sip_status->st_status>=200)
			mLog->setCompleted();
		ev->setEventLog(mLog);
	}
}

bool ForkCallContext::onNewRegister(const url_t *url, const string &uid){
	if (isCompleted()) return false;
	return ForkContext::onNewRegister(url,uid);
}

bool ForkCallContext::isCompleted()const{
	if (getLastResponseCode()>=200 || mCancelled) return true;
	return false;
}

void ForkCallContext::onShortTimer(){
	LOGD("ForkCallContext [%p]: time to send urgent replies",this);
	/*first stop the timer, it has to be one shot*/
	su_timer_destroy(mShortTimer);
	mShortTimer=NULL;

	if (getLastResponseCode()>=180) return; /*it's ringing somewhere*/
	auto br=findBestBranch(getUrgentCodes());
	if (br){
		logResponse(forwardResponse(br));
	}
}

void ForkCallContext::onLateTimeout() {
	auto br=findBestBranch(getUrgentCodes());
	if (!br || br->getStatus()==0 || br->getStatus()==503){
		shared_ptr<MsgSip> msgsip(mIncoming->createResponse(SIP_408_REQUEST_TIMEOUT));
		shared_ptr<ResponseSipEvent> ev(new ResponseSipEvent(dynamic_pointer_cast<OutgoingAgent>(mAgent->shared_from_this()), msgsip));
		logResponse(forwardResponse(ev));
	}else{
		logResponse(forwardResponse(br));
	}
	/*cancel all possibly pending outgoing transactions*/
	cancelOthers(shared_ptr<BranchInfo>());
}

void ForkCallContext::sOnShortTimer(su_root_magic_t *magic, su_timer_t *t, su_timer_arg_t *arg){
	ForkCallContext *zis=static_cast<ForkCallContext*>(arg);
	zis->onShortTimer();
}

void ForkCallContext::onPushTimer(){
	if (!isCompleted() && getLastResponseCode()<180) {
		SLOGD << "ForkCallContext " << this << " push timer : no uac response";
	}
	su_timer_destroy(mPushTimer);
	mPushTimer=NULL;
}

void ForkCallContext::sOnPushTimer(su_root_magic_t *magic, su_timer_t *t, su_timer_arg_t *arg){
	ForkCallContext *zis=static_cast<ForkCallContext*>(arg);
	zis->onPushTimer();
}
void ForkCallContext::onPushInitiated(const string &key) {
	++mActivePushes;
}

void ForkCallContext::onPushError(const string &key, const string &errormsg) {
	--mActivePushes;
	if (mActivePushes != 0) return;
	SLOGD << "Early fail due to all push requests having failed";
	onPushTimer();
}

<|endoftext|>


<commit_before>/*
* (C) 2019 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "fuzzers.h"
#include <botan/x509_dn.h>
#include <botan/ber_dec.h>
#include <botan/hex.h>

void fuzz(const uint8_t in[], size_t len)
   {
   const size_t half = len / 2;
   Botan::X509_DN dn1;
   Botan::X509_DN dn2;

   try
      {
      Botan::BER_Decoder ber1(in, half);
      dn1.decode_from(ber1);
      ber1.verify_end();

      Botan::BER_Decoder ber2(in + half, half);
      dn2.decode_from(ber2);
      ber2.verify_end();
      }
   catch(...) { return; }

   const bool eq = dn1 == dn2;
   const bool lt1 = dn1 < dn2;
   const bool lt2 = dn2 < dn1;

   if(lt1 == false && lt2 == false)
      {
      FUZZER_ASSERT_TRUE(eq);
      }
   else
      {
      // one is less than the other
      FUZZER_ASSERT_TRUE(lt1 || lt2);

      // it is not the case that both are less than the other
      FUZZER_ASSERT_TRUE(!lt1 || !lt2);
      }
   }
<commit_msg>In X509 DN fuzzer allow the names to be different lengths<commit_after>/*
* (C) 2019 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "fuzzers.h"
#include <botan/x509_dn.h>
#include <botan/ber_dec.h>
#include <botan/hex.h>

void fuzz(const uint8_t in[], size_t len)
   {
   Botan::X509_DN dn1;
   Botan::X509_DN dn2;

   try
      {
      Botan::BER_Decoder ber(in, len);
      dn1.decode_from(ber);
      dn2.decode_from(ber);
      }
   catch(...) { return; }

   const bool eq = dn1 == dn2;
   const bool lt1 = dn1 < dn2;
   const bool lt2 = dn2 < dn1;

   if(lt1 == false && lt2 == false)
      {
      FUZZER_ASSERT_TRUE(eq);
      }
   else
      {
      // one is less than the other
      FUZZER_ASSERT_TRUE(lt1 || lt2);

      // it is not the case that both are less than the other
      FUZZER_ASSERT_TRUE(!lt1 || !lt2);
      }
   }
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/perception/obstacle/base/object.h"

#include "modules/common/log.h"
#include "modules/common/macro.h"
#include "modules/common/util/string_util.h"
#include "modules/perception/common/perception_gflags.h"

namespace apollo {
namespace perception {

using Eigen::Vector3d;
using apollo::common::util::Print;
using apollo::common::util::StrCat;

Object::Object() {
  cloud.reset(new pcl_util::PointCloud);
  type_probs.resize(static_cast<int>(ObjectType::MAX_OBJECT_TYPE), 0);
  position_uncertainty << 0.01, 0, 0, 0, 0.01, 0, 0, 0, 0.01;
  velocity_uncertainty << 0.01, 0, 0, 0, 0.01, 0, 0, 0, 0.01;
}

void Object::clone(const Object& rhs) {
  *this = rhs;
  pcl::copyPointCloud<pcl_util::Point, pcl_util::Point>(*(rhs.cloud), *cloud);
  radar_supplement = nullptr;
  if (rhs.radar_supplement != nullptr) {
    radar_supplement.reset(new RadarSupplement(*rhs.radar_supplement));
  }
  camera_supplement = nullptr;
  if (rhs.camera_supplement != nullptr) {
    camera_supplement.reset(new CameraSupplement());
    camera_supplement->clone(*(rhs.camera_supplement));
  }
}

std::string Object::ToString() const {
  // StrCat supports 9 arguments at most.
  return StrCat(StrCat("Object[id: ", id,
                       ", "
                       "track_id: ",
                       track_id,
                       ", "
                       "cloud_size: ",
                       cloud->size(),
                       ", "
                       "direction: ",
                       Print(direction.transpose()), ", "),
                StrCat("center: ", Print(center.transpose()),
                       ", "
                       "velocity: ",
                       Print(velocity.transpose()),
                       ", "
                       "width: ",
                       width,
                       ", "
                       "length: ",
                       length, ", "),
                StrCat("height: ", height,
                       ", "
                       "polygon_size: ",
                       polygon.size(),
                       ", "
                       "type: ",
                       static_cast<int>(type),
                       ", "
                       "is_background: ",
                       is_background),
                StrCat(", is_cipv: ",
                       b_cipv, "]"));
}

// Add 4 corners in the polygon
void Object::AddFourCorners(PerceptionObstacle* pb_obj) const {
  double cos_theta = cos(theta);
  double sin_theta = sin(theta);

  double half_width = width / 2;
  double minus_half_width = -half_width;
  double half_length = length / 2;
  double minus_half_length = -half_length;

  Point* p1 = pb_obj->add_polygon_point();
  p1->set_x(minus_half_width * cos_theta + half_length * sin_theta + center(0));
  p1->set_y(half_length * cos_theta - minus_half_width * sin_theta + center(1));
  p1->set_z(0.0);

  Point* p2 = pb_obj->add_polygon_point();
  p2->set_x(minus_half_width * cos_theta + minus_half_length * sin_theta
            + center(0));
  p2->set_y(minus_half_length * cos_theta - minus_half_width * sin_theta
            + center(1));
  p2->set_z(0.0);

  Point* p3 = pb_obj->add_polygon_point();
  p3->set_x(half_width * cos_theta + half_length * sin_theta + center(0));
  p3->set_y(half_length * cos_theta - half_width * sin_theta + center(1));
  p3->set_z(0.0);

  Point* p4 = pb_obj->add_polygon_point();
  p4->set_x(half_width * cos_theta + minus_half_length * sin_theta + center(0));
  p4->set_y(minus_half_length * cos_theta - half_width * sin_theta + center(1));
  p4->set_z(0.0);
}

void Object::Serialize(PerceptionObstacle* pb_obj) const {
  CHECK(pb_obj != nullptr);
  pb_obj->set_id(track_id);
  pb_obj->set_theta(theta);

  Point* obj_center = pb_obj->mutable_position();
  obj_center->set_x(center(0));
  obj_center->set_y(center(1));
  obj_center->set_z(center(2));

  Point* obj_velocity = pb_obj->mutable_velocity();
  obj_velocity->set_x(velocity(0));
  obj_velocity->set_y(velocity(1));
  obj_velocity->set_z(velocity(2));

  pb_obj->set_length(length);
  pb_obj->set_width(width);
  pb_obj->set_height(height);

  if (polygon.size() /*pb_obs.polygon_point_size() */ >= 4) {
    for (auto point : polygon.points) {
      Point* p = pb_obj->add_polygon_point();
      p->set_x(point.x);
      p->set_y(point.y);
      p->set_z(point.z);
    }
  } else {  // if polygon size is less than 4
    // Generate polygon from center position, width, height
    // and orientation of the object
    AddFourCorners(pb_obj);
  }

  if (FLAGS_is_serialize_point_cloud) {
    for (auto point : cloud->points) {
      pb_obj->add_point_cloud(point.x);
      pb_obj->add_point_cloud(point.y);
      pb_obj->add_point_cloud(point.z);
    }
  }

  pb_obj->set_confidence(score);
  pb_obj->set_confidence_type(
      static_cast<PerceptionObstacle::ConfidenceType>(score_type));
  pb_obj->set_tracking_time(tracking_time);
  pb_obj->set_type(static_cast<PerceptionObstacle::Type>(type));
  pb_obj->set_timestamp(latest_tracked_time);  // in seconds.
}

void Object::Deserialize(const PerceptionObstacle& pb_obs) {
  track_id = pb_obs.id();
  theta = pb_obs.theta();

  center(0) = pb_obs.position().x();
  center(1) = pb_obs.position().y();
  center(2) = pb_obs.position().z();

  velocity(0) = pb_obs.velocity().x();
  velocity(1) = pb_obs.velocity().y();
  velocity(2) = pb_obs.velocity().z();

  length = pb_obs.length();
  width = pb_obs.width();
  height = pb_obs.height();

  polygon.clear();
  for (int idx = 0; idx < pb_obs.polygon_point_size(); ++idx) {
    const auto& p = pb_obs.polygon_point(idx);
    pcl_util::PointD point;
    point.x = p.x();
    point.y = p.y();
    point.z = p.z();
    polygon.push_back(point);
  }

  score = pb_obs.confidence();
  score_type = static_cast<ScoreType>(pb_obs.confidence_type());
  tracking_time = pb_obs.tracking_time();
  latest_tracked_time = pb_obs.timestamp();
  type = static_cast<ObjectType>(pb_obs.type());
}

std::string SensorObjects::ToString() const {
  std::ostringstream oss;
  oss << "sensor_type: " << GetSensorType(sensor_type)
      << ", timestamp:" << GLOG_TIMESTAMP(timestamp)
      << ", sensor2world_pose:\n";
  oss << sensor2world_pose << "\n, objects: " << objects.size() << " < ";
  for (auto obj : objects) {
    oss << "\n" << obj->ToString();
  }
  oss << " >]";
  return oss.str();
}

}  // namespace perception
}  // namespace apollo
<commit_msg>Perception: Fixed bounding box issue (#3634)<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/perception/obstacle/base/object.h"

#include "modules/common/log.h"
#include "modules/common/macro.h"
#include "modules/common/util/string_util.h"
#include "modules/perception/common/perception_gflags.h"

namespace apollo {
namespace perception {

using Eigen::Vector3d;
using apollo::common::util::Print;
using apollo::common::util::StrCat;

Object::Object() {
  cloud.reset(new pcl_util::PointCloud);
  type_probs.resize(static_cast<int>(ObjectType::MAX_OBJECT_TYPE), 0);
  position_uncertainty << 0.01, 0, 0, 0, 0.01, 0, 0, 0, 0.01;
  velocity_uncertainty << 0.01, 0, 0, 0, 0.01, 0, 0, 0, 0.01;
}

void Object::clone(const Object& rhs) {
  *this = rhs;
  pcl::copyPointCloud<pcl_util::Point, pcl_util::Point>(*(rhs.cloud), *cloud);
  radar_supplement = nullptr;
  if (rhs.radar_supplement != nullptr) {
    radar_supplement.reset(new RadarSupplement(*rhs.radar_supplement));
  }
  camera_supplement = nullptr;
  if (rhs.camera_supplement != nullptr) {
    camera_supplement.reset(new CameraSupplement());
    camera_supplement->clone(*(rhs.camera_supplement));
  }
}

std::string Object::ToString() const {
  // StrCat supports 9 arguments at most.
  return StrCat(StrCat("Object[id: ", id,
                       ", "
                       "track_id: ",
                       track_id,
                       ", "
                       "cloud_size: ",
                       cloud->size(),
                       ", "
                       "direction: ",
                       Print(direction.transpose()), ", "),
                StrCat("center: ", Print(center.transpose()),
                       ", "
                       "velocity: ",
                       Print(velocity.transpose()),
                       ", "
                       "width: ",
                       width,
                       ", "
                       "length: ",
                       length, ", "),
                StrCat("height: ", height,
                       ", "
                       "polygon_size: ",
                       polygon.size(),
                       ", "
                       "type: ",
                       static_cast<int>(type),
                       ", "
                       "is_background: ",
                       is_background),
                StrCat(", is_cipv: ",
                       b_cipv, "]"));
}

// Add 4 corners in the polygon
void Object::AddFourCorners(PerceptionObstacle* pb_obj) const {
  double cos_theta = cos(theta);
  double sin_theta = sin(theta);

  double half_width = width / 2;
  double minus_half_width = -half_width;
  double half_length = length / 2;
  double minus_half_length = -half_length;

  Point* p1 = pb_obj->add_polygon_point();
  p1->set_x(minus_half_length * cos_theta + half_width * sin_theta + center(0));
  p1->set_y(half_width * cos_theta - minus_half_length * sin_theta + center(1));
  p1->set_z(0.0);

  Point* p2 = pb_obj->add_polygon_point();
  p2->set_x(minus_half_length * cos_theta + minus_half_width * sin_theta
            + center(0));
  p2->set_y(minus_half_width * cos_theta - minus_half_length * sin_theta
            + center(1));
  p2->set_z(0.0);

  Point* p3 = pb_obj->add_polygon_point();
  p3->set_x(half_length * cos_theta + minus_half_width * sin_theta + center(0));
  p3->set_y(minus_half_width * cos_theta - half_length * sin_theta + center(1));
  p3->set_z(0.0);

  Point* p4 = pb_obj->add_polygon_point();
  p4->set_x(half_length * cos_theta + half_width * sin_theta + center(0));
  p4->set_y(half_width * cos_theta - half_length * sin_theta + center(1));
  p4->set_z(0.0);

  // AINFO << "center : [" << center(0) << ", " << center(1) << ", "
  //       << center(2) << "]";
  // AINFO << "width: " << width << ", length: " << length;
  // AINFO << "theta: " << theta;

  // AINFO << "p1: [" << p1->x() << ", " << p1->y() << ", " << p1->z() << "]" ;
  // AINFO << "p2: [" << p2->x() << ", " << p2->y() << ", " << p2->z() << "]" ;
  // AINFO << "p3: [" << p3->x() << ", " << p3->y() << ", " << p3->z() << "]" ;
  // AINFO << "p4: [" << p4->x() << ", " << p4->y() << ", " << p4->z() << "]" ;
}

void Object::Serialize(PerceptionObstacle* pb_obj) const {
  CHECK(pb_obj != nullptr);
  pb_obj->set_id(track_id);
  pb_obj->set_theta(theta);

  Point* obj_center = pb_obj->mutable_position();
  obj_center->set_x(center(0));
  obj_center->set_y(center(1));
  obj_center->set_z(center(2));

  Point* obj_velocity = pb_obj->mutable_velocity();
  obj_velocity->set_x(velocity(0));
  obj_velocity->set_y(velocity(1));
  obj_velocity->set_z(velocity(2));

  pb_obj->set_length(length);
  pb_obj->set_width(width);
  pb_obj->set_height(height);

  if (polygon.size() /*pb_obs.polygon_point_size() */ >= 4) {
    for (auto point : polygon.points) {
      Point* p = pb_obj->add_polygon_point();
      p->set_x(point.x);
      p->set_y(point.y);
      p->set_z(point.z);
    }
  } else {  // if polygon size is less than 4
    // Generate polygon from center position, width, height
    // and orientation of the object
    AddFourCorners(pb_obj);
  }

  if (FLAGS_is_serialize_point_cloud) {
    for (auto point : cloud->points) {
      pb_obj->add_point_cloud(point.x);
      pb_obj->add_point_cloud(point.y);
      pb_obj->add_point_cloud(point.z);
    }
  }

  pb_obj->set_confidence(score);
  pb_obj->set_confidence_type(
      static_cast<PerceptionObstacle::ConfidenceType>(score_type));
  pb_obj->set_tracking_time(tracking_time);
  pb_obj->set_type(static_cast<PerceptionObstacle::Type>(type));
  pb_obj->set_timestamp(latest_tracked_time);  // in seconds.
}

void Object::Deserialize(const PerceptionObstacle& pb_obs) {
  track_id = pb_obs.id();
  theta = pb_obs.theta();

  center(0) = pb_obs.position().x();
  center(1) = pb_obs.position().y();
  center(2) = pb_obs.position().z();

  velocity(0) = pb_obs.velocity().x();
  velocity(1) = pb_obs.velocity().y();
  velocity(2) = pb_obs.velocity().z();

  length = pb_obs.length();
  width = pb_obs.width();
  height = pb_obs.height();

  polygon.clear();
  for (int idx = 0; idx < pb_obs.polygon_point_size(); ++idx) {
    const auto& p = pb_obs.polygon_point(idx);
    pcl_util::PointD point;
    point.x = p.x();
    point.y = p.y();
    point.z = p.z();
    polygon.push_back(point);
  }

  score = pb_obs.confidence();
  score_type = static_cast<ScoreType>(pb_obs.confidence_type());
  tracking_time = pb_obs.tracking_time();
  latest_tracked_time = pb_obs.timestamp();
  type = static_cast<ObjectType>(pb_obs.type());
}

std::string SensorObjects::ToString() const {
  std::ostringstream oss;
  oss << "sensor_type: " << GetSensorType(sensor_type)
      << ", timestamp:" << GLOG_TIMESTAMP(timestamp)
      << ", sensor2world_pose:\n";
  oss << sensor2world_pose << "\n, objects: " << objects.size() << " < ";
  for (auto obj : objects) {
    oss << "\n" << obj->ToString();
  }
  oss << " >]";
  return oss.str();
}

}  // namespace perception
}  // namespace apollo
<|endoftext|>


<commit_before><commit_msg>planning: enable park-n-go scenario<commit_after><|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/planning/common/planning_gflags.h"
DEFINE_int32(planning_loop_rate, 5, "Loop rate for planning node");

DEFINE_string(rtk_trajectory_filename, "modules/planning/data/garage.csv",
              "Loop rate for planning node");

DEFINE_uint64(backward_trajectory_point_num, 10,
              "The number of points to be included in planning trajectory "
              "before the matched point");

DEFINE_uint64(rtk_trajectory_forward, 800,
              "The number of points to be included in RTK trajectory "
              "after the matched point");

DEFINE_double(trajectory_resolution, 0.01,
              "The time resolution of "
              "output trajectory.");

DEFINE_double(
    look_backward_distance, 10,
    "look backward this distance when creating reference line from routing");

DEFINE_double(
    look_forward_distance, 70,
    "look forward this distance when creating reference line from routing");
DEFINE_bool(enable_smooth_reference_line, true,
            "enable smooth the map reference line");

DEFINE_int32(max_history_frame_num, 5, "The maximum history frame number");

DEFINE_double(max_collision_distance, 0.1,
              "considered as collision if distance (meters) is smaller than or "
              "equal to this (meters)");

DEFINE_double(replan_distance_threshold, 5.0,
              "The distance threshold of replan");

DEFINE_double(default_reference_line_width, 4.0,
              "Default reference line width");

DEFINE_double(planning_upper_speed_limit, 10.0, "Maximum speed in planning.");

DEFINE_double(planning_distance, 100, "Planning distance");

DEFINE_double(trajectory_time_length, 8.0, "Trajectory time length");
DEFINE_double(trajectory_time_resolution, 0.1,
              "Trajectory time resolution in planning");
DEFINE_double(output_trajectory_time_resolution, 0.05,
              "Trajectory time resolution when publish");

DEFINE_double(speed_lower_bound, 0.0, "The lowest speed allowed.");
DEFINE_double(speed_upper_bound, 40.0, "The highest speed allowed.");

DEFINE_double(longitudinal_acceleration_lower_bound, -4.5,
              "The lowest longitudinal acceleration allowed.");
DEFINE_double(longitudinal_acceleration_upper_bound, 4.0,
              "The highest longitudinal acceleration allowed.");

DEFINE_double(lateral_acceleration_bound, 4.5,
              "Bound of lateral acceleration; symmetric for left and right");
DEFINE_double(lateral_jerk_bound, 4.0,
              "Bound of lateral jerk; symmetric for left and right");

DEFINE_double(longitudinal_jerk_lower_bound, -4.0,
              "The lower bound of longitudinal jerk.");
DEFINE_double(longitudinal_jerk_upper_bound, 4.0,
              "The upper bound of longitudinal jerk.");

DEFINE_double(kappa_bound, 0.23, "The bound for vehicle curvature");

// ST Boundary
DEFINE_double(st_max_s, 80, "the maximum s of st boundary");
DEFINE_double(st_max_t, 10, "the maximum t of st boundary");

// Decision Part
DEFINE_double(static_obstacle_speed_threshold, 1.0,
              "obstacles are considered as static obstacle if its speed is "
              "less than this value (m/s)");
DEFINE_bool(enable_nudge_decision, false, "enable nudge decision");
DEFINE_double(static_decision_ignore_s_range, 3.0,
              "threshold for judging nudge in dp path computing decision");
DEFINE_double(static_decision_nudge_l_buffer, 0.5, "l buffer for nudge");
DEFINE_double(stop_distance_obstacle, 5.0,
              "stop distance from in-lane obstacle (meters)");
DEFINE_double(destination_adjust_distance_buffer, 1.0,
              "distance buffer when adjusting destination stop line");
DEFINE_double(min_driving_width, 2.5,
              "minimum road width(meters) for adc to drive through");
DEFINE_double(nudge_distance_obstacle, 0.3,
              "minimum distance to nudge a obstacle (meters)");
DEFINE_double(follow_min_distance, 10,
              "min follow distance for vehicles/bicycles/moving objects");
DEFINE_double(stop_line_min_distance, 0.0,
              "min distance (meters) to stop line for a valid stop");

DEFINE_string(destination_obstacle_id, "DEST",
              "obstacle id for converting destination to an obstacle");
DEFINE_int32(virtual_obstacle_perception_id, -1,
             "virtual obstacle perception id(a negative int)");
DEFINE_double(virtual_stop_wall_length, 0.1,
              "virtual stop wall length (meters)");
DEFINE_double(virtual_stop_wall_width, 3.7, "virtual stop wall width (meters)");
DEFINE_double(virtual_stop_wall_height, 2.0,
              "virtual stop wall height (meters)");

// Prediction Part
DEFINE_double(prediction_total_time, 5.0, "Total prediction time");
DEFINE_bool(align_prediction_time, true,
            "enable align prediction data based planning time");

// Trajectory
DEFINE_bool(enable_rule_layer, true,
            "enable rule for trajectory before model computation");

// Traffic decision

DEFINE_string(planning_config_file,
              "modules/planning/conf/planning_config.pb.txt",
              "planning config file");

DEFINE_int32(trajectory_point_num_for_debug, 10,
             "number of output trajectory points for debugging");

DEFINE_double(decision_valid_stop_range, 0.5,
              "The valid stop range in decision.");
DEFINE_bool(enable_record_debug, true,
            "True to enable record debug into debug protobuf.");
DEFINE_bool(enable_prediction, true, "True to enable prediction input.");
<commit_msg>Planning: fixed shift at turning.<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/planning/common/planning_gflags.h"
DEFINE_int32(planning_loop_rate, 5, "Loop rate for planning node");

DEFINE_string(rtk_trajectory_filename, "modules/planning/data/garage.csv",
              "Loop rate for planning node");

DEFINE_uint64(backward_trajectory_point_num, 10,
              "The number of points to be included in planning trajectory "
              "before the matched point");

DEFINE_uint64(rtk_trajectory_forward, 800,
              "The number of points to be included in RTK trajectory "
              "after the matched point");

DEFINE_double(trajectory_resolution, 0.01,
              "The time resolution of "
              "output trajectory.");

DEFINE_double(
    look_backward_distance, 30,
    "look backward this distance when creating reference line from routing");

DEFINE_double(
    look_forward_distance, 70,
    "look forward this distance when creating reference line from routing");
DEFINE_bool(enable_smooth_reference_line, true,
            "enable smooth the map reference line");

DEFINE_int32(max_history_frame_num, 5, "The maximum history frame number");

DEFINE_double(max_collision_distance, 0.1,
              "considered as collision if distance (meters) is smaller than or "
              "equal to this (meters)");

DEFINE_double(replan_distance_threshold, 5.0,
              "The distance threshold of replan");

DEFINE_double(default_reference_line_width, 4.0,
              "Default reference line width");

DEFINE_double(planning_upper_speed_limit, 10.0, "Maximum speed in planning.");

DEFINE_double(planning_distance, 100, "Planning distance");

DEFINE_double(trajectory_time_length, 8.0, "Trajectory time length");
DEFINE_double(trajectory_time_resolution, 0.1,
              "Trajectory time resolution in planning");
DEFINE_double(output_trajectory_time_resolution, 0.05,
              "Trajectory time resolution when publish");

DEFINE_double(speed_lower_bound, 0.0, "The lowest speed allowed.");
DEFINE_double(speed_upper_bound, 40.0, "The highest speed allowed.");

DEFINE_double(longitudinal_acceleration_lower_bound, -4.5,
              "The lowest longitudinal acceleration allowed.");
DEFINE_double(longitudinal_acceleration_upper_bound, 4.0,
              "The highest longitudinal acceleration allowed.");

DEFINE_double(lateral_acceleration_bound, 4.5,
              "Bound of lateral acceleration; symmetric for left and right");
DEFINE_double(lateral_jerk_bound, 4.0,
              "Bound of lateral jerk; symmetric for left and right");

DEFINE_double(longitudinal_jerk_lower_bound, -4.0,
              "The lower bound of longitudinal jerk.");
DEFINE_double(longitudinal_jerk_upper_bound, 4.0,
              "The upper bound of longitudinal jerk.");

DEFINE_double(kappa_bound, 0.23, "The bound for vehicle curvature");

// ST Boundary
DEFINE_double(st_max_s, 80, "the maximum s of st boundary");
DEFINE_double(st_max_t, 10, "the maximum t of st boundary");

// Decision Part
DEFINE_double(static_obstacle_speed_threshold, 1.0,
              "obstacles are considered as static obstacle if its speed is "
              "less than this value (m/s)");
DEFINE_bool(enable_nudge_decision, false, "enable nudge decision");
DEFINE_double(static_decision_ignore_s_range, 3.0,
              "threshold for judging nudge in dp path computing decision");
DEFINE_double(static_decision_nudge_l_buffer, 0.5, "l buffer for nudge");
DEFINE_double(stop_distance_obstacle, 5.0,
              "stop distance from in-lane obstacle (meters)");
DEFINE_double(destination_adjust_distance_buffer, 1.0,
              "distance buffer when adjusting destination stop line");
DEFINE_double(min_driving_width, 2.5,
              "minimum road width(meters) for adc to drive through");
DEFINE_double(nudge_distance_obstacle, 0.3,
              "minimum distance to nudge a obstacle (meters)");
DEFINE_double(follow_min_distance, 10,
              "min follow distance for vehicles/bicycles/moving objects");
DEFINE_double(stop_line_min_distance, 0.0,
              "min distance (meters) to stop line for a valid stop");

DEFINE_string(destination_obstacle_id, "DEST",
              "obstacle id for converting destination to an obstacle");
DEFINE_int32(virtual_obstacle_perception_id, -1,
             "virtual obstacle perception id(a negative int)");
DEFINE_double(virtual_stop_wall_length, 0.1,
              "virtual stop wall length (meters)");
DEFINE_double(virtual_stop_wall_width, 3.7, "virtual stop wall width (meters)");
DEFINE_double(virtual_stop_wall_height, 2.0,
              "virtual stop wall height (meters)");

// Prediction Part
DEFINE_double(prediction_total_time, 5.0, "Total prediction time");
DEFINE_bool(align_prediction_time, true,
            "enable align prediction data based planning time");

// Trajectory
DEFINE_bool(enable_rule_layer, true,
            "enable rule for trajectory before model computation");

// Traffic decision

DEFINE_string(planning_config_file,
              "modules/planning/conf/planning_config.pb.txt",
              "planning config file");

DEFINE_int32(trajectory_point_num_for_debug, 10,
             "number of output trajectory points for debugging");

DEFINE_double(decision_valid_stop_range, 0.5,
              "The valid stop range in decision.");
DEFINE_bool(enable_record_debug, true,
            "True to enable record debug into debug protobuf.");
DEFINE_bool(enable_prediction, true, "True to enable prediction input.");
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015, 2016, 2017, 2018, 2019, 2020, Intel Corporation
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the
 *       distribution.
 *
 *     * Neither the name of Intel Corporation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY LOG OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>

#include <string>
#include <stdexcept>
#include <iostream>
#include <iomanip>

#include "geopm_version.h"
#include "geopm_error.h"
#include "geopm_hash.h"
#include "PlatformIO.hpp"
#include "PlatformTopo.hpp"
#include "Exception.hpp"

#include "config.h"

using geopm::PlatformIO;
using geopm::PlatformTopo;

int parse_domain_type(const std::string &dom);

int main(int argc, char **argv)
{
    const char *usage = "\nUsage:\n"
                        "       geopmread SIGNAL_NAME DOMAIN_TYPE DOMAIN_INDEX\n"
                        "       geopmread [--domain [SIGNAL_NAME]]\n"
                        "       geopmread [--info [SIGNAL_NAME]]\n"
                        "       geopmread [--help] [--version] [--cache]\n"
                        "\n"
                        "  SIGNAL_NAME:  name of the signal\n"
                        "  DOMAIN_TYPE:  name of the domain for which the signal should be read\n"
                        "  DOMAIN_INDEX: index of the domain, starting from 0\n"
                        "\n"
                        "  -d, --domain                     print domain of a signal\n"
                        "  -i, --info                       print longer description of a signal\n"
                        "  -c, --cache                      create geopm topo cache if it does not exist\n"
                        "  -h, --help                       print brief summary of the command line\n"
                        "                                   usage information, then exit\n"
                        "  -v, --version                    print version of GEOPM to standard output,\n"
                        "                                   then exit\n"
                        "\n"
                        "Copyright (c) 2015, 2016, 2017, 2018, 2019, 2020, Intel Corporation. All rights reserved.\n"
                        "\n";

    static struct option long_options[] = {
        {"domain", no_argument, NULL, 'd'},
        {"info", no_argument, NULL, 'i'},
        {"cache", no_argument, NULL, 'c'},
        {"help", no_argument, NULL, 'h'},
        {"version", no_argument, NULL, 'v'},
        {NULL, 0, NULL, 0}
    };

    int opt;
    int err = 0;
    bool is_domain = false;
    bool is_info = false;
    while (!err && (opt = getopt_long(argc, argv, "dichv", long_options, NULL)) != -1) {
        switch (opt) {
            case 'd':
                is_domain = true;
                break;
            case 'i':
                is_info = true;
                break;
            case 'c':
                geopm::PlatformTopo::create_cache();
                return 0;
            case 'h':
                printf("%s", usage);
                return 0;
            case 'v':
                printf("%s\n", geopm_version());
                printf("\n\nCopyright (c) 2015, 2016, 2017, 2018, 2019, 2020, Intel Corporation. All rights reserved.\n\n");
                return 0;
            case '?': // opt is ? when an option required an arg but it was missing
                fprintf(stderr, usage, argv[0]);
                err = EINVAL;
                break;
            default:
                fprintf(stderr, "Error: getopt returned character code \"0%o\"\n", opt);
                err = EINVAL;
                break;
        }
    }

    if (is_domain && is_info) {
        std::cerr << "Error: info about domain not implemented." << std::endl;
        return EINVAL;
    }

    std::vector<std::string> pos_args;
    while (optind < argc) {
        pos_args.emplace_back(argv[optind++]);
    }

    PlatformIO &platform_io = geopm::platform_io();
    const PlatformTopo &platform_topo = geopm::platform_topo();
    if (is_domain) {
        if (pos_args.size() == 0) {
            // print all domains
            for (int dom = GEOPM_DOMAIN_BOARD; dom < GEOPM_NUM_DOMAIN; ++dom) {
                std::cout << std::setw(24) << std::left
                          << PlatformTopo::domain_type_to_name(dom)
                          << platform_topo.num_domain(dom) << std::endl;
            }
        }
        else {
            // print domain for one signal
            try {
                int domain_type = platform_io.signal_domain_type(pos_args[0]);
                std::cout << PlatformTopo::domain_type_to_name(domain_type) << std::endl;
            }
            catch (const geopm::Exception &ex) {
                std::cerr << "Error: unable to determine signal type: " << ex.what() << std::endl;
                err = EINVAL;
            }
        }
    }
    else if (is_info) {
        try {
            if (pos_args.size() == 0) {
                // print all signals with description
                auto signals = platform_io.signal_names();
                for (const auto &sig : signals) {
                    /// @todo nicer formatting
                    std::cout << sig << ": " << platform_io.signal_description(sig) << std::endl;
                }
            }
            else {
                // print description for one signal
                std::cout << pos_args[0] << ": " << platform_io.signal_description(pos_args[0]) << std::endl;
            }
        }
        catch (const geopm::Exception &ex) {
            std::cerr << "Error: " << ex.what() << std::endl;
            err = EINVAL;
        }
    }
    else {
        if (pos_args.size() == 0) {
            // print all signals
            auto signals = platform_io.signal_names();
            for (const auto &sig : signals) {
                std::cout << sig << std::endl;
            }
        }
        else if (pos_args.size() >= 3) {
            // read signal
            std::string signal_name = pos_args[0];
            int domain_idx = -1;
            try {
                domain_idx = std::stoi(pos_args[2]);
            }
            catch (const std::invalid_argument &) {
                std::cerr << "Error: invalid domain index.\n" << std::endl;
                err = EINVAL;
            }
            if (!err) {
                try {
                    int domain_type = PlatformTopo::domain_name_to_type(pos_args[1]);
                    int idx = platform_io.push_signal(signal_name, domain_type, domain_idx);
                    // read_batch multiple times for derivative-based signals;
                    // should not affect other signals
                    for (int ii = 0; ii < 16; ++ii) {
                        platform_io.read_batch();
                        platform_io.sample(idx);
                        usleep(5000);
                    }
                    double result = platform_io.sample(idx);
                    std::cout << platform_io.format_function(signal_name)(result) << std::endl;
                }
                catch (const geopm::Exception &ex) {
                    std::cerr << "Error: cannot read signal: " << ex.what() << std::endl;
                    err = EINVAL;
                }
            }
        }
        else {
            std::cerr << "Error: domain type and domain index are required to read signal.\n" << std::endl;
            err = EINVAL;
        }
    }
    return err;
}
<commit_msg>Use read_signal in geopmread<commit_after>/*
 * Copyright (c) 2015, 2016, 2017, 2018, 2019, 2020, Intel Corporation
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the
 *       distribution.
 *
 *     * Neither the name of Intel Corporation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY LOG OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <errno.h>

#include <string>
#include <stdexcept>
#include <iostream>
#include <iomanip>

#include "geopm_version.h"
#include "geopm_error.h"
#include "geopm_hash.h"
#include "PlatformIO.hpp"
#include "PlatformTopo.hpp"
#include "Exception.hpp"

#include "config.h"

using geopm::PlatformIO;
using geopm::PlatformTopo;

int parse_domain_type(const std::string &dom);

int main(int argc, char **argv)
{
    const char *usage = "\nUsage:\n"
                        "       geopmread SIGNAL_NAME DOMAIN_TYPE DOMAIN_INDEX\n"
                        "       geopmread [--domain [SIGNAL_NAME]]\n"
                        "       geopmread [--info [SIGNAL_NAME]]\n"
                        "       geopmread [--help] [--version] [--cache]\n"
                        "\n"
                        "  SIGNAL_NAME:  name of the signal\n"
                        "  DOMAIN_TYPE:  name of the domain for which the signal should be read\n"
                        "  DOMAIN_INDEX: index of the domain, starting from 0\n"
                        "\n"
                        "  -d, --domain                     print domain of a signal\n"
                        "  -i, --info                       print longer description of a signal\n"
                        "  -c, --cache                      create geopm topo cache if it does not exist\n"
                        "  -h, --help                       print brief summary of the command line\n"
                        "                                   usage information, then exit\n"
                        "  -v, --version                    print version of GEOPM to standard output,\n"
                        "                                   then exit\n"
                        "\n"
                        "Copyright (c) 2015, 2016, 2017, 2018, 2019, 2020, Intel Corporation. All rights reserved.\n"
                        "\n";

    static struct option long_options[] = {
        {"domain", no_argument, NULL, 'd'},
        {"info", no_argument, NULL, 'i'},
        {"cache", no_argument, NULL, 'c'},
        {"help", no_argument, NULL, 'h'},
        {"version", no_argument, NULL, 'v'},
        {NULL, 0, NULL, 0}
    };

    int opt;
    int err = 0;
    bool is_domain = false;
    bool is_info = false;
    while (!err && (opt = getopt_long(argc, argv, "dichv", long_options, NULL)) != -1) {
        switch (opt) {
            case 'd':
                is_domain = true;
                break;
            case 'i':
                is_info = true;
                break;
            case 'c':
                geopm::PlatformTopo::create_cache();
                return 0;
            case 'h':
                printf("%s", usage);
                return 0;
            case 'v':
                printf("%s\n", geopm_version());
                printf("\n\nCopyright (c) 2015, 2016, 2017, 2018, 2019, 2020, Intel Corporation. All rights reserved.\n\n");
                return 0;
            case '?': // opt is ? when an option required an arg but it was missing
                fprintf(stderr, usage, argv[0]);
                err = EINVAL;
                break;
            default:
                fprintf(stderr, "Error: getopt returned character code \"0%o\"\n", opt);
                err = EINVAL;
                break;
        }
    }

    if (is_domain && is_info) {
        std::cerr << "Error: info about domain not implemented." << std::endl;
        return EINVAL;
    }

    std::vector<std::string> pos_args;
    while (optind < argc) {
        pos_args.emplace_back(argv[optind++]);
    }

    PlatformIO &platform_io = geopm::platform_io();
    const PlatformTopo &platform_topo = geopm::platform_topo();
    if (is_domain) {
        if (pos_args.size() == 0) {
            // print all domains
            for (int dom = GEOPM_DOMAIN_BOARD; dom < GEOPM_NUM_DOMAIN; ++dom) {
                std::cout << std::setw(24) << std::left
                          << PlatformTopo::domain_type_to_name(dom)
                          << platform_topo.num_domain(dom) << std::endl;
            }
        }
        else {
            // print domain for one signal
            try {
                int domain_type = platform_io.signal_domain_type(pos_args[0]);
                std::cout << PlatformTopo::domain_type_to_name(domain_type) << std::endl;
            }
            catch (const geopm::Exception &ex) {
                std::cerr << "Error: unable to determine signal type: " << ex.what() << std::endl;
                err = EINVAL;
            }
        }
    }
    else if (is_info) {
        try {
            if (pos_args.size() == 0) {
                // print all signals with description
                auto signals = platform_io.signal_names();
                for (const auto &sig : signals) {
                    /// @todo nicer formatting
                    std::cout << sig << ": " << platform_io.signal_description(sig) << std::endl;
                }
            }
            else {
                // print description for one signal
                std::cout << pos_args[0] << ": " << platform_io.signal_description(pos_args[0]) << std::endl;
            }
        }
        catch (const geopm::Exception &ex) {
            std::cerr << "Error: " << ex.what() << std::endl;
            err = EINVAL;
        }
    }
    else {
        if (pos_args.size() == 0) {
            // print all signals
            auto signals = platform_io.signal_names();
            for (const auto &sig : signals) {
                std::cout << sig << std::endl;
            }
        }
        else if (pos_args.size() >= 3) {
            // read signal
            std::string signal_name = pos_args[0];
            int domain_idx = -1;
            try {
                domain_idx = std::stoi(pos_args[2]);
            }
            catch (const std::invalid_argument &) {
                std::cerr << "Error: invalid domain index.\n" << std::endl;
                err = EINVAL;
            }
            if (!err) {
                try {
                    int domain_type = PlatformTopo::domain_name_to_type(pos_args[1]);
                    double result = platform_io.read_signal(signal_name, domain_type, domain_idx);
                    std::cout << platform_io.format_function(signal_name)(result) << std::endl;
                }
                catch (const geopm::Exception &ex) {
                    std::cerr << "Error: cannot read signal: " << ex.what() << std::endl;
                    err = EINVAL;
                }
            }
        }
        else {
            std::cerr << "Error: domain type and domain index are required to read signal.\n" << std::endl;
            err = EINVAL;
        }
    }
    return err;
}
<|endoftext|>