diff --git a/src/tests/kits/net/new_stack/stack/attribute.c b/src/tests/kits/net/new_stack/stack/attribute.c new file mode 100644 index 0000000000..b0f0c193b7 --- /dev/null +++ b/src/tests/kits/net/new_stack/stack/attribute.c @@ -0,0 +1,151 @@ +#include +#include +#include +#include + +#include +#include + +#include "net_stack.h" +#include "memory_pool.h" +#include "atomizer.h" +#include "attribute.h" + +#define DPRINTF printf + +#define ATTRIBUTES_PER_POOL (64) + +static memory_pool *g_attributes_pool = NULL; +extern memory_pool_module_info *g_memory_pool; + +#define DEFAULT_ATOMIZER (const void *) (-1) +atomizer_module_info *g_atomizer = NULL; + +// Privates prototypes +// ------------------- + +// LET'S GO FOR IMPLEMENTATION +// ------------------------------------ + +const void * register_attribute_id(const char *name) +{ + status_t status; + + if (g_atomizer == NULL) { + status = get_module(B_ATOMIZER_MODULE_NAME, (module_info **) &g_atomizer); + if (status != B_OK) { + dprintf("register_attribute_id(%s): Can't load " B_ATOMIZER_MODULE_NAME " module!\n", name); + g_atomizer = (atomizer_module_info *) -1; + }; + }; + + if (g_atomizer == (atomizer_module_info *) -1) + return NULL; + + return g_atomizer->atomize(DEFAULT_ATOMIZER, name, true); +} + + +net_attribute * new_attribute(net_attribute **in_list, const void *id) +{ + net_attribute *attr; + + if (! g_attributes_pool) + g_attributes_pool = g_memory_pool->new_pool(sizeof(*attr), ATTRIBUTES_PER_POOL); + + if (! g_attributes_pool) + return NULL; + + attr = (net_attribute *) g_memory_pool->new_pool_node(g_attributes_pool); + if (! attr) + return NULL; + + attr->id = id; + attr->type = 0; + + if (in_list) { + // prepend this attribut to the list + attr->next = *in_list; + *in_list = attr; + } else + attr->next = NULL; + + return attr; + +} + +status_t delete_attribute(net_attribute *attr, net_attribute **from_list) +{ + if (! attr) + return B_BAD_VALUE; + + if (! g_attributes_pool) + // Uh? From where come this net_attribute!?! + return B_ERROR; + + // dprintf("delete_attribute(%p, %p)\n", attr, from_list); + + // Remove attribut from list, if any + if (from_list) { + if (*from_list == attr) + *from_list = attr->next; + else { + net_attribute *tmp = *from_list; + while (tmp) { + if (tmp->next == attr) + break; + tmp = tmp->next; + } + if (tmp) + tmp->next = attr->next; + } + } + + // Last, delete the net_buffer itself + return g_memory_pool->delete_pool_node(g_attributes_pool, attr); +} + + +net_attribute * find_attribute(net_attribute *list, const void *id, int *type, + void **value, size_t *size) +{ + net_attribute *attr; + + if (! list) + return NULL; + + // dprintf("find_attribute(%p, %p)\n", list, id); + attr = list; + while (attr) { + if (attr->id == id) { + if (type) *type = attr->type; + if (size) *size = attr->size; + if (value) { + switch (attr->type & NET_ATTRIBUTE_TYPE_MASK) { + case NET_ATTRIBUTE_BOOL: *value = &attr->u.boolean; break; + case NET_ATTRIBUTE_BYTE: *value = &attr->u.byte; break; + case NET_ATTRIBUTE_INT16: *value = &attr->u.word; break; + case NET_ATTRIBUTE_INT32: *value = &attr->u.dword; break; + case NET_ATTRIBUTE_INT64: *value = &attr->u.ddword; break; + + case NET_ATTRIBUTE_DATA: + case NET_ATTRIBUTE_STRING: + *value = &attr->u.data; + break; + + case NET_ATTRIBUTE_POINTER: + *value = attr->u.vec[0].iov_base; + break; + + case NET_ATTRIBUTE_IOVEC: + *value = &attr->u.vec; + break; + }; + }; + return attr; + }; + attr = attr->next; + }; + return NULL; +} + diff --git a/src/tests/kits/net/new_stack/stack/attribute.h b/src/tests/kits/net/new_stack/stack/attribute.h new file mode 100644 index 0000000000..0962e99159 --- /dev/null +++ b/src/tests/kits/net/new_stack/stack/attribute.h @@ -0,0 +1,43 @@ +/* attribute.h + * private definitions for network attributes + */ + +#ifndef OBOS_NET_STACK_ATTRIBUTE_H +#define OBOS_NET_STACK_ATTRIBUTE_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct net_attribute +{ + struct net_attribute *next; + const void *id; + uint32 type; + uint32 size; + union { + bool boolean; + uint8 byte; + uint16 word; + uint32 dword; + uint64 ddword; + char data[256]; + void *ptr; + iovec vec[16]; // Beware: 16 max :-( + } u; +} net_attribute; + +extern const void * register_attribute_id(const char *name); +extern net_attribute * new_attribute(net_attribute **in_list, const void *id); +extern status_t delete_attribute(net_attribute *attribut, net_attribute **from_list); +extern net_attribute * find_attribute(net_attribute *list, const void *id, int *type, void **value, size_t *size); + +#ifdef __cplusplus +} +#endif + +#endif // OBOS_NET_STACK_ATTRIBUTE_H diff --git a/src/tests/kits/net/new_stack/stack/buffer.c b/src/tests/kits/net/new_stack/stack/buffer.c index a9cbea08bf..92049c8042 100644 --- a/src/tests/kits/net/new_stack/stack/buffer.c +++ b/src/tests/kits/net/new_stack/stack/buffer.c @@ -1,13 +1,17 @@ #include #include #include +#include +#include + #include #include #include "memory_pool.h" #include "net_stack.h" +#include "dump.h" #include "buffer.h" - +#include "attribute.h" typedef struct net_buffer_chunk { @@ -28,8 +32,7 @@ struct net_buffer { uint32 flags; #define BUFFER_TO_FREE (1) #define BUFFER_IS_URGENT (2) -// TODO: handle buffer attributs storage and lookup -// struct attribut *attributs; // buffer attributs + net_attribute *attributes; // buffer attributes }; struct net_buffer_queue @@ -62,7 +65,7 @@ static volatile sem_id g_buffers_purgatory_sync = -1; // use to notify buffers static memory_pool * g_buffer_queues_pool = NULL; -extern struct memory_pool_module_info *g_memory_pool; +extern memory_pool_module_info *g_memory_pool; // Privates prototypes // ------------------- @@ -121,7 +124,7 @@ status_t stop_buffers_service() wait_for_thread(g_buffers_purgatory_thread, &status); // As the purgatory thread stop, some net_buffer(s) still could be flagged - // BUFFER_TO_FREE, but not deleted... yet. + // PACKET_TO_FREE, but not deleted... yet. g_memory_pool->for_each_pool_node(g_buffers_pool, buffer_killer, NULL); // free buffers-related pools @@ -158,6 +161,7 @@ net_buffer * new_buffer(void) buffer->next = NULL; buffer->data_chunks = NULL; buffer->all_chunks = NULL; + buffer->attributes = NULL; buffer->len = 0; buffer->flags = 0; @@ -169,9 +173,6 @@ net_buffer * new_buffer(void) // -------------------------------------------------- status_t delete_buffer(net_buffer *buffer, bool interrupt_safe) { - net_buffer_chunk *chunk; - net_buffer_chunk *next_chunk; - if (! buffer) return B_BAD_VALUE; @@ -190,31 +191,51 @@ status_t delete_buffer(net_buffer *buffer, bool interrupt_safe) return release_sem_etc(g_buffers_purgatory_sync, 1, B_DO_NOT_RESCHEDULE); }; - // Okay, we can free each buffer chunk(s) right now! - chunk = buffer->all_chunks; - while (chunk) { - // okay, one net_buffer_chunk less referencing this data - chunk->ref_count--; - next_chunk = chunk->next; - - if (chunk->ref_count == 0) { - // it was the last net_buffer_chunk to reference this data, - // so free it now! + if (buffer->all_chunks) { + // Okay, we can (try to) free each buffer chunk(s) right now! - // do we have to call the free_func() on this data? - if (chunk->free_func) { - // yes, please!!! - // call the right free_func kind on this data - if (chunk->free_cookie) - chunk->free_func(chunk->free_cookie, (void *) chunk->data); - else - chunk->free_func((void *) chunk->data); + net_buffer_chunk *chunk; + net_buffer_chunk *next_chunk; + + chunk = buffer->all_chunks; + while (chunk) { + // okay, one net_buffer_chunk less referencing this data + atomic_add(&chunk->ref_count, -1); + next_chunk = chunk->next; + + if (chunk->ref_count == 0) { + // it was the last net_buffer_chunk to reference this data, + // so free it now! + + // do we have to call the free_func() on this data? + if (chunk->free_func) { + // yes, please!!! + // call the right free_func kind on this data + if (chunk->free_cookie) + chunk->free_func(chunk->free_cookie, (void *) chunk->data); + else + chunk->free_func((void *) chunk->data); + }; + // delete this net_buffer_chunk + g_memory_pool->delete_pool_node(g_buffer_chunks_pool, chunk); }; - }; - // delete this net_buffer_chunk - g_memory_pool->delete_pool_node(g_buffer_chunks_pool, chunk); - chunk = next_chunk; + chunk = next_chunk; + }; + }; + + if (buffer->attributes) { + // Free buffer attributes + + net_attribute *attr; + net_attribute *next_attr; + + attr = buffer->attributes; + while (attr) { + next_attr = attr->next; + delete_attribute(attr, NULL); + attr = next_attr; + }; }; // Last, delete the net_buffer itself @@ -232,7 +253,34 @@ net_buffer * duplicate_buffer(net_buffer *buffer) // -------------------------------------------------- net_buffer * clone_buffer(net_buffer *buffer) { - return NULL; // B_UNSUPPORTED; + net_buffer *clone; + net_buffer_chunk *chunk; + + if (! g_buffers_pool) + g_buffers_pool = g_memory_pool->new_pool(sizeof(*buffer), BUFFERS_PER_POOL); + + if (! g_buffers_pool) + return NULL; + + clone = (net_buffer *) g_memory_pool->new_pool_node(g_buffers_pool); + if (! clone) + return NULL; + + clone->next = NULL; + clone->data_chunks = buffer->data_chunks; + clone->all_chunks = buffer->all_chunks; + clone->len = buffer->len; + clone->flags = buffer->flags; + + // Okay, increase all chunks ref count, as we have another buffer referencing them + chunk = buffer->all_chunks; + while (chunk) { + // okay, one net_buffer_chunk less referencing this data + atomic_add(&chunk->ref_count, 1); + chunk = chunk->next; + }; + + return clone; } @@ -243,7 +291,7 @@ net_buffer * split_buffer(net_buffer *buffer, uint32 offset) } // -------------------------------------------------- -status_t merge_buffers(net_buffer *begin_buffer, net_buffer *end_buffer) +status_t concatenate_buffers(net_buffer *begin_buffer, net_buffer *end_buffer) { return B_ERROR; } @@ -501,22 +549,112 @@ uint32 write_buffer(net_buffer *buffer, uint32 offset, const void *data, uint32 // -------------------------------------------------- -status_t add_buffer_attribut(net_buffer *buffer, const char *name, int type, ...) +status_t add_buffer_attribute(net_buffer *buffer, const void *id, int type, ...) { - return B_ERROR; + net_attribute *attr; + + if (! buffer) + return B_BAD_VALUE; + + attr = new_attribute(&buffer->attributes, id); + if (! attr) + return B_NO_MEMORY; + + if (type & FROM_BUFFER) { + va_list args; + net_buffer_chunk *chunk; + int offset; + uint32 offset_in_chunk; + int size; + uint8 *ptr; + + type = (type & NET_ATTRIBUTE_FLAGS_MASK); + + va_start(args, type); + offset = va_arg(args, int); + size = va_arg(args, int); + va_end(args); + + chunk = find_buffer_chunk(buffer, offset, &offset_in_chunk, NULL); + if (chunk == NULL) { + delete_attribute(attr, &buffer->attributes); + return B_BAD_VALUE; + }; + + attr->size = size; + + if (size < chunk->len - offset_in_chunk) { + ptr = (uint8 *) chunk->data; + ptr += offset_in_chunk; + + attr->type = type | NET_ATTRIBUTE_POINTER; + attr->u.ptr = ptr; + } else { + // data overlap this chunk, use iovec attribute type + int i; + uint32 len; + uint32 chunk_len; + + i = 0; + len = 0; + while (chunk) { + ptr = (uint8 *) chunk->data; + ptr += offset_in_chunk; + chunk_len = min((chunk->len - offset_in_chunk), (size - len)); + + attr->u.vec[i].iov_base = ptr; + attr->u.vec[i].iov_len = chunk_len; + + len += chunk_len; + i++; + if (len >= size || i > 16) + break; + + offset_in_chunk = 0; // only the first chunk + + chunk = chunk->next_data; // next chunk + }; + + attr->type = type | NET_ATTRIBUTE_IOVEC; + } + + } else { + // Not implemented + return B_ERROR; + } + + return B_OK; } // -------------------------------------------------- -status_t remove_buffer_attribut(net_buffer *buffer, const char *name) +status_t remove_buffer_attribute(net_buffer *buffer, const void *id) { - return B_ERROR; + net_attribute *attr; + + if (! buffer) + return B_BAD_VALUE; + + attr = find_attribute(buffer->attributes, id, NULL, NULL, NULL); + if (! attr) + return B_NAME_NOT_FOUND; + + return delete_attribute(attr, &buffer->attributes); } -status_t find_buffer_attribut(net_buffer *buffer, const char *name, int *type, void **attribut, size_t *size) +status_t find_buffer_attribute(net_buffer *buffer, const void *id, int *type, void **value, size_t *size) { - return B_ERROR; + net_attribute *attr; + + if (! buffer) + return B_BAD_VALUE; + + attr = find_attribute(buffer->attributes, id, type, value, size); + if (! attr) + return B_NAME_NOT_FOUND; + + return B_OK; } @@ -810,56 +948,6 @@ static status_t append_buffer(net_buffer *buffer, const void *data, uint32 bytes } -// -------------------------------------------------- -void dump_memory - ( - const char * prefix, - const void * data, - uint32 len - ) -{ - uint32 i,j; - char text[96]; // only 3*16 + 16 max by line needed - uint8 * byte; - char * ptr; - - byte = (uint8 *) data; - - for ( i = 0; i < len; i += 16 ) - { - ptr = text; - - for ( j = i; j < i+16 ; j++ ) - { - if ( j < len ) - sprintf(ptr, "%02x ", byte[j]); - else - sprintf(ptr, " "); - ptr += 3; - }; - - for (j = i; j < len && j < i+16;j++) - { - if ( byte[j] >= 0x20 && byte[j] < 0x7e ) - *ptr = byte[j]; - else - *ptr = '.'; - - ptr++; - }; - *ptr = '\n'; - ptr++; - *ptr = '\0'; - - if (prefix) - DPRINTF(prefix); - DPRINTF(text); - - // next line - }; -} - - // -------------------------------------------------- void dump_buffer(net_buffer *buffer) { @@ -893,7 +981,7 @@ void dump_buffer(net_buffer *buffer) } -// #pragma mark [Buffers Purgatory functions] +// #pragma mark [Packets Purgatory functions] // -------------------------------------------------- static int32 buffers_purgatory_thread(void *data) diff --git a/src/tests/kits/net/new_stack/stack/buffer.h b/src/tests/kits/net/new_stack/stack/buffer.h index 800d13b606..8ae1ac7e1f 100644 --- a/src/tests/kits/net/new_stack/stack/buffer.h +++ b/src/tests/kits/net/new_stack/stack/buffer.h @@ -33,9 +33,9 @@ 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 status_t add_buffer_attribute(net_buffer *buffer, const void *id, int type, ...); +extern status_t remove_buffer_attribute(net_buffer *buffer, const void *id); +extern status_t find_buffer_attribute(net_buffer *buffer, const void *id, int *type, void **value, size_t *size); extern void dump_buffer(net_buffer *buffer); diff --git a/src/tests/kits/net/new_stack/stack/dump.c b/src/tests/kits/net/new_stack/stack/dump.c new file mode 100644 index 0000000000..b7fc4c51a5 --- /dev/null +++ b/src/tests/kits/net/new_stack/stack/dump.c @@ -0,0 +1,53 @@ +#include + +#include +#include + +// -------------------------------------------------- +void dump_memory + ( + const char * prefix, + const void * data, + uint32 len + ) +{ + uint32 i,j; + char text[96]; // only 3*16 + 16 max by line needed + uint8 * byte; + char * ptr; + + byte = (uint8 *) data; + + for ( i = 0; i < len; i += 16 ) + { + ptr = text; + + for ( j = i; j < i+16 ; j++ ) + { + if ( j < len ) + sprintf(ptr, "%02x ", byte[j]); + else + sprintf(ptr, " "); + ptr += 3; + }; + + for (j = i; j < len && j < i+16;j++) + { + if ( byte[j] >= 0x20 && byte[j] < 0x7e ) + *ptr = byte[j]; + else + *ptr = '.'; + + ptr++; + }; + *ptr = '\n'; + ptr++; + *ptr = '\0'; + + if (prefix) + dprintf(prefix); + dprintf(text); + + // next line + }; +} diff --git a/src/tests/kits/net/new_stack/stack/dump.h b/src/tests/kits/net/new_stack/stack/dump.h new file mode 100644 index 0000000000..190c63f870 --- /dev/null +++ b/src/tests/kits/net/new_stack/stack/dump.h @@ -0,0 +1,6 @@ +#ifndef DUMP_H +#define DUMP_H + +extern void dump_memory(const char *prefix, const void *data, uint32 len); + +#endif 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 1c60907e38..3a6cd808fc 100644 --- a/src/tests/kits/net/new_stack/stack/layers_manager.c +++ b/src/tests/kits/net/new_stack/stack/layers_manager.c @@ -24,10 +24,13 @@ 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 net_layer * new_layer(const char *name, const char *type, int priority, + net_layer_module_info *module, void *cookie); static status_t delete_layer(net_layer *layer); -extern struct memory_pool_module_info *g_memory_pool; +extern memory_pool_module_info *g_memory_pool; + +char joker_type[] = "*"; // #pragma mark [Start/Stop functions] @@ -63,7 +66,7 @@ status_t start_layers_manager() if (!strlen(module_name)) continue; - printf("layers_manager: loading %s layer(s) module\n", module_name); + dprintf("layers_manager: loading %s layer(s) module\n", module_name); if (get_module(module_name, (module_info **) &nlmi) != B_OK) continue; @@ -104,14 +107,14 @@ status_t stop_layers_manager() while (layer) { next = layer->next; module_name = layer->module->info.name; - printf("layers_manager: uniniting '%s' layer\n", layer->name); + dprintf("layers_manager: uniniting '%s' layer\n", layer->name); // 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); + dprintf("layers_manager: unloading %s layer(s) module\n", module_name); put_module(module_name); layer = next; @@ -127,7 +130,8 @@ status_t stop_layers_manager() // #pragma mark [Public functions] // -------------------------------------------------- -status_t register_layer(const char *name, net_layer_module_info *module, void *cookie, net_layer **_layer) +status_t register_layer(const char *name, const char *type, int priority, + net_layer_module_info *module, void *cookie, net_layer **_layer) { status_t status; module_info *dummy; @@ -138,7 +142,7 @@ status_t register_layer(const char *name, net_layer_module_info *module, void *c module == NULL) return B_ERROR; - layer = new_layer(name, module, cookie); + layer = new_layer(name, type, priority, module, cookie); if (!layer) return B_NO_MEMORY; @@ -156,7 +160,7 @@ status_t register_layer(const char *name, net_layer_module_info *module, void *c release_sem(g_layers.lock); - printf("layers_manager: '%s' layer registered\n", layer->name); + dprintf("layers_manager: '%s' layer, registering %s/%s type\n", layer->name, layer->type, layer->sub_type); if (_layer) *_layer = layer; @@ -191,7 +195,7 @@ status_t unregister_layer(net_layer *layer) if (!p) { // Oh oh... :-( - printf("layers_manager: unregister_layer(): %p layer not found in list!\n", layer); + dprintf("layers_manager: unregister_layer(): %p layer not found in list!\n", layer); release_sem(g_layers.lock); return B_ERROR; }; @@ -202,7 +206,7 @@ status_t unregister_layer(net_layer *layer) layer->module->uninit(layer); - printf("layers_manager: '%s' layer unregistered\n", layer->name); + dprintf("layers_manager: '%s' layer unregistered\n", layer->name); put_module(layer->module->info.name); @@ -235,14 +239,14 @@ net_layer * find_layer(const char *name) // -------------------------------------------------- -status_t add_layer_attribut(net_layer *layer, const char *name, int type, ...) +status_t add_layer_attribute(net_layer *layer, const void *id, int type, ...) { va_list args; va_start(args, type); switch(type) { - case NET_ATTRIBUT_POINTER: + case NET_ATTRIBUTE_DATA: // hack layer->cookie = va_arg(args, void *); break; @@ -255,53 +259,77 @@ 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 remove_layer_attribute(net_layer *layer, const void *id) { return B_ERROR; } -status_t find_layer_attribut(net_layer *layer, const char *name, int *type, void **attribut, size_t *size) +status_t find_layer_attribute(net_layer *layer, const void *id, int *type, + void **attribute, size_t *size) { - *attribut = &layer->cookie; + *attribute = &layer->cookie; return B_OK; } // -------------------------------------------------- -status_t push_buffer_up(net_layer *layer, net_buffer *buffer) +status_t send_up(net_layer *layer, net_buffer *buffer) { net_layer *above; status_t status; - int i; + // int i; if (!layer) return B_ERROR; - // #### TODO: lock the layer(s) above & below hierarchy - if (!layer->layers_above) - // no layers above this one - return B_ERROR; - - status = B_ERROR; - i = 0; - while (layer->layers_above[i]) { - above = layer->layers_above[i++]; - if (!above->module->input_buffer) - // this layer don't input buffer - continue; - - status = above->module->input_buffer(above, buffer); - if (status == B_OK) - return status; - }; + status = acquire_sem(g_layers.lock); + if (status != B_OK) + return status; + status = B_ERROR; + // TODO: lookup thru a previoulsy (at each layer [un]registration time) built list of + // "above" layers of caller layer. + + // dprintf("layers_manager: send_up(): layer %s (%s/%s), searching a matching upper layer...\n", + // layer->name, layer->type, layer->sub_type); + + // HACK: today, we lookup thru ALL :-( registered layers. + // In the future, such layers (de)assembly should be done at layer (un)resgistration time, as + // it never change until layers list change herself... + above = g_layers.first; + while (above) { + // dprintf("layers_manager: send_up: Matching against layer %s (%s/%s) ?\n", + // above->name, above->type, above->sub_type); + + if ( above->module->process_input && + (strcmp(above->type, joker_type) == 0 || + (strcmp(above->type, layer->sub_type) == 0)) ) { +/* + dprintf("layers_manager: send_up: handing buffer from %s/%s (%s) to %s/%s (%s)...\n", + layer->type, layer->sub_type, layer->name, + above->type, above->sub_type, above->name); +*/ + release_sem(g_layers.lock); + status = above->module->process_input(above, buffer); + if (status == B_OK) { + atomic_add(&above->use_count, 1); + return status; + }; + + status = acquire_sem(g_layers.lock); + if (status != B_OK) + return status; + }; + above = above->next; + } + release_sem(g_layers.lock); return status; } // -------------------------------------------------- -status_t push_buffer_down(net_layer *layer, net_buffer *buffer) +status_t send_down(net_layer *layer, net_buffer *buffer) { net_layer *below; status_t status; @@ -319,11 +347,11 @@ status_t push_buffer_down(net_layer *layer, net_buffer *buffer) i = 0; while (layer->layers_below[i]) { below = layer->layers_below[i++]; - if (!below->module->output_buffer) - // this layer don't output buffer + if (!below->module->process_output) + // this layer don't process output buffer continue; - status = below->module->output_buffer(below, buffer); + status = below->module->process_output(below, buffer); if (status == B_OK) return status; }; @@ -335,7 +363,8 @@ status_t push_buffer_down(net_layer *layer, net_buffer *buffer) // -------------------------------------------------- -static net_layer * new_layer(const char *name, net_layer_module_info *module, void *cookie) +static net_layer * new_layer(const char *name, const char *type, int priority, + net_layer_module_info *module, void *cookie) { net_layer *layer; @@ -349,9 +378,24 @@ static net_layer * new_layer(const char *name, net_layer_module_info *module, vo if (! layer) return NULL; - layer->name = strdup(name); - layer->module = module; - layer->cookie = cookie; + layer->name = strdup(name); + + if (type) { + char *tmp, *t, *n; + + tmp = strdup(type); + t = strtok_r(tmp, "/", &n); + layer->type = (t ? strdup(t) : joker_type); + t = strtok_r(NULL, " ", &n); + layer->sub_type = (t ? strdup(t) : joker_type); + free(tmp); + } else + layer->type = layer->sub_type = NULL; + + + layer->priority = priority; + layer->module = module; + layer->cookie = cookie; layer->layers_above = NULL; layer->layers_below = NULL; @@ -372,6 +416,11 @@ static status_t delete_layer(net_layer *layer) if (layer->name) free(layer->name); + if (layer->type && layer->type != joker_type) + free(layer->type); + if (layer->sub_type && layer->type != joker_type) + free(layer->sub_type); + if (layer->layers_above) free(layer->layers_above); if (layer->layers_below) 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 015210ac1d..0933863c44 100644 --- a/src/tests/kits/net/new_stack/stack/layers_manager.h +++ b/src/tests/kits/net/new_stack/stack/layers_manager.h @@ -14,18 +14,18 @@ extern "C" { extern status_t start_layers_manager(); extern status_t stop_layers_manager(); -extern status_t register_layer(const char *name, net_layer_module_info *module, void *cookie, - net_layer **me); +extern status_t register_layer(const char *name, const char *type, int priority, + net_layer_module_info *module, void *cookie, net_layer **layer); extern status_t unregister_layer(net_layer *layer); extern net_layer * find_layer(const char *name); -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 add_layer_attribute(net_layer *layer, const void *id, int type, ...); +extern status_t remove_layer_attribute(net_layer *layer, const void *id); +extern status_t find_layer_attribute(net_layer *layer, const void *id, + int *type, void **attribute, 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); +extern status_t send_up(net_layer *me, struct net_buffer *buffer); +extern status_t send_down(net_layer *me, struct net_buffer *buffer); #ifdef __cplusplus diff --git a/src/tests/kits/net/new_stack/stack/stack.c b/src/tests/kits/net/new_stack/stack/stack.c index bc5c94bd87..f2f699468e 100644 --- a/src/tests/kits/net/new_stack/stack/stack.c +++ b/src/tests/kits/net/new_stack/stack/stack.c @@ -11,11 +11,14 @@ #include "net_stack.h" #include "memory_pool.h" +#include "attribute.h" #include "layers_manager.h" #include "buffer.h" #include "timer.h" +#include "dump.h" + +memory_pool_module_info *g_memory_pool = NULL; -struct memory_pool_module_info *g_memory_pool = NULL; static bool g_started = false; status_t std_ops(int32 op, ...); @@ -29,14 +32,14 @@ static status_t start(void) if (g_started) return B_OK; - puts("stack: starting..."); + dprintf("stack: starting...\n"); start_buffers_service(); start_timers_service(); start_layers_manager(); - puts("stack: started."); + dprintf("stack: started.\n"); g_started = true; return B_OK; @@ -44,7 +47,7 @@ static status_t start(void) static status_t stop(void) { - puts("stack: stopping..."); + dprintf("stack: stopping...\n"); stop_layers_manager(); @@ -52,12 +55,13 @@ static status_t stop(void) stop_buffers_service(); - puts("stack: stopped."); + dprintf("stack: stopped.\n"); g_started = false; return 0; } + // #pragma mark - struct net_stack_module_info nsmi = { @@ -67,19 +71,23 @@ struct net_stack_module_info nsmi = { std_ops }, + // Global stack control start, stop, + + // Attributs IDs + register_attribute_id, // Layers handling register_layer, unregister_layer, find_layer, - add_layer_attribut, - remove_layer_attribut, - find_layer_attribut, + add_layer_attribute, + remove_layer_attribute, + find_layer_attribute, - push_buffer_up, - push_buffer_down, + send_up, + send_down, // net_buffer support new_buffer, @@ -96,9 +104,9 @@ struct net_stack_module_info nsmi = { read_buffer, write_buffer, - add_buffer_attribut, - remove_buffer_attribut, - find_buffer_attribut, + add_buffer_attribute, + remove_buffer_attribute, + find_buffer_attribute, dump_buffer, @@ -114,7 +122,10 @@ struct net_stack_module_info nsmi = { delete_net_timer, start_net_timer, cancel_net_timer, - net_timer_appointment + net_timer_appointment, + + // Misc. + dump_memory }; status_t std_ops(int32 op, ...) @@ -123,11 +134,13 @@ status_t std_ops(int32 op, ...) switch(op) { case B_MODULE_INIT: - printf("stack: B_MODULE_INIT\n"); + dprintf("stack: B_MODULE_INIT\n"); load_driver_symbols("stack"); status = get_module(MEMORY_POOL_MODULE_NAME, (module_info **) &g_memory_pool); - if (status != B_OK) + if (status != B_OK) { + dprintf("stack: Can't load " MEMORY_POOL_MODULE_NAME " module!\n"); return status; + }; // Re-publish memory_pool module api thru our nsmi.new_pool = g_memory_pool->new_pool; @@ -138,8 +151,7 @@ status_t std_ops(int32 op, ...) break; case B_MODULE_UNINIT: - // the stack is keeping loaded, so don't stop it - printf("stack: B_MODULE_UNINIT\n"); + dprintf("stack: B_MODULE_UNINIT\n"); put_module(MEMORY_POOL_MODULE_NAME); break; diff --git a/src/tests/kits/net/new_stack/stack/stack_module_x86.proj b/src/tests/kits/net/new_stack/stack/stack_module_x86.proj index 2e218fa059..149149c0f4 100644 Binary files a/src/tests/kits/net/new_stack/stack/stack_module_x86.proj and b/src/tests/kits/net/new_stack/stack/stack_module_x86.proj differ