ARPDAS_QNX6 1.0
colsend.c
Go to the documentation of this file.
00001 /* colsend.c contains Col_send_init() and Col_send(), since one is
00002    useless without the other. Col_send_reset() will probably go in
00003    here also because I'm a little lazy, though it should be used
00004    together with the other two, it is kinda optional also.
00005    
00006    See also collect.h for a description of the message-level protocol.
00007    
00008    My strategy with these functions is to be verbose with the init,
00009    but to be quiet with the other functions. i.e. once a connection
00010    is established, these functions will not fail in a big way.
00011    If the DG were to go away, the Sendmx() would fail and I would
00012    return an error code, but I won't be dying due to nl_response
00013    for that kind of failure.
00014 */
00015 #include <unistd.h>
00016 #include <limits.h>
00017 #include <string.h>
00018 #include <errno.h>
00019 #include <sys/iomsg.h>
00020 #include <pthread.h>
00021 #include "collect.h"
00022 #include "nortlib.h"
00023 #include "nl_assert.h"
00024 #include "tm.h"
00025 char rcsid_colsend_c[] =
00026   "$Header: /cvsroot/arp-das/QNX6/tmlib/src/colsend.c,v 1.7 2009/11/17 22:29:33 ntallen Exp $";
00027 
00028 /* Establishes connection with collection */
00029 send_id Col_send_init(const char *name, void *data, unsigned short size, int blocking) {
00030   char data_path[PATH_MAX], *dev_path;
00031   send_id sender = NULL;
00032   int fd;
00033   
00034   nl_assert( name != 0 && data != 0 );
00035   snprintf( data_path, PATH_MAX-1, "DG/data/%s", name );
00036   dev_path = tm_dev_name( data_path );
00037   fd = open(dev_path, O_WRONLY | (blocking ? 0 : O_NONBLOCK) );
00038   if ( fd < 0 ) {
00039     if (nl_response)
00040       nl_error(nl_response,
00041         "Col_send_init(%s) failed on open: %s", dev_path, strerror(errno));
00042     return NULL;
00043   }
00044   sender = (send_id)nl_new_memory(sizeof(send_id_struct));
00045   sender->fd = fd;
00046   sender->data = data;
00047   sender->data_size = size;
00048   sender->err_code = 0;
00049   sender->armed = blocking ? 0 : 1;
00050   return sender;
00051 }
00052 
00053 int Col_send_arm( send_id sender, int coid, short code, int value ) {
00054   int policy;
00055   struct sched_param param;
00056   nl_assert(sender != 0);
00057   if (sender->armed == 0) {
00058     nl_error(nl_response, "Col_send_arm() requires non-blocking option");
00059     return 1;
00060   }
00061   sender->event.sigev_notify = SIGEV_PULSE;
00062   sender->event.sigev_coid = coid;
00063   sender->event.sigev_code = code;
00064   sender->event.sigev_value.sival_int = value;
00065   sender->event.sigev_priority = SIGEV_PULSE_PRIO_INHERIT;
00066   sender->armed = 2;
00067   return Col_send(sender);
00068 }
00069 
00070 /* return 0 on success, non-zero otherwise
00071    Failure of the send is quiet, but causes an error return.
00072  */
00073 int Col_send(send_id sender) {
00074   if ( sender == 0 ) return 1;
00075   if ( sender->fd >= 0 ) {
00076     int nb = write(sender->fd, sender->data, sender->data_size);
00077     if ( nb == -1 ) {
00078       nl_error(-2,"Col_send() write returned errno %d", errno);
00079       sender->err_code = errno;
00080       return 1;
00081     } else if ( nb == 0 ) {
00082       return 1;
00083     }
00084     if (sender->armed == 2) {
00085       int rv = ionotify(sender->fd, _NOTIFY_ACTION_POLLARM,
00086           _NOTIFY_COND_OUTPUT, &(sender->event));
00087       if (rv == -1) {
00088         nl_error(MSG_DEBUG, "Col_send() ionotify returned errno %d", errno);
00089         sender->err_code = errno;
00090         return 1;
00091       }
00092       if (rv & _NOTIFY_COND_OUTPUT) {
00093         nl_error(MSG_DEBUG, "Col_send() auto-pulsing");
00094         if ( MsgSendPulse(sender->event.sigev_coid, sender->event.sigev_priority,
00095               sender->event.sigev_code,
00096               sender->event.sigev_value.sival_int) == -1)
00097           nl_error(4, "Error %d calling MsgSendPulse() in Col_send()", errno);
00098       } else nl_error(MSG_DEBUG, "Col_send() armed");
00099     }
00100   }
00101   sender->err_code = 0;
00102   return 0;
00103 }
00104 
00105 /* returns zero on success, non-zero otherwise. Quiet */
00106 int Col_send_reset(send_id sender) {
00107   if (sender != 0) {
00108     if ( close(sender->fd) == -1 ) return 1;
00109     nl_free_memory(sender);
00110   }
00111   return 0;
00112 }
00113 
00114 /*
00115 =Name Col_send_init(): Initialize communication with collection
00116 =Subject Data Collection
00117 =Subject Startup
00118 =Name Col_send(): Send data to collection
00119 =Subject Data Collection
00120 =Name Col_send_reset(): Terminate communication with collection
00121 =Subject Data Collection
00122 
00123 =Synopsis
00124 
00125 #include "collect.h"
00126 send_id Col_send_init(const char *name, void *data, unsigned short size);
00127 int Col_send(send_id sender);
00128 int Col_send_reset(send_id sender);
00129 
00130 =Description
00131 
00132   These functions define the standard approach for sending data
00133   to collection. This is necessary whenever an auxilliary program
00134   is generating data which needs to be fed into the telemetry
00135   frame.<P>
00136   
00137   Col_send_init() initializes the connection, creating a data
00138   structure to hold all the details. The name string must match the
00139   name specified in the corresponding 'TM "Receive"' statement in
00140   the collection program. Data points to where the data will be
00141   stored, and size specifies the size of the data.<P>
00142   
00143   Whenever the data is updated, Col_send() should be called to
00144   forward the data to collection.<P>
00145   
00146   On termination, Col_send_reset() may be called to provide an
00147   orderly shutdown.
00148 
00149 =Returns
00150 
00151   Col_send_init() returns a pointer to a structure which holds
00152   the state of the connection. This pointer must be passed to
00153   Col_send() or Col_send_reset(). On error, Col_send_init() will
00154   return NULL unless =nl_response= indicates a fatal response.<P>
00155   
00156   Col_send() returns 0 on success, non-zero otherwise.
00157   Failure of the send is quiet, but causes an error return.<P>
00158   
00159   Col_send_reset() returns 0 on success, non-zero otherwise. It
00160   does not issue any diagnostic messages, since failure is
00161   expected to be fairly common (Collection may quit before we get
00162   around to our termination.)
00163 
00164 =SeeAlso
00165 
00166   =Data Collection= functions.
00167 
00168 =End
00169 */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines