ICP  1
ISISDS.cpp
Go to the documentation of this file.
1 #include "stdafx.h"
2 #include "isisds_command.h"
3 #include "ISISDS.h"
4 
5 //#define NO_CDAE
6 //#include "..\isisicp\dae.h"
7 //#include "..\isisicp\isisicp_i.c"
8 
9 #include "..\newicp\isiscrpt.h"
10 #include "..\newicp\isisraw.h"
11 
12 ISISDS* m_ds = NULL;
13 
14 ISISDS::ISISDS() : ThreadedClass(), ISIS::Base()
15 {
16  setLoggerName("ISISDS");
17 }
18 
20 {
21 // call stop and delete on m_requests
22 }
23 
24 // where the running m_thread ends up
26 {
27  HRESULT hr;
28  // allow things elsewhere to start
29  Sleep(2000);
30  int setkeepalive = 1;
31  // wait for ICP global section
32  if (m_crpt.mapCRPT("isis_current", "isis_data", true, true) == DAEstatus::Failure)
33  {
34  return;
35  }
36  WSADATA WsaDat;
37  if (WSAStartup(MAKEWORD(2, 2), &WsaDat) != 0)
38  {
39  return;
40  }
41  SOCKET s = socket(PF_INET, SOCK_STREAM, 0);
42  if (s == INVALID_SOCKET)
43  {
44  perror("socket");
45  return;
46  }
47  hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
48  if (FAILED(hr))
49  {
50  return;
51  }
52  try
53  {
54  hr = m_dae.CoCreateInstance(isisicpLib::CLSID_dae, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER|CLSCTX_LOCAL_SERVER);
55  }
56  catch(...)
57  {
58  return;
59  }
60  if (FAILED(hr))
61  {
62  return;
63  }
64  struct sockaddr_in sin, sad_from;
65  memset(&sin, 0, sizeof(sin));
66  struct in_addr the_addr;
67  the_addr.S_un.S_addr = INADDR_ANY;
68  sin.sin_family = PF_INET;
69  sin.sin_addr = the_addr;
70  sin.sin_port = htons(ISISDS_PORT);
71  if (bind(s, (struct sockaddr*)&sin, sizeof(sin)) == -1)
72  {
73  perror("bind");
74  closesocket(s);
75  return;
76  }
77  if (listen(s, 5) == -1)
78  {
79  perror("listen");
80  closesocket(s);
81  return;
82  }
83  // may need to disable SIGPIPE - might get this on external connection close
84  int n, len_sadfrom;
85  const char* address;
86  fd_set readfds;
87  SOCKET sd;
88  std::list<ISISDSRequest*>::iterator iter;
89  while(1)
90  {
91  for(iter=m_requests.begin(); iter != m_requests.end(); iter++)
92  {
93  if ( !((*iter)->isRunning()) )
94  {
95 // std::cerr << "Terminating from " << (*iter)->address() << std::endl;
96  delete (*iter);
97  m_requests.erase(iter);
98  break; // loop seems to die unless we exit after erase()
99  }
100  }
101  FD_ZERO(&readfds);
102  FD_SET(s, &readfds);
103  struct timeval select_timeout = { 5, 0 };
104  n = select(FD_SETSIZE, &readfds, NULL, NULL, &select_timeout);
105  if (n < 0)
106  {
107  perror("select");
108  return; // select failed, socket invalid?
109  }
110  else if (n == 0) // select timeout
111  {
112  try
113  {
114  hr = m_dae->areYouThere();
115  }
116  catch(...)
117  {
118  return;
119  }
120  if (FAILED(hr))
121  {
122  return;
123  }
124  continue;
125  }
126  if (FD_ISSET(s, &readfds))
127  {
128  len_sadfrom = sizeof(sad_from);
129  sd = accept(s, (struct sockaddr*)&sad_from, &len_sadfrom);
130  if (sd == INVALID_SOCKET)
131  {
132  Poco::Thread::sleep(2000);
133  continue;
134  }
135  setsockopt(sd, SOL_SOCKET, SO_KEEPALIVE, (char*)&setkeepalive, sizeof(setkeepalive));
136  address = inet_ntoa(sad_from.sin_addr);
137  LOGSTR_DEBUG("Connection from " << address);
138  ISISDSRequest* req = new ISISDSRequest(sd, address, m_crpt);
139  m_requests.push_back(req);
140  req->start();
141  }
142  }
143 }
144 
146 {
147  int dims_array_out[10], ndims_out;
148  HRESULT hr;
149  ISISDSDataType type_out = ISISDSUnknown;
150  hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
151  if (FAILED(hr))
152  {
153  return;
154  }
155  char *command_in, *comm_data_in, *comm_data_out;
156  bool free_out;
157  int comm_data_len_out, istat;
158  ISISDSAccessMode access_type;
159  if (isisds_recv_open(m_socket, &access_type) <= 0)
160  {
161  return;
162  }
163  try
164  {
165  hr = m_dae.CoCreateInstance(isisicpLib::CLSID_dae, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER|CLSCTX_LOCAL_SERVER);
166  }
167  catch(...)
168  {
169  return;
170  }
171  if (FAILED(hr))
172  {
173  return;
174  }
175  int ndims_in, data_dims_in[10];
176  ISISDSDataType data_type_in;
177  while(true)
178  {
179  if (isisds_recv_command_alloc(m_socket, &command_in, (void**)&comm_data_in, &data_type_in, data_dims_in, &ndims_in) <= 0)
180  {
181  break;
182  }
183  if (processCommand(access_type, command_in, comm_data_in, 0,
184  comm_data_out, type_out, dims_array_out, ndims_out, free_out))
185  {
186  istat = isisds_send_command(m_socket, "OK", comm_data_out, type_out, dims_array_out, ndims_out);
187  }
188  else
189  {
190  istat = isisds_send_command(m_socket, "ERROR", comm_data_out, type_out, dims_array_out, ndims_out);
191  }
192  free(command_in);
193  if (comm_data_in != NULL)
194  {
195  free(comm_data_in);
196  }
197  if (free_out)
198  {
199  free(comm_data_out);
200  }
201  if (istat <= 0)
202  {
203  break;
204  }
205  }
206  return;
207 }
208 
209 // return true on OK
210 // access_type = 0 for dae, 1 for crpt
211 // need to use malloc/free for comm_data_out
212 bool ISISDSRequest::processCommand(ISISDSAccessMode access_type, const char* command_in, const char* comm_data_in, int comm_data_len_in,
213  char*& comm_data_out, ISISDSDataType& type_out, int* dims_array_out, int& ndims_out, bool& free_out)
214 {
215  DAEstatus status;
216  std::string cvalue;
217  long lvalue;
218  double dvalue, *darray;
219  float *farray;
220  long *larray;
221  HRESULT hr;
222 // VARIANT result;
223 // BSTR item_name, messages;
224 // hr = m_dae->getValue(item_name, &messages, &result);
225  free_out = false;
226  comm_data_out = NULL;
227  int i, total_size;
228  ndims_out = 1;
229  dims_array_out[0] = 0;
230  type_out = ISISDSUnknown;
231  if ( !strcmp(command_in, "GETPARC08") &&
232  (m_crpt->getCharItem(comm_data_in, cvalue, status) == DAEstatus::Success) )
233  {
234  comm_data_out = strdup(cvalue.c_str());
235  dims_array_out[0] = strlen(comm_data_out);
236  free_out = true;
237  type_out = ISISDSChar;
238  LOGSTR_DEBUG("Processing command \"" << command_in << "\" for item \"" << comm_data_in << "\" returning \"" << comm_data_out << "\"");
239  return true;
240  }
241  else if ( !strcmp(command_in, "GETPARI32") &&
242  (m_crpt->getIntItem(comm_data_in, lvalue, status) == DAEstatus::Success) )
243  {
244  dims_array_out[0] = 1;
245  comm_data_out = (char*)malloc(sizeof(int));
246  *((int*)comm_data_out) = lvalue;
247  free_out = true;
248  type_out = ISISDSInt32;
249  LOGSTR_DEBUG("Processing command \"" << command_in << "\" for item \"" << comm_data_in << "\" returning " << lvalue);
250  return true;
251  }
252  else if (!strcmp(command_in, "GETPARR32") &&
253  (m_crpt->getRealItem(comm_data_in, dvalue, status) == DAEstatus::Success) )
254  {
255  dims_array_out[0] = 1;
256  comm_data_out = (char*)malloc(sizeof(float));
257  *((float*)comm_data_out) = dvalue;
258  free_out = true;
259  type_out = ISISDSReal32;
260  LOGSTR_DEBUG("Processing command \"" << command_in << "\" for item \"" << comm_data_in << "\" returning " << dvalue);
261  return true;
262  }
263  else if (!strcmp(command_in, "GETPARR64") &&
264  (m_crpt->getRealItem(comm_data_in, dvalue, status) == DAEstatus::Success) )
265  {
266  dims_array_out[0] = 1;
267  comm_data_out = (char*)malloc(sizeof(double));
268  *((double*)comm_data_out) = dvalue;
269  free_out = true;
270  type_out = ISISDSReal64;
271  LOGSTR_DEBUG("Processing command \"" << command_in << "\" for item \"" << comm_data_in << "\" returning " << dvalue);
272  return true;
273  }
274  else if (!strcmp(command_in, "GETPARR64") &&
275  (m_crpt->getRealArrayItemSize(comm_data_in, dims_array_out, ndims_out, status) == DAEstatus::Success) )
276  {
277  total_size = 1;
278  for(i=0; i<ndims_out; i++)
279  {
280  total_size *= dims_array_out[i];
281  }
282  darray = (double*)malloc(total_size * sizeof(double));
283  m_crpt.getRealArrayItem(comm_data_in, darray, status);
284  comm_data_out = (char*)darray;
285  free_out = true;
286  type_out = ISISDSReal64;
287  LOGSTR_DEBUG("Processing command \"" << command_in << "\" for item \"" << comm_data_in << "\" returning array length " << total_size);
288  return true;
289  }
290  else if (!strcmp(command_in, "GETPARR32") &&
291  (m_crpt->getRealArrayItemSize(comm_data_in, dims_array_out, ndims_out, status) == DAEstatus::Success) )
292  {
293  total_size = 1;
294  for(i=0; i<ndims_out; i++)
295  {
296  total_size *= dims_array_out[i];
297  }
298  farray = (float*)malloc(total_size * sizeof(float));
299  m_crpt.getRealArrayItem(comm_data_in, farray, status);
300  comm_data_out = (char*)farray;
301  free_out = true;
302  type_out = ISISDSReal32;
303  LOGSTR_DEBUG("Processing command \"" << command_in << "\" for item \"" << comm_data_in << "\" returning array length " << total_size);
304  return true;
305  }
306  else if ( !strcmp(command_in, "GETPARI32") &&
307  (m_crpt->getIntArrayItemSize(comm_data_in, dims_array_out, ndims_out, status) == DAEstatus::Success) )
308  {
309  total_size = 1;
310  for(i=0; i<ndims_out; i++)
311  {
312  total_size *= dims_array_out[i];
313  }
314  larray = (long*)malloc(total_size * sizeof(long));
315  m_crpt.getIntArrayItem(comm_data_in, larray, status);
316  comm_data_out = (char*)larray;
317  free_out = true;
318  type_out = ISISDSInt32;
319  LOGSTR_DEBUG("Processing command \"" << command_in << "\" for item \"" << comm_data_in << "\" returning array length " << total_size);
320  return true;
321  }
322  else if ( !strcmp(command_in, "GETDAT") )
323  {
324  int dims_temp[5], ndims_temp;
325  int ifsn = ((int*)comm_data_in)[0];
326  int nos = ((int*)comm_data_in)[1];
327  long* spec_array = new long[nos];
328  for(i=0; i<nos; i++)
329  {
330  spec_array[i] = ifsn + i;
331  }
332  BSTR messages = NULL;
333  try
334  {
335  hr = m_dae->updateCRPTSpectra(0, ifsn, nos, &messages); // update dae for current period, but (ifsn > nsp1) will do second and subsequent periods
336  }
337  catch( ... )
338  {
339  LOGSTR_ERROR("updateCRPTSpectra failed");
340  status.addInfo(FAC_DAE, "updateCRPTSpectra failed");
341  }
342  if ( FAILED(hr) )
343  {
344  LOGSTR_ERROR("updateCRPTSpectra failed");
345  status.addInfo(FAC_DAE, "updateCRPTSpectra failed");
346  }
347  m_crpt->getIntArrayItemSize("SPECTRUMT0", spec_array, nos, dims_temp, ndims_temp, status);
348  total_size = dims_temp[0] * nos;
349 // ndims_out = 2;
350 // dims_array_out[0] = nos;
351 // dims_array_out[1] = dims_temp[0]; // spectrum size
352  ndims_out = 1;
353  dims_array_out[0] = total_size;
354  larray = (long*)malloc(total_size * sizeof(long));
355  m_crpt.getIntArrayItem("SPECTRUMT0", spec_array, nos, larray, status);
356  comm_data_out = (char*)larray;
357  delete[] spec_array;
358  free_out = true;
359  type_out = ISISDSInt32;
360  LOGSTR_DEBUG("Processing command \"" << command_in << "\" ifsn " << ifsn << " nos " << nos << " returning array length " << total_size);
361  return true;
362  }
363  LOGSTR_ERROR("Invalid command " << command_in);
364  return false;
365 }
#define ISISDS_PORT
Definition: isisds_command.h:6
virtual void run()
Definition: ISISDS.cpp:145
#define FAC_DAE
virtual ~ISISDS()
Definition: ISISDS.cpp:19
int getRealArrayItem(const char *item_name, const long *spec_array, int nspec, double *darray, DAEstatus &status) const
Definition: CRPTProxy.h:382
ISISDSDataType
CComPtr< isisicpLib::Idae > m_dae
Definition: ISISDS.h:69
static const int Failure
Definition: DAEstatus.h:141
int getCharItem(const char *item_name, std::string &cvalue, DAEstatus &status) const
Definition: isiscrpt.cpp:228
int getIntArrayItem(const char *item_name, const long *spec_array, int nspec, long *larray, DAEstatus &status) const
Definition: CRPTProxy.h:374
static const int Success
Definition: DAEstatus.h:140
#define LOGSTR_DEBUG(__arg)
Definition: IsisBase.h:71
CComPtr< isisicpLib::Idae > m_dae
Definition: ISISDS.h:51
int isisds_send_command(SOCKET s, const char *command, const void *data, ISISDSDataType type, const int dims_array[], int ndims)
Definition: ISISDS.h:64
std::list< ISISDSRequest * > m_requests
Definition: ISISDS.h:67
int getRealItem(const char *item_name, double &dblVal, DAEstatus &status) const
Definition: isiscrpt.cpp:391
#define LOGSTR_ERROR(__arg)
Definition: IsisBase.h:99
virtual void run()
Definition: ISISDS.cpp:25
CRPTProxy m_crpt
Definition: ISISDS.h:68
#define INVALID_SOCKET
int getRealArrayItemSize(const char *item_name, int *dims_array, int &ndims, DAEstatus &status) const
Definition: isiscrpt.cpp:519
#define SOCKET
int mapCRPT(const std::string &crpt_name, const std::string &crpt_data_name, bool read_only, bool existing)
Definition: CRPTProxy.cpp:289
CRPTProxy & m_crpt
Definition: ISISDS.h:50
ISISDSAccessMode
ISISDS * m_ds
Definition: ISISDS.cpp:12
int isisds_recv_open(SOCKET s, ISISDSAccessMode *access_type)
void start()
Definition: ISISDS.h:17
#define closesocket
void setLoggerName(const std::string &logger_name)
Definition: IsisBase.h:17
bool processCommand(ISISDSAccessMode access_type, const char *command_in, const char *comm_data_in, int comm_data_len_in, char *&comm_data_out, ISISDSDataType &type_out, int *dims_array_out, int &ndims_out, bool &free_out)
Definition: ISISDS.cpp:212
int addInfo(int facility, const std::string &text)
Definition: DAEstatus.cpp:86
int getIntItem(const char *item_name, long &lVal, DAEstatus &status) const
Definition: isiscrpt.cpp:233
int getIntArrayItemSize(const char *item_name, int *dims_array, int &ndims, DAEstatus &status) const
Definition: isiscrpt.cpp:432
SOCKET m_socket
Definition: ISISDS.h:52
ISISDS()
Definition: ISISDS.cpp:14
int isisds_recv_command_alloc(SOCKET s, char **command, void **data, ISISDSDataType *type, int dims_array[], int *ndims)