Draft attributes support added.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5888 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Philippe Houdoin
2004-01-03 18:20:45 +00:00
parent c110aa422b
commit c29a3f4826
10 changed files with 562 additions and 160 deletions
@@ -0,0 +1,151 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iovec.h>
#include <KernelExport.h>
#include <OS.h>
#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;
}
@@ -0,0 +1,43 @@
/* attribute.h
* private definitions for network attributes
*/
#ifndef OBOS_NET_STACK_ATTRIBUTE_H
#define OBOS_NET_STACK_ATTRIBUTE_H
#include <iovec.h>
#include <SupportDefs.h>
#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
+177 -89
View File
@@ -1,13 +1,17 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iovec.h>
#include <stdarg.h>
#include <KernelExport.h>
#include <OS.h>
#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)
+3 -3
View File
@@ -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);
+53
View File
@@ -0,0 +1,53 @@
#include <stdio.h>
#include <drivers/module.h>
#include <drivers/KernelExport.h>
// --------------------------------------------------
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
};
}
@@ -0,0 +1,6 @@
#ifndef DUMP_H
#define DUMP_H
extern void dump_memory(const char *prefix, const void *data, uint32 len);
#endif
@@ -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)
@@ -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
+30 -18
View File
@@ -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;