Changes in uspace/srv/net/nil/nildummy/nildummy.c [514ee46:46d4d9f] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/nil/nildummy/nildummy.c
r514ee46 r46d4d9f 41 41 #include <stdio.h> 42 42 #include <str.h> 43 #include <err.h>44 43 #include <ipc/ipc.h> 45 44 #include <ipc/net.h> … … 58 57 #include "nildummy.h" 59 58 60 /** The module name. 61 * 62 */ 59 /** The module name. */ 63 60 #define NAME "nildummy" 64 61 65 /** Default maximum transmission unit. 66 * 67 */ 62 /** Default maximum transmission unit. */ 68 63 #define NET_DEFAULT_MTU 1500 69 64 70 /** Network interface layer module global data. 71 * 72 */ 65 /** Network interface layer module global data. */ 73 66 nildummy_globals_t nildummy_globals; 74 67 … … 78 71 { 79 72 fibril_rwlock_read_lock(&nildummy_globals.protos_lock); 80 81 73 if (nildummy_globals.proto.phone) 82 il_device_state_msg(nildummy_globals.proto.phone, device_id, state, 83 nildummy_globals.proto.service); 84 74 il_device_state_msg(nildummy_globals.proto.phone, device_id, 75 state, nildummy_globals.proto.service); 85 76 fibril_rwlock_read_unlock(&nildummy_globals.protos_lock); 86 77 … … 90 81 int nil_initialize(int net_phone) 91 82 { 92 ERROR_DECLARE;83 int rc; 93 84 94 85 fibril_rwlock_initialize(&nildummy_globals.devices_lock); … … 99 90 nildummy_globals.net_phone = net_phone; 100 91 nildummy_globals.proto.phone = 0; 101 ERROR_PROPAGATE(nildummy_devices_initialize(&nildummy_globals.devices));92 rc = nildummy_devices_initialize(&nildummy_globals.devices); 102 93 103 94 fibril_rwlock_write_unlock(&nildummy_globals.protos_lock); 104 95 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 105 96 106 return EOK; 107 } 108 109 /** Process IPC messages from the registered device driver modules in an infinite loop. 110 * 111 * @param[in] iid The message identifier. 112 * @param[in,out] icall The message parameters. 113 * 114 */ 115 static void nildummy_receiver(ipc_callid_t iid, ipc_call_t * icall){ 116 ERROR_DECLARE; 117 118 packet_t packet; 119 120 while(true){ 121 switch(IPC_GET_METHOD(*icall)){ 122 case NET_NIL_DEVICE_STATE: 123 ERROR_CODE = nil_device_state_msg_local(0, IPC_GET_DEVICE(icall), IPC_GET_STATE(icall)); 124 ipc_answer_0(iid, (ipcarg_t) ERROR_CODE); 125 break; 126 case NET_NIL_RECEIVED: 127 if(! ERROR_OCCURRED(packet_translate_remote(nildummy_globals.net_phone, &packet, IPC_GET_PACKET(icall)))){ 128 ERROR_CODE = nil_received_msg_local(0, IPC_GET_DEVICE(icall), packet, 0); 129 } 130 ipc_answer_0(iid, (ipcarg_t) ERROR_CODE); 131 break; 132 default: 133 ipc_answer_0(iid, (ipcarg_t) ENOTSUP); 97 return rc; 98 } 99 100 /** Process IPC messages from the registered device driver modules in an 101 * infinite loop. 102 * 103 * @param[in] iid The message identifier. 104 * @param[in,out] icall The message parameters. 105 */ 106 static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall) 107 { 108 packet_t *packet; 109 int rc; 110 111 while (true) { 112 switch (IPC_GET_METHOD(*icall)) { 113 case NET_NIL_DEVICE_STATE: 114 rc = nil_device_state_msg_local(0, 115 IPC_GET_DEVICE(icall), IPC_GET_STATE(icall)); 116 ipc_answer_0(iid, (ipcarg_t) rc); 117 break; 118 119 case NET_NIL_RECEIVED: 120 rc = packet_translate_remote(nildummy_globals.net_phone, 121 &packet, IPC_GET_PACKET(icall)); 122 if (rc == EOK) { 123 rc = nil_received_msg_local(0, 124 IPC_GET_DEVICE(icall), packet, 0); 125 } 126 ipc_answer_0(iid, (ipcarg_t) rc); 127 break; 128 129 default: 130 ipc_answer_0(iid, (ipcarg_t) ENOTSUP); 134 131 } 132 135 133 iid = async_get_call(icall); 136 134 } … … 141 139 * Determine the device local hardware address. 142 140 * 143 * @param[in] device_id 144 * @param[in] service 145 * @param[in] mtu 146 * 147 * @return s EOK on success.148 * @return s EEXIST if the device with the different service exists.149 * @return s ENOMEM if there is not enough memory left.150 * @returns Other error codes as defined for thenetif_bind_service() function.151 * @return s Other error codes as defined for the netif_get_addr_req() function.152 * 141 * @param[in] device_id The new device identifier. 142 * @param[in] service The device driver service. 143 * @param[in] mtu The device maximum transmission unit. 144 * @return EOK on success. 145 * @return EEXIST if the device with the different service exists. 146 * @return ENOMEM if there is not enough memory left. 147 * @return Other error codes as defined for the 148 * netif_bind_service() function. 149 * @return Other error codes as defined for the 150 * netif_get_addr_req() function. 153 151 */ 154 152 static int nildummy_device_message(device_id_t device_id, services_t service, 155 153 size_t mtu) 156 154 { 157 ERROR_DECLARE; 158 159 nildummy_device_ref device; 155 nildummy_device_t *device; 160 156 int index; 157 int rc; 161 158 162 159 fibril_rwlock_write_lock(&nildummy_globals.devices_lock); 163 // an existing device? 160 161 /* An existing device? */ 164 162 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 165 if (device){166 if (device->service != service){163 if (device) { 164 if (device->service != service) { 167 165 printf("Device %d already exists\n", device->device_id); 168 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 166 fibril_rwlock_write_unlock( 167 &nildummy_globals.devices_lock); 169 168 return EEXIST; 170 }else{171 // update mtu172 if(mtu > 0){173 device->mtu = mtu;174 }else{175 device->mtu = NET_DEFAULT_MTU;176 }177 printf("Device %d already exists:\tMTU\t= %d\n", device->device_id, device->mtu);178 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);179 // notify the upper layer module180 fibril_rwlock_read_lock(&nildummy_globals.protos_lock);181 if(nildummy_globals.proto.phone){182 il_mtu_changed_msg(nildummy_globals.proto.phone, device->device_id, device->mtu, nildummy_globals.proto.service);183 }184 fibril_rwlock_read_unlock(&nildummy_globals.protos_lock);185 return EOK;186 169 } 187 }else{ 188 // create a new device 189 device = (nildummy_device_ref) malloc(sizeof(nildummy_device_t)); 190 if(! device){ 191 return ENOMEM; 170 171 /* Update MTU */ 172 if (mtu > 0) 173 device->mtu = mtu; 174 else 175 device->mtu = NET_DEFAULT_MTU; 176 177 printf("Device %d already exists:\tMTU\t= %d\n", 178 device->device_id, device->mtu); 179 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 180 181 /* Notify the upper layer module */ 182 fibril_rwlock_read_lock(&nildummy_globals.protos_lock); 183 if (nildummy_globals.proto.phone) { 184 il_mtu_changed_msg(nildummy_globals.proto.phone, 185 device->device_id, device->mtu, 186 nildummy_globals.proto.service); 192 187 } 193 device->device_id = device_id; 194 device->service = service; 195 if(mtu > 0){ 196 device->mtu = mtu; 197 }else{ 198 device->mtu = NET_DEFAULT_MTU; 199 } 200 // bind the device driver 201 device->phone = netif_bind_service(device->service, device->device_id, SERVICE_ETHERNET, nildummy_receiver); 202 if(device->phone < 0){ 203 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 204 free(device); 205 return device->phone; 206 } 207 // get hardware address 208 if(ERROR_OCCURRED(netif_get_addr_req(device->phone, device->device_id, &device->addr, &device->addr_data))){ 209 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 210 free(device); 211 return ERROR_CODE; 212 } 213 // add to the cache 214 index = nildummy_devices_add(&nildummy_globals.devices, device->device_id, device); 215 if(index < 0){ 216 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 217 free(device->addr); 218 free(device->addr_data); 219 free(device); 220 return index; 221 } 222 printf("%s: Device registered (id: %d, service: %d, mtu: %d)\n", 223 NAME, device->device_id, device->service, device->mtu); 224 } 188 fibril_rwlock_read_unlock(&nildummy_globals.protos_lock); 189 190 return EOK; 191 } 192 193 /* Create a new device */ 194 device = (nildummy_device_t *) malloc(sizeof(nildummy_device_t)); 195 if (!device) 196 return ENOMEM; 197 198 device->device_id = device_id; 199 device->service = service; 200 if (mtu > 0) 201 device->mtu = mtu; 202 else 203 device->mtu = NET_DEFAULT_MTU; 204 205 /* Bind the device driver */ 206 device->phone = netif_bind_service(device->service, device->device_id, 207 SERVICE_ETHERNET, nildummy_receiver); 208 if (device->phone < 0) { 209 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 210 free(device); 211 return device->phone; 212 } 213 214 /* Get hardware address */ 215 rc = netif_get_addr_req(device->phone, device->device_id, &device->addr, 216 &device->addr_data); 217 if (rc != EOK) { 218 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 219 free(device); 220 return rc; 221 } 222 223 /* Add to the cache */ 224 index = nildummy_devices_add(&nildummy_globals.devices, 225 device->device_id, device); 226 if (index < 0) { 227 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 228 free(device->addr); 229 free(device->addr_data); 230 free(device); 231 return index; 232 } 233 234 printf("%s: Device registered (id: %d, service: %d, mtu: %d)\n", 235 NAME, device->device_id, device->service, device->mtu); 225 236 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 226 237 return EOK; … … 229 240 /** Return the device hardware address. 230 241 * 231 * @param[in] device_id The device identifier. 232 * @param[out] address The device hardware address. 233 * 234 * @return EOK on success. 235 * @return EBADMEM if the address parameter is NULL. 236 * @return ENOENT if there no such device. 242 * @param[in] device_id The device identifier. 243 * @param[out] address The device hardware address. 244 * @return EOK on success. 245 * @return EBADMEM if the address parameter is NULL. 246 * @return ENOENT if there no such device. 237 247 * 238 248 */ 239 249 static int nildummy_addr_message(device_id_t device_id, 240 measured_string_ ref*address)241 { 242 nildummy_device_ refdevice;243 244 if (! address){250 measured_string_t **address) 251 { 252 nildummy_device_t *device; 253 254 if (!address) 245 255 return EBADMEM; 246 }256 247 257 fibril_rwlock_read_lock(&nildummy_globals.devices_lock); 248 258 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 249 if (! device){259 if (!device) { 250 260 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 251 261 return ENOENT; … … 253 263 *address = device->addr; 254 264 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 265 255 266 return (*address) ? EOK : ENOENT; 256 267 } … … 258 269 /** Return the device packet dimensions for sending. 259 270 * 260 * @param[in] device_id The device identifier. 261 * @param[out] addr_len The minimum reserved address length. 262 * @param[out] prefix The minimum reserved prefix size. 263 * @param[out] content The maximum content size. 264 * @param[out] suffix The minimum reserved suffix size. 265 * 266 * @return EOK on success. 267 * @return EBADMEM if either one of the parameters is NULL. 268 * @return ENOENT if there is no such device. 269 * 270 */ 271 static int nildummy_packet_space_message(device_id_t device_id, 272 size_t *addr_len, size_t *prefix, size_t *content, size_t *suffix) 273 { 274 nildummy_device_ref device; 275 276 if(!(addr_len && prefix && content && suffix)){ 271 * @param[in] device_id The device identifier. 272 * @param[out] addr_len The minimum reserved address length. 273 * @param[out] prefix The minimum reserved prefix size. 274 * @param[out] content The maximum content size. 275 * @param[out] suffix The minimum reserved suffix size. 276 * @return EOK on success. 277 * @return EBADMEM if either one of the parameters is NULL. 278 * @return ENOENT if there is no such device. 279 * 280 */ 281 static int nildummy_packet_space_message(device_id_t device_id, size_t *addr_len, 282 size_t *prefix, size_t *content, size_t *suffix) 283 { 284 nildummy_device_t *device; 285 286 if (!addr_len || !prefix || !content || !suffix) 277 287 return EBADMEM; 278 }288 279 289 fibril_rwlock_read_lock(&nildummy_globals.devices_lock); 280 290 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 281 if (! device){291 if (!device) { 282 292 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 283 293 return ENOENT; 284 294 } 295 285 296 *content = device->mtu; 286 297 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 298 287 299 *addr_len = 0; 288 300 *prefix = 0; … … 291 303 } 292 304 293 int nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet, services_t target){ 294 packet_t next; 305 int nil_received_msg_local(int nil_phone, device_id_t device_id, 306 packet_t *packet, services_t target) 307 { 308 packet_t *next; 295 309 296 310 fibril_rwlock_read_lock(&nildummy_globals.protos_lock); 297 if (nildummy_globals.proto.phone){298 do {311 if (nildummy_globals.proto.phone) { 312 do { 299 313 next = pq_detach(packet); 300 il_received_msg(nildummy_globals.proto.phone, device_id, packet, nildummy_globals.proto.service); 314 il_received_msg(nildummy_globals.proto.phone, device_id, 315 packet, nildummy_globals.proto.service); 301 316 packet = next; 302 } while(packet);317 } while(packet); 303 318 } 304 319 fibril_rwlock_read_unlock(&nildummy_globals.protos_lock); 320 305 321 return EOK; 306 322 } … … 310 326 * Pass received packets for this service. 311 327 * 312 * @param[in] service The module service. 313 * @param[in] phone The service phone. 314 * 315 * @return EOK on success. 316 * @return ENOENT if the service is not known. 317 * @return ENOMEM if there is not enough memory left. 318 * 328 * @param[in] service The module service. 329 * @param[in] phone The service phone. 330 * @return EOK on success. 331 * @return ENOENT if the service is not known. 332 * @return ENOMEM if there is not enough memory left. 319 333 */ 320 334 static int nildummy_register_message(services_t service, int phone) … … 333 347 /** Send the packet queue. 334 348 * 335 * @param[in] device_id The device identifier. 336 * @param[in] packet The packet queue. 337 * @param[in] sender The sending module service. 338 * 339 * @return EOK on success. 340 * @return ENOENT if there no such device. 341 * @return EINVAL if the service parameter is not known. 342 * 343 */ 344 static int nildummy_send_message(device_id_t device_id, packet_t packet, 349 * @param[in] device_id The device identifier. 350 * @param[in] packet The packet queue. 351 * @param[in] sender The sending module service. 352 * @return EOK on success. 353 * @return ENOENT if there no such device. 354 * @return EINVAL if the service parameter is not known. 355 */ 356 static int nildummy_send_message(device_id_t device_id, packet_t *packet, 345 357 services_t sender) 346 358 { 347 nildummy_device_ refdevice;359 nildummy_device_t *device; 348 360 349 361 fibril_rwlock_read_lock(&nildummy_globals.devices_lock); 350 362 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 351 if (! device){363 if (!device) { 352 364 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 353 365 return ENOENT; 354 366 } 355 // send packet queue 356 if(packet){ 357 netif_send_msg(device->phone, device_id, packet, SERVICE_NILDUMMY); 358 } 367 368 /* Send packet queue */ 369 if (packet) 370 netif_send_msg(device->phone, device_id, packet, 371 SERVICE_NILDUMMY); 359 372 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 360 373 return EOK; 361 374 } 362 375 363 int nil_message_standalone(const char *name, ipc_callid_t callid, ipc_call_t *call, 364 ipc_call_t *answer, int *answer_count) 365 { 366 ERROR_DECLARE; 367 368 measured_string_ref address; 369 packet_t packet; 376 int nil_message_standalone(const char *name, ipc_callid_t callid, 377 ipc_call_t *call, ipc_call_t *answer, int *answer_count) 378 { 379 measured_string_t *address; 380 packet_t *packet; 370 381 size_t addrlen; 371 382 size_t prefix; 372 383 size_t suffix; 373 384 size_t content; 385 int rc; 374 386 375 387 *answer_count = 0; 376 388 switch (IPC_GET_METHOD(*call)) { 377 case IPC_M_PHONE_HUNGUP: 378 return EOK; 379 case NET_NIL_DEVICE: 380 return nildummy_device_message(IPC_GET_DEVICE(call), 381 IPC_GET_SERVICE(call), IPC_GET_MTU(call)); 382 case NET_NIL_SEND: 383 ERROR_PROPAGATE(packet_translate_remote(nildummy_globals.net_phone, 384 &packet, IPC_GET_PACKET(call))); 385 return nildummy_send_message(IPC_GET_DEVICE(call), packet, 386 IPC_GET_SERVICE(call)); 387 case NET_NIL_PACKET_SPACE: 388 ERROR_PROPAGATE(nildummy_packet_space_message(IPC_GET_DEVICE(call), 389 &addrlen, &prefix, &content, &suffix)); 390 IPC_SET_ADDR(answer, addrlen); 391 IPC_SET_PREFIX(answer, prefix); 392 IPC_SET_CONTENT(answer, content); 393 IPC_SET_SUFFIX(answer, suffix); 394 *answer_count = 4; 395 return EOK; 396 case NET_NIL_ADDR: 397 ERROR_PROPAGATE(nildummy_addr_message(IPC_GET_DEVICE(call), 398 &address)); 399 return measured_strings_reply(address, 1); 400 case NET_NIL_BROADCAST_ADDR: 401 ERROR_PROPAGATE(nildummy_addr_message(IPC_GET_DEVICE(call), 402 &address)); 403 return measured_strings_reply(address, 1); 404 case IPC_M_CONNECT_TO_ME: 405 return nildummy_register_message(NIL_GET_PROTO(call), 406 IPC_GET_PHONE(call)); 389 case IPC_M_PHONE_HUNGUP: 390 return EOK; 391 392 case NET_NIL_DEVICE: 393 return nildummy_device_message(IPC_GET_DEVICE(call), 394 IPC_GET_SERVICE(call), IPC_GET_MTU(call)); 395 396 case NET_NIL_SEND: 397 rc = packet_translate_remote(nildummy_globals.net_phone, 398 &packet, IPC_GET_PACKET(call)); 399 if (rc != EOK) 400 return rc; 401 return nildummy_send_message(IPC_GET_DEVICE(call), packet, 402 IPC_GET_SERVICE(call)); 403 404 case NET_NIL_PACKET_SPACE: 405 rc = nildummy_packet_space_message(IPC_GET_DEVICE(call), 406 &addrlen, &prefix, &content, &suffix); 407 if (rc != EOK) 408 return rc; 409 IPC_SET_ADDR(answer, addrlen); 410 IPC_SET_PREFIX(answer, prefix); 411 IPC_SET_CONTENT(answer, content); 412 IPC_SET_SUFFIX(answer, suffix); 413 *answer_count = 4; 414 return EOK; 415 416 case NET_NIL_ADDR: 417 rc = nildummy_addr_message(IPC_GET_DEVICE(call), &address); 418 if (rc != EOK) 419 return rc; 420 return measured_strings_reply(address, 1); 421 422 case NET_NIL_BROADCAST_ADDR: 423 rc = nildummy_addr_message(IPC_GET_DEVICE(call), &address); 424 if (rc != EOK) 425 return rc; 426 return measured_strings_reply(address, 1); 427 428 case IPC_M_CONNECT_TO_ME: 429 return nildummy_register_message(NIL_GET_PROTO(call), 430 IPC_GET_PHONE(call)); 407 431 } 408 432 … … 412 436 /** Default thread for new connections. 413 437 * 414 * @param[in] iid The initial message identifier. 415 * @param[in] icall The initial message call structure. 416 * 438 * @param[in] iid The initial message identifier. 439 * @param[in] icall The initial message call structure. 417 440 */ 418 441 static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall) … … 424 447 ipc_answer_0(iid, EOK); 425 448 426 while (true) {449 while (true) { 427 450 ipc_call_t answer; 428 451 int answer_count; … … 436 459 437 460 /* Process the message */ 438 int res = nil_module_message_standalone(NAME, callid, &call, &answer, 439 &answer_count); 440 441 /* End if said to either by the message or the processing result */ 442 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP)) 461 int res = nil_module_message_standalone(NAME, callid, &call, 462 &answer, &answer_count); 463 464 /* 465 * End if told to either by the message or the processing 466 * result. 467 */ 468 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || 469 (res == EHANGUP)) 443 470 return; 444 471 … … 450 477 int main(int argc, char *argv[]) 451 478 { 452 ERROR_DECLARE;479 int rc; 453 480 454 481 /* Start the module */ 455 if (ERROR_OCCURRED(nil_module_start_standalone(nil_client_connection))) 456 return ERROR_CODE; 457 458 return EOK; 482 rc = nil_module_start_standalone(nil_client_connection); 483 return rc; 459 484 } 460 485
Note:
See TracChangeset
for help on using the changeset viewer.