Here is what I did.
So far, a singleton depends on its own class <T> and a response message <X>. For messages without sophisticated structure, DummyResponseBody can be used as <X>.
1. The singleton header.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
/*
* ControlReqSingleton.h
*
* Created on: Apr 26, 2016
* Author: Technoboundary
*/
#ifndef CONTROLREQSINGLETON_H_
#define CONTROLREQSINGLETON_H_
#include "ControlReq.h"
//Lang: For many ASN.1 request, the response does not have a body.
// In order to use this framework, a dummy response body structure is used.
struct DummyResponseBody
{
uint32_t dummy;
};
template <typename ...> class ControlReqSingleton;
template <class T, typename X>
class ControlReqSingleton<T, X> : public ControlReq {
public:
ControlReqSingleton() {};
virtual ~ControlReqSingleton() {};
//ToDo: should be reference instead of pointer.
static T* getControlReq()
{
if (NULL == _instance)
{
_instance = new T();
}
return _instance;
}
virtual void reInitialize()
{
ControlReq::reInitialize();
}
virtual void handleReq(ICD_ControlRequest* pMsg, eIntfcId intfcId_) = 0;
virtual uint32_t getMessageTag() = 0;
virtual X* fillResponseBody() = 0;
virtual void genResp()
{
// put inquiry in control response body
ControlReq::pControlResponse->body.t = getMessageTag();
// u is a union.
ControlReq::pControlResponse->body.u.inquiry = (InquiryResponseBody*) fillResponseBody();
// add common response
ControlReq::addCommonResp();
}
private:
static T* _instance;
};
//initiate singleton instance here
template <class T, typename X>
T* ControlReqSingleton<T, X>::_instance = NULL;
#endif /* CONTROLREQSINGLETON_H_ */
2. derived class header
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
/*
* AntennaRangeInquiry.h
*
* Created on: Apr 26, 2016
* Author: Technoboundary
*/
#ifndef ANTENNARANGEINQUIRY_H_
#define ANTENNARANGEINQUIRY_H_
#include "ControlReqSingleton.h"
class AntennaRangeInquiry;
class AntennaRangeInquiry: public ControlReqSingleton<AntennaRangeInquiry, AntennaRangeInquiryResponse>{
public:
AntennaRangeInquiry();
virtual ~AntennaRangeInquiry();
virtual void handleReq(ICD_ControlRequest* pMsg, eIntfcId intfcId_);
virtual uint32_t getMessageTag();
virtual AntennaRangeInquiryResponse* fillResponseBody();
void fillAntennaRange();
};
#endif /* ANTENNARANGEINQUIRY_H_ */
3. derived class cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
/*
* AntennaRangeInquiry.cpp
*
* Created on: Apr 26, 2016
* Author: Technoboundary
*/
#include "AntennaRangeInquiry.h"
AntennaRangeInquiry::AntennaRangeInquiry() {
// TODO Auto-generated constructor stub
}
AntennaRangeInquiry::~AntennaRangeInquiry() {
// TODO Auto-generated destructor stub
}
void AntennaRangeInquiry::handleReq(ICD_ControlRequest* pMsg, eIntfcId intfcId_)
{
//reInitialize();
//bind(pMsg);
//status = checkAndParseMsgBody();
}
uint32_t AntennaRangeInquiry::getMessageTag()
{
return T_ControlResponseBody_antennaRangeInquiry;
}
AntennaRangeInquiryResponse* AntennaRangeInquiry::fillResponseBody()
{
// First allocate memory for Inquiry and initialize it
AntennaRangeInquiryResponse* pResp = rtxMemAllocType(pWCtxt, AntennaRangeInquiryResponse); //Lang: this is globally available. do not know who will free yet.
InitIncExtElem1(AntennaRangeInquiryResponse, pResp);
return pResp;
}
void AntennaRangeInquiry::fillAntennaRange()
{
}