Exemple #1
0
static void interruptCallbackOutput(void *drvPvt, asynUser *pasynUser,
                epicsFloat64 value)
{
    devPvt *pPvt = (devPvt *)drvPvt;
    dbCommon *pr = pPvt->pr;
    ringBufferElement *rp;

    asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE,
        "%s devAsynFloat64::interruptCallbackOutput new value=%f\n",
        pr->name, value);
    if (!interruptAccept) return;
    epicsMutexLock(pPvt->ringBufferLock);
    rp = &pPvt->ringBuffer[pPvt->ringHead];
    rp->value = value;
    rp->time = pasynUser->timestamp;
    rp->status = pasynUser->auxStatus;
    rp->alarmStatus = pasynUser->alarmStatus;
    rp->alarmSeverity = pasynUser->alarmSeverity;
    pPvt->ringHead = (pPvt->ringHead==pPvt->ringSize) ? 0 : pPvt->ringHead+1;
    if (pPvt->ringHead == pPvt->ringTail) {
        pPvt->ringTail = (pPvt->ringTail==pPvt->ringSize) ? 0 : pPvt->ringTail+1;
        pPvt->ringBufferOverflows++;
    } else {
        scanOnce(pr);
    }
    epicsMutexUnlock(pPvt->ringBufferLock);
}
Exemple #2
0
void scanShutdown(void)
{
    int i;

    if (scanCtl == ctlExit) return;
    scanCtl = ctlExit;

    interruptAccept = FALSE;

    for (i = 0; i < nPeriodic; i++) {
        papPeriodic[i]->scanCtl = ctlExit;
        epicsEventSignal(papPeriodic[i]->loopEvent);
        epicsEventWait(startStopEvent);
    }

    scanOnce((dbCommon *)&exitOnce);
    epicsEventWait(startStopEvent);

    deletePeriodic();
    ioscanDestroy();

    epicsRingPointerDelete(onceQ);

    epicsEventDestroy(startStopEvent);
    epicsEventDestroy(onceSem);
    onceSem = startStopEvent = NULL;

    free(periodicTaskId);
    papPeriodic = NULL;
    periodicTaskId = NULL;
}
Exemple #3
0
static void interruptCallbackOutput(void *drvPvt, asynUser *pasynUser,
                epicsInt32 value)
{
    devInt32Pvt *pPvt = (devInt32Pvt *)drvPvt;
    dbCommon *pr = pPvt->pr;
    ringBufferElement *rp;

    if (pPvt->mask) {
        value &= pPvt->mask;
        if (pPvt->bipolar && (value & pPvt->signBit)) value |= ~pPvt->mask;
    }
    asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE,
        "%s devAsynInt32::interruptCallbackOutput new value=%d\n",
        pr->name, value);
    if (!interruptAccept) return;
    epicsMutexLock(pPvt->ringBufferLock);
    rp = &pPvt->ringBuffer[pPvt->ringHead];
    rp->value = value;
    rp->time = pasynUser->timestamp;
    rp->status = pasynUser->auxStatus;
    pPvt->ringHead = (pPvt->ringHead==pPvt->ringSize) ? 0 : pPvt->ringHead+1;
    if (pPvt->ringHead == pPvt->ringTail) {
        pPvt->ringTail = (pPvt->ringTail==pPvt->ringSize) ? 0 : pPvt->ringTail+1;
        pPvt->ringBufferOverflows++;
    } else {
        scanOnce(pr);
    }
    epicsMutexUnlock(pPvt->ringBufferLock);
}
Exemple #4
0
static void accessRightsCallback(struct access_rights_handler_args arg)
{
    caLink *pca = (caLink *)ca_puser(arg.chid);
    struct link	*plink;
    struct pv_link *ppv_link;
    dbCommon *precord;

    assert(pca);
    if (ca_state(pca->chid) != cs_conn)
        return; /* connectionCallback will handle */
    epicsMutexMustLock(pca->lock);
    plink = pca->plink;
    if (!plink) goto done;
    pca->hasReadAccess = ca_read_access(arg.chid);
    pca->hasWriteAccess = ca_write_access(arg.chid);
    if (pca->hasReadAccess && pca->hasWriteAccess) goto done;
    ppv_link = &plink->value.pv_link;
    precord = ppv_link->precord;
    if (precord &&
        ((ppv_link->pvlMask & pvlOptCP) ||
         ((ppv_link->pvlMask & pvlOptCPP) && precord->scan == 0)))
        scanOnce(precord);
done:
    epicsMutexUnlock(pca->lock);
}
Exemple #5
0
static void liSrqHandler(void *userPrivate,asynUser *pasynUser,
                         epicsInt32 statusByte)
{
    longinRecord *pli = (longinRecord *)userPrivate;
    gpibDpvt *pgpibDpvt = gpibDpvtGet(pli);
    pli->val = statusByte;
    pli->udf = FALSE;
    scanOnce(pgpibDpvt->precord);
}
Exemple #6
0
/* We need to know when a save or restore operation has completed, so client software
 * can wait for the operation to complete before acting on the result.
 */
void configMenuCallback(int status, void *puserPvt) {
	aSubRecord *pasub = (aSubRecord *)puserPvt;
	epicsInt32 *d = (epicsInt32 *)pasub->d;

	if (configMenuDebug)
		printf("configMenuCallback:status=%d, puserPvt=%p\n", status, puserPvt);
	dbScanLock((dbCommon *)pasub);
	*d = (epicsInt32)status;
	dbScanUnlock((dbCommon *)pasub);
	scanOnce((dbCommon *)puserPvt);
}
Exemple #7
0
/* Callback for bo, see ao_callback comments */
static void check_bo_callback(void *arg)
{
    boRecord      *rec = (boRecord *) arg;
    struct rset   *rset= (struct rset *)(rec->rset);
    DevicePrivate *pvt = (DevicePrivate *)rec->dpvt;
    unsigned long rval;
    eip_bool      process = false;

    /* We are about the check and even set val, & rval -> lock */
    dbScanLock((dbCommon *)rec);
    if (rec->pact)
    {
        (*rset->process) ((dbCommon *)rec);
        dbScanUnlock((dbCommon *)rec);
        return;
    }
    /* Check if record's (R)VAL is current */
    if (!check_data((dbCommon *) rec))
    {
        (*rset->process) ((dbCommon *)rec);
        dbScanUnlock((dbCommon *)rec);
        return;
    }
    if (get_bits((dbCommon *)rec, 1, &rval) &&
        (rec->udf || rec->sevr == INVALID_ALARM || rec->rval != rval))
    {
        if (rec->tpro)
            printf("'%s': got %lu from driver\n", rec->name, rval);
        if (!rec->udf  &&  pvt->special & SPCO_FORCE)
        {
            if (rec->tpro)
                printf("'%s': will re-write record's value %u\n",
                       rec->name, (unsigned int)rec->val);
        }
        else
        {   /* back-convert rval into val */
            rec->rval = rval;
            rec->val  = (rec->rval==0) ? 0 : 1;
            rec->udf = false;
            if (rec->tpro)
                printf("'%s': updated record to tag, val = %u\n",
                       rec->name, (unsigned int)rec->val);
        }
        process = true;
    }
    dbScanUnlock((dbCommon *)rec);
    /* Does record need processing and is not periodic? */
    if (process && rec->scan < SCAN_1ST_PERIODIC)
        scanOnce(rec);
}
Exemple #8
0
void recGblFwdLink(void *precord)
{
    dbCommon *pdbc = precord;

    dbScanFwdLink(&pdbc->flnk);
    /*Handle dbPutFieldNotify record completions*/
    if(pdbc->ppn) dbNotifyCompletion(pdbc);
    if(pdbc->rpro) {
	/*If anyone requested reprocessing do it*/
	pdbc->rpro = FALSE;
	scanOnce(pdbc);
    }
    /*In case putField caused put we are all done */
    pdbc->putf = FALSE;
}
static void interruptCallbackOutput(void *drvPvt, asynUser *pasynUser,
                epicsInt32 value)
{
    devInt32Pvt *pPvt = (devInt32Pvt *)drvPvt;
    dbCommon *pr = pPvt->pr;
    int count, size = sizeof(epicsInt32);

    asynPrint(pPvt->pasynUser, ASYN_TRACEIO_DEVICE,
        "%s devAsynInt32::interruptCallbackOutput new value=%d\n",
        pr->name, value);
    epicsMutexLock(pPvt->mutexId);
    count = epicsRingBytesPut(pPvt->ringBuffer, (char *)&value, size);
    if (count != size) {
        pPvt->ringBufferOverflows++;
    }
    epicsMutexUnlock(pPvt->mutexId);
    scanOnce(pr);
}
static void testRTT() {

    wifi_scan_result results[256];
    int num_results = scanOnce(WIFI_BAND_ABG, results, countof(results));
    if (num_results == 0) {
        printMsg("RTT aborted because of no scan results\n");
        return;
    } else {
        printMsg("Retrieved %d scan results\n", num_results);
    }

    num_results = removeDuplicateScanResults(results, num_results);
    /*
    printMsg("Deduped scan results - %d\n", num_results);
    for (int i = 0; i < num_results; i++) {
        printScanResult(results[i]);
    }
    */

    sortScanResultsByRssi(results, num_results);
    printMsg("Sorted scan results -\n");
    for (int i = 0; i < num_results; i++) {
        printScanResult(results[i]);
    }


    static const int max_ap = 5;
    wifi_rtt_config params[max_ap];
    memset(params, 0, sizeof(params));

    printMsg("Configuring RTT for %d APs, num_samples = %d\n",
            min(num_results, max_ap), rtt_samples);

    unsigned num_ap = 0;
    for (int i = 0; i < min(num_results, max_ap); i++, num_ap++) {

        memcpy(params[i].addr, results[i].bssid, sizeof(mac_addr));
        mac_addr &addr = params[i].addr;
        printMsg("Adding %02x:%02x:%02x:%02x:%02x:%02x (%d) for RTT\n", addr[0],
                addr[1], addr[2], addr[3], addr[4], addr[5], results[i].channel);

        params[i].type  = RTT_TYPE_1_SIDED;
        params[i].channel.center_freq = results[i].channel;
        params[i].channel.width = WIFI_CHAN_WIDTH_20;
        params[i].peer  = WIFI_PEER_INVALID;
        params[i].continuous = 1;
        params[i].interval = 1000;
        params[i].num_samples_per_measurement = rtt_samples;
        params[i].num_retries_per_measurement = 10;
    }

    wifi_rtt_event_handler handler;
    handler.on_rtt_results = &onRTTResults;

    int result = wifi_rtt_range_request(rttCmdId, wlan0Handle, num_ap, params, handler);

    if (result == WIFI_SUCCESS) {
        printMsg("Waiting for RTT results\n");

        while (true) {
            EventInfo info;
            memset(&info, 0, sizeof(info));
            getEventFromCache(info);

            if (info.type == EVENT_TYPE_SCAN_RESULTS_AVAILABLE) {
                retrieveScanResults();
            } else if (info.type == EVENT_TYPE_RTT_RESULTS) {
                break;
            }
        }
    } else {
        printMsg("Could not set setRTTAPs : %d\n", result);
    }
}
Exemple #11
0
/* Callback for mbbo */
static void check_mbbo_callback(void *arg)
{
    mbboRecord    *rec = (mbboRecord *) arg;
    struct rset   *rset= (struct rset *)(rec->rset);
    DevicePrivate *pvt = (DevicePrivate *)rec->dpvt;
    unsigned long rval, *state_val;
    size_t        i;
    eip_bool      process = false;

    /* We are about the check and even set val, & rval -> lock */
    dbScanLock((dbCommon *)rec);
    if (rec->pact)
    {
        (*rset->process) ((dbCommon *)rec);
        dbScanUnlock((dbCommon *)rec);
        return;
    }
    /* Check if record's (R)VAL is current */
    if (!check_data ((dbCommon *) rec))
    {
        (*rset->process) ((dbCommon *)rec);
        dbScanUnlock((dbCommon *)rec);
        return;
    }
    if (get_bits ((dbCommon *)rec, rec->nobt, &rval) &&
        (rec->udf || rec->sevr == INVALID_ALARM || rec->rval != rval))
    {
        if (rec->tpro)
            printf("'%s': got %lu from driver\n", rec->name, rval);
        if (!rec->udf  &&  pvt->special & SPCO_FORCE)
        {
            if (rec->tpro)
                printf("'%s': will re-write record's rval 0x%X\n",
                       rec->name, (unsigned int)rec->rval);
        }
        else
        {   /* back-convert rval into val */
            if (rec->sdef)
            {
                rec->val  = 65535;  /* initalize to unknown state*/
                state_val = &rec->zrvl;
                for (i=0; i<16; ++i)
                {
                    if (*state_val == rval)
                    {
                        rec->val = i;
                        break;
                    }
                    state_val++;
                }
                rec->udf = false;
            }
            else
            {
                /* the raw value is the desired val */
                rec->val = (unsigned short)rval;
                rec->udf = false;
            }
            if (rec->tpro)
                printf("--> val = %u\n", (unsigned int)rec->val);
        }
        process = true;
    }
    dbScanUnlock((dbCommon *)rec);
    /* Does record need processing and is not periodic? */
    if (process && rec->scan < SCAN_1ST_PERIODIC)
        scanOnce (rec);
}
Exemple #12
0
/* Callback from driver for every received tag, for ao record:
 * Check if
 *
 * 1) pact set -> this is the "finshed the write" callback
 * 2) pact not set -> this is the "new value" callback
 *    Tag value is either different from current record value
 *    or there is no current record value:
 * 2a) disconnected; process record to set WRITE/INVALID
 * 2b) PLC's value != record's idea of the current value
 * 2c) record is UDF, so this is the first time we get a value
 *     from the PLC after a reboot
 * Causing process if necessary to update the record.
 * That process()/scanOnce() call should NOT cause the record to write
 * to the PLC because the xxx_write method will notice that
 * the PLC and record value agree.
 * It will, however, trigger CA monitors.
 *
 * Problem: Alarms are handled before "write_xx" is called.
 * So we have to set udf in here,
 * then process() can recognize udf and finally it will
 * call write_xx.
 */
static void check_ao_callback(void *arg)
{
    aoRecord      *rec = (aoRecord *) arg;
    struct rset   *rset= (struct rset *)(rec->rset);
    DevicePrivate *pvt = (DevicePrivate *)rec->dpvt;
    double        dbl;
    CN_DINT       dint;
    eip_bool      process = false;

    /* We are about the check and even set val, & rval -> lock */
    dbScanLock((dbCommon *)rec);
    if (rec->pact)
    {
        if (rec->tpro)
            printf("EIP check_ao_callback('%s'), pact=%d\n",
                   rec->name, rec->pact);
        (*rset->process) ((dbCommon *)rec);
        dbScanUnlock((dbCommon *)rec);
        return;
    }
    /* Check if record's (R)VAL is current */
    if (!check_data((dbCommon *)rec))
    {
        if (rec->tpro)
            printf("EIP check_ao_callback('%s'), no data\n", rec->name);
        (*rset->process) ((dbCommon *)rec);
        dbScanUnlock((dbCommon *)rec);
        return;
    }
    if (get_CIP_typecode(pvt->tag->data) == T_CIP_REAL)
    {
        if (rec->tpro)
            printf("EIP check_ao_callback('%s') w/ real data\n", rec->name);
        if (get_CIP_double(pvt->tag->data, pvt->element, &dbl) &&
            (rec->udf || rec->sevr == INVALID_ALARM || rec->val != dbl))
        {
            if (rec->tpro)
                printf("'%s': got %g from driver\n", rec->name, dbl);
            if (!rec->udf  &&  pvt->special & SPCO_FORCE)
            {
                if (rec->tpro)
                    printf("'%s': will re-write record's value %g\n",
                           rec->name, rec->val);
            }
            else
            {
                rec->val = rec->pval = dbl;
                rec->udf = false;
                if (rec->tpro)
                    printf("'%s': updated record's value %g\n",
                           rec->name, rec->val);
            }
            process = true;
        }
    }
    else
    {
        if (rec->tpro)
            printf("EIP check_ao_callback('%s') w/ int. data\n", rec->name);
        if (get_CIP_DINT(pvt->tag->data, pvt->element, &dint) &&
            (rec->udf || rec->sevr == INVALID_ALARM || rec->rval != dint))
        {
            if (rec->tpro)
                printf("AO '%s': got %ld from driver\n",
                       rec->name, (long)dint);
            if (!rec->udf  &&  pvt->special & SPCO_FORCE)
            {
                if (rec->tpro)
                    printf("AO '%s': will re-write record's rval 0x%X\n",
                           rec->name, (unsigned int)rec->rval);
            }
            else
            {
                /* back-convert raw value into val (copied from ao init) */
                dbl = (double)dint + (double)rec->roff;
                if (rec->aslo!=0.0)
                    dbl *= rec->aslo;
                dbl += rec->aoff;
                switch (rec->linr)
                {
                    case menuConvertNO_CONVERSION:
                        rec->val = rec->pval = dbl;
                        rec->udf = false;
                        break;
                    case menuConvertLINEAR:
                    case menuConvertSLOPE:
                        dbl = dbl*rec->eslo + rec->eoff;
                        rec->val = rec->pval = dbl;
                        rec->udf = false;
                        break;
                    default:
                        if (cvtRawToEngBpt(&dbl,rec->linr,rec->init,
                                           (void *)&rec->pbrk,
                                           &rec->lbrk)!=0)
                            break; /* cannot back-convert */
                        rec->val = rec->pval = dbl;
                        rec->udf = false;
                }
                if (rec->tpro)
                    printf("'%s': updated record's value to %g\n",
                           rec->name, rec->val);
            }
            process = true;
        }
    }
    dbScanUnlock((dbCommon *)rec);
    /* Does record need processing and is not periodic? */
    if (process && rec->scan < SCAN_1ST_PERIODIC)
        scanOnce(rec);
}
Exemple #13
0
static void eventCallback(struct event_handler_args arg)
{
    caLink *pca = (caLink *)arg.usr;
    struct link *plink;
    size_t size;
    dbCommon *precord = 0;
    struct dbr_time_double *pdbr_time_double;
    dbCaCallback monitor = 0;
    void *userPvt = 0;

    assert(pca);
    epicsMutexMustLock(pca->lock);
    plink = pca->plink;
    if (!plink) goto done;
    monitor = pca->monitor;
    userPvt = pca->userPvt;
    precord = plink->value.pv_link.precord;
    if (arg.status != ECA_NORMAL) {
        if (precord) {
            if (arg.status != ECA_NORDACCESS &&
                arg.status != ECA_GETFAIL)
                errlogPrintf("dbCa: eventCallback record %s error %s\n",
                    precord->name, ca_message(arg.status));
        } else {
            errlogPrintf("dbCa: eventCallback error %s\n",
                ca_message(arg.status));
        }
        goto done;
    }
    assert(arg.dbr);
    size = arg.count * dbr_value_size[arg.type];
    if (arg.type == DBR_TIME_STRING &&
        ca_field_type(pca->chid) == DBR_ENUM) {
        assert(pca->pgetString);
        memcpy(pca->pgetString, dbr_value_ptr(arg.dbr, arg.type), size);
        pca->gotInString = TRUE;
    } else switch (arg.type){
    case DBR_TIME_STRING: 
    case DBR_TIME_SHORT: 
    case DBR_TIME_FLOAT:
    case DBR_TIME_ENUM:
    case DBR_TIME_CHAR:
    case DBR_TIME_LONG:
    case DBR_TIME_DOUBLE:
        assert(pca->pgetNative);
        memcpy(pca->pgetNative, dbr_value_ptr(arg.dbr, arg.type), size);
        pca->gotInNative = TRUE;
        break;
    default:
        errMessage(-1, "dbCa: eventCallback Logic Error\n");
        break;
    }
    pdbr_time_double = (struct dbr_time_double *)arg.dbr;
    pca->sevr = pdbr_time_double->severity;
    pca->stat = pdbr_time_double->status;
    memcpy(&pca->timeStamp, &pdbr_time_double->stamp, sizeof(epicsTimeStamp));
    if (precord) {
        struct pv_link *ppv_link = &plink->value.pv_link;

        if ((ppv_link->pvlMask & pvlOptCP) ||
            ((ppv_link->pvlMask & pvlOptCPP) && precord->scan == 0))
        scanOnce(precord);
    }
done:
    epicsMutexUnlock(pca->lock);
    if (monitor) monitor(userPvt);
}
Exemple #14
0
static void connectionCallback(struct connection_handler_args arg)
{
    caLink *pca;
    short link_action = 0;
    struct link *plink;

    pca = ca_puser(arg.chid);
    assert(pca);
    epicsMutexMustLock(pca->lock);
    plink = pca->plink;
    if (!plink) goto done;
    pca->isConnected = (ca_state(arg.chid) == cs_conn);
    if (!pca->isConnected) {
        struct pv_link *ppv_link = &plink->value.pv_link;
        dbCommon *precord = ppv_link->precord;

        pca->nDisconnect++;
        if (precord &&
            ((ppv_link->pvlMask & pvlOptCP) ||
             ((ppv_link->pvlMask & pvlOptCPP) && precord->scan == 0)))
            scanOnce(precord);
        goto done;
    }
    pca->hasReadAccess = ca_read_access(arg.chid);
    pca->hasWriteAccess = ca_write_access(arg.chid);

    if (pca->gotFirstConnection) {
        if (pca->nelements != ca_element_count(arg.chid) ||
            pca->dbrType != ca_field_type(arg.chid)) {
            /* BUG: We have no way to clear any old subscription with the
             *      originally chosen data type/size.  That will continue
             *      to send us data and will result in an assert() fail.
             */
            /* Let next dbCaGetLink and/or dbCaPutLink determine options */
            plink->value.pv_link.pvlMask &=
                ~(pvlOptInpNative | pvlOptInpString |
                  pvlOptOutNative | pvlOptOutString);

            pca->gotInNative  = 0;
            pca->gotOutNative = 0;
            pca->gotInString  = 0;
            pca->gotOutString = 0;
            free(pca->pgetNative); pca->pgetNative = 0;
            free(pca->pgetString); pca->pgetString = 0;
            free(pca->pputNative); pca->pputNative = 0;
            free(pca->pputString); pca->pputString = 0;
        }
    }
    pca->gotFirstConnection = TRUE;
    pca->nelements = ca_element_count(arg.chid);
    pca->dbrType = ca_field_type(arg.chid);
    if ((plink->value.pv_link.pvlMask & pvlOptInpNative) && !pca->pgetNative) {
        link_action |= CA_MONITOR_NATIVE;
    }
    if ((plink->value.pv_link.pvlMask & pvlOptInpString) && !pca->pgetString) {
        link_action |= CA_MONITOR_STRING;
    }
    if ((plink->value.pv_link.pvlMask & pvlOptOutNative) && pca->gotOutNative) {
        link_action |= CA_WRITE_NATIVE;
    }
    if ((plink->value.pv_link.pvlMask & pvlOptOutString) && pca->gotOutString) {
        link_action |= CA_WRITE_STRING;
    }
    pca->gotAttributes = 0;
    if (pca->dbrType != DBR_STRING) {
        link_action |= CA_GET_ATTRIBUTES;
    }
done:
    if (link_action) addAction(pca, link_action);
    epicsMutexUnlock(pca->lock);
}