00001
00002
00003 #include <fesa-core/Server/Property.h>
00004
00005 #include <fesa-core/Server/RequestEvent.h>
00006 #include <fesa-core/Server/AbstractServerAction.h>
00007 #include <fesa-core/DataStore/GlobalDevice.h>
00008 #include <fesa-core/Synchronization/MultiplexingContext.h>
00009 #include <fesa-core/Synchronization/NoneContext.h>
00010 #include <fesa-core/Synchronization/TimingContext.h>
00011 #include <fesa-core/Synchronization/SynchronizationLabObjectFactory.h>
00012 #include <fesa-core/Synchronization/CycleDescriptor.h>
00013 #include <fesa-core/Diagnostic/FesaStream.h>
00014
00015 #include <cmw-rda/Data.h>
00016
00017
00018 namespace fesa
00019 {
00020
00021 Property::Property(const std::string& name, bool isGlobal, bool isOnChange, bool isSubscribable, PropertyType type,
00022 bool multiplexed, int32_t priorityOffset, const std::string& notificationThreadKey, AbstractServerAction* getServerAction,
00023 AbstractServerAction* setServerAction, const std::string& className) :
00024 name_(name),
00025 isGlobal_(isGlobal),
00026 isOnChange_(isOnChange),
00027 isSubscribable_(isSubscribable),
00028 type_(type),
00029 multiplexed_(multiplexed),
00030 priorityOffset_(priorityOffset),
00031 notificationThreadKey_(notificationThreadKey),
00032 getServerAction_(getServerAction),
00033 setServerAction_(setServerAction)
00034 {
00035
00036
00037 }
00038
00039
00040 Property::~Property()
00041 {
00042 if (getServerAction_ != NULL)
00043 {
00044 delete getServerAction_;
00045 getServerAction_ = NULL;
00046 }
00047
00048 if (setServerAction_ != NULL)
00049 {
00050 delete setServerAction_;
00051 setServerAction_ = NULL;
00052 }
00053 }
00054
00055 void Property::get(AbstractDevice& device, const std::string& cycleSelector, const rdaData& filter, rdaData& value,
00056 RequestType reqType)
00057 {
00058
00059 if (getServerAction_ == NULL)
00060 throw FesaException(__FILE__, __LINE__, FesaErrorPropertyNotReadable.c_str(), name_.c_str());
00061
00062
00063 validateParameters(device, cycleSelector, !(filter.isEmpty()), reqType);
00064
00065 MultiplexingContext ctx;
00066 if (cycleSelector.empty())
00067 {
00068 ctx = NoneContext();
00069 }
00070 else
00071 {
00072 ctx = TimingContext(cycleSelector);
00073 }
00074
00075 RequestEvent ev(&ctx);
00076
00077 ctx.setSettingAccess(MultiplexingContext::CHECK_FLAG_TO_BE_SYNC);
00078
00079 ctx.setAcquisitionAccess(MultiplexingContext::SET_NOT_ALLOWED);
00080
00081
00082 if (!filter.isEmpty() && filter.contains(EXTRA_CRITERION_NAME.c_str()))
00083 {
00084 ctx.setExtraCondition(filter.extractString(EXTRA_CRITERION_NAME.c_str()));
00085 }
00086 getServerAction_->execute(&ev, device, filter, value, Output, reqType);
00087
00088 }
00089
00090 void Property::get(AbstractDevice& device, MultiplexingContext& context, const rdaData& filter, rdaData& value,
00091 RequestType reqType)
00092 {
00093
00094 if (getServerAction_ == NULL)
00095 {
00096 throw FesaException(__FILE__, __LINE__, FesaErrorPropertyNotReadable.c_str(), name_.c_str());
00097 }
00098
00099 RequestEvent ev(&context);
00100
00101
00102
00103
00104
00105 context.setSettingAccess(MultiplexingContext::CHECK_FLAG_TO_BE_SYNC);
00106
00107 context.setAcquisitionAccess(MultiplexingContext::SET_NOT_ALLOWED);
00108 getServerAction_->execute(&ev, device, filter, value, Output, reqType);
00109 }
00110
00111 void Property::set(AbstractDevice& device, const std::string& cycleSelector, const rdaData& filter,
00112 const rdaData& value)
00113 {
00114
00115 if (setServerAction_ == NULL)
00116 throw FesaException(__FILE__, __LINE__, FesaErrorPropertyNotWritable.c_str(), name_.c_str());
00117
00118
00119 validateParameters(device, cycleSelector, !(filter.isEmpty()), SET);
00120
00121
00122 MultiplexingContext ctx;
00123 if (cycleSelector.empty())
00124 {
00125 ctx = NoneContext();
00126 }
00127 else
00128 {
00129 ctx = TimingContext(cycleSelector);
00130 }
00131
00132
00133
00134 ctx.setSettingAccess(MultiplexingContext::SET_ALLOWED);
00135
00136 ctx.setAcquisitionAccess(MultiplexingContext::SET_NOT_ALLOWED);
00137
00138 RequestEvent ev(&ctx);
00139
00140 if (!filter.isEmpty() && filter.contains(EXTRA_CRITERION_NAME.c_str()))
00141 {
00142 ctx.setExtraCondition(filter.extractString(EXTRA_CRITERION_NAME.c_str()));
00143 }
00144
00145
00146
00147 setServerAction_->execute(&ev, device, filter, *const_cast<rdaData*> (&value), Input, SET);
00148 }
00149
00150 void Property::validateParameters(AbstractDevice& dev, const std::string& cycleSelector, bool hasFilter,
00151 RequestType reqType)
00152 {
00153
00154
00155 GlobalDevice* globdev = dynamic_cast<GlobalDevice*> (&dev);
00156
00157
00158 if (((globdev != NULL) && (!isGlobal_)) || ((globdev == NULL) && (isGlobal_)))
00159 {
00160 throw FesaException(__FILE__, __LINE__, FesaErrorMixedGlobalWithNoneGlobal.c_str());
00161 }
00162
00163 if (reqType == SUBSCRIBE && !isSubscribable_)
00164 {
00165 throw FesaInvalidResourceException(__FILE__, __LINE__, FesaErrorPropertyNotSubscribable.c_str(),
00166 name_.c_str());
00167 }
00168
00169
00170 if (cycleSelector.empty())
00171 {
00172 if (dev.isMultiplexed() && multiplexed_ && reqType != SUBSCRIBE)
00173 throw FesaException(__FILE__, __LINE__, FesaErrorCycleNULLInMultiplexedProperty.c_str(), name_.c_str());
00174 }
00175 else
00176 {
00177
00178 validateCycleSelector(dev, cycleSelector, reqType);
00179 }
00180
00181
00182 if (hasFilter != needFilter())
00183 {
00184 if (needFilter())
00185 throw FesaException(__FILE__, __LINE__, FesaErrorPropertyNeedsFilter.c_str(), name_.c_str());
00186 else
00187 throw FesaException(__FILE__, __LINE__, FesaErrorPropertyNotSupportFilter.c_str(), name_.c_str());
00188 }
00189 }
00190
00191
00197 void Property::validateCycleSelector(fesa::AbstractDevice& device, const std::string& cycleSelector,
00198 fesa::RequestType reqType)
00199 {
00200 CycleSelector timingSelector;
00201 fesa::parseCycleSelector(cycleSelector, timingSelector);
00202
00203
00204 const std::string& timDom = device.timingDomain.get();
00205
00206 if (timingSelector.domain_ != timDom)
00207 throw FesaException(__FILE__, __LINE__, FesaErrorWrongTimingDomain.c_str(), timingSelector.domain_.c_str(),
00208 timDom.c_str());
00209
00210
00211 SynchronizationLabObjectFactory* syncFactory = SynchronizationLabObjectFactory::getInstance();
00212 CycleDescriptor* td = syncFactory->getCycleDescriptor(timingSelector.domain_, timingSelector.criterion_);
00213
00214 td->isValidCycleSelector(cycleSelector);
00215
00216 if ((reqType != SUBSCRIBE) && (device.isMultiplexed()) && (strcmp(timingSelector.criterion_.c_str(),
00217 device.mainMuxCriterion.get()) != 0))
00218
00219 throw FesaException(__FILE__, __LINE__, FesaErrorIllegalTiming.c_str(), name_.c_str());
00220
00221
00222
00223 fesa::validateCycleSelector(timingSelector, reqType);
00224 }
00225
00226 int64_t Property::getDataTimestamp(AbstractDevice& device, MultiplexingContext& context, const rdaData& filter)
00227 {
00228
00229 return 0;
00230 }
00231
00232 void Property::printConfig(FesaStream* configStream)
00233 {
00234 *configStream << "\t\t\t\t\t<property name=\"" << name_ << "\" multiplexed=\"" << multiplexed_
00235 << "\" onChange=\"" << isOnChange_ << "\" subscribable=\"" << isSubscribable_ << "\">" << std::endl;
00236 if(getServerAction_ != NULL)
00237 {
00238 *configStream << "\t\t\t\t\t\t<get-server-action ";
00239 getServerAction_->printConfig(configStream);
00240 *configStream << "\t\t\t\t\t\t</get-server-action>";
00241 }
00242 if(setServerAction_ != NULL)
00243 {
00244 *configStream << "\t\t\t\t\t\t<set-server-action ";
00245 getServerAction_->printConfig(configStream);
00246 *configStream << "\t\t\t\t\t\t</set-server-action>";
00247 }
00248 *configStream << "\t\t\t\t\t</property>" << std::endl;
00249 }
00250
00251 void Property::printState(FesaStream* fesaStream, double elapsedTime)
00252 {
00253
00254 }
00255
00256 const std::string& Property::getNotificationThreadKey()
00257 {
00258 return notificationThreadKey_;
00259 }
00260
00261 const std::string& Property::getClassName()
00262 {
00263 return className_;
00264 }
00265
00266 }