Beispiel #1
0
struct dbChannel * dbChannel_create(const char *pname)
{
    dbChannel *chan = dbChannelCreate(pname);

    if (!chan)
        return NULL;

    if (INVALID_DB_REQ(dbChannelExportType(chan)) ||
        dbChannelOpen(chan)) {
        dbChannelDelete(chan);
        return NULL;
    }

    return chan;
}
int epicsShareAPI ca_create_subscription ( 
        chtype type, arrayElementCount count, chid pChan, 
        long mask, caEventCallBackFunc * pCallBack, void * pCallBackArg, 
        evid * monixptr )
{
    if ( type < 0 ) {
        return ECA_BADTYPE;
    }
    unsigned tmpType = static_cast < unsigned > ( type );

    if ( INVALID_DB_REQ (type) ) {
        return ECA_BADTYPE;
    }

    if ( pCallBack == NULL ) {
        return ECA_BADFUNCPTR;
    }

    static const long maskMask = 0xffff;
    if ( ( mask & maskMask ) == 0) {
        return ECA_BADMASK;
    }

    if ( mask & ~maskMask ) {
        return ECA_BADMASK;
    }

    try {
        epicsGuard < epicsMutex > guard ( pChan->cacCtx.mutexRef () );
        try {
            // if this stalls out on a live circuit then an exception 
            // can be forthcoming which we must ignore (this is a
            // special case preserving legacy ca_create_subscription
            // behavior)
            pChan->eliminateExcessiveSendBacklog ( guard );
        }
        catch ( cacChannel::notConnected & ) {
            // intentionally ignored (its ok to subscribe when not connected)
        }
        new ( pChan->getClientCtx().subscriptionFreeList )
            oldSubscription  ( 
                guard, *pChan, pChan->io, tmpType, count, mask,
                pCallBack, pCallBackArg, monixptr );
        // dont touch object created after above new because
        // the first callback might have canceled, and therefore
        // destroyed, it
        return ECA_NORMAL;
    }
    catch ( cacChannel::badType & )
    {
        return ECA_BADTYPE;
    }
    catch ( cacChannel::outOfBounds & )
    {
        return ECA_BADCOUNT;
    }
    catch ( cacChannel::badEventSelection & )
    {
        return ECA_BADMASK;
    }
    catch ( cacChannel::noReadAccess & )
    {
        return ECA_NORDACCESS;
    }
    catch ( cacChannel::unsupportedByService & )
    {
        return ECA_UNAVAILINSERV;
    }
    catch ( std::bad_alloc & )
    {
        return ECA_ALLOCMEM;
    }
    catch ( cacChannel::msgBodyCacheTooSmall & ) {
        return ECA_TOLARGE;
    }
    catch ( ... )
    {
        return ECA_INTERNAL;
    }
}
Beispiel #3
0
void comQueSend::insertRequestWithPayLoad (
    ca_uint16_t request, unsigned dataType, arrayElementCount nElem, 
    ca_uint32_t cid, ca_uint32_t requestDependent, 
    const void * pPayload, bool v49Ok ) 
{
    if ( INVALID_DB_REQ ( dataType ) ) {
        throw cacChannel::badType ();
    }
    if ( dataType >= comQueSendCopyDispatchSize ) {
        throw cacChannel::badType();
    }
    ca_uint32_t size = 0u;
    ca_uint32_t payloadSize = 0u;
    if ( nElem == 1 ) {
        if ( dataType == DBR_STRING  ) {
            const char * pStr = static_cast < const char * >  ( pPayload );
            size = strlen ( pStr ) + 1u;
            if ( size > MAX_STRING_SIZE ) {
                throw cacChannel::outOfBounds();
            }
            payloadSize = CA_MESSAGE_ALIGN ( size );
            this->insertRequestHeader ( request, payloadSize, 
                static_cast <ca_uint16_t> ( dataType ), 
                nElem, cid, requestDependent, v49Ok );
            this->pushString ( pStr, size );  
        }
        else {
            size = dbr_size[dataType];
            payloadSize = CA_MESSAGE_ALIGN ( size );
            this->insertRequestHeader ( request, payloadSize, 
                static_cast <ca_uint16_t> ( dataType ), 
                nElem, cid, requestDependent, v49Ok );
            ( this->*dbrCopyScalar [dataType] ) ( pPayload );
        }
    }
    else {
        arrayElementCount maxBytes;
        if ( v49Ok ) {
            maxBytes = 0xffffffff;
        }
        else {
            maxBytes = MAX_TCP - sizeof ( caHdr ); 
        }
        arrayElementCount maxElem = 
            ( maxBytes - sizeof (dbr_double_t) - dbr_size[dataType] ) / 
                dbr_value_size[dataType];
        if ( nElem >= maxElem ) {
            throw cacChannel::outOfBounds();
        }
        // the above checks verify that the total size
        // is lest that 0xffffffff
        size = static_cast < ca_uint32_t > 
            ( dbr_size_n ( dataType, nElem ) ); // X aCC 392
        payloadSize = CA_MESSAGE_ALIGN ( size );
        this->insertRequestHeader ( request, payloadSize, 
            static_cast <ca_uint16_t> ( dataType ), 
            static_cast < ca_uint32_t > ( nElem ), 
            cid, requestDependent, v49Ok );
        ( this->*dbrCopyVector [dataType] ) ( pPayload, nElem );
    }
    // set pad bytes to nill
    unsigned padSize = payloadSize - size;
    if ( padSize ) {
        this->pushString ( cacNillBytes, payloadSize - size );
    }
}
Beispiel #4
0
long dbGet(DBADDR *paddr, short dbrType,
    void *pbuffer, long *options, long *nRequest, void *pflin)
{
    char *pbuf = pbuffer;
    void *pfieldsave = paddr->pfield;
    db_field_log *pfl = (db_field_log *)pflin;
    short field_type;
    long capacity, no_elements, offset;
    struct rset *prset;
    long status = 0;

    if (options && *options)
        getOptions(paddr, &pbuf, options, pflin);
    if (nRequest && *nRequest == 0)
        return 0;

    if (!pfl || pfl->type == dbfl_type_rec) {
        field_type = paddr->field_type;
        no_elements = capacity = paddr->no_elements;

        /* Update field info from record
         * may modify paddr->pfield
         */
        if (paddr->pfldDes->special == SPC_DBADDR &&
            (prset = dbGetRset(paddr)) &&
            prset->get_array_info) {
            status = prset->get_array_info(paddr, &no_elements, &offset);
        } else
            offset = 0;
    } else {
        field_type = pfl->field_type;
        no_elements = capacity = pfl->no_elements;
        offset = 0;
    }

    if (field_type >= DBF_INLINK && field_type <= DBF_FWDLINK) {
        status = getLinkValue(paddr, dbrType, pbuf, nRequest);
        goto done;
    }

    if (paddr->special == SPC_ATTRIBUTE) {
        status = getAttrValue(paddr, dbrType, pbuf, nRequest);
        goto done;
    }

    /* Check for valid request */
    if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) {
        char message[80];

        sprintf(message, "dbGet: Request type is %d\n", dbrType);
        recGblDbaddrError(S_db_badDbrtype, paddr, message);
        status = S_db_badDbrtype;
        goto done;
    }

    if (offset == 0 && (!nRequest || no_elements == 1)) {
        if (nRequest)
            *nRequest = 1;
        if (!pfl || pfl->type == dbfl_type_rec) {
            status = dbFastGetConvertRoutine[field_type][dbrType]
                (paddr->pfield, pbuf, paddr);
        } else {
            DBADDR localAddr = *paddr; /* Structure copy */

            localAddr.field_type = pfl->field_type;
            localAddr.field_size = pfl->field_size;
            localAddr.no_elements = pfl->no_elements;
            if (pfl->type == dbfl_type_val)
                localAddr.pfield = (char *) &pfl->u.v.field;
            else
                localAddr.pfield = (char *)  pfl->u.r.field;
            status = dbFastGetConvertRoutine[field_type][dbrType]
                (localAddr.pfield, pbuf, &localAddr);
        }
    } else {
        long n;
        GETCONVERTFUNC convert;

        if (nRequest) {
            if (no_elements < *nRequest)
                *nRequest = no_elements;
            n = *nRequest;
        } else {
            n = 1;
        }
        convert = dbGetConvertRoutine[field_type][dbrType];
        if (!convert) {
            char message[80];

            sprintf(message, "dbGet: Missing conversion for [%d][%d]\n",
                    field_type, dbrType);
            recGblDbaddrError(S_db_badDbrtype, paddr, message);
            status = S_db_badDbrtype;
            goto done;
        }
        /* convert data into the caller's buffer */
        if (n <= 0) {
            ;/*do nothing*/
        } else if (!pfl || pfl->type == dbfl_type_rec) {
            status = convert(paddr, pbuf, n, capacity, offset);
        } else {
            DBADDR localAddr = *paddr; /* Structure copy */

            localAddr.field_type = pfl->field_type;
            localAddr.field_size = pfl->field_size;
            localAddr.no_elements = pfl->no_elements;
            if (pfl->type == dbfl_type_val)
                localAddr.pfield = (char *) &pfl->u.v.field;
            else
                localAddr.pfield = (char *)  pfl->u.r.field;
            status = convert(&localAddr, pbuf, n, capacity, offset);
        }
    }
done:
    paddr->pfield = pfieldsave;
    return status;
}
Beispiel #5
0
long dbPut(DBADDR *paddr, short dbrType,
    const void *pbuffer, long nRequest)
{
    dbCommon *precord = paddr->precord;
    short field_type  = paddr->field_type;
    long no_elements  = paddr->no_elements;
    long special      = paddr->special;
    void *pfieldsave  = paddr->pfield;
    struct rset *prset = dbGetRset(paddr);
    long status = 0;
    long offset;
    dbFldDes *pfldDes;
    int isValueField;

    if (special == SPC_ATTRIBUTE)
        return S_db_noMod;

    if (dbrType == DBR_PUT_ACKT && field_type <= DBF_DEVICE) {
        return putAckt(paddr, pbuffer, 1, 1, 0);
    } else if (dbrType == DBR_PUT_ACKS && field_type <= DBF_DEVICE) {
        return putAcks(paddr, pbuffer, 1, 1, 0);
    } else if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) {
        char message[80];

        sprintf(message, "dbPut: Request type is %d", dbrType);
        recGblDbaddrError(S_db_badDbrtype, paddr, message);
        return S_db_badDbrtype;
    }

    if (special) {
        status = dbPutSpecial(paddr, 0);
        if (status) return status;
    }

    if (paddr->pfldDes->special == SPC_DBADDR &&
        prset && prset->get_array_info) {
        long dummy;

        status = prset->get_array_info(paddr, &dummy, &offset);
        /* paddr->pfield may be modified */
        if (status) goto done;
    } else
        offset = 0;

    if (no_elements <= 1) {
        status = dbFastPutConvertRoutine[dbrType][field_type](pbuffer,
            paddr->pfield, paddr);
        nRequest = 1;
    } else {
        if (no_elements < nRequest)
            nRequest = no_elements;
        status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer,
            nRequest, no_elements, offset);
    }

    /* update array info */
    if (!status &&
        paddr->pfldDes->special == SPC_DBADDR &&
        prset && prset->put_array_info) {
        status = prset->put_array_info(paddr, nRequest);
    }

    /* Always do special processing if needed */
    if (special) {
        long status2 = dbPutSpecial(paddr, 1);
        if (status2) goto done;
    }
    if (status) goto done;

    /* Propagate monitor events for this field, */
    /* unless the field is VAL and PP is true. */
    pfldDes = paddr->pfldDes;
    isValueField = dbIsValueField(pfldDes);
    if (isValueField) precord->udf = FALSE;
    if (precord->mlis.count &&
        !(isValueField && pfldDes->process_passive))
        db_post_events(precord, pfieldsave, DBE_VALUE | DBE_LOG);
    /* If this field is a property (metadata) field,
     * then post a property change event (even if the field
     * didn't change).
     */
    if (precord->mlis.count && pfldDes->prop)
        db_post_events(precord, NULL, DBE_PROPERTY);
done:
    paddr->pfield = pfieldsave;
    return status;
}
Beispiel #6
0
long epicsShareAPI dbGet(DBADDR *paddr, short dbrType,
    void *pbuffer, long *options, long *nRequest, void *pflin)
{
    db_field_log *pfl = (db_field_log *)pflin;
    short field_type  = paddr->field_type;
    long no_elements  = paddr->no_elements;
    long offset;
    struct rset *prset;
    long status = 0;

    if (options && *options) {
        char *pbuf = pbuffer;

        getOptions(paddr, &pbuf, options, pflin);
        pbuffer = pbuf;
    }
    if (nRequest && *nRequest == 0) return 0;

    if (paddr->special == SPC_ATTRIBUTE) {
        char *pbuf = pbuffer;
        int maxlen;

        if (!paddr->pfield) return S_db_badField;

        switch (dbrType) {
        case DBR_STRING:
            maxlen = MAX_STRING_SIZE - 1;
            if (nRequest && *nRequest > 1) *nRequest = 1;
            break;

        case DBR_CHAR:
        case DBR_UCHAR:
            if (nRequest && *nRequest > 0) {
                maxlen = *nRequest - 1;
                break;
            }
            /* else fall through ... */
        default:
            return S_db_badDbrtype;
        }

        strncpy(pbuf, (char *)paddr->pfield, maxlen);
        pbuf[maxlen] = 0;
        return 0;
    }

    /* Check for valid request */
    if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) {
        char message[80];

        sprintf(message, "dbGet: Request type is %d\n", dbrType);
        recGblDbaddrError(S_db_badDbrtype, paddr, message);
        return S_db_badDbrtype;
    }

    /* check for array */
    if (paddr->special == SPC_DBADDR &&
        no_elements > 1 &&
        (prset = dbGetRset(paddr)) &&
        prset->get_array_info) {
        status = prset->get_array_info(paddr, &no_elements, &offset);
    } else
        offset = 0;

    if (offset == 0 && (!nRequest || no_elements == 1)) {
        if (nRequest) *nRequest = 1;
        if (pfl != NULL) {
            DBADDR localAddr = *paddr; /* Structure copy */

            localAddr.pfield = (char *)&pfl->field;
            status = dbFastGetConvertRoutine[field_type][dbrType]
                (localAddr.pfield, pbuffer, &localAddr);
        } else {
            status = dbFastGetConvertRoutine[field_type][dbrType]
                (paddr->pfield, pbuffer, paddr);
        }
    } else {
        long n;
        long (*convert)();

        if (nRequest) {
            if (no_elements<(*nRequest)) *nRequest = no_elements;
            n = *nRequest;
        } else {
            n = 1;
        }
        convert = dbGetConvertRoutine[field_type][dbrType];
        if (!convert) {
            char message[80];

            sprintf(message, "dbGet: Missing conversion for [%d][%d]\n",
                    field_type, dbrType);
            recGblDbaddrError(S_db_badDbrtype, paddr, message);
            return S_db_badDbrtype;
        }
        /* convert database field  and place it in the buffer */
        if (n <= 0) {
            ;/*do nothing*/
        } else if (pfl) {
            DBADDR localAddr = *paddr; /* Structure copy */

            localAddr.pfield = (char *)&pfl->field;
            status = convert(&localAddr, pbuffer, n, no_elements, offset);
        } else {
            status = convert(paddr, pbuffer, n, no_elements, offset);
        }
    }
    return status;
}
Beispiel #7
0
long epicsShareAPI dbPut(DBADDR *paddr, short dbrType,
    const void *pbuffer, long nRequest)
{
    dbCommon *precord = paddr->precord;
    short field_type  = paddr->field_type;
    long no_elements  = paddr->no_elements;
    long special      = paddr->special;
    long offset;
    long status = 0;
    dbFldDes *pfldDes;
    int isValueField;

    if (special == SPC_ATTRIBUTE) return S_db_noMod;

    if (dbrType == DBR_PUT_ACKT && field_type <= DBF_DEVICE) {
        return putAckt(paddr, (unsigned short *)pbuffer, 1, 1, 0);
    } else if (dbrType == DBR_PUT_ACKS && field_type <= DBF_DEVICE) {
        return putAcks(paddr, (unsigned short *)pbuffer, 1, 1, 0);
    } else if (INVALID_DB_REQ(dbrType) || field_type > DBF_DEVICE) {
        char message[80];

        sprintf(message, "dbPut: Request type is %d", dbrType);
        recGblDbaddrError(S_db_badDbrtype, paddr, message);
        return S_db_badDbrtype;
    }

    if (special) {
        status = dbPutSpecial(paddr, 0);
        if (status) return status;
    }

    if (no_elements <= 1) {
        status = dbFastPutConvertRoutine[dbrType][field_type](pbuffer,
            paddr->pfield, paddr);
    } else {
        struct rset *prset = dbGetRset(paddr);

        if (paddr->special == SPC_DBADDR &&
            prset && prset->get_array_info) {
            long dummy;

            status = prset->get_array_info(paddr, &dummy, &offset);
        }
        else
            offset = 0;
        if (no_elements < nRequest) nRequest = no_elements;
        if (!status)
            status = dbPutConvertRoutine[dbrType][field_type](paddr, pbuffer,
                nRequest, no_elements, offset);

        /* update array info */
        if (!status &&
            paddr->special == SPC_DBADDR &&
            prset && prset->put_array_info) {
            status = prset->put_array_info(paddr, nRequest);
        }
    }
    if (status) return status;

    /* check if special processing is required */
    if (special) {
        status = dbPutSpecial(paddr,1);
        if (status) return status;
    }

    /* Propagate monitor events for this field, */
    /* unless the field field is VAL and PP is true. */
    pfldDes = paddr->pfldDes;
    isValueField = dbIsValueField(pfldDes);
    if (isValueField) precord->udf = FALSE;
    if (precord->mlis.count &&
        !(isValueField && pfldDes->process_passive))
        db_post_events(precord, paddr->pfield, DBE_VALUE | DBE_LOG);

    return status;
}