diff --git a/src/tests/kits/net/new_stack/arp/arp.c b/src/tests/kits/net/new_stack/arp/arp.c index 88ea4810b9..eb1c3ce06d 100644 --- a/src/tests/kits/net/new_stack/arp/arp.c +++ b/src/tests/kits/net/new_stack/arp/arp.c @@ -12,7 +12,6 @@ #include #include "net_stack.h" -#include "net_layer.h" status_t std_ops(int32 op, ...); @@ -21,44 +20,16 @@ struct net_layer_module_info nlmi; static struct net_stack_module_info *g_stack = NULL; // ------------------- -status_t init(void * params) +status_t init(net_layer *me) { - status_t status; - net_layer *layer1, *layer2; + printf("%s: initing layer\n", me->name); + return B_OK; - layer2 = NULL; - status = B_NO_MEMORY; - - layer1 = malloc(sizeof(*layer1)); - if (!layer1) - goto error; - - layer1->name = "ethernet/arp"; - layer1->module = &nlmi; - - layer2 = malloc(sizeof(*layer2)); - if (!layer2) - goto error; - - layer2->name = "arp/ethernet"; - layer2->module = &nlmi; - - status = g_stack->register_layer(layer1); - return g_stack->register_layer(layer2); - -error:; - if (layer1) - free(layer1); - if (layer2) - free(layer2); - return status; } status_t uninit(net_layer *me) { printf("%s: uniniting layer\n", me->name); - - free(me); return B_OK; } @@ -94,9 +65,30 @@ status_t output_buffer(net_layer *me, net_buffer *buffer) status_t std_ops(int32 op, ...) { switch(op) { - case B_MODULE_INIT: + case B_MODULE_INIT: { + status_t status; + net_layer *layer1, *layer2; + printf("arp: B_MODULE_INIT\n"); - return get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack); + status = get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack); + if (status != B_OK) + return status; + + status = g_stack->register_layer("ethernet/arp", &nlmi, NULL, &layer1); + if (status != B_OK) + goto error1; + + status = g_stack->register_layer("arp/ethernet", &nlmi, NULL, &layer2); + if (status != B_OK) + goto error2; + + return B_OK; +error2: + g_stack->unregister_layer(layer1); +error1: + put_module(NET_STACK_MODULE_NAME); + return status; + } case B_MODULE_UNINIT: printf("arp: B_MODULE_UNINIT\n"); @@ -111,7 +103,7 @@ status_t std_ops(int32 op, ...) struct net_layer_module_info nlmi = { { - NET_LAYER_MODULE_ROOT "protocols/arp/v0", + NET_LAYER_MODULES_ROOT "protocols/arp/v0", 0, std_ops }, diff --git a/src/tests/kits/net/new_stack/ethernet/ethernet.c b/src/tests/kits/net/new_stack/ethernet/ethernet.c index 76e74e5d57..e3d8e361ad 100644 --- a/src/tests/kits/net/new_stack/ethernet/ethernet.c +++ b/src/tests/kits/net/new_stack/ethernet/ethernet.c @@ -14,7 +14,6 @@ #include #include "net_stack.h" -#include "net_layer.h" enum { ETHER_GETADDR = B_DEVICE_OP_CODES_END, @@ -26,12 +25,11 @@ enum { ETHER_GETFRAMESIZE }; -typedef struct ethernet_device_layer { - net_layer layer; +typedef struct ethernet_device { int fd; int max_frame_size; volatile thread_id reader_thread; -} ethernet_device_layer; +} ethernet_device; #define ETHER_ADDR_LEN 6 /* Ethernet address length */ #define ETHER_TYPE_LEN 2 /* Ethernet type field length */ @@ -58,36 +56,35 @@ static struct net_stack_module_info *g_stack = NULL; // ------------------- -status_t init(void * params) +status_t init(net_layer *me) { - return lookup_devices("/dev/net", params); + printf("%s: initing layer\n", me->name); + return B_OK; } status_t uninit(net_layer *me) { - ethernet_device_layer *edl = (ethernet_device_layer *) me; + ethernet_device *ed = me->cookie; printf("%s: uniniting layer\n", me->name); - close(edl->fd); + close(ed->fd); + free(me->cookie); - free(me->name); - free(me); - return B_OK; } status_t enable(net_layer *me, bool enable) { - ethernet_device_layer *edl = (ethernet_device_layer *) me; + ethernet_device *ed = me->cookie; if (enable) { // enable this layer thread_id tid; char name[B_OS_NAME_LENGTH * 2]; - if (edl->reader_thread != -1) + if (ed->reader_thread != -1) // already up return B_OK; @@ -100,7 +97,7 @@ status_t enable(net_layer *me, bool enable) return tid; }; - edl->reader_thread = tid; + ed->reader_thread = tid; return resume_thread(tid); } else { @@ -108,14 +105,14 @@ status_t enable(net_layer *me, bool enable) status_t dummy; // disable this layer - if (edl->reader_thread == -1) + if (ed->reader_thread == -1) // already down return B_OK; - send_signal_etc(edl->reader_thread, SIGTERM, 0); - wait_for_thread(edl->reader_thread, &dummy); + send_signal_etc(ed->reader_thread, SIGTERM, 0); + wait_for_thread(ed->reader_thread, &dummy); printf("%s: device reader stopped.\n", me->name); - edl->reader_thread = -1; + ed->reader_thread = -1; return B_OK; }; @@ -186,7 +183,7 @@ status_t lookup_devices(char *root, void *cookie) status_t register_device(const char *path, void *cookie) { - ethernet_device_layer *edl; + ethernet_device *ed; int frame_size; ether_addr_t mac_address; int fd; @@ -232,32 +229,29 @@ status_t register_device(const char *path, void *cookie) mac_address.byte[2], mac_address.byte[3], mac_address.byte[4], mac_address.byte[5], frame_size); - edl = malloc(sizeof(*edl)); - if (!edl) { + ed = malloc(sizeof(*ed)); + if (!ed) { close(fd); return B_NO_MEMORY; }; - edl->fd = fd; - edl->max_frame_size = frame_size; - edl->reader_thread = -1; + ed->fd = fd; + ed->max_frame_size = frame_size; + ed->reader_thread = -1; name = malloc(strlen("ethernet/") + strlen(path)); strcpy(name, "ethernet/"); strcat(name, path + strlen("/dev/net/")); - edl->layer.name = name; - edl->layer.module = &nlmi; - - return g_stack->register_layer(&edl->layer); + return g_stack->register_layer(name, &nlmi, ed, NULL); } // ---------------------------------------------------- status_t device_reader(void *args) { - net_layer *me = args; - ethernet_device_layer *edl = (ethernet_device_layer *) me; - net_buffer *buffer; + net_layer *me = args; + ethernet_device *ed = (ethernet_device *) me->cookie; + net_buffer *buffer; status_t status; void *frame; ssize_t sz; @@ -266,14 +260,14 @@ status_t device_reader(void *args) status = B_OK; while(1) { - frame = malloc(edl->max_frame_size); + frame = malloc(ed->max_frame_size); if (!frame) { status = B_NO_MEMORY; break; }; // read on frame at time - sz = read(edl->fd, frame, edl->max_frame_size); + sz = read(ed->fd, frame, ed->max_frame_size); if (sz >= B_OK) { buffer = g_stack->new_buffer(); if (!buffer) { @@ -293,7 +287,7 @@ status_t device_reader(void *args) }; }; - edl->reader_thread = -1; + ed->reader_thread = -1; return status; } @@ -302,9 +296,17 @@ status_t device_reader(void *args) status_t std_ops(int32 op, ...) { switch(op) { - case B_MODULE_INIT: + case B_MODULE_INIT: { + status_t status; + printf("ethernet: B_MODULE_INIT\n"); - return get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack); + status = get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack); + if (status != B_OK) + return status; + + lookup_devices("/dev/net", NULL); + return B_OK; + }; case B_MODULE_UNINIT: printf("ethernet: B_MODULE_UNINIT\n"); @@ -319,7 +321,7 @@ status_t std_ops(int32 op, ...) struct net_layer_module_info nlmi = { { - NET_LAYER_MODULE_ROOT "interfaces/ethernet", + NET_LAYER_MODULES_ROOT "interfaces/ethernet", 0, std_ops }, diff --git a/src/tests/kits/net/new_stack/loopback/loopback.c b/src/tests/kits/net/new_stack/loopback/loopback.c index 15821559dc..a1e2c84251 100644 --- a/src/tests/kits/net/new_stack/loopback/loopback.c +++ b/src/tests/kits/net/new_stack/loopback/loopback.c @@ -12,7 +12,6 @@ #include #include "net_stack.h" -#include "net_layer.h" status_t std_ops(int32 op, ...); @@ -22,24 +21,15 @@ static struct net_stack_module_info *g_stack = NULL; // ------------------- -status_t init(void * params) +status_t init(net_layer *me) { - net_layer *layer; - - layer = malloc(sizeof(*layer)); - if (!layer) - return B_NO_MEMORY; - - layer->name = "*/loopback"; - layer->module = &nlmi; - - return g_stack->register_layer(layer); + printf("%s: initing layer\n", me->name); + return B_OK; } status_t uninit(net_layer *me) { - printf("%s: uniniting layer\n", me->name); - free(me); + printf("loopback: uniniting layer\n"); return B_OK; } @@ -63,9 +53,16 @@ status_t output_buffer(net_layer *me, net_buffer *buffer) status_t std_ops(int32 op, ...) { switch(op) { - case B_MODULE_INIT: + case B_MODULE_INIT: { + status_t status; + printf("loopback: B_MODULE_INIT\n"); - return get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack); + status = get_module(NET_STACK_MODULE_NAME, (module_info **) &g_stack); + if (status != B_OK) + return status; + + return g_stack->register_layer("*/loopback", &nlmi, NULL, NULL); + } case B_MODULE_UNINIT: printf("loopback: B_MODULE_UNINIT\n"); @@ -80,7 +77,7 @@ status_t std_ops(int32 op, ...) struct net_layer_module_info nlmi = { { - NET_LAYER_MODULE_ROOT "interfaces/loopback", + NET_LAYER_MODULES_ROOT "interfaces/loopback", 0, std_ops }, diff --git a/src/tests/kits/net/new_stack/net_server.cpp b/src/tests/kits/net/new_stack/net_server.cpp index 4b9e250997..e847c4352d 100644 --- a/src/tests/kits/net/new_stack/net_server.cpp +++ b/src/tests/kits/net/new_stack/net_server.cpp @@ -68,6 +68,11 @@ int test_buffer() g_stack->dump_buffer(buffer); + printf("Removing 61 bytes at offset 4...\n"); + g_stack->remove_from_buffer(buffer, 4, 61); + + g_stack->dump_buffer(buffer); + len = g_stack->read_buffer(buffer, 2, data, sizeof(data)); data[len] = 0; diff --git a/src/tests/kits/net/new_stack/net_stack.h b/src/tests/kits/net/new_stack/net_stack.h index b4cf09c15a..4abd6a2ec1 100644 --- a/src/tests/kits/net/new_stack/net_stack.h +++ b/src/tests/kits/net/new_stack/net_stack.h @@ -29,8 +29,40 @@ typedef int benaphore; #define lock_benaphore(a) #define unlock_benaphore(a) -// Networking layer(s) definition -#include "net_layer.h" +// Networking layer(s) definitions +typedef struct net_layer net_layer; +#define NET_LAYER_MODULES_ROOT "network/layers/" + +typedef struct net_layer_module_info { + module_info info; + + status_t (*init)(net_layer *me); + status_t (*uninit)(net_layer *me); + status_t (*enable)(net_layer *me, bool enable); + status_t (*input_buffer)(net_layer *me, struct net_buffer *buffer); + status_t (*output_buffer)(net_layer *me, struct net_buffer *buffer); +} net_layer_module_info; + +struct net_layer { + struct net_layer *next; + char *name; + net_layer_module_info *module; + void *cookie; + struct net_layer **layers_above; + struct net_layer **layers_below; +}; + +// Networking attributs +enum { + NET_ATTRIBUT_BOOL, + NET_ATTRIBUT_BYTE, + NET_ATTRIBUT_INT16, + NET_ATTRIBUT_INT32, + NET_ATTRIBUT_INT64, + NET_ATTRIBUT_DATA, + NET_ATTRIBUT_STRING, + NET_ATTRIBUT_POINTER +}; // Network stack main module definition @@ -48,8 +80,13 @@ struct net_stack_module_info { * Net layers handling */ - status_t (*register_layer)(net_layer *layer); + status_t (*register_layer)(const char *name, net_layer_module_info *module, void *cookie, net_layer **me); status_t (*unregister_layer)(net_layer *layer); + + status_t (*add_layer_attribut)(net_layer *layer, const char *name, int type, ...); + status_t (*remove_layer_attribut)(net_layer *layer, const char *name); + status_t (*find_layer_attribut)(net_layer *layer, const char *name, + int *type, void **attribut, size_t *size); status_t (*push_buffer_up)(net_layer *me, net_buffer *buffer); status_t (*push_buffer_down)(net_layer *me, net_buffer *buffer); @@ -77,6 +114,11 @@ struct net_stack_module_info { uint32 (*read_buffer)(net_buffer *buffer, uint32 offset, void *data, uint32 bytes); uint32 (*write_buffer)(net_buffer *buffer, uint32 offset, const void *data, uint32 bytes); + status_t (*add_buffer_attribut)(net_buffer *buffer, const char *name, int type, ...); + status_t (*remove_buffer_attribut)(net_buffer *buffer, const char *name); + status_t (*find_buffer_attribut)(net_buffer *buffer, const char *name, + int *type, void **attribut, size_t *size); + void (*dump_buffer)(net_buffer *buffer); // Buffer queues support diff --git a/src/tests/kits/net/new_stack/stack/buffer.c b/src/tests/kits/net/new_stack/stack/buffer.c index 47e26667d2..0924450e3f 100644 --- a/src/tests/kits/net/new_stack/stack/buffer.c +++ b/src/tests/kits/net/new_stack/stack/buffer.c @@ -176,7 +176,7 @@ status_t delete_buffer(net_buffer *buffer, bool interrupt_safe) return B_BAD_VALUE; if (! g_buffers_pool) - // Uh? From where come this net_data!?! + // Uh? From where come this net_buffer!?! return B_ERROR; printf("delete_buffer(%p)\n", buffer); @@ -355,135 +355,69 @@ error1: // -------------------------------------------------- status_t remove_from_buffer(net_buffer *buffer, uint32 offset, uint32 bytes) { -#if 0 - // TODO!!! - - net_buffer_chunk * ndn; - net_buffer_chunk * start_node; - net_buffer_chunk * end_node; - uint32 start_node_offset; - uint32 end_node_offset; - net_buffer_chunk * start_split_node; - net_buffer_chunk * end_split_node; - uint8 * data; + net_buffer_chunk *first_chunk; + net_buffer_chunk *last_chunk; + net_buffer_chunk *previous_chunk; + uint32 offset_in_first_chunk; + uint32 offset_in_last_chunk; + if (! buffer) + return B_BAD_VALUE; + + if (offset >= buffer->len) + return B_BAD_VALUE; + if (bytes < 1) return B_BAD_VALUE; - /* - Possibles cases: - [XXXXXXX|++++++].... Triming at start of node (start and/or end nodes) - [+++|XXXXXX|+++].... Triming in the middle of *one* node - [+++++|XXXXXXXX].... Triming at the end of start node - ...[XXXXXXXXXXXXXX].... Triming one or more full node - */ - - start_node = find_buffer_chunk(nd, offset, &start_node_offset, NULL); - if (! start_node) + first_chunk = find_buffer_chunk(buffer, offset, &offset_in_first_chunk, &previous_chunk); + if (! first_chunk) return B_BAD_VALUE; - - end_node = find_buffer_chunk(nd, offset + bytes, &end_node_offset, NULL); - if (! end_node) + + last_chunk = find_buffer_chunk(buffer, offset + bytes, &offset_in_last_chunk, NULL); + if (! last_chunk) return B_BAD_VALUE; + + if (offset_in_last_chunk) { + // we must split last_chunk data in two parts, + // removing beginnin chunk from data lists and adding the ending one :-( - if ( (start_node == end_node) && - (start_node_offset > 0) && (end_node_offset != end_node->len) ) - // need to split one node into two parts, left & right, to be able to - // trim data in the middle: - // [++++|XXXXXX|+++++++] - return B_OK; - }; - - // if the trimmed part is in one node, we know now that it's: - // |++++++|XXXXXXXXXXXX|, or: - // |XXXXXXXXX|+++++++++| - - if (start_node_offset) - start_node->len = start_node_offset; - - if (end_node_offset) { - data = (uint8 *) end_node->data; - data += end_node_offset; - end_node->data = data; - end_node->len -= end_node_offset; - }; - - // start node must be split - split = (uint8 *) start_node->data; - split += start_node_offset; - start_split_node = new_buffer_chunk(split, start_node->len - start_node_offset); - if (! start_split_node) - goto error1; - }; - - if (end_node_offset) { - // end node must be split - split = (uint8 *) end_node->data; - split += end_node_offset; - end_split_node = new_buffer_chunk(split, end_node->len - end_node_offset); - if (! end_split_node) - goto error2; - }; - - if (start_split_node) { - }; - - ndn = start_node->next_data; - while (ndn->next_data != end_node) { - if (ndn->next_data == end_node) - break; - - ndn = ndn->next_data; - }; - != end_node - - if (end_split_node) { - }; - - - // split start_node data chunk in two parts - start_node->len = start_node_offset; + net_buffer_chunk *split_chunk; + uint8 *split; - start_split_node->free_func = NULL; + // remove the beginning of last_chunk data + + split = (uint8 *) last_chunk->data; + split += offset_in_last_chunk; + split_chunk = new_buffer_chunk(split, last_chunk->len - offset_in_last_chunk); + // if (! split_chunk) + // goto error1; + // as split_chunk data comes from 'last_chunk', we don't + // ask to free this chunk data, as it would be by previous_chunk + split_chunk->free_func = NULL; + split_chunk->next_data = last_chunk->next_data; + // add the split_chunk to buffer's all_chunks list + split_chunk->next = buffer->all_chunks; + buffer->all_chunks = split_chunk; + + last_chunk = split_chunk; }; - + if (offset_in_first_chunk) { + // remove the end of first_chunk data: just forgot about last bytes of data :-) + first_chunk->len = offset_in_first_chunk; + } else + first_chunk = previous_chunk; - ndn->len = offset_in_node; - - split_node->free_func = NULL; // as split_node data comes from 'ndn', we don't - // free this node data but only 'ndn' one... - - // create a new node to host inserted data - new_node = new_buffer_chunk(data, bytes); - if (! new_node) - goto error2; - - new_node->free_func = freethis; // can be NULL = don't free this chunk - new_node->free_cookie = NULL; - - // add these nodes to node_list (nodes order don't matter in this list, so we do it the easy way :-) - split_node->next = nd->node_list; - new_node->next = split_node; - nd->node_list = new_node; - - // Insert this new_node this node to the end of data_list - split_node->next_data = ndn->next_data; - ndn->next_data = new_node; - new_node->next_data = split_node; - - nd->len -= bytes; + // fix the data chunks list to remove chunk(s), if any + if (first_chunk) + first_chunk->next_data = last_chunk; + else + buffer->data_chunks = last_chunk; + buffer->len -= bytes; return B_OK; - -error2: - g_memory_pool->delete_pool_node(g_buffer_chunks_pool, end_split_node); -error1: - if (start_split_node) - g_memory_pool->delete_pool_node(g_buffer_chunks_pool, start_split_node); -#endif - return B_ERROR; } @@ -559,6 +493,27 @@ uint32 write_buffer(net_buffer *buffer, uint32 offset, const void *data, uint32 return len; } + +// -------------------------------------------------- +status_t add_buffer_attribut(net_buffer *buffer, const char *name, int type, ...) +{ + return B_ERROR; +} + + +// -------------------------------------------------- +status_t remove_buffer_attribut(net_buffer *buffer, const char *name) +{ + return B_ERROR; +} + + +status_t find_buffer_attribut(net_buffer *buffer, const char *name, int *type, void **attribut, size_t *size) +{ + return B_ERROR; +} + + // #pragma mark [data(s) queues functions] // -------------------------------------------------- @@ -871,7 +826,7 @@ void dump_memory for ( j = i; j < i+16 ; j++ ) { if ( j < len ) - sprintf(ptr, "%02x ",byte[j]); + sprintf(ptr, "%02x ", byte[j]); else sprintf(ptr, " "); ptr += 3; diff --git a/src/tests/kits/net/new_stack/stack/buffer.h b/src/tests/kits/net/new_stack/stack/buffer.h index 511b0352e8..c44823810b 100644 --- a/src/tests/kits/net/new_stack/stack/buffer.h +++ b/src/tests/kits/net/new_stack/stack/buffer.h @@ -32,6 +32,10 @@ extern status_t attach_buffer_free_element(net_buffer *buffer, void *arg1, voi extern uint32 read_buffer(net_buffer *buffer, uint32 offset, void *data, uint32 bytes); extern uint32 write_buffer(net_buffer *buffer, uint32 offset, const void *data, uint32 bytes); +extern status_t add_buffer_attribut(net_buffer *buffer, const char *name, int type, ...); +extern status_t remove_buffer_attribut(net_buffer *buffer, const char *name); +extern status_t find_buffer_attribut(net_buffer *buffer, const char *name, int *type, void **attribut, size_t *size); + extern void dump_buffer(net_buffer *buffer); // Network buffer(s) queue(s) diff --git a/src/tests/kits/net/new_stack/stack/layers_manager.c b/src/tests/kits/net/new_stack/stack/layers_manager.c index bde9081c07..10cf552c49 100644 --- a/src/tests/kits/net/new_stack/stack/layers_manager.c +++ b/src/tests/kits/net/new_stack/stack/layers_manager.c @@ -4,23 +4,32 @@ #include #include #include +#include #include #include +#include +#include "memory_pool.h" #include "layers_manager.h" #include "buffer.h" -/* Defines we need */ -#define NET_LAYER_MODULES_ROOT "network/layers/" - struct layers_list { - net_layer *first; - sem_id lock; + struct net_layer *first; + sem_id lock; }; static struct layers_list g_layers; +static memory_pool * g_layers_pool = NULL; +#define LAYERS_PER_POOL (64) + +static net_layer * new_layer(const char *name, net_layer_module_info *module, void *cookie); +static status_t delete_layer(net_layer *layer); + +extern struct memory_pool_module_info *g_memory_pool; + + // #pragma mark [Start/Stop functions] @@ -54,13 +63,12 @@ status_t start_layers_manager() if (!strlen(module_name)) continue; + printf("layers_manager: loading %s layer(s) module\n", module_name); if (get_module(module_name, (module_info **) &nlmi) != B_OK) continue; - printf("layers_manager: initing %s layer(s) module...\n", module_name); - // allow this module to register one or more interfaces - nlmi->init(NULL); // this module may have been acquire more time by calling register_layer() + // or have B_KEEP_LOADED flag, so we don't care... put_module(module_name); }; close_module_list(module_list); @@ -70,6 +78,7 @@ status_t start_layers_manager() acquire_sem(g_layers.lock); layer = g_layers.first; while (layer) { + layer->module->init(layer); layer->module->enable(layer, true); layer = layer->next; }; @@ -90,7 +99,7 @@ status_t stop_layers_manager() // TODO: handle multiple layers registered by same net module - // unregister all layers... + // disable all layers... layer = g_layers.first; while (layer) { next = layer->next; @@ -99,8 +108,12 @@ status_t stop_layers_manager() // down the layer if currently up layer->module->enable(layer, false); layer->module->uninit(layer); + + delete_layer(layer); + printf("layers_manager: unloading %s layer(s) module\n", module_name); put_module(module_name); + layer = next; }; @@ -114,39 +127,49 @@ status_t stop_layers_manager() // #pragma mark [Public functions] // -------------------------------------------------- -status_t register_layer(net_layer *layer) +status_t register_layer(const char *name, net_layer_module_info *module, void *cookie, net_layer **_layer) { status_t status; module_info *dummy; + net_layer *layer; - if (!layer) + if (name == NULL || + strlen(name) <= 0 || + module == NULL) return B_ERROR; - if (layer->module == NULL) - return B_ERROR; - + layer = new_layer(name, module, cookie); + if (!layer) + return B_NO_MEMORY; + // acquire this module, to keep it loaded while this layer is registered - status = get_module(layer->module->info.name, &dummy); + status = get_module(module->info.name, &dummy); if (status != B_OK) - return status; + goto error1; - layer->layers_above = NULL; - layer->layers_below = NULL; - status = acquire_sem(g_layers.lock); if (status != B_OK) - return status; - + goto error2; + layer->next = g_layers.first; g_layers.first = layer; release_sem(g_layers.lock); - printf("layers_manager: '%s' layer registered\n", layer->name); + + if (_layer) + *_layer = layer; return B_OK; + +error2: + put_module(module->info.name); +error1: + return status; } + + // -------------------------------------------------- status_t unregister_layer(net_layer *layer) { @@ -166,15 +189,57 @@ status_t unregister_layer(net_layer *layer) while (p && p->next != layer) p = p->next; - if (!p) + if (!p) { + // Oh oh... :-( printf("layers_manager: unregister_layer(): %p layer not found in list!\n", layer); - else - p->next = layer->next; + release_sem(g_layers.lock); + return B_ERROR; + }; + + p->next = layer->next; }; - release_sem(g_layers.lock); + layer->module->uninit(layer); + printf("layers_manager: '%s' layer unregistered\n", layer->name); + + put_module(layer->module->info.name); + + return delete_layer(layer); +} + + +// -------------------------------------------------- +status_t add_layer_attribut(net_layer *layer, const char *name, int type, ...) +{ + va_list args; + + va_start(args, type); + + switch(type) { + case NET_ATTRIBUT_POINTER: + // hack + layer->cookie = va_arg(args, void *); + break; + } + + va_end(args); + + return B_OK; +} + + +// -------------------------------------------------- +status_t remove_layer_attribut(net_layer *layer, const char *name) +{ + return B_ERROR; +} + + +status_t find_layer_attribut(net_layer *layer, const char *name, int *type, void **attribut, size_t *size) +{ + *attribut = &layer->cookie; return B_OK; } @@ -211,6 +276,7 @@ status_t push_buffer_up(net_layer *layer, net_buffer *buffer) } +// -------------------------------------------------- status_t push_buffer_down(net_layer *layer, net_buffer *buffer) { net_layer *below; @@ -244,27 +310,50 @@ status_t push_buffer_down(net_layer *layer, net_buffer *buffer) // #pragma mark [Private functions] -#if 0 -// ---------------------------------------------------- -status_t interface_reader(void *args) +// -------------------------------------------------- +static net_layer * new_layer(const char *name, net_layer_module_info *module, void *cookie) { - ifnet_t *iface = args; - net_buffer *buffer; - status_t status; + net_layer *layer; + + if (! g_layers_pool) + g_layers_pool = g_memory_pool->new_pool(sizeof(*layer), LAYERS_PER_POOL); + + if (! g_layers_pool) + return NULL; - if (!iface || iface->module == NULL) + layer = (net_layer *) g_memory_pool->new_pool_node(g_layers_pool); + if (! layer) + return NULL; + + layer->name = strdup(name); + layer->module = module; + layer->cookie = cookie; + + layer->layers_above = NULL; + layer->layers_below = NULL; + + return layer; +} + + +// -------------------------------------------------- +static status_t delete_layer(net_layer *layer) +{ + if (!layer) + return B_ERROR; + + if (! g_layers_pool) + // Uh? From where come this net_data!?! return B_ERROR; - while(iface->if_flags & IFF_UP) { - buffer = NULL; - status = iface->module->receive_buffer(iface, &buffer); - if (status < B_OK || buffer == NULL) - continue; - - dump_buffer(buffer); - delete_buffer(buffer, false); - }; - - return B_OK; + if (layer->name) + free(layer->name); + if (layer->layers_above) + free(layer->layers_above); + if (layer->layers_below) + free(layer->layers_below); + + return g_memory_pool->delete_pool_node(g_layers_pool, layer); } -#endif + + diff --git a/src/tests/kits/net/new_stack/stack/layers_manager.h b/src/tests/kits/net/new_stack/stack/layers_manager.h index ed5aa7f2b5..55f433322d 100644 --- a/src/tests/kits/net/new_stack/stack/layers_manager.h +++ b/src/tests/kits/net/new_stack/stack/layers_manager.h @@ -5,7 +5,7 @@ #ifndef OBOS_NET_STACK_LAYERS_MANAGER_H #define OBOS_NET_STACK_LAYERS_MANAGER_H -#include "net_layer.h" +#include "net_stack.h" #ifdef __cplusplus extern "C" { @@ -14,9 +14,15 @@ extern "C" { extern status_t start_layers_manager(); extern status_t stop_layers_manager(); -extern status_t register_layer(net_layer *layer); +extern status_t register_layer(const char *name, net_layer_module_info *module, void *cookie, + net_layer **me); extern status_t unregister_layer(net_layer *layer); +extern status_t add_layer_attribut(net_layer *layer, const char *name, int type, ...); +extern status_t remove_layer_attribut(net_layer *layer, const char *name); +extern status_t find_layer_attribut(net_layer *layer, const char *name, + int *type, void **attribut, size_t *size); + extern status_t push_buffer_up(net_layer *me, struct net_buffer *buffer); extern status_t push_buffer_down(net_layer *me, struct net_buffer *buffer); diff --git a/src/tests/kits/net/new_stack/stack/stack.c b/src/tests/kits/net/new_stack/stack/stack.c index a67c8a5ead..d159352302 100644 --- a/src/tests/kits/net/new_stack/stack/stack.c +++ b/src/tests/kits/net/new_stack/stack/stack.c @@ -73,6 +73,9 @@ struct net_stack_module_info nsmi = { // Layers handling register_layer, unregister_layer, + add_layer_attribut, + remove_layer_attribut, + find_layer_attribut, push_buffer_up, push_buffer_down, @@ -91,6 +94,10 @@ struct net_stack_module_info nsmi = { read_buffer, write_buffer, + + add_buffer_attribut, + remove_buffer_attribut, + find_buffer_attribut, dump_buffer,