Пример #1
0
static void connection_handler ( struct connection_handler_args args )
{
    pv *ppv = ( pv * ) ca_puser ( args.chid );
    if ( args.op == CA_OP_CONN_UP ) {
        nConn++;
        if (!ppv->onceConnected) {
            ppv->onceConnected = 1;
                                /* Set up pv structure */
                                /* ------------------- */

                                /* Get natural type and array count */
            ppv->dbfType = ca_field_type(ppv->chid);
            ppv->dbrType = dbf_type_to_DBR_TIME(ppv->dbfType); /* Use native type */
            if (dbr_type_is_ENUM(ppv->dbrType))                /* Enums honour -n option */
            {
                if (enumAsNr) ppv->dbrType = DBR_TIME_INT;
                else          ppv->dbrType = DBR_TIME_STRING;
            }
            else if (floatAsString &&
                     (dbr_type_is_FLOAT(ppv->dbrType) || dbr_type_is_DOUBLE(ppv->dbrType)))
            {
                ppv->dbrType = DBR_TIME_STRING;
            }
                                /* Set request count */
            ppv->nElems   = ca_element_count(ppv->chid);
            ppv->reqElems = reqElems > ppv->nElems ? ppv->nElems : reqElems;

                                /* Issue CA request */
                                /* ---------------- */
            /* install monitor once with first connect */
            ppv->status = ca_create_subscription(ppv->dbrType,
                                                ppv->reqElems,
                                                ppv->chid,
                                                eventMask,
                                                event_handler,
                                                (void*)ppv,
                                                NULL);
        }
    }
    else if ( args.op == CA_OP_CONN_DOWN ) {
        nConn--;
        ppv->status = ECA_DISCONN;
        print_time_val_sts(ppv, reqElems);
    }
}
Пример #2
0
void connection_handler ( struct connection_handler_args args )
{
    pv *ppv = ( pv * ) ca_puser ( args.chid );
    if ( args.op == CA_OP_CONN_UP ) {
        int dbrType;
                                /* Set up pv structure */
                                /* ------------------- */

                                /* Get natural type and array count */
        ppv->nElems  = ca_element_count(ppv->chid);
        ppv->dbfType = ca_field_type(ppv->chid);

                                /* Set up value structures */
        dbrType = dbf_type_to_DBR_TIME(ppv->dbfType); /* Use native type */
        if (dbr_type_is_ENUM(dbrType))                  /* Enums honour -n option */
        {
            if (enumAsNr) dbrType = DBR_TIME_INT;
            else          dbrType = DBR_TIME_STRING;
        }
        
        else if (floatAsString &&
                 (dbr_type_is_FLOAT(dbrType) || dbr_type_is_DOUBLE(dbrType)))
        {
            dbrType = DBR_TIME_STRING;
        }
                                /* Adjust array count */
        if (reqElems == 0 || ppv->nElems < reqElems){
            ppv->reqElems = ppv->nElems; /* Use full number of points */
        } else {
            ppv->reqElems = reqElems; /* Limit to specified number */
        }

                                /* Remember dbrType */
        ppv->dbrType  = dbrType;

        ppv->onceConnected = 1;
        nConn++;
                                /* Issue CA request */
                                /* ---------------- */
        /* install monitor once with first connect */
        if ( ! ppv->value ) {
                                    /* Allocate value structure */
            ppv->value = calloc(1, dbr_size_n(dbrType, ppv->reqElems));           
            if ( ppv->value ) {
                ppv->status = ca_create_subscription(dbrType,
                                                ppv->reqElems,
                                                ppv->chid,
                                                eventMask,
                                                event_handler,
                                                (void*)ppv,
                                                NULL);
                if ( ppv->status != ECA_NORMAL ) {
                    free ( ppv->value );
                }
            }
        }
    }
    else if ( args.op == CA_OP_CONN_DOWN ) {
        nConn--;
        ppv->status = ECA_DISCONN;
        print_time_val_sts(ppv, ppv->reqElems);
    }
}
Пример #3
0
int caget (pv *pvs, int nPvs, OutputT format,
           chtype dbrType, unsigned long reqElems)
{
    unsigned int i;
    int n, result;

    for (n = 0; n < nPvs; n++) {

                                /* Set up pvs structure */
                                /* -------------------- */

                                /* Get natural type and array count */
        pvs[n].nElems  = ca_element_count(pvs[n].chid);
        pvs[n].dbfType = ca_field_type(pvs[n].chid);
        pvs[n].dbrType = dbrType;

                                /* Set up value structures */
        pvs[n].dbrType = dbf_type_to_DBR_TIME(pvs[n].dbfType); /* Use native type */
        if (dbr_type_is_ENUM(pvs[n].dbrType))             /* Enums honour -n option */
        {
            if (enumAsNr) pvs[n].dbrType = DBR_TIME_INT;
            else          pvs[n].dbrType = DBR_TIME_STRING;
        }

        if (reqElems == 0 || pvs[n].nElems < reqElems)    /* Adjust array count */
            pvs[n].reqElems = pvs[n].nElems;
        else
            pvs[n].reqElems = reqElems;

                                /* Issue CA request */
                                /* ---------------- */

        if (ca_state(pvs[n].chid) == cs_conn)
        {
            nConn++;
            pvs[n].onceConnected = 1;
                                   /* Allocate value structure */
            pvs[n].value = calloc(1, dbr_size_n(pvs[n].dbrType, pvs[n].reqElems));
            if(!pvs[n].value){
                fprintf(stderr,"Allocation failed\n");
                exit(1);
            }
            result = ca_array_get(pvs[n].dbrType,
                                  pvs[n].reqElems,
                                  pvs[n].chid,
                                  pvs[n].value);
            pvs[n].status = result;
        } else {
            pvs[n].status = ECA_DISCONN;
        }
    }
    if (!nConn) return 1;              /* No connection? We're done. */

                                /* Wait for completion */
                                /* ------------------- */

    result = ca_pend_io(caTimeout);
    if (result == ECA_TIMEOUT)
        fprintf(stderr, "Read operation timed out: PV data was not read.\n");

                                /* Print the data */
                                /* -------------- */

    for (n = 0; n < nPvs; n++) {

        switch (format) {
        case plain:             /* Emulate old caput behaviour */
            if (pvs[n].reqElems <= 1 && fieldSeparator == ' ') printf("%-30s", pvs[n].name);
            else                                               printf("%s", pvs[n].name);
            printf("%c", fieldSeparator);
        case terse:
            if (pvs[n].status == ECA_DISCONN)
                printf("*** not connected\n");
            else if (pvs[n].status == ECA_NORDACCESS)
                printf("*** no read access\n");
            else if (pvs[n].status != ECA_NORMAL)
                printf("*** CA error %s\n", ca_message(pvs[n].status));
            else if (pvs[n].value == 0)
                printf("*** no data available (timeout)\n");
            else
            {
                if (charArrAsStr && dbr_type_is_CHAR(pvs[n].dbrType) && (reqElems || pvs[n].reqElems > 1)) {
                    dbr_char_t *s = (dbr_char_t*) dbr_value_ptr(pvs[n].value, pvs[n].dbrType);
                    int dlen = epicsStrnEscapedFromRawSize((char*)s, strlen((char*)s));
                    char *d = calloc(dlen+1, sizeof(char));
                    if(!d){
                        fprintf(stderr,"Allocation failed\n");
                        exit(1);
                    }
                    epicsStrnEscapedFromRaw(d, dlen+1, (char*)s, strlen((char*)s));
                    printf("%s", d);
                    free(d);
                } else {
                    if (reqElems || pvs[n].nElems > 1) printf("%lu%c", pvs[n].reqElems, fieldSeparator);
                    for (i=0; i<pvs[n].reqElems; ++i) {
                        if (i) printf ("%c", fieldSeparator);
                        printf("%s", val2str(pvs[n].value, pvs[n].dbrType, i));
                    }
                }
                printf("\n");
            }
            break;
        case all:
            print_time_val_sts(&pvs[n], reqElems);
            break;
        default :
            break;
        }
    }
    return 0;
}
Пример #4
0
int cagetFuZE(char *pvName, char *pvValue) {

  RequestT request = get;
  OutputT format = plain;
  chtype dbrType = -1;
  unsigned long reqElems = 0;
  int n, result;
  pv* pvs;
  int i;
  unsigned long nElems;
  

  result = ca_context_create(ca_disable_preemptive_callback);

  pvs = calloc(1, sizeof(pv));

  pvs[0].name = pvName;
  
  connect_pvs(pvs, 1);
  
  for (n = 0; n < 1; n++) {
    
    /* Set up pvs structure */
    /* -------------------- */

    /* Get natural type and array count */
    nElems         = ca_element_count(pvs[n].chid);
    pvs[n].dbfType = ca_field_type(pvs[n].chid);
    pvs[n].dbrType = dbrType;

    /* Set up value structures */
    if (format != specifiedDbr)
      {
	pvs[n].dbrType = dbf_type_to_DBR_TIME(pvs[n].dbfType); /* Use native type */
	if (dbr_type_is_ENUM(pvs[n].dbrType))                  /* Enums honour -n option */
	  {
	    if (enumAsNr) pvs[n].dbrType = DBR_TIME_INT;
	    else          pvs[n].dbrType = DBR_TIME_STRING;
	  }
	else if (floatAsString &&
		 (dbr_type_is_FLOAT(pvs[n].dbrType) || dbr_type_is_DOUBLE(pvs[n].dbrType)))
	  {
	    pvs[n].dbrType = DBR_TIME_STRING;
	  }
      }

    /* Issue CA request */
    /* ---------------- */

    if (ca_state(pvs[n].chid) == cs_conn)
      {
  	nConn++;
  	pvs[n].onceConnected = 1;
  	if (request == callback)
  	  {
  	    /* Event handler will allocate value and set nElems */
  	    pvs[n].reqElems = reqElems > nElems ? nElems : reqElems;
  	    result = ca_array_get_callback(pvs[n].dbrType,
  					   pvs[n].reqElems,
  					   pvs[n].chid,
  					   event_handler,
  					   (void*)&pvs[n]);
  	  } else {
  	  /* We allocate value structure and set nElems */
	  pvs[n].nElems = reqElems && reqElems < nElems ? reqElems : nElems;
  	  pvs[n].value = calloc(1, dbr_size_n(pvs[n].dbrType, pvs[n].nElems));
	  if (!pvs[n].value) {
  	    fprintf(stderr,"Memory allocation failed\n");
  	    return -1;
  	  }
  	  result = ca_array_get(pvs[n].dbrType,
  				pvs[n].nElems,
  				pvs[n].chid,
  				pvs[n].value);
  	}
  	pvs[n].status = result;
      } else {
      pvs[n].status = ECA_DISCONN;
    }
  }

  if (!nConn) return -1;              /* No connection? We're done. */

  /* Wait for completion */
  /* ------------------- */

  result = ca_pend_io(caTimeout);
  if (result == ECA_TIMEOUT) {
    fprintf(stderr, "Read operation timed out: some PV data was not read.\n");
    return -1;
  }

  if (request == callback)    /* Also wait for callbacks */
    {
      if (caTimeout != 0)
        {
	  double slice = caTimeout / PEND_EVENT_SLICES;
	  for (n = 0; n < PEND_EVENT_SLICES; n++)
            {
	      ca_pend_event(slice);
	      if (nRead >= nConn) break;
            }
	  if (nRead < nConn) {
	    fprintf(stderr, "Read operation timed out: some PV data was not read.\n");
	    return -1;
	  }
	} else {
	/* For 0 timeout keep waiting until all are done */
	    while (nRead < nConn) {
	      ca_pend_event(1.0);
	    }
      }
    }


  // Does this kill the connection??
  ca_context_destroy();
  
  sprintf(pvValue, "%s\n", val2str(pvs[0].value, pvs[0].dbrType, 0));

  return 1;

}
Пример #5
0
static void medmConnectEventCb(struct connection_handler_args args) {
    int status;
    Channel *pCh = (Channel *)ca_puser(args.chid);
    int count;

  /* Increment the event counter */
    caTask.caEventCount++;

  /* Check for valid values */
    if(globalDisplayListTraversalMode != DL_EXECUTE) return;
    if(!pCh || !pCh->chid || !pCh->pr) {
	medmPostMsg(0,"medmConnectEventCb: Invalid channel information\n");
	return;
    }

  /* Do a get every time a channel is connected or reconnected and has
   * read access.  The get will cause the graphical info callback to
   * be called */
    if(args.op == CA_OP_CONN_UP && ca_read_access(pCh->chid)) {
	status = ca_array_get_callback(
	  dbf_type_to_DBR_CTRL(ca_field_type(args.chid)),
	  1, args.chid, medmUpdateGraphicalInfoCb, NULL);
	if(status != ECA_NORMAL) {
	    medmPostMsg(0,"medmConnectEventCb: "
	      "ca_array_get_callback [%s]:\n %s\n",
	      ca_name(pCh->chid)?ca_name(pCh->chid):"Unknown",
	      ca_message(status));
#if DEBUG_CONNECTION
# if 0
	    system("netstat | grep iocacis");
# endif
	    print("  pCh->chid %s args.chid\n",
	      pCh->chid == args.chid?"==":"!=");
	    print(
	      "  Channel Name: %s\n"
	      "  State: %s\n"
	      "  Native Type: %s\n"
	      "  Native Count: %hu\n"
	      "  Access: %s%s\n"
	      "  IOC: %s\n",
	      args.chid?ca_name(args.chid):"Unavailable",
	      args.chid?ca_state(args.chid) == cs_never_conn?"Never":
	      ca_state(args.chid) == cs_prev_conn?"Prev":
	      ca_state(args.chid) == cs_conn?"Conn":
	      ca_state(args.chid) == cs_closed?"Closed":"Unknown":"Unavailable",
	      args.chid?dbf_type_to_text(ca_field_type(args.chid)):"Unavailable",
	      args.chid?ca_element_count(args.chid):0,
	      args.chid?(ca_read_access(args.chid)?"R":"None"):"Unavailable",
	      args.chid?(ca_write_access(args.chid)?"W":""):"",
	      args.chid?ca_host_name(args.chid):"Unavailable");
#endif
	}
    }

  /* Handle four cases: connected or not and previously connected or not */
    if(args.op == CA_OP_CONN_UP) {
      /* Connected */
	if(pCh->previouslyConnected == False) {
	  /* Connected and not previously connected */
	  /* Set these first so they will be right for the updateValueCb */
	    pCh->pr->elementCount = ca_element_count(pCh->chid);
	    pCh->pr->dataType = ca_field_type(args.chid);
	    pCh->pr->connected = True;
	    caTask.channelConnected++;
	  /* Add the access-rights-change callback and the
	     significant-change (value, alarm or severity)
	     callback. Don't call the updateValueCb because
	     ca_replace_access_rights_event will call it. */
	    status = ca_replace_access_rights_event(
	      pCh->chid,medmReplaceAccessRightsEventCb);
	    if(status != ECA_NORMAL) {
		medmPostMsg(0,"medmConnectEventCb: "
		  "ca_replace_access_rights_event [%s]: %s\n",
		  ca_name(pCh->chid)?ca_name(pCh->chid):"Unknown",
		  ca_message(status));
	    }
	    if(pCh->pr->currentCount == -2) {
                count=0;
            } else {
                count=ca_element_count(pCh->chid);
            }
#ifdef __USING_TIME_STAMP__
	    status = ca_add_array_event(
	      dbf_type_to_DBR_TIME(ca_field_type(pCh->chid)),
	      count, pCh->chid,
	      medmUpdateChannelCb, pCh, 0.0,0.0,0.0, &(pCh->evid));
#else
	    status = ca_add_array_event(
	      dbf_type_to_DBR_STS(ca_field_type(pCh->chid)),
	      count, pCh->chid,
	      medmUpdateChannelCb, pCh, 0.0,0.0,0.0, &(pCh->evid));
#endif
	    if(status != ECA_NORMAL) {
	      /* Set the pointer to NULL in case CA didn't.  We don't
                 want to use it or clear it later. */
#if DEBUG_CONNECTION
		if(!pCh->evid) {
		    print("medmConnectEventCb: ca_add_array_event: \n"
		      "  status[%d] != ECA_NORMAL and pCh->evid != NULL\n",
		      status);
		}
#endif
		pCh->evid = NULL;
		medmPostMsg(0,"medmConnectEventCb: "
		  "ca_add_array_event [%s]:\n %s\n",
		  ca_name(pCh->chid)?ca_name(pCh->chid):"Unknown",
		  ca_message(status));
#if DEBUG_CONNECTION
# if 0
		system("netstat | grep iocacis");
# endif
		print("  pCh->chid %s args.chid\n",
		  pCh->chid == args.chid?"==":"!=");
		print(
		  "  Channel Name: %s\n"
		  "  State: %s\n"
		  "  Native Type: %s\n"
		  "  Native Count: %hu\n"
		  "  Access: %s%s\n"
		  "  IOC: %s\n",
		  args.chid?ca_name(args.chid):"Unavailable",
		  args.chid?ca_state(args.chid) == cs_never_conn?"Never":
		  ca_state(args.chid) == cs_prev_conn?"Prev":
		  ca_state(args.chid) == cs_conn?"Conn":
		  ca_state(args.chid) == cs_closed?"Closed":"Unknown":"Unavailable",
		  args.chid?dbf_type_to_text(ca_field_type(args.chid)):"Unavailable",
		  args.chid?ca_element_count(args.chid):0,
		  args.chid?(ca_read_access(args.chid)?"R":"None"):"Unavailable",
		  args.chid?(ca_write_access(args.chid)?"W":""):"",
		  args.chid?ca_host_name(args.chid):"Unavailable");
#endif
	    }
	  /* Set this one last so ca_replace_access_rights_event can
             use the old value */
	    pCh->previouslyConnected = True;
	} else {
	  /* Connected and previously connected */
	    pCh->pr->connected = True;
	    caTask.channelConnected++;
	    if(pCh->pr->updateValueCb)
	      pCh->pr->updateValueCb((XtPointer)pCh->pr);
	}
    } else {
      /* Not connected */
	if(pCh->previouslyConnected == False) {
	  /* Not connected and not previously connected */
	  /* Probably doesn't happen -- if CA can't connect, this
	   *   routine never gets called */
	    pCh->pr->connected = False;
	} else {
	  /* Not connected but previously connected */
	    pCh->pr->connected = False;
	    caTask.channelConnected--;
	    if(pCh->pr->updateValueCb)
	      pCh->pr->updateValueCb((XtPointer)pCh->pr);
	}
    }
}