These code examples are provided in source form as part of the Cascade DataHub API. They are provided here so that you can see what is involved in communicating with the Cascade DataHub using your own C programs. The Gamma programming language also contains many 'hooks' into the Cascade DataHub. For more information about using Gamma with the Cascade DataHub see the Cascade DataHub demo program that is available for download from the Cogent web site. The Cascade DataHub demo uses Gamma to show the features of the datahub. If you download and run the Gamma demo for the Cascade DataHub you will have to reinstall your commercial version of the Cascade DataHub, because the version that comes with the Gamma demo contains a time limited license. The API can be downloaded at no charge from the Cogent Web Site
/*
* Cascade DataHub point reader: readpt
*
* (C) Copyright Cogent Real-Time Systems Inc., 1997 All rights reserved.
*
* This program reads a point from the Cascade DataHub and displays the
* result on the standard output.
*
* This program is supplied with the Cascade DataHub programming API. It
* may be copied or modified, in whole or in part, for the sole purpose of
* creating applications to be used with the Cascade DataHub.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <cogent/cogdb.h>
/*
* A point is one of three types. We discover which one we have and
* print the appropriate name, value, confidence factor, lock status
* and security level.
*/
void print_point (PT_pCPOINT ppoint)
{
char *t;
printf ("Point: %s\n", ppoint->name);
switch (ppoint->type)
{
case PT_TYPE_INT32:
printf ("Value: %d\n", ppoint->value.i);
break;
case PT_TYPE_REAL:
printf ("Value: %g\n", ppoint->value.r);
break;
case PT_TYPE_STRING:
printf ("Value: %s\n", ppoint->value.s);
break;
default:
printf ("Value: Unknown\n");
break;
}
t = ctime ((time_t*)&ppoint->seconds);
t[19] = '\0';
printf ("Time: %s.%03d\n", &t[4], ppoint->nanoseconds / 1000000);
printf ("Conf: %d\n", ppoint->conf);
printf ("Lock: %d\n", ppoint->locked);
printf ("Secur: %d\n", ppoint->security);
}
#ifdef __USAGE
Copyright (C) Cogent Real-Time Systems Inc., 1996-1997
%C [-d domain] pointname
Read a point from the Cascade DataHub in the given domain. If no domain is
specified, then the default domain is used. #endif
void Usage (char** argv)
{
print_usage (argv);
exit (1);
}
int main (int argc, char** argv)
{
IP_hMSG hmsg;
ST_STATUS status;
PT_stCPOINT point;
char *ptname = NULL, *domain = NULL;
int i;
IP_hTASK htask;
/*
* Parse the input arguments. The only interesting argument is an
* alternate datahub domain name. We really do not need this, as
* we could specify the point name as domain:name
*/
for (i=1; i<argc; i++)
{
if (argv[i][0] == '-')
{
switch (argv[i][1])
{
case 'd':
domain = argv[++i];
if (strlen(domain) > 15)
domain[15] = '\0';
break;
default:
Usage (argv);
break;
}
}
else
{
ptname = argv[i];
}
}
if (!ptname)
{
printf ("Need a point name\n");
exit (1);
}
/*
* Initialize communication with the Cascade NameServer. We do
* not want other tasks to be notified of the start and stop of this
* task, so we make it NS_INVISIBLE. The name server will know about
* this task, it just will not tell anybody. Also, since we do not
* want to be receiving queue messages, do not name the queue.
*/
if (!(htask = NS_Init (argv[0], NULL, domain, NS_INVISIBLE)))
{
fprintf (stderr, "Could not initialize Cascade DataHub IPC subsystem\n");
exit (1);
}
/*
* Create a pre-allocated message structure for use with all
* IPC calls. This includes the DH_* functions. The API could have
* created its own internal message structure, but this would have
* left us with no way to control its size or be efficient about
* allocation. This way we do a little more work, but have more
* control of what is being allocated.
*/
hmsg = IP_CreateMsg (0, 0, NULL, IP_MAX_MESSAGE, NULL);
/*
* Zero the point structure. If we do not do this, the address
* field could be non-zero, and then the API will take that to be a
* cached datahub address. That might cause a crash.
*/
memset (&point, 0, sizeof(point));
/*
* Provide a point name buffer separately from the rest of the point
* structure. There is no way for the API to know what the allocation
* status of a point name is, so it will never attempt to free this
* buffer, nor write into it.
*/
point.name = ptname;
if ((status = DH_ReadPoint (htask, &point, hmsg, NULL)) != ST_OK)
printf ("Read point failed: %d\n", ST_StatusName (status));
else
print_point (&point);
return (0);
}