Changes in uspace/srv/hid/remcons/remcons.c [5d94b16c:3123d2a] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/remcons/remcons.c
r5d94b16c r3123d2a 34 34 35 35 #include <async.h> 36 #include <stdio.h> 37 #include <adt/prodcons.h> 38 #include <ipc/input.h> 39 #include <ipc/console.h> 40 #include <ipc/vfs.h> 36 41 #include <errno.h> 37 #include <io/con_srv.h>38 #include <stdio.h>39 #include <stdlib.h>40 42 #include <str_error.h> 41 43 #include <loc.h> … … 43 45 #include <io/keycode.h> 44 46 #include <align.h> 47 #include <malloc.h> 48 #include <as.h> 45 49 #include <fibril_synch.h> 46 50 #include <task.h> … … 71 75 sizeof(telnet_force_character_mode_command) / sizeof(telnet_cmd_t); 72 76 73 static int remcons_open(con_srvs_t *, con_srv_t *); 74 static int remcons_close(con_srv_t *); 75 static int remcons_write(con_srv_t *, void *, size_t); 76 static void remcons_sync(con_srv_t *); 77 static void remcons_clear(con_srv_t *); 78 static void remcons_set_pos(con_srv_t *, sysarg_t col, sysarg_t row); 79 static int remcons_get_pos(con_srv_t *, sysarg_t *, sysarg_t *); 80 static int remcons_get_size(con_srv_t *, sysarg_t *, sysarg_t *); 81 static int remcons_get_color_cap(con_srv_t *, console_caps_t *); 82 static int remcons_get_event(con_srv_t *, kbd_event_t *); 83 84 static con_ops_t con_ops = { 85 .open = remcons_open, 86 .close = remcons_close, 87 .read = NULL, 88 .write = remcons_write, 89 .sync = remcons_sync, 90 .clear = remcons_clear, 91 .set_pos = remcons_set_pos, 92 .get_pos = remcons_get_pos, 93 .get_size = remcons_get_size, 94 .get_color_cap = remcons_get_color_cap, 95 .set_style = NULL, 96 .set_color = NULL, 97 .set_rgb_color = NULL, 98 .set_cursor_visibility = NULL, 99 .get_event = remcons_get_event 100 }; 101 102 static telnet_user_t *srv_to_user(con_srv_t *srv) 103 { 104 return srv->srvs->sarg; 105 } 106 107 static int remcons_open(con_srvs_t *srvs, con_srv_t *srv) 108 { 109 telnet_user_t *user = srv_to_user(srv); 110 111 telnet_user_log(user, "New client connected (%p).", srv); 112 113 /* Force character mode. */ 114 send(user->socket, (void *)telnet_force_character_mode_command, 115 telnet_force_character_mode_command_count, 0); 116 117 return EOK; 118 } 119 120 static int remcons_close(con_srv_t *srv) 121 { 122 telnet_user_t *user = srv_to_user(srv); 123 124 telnet_user_notify_client_disconnected(user); 125 telnet_user_log(user, "Client disconnected (%p).", srv); 126 127 return EOK; 128 } 129 130 static int remcons_write(con_srv_t *srv, void *data, size_t size) 131 { 132 telnet_user_t *user = srv_to_user(srv); 133 int rc; 134 135 rc = telnet_user_send_data(user, data, size); 136 if (rc != EOK) 137 return rc; 138 139 return size; 140 } 141 142 static void remcons_sync(con_srv_t *srv) 143 { 144 (void) srv; 145 } 146 147 static void remcons_clear(con_srv_t *srv) 148 { 149 (void) srv; 150 } 151 152 static void remcons_set_pos(con_srv_t *srv, sysarg_t col, sysarg_t row) 153 { 154 telnet_user_t *user = srv_to_user(srv); 155 156 telnet_user_update_cursor_x(user, col); 157 } 158 159 static int remcons_get_pos(con_srv_t *srv, sysarg_t *col, sysarg_t *row) 160 { 161 telnet_user_t *user = srv_to_user(srv); 162 163 *col = user->cursor_x; 164 *row = 0; 165 166 return EOK; 167 } 168 169 static int remcons_get_size(con_srv_t *srv, sysarg_t *cols, sysarg_t *rows) 170 { 171 (void) srv; 172 173 *cols = 100; 174 *rows = 1; 175 176 return EOK; 177 } 178 179 static int remcons_get_color_cap(con_srv_t *srv, console_caps_t *ccaps) 180 { 181 (void) srv; 182 *ccaps = CONSOLE_CAP_NONE; 183 184 return EOK; 185 } 186 187 static int remcons_get_event(con_srv_t *srv, kbd_event_t *event) 188 { 189 telnet_user_t *user = srv_to_user(srv); 190 int rc; 191 192 rc = telnet_user_get_next_keyboard_event(user, event); 193 if (rc != EOK) { 194 /* XXX What? */ 195 memset(event, 0, sizeof(*event)); 196 return EOK; 197 } 198 199 return EOK; 77 78 /** Handling client requests (VFS and console interface). 79 * 80 * @param user Telnet user the requests belong to. 81 */ 82 static void client_connection_message_loop(telnet_user_t *user) 83 { 84 while (true) { 85 ipc_call_t call; 86 ipc_callid_t callid = 0; 87 88 /* 89 * The getterm task might terminate while we are here, 90 * waiting for a call. Also, the socket might be closed 91 * meanwhile. 92 * We want to detect this situation early, so we use a 93 * timeout variant of async_get_call(). 94 */ 95 while (callid == 0) { 96 callid = async_get_call_timeout(&call, 1000); 97 98 if (telnet_user_is_zombie(user)) { 99 if (callid != 0) { 100 async_answer_0(callid, EINTR); 101 } 102 return; 103 } 104 } 105 106 if (!IPC_GET_IMETHOD(call)) { 107 return; 108 } 109 110 switch (IPC_GET_IMETHOD(call)) { 111 case CONSOLE_GET_SIZE: 112 async_answer_2(callid, EOK, 100, 1); 113 break; 114 case CONSOLE_GET_POS: 115 fibril_mutex_lock(&user->guard); 116 async_answer_2(callid, EOK, user->cursor_x, 0); 117 fibril_mutex_unlock(&user->guard); 118 break; 119 case CONSOLE_GET_EVENT: { 120 kbd_event_t event; 121 int rc = telnet_user_get_next_keyboard_event(user, &event); 122 if (rc != EOK) { 123 /* Silently ignore. */ 124 async_answer_0(callid, EOK); 125 break; 126 } 127 async_answer_4(callid, EOK, event.type, event.key, event.mods, event.c); 128 break; 129 } 130 case CONSOLE_GOTO: { 131 int new_x = IPC_GET_ARG1(call); 132 telnet_user_update_cursor_x(user, new_x); 133 async_answer_0(callid, ENOTSUP); 134 break; 135 } 136 case VFS_OUT_READ: 137 async_answer_0(callid, ENOTSUP); 138 break; 139 case VFS_OUT_WRITE: { 140 uint8_t *buf; 141 size_t size; 142 int rc = async_data_write_accept((void **)&buf, false, 0, 0, 0, &size); 143 144 if (rc != EOK) { 145 async_answer_0(callid, rc); 146 break; 147 } 148 149 rc = telnet_user_send_data(user, buf, size); 150 free(buf); 151 152 if (rc != EOK) { 153 async_answer_0(callid, rc); 154 break; 155 } 156 157 async_answer_1(callid, EOK, size); 158 break; 159 } 160 case VFS_OUT_SYNC: 161 async_answer_0(callid, EOK); 162 break; 163 case CONSOLE_CLEAR: 164 async_answer_0(callid, EOK); 165 break; 166 167 case CONSOLE_GET_COLOR_CAP: 168 async_answer_1(callid, EOK, CONSOLE_CAP_NONE); 169 break; 170 case CONSOLE_SET_STYLE: 171 async_answer_0(callid, ENOTSUP); 172 break; 173 case CONSOLE_SET_COLOR: 174 async_answer_0(callid, ENOTSUP); 175 break; 176 case CONSOLE_SET_RGB_COLOR: 177 async_answer_0(callid, ENOTSUP); 178 break; 179 180 case CONSOLE_CURSOR_VISIBILITY: 181 async_answer_0(callid, ENOTSUP); 182 break; 183 184 default: 185 async_answer_0(callid, EINVAL); 186 break; 187 } 188 } 200 189 } 201 190 … … 209 198 return; 210 199 } 200 async_answer_0(iid, EOK); 201 202 telnet_user_log(user, "New client connected (%" PRIxn").", iid); 203 204 /* Force character mode. */ 205 send(user->socket, (void *)telnet_force_character_mode_command, 206 telnet_force_character_mode_command_count, 0); 211 207 212 208 /* Handle messages. */ 213 con_conn(iid, icall, &user->srvs); 209 client_connection_message_loop(user); 210 211 telnet_user_notify_client_disconnected(user); 212 telnet_user_log(user, "Client disconnected (%" PRIxn").", iid); 214 213 } 215 214 … … 233 232 fibril_mutex_lock(&user->guard); 234 233 user->task_finished = true; 235 user->srvs.aborted = true;236 234 fibril_condvar_signal(&user->refcount_cv); 237 235 fibril_mutex_unlock(&user->guard); … … 253 251 fibril_mutex_lock(&user->guard); 254 252 user->task_finished = true; 255 user->srvs.aborted = true;256 253 fibril_condvar_signal(&user->refcount_cv); 257 254 fibril_mutex_unlock(&user->guard); … … 298 295 closesocket(user->socket); 299 296 user->socket_closed = true; 300 user->srvs.aborted = true;301 297 continue; 302 298 } else if (user->socket_closed) { … … 367 363 368 364 printf("%s: HelenOS Remote console service\n", NAME); 369 task_retval(0);370 365 371 366 while (true) { … … 384 379 assert(user); 385 380 386 con_srvs_init(&user->srvs);387 user->srvs.ops = &con_ops;388 user->srvs.sarg = user;389 user->srvs.abort_timeout = 1000;390 391 telnet_user_add(user);392 393 381 fid_t fid = fibril_create(network_user_fibril, user); 394 382 assert(fid);
Note:
See TracChangeset
for help on using the changeset viewer.