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