예제 #1
0
static chtype getDBRType(PVStructure::shared_pointer const & pvRequest, chtype nativeType)
{
    // get "field" sub-structure
    PVStructure::shared_pointer fieldSubField =
            std::tr1::dynamic_pointer_cast<PVStructure>(pvRequest->getSubField("field"));
    if (!fieldSubField)
        fieldSubField = pvRequest;
    Structure::const_shared_pointer fieldStructure = fieldSubField->getStructure();

    // no fields or control -> DBR_CTRL_<type>
    if (fieldStructure->getNumberFields() == 0 ||
          fieldStructure->getField("control"))
        return static_cast<chtype>(static_cast<int>(nativeType) + DBR_CTRL_STRING);

    // display/valueAlarm -> DBR_GR_<type>
    if (fieldStructure->getField("display") || fieldStructure->getField("valueAlarm"))
        return static_cast<chtype>(static_cast<int>(nativeType) + DBR_GR_STRING);

    // timeStamp -> DBR_TIME_<type>
    // NOTE: that only DBR_TIME_<type> type holds timestamp, therefore if you request for
    // the fields above, you will never get timestamp
    if (fieldStructure->getField("timeStamp"))
        return static_cast<chtype>(static_cast<int>(nativeType) + DBR_TIME_STRING);

    // alarm -> DBR_STS_<type>
    if (fieldStructure->getField("alarm"))
        return static_cast<chtype>(static_cast<int>(nativeType) + DBR_STS_STRING);

    return nativeType;
}
예제 #2
0
static PVStructure::shared_pointer createPVStructure(CAChannel::shared_pointer const & channel, string const & properties)
{
    PVStructure::shared_pointer pvStructure = getPVDataCreate()->createPVStructure(createStructure(channel, properties));
    if (channel->getNativeType() == DBR_ENUM)
    {

        PVScalarArrayPtr pvScalarArray = pvStructure->getScalarArrayField("value.choices", pvString);

        // TODO avoid getting labels if DBR_GR_ENUM or DBR_CTRL_ENUM is used in subsequent get
        int result = ca_array_get_callback(DBR_GR_ENUM, 1, channel->getChannelID(), ca_get_labels_handler, pvScalarArray.get());
        if (result == ECA_NORMAL)
        {
            ca_flush_io();

            // NOTE: we do not wait here, since all subsequent request (over TCP) is serialized
            // and will guarantee that ca_get_labels_handler is called first
        }
        else
        {
            // TODO better error handling
            std::cerr << "failed to get labels for enum " << channel->getChannelName() << ": " << ca_message(result) << std::endl;
        }
    }

    return pvStructure;
}
예제 #3
0
void copy_DBR_CTRL(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure)
{
    const T* data = static_cast<const T*>(dbr);

    PVStructure::shared_pointer alarm = pvStructure->getSubField<PVStructure>("alarm");
    alarm->getSubField<PVInt>("status")->put(0);
    alarm->getSubField<PVInt>("severity")->put(data->severity);
    alarm->getSubField<PVString>("message")->put(dbrStatus2alarmMessage[data->status]);

    PVStructure::shared_pointer disp = pvStructure->getSubField<PVStructure>("display");
    disp->getSubField<PVString>("units")->put(std::string(data->units));
    disp->getSubField<PVDouble>("limitHigh")->put(data->upper_disp_limit);
    disp->getSubField<PVDouble>("limitLow")->put(data->lower_disp_limit);

    copy_format<T>(dbr, disp);

    PVStructure::shared_pointer va = pvStructure->getSubField<PVStructure>("valueAlarm");
    std::tr1::static_pointer_cast<sF>(va->getSubField("highAlarmLimit"))->put(data->upper_alarm_limit);
    std::tr1::static_pointer_cast<sF>(va->getSubField("highWarningLimit"))->put(data->upper_warning_limit);
    std::tr1::static_pointer_cast<sF>(va->getSubField("lowWarningLimit"))->put(data->lower_warning_limit);
    std::tr1::static_pointer_cast<sF>(va->getSubField("lowAlarmLimit"))->put(data->lower_alarm_limit);

    PVStructure::shared_pointer ctrl = pvStructure->getSubField<PVStructure>("control");
    ctrl->getSubField<PVDouble>("limitHigh")->put(data->upper_ctrl_limit);
    ctrl->getSubField<PVDouble>("limitLow")->put(data->lower_ctrl_limit);

    copy_DBR<pT, sT, sF, aF>(&data->value, count, pvStructure);
}
예제 #4
0
int doPut_pvStructure<dbr_enum_t, pvString, PVString, PVStringArray>(CAChannel::shared_pointer const & channel, void *usrArg, PVStructure::shared_pointer const & pvStructure)
{
    bool isScalarValue = pvStructure->getStructure()->getField("value")->getType() == structure;

    if (isScalarValue)
    {
        std::tr1::shared_ptr<PVInt> value = std::tr1::static_pointer_cast<PVInt>(pvStructure->getSubField("value.index"));

        dbr_enum_t val = value->get();
        int result = ca_array_put_callback(channel->getNativeType(), 1,
                                           channel->getChannelID(), &val,
                                           ca_put_handler, usrArg);

        if (result == ECA_NORMAL)
        {
            ca_flush_io();
        }

        return result;
    }
    else
    {
        // no enum arrays in V3
        return ECA_NOSUPPORT;
    }
}
예제 #5
0
int doPut_pvStructure<string, pvString, PVString, PVStringArray>(CAChannel::shared_pointer const & channel, void *usrArg, PVStructure::shared_pointer const & pvStructure)
{
    bool isScalarValue = pvStructure->getStructure()->getField("value")->getType() == scalar;

    if (isScalarValue)
    {
        std::tr1::shared_ptr<PVString> value = std::tr1::static_pointer_cast<PVString>(pvStructure->getSubField("value"));

        string val = value->get();
        int result = ca_array_put_callback(channel->getNativeType(), 1,
                                           channel->getChannelID(), val.c_str(),
                                           ca_put_handler, usrArg);

        if (result == ECA_NORMAL)
        {
            ca_flush_io();
        }

        return result;
    }
    else
    {
        std::tr1::shared_ptr<PVStringArray> value =
                std::tr1::static_pointer_cast<PVStringArray>(pvStructure->getScalarArrayField("value", pvString));

        PVStringArray::const_svector stringArray(value->view());

        size_t arraySize = stringArray.size();
        size_t ca_stringBufferSize = arraySize * MAX_STRING_SIZE;
        char* ca_stringBuffer = new char[ca_stringBufferSize];
        memset(ca_stringBuffer, 0, ca_stringBufferSize);

        char *p = ca_stringBuffer;
        for(size_t i = 0; i < arraySize; i++)
        {
            string value = stringArray[i];
            size_t len = value.length();
            if (len >= MAX_STRING_SIZE)
                len = MAX_STRING_SIZE - 1;
            memcpy(p, value.c_str(), len);
            p += MAX_STRING_SIZE;
        }


        int result = ca_array_put_callback(channel->getNativeType(), arraySize,
                                           channel->getChannelID(), ca_stringBuffer,
                                           ca_put_handler, usrArg);
        delete[] ca_stringBuffer;

        if (result == ECA_NORMAL)
        {
            ca_flush_io();
        }

        return result;
    }
}
예제 #6
0
void printValue(std::string const & channelName, PVStructure::shared_pointer const & pv)
{
    if (mode == ValueOnlyMode)
    {
        PVField::shared_pointer value = pv->getSubField("value");
        if (value.get() == 0)
        {
            std::cerr << "no 'value' field" << std::endl;
            //std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl;
            pvutil_ostream myos(std::cout.rdbuf());
            myos << channelName << std::endl << *(pv.get()) << std::endl << std::endl;
        }
        else
        {
            Type valueType = value->getField()->getType();
            if (valueType != scalar && valueType != scalarArray)
            {
                // switch to structure mode, unless it's T-type
                if (valueType == structure && isTType(static_pointer_cast<PVStructure>(value)))
                {
                    std::cout << std::setw(30) << std::left << channelName;
                    std::cout << fieldSeparator;
                    formatTType(std::cout, static_pointer_cast<PVStructure>(value));
                    std::cout << std::endl;
                }
                else
                {
                    //std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl;
                    pvutil_ostream myos(std::cout.rdbuf());
                    myos << channelName << std::endl << *(pv.get()) << std::endl << std::endl;
                }
            }
            else
            {
                if (fieldSeparator == ' ' && value->getField()->getType() == scalar)
                    std::cout << std::setw(30) << std::left << channelName;
                else
                    std::cout << channelName;

                std::cout << fieldSeparator;

                terse(std::cout, value) << std::endl;
            }
        }
    }
    else if (mode == TerseMode)
        terseStructure(std::cout, pv) << std::endl;
    else
    {
        //std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl;
        pvutil_ostream myos(std::cout.rdbuf());
        myos << channelName << std::endl << *(pv.get()) << std::endl << std::endl;
    }
}
예제 #7
0
    PVStructure::shared_pointer request(PVStructure::shared_pointer const & args)
        throw (RPCRequestException)
    {
        // TODO error handling
        double a = atof(args->getStringField("a")->get().c_str());
        double b = atof(args->getStringField("b")->get().c_str());

        PVStructure::shared_pointer result = getPVDataCreate()->createPVStructure(resultStructure);
        result->getDoubleField("c")->put(a+b);
        return result;
    }
예제 #8
0
void copy_DBR_STS(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure)
{
    const T* data = static_cast<const T*>(dbr);

    PVStructure::shared_pointer alarm = pvStructure->getStructureField("alarm");
    // no mapping needed
    alarm->getIntField("status")->put(0);
    alarm->getIntField("severity")->put(data->severity);
    alarm->getStringField("message")->put(dbrStatus2alarmMessage[data->status]);

    copy_DBR<pT, sT, sF, aF>(&data->value, count, pvStructure);
}
예제 #9
0
void copy_DBR_TIME(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure)
{
    const T* data = static_cast<const T*>(dbr);

    PVStructure::shared_pointer ts = pvStructure->getStructureField("timeStamp");
    epics::pvData::int64 spe = data->stamp.secPastEpoch;
    spe += 7305*86400;
    ts->getLongField("secondsPastEpoch")->put(spe);
    ts->getIntField("nanoseconds")->put(data->stamp.nsec);

    copy_DBR_STS<T, pT, sT, sF, aF>(dbr, count, pvStructure);
}
예제 #10
0
    PVStructure::shared_pointer request(PVStructure::shared_pointer const & pvArguments)
    {
        // NTURI support
        PVStructure::shared_pointer args(
            (starts_with(pvArguments->getStructure()->getID(), "epics:nt/NTURI:1.")) ?
            pvArguments->getSubField<PVStructure>("query") :
            pvArguments
        );

        // get fields and check their existence
        PVScalar::shared_pointer af = args->getSubField<PVScalar>("a");
        PVScalar::shared_pointer bf = args->getSubField<PVScalar>("b");
        if (!af || !bf)
            throw RPCRequestException(Status::STATUSTYPE_ERROR, "scalar 'a' and 'b' fields are required");

        // get the numbers (and convert if neccessary)
        double a, b;
        try
        {
            a = af->getAs<double>();
            b = bf->getAs<double>();
        }
        catch (std::exception &e)
        {
            throw RPCRequestException(Status::STATUSTYPE_ERROR,
                                      std::string("failed to convert arguments to double: ") + e.what());
        }

        // create return structure and set data
        PVStructure::shared_pointer result = getPVDataCreate()->createPVStructure(resultStructure);
        result->getSubFieldT<PVDouble>("c")->put(a+b);
        return result;
    }
예제 #11
0
void copy_DBR<dbr_long_t, pvInt, PVInt, PVIntArray>(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure)
{
    if (count == 1)
    {
        std::tr1::shared_ptr<PVInt> value = std::tr1::static_pointer_cast<PVInt>(pvStructure->getSubField("value"));
        value->put(static_cast<const int32*>(dbr)[0]);
    }
    else
    {
        std::tr1::shared_ptr<PVIntArray> value =
                std::tr1::static_pointer_cast<PVIntArray>(pvStructure->getScalarArrayField("value", pvInt));
        PVIntArray::svector temp(value->reuse());
        temp.resize(count);
        std::copy(static_cast<const int32*>(dbr), static_cast<const int32*>(dbr) + count, temp.begin());
        value->replace(freeze(temp));
    }
}
예제 #12
0
void copy_DBR(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure)
{
    if (count == 1)
    {
        std::tr1::shared_ptr<sF> value = std::tr1::static_pointer_cast<sF>(pvStructure->getSubField("value"));
        value->put(static_cast<const pT*>(dbr)[0]);
    }
    else
    {
        std::tr1::shared_ptr<aF> value =
                std::tr1::static_pointer_cast<aF>(pvStructure->getScalarArrayField("value", sT));
        typename aF::svector temp(value->reuse());
        temp.resize(count);
        std::copy(static_cast<const pT*>(dbr), static_cast<const pT*>(dbr) + count, temp.begin());
        value->replace(freeze(temp));
    }
}
예제 #13
0
void copy_DBR<dbr_enum_t, pvString, PVString, PVStringArray>(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure)
{
    if (count == 1)
    {
        std::tr1::shared_ptr<PVInt> value = std::tr1::static_pointer_cast<PVInt>(pvStructure->getSubField("value.index"));
        value->put(static_cast<const dbr_enum_t*>(dbr)[0]);
    }
    else
    {
        // not supported
        std::cerr << "caChannel: array of enums not supported" << std::endl;
    }
}
    PVStructure::shared_pointer request(PVStructure::shared_pointer const & pvArguments)
    {
        // requires NTURI as argument
        if (pvArguments->getStructure()->getID() != "epics:nt/NTURI:1.0")
            throw RPCRequestException(Status::STATUSTYPE_ERROR, "RPC argument must be a NTURI normative type");

        std::string channelName = pvArguments->getSubField<PVString>("path")->get();
        
        // create return structure and set data
        PVStructure::shared_pointer result = getPVDataCreate()->createPVStructure(resultStructure);
        result->getSubField<PVString>("channelName")->put(channelName);
        return result;
    }
예제 #15
0
int doPut_pvStructure(CAChannel::shared_pointer const & channel, void *usrArg, PVStructure::shared_pointer const & pvStructure)
{
    bool isScalarValue = pvStructure->getStructure()->getField("value")->getType() == scalar;

    if (isScalarValue)
    {
        std::tr1::shared_ptr<sF> value = std::tr1::static_pointer_cast<sF>(pvStructure->getSubField("value"));

        pT val = value->get();
        int result = ca_array_put_callback(channel->getNativeType(), 1,
                                           channel->getChannelID(), &val,
                                           ca_put_handler, usrArg);

        if (result == ECA_NORMAL)
        {
            ca_flush_io();
        }

        return result;
    }
    else
    {
        std::tr1::shared_ptr<aF> value =
                std::tr1::static_pointer_cast<aF>(pvStructure->getScalarArrayField("value", sT));

        const pT* val = value->view().data();
        int result = ca_array_put_callback(channel->getNativeType(), static_cast<unsigned long>(value->getLength()),
                                           channel->getChannelID(), val,
                                           ca_put_handler, usrArg);

        if (result == ECA_NORMAL)
        {
            ca_flush_io();
        }

        return result;
    }
}
예제 #16
0
void MyChannelGetRequester::getDone(const Status& status,
        ChannelGet::shared_pointer const & channelGet,
        PVStructure::shared_pointer const & pvStructure,
        BitSet::shared_pointer const & bitSet)
{
    cout << "ChannelGet for " << channelGet->getChannel()->getChannelName()
         << " finished, " << status << endl;

    if (status.isSuccess())
    {
        pvStructure->dumpValue(cout);
        done_event.signal();
    }
}
예제 #17
0
void copy_DBR<string, pvString, PVString, PVStringArray>(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure)
{
    if (count == 1)
    {
        std::tr1::shared_ptr<PVString> value = std::tr1::static_pointer_cast<PVString>(pvStructure->getSubField("value"));
        value->put(std::string(static_cast<const char*>(dbr)));
    }
    else
    {
        std::tr1::shared_ptr<PVStringArray> value =
                std::tr1::static_pointer_cast<PVStringArray>(pvStructure->getScalarArrayField("value", pvString));
        const dbr_string_t* dbrStrings = static_cast<const dbr_string_t*>(dbr);
        PVStringArray::svector sA(value->reuse());
        sA.resize(count);
        std::copy(dbrStrings, dbrStrings + count, sA.begin());
        value->replace(freeze(sA));
    }
}
int main (int argc, char *argv[])
{
    int opt;                    // getopt() current option
    std::string testFile;

    setvbuf(stdout,NULL,_IOLBF,BUFSIZ);    // Set stdout to line buffering

    while ((opt = getopt(argc, argv, ":hr:w:i:c:s:l:f:v")) != -1) {
        switch (opt) {
        case 'h':               // Print usage
            usage();
            return 0;
        case 'w':               // Set PVA timeout value
            if((epicsScanDouble(optarg, &timeOut)) != 1)
            {
                fprintf(stderr, "'%s' is not a valid timeout value "
                        "- ignored. ('cainfo -h' for help.)\n", optarg);
                timeOut = DEFAULT_TIMEOUT;
            }
            break;
        case 'r':               // pvRequest string
            request = optarg;
            break;
        case 'i':               // iterations
            iterations = atoi(optarg);
            break;
        case 'c':               // channels
            channels = atoi(optarg);
            break;
        case 's':               // arraySize
            arraySize = atoi(optarg);
            break;
        case 'l':               // runs
            runs = atoi(optarg);
            break;
        case 'f':               // testFile
            testFile = optarg;
            break;
        case 'v':               // testFile
            verbose = true;
            break;
        case '?':
            fprintf(stderr,
                    "Unrecognized option: '-%c'. ('testGetPerformance -h' for help.)\n",
                    optopt);
            return 1;
        case ':':
            fprintf(stderr,
                    "Option '-%c' requires an argument. ('testGetPerformance -h' for help.)\n",
                    optopt);
            return 1;
        default :
            usage();
            return 1;
        }
    }

    // typedef enum {logLevelInfo, logLevelDebug, logLevelError, errlogFatal} errlogSevEnum;
    SET_LOG_LEVEL(logLevelError);

    pvRequest = CreateRequest::create()->createRequest(request);
    if (pvRequest.get() == 0) {
        printf("failed to parse request string\n");
        return 1;
    }

    ClientFactory::start();
    provider = ChannelProviderRegistry::clients()->getProvider("pva");

    if (!testFile.empty())
    {
        ifstream ifs(testFile.c_str(), ifstream::in);
        if (ifs.good())
        {
            string line;
            while (true)
            {
                getline(ifs, line);
                if (ifs.good())
                {
                    // ignore lines that starts (no trimming) with '#'
                    if (line.find('#') != 0)
                    {
                        // <c> <s> <i> <l>
                        if (sscanf(line.c_str(), "%d %d %d %d", &channels, &arraySize, &iterations, &runs) == 4)
                        {
                            //printf("%d %d %d %d\n", channels, arraySize, iterations, runs);
                            runTest();

                            // wait a bit for a next test
                            epicsThreadSleep(1.0);
                        }
                        else
                        {
                            fprintf(stderr,
                                    "Failed to parse line '%s', ignoring...\n",
                                    line.c_str());
                        }
                    }
                }
                else
                    break;
            }
        }
        else
        {
            fprintf(stderr,
                    "Failed to open file '%s'\n",
                    testFile.c_str());
            return 2;
        }

        ifs.close();
    }
    else
    {
        // in non-file mode, verbose is true by default
        verbose = true;
        runTest();
    }

    //ClientFactory::stop();

    return 0;
}
예제 #19
0
void copy_format<dbr_time_string>(const void * /*dbr*/, PVStructure::shared_pointer const & pvDisplayStructure)
{
    pvDisplayStructure->getStringField("format")->put("%s");
}