ARPDAS_QNX6 1.0
|
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 */