void read_msg (DDS_DataReaderListener *l, DDS_DataReader dr) { ChatMsg_t msg; DDS_InstanceStateKind kind; int valid; DDS_ReturnCode_t ret; ARG_NOT_USED (l) memset (&msg, 0, sizeof (msg)); ret = ChatMsg_read_or_take (dr, &msg, DDS_NOT_READ_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE, 1, &valid, &kind); if (ret == DDS_RETCODE_OK) do { #ifndef DISPLAY_SELF if (!strcmp (msg.from, user_name) && !strcmp (msg.chatroom, chatroom)) break; #endif if (valid) printf ("%s: %s\r\n", msg.from, msg.message); else if (kind == DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE) printf ("%s is busy!\r\n", msg.from); else if (kind == DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE) printf ("%s has left!\r\n", msg.from); } while (0); ChatMsg_cleanup (&msg); }
void do_chat (DDS_DataWriter dw) { ChatMsg_t m; DDS_InstanceHandle_t h; char buf [256]; #if !defined (NUTTX_RTOS) tty_init (); #endif DDS_Handle_attach (tty_stdin, POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL, tty_input, NULL); printf ("Welcome to the ROS 2.0 DDS chatroom.\r\n"); printf ("Anything you type will be sent to all chatroom attendees.\r\n"); printf (" (Please write messages of less than 255 characters).\r\n"); printf ("Type '!help' for chatroom options.\r\n"); m.chatroom = chatroom; m.from = user_name; h = 0; while (!aborting) { #if defined (NUTTX_RTOS) /* Take into account that fgets reads the "\n" character at the end of each line. Code should consider this aspect in every case */ fgets(buf, 256, stdin); #else tty_gets (sizeof (buf), buf, 0, 1); #endif if (buf [0] == '!') { #if defined (NUTTX_RTOS) if (!strcmp (buf + 1, "quit\n") || (buf [1] == 'q' && buf [2] == '\n')) { #else if (!strcmp (buf + 1, "quit") || (buf [1] == 'q' && buf [2] == '\0')) { #endif aborting = 1; break; } #if defined (NUTTX_RTOS) else if (!strcmp (buf + 1, "list\n")) #else else if (!strcmp (buf + 1, "list")) #endif printf ("Attendees:\r\n\t%s\r\n", user_name); #if defined (NUTTX_RTOS) else if (!memcmp (buf + 1, "user\n", 4)) { #else else if (!memcmp (buf + 1, "user", 4)) { #endif if (h) { ChatMsg_signal (dw, h, 1); h = 0; } strcpy (user_name, buf + 6); printf ("You are now: %s\r\n", user_name); } #if defined (NUTTX_RTOS) else if (!memcmp (buf + 1, "room\n", 4)) { #else else if (!memcmp (buf + 1, "room", 4)) { #endif if (h) { ChatMsg_signal (dw, h, 1); h = 0; } strcpy (chatroom, buf + 6); printf ("Switched to chatroom: %s\r\n", chatroom); } #if defined (NUTTX_RTOS) else if (!strcmp (buf + 1, "info\n")) #else else if (!strcmp (buf + 1, "info")) #endif printf ("Chatroom: %s, Username: %s\r\n", chatroom, user_name); #if defined (NUTTX_RTOS) else if (!strcmp (buf + 1, "busy\n")) #else else if (!strcmp (buf + 1, "busy")) #endif ChatMsg_signal (dw, h, 0); #if defined (NUTTX_RTOS) else if (!strcmp (buf + 1, "away\n")) { #else else if (!strcmp (buf + 1, "away")) { #endif if (h) { ChatMsg_signal (dw, h, 1); h = 0; } } #if defined (NUTTX_RTOS) else if (!strcmp (buf + 1, "help\n") || (buf [1] == 'h' && buf [2] == '\n\0') || (buf [1] == '?' && buf [2] == '\n\0')) { #else else if (!strcmp (buf + 1, "help") || (buf [1] == 'h' && buf [2] == '\0') || (buf [1] == '?' && buf [2] == '\0')) { #endif printf ("Commands:\r\n"); printf (" !room <room_name> -> set the chatroom name.\r\n"); printf (" !user <user_name> -> set the user name.\r\n"); printf (" !list -> list the attendees.\r\n"); printf (" !info -> show chatroom and user.\r\n"); printf (" !busy -> momentarily not involved.\r\n"); printf (" !away -> gone away.\r\n"); printf (" !help or !h or !? -> Show this info.\r\n"); printf (" !quit or !q -> Quit the chatroom.\r\n"); printf (" !!<command> -> DDS debug command.\r\n"); /* printf (" !$<command> -> Shell command.\r\n"); */ } else if (buf [1] == '!') DDS_Debug_command (buf + 2); /* else if (buf [1] == '$') system (buf + 2); */ else printf ("?%s\r\n", buf + 1); continue; } if (!h) h = ChatMsg_register (dw, &m); m.message = buf; ChatMsg_write (dw, &m, h); } } void read_msg (DDS_DataReaderListener *l, DDS_DataReader dr) { ChatMsg_t msg; DDS_InstanceStateKind kind; int valid; DDS_ReturnCode_t ret; ARG_NOT_USED (l) memset (&msg, 0, sizeof (msg)); ret = ChatMsg_read_or_take (dr, &msg, DDS_NOT_READ_SAMPLE_STATE, DDS_ANY_VIEW_STATE, DDS_ANY_INSTANCE_STATE, 1, &valid, &kind); if (ret == DDS_RETCODE_OK) do { #ifndef DISPLAY_SELF if (!strcmp (msg.from, user_name) && !strcmp (msg.chatroom, chatroom)) break; #endif if (valid) printf ("%s: %s\r\n", msg.from, msg.message); else if (kind == DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE) printf ("%s is busy!\r\n", msg.from); else if (kind == DDS_NOT_ALIVE_NO_WRITERS_INSTANCE_STATE) printf ("%s has left!\r\n", msg.from); } while (0); ChatMsg_cleanup (&msg); } #ifdef WAITSETS static void *chat_reader (void *args) { DDS_DynamicDataReader dr; DDS_WaitSet ws; DDS_SampleStateMask ss = DDS_NOT_READ_SAMPLE_STATE; DDS_ViewStateMask vs = DDS_ANY_VIEW_STATE; DDS_InstanceStateMask is = DDS_ANY_INSTANCE_STATE; DDS_ReadCondition rc; DDS_ConditionSeq conds = DDS_SEQ_INITIALIZER (DDS_Condition); DDS_Duration_t to; DDS_ReturnCode_t ret; dr = args; ws = DDS_WaitSet__alloc (); if (!ws) fatal ("Unable to allocate a WaitSet!"); if (verbose) printf ("DDS Waitset allocated.\r\n"); rc = DDS_DataReader_create_readcondition (dr, ss, vs, is); if (!rc) fatal ("DDS_DataReader_create_readcondition () returned an error!"); if (verbose) printf ("DDS Readcondition created.\r\n"); ret = DDS_WaitSet_attach_condition (ws, rc); if (ret) fatal ("Unable to attach condition to a WaitSet!"); while (!aborting) { to.sec = 0; to.nanosec = 200000000; /* Timeout after 200ms. */ ret = DDS_WaitSet_wait (ws, &conds, &to); if (ret == DDS_RETCODE_TIMEOUT) continue; read_msg (NULL, dr); } ret = DDS_WaitSet_detach_condition (ws, rc); if (ret) fatal ("Unable to detach condition from WaitSet (%s)!", DDS_error (ret)); DDS_WaitSet__free (ws); return (NULL); } static void start_chat_reader (DDS_DynamicDataReader dr) { thread_create (rt, chat_reader, dr); } static void stop_chat_reader (DDS_DynamicDataReader dr) { ARG_NOT_USED (dr) thread_wait (rt, NULL); } #else static DDS_DataReaderListener msg_listener = { NULL, /* Sample rejected. */ NULL, /* Liveliness changed. */ NULL, /* Requested Deadline missed. */ NULL, /* Requested incompatible QoS. */ read_msg, /* Data available. */ NULL, /* Subscription matched. */ NULL, /* Sample lost. */ NULL /* Cookie */ }; #endif #ifdef DDS_SECURITY #define fail_unless assert static void enable_security (void) { DDS_Credentials credentials; DDS_ReturnCode_t error; #ifdef MSECPLUG_WITH_SECXML /*int dhandle, thandle;*/ #endif error = DDS_SP_set_policy (); if (error) fatal ("DDS_SP_set_policy() returned error (%s)!", DDS_error (error)); #ifdef MSECPLUG_WITH_SECXML if (DDS_SP_parse_xml ("security.xml")) fatal ("SP: no DDS security rules in 'security.xml'!\r\n"); #else DDS_SP_add_domain(); if (!realm_name) DDS_SP_add_participant (); else DDS_SP_set_participant_access (DDS_SP_add_participant (), strcat(realm_name, "*"), 2, 0); #endif if (!cert_path || !key_path) fatal ("Error: you must provide a valid certificate path and a valid private key path\r\n"); if (engine_id) { DDS_SP_init_engine (engine_id, init_engine_fs); credentials.credentialKind = DDS_ENGINE_BASED; credentials.info.engine.engine_id = engine_id; credentials.info.engine.cert_id = cert_path; credentials.info.engine.priv_key_id = key_path; } else { credentials.credentialKind = DDS_FILE_BASED; credentials.info.filenames.private_key_file = key_path; credentials.info.filenames.certificate_chain_file = cert_path; } error = DDS_Security_set_credentials ("Technicolor Chatroom", &credentials); }