00001
00002
00003 #include "cms.hh"
00004
00005 #include "ttymem.hh"
00006 #include "ttyintf.hh"
00007 #include "sokintrf.h"
00008 #include "rem_msg.hh"
00009 #include "rcs_prnt.hh"
00010
00011 #include <stdlib.h>
00012 #include <string.h>
00013
00014
00015 TTYMEM::TTYMEM (char *bufline, char *procline):
00016 CMS (bufline, procline)
00017 {
00018 serial_number = 0;
00019 returned_serial_number = 0;
00020 memset (temp_buffer, 0, 0x2000);
00021
00022 #ifdef UNIX_LIKE_PLAT
00023 char *default_dev_name = "/dev/ttyb";
00024 #else
00025 char *default_dev_name = "COM2:";
00026 #endif
00027
00028 char *devNameEq = strstr (procline, "serialPortDevName=");
00029 if (NULL != devNameEq)
00030 {
00031 strncpy (ttyDevName, clean_string (devNameEq + 18, 80), 80);
00032 }
00033 else
00034 {
00035 strncpy (ttyDevName, default_dev_name, 80);
00036 }
00037
00038 handle = open_serial_communications_port (ttyDevName);
00039 if (handle <= 0)
00040 {
00041 status = CMS_MISC_ERROR;
00042 return;
00043 }
00044 settings.baud_rate = 9600;
00045 settings.data_bits = 8;
00046 settings.stop_bits = 1;
00047 settings.use_parity = 0;
00048
00049 if (strstr (bufline, "evenparity"))
00050 {
00051 settings.use_parity = 1;
00052 settings.even_parity = 1;
00053 }
00054 if (strstr (bufline, "oddparity"))
00055 {
00056 settings.use_parity = 1;
00057 settings.even_parity = 0;
00058 }
00059
00060 char *baud_rate_eq = strstr (bufline, "baud_rate=");
00061 if (NULL != baud_rate_eq)
00062 {
00063 settings.baud_rate = atol (baud_rate_eq + 10);
00064 }
00065 char *data_bits_eq = strstr (bufline, "data_bits=");
00066 if (NULL != data_bits_eq)
00067 {
00068 settings.data_bits = atol (data_bits_eq + 10);
00069 }
00070 char *stop_bits_eq = strstr (bufline, "stop_bits=");
00071 if (NULL != stop_bits_eq)
00072 {
00073 settings.stop_bits = atol (stop_bits_eq + 10);
00074 }
00075 if (set_serial_port_configuration (handle, &settings) < 0)
00076 {
00077 status = CMS_MISC_ERROR;
00078 return;
00079 }
00080 verify_bufname ();
00081 }
00082
00083
00084 TTYMEM::~TTYMEM ()
00085 {
00086 close_serial_communications_port (handle);
00087 }
00088
00089
00090 void
00091 TTYMEM::verify_bufname ()
00092 {
00093 *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
00094 *((u_long *) temp_buffer + 1) =
00095 dl_htonl ((u_long) REMOTE_CMS_GET_BUF_NAME_REQUEST_TYPE);
00096 *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
00097 if (write_serial_communications_port (handle, temp_buffer, 20) < 0)
00098 {
00099 status = CMS_MISC_ERROR;
00100 return;
00101 }
00102 serial_number++;
00103 if (readn_serial_communications_port (handle, temp_buffer, 40) < 40)
00104 {
00105 status = CMS_MISC_ERROR;
00106 return;
00107 }
00108 returned_serial_number = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
00109 if (returned_serial_number != serial_number)
00110 {
00111 rcs_print_error
00112 ("TTYMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
00113 returned_serial_number, serial_number);
00114 status = CMS_MISC_ERROR;
00115 return;
00116 }
00117 status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
00118 if (status < 0)
00119 {
00120 return;
00121 }
00122 if (strncmp (temp_buffer + 8, BufferName, 31))
00123 {
00124 rcs_print_error
00125 ("TTYMEM: The buffer (%s) is registered with buffer number %d.\n",
00126 ((char *) temp_buffer + 8), buffer_number);
00127 rcs_print_error
00128 ("TTYMEM: However, this process (%s) is attempting to connect to the buffer %s at the same location.\n",
00129 ProcessName, BufferName);
00130 status = CMS_RESOURCE_CONFLICT_ERROR;
00131 return;
00132 }
00133 }
00134
00135
00136 void
00137 TTYMEM::reconnect ()
00138 {
00139 }
00140
00141 void
00142 TTYMEM::disconnect ()
00143 {
00144 }
00145
00146 CMS_STATUS
00147 TTYMEM::read ()
00148 {
00149
00150
00151 if (!read_permission_flag)
00152 {
00153 rcs_print_error ("CMS: %s was not configured to read %s\n",
00154 ProcessName, BufferName);
00155 return (status = CMS_PERMISSIONS_ERROR);
00156 }
00157
00158
00159 *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
00160 *((u_long *) temp_buffer + 1) =
00161 dl_htonl ((u_long) REMOTE_CMS_READ_REQUEST_TYPE);
00162 *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
00163 *((u_long *) temp_buffer + 3) = dl_htonl ((u_long) CMS_READ_ACCESS);
00164 *((u_long *) temp_buffer + 4) = dl_htonl ((u_long) in_buffer_id);
00165
00166 int send_header_size = 20;
00167 if (total_subdivisions > 1)
00168 {
00169 *((u_long *) temp_buffer + 5) = dl_htonl ((u_long) current_subdivision);
00170 send_header_size = 24;
00171 }
00172 if (write_serial_communications_port (handle, temp_buffer, send_header_size)
00173 < 0)
00174 {
00175 rcs_print_error ("TTYMEM: Can't send READ request to server.\n");
00176 return (status = CMS_MISC_ERROR);
00177 }
00178 serial_number++;
00179 if (readn_serial_communications_port (handle, temp_buffer, 20) < 0)
00180 {
00181 return (status = CMS_MISC_ERROR);
00182 }
00183 returned_serial_number = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
00184 if (returned_serial_number != serial_number)
00185 {
00186 rcs_print_error
00187 ("TTYMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
00188 returned_serial_number, serial_number);
00189 return (status = CMS_MISC_ERROR);
00190 }
00191 status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
00192 message_size = dl_ntohl (*((u_long *) temp_buffer + 2));
00193 id = dl_ntohl (*((u_long *) temp_buffer + 3));
00194 header.was_read = dl_ntohl (*((u_long *) temp_buffer + 4));
00195 if (message_size > max_encoded_message_size)
00196 {
00197 rcs_print_error ("Recieved message is too big. (%ld > %ld)\n",
00198 message_size, max_encoded_message_size);
00199 return (status = CMS_MISC_ERROR);
00200 }
00201 if (message_size > 0)
00202 {
00203 if (readn_serial_communications_port
00204 (handle, (char *) encoded_data, message_size) < 0)
00205 {
00206 return (status = CMS_MISC_ERROR);
00207 }
00208 }
00209 check_id (id);
00210 return (status);
00211 }
00212
00213
00214
00215
00216 CMS_STATUS
00217 TTYMEM::peek ()
00218 {
00219
00220 if (!read_permission_flag)
00221 {
00222 rcs_print_error ("CMS: %s was not configured to read %s\n",
00223 ProcessName, BufferName);
00224 return (status = CMS_PERMISSIONS_ERROR);
00225 }
00226
00227
00228 *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
00229 *((u_long *) temp_buffer + 1) =
00230 dl_htonl ((u_long) REMOTE_CMS_READ_REQUEST_TYPE);
00231 *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
00232 *((u_long *) temp_buffer + 3) = dl_htonl ((u_long) CMS_PEEK_ACCESS);
00233 *((u_long *) temp_buffer + 4) = dl_htonl ((u_long) in_buffer_id);
00234
00235 int send_header_size = 20;
00236 if (total_subdivisions > 1)
00237 {
00238 *((u_long *) temp_buffer + 5) = dl_htonl ((u_long) current_subdivision);
00239 send_header_size = 24;
00240 }
00241 if (write_serial_communications_port (handle, temp_buffer, send_header_size)
00242 < 0)
00243 {
00244 rcs_print_error ("TTYMEM: Can't send READ request to server.\n");
00245 return (status = CMS_MISC_ERROR);
00246 }
00247 serial_number++;
00248 if (readn_serial_communications_port (handle, temp_buffer, 20) < 0)
00249 {
00250 return (status = CMS_MISC_ERROR);
00251 }
00252 returned_serial_number = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
00253 if (returned_serial_number != serial_number)
00254 {
00255 rcs_print_error
00256 ("TTYMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
00257 returned_serial_number, serial_number);
00258 return (status = CMS_MISC_ERROR);
00259 }
00260 status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
00261 message_size = dl_ntohl (*((u_long *) temp_buffer + 2));
00262 id = dl_ntohl (*((u_long *) temp_buffer + 3));
00263 header.was_read = dl_ntohl (*((u_long *) temp_buffer + 4));
00264 if (message_size > max_encoded_message_size)
00265 {
00266 rcs_print_error ("Recieved message is too big. (%ld > %ld)\n",
00267 message_size, max_encoded_message_size);
00268 return (status = CMS_MISC_ERROR);
00269 }
00270 if (message_size > 0)
00271 {
00272 if (readn_serial_communications_port
00273 (handle, (char *) encoded_data, message_size) < 0)
00274 {
00275 return (status = CMS_MISC_ERROR);
00276 }
00277 }
00278 check_id (id);
00279 return (status);
00280 }
00281
00282
00283 CMS_STATUS
00284 TTYMEM::blocking_read (double _blocking_timeout)
00285 {
00286 rcs_print_error (" Can not call blocking_read(%f) when using TTYMEM.\n",
00287 _blocking_timeout);
00288 return (status = CMS_NO_BLOCKING_SEM_ERROR);
00289 }
00290
00291
00292 CMS_STATUS
00293 TTYMEM::write (void *user_data)
00294 {
00295
00296 if (!force_raw)
00297 {
00298 user_data = encoded_data;
00299 }
00300
00301 if (!write_permission_flag)
00302
00303 {
00304 rcs_print_error ("CMS: %s was not configured to write to %s\n",
00305 ProcessName, BufferName);
00306 return (status = CMS_PERMISSIONS_ERROR);
00307 }
00308
00309 *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
00310 *((u_long *) temp_buffer + 1) =
00311 dl_htonl ((u_long) REMOTE_CMS_WRITE_REQUEST_TYPE);
00312 *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
00313 *((u_long *) temp_buffer + 3) = dl_htonl ((u_long) CMS_WRITE_ACCESS);
00314 *((u_long *) temp_buffer + 4) = dl_htonl ((u_long) header.in_buffer_size);
00315 int send_header_size = 20;
00316 if (total_subdivisions > 1)
00317 {
00318 *((u_long *) temp_buffer + 5) = dl_htonl ((u_long) current_subdivision);
00319 send_header_size = 24;
00320 }
00321 if (header.in_buffer_size < 0x2000 - 20 && header.in_buffer_size > 0)
00322 {
00323 memcpy (temp_buffer + send_header_size, user_data,
00324 header.in_buffer_size);
00325 if (write_serial_communications_port
00326 (handle, temp_buffer, header.in_buffer_size + send_header_size) < 0)
00327 {
00328 rcs_print_error
00329 ("TTYMEM: Failed to send message of size %d + header of size %d to the server.\n",
00330 header.in_buffer_size, send_header_size);
00331 return (status = CMS_MISC_ERROR);
00332 }
00333 }
00334 else
00335 {
00336 if (write_serial_communications_port
00337 (handle, temp_buffer, send_header_size) < 0)
00338 {
00339 rcs_print_error ("TTYMEM: Failed to send header to server.\n");
00340 return (status = CMS_MISC_ERROR);
00341 }
00342 if (header.in_buffer_size > 0)
00343 {
00344 if (write_serial_communications_port
00345 (handle, (char *) user_data, header.in_buffer_size) < 0)
00346 {
00347 return (status = CMS_MISC_ERROR);
00348 }
00349 }
00350 }
00351 serial_number++;
00352 if ((min_compatible_version < 2.58 && min_compatible_version > 1e-6)
00353 || confirm_write)
00354 {
00355 if (readn_serial_communications_port (handle, temp_buffer, 12) < 0)
00356 {
00357 return (status = CMS_MISC_ERROR);
00358 }
00359 returned_serial_number =
00360 (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
00361 if (returned_serial_number != serial_number)
00362 {
00363 rcs_print_error
00364 ("TTYMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
00365 returned_serial_number, serial_number);
00366 return (status = CMS_MISC_ERROR);
00367 }
00368 status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
00369 header.was_read = dl_ntohl (*((u_long *) temp_buffer + 2));
00370 }
00371 else
00372 {
00373 header.was_read = 0;
00374 status = CMS_WRITE_OK;
00375 returned_serial_number = serial_number;
00376 }
00377 return (status);
00378 }
00379
00380
00381
00382 CMS_STATUS
00383 TTYMEM::write_if_read (void *user_data)
00384 {
00385
00386 if (!force_raw)
00387 {
00388 user_data = encoded_data;
00389 }
00390
00391 if (!write_permission_flag)
00392
00393 {
00394 rcs_print_error ("CMS: %s was not configured to write to %s\n",
00395 ProcessName, BufferName);
00396 return (status = CMS_PERMISSIONS_ERROR);
00397 }
00398
00399 *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
00400 *((u_long *) temp_buffer + 1) =
00401 dl_htonl ((u_long) REMOTE_CMS_WRITE_REQUEST_TYPE);
00402 *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
00403 *((u_long *) temp_buffer + 3) = dl_htonl ((u_long) CMS_WRITE_ACCESS);
00404 *((u_long *) temp_buffer + 4) = dl_htonl ((u_long) header.in_buffer_size);
00405 int send_header_size = 20;
00406 if (total_subdivisions > 1)
00407 {
00408 *((u_long *) temp_buffer + 5) = dl_htonl ((u_long) current_subdivision);
00409 send_header_size = 24;
00410 }
00411 if (header.in_buffer_size < 0x2000 - 20 && header.in_buffer_size > 0)
00412 {
00413 memcpy (temp_buffer + send_header_size, user_data,
00414 header.in_buffer_size);
00415 if (write_serial_communications_port
00416 (handle, temp_buffer, header.in_buffer_size + send_header_size) < 0)
00417 {
00418 rcs_print_error
00419 ("TTYMEM: Failed to send message of size %d + header of size %d to the server.\n",
00420 header.in_buffer_size, send_header_size);
00421 return (status = CMS_MISC_ERROR);
00422 }
00423 }
00424 else
00425 {
00426 if (write_serial_communications_port
00427 (handle, temp_buffer, send_header_size) < 0)
00428 {
00429 rcs_print_error ("TTYMEM: Failed to send header to server.\n");
00430 return (status = CMS_MISC_ERROR);
00431 }
00432 if (header.in_buffer_size > 0)
00433 {
00434 if (write_serial_communications_port
00435 (handle, (char *) user_data, header.in_buffer_size) < 0)
00436 {
00437 return (status = CMS_MISC_ERROR);
00438 }
00439 }
00440 }
00441 serial_number++;
00442 if ((min_compatible_version < 2.58 && min_compatible_version > 1e-6)
00443 || confirm_write)
00444 {
00445 if (readn_serial_communications_port (handle, temp_buffer, 12) < 0)
00446 {
00447 return (status = CMS_MISC_ERROR);
00448 }
00449 returned_serial_number =
00450 (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
00451 if (returned_serial_number != serial_number)
00452 {
00453 rcs_print_error
00454 ("TTYMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
00455 returned_serial_number, serial_number);
00456 return (status = CMS_MISC_ERROR);
00457 }
00458 status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
00459 header.was_read = dl_ntohl (*((u_long *) temp_buffer + 2));
00460 }
00461 else
00462 {
00463 header.was_read = 0;
00464 status = CMS_WRITE_OK;
00465 returned_serial_number = serial_number;
00466 }
00467 return (status);
00468 }
00469
00470
00471 int
00472 TTYMEM::check_if_read ()
00473 {
00474
00475 *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
00476 *((u_long *) temp_buffer + 1) =
00477 dl_htonl ((u_long) REMOTE_CMS_CHECK_IF_READ_REQUEST_TYPE);
00478 *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
00479 int send_header_size = 20;
00480 if (total_subdivisions > 1)
00481 {
00482 *((u_long *) temp_buffer + 3) = dl_htonl ((u_long) current_subdivision);
00483 }
00484 if (write_serial_communications_port (handle, temp_buffer, send_header_size)
00485 < 0)
00486 {
00487 status = CMS_MISC_ERROR;
00488 return (0);
00489 }
00490 serial_number++;
00491 if (readn_serial_communications_port (handle, temp_buffer, 12) < 0)
00492 {
00493 status = CMS_MISC_ERROR;
00494 return 0;
00495 }
00496 returned_serial_number = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
00497 if (returned_serial_number != serial_number)
00498 {
00499 rcs_print_error
00500 ("TTYMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
00501 returned_serial_number, serial_number);
00502 return (status = CMS_MISC_ERROR);
00503 }
00504 status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
00505 header.was_read = dl_ntohl (*((u_long *) temp_buffer + 2));
00506 return (header.was_read);
00507 }
00508
00509
00510 CMS_STATUS
00511 TTYMEM::clear ()
00512 {
00513 *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
00514 *((u_long *) temp_buffer + 1) =
00515 dl_htonl ((u_long) REMOTE_CMS_CLEAR_REQUEST_TYPE);
00516 *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
00517 *((u_long *) temp_buffer + 3) = dl_htonl ((u_long) current_subdivision);
00518
00519 if (write_serial_communications_port (handle, temp_buffer, 20) < 0)
00520 {
00521 return (status = CMS_MISC_ERROR);
00522 }
00523 serial_number++;
00524 if (readn_serial_communications_port (handle, temp_buffer, 8) < 0)
00525 {
00526 return (status = CMS_MISC_ERROR);
00527 }
00528 returned_serial_number = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
00529 if (returned_serial_number != serial_number)
00530 {
00531 rcs_print_error
00532 ("TTYMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
00533 returned_serial_number, serial_number);
00534 return (status = CMS_MISC_ERROR);
00535 }
00536 status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
00537 header.was_read = dl_ntohl (*((u_long *) temp_buffer + 2));
00538 return (status);
00539 }