Changeset 89c57b6 in mainline for uspace/srv/net/nil/nildummy/nildummy.c
- Timestamp:
- 2011-04-13T14:45:41Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 88634420
- Parents:
- cefb126 (diff), 17279ead (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/nil/nildummy/nildummy.c
rcefb126 r89c57b6 41 41 #include <stdio.h> 42 42 #include <str.h> 43 #include <ipc/ipc.h> 43 #include <ipc/nil.h> 44 #include <ipc/net.h> 44 45 #include <ipc/services.h> 45 46 46 #include <net_err.h> 47 #include <net_messages.h> 48 #include <net_modules.h> 49 #include <net_device.h> 50 #include <netif_interface.h> 51 #include <nil_interface.h> 52 #include <il_interface.h> 47 #include <net/modules.h> 48 #include <net/device.h> 49 #include <il_remote.h> 53 50 #include <adt/measured_strings.h> 54 #include < packet/packet.h>51 #include <net/packet.h> 55 52 #include <packet_remote.h> 56 #include <nil_local.h> 53 #include <netif_remote.h> 54 #include <nil_skel.h> 57 55 58 56 #include "nildummy.h" 59 57 60 /** The module name. 61 * 62 */ 58 /** The module name. */ 63 59 #define NAME "nildummy" 64 60 65 /** Default maximum transmission unit. 66 * 67 */ 61 /** Default maximum transmission unit. */ 68 62 #define NET_DEFAULT_MTU 1500 69 63 70 /** Network interface layer module global data. 71 * 72 */ 64 /** Network interface layer module global data. */ 73 65 nildummy_globals_t nildummy_globals; 74 66 … … 78 70 { 79 71 fibril_rwlock_read_lock(&nildummy_globals.protos_lock); 80 81 72 if (nildummy_globals.proto.phone) 82 il_device_state_msg(nildummy_globals.proto.phone, device_id, state, 83 nildummy_globals.proto.service); 84 73 il_device_state_msg(nildummy_globals.proto.phone, device_id, 74 state, nildummy_globals.proto.service); 85 75 fibril_rwlock_read_unlock(&nildummy_globals.protos_lock); 86 76 … … 90 80 int nil_initialize(int net_phone) 91 81 { 92 ERROR_DECLARE;93 94 82 fibril_rwlock_initialize(&nildummy_globals.devices_lock); 95 83 fibril_rwlock_initialize(&nildummy_globals.protos_lock); … … 99 87 nildummy_globals.net_phone = net_phone; 100 88 nildummy_globals.proto.phone = 0; 101 ERROR_PROPAGATE(nildummy_devices_initialize(&nildummy_globals.devices));89 int rc = nildummy_devices_initialize(&nildummy_globals.devices); 102 90 103 91 fibril_rwlock_write_unlock(&nildummy_globals.protos_lock); 104 92 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 105 93 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); 94 return rc; 95 } 96 97 /** Process IPC messages from the registered device driver modules 98 * 99 * @param[in] iid Message identifier. 100 * @param[in,out] icall Message parameters. 101 * 102 */ 103 static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall) 104 { 105 packet_t *packet; 106 int rc; 107 108 while (true) { 109 switch (IPC_GET_IMETHOD(*icall)) { 110 case NET_NIL_DEVICE_STATE: 111 rc = nil_device_state_msg_local(0, 112 IPC_GET_DEVICE(*icall), IPC_GET_STATE(*icall)); 113 async_answer_0(iid, (sysarg_t) rc); 114 break; 115 116 case NET_NIL_RECEIVED: 117 rc = packet_translate_remote(nildummy_globals.net_phone, 118 &packet, IPC_GET_PACKET(*icall)); 119 if (rc == EOK) 120 rc = nil_received_msg_local(0, 121 IPC_GET_DEVICE(*icall), packet, 0); 122 123 async_answer_0(iid, (sysarg_t) rc); 124 break; 125 126 default: 127 async_answer_0(iid, (sysarg_t) ENOTSUP); 134 128 } 129 135 130 iid = async_get_call(icall); 136 131 } … … 141 136 * Determine the device local hardware address. 142 137 * 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. 138 * @param[in] device_id New device identifier. 139 * @param[in] service Device driver service. 140 * @param[in] mtu Device maximum transmission unit. 141 * 142 * @return EOK on success. 143 * @return EEXIST if the device with the different service exists. 144 * @return ENOMEM if there is not enough memory left. 145 * @return Other error codes as defined for the 146 * netif_bind_service() function. 147 * @return Other error codes as defined for the 148 * netif_get_addr_req() function. 152 149 * 153 150 */ … … 155 152 size_t mtu) 156 153 { 157 ERROR_DECLARE;158 159 nildummy_device_ref device;160 int index;161 162 154 fibril_rwlock_write_lock(&nildummy_globals.devices_lock); 163 // an existing device? 164 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 165 if(device){ 166 if(device->service != service){ 155 156 /* An existing device? */ 157 nildummy_device_t *device = 158 nildummy_devices_find(&nildummy_globals.devices, device_id); 159 if (device) { 160 if (device->service != service) { 167 161 printf("Device %d already exists\n", device->device_id); 168 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 162 fibril_rwlock_write_unlock( 163 &nildummy_globals.devices_lock); 169 164 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 165 } 187 }else{ 188 // create a new device 189 device = (nildummy_device_ref) malloc(sizeof(nildummy_device_t)); 190 if(! device){ 191 return ENOMEM; 166 167 /* Update MTU */ 168 if (mtu > 0) 169 device->mtu = mtu; 170 else 171 device->mtu = NET_DEFAULT_MTU; 172 173 printf("Device %d already exists:\tMTU\t= %zu\n", 174 device->device_id, device->mtu); 175 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 176 177 /* Notify the upper layer module */ 178 fibril_rwlock_read_lock(&nildummy_globals.protos_lock); 179 if (nildummy_globals.proto.phone) { 180 il_mtu_changed_msg(nildummy_globals.proto.phone, 181 device->device_id, device->mtu, 182 nildummy_globals.proto.service); 192 183 } 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 } 184 fibril_rwlock_read_unlock(&nildummy_globals.protos_lock); 185 186 return EOK; 187 } 188 189 /* Create a new device */ 190 device = (nildummy_device_t *) malloc(sizeof(nildummy_device_t)); 191 if (!device) 192 return ENOMEM; 193 194 device->device_id = device_id; 195 device->service = service; 196 if (mtu > 0) 197 device->mtu = mtu; 198 else 199 device->mtu = NET_DEFAULT_MTU; 200 201 /* Bind the device driver */ 202 device->phone = netif_bind_service(device->service, device->device_id, 203 SERVICE_ETHERNET, nildummy_receiver); 204 if (device->phone < 0) { 205 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 206 free(device); 207 return device->phone; 208 } 209 210 /* Get hardware address */ 211 int rc = netif_get_addr_req(device->phone, device->device_id, 212 &device->addr, &device->addr_data); 213 if (rc != EOK) { 214 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 215 free(device); 216 return rc; 217 } 218 219 /* Add to the cache */ 220 int index = nildummy_devices_add(&nildummy_globals.devices, 221 device->device_id, device); 222 if (index < 0) { 223 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 224 free(device->addr); 225 free(device->addr_data); 226 free(device); 227 return index; 228 } 229 230 printf("%s: Device registered (id: %d, service: %d, mtu: %zu)\n", 231 NAME, device->device_id, device->service, device->mtu); 225 232 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 226 233 return EOK; … … 229 236 /** Return the device hardware address. 230 237 * 231 * @param[in] device_id The device identifier.232 * @param[out] address The device hardware address.238 * @param[in] device_id Device identifier. 239 * @param[out] address Device hardware address. 233 240 * 234 241 * @return EOK on success. … … 238 245 */ 239 246 static int nildummy_addr_message(device_id_t device_id, 240 measured_string_ref *address) 241 { 242 nildummy_device_ref device; 243 244 if(! address){ 247 measured_string_t **address) 248 { 249 if (!address) 245 250 return EBADMEM; 246 }251 247 252 fibril_rwlock_read_lock(&nildummy_globals.devices_lock); 248 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 249 if(! device){ 253 254 nildummy_device_t *device = 255 nildummy_devices_find(&nildummy_globals.devices, device_id); 256 if (!device) { 250 257 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 251 258 return ENOENT; 252 259 } 260 253 261 *address = device->addr; 262 254 263 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 264 255 265 return (*address) ? EOK : ENOENT; 256 266 } … … 258 268 /** Return the device packet dimensions for sending. 259 269 * 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.270 * @param[in] device_id Device identifier. 271 * @param[out] addr_len Minimum reserved address length. 272 * @param[out] prefix Minimum reserved prefix size. 273 * @param[out] content Maximum content size. 274 * @param[out] suffix Minimum reserved suffix size. 265 275 * 266 276 * @return EOK on success. … … 269 279 * 270 280 */ 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)){ 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 if ((!addr_len) || (!prefix) || (!content) || (!suffix)) 277 285 return EBADMEM; 278 }286 279 287 fibril_rwlock_read_lock(&nildummy_globals.devices_lock); 280 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 281 if(! device){ 288 289 nildummy_device_t *device = 290 nildummy_devices_find(&nildummy_globals.devices, device_id); 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; 297 286 298 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 299 287 300 *addr_len = 0; 288 301 *prefix = 0; … … 291 304 } 292 305 293 int nil_received_msg_local(int nil_phone, device_id_t device_id, packet_t packet, services_t target){294 packet_t next; 295 306 int nil_received_msg_local(int nil_phone, device_id_t device_id, 307 packet_t *packet, services_t target) 308 { 296 309 fibril_rwlock_read_lock(&nildummy_globals.protos_lock); 297 if(nildummy_globals.proto.phone){ 298 do{ 299 next = pq_detach(packet); 300 il_received_msg(nildummy_globals.proto.phone, device_id, packet, nildummy_globals.proto.service); 310 311 if (nildummy_globals.proto.phone) { 312 do { 313 packet_t *next = pq_detach(packet); 314 il_received_msg(nildummy_globals.proto.phone, device_id, 315 packet, nildummy_globals.proto.service); 301 316 packet = next; 302 }while(packet); 303 } 317 } while (packet); 318 } 319 304 320 fibril_rwlock_read_unlock(&nildummy_globals.protos_lock); 321 305 322 return EOK; 306 323 } … … 310 327 * Pass received packets for this service. 311 328 * 312 * @param[in] service The module service.313 * @param[in] phone The service phone.329 * @param[in] service Module service. 330 * @param[in] phone Service phone. 314 331 * 315 332 * @return EOK on success. … … 333 350 /** Send the packet queue. 334 351 * 335 * @param[in] device_id The device identifier.336 * @param[in] packet The packet queue.337 * @param[in] sender The sending module service.352 * @param[in] device_id Device identifier. 353 * @param[in] packet Packet queue. 354 * @param[in] sender Sending module service. 338 355 * 339 356 * @return EOK on success. … … 342 359 * 343 360 */ 344 static int nildummy_send_message(device_id_t device_id, packet_t packet,361 static int nildummy_send_message(device_id_t device_id, packet_t *packet, 345 362 services_t sender) 346 363 { 347 nildummy_device_ref device;348 349 364 fibril_rwlock_read_lock(&nildummy_globals.devices_lock); 350 device = nildummy_devices_find(&nildummy_globals.devices, device_id); 351 if(! device){ 365 366 nildummy_device_t *device = 367 nildummy_devices_find(&nildummy_globals.devices, device_id); 368 if (!device) { 352 369 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 353 370 return ENOENT; 354 371 } 355 // send packet queue 356 if(packet){ 357 netif_send_msg(device->phone, device_id, packet, SERVICE_NILDUMMY); 358 } 372 373 /* Send packet queue */ 374 if (packet) 375 netif_send_msg(device->phone, device_id, packet, 376 SERVICE_NILDUMMY); 377 359 378 fibril_rwlock_read_unlock(&nildummy_globals.devices_lock); 360 return EOK; 361 } 362 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; 379 380 return EOK; 381 } 382 383 int nil_module_message(ipc_callid_t callid, ipc_call_t *call, 384 ipc_call_t *answer, size_t *answer_count) 385 { 386 measured_string_t *address; 387 packet_t *packet; 370 388 size_t addrlen; 371 389 size_t prefix; 372 390 size_t suffix; 373 391 size_t content; 392 int rc; 374 393 375 394 *answer_count = 0; 376 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)); 395 switch (IPC_GET_IMETHOD(*call)) { 396 case IPC_M_PHONE_HUNGUP: 397 return EOK; 398 399 case NET_NIL_DEVICE: 400 return nildummy_device_message(IPC_GET_DEVICE(*call), 401 IPC_GET_SERVICE(*call), IPC_GET_MTU(*call)); 402 403 case NET_NIL_SEND: 404 rc = packet_translate_remote(nildummy_globals.net_phone, 405 &packet, IPC_GET_PACKET(*call)); 406 if (rc != EOK) 407 return rc; 408 return nildummy_send_message(IPC_GET_DEVICE(*call), packet, 409 IPC_GET_SERVICE(*call)); 410 411 case NET_NIL_PACKET_SPACE: 412 rc = nildummy_packet_space_message(IPC_GET_DEVICE(*call), 413 &addrlen, &prefix, &content, &suffix); 414 if (rc != EOK) 415 return rc; 416 IPC_SET_ADDR(*answer, addrlen); 417 IPC_SET_PREFIX(*answer, prefix); 418 IPC_SET_CONTENT(*answer, content); 419 IPC_SET_SUFFIX(*answer, suffix); 420 *answer_count = 4; 421 return EOK; 422 423 case NET_NIL_ADDR: 424 rc = nildummy_addr_message(IPC_GET_DEVICE(*call), &address); 425 if (rc != EOK) 426 return rc; 427 return measured_strings_reply(address, 1); 428 429 case NET_NIL_BROADCAST_ADDR: 430 rc = nildummy_addr_message(IPC_GET_DEVICE(*call), &address); 431 if (rc != EOK) 432 return rc; 433 return measured_strings_reply(address, 1); 434 435 case IPC_M_CONNECT_TO_ME: 436 return nildummy_register_message(NIL_GET_PROTO(*call), 437 IPC_GET_PHONE(*call)); 407 438 } 408 439 … … 410 441 } 411 442 412 #ifndef CONFIG_NETIF_NIL_BUNDLE413 414 /** Default thread for new connections.415 *416 * @param[in] iid The initial message identifier.417 * @param[in] icall The initial message call structure.418 *419 */420 static void nil_client_connection(ipc_callid_t iid, ipc_call_t *icall)421 {422 /*423 * Accept the connection424 * - Answer the first IPC_M_CONNECT_ME_TO call.425 */426 ipc_answer_0(iid, EOK);427 428 while(true) {429 ipc_call_t answer;430 int answer_count;431 432 /* Clear the answer structure */433 refresh_answer(&answer, &answer_count);434 435 /* Fetch the next message */436 ipc_call_t call;437 ipc_callid_t callid = async_get_call(&call);438 439 /* Process the message */440 int res = nil_module_message_standalone(NAME, callid, &call, &answer,441 &answer_count);442 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))445 return;446 447 /* Answer the message */448 answer_call(callid, res, &answer, answer_count);449 }450 }451 452 443 int main(int argc, char *argv[]) 453 444 { 454 ERROR_DECLARE;455 456 445 /* Start the module */ 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 */ 446 return nil_module_start(SERVICE_NILDUMMY); 447 } 464 448 465 449 /** @}
Note:
See TracChangeset
for help on using the changeset viewer.