Attributes support evolution. Now layers support attributes too.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6419 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
4d61634cbe
commit
313aa5fc08
@ -40,10 +40,10 @@ struct net_layer_module_info nlmi;
|
||||
|
||||
static struct net_stack_module_info *g_stack = NULL;
|
||||
|
||||
net_attribute_id ethernet_header_attr;
|
||||
net_attribute_id ethernet_from_attr;
|
||||
net_attribute_id ethernet_to_attr;
|
||||
net_attribute_id ethernet_protocol_attr;
|
||||
string_token ethernet_header_attr;
|
||||
string_token ethernet_from_attr;
|
||||
string_token ethernet_to_attr;
|
||||
string_token ethernet_protocol_attr;
|
||||
|
||||
|
||||
static void dump_ethernet(net_buffer *buffer)
|
||||
@ -105,7 +105,7 @@ static status_t process_input(net_layer *me, net_buffer *buffer)
|
||||
// strip ethernet header
|
||||
g_stack->remove_from_buffer(buffer, 0, 14);
|
||||
|
||||
return g_stack->send_up(me, buffer);
|
||||
return g_stack->send_layers_up(me, buffer);
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,6 +16,23 @@ extern "C" {
|
||||
// String tokens use here and there by stack components
|
||||
typedef const void *string_token;
|
||||
|
||||
// Networking attribute(s) definition
|
||||
typedef struct net_attribute net_attribute;
|
||||
|
||||
#define NET_ATTRIBUTE_TYPE_MASK 0xFF // Up to 256 basic types
|
||||
#define NET_ATTRIBUTE_FLAGS_MASK 0xFFFFFF00
|
||||
enum {
|
||||
NET_ATTRIBUTE_BOOL = 1, // ... = bool value
|
||||
NET_ATTRIBUTE_BYTE, // ... = uint8 value
|
||||
NET_ATTRIBUTE_INT16, // ... = uint16 value
|
||||
NET_ATTRIBUTE_INT32, // ... = uint32 value
|
||||
NET_ATTRIBUTE_INT64, // ... = uint64 value
|
||||
NET_ATTRIBUTE_DATA, // ... = void *data, size_t data_len
|
||||
NET_ATTRIBUTE_STRING, // ... = char *string
|
||||
NET_ATTRIBUTE_POINTER, // ... = void *ptr
|
||||
NET_ATTRIBUTE_IOVEC // ... = int nb, iovec *vec
|
||||
};
|
||||
|
||||
// Networking buffer(s) definition
|
||||
typedef struct net_buffer net_buffer;
|
||||
typedef struct net_buffer_queue net_buffer_queue;
|
||||
@ -63,25 +80,9 @@ struct net_layer {
|
||||
uint32 use_count;
|
||||
struct net_layer **layers_above;
|
||||
struct net_layer **layers_below;
|
||||
struct net_attribute *attributes; // layer attributes
|
||||
};
|
||||
|
||||
typedef string_token net_attribute_id;
|
||||
|
||||
#define NET_ATTRIBUTE_TYPE_MASK 0xFF // Up to 256 basic types
|
||||
#define NET_ATTRIBUTE_FLAGS_MASK 0xFFFFFF00
|
||||
enum {
|
||||
NET_ATTRIBUTE_BOOL,
|
||||
NET_ATTRIBUTE_BYTE,
|
||||
NET_ATTRIBUTE_INT16,
|
||||
NET_ATTRIBUTE_INT32,
|
||||
NET_ATTRIBUTE_INT64,
|
||||
NET_ATTRIBUTE_DATA,
|
||||
NET_ATTRIBUTE_STRING,
|
||||
NET_ATTRIBUTE_POINTER,
|
||||
NET_ATTRIBUTE_IOVEC
|
||||
};
|
||||
|
||||
|
||||
// Network stack main module definition
|
||||
|
||||
struct net_stack_module_info {
|
||||
@ -108,13 +109,13 @@ struct net_stack_module_info {
|
||||
status_t (*unregister_layer)(net_layer *layer);
|
||||
net_layer * (*find_layer)(const char *name);
|
||||
|
||||
status_t (*add_layer_attribute)(net_layer *layer, net_attribute_id id, int type, ...);
|
||||
status_t (*remove_layer_attribute)(net_layer *layer, net_attribute_id id);
|
||||
status_t (*find_layer_attribute)(net_layer *layer, net_attribute_id id,
|
||||
status_t (*add_layer_attribute)(net_layer *layer, string_token id, int type, ...);
|
||||
status_t (*remove_layer_attribute)(net_layer *layer, string_token id, int index);
|
||||
status_t (*find_layer_attribute)(net_layer *layer, string_token id, int index,
|
||||
int *type, void **value, size_t *size);
|
||||
|
||||
status_t (*send_up)(net_layer *me, net_buffer *buffer);
|
||||
status_t (*send_down)(net_layer *me, net_buffer *buffer);
|
||||
status_t (*send_layers_up)(net_layer *me, net_buffer *buffer);
|
||||
status_t (*send_layers_down)(net_layer *me, net_buffer *buffer);
|
||||
|
||||
/*
|
||||
* Buffer(s) support
|
||||
@ -132,20 +133,20 @@ struct net_stack_module_info {
|
||||
// specials offsets for add_to_buffer()
|
||||
#define BUFFER_BEGIN 0
|
||||
#define BUFFER_END 0xFFFFFFFF
|
||||
status_t (*add_to_buffer)(net_buffer *buffer, uint32 offset, const void *data, uint32 bytes, buffer_chunk_free_func freethis);
|
||||
status_t (*remove_from_buffer)(net_buffer *buffer, uint32 offset, uint32 bytes);
|
||||
status_t (*add_to_buffer)(net_buffer *buffer, uint32 offset, const void *data, size_t bytes, buffer_chunk_free_func freethis);
|
||||
status_t (*remove_from_buffer)(net_buffer *buffer, uint32 offset, size_t bytes);
|
||||
|
||||
status_t (*attach_buffer_free_element)(net_buffer *buffer, void *arg1, void *arg2, buffer_chunk_free_func freethis);
|
||||
|
||||
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);
|
||||
size_t (*read_buffer)(net_buffer *buffer, uint32 offset, void *data, size_t bytes);
|
||||
size_t (*write_buffer)(net_buffer *buffer, uint32 offset, const void *data, size_t bytes);
|
||||
|
||||
// Flags to combine with
|
||||
#define FROM_BUFFER 0x010000
|
||||
#define FROM_BUFFER 0x010000 // ... = int offset, int size
|
||||
#define NETWORK_ORDER 0x020000
|
||||
status_t (*add_buffer_attribute)(net_buffer *buffer, net_attribute_id id, int type, ...);
|
||||
status_t (*remove_buffer_attribute)(net_buffer *buffer, net_attribute_id id);
|
||||
status_t (*find_buffer_attribute)(net_buffer *buffer, net_attribute_id id,
|
||||
status_t (*add_buffer_attribute)(net_buffer *buffer, string_token id, int type, ...);
|
||||
status_t (*remove_buffer_attribute)(net_buffer *buffer, string_token id, int index);
|
||||
status_t (*find_buffer_attribute)(net_buffer *buffer, string_token id, int index,
|
||||
int *type, void **value, size_t *size);
|
||||
|
||||
void (*dump_buffer)(net_buffer *buffer);
|
||||
@ -169,7 +170,7 @@ struct net_stack_module_info {
|
||||
// Lockers
|
||||
|
||||
// Misc.
|
||||
void (*dump_memory)(const char *prefix, const void *data, uint32 len);
|
||||
void (*dump_memory)(const char *prefix, const void *data, size_t len);
|
||||
|
||||
// Memory Pools support
|
||||
memory_pool * (*new_pool)(size_t node_size, uint32 node_count);
|
||||
|
@ -275,7 +275,7 @@ status_t device_reader(void *args)
|
||||
g_stack->add_to_buffer(buffer, 0, frame, sz, (buffer_chunk_free_func) free);
|
||||
|
||||
dprintf("%s: input packet %p:\n", me->name, buffer);
|
||||
if (g_stack->send_up(me, buffer) != B_OK) {
|
||||
if (g_stack->send_layers_up(me, buffer) != B_OK) {
|
||||
// nobody above us *eat* this packet, so we drop it ourself :-(
|
||||
dprintf("%s: okay, nobody cares about this input packet %p: deletion!\n", me->name, buffer);
|
||||
g_stack->dump_buffer(buffer);
|
||||
|
@ -43,7 +43,7 @@ static status_t process_output(net_layer *me, net_buffer *buffer)
|
||||
return B_ERROR;
|
||||
|
||||
// Here the magical loopback effect ;-)
|
||||
return g_stack->send_up(me, buffer);
|
||||
return g_stack->send_layers_up(me, buffer);
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
@ -16,7 +16,7 @@ struct net_layer_module_info nlmi;
|
||||
|
||||
static struct net_stack_module_info *g_stack = NULL;
|
||||
|
||||
net_attribute_id ethernet_protocol_attr;
|
||||
string_token ethernet_protocol_attr;
|
||||
|
||||
typedef struct ethernet_addr {
|
||||
uint8 byte[6];
|
||||
@ -134,7 +134,7 @@ static status_t process_input(net_layer *me, net_buffer *buffer)
|
||||
if (!buffer)
|
||||
return B_ERROR;
|
||||
|
||||
if (g_stack->find_buffer_attribute(buffer, ethernet_protocol_attr, NULL, (void **) &protocol, NULL) != B_OK)
|
||||
if (g_stack->find_buffer_attribute(buffer, ethernet_protocol_attr, 0, NULL, (void **) &protocol, NULL) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
if (*protocol != htons(0x0806)) // ARP on Ethernet protocol value
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
typedef struct ipv4_addr {
|
||||
uint8 byte[4];
|
||||
} ipv4_addr;
|
||||
} _PACKED ipv4_addr;
|
||||
|
||||
|
||||
typedef struct ipv4_header {
|
||||
@ -43,7 +43,7 @@ status_t std_ops(int32 op, ...);
|
||||
struct net_layer_module_info nlmi;
|
||||
|
||||
static struct net_stack_module_info *g_stack = NULL;
|
||||
net_attribute_id ethernet_protocol_attr;
|
||||
string_token ethernet_protocol_attr;
|
||||
static uint32 g_next_ipv4_id = 0;
|
||||
|
||||
static void dump_ipv4_header(net_buffer *buffer)
|
||||
@ -109,7 +109,7 @@ static status_t process_input(net_layer *me, net_buffer *buffer)
|
||||
if (!buffer)
|
||||
return B_ERROR;
|
||||
|
||||
if (g_stack->find_buffer_attribute(buffer, ethernet_protocol_attr, NULL, (void **) &protocol, NULL) != B_OK)
|
||||
if (g_stack->find_buffer_attribute(buffer, ethernet_protocol_attr, 0, NULL, (void **) &protocol, NULL) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
if (*protocol != htons(0x0800)) // IPv4 on Ethernet protocol value
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <iovec.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <OS.h>
|
||||
@ -17,14 +18,80 @@
|
||||
static memory_pool *g_attributes_pool = NULL;
|
||||
extern memory_pool_module_info *g_memory_pool;
|
||||
|
||||
|
||||
// Privates prototypes
|
||||
// -------------------
|
||||
|
||||
// LET'S GO FOR IMPLEMENTATION
|
||||
// ------------------------------------
|
||||
|
||||
net_attribute * new_attribute(net_attribute **in_list, const void *id)
|
||||
status_t add_attribute(net_attribute **in_list, string_token id, int type, va_list args)
|
||||
{
|
||||
net_attribute *attr;
|
||||
|
||||
attr = new_attribute(in_list, id);
|
||||
if (! attr)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
attr->type = type;
|
||||
switch(type & NET_ATTRIBUTE_TYPE_MASK) {
|
||||
case NET_ATTRIBUTE_BOOL:
|
||||
attr->u.boolean = va_arg(args, bool);
|
||||
break;
|
||||
|
||||
case NET_ATTRIBUTE_BYTE:
|
||||
attr->u.byte = va_arg(args, uint8);
|
||||
break;
|
||||
|
||||
case NET_ATTRIBUTE_INT16:
|
||||
attr->u.word = va_arg(args, uint16);
|
||||
break;
|
||||
|
||||
case NET_ATTRIBUTE_INT32:
|
||||
attr->u.dword = va_arg(args, uint32);
|
||||
break;
|
||||
|
||||
case NET_ATTRIBUTE_INT64:
|
||||
attr->u.ddword = va_arg(args, uint64);
|
||||
break;
|
||||
|
||||
case NET_ATTRIBUTE_DATA:
|
||||
{ // void *data, size_t data_len
|
||||
void *data = va_arg(args, void *);
|
||||
size_t sz = va_arg(args, size_t);
|
||||
|
||||
if (sz > MAX_ATTRIBUTE_DATA_LEN)
|
||||
sz = MAX_ATTRIBUTE_DATA_LEN;
|
||||
|
||||
memcpy(attr->u.data, data, sz);
|
||||
break;
|
||||
}
|
||||
|
||||
case NET_ATTRIBUTE_STRING:
|
||||
strncpy(attr->u.data, va_arg(args, char *), MAX_ATTRIBUTE_DATA_LEN);
|
||||
break;
|
||||
|
||||
case NET_ATTRIBUTE_POINTER:
|
||||
// NB: data behind pointer ARE NOT copied
|
||||
attr->u.ptr = va_arg(args, void *);
|
||||
break;
|
||||
|
||||
case NET_ATTRIBUTE_IOVEC:
|
||||
{ // int nb, iovec *vec
|
||||
int nb = va_arg(args, int);
|
||||
iovec * vec = va_arg(args, iovec *);
|
||||
if (nb > MAX_ATTRIBUTE_IOVECS)
|
||||
nb = MAX_ATTRIBUTE_IOVECS;
|
||||
|
||||
memcpy(&attr->u.vec, vec, nb * sizeof(iovec));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
net_attribute * new_attribute(net_attribute **in_list, string_token id)
|
||||
{
|
||||
net_attribute *attr;
|
||||
|
||||
@ -84,8 +151,8 @@ status_t delete_attribute(net_attribute *attr, net_attribute **from_list)
|
||||
}
|
||||
|
||||
|
||||
net_attribute * find_attribute(net_attribute *list, const void *id, int *type,
|
||||
void **value, size_t *size)
|
||||
net_attribute * find_attribute(net_attribute *list, string_token id, int index,
|
||||
int *type, void **value, size_t *size)
|
||||
{
|
||||
net_attribute *attr;
|
||||
|
||||
@ -95,7 +162,7 @@ net_attribute * find_attribute(net_attribute *list, const void *id, int *type,
|
||||
// dprintf("find_attribute(%p, %p)\n", list, id);
|
||||
attr = list;
|
||||
while (attr) {
|
||||
if (attr->id == id) {
|
||||
if (attr->id == id && index-- == 0) {
|
||||
if (type) *type = attr->type;
|
||||
if (size) *size = attr->size;
|
||||
if (value) {
|
||||
|
@ -5,8 +5,10 @@
|
||||
#ifndef OBOS_NET_STACK_ATTRIBUTE_H
|
||||
#define OBOS_NET_STACK_ATTRIBUTE_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <iovec.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include "net_stack.h"
|
||||
|
||||
@ -14,27 +16,30 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct net_attribute {
|
||||
#define MAX_ATTRIBUTE_IOVECS (16)
|
||||
#define MAX_ATTRIBUTE_DATA_LEN (256)
|
||||
|
||||
struct net_attribute {
|
||||
struct net_attribute *next;
|
||||
string_token id;
|
||||
uint32 type;
|
||||
uint32 size;
|
||||
size_t size;
|
||||
union {
|
||||
bool boolean;
|
||||
uint8 byte;
|
||||
uint16 word;
|
||||
uint32 dword;
|
||||
uint64 ddword;
|
||||
char data[256];
|
||||
char data[MAX_ATTRIBUTE_DATA_LEN]; // Beware: data max size is limited :-(
|
||||
void *ptr;
|
||||
iovec vec[16]; // Beware: 16 max :-(
|
||||
iovec vec[MAX_ATTRIBUTE_IOVECS]; // Beware: these are limited too :-(
|
||||
} u;
|
||||
} net_attribute;
|
||||
|
||||
};
|
||||
|
||||
extern status_t add_attribute(net_attribute **in_list, string_token id, int type, va_list args);
|
||||
extern net_attribute * new_attribute(net_attribute **in_list, string_token id);
|
||||
extern status_t delete_attribute(net_attribute *attribut, net_attribute **from_list);
|
||||
extern net_attribute * find_attribute(net_attribute *list, string_token id, int *type, void **value, size_t *size);
|
||||
extern net_attribute * find_attribute(net_attribute *list, string_token id, int index, int *type, void **value, size_t *size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ typedef struct net_buffer_chunk {
|
||||
struct net_buffer_chunk *next_data;
|
||||
uint32 ref_count; // this data is referenced by 'ref_count' net_buffer_chunk(s)
|
||||
const void *data; // address of data
|
||||
uint32 len; // in bytes (could be 0, with *guest* add_buffer_free_element() node
|
||||
size_t len; // in bytes (could be 0, with *guest* add_buffer_free_element() node
|
||||
buffer_chunk_free_func free_func; // if NULL, don't free it!
|
||||
void * free_cookie; // if != NULL, free_func(cookie, data) is called... otherwise, free_func(data)
|
||||
} net_buffer_chunk;
|
||||
@ -68,11 +68,11 @@ extern memory_pool_module_info *g_memory_pool;
|
||||
// Privates prototypes
|
||||
// -------------------
|
||||
|
||||
static net_buffer_chunk * new_buffer_chunk(const void *data, uint32 len);
|
||||
static net_buffer_chunk * new_buffer_chunk(const void *data, size_t len);
|
||||
static net_buffer_chunk * find_buffer_chunk(net_buffer *buffer, uint32 offset, uint32 *offset_in_chunk, net_buffer_chunk **previous_chunk);
|
||||
|
||||
static status_t prepend_buffer(net_buffer *buffer, const void *data, uint32 bytes, buffer_chunk_free_func freethis);
|
||||
static status_t append_buffer(net_buffer *buffer, const void *data, uint32 bytes, buffer_chunk_free_func freethis);
|
||||
static status_t prepend_buffer(net_buffer *buffer, const void *data, size_t bytes, buffer_chunk_free_func freethis);
|
||||
static status_t append_buffer(net_buffer *buffer, const void *data, size_t bytes, buffer_chunk_free_func freethis);
|
||||
|
||||
static int32 buffers_purgatory_thread(void * data);
|
||||
|
||||
@ -84,9 +84,6 @@ static status_t buffer_queue_killer(memory_pool * pool, void * node, void *
|
||||
// ------------------------------------
|
||||
|
||||
|
||||
// #pragma mark [Start/Stop Service functions]
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
status_t start_buffers_service()
|
||||
{
|
||||
@ -138,7 +135,7 @@ status_t stop_buffers_service()
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark [Public functions]
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
@ -320,7 +317,7 @@ status_t attach_buffer_free_element(net_buffer *buffer, void *arg1, void *arg2,
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
status_t add_to_buffer(net_buffer *buffer, uint32 offset, const void *data, uint32 bytes, buffer_chunk_free_func freethis)
|
||||
status_t add_to_buffer(net_buffer *buffer, uint32 offset, const void *data, size_t bytes, buffer_chunk_free_func freethis)
|
||||
{
|
||||
net_buffer_chunk *previous_chunk;
|
||||
net_buffer_chunk *next_chunk;
|
||||
@ -405,7 +402,7 @@ error1:
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
status_t remove_from_buffer(net_buffer *buffer, uint32 offset, uint32 bytes)
|
||||
status_t remove_from_buffer(net_buffer *buffer, uint32 offset, size_t bytes)
|
||||
{
|
||||
net_buffer_chunk *first_chunk;
|
||||
net_buffer_chunk *last_chunk;
|
||||
@ -474,12 +471,12 @@ status_t remove_from_buffer(net_buffer *buffer, uint32 offset, uint32 bytes)
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
uint32 read_buffer(net_buffer *buffer, uint32 offset, void *data, uint32 bytes)
|
||||
size_t read_buffer(net_buffer *buffer, uint32 offset, void *data, size_t bytes)
|
||||
{
|
||||
net_buffer_chunk *chunk;
|
||||
uint32 offset_in_chunk;
|
||||
uint32 len;
|
||||
uint32 chunk_len;
|
||||
size_t len;
|
||||
size_t chunk_len;
|
||||
uint8 *from;
|
||||
uint8 *to;
|
||||
|
||||
@ -509,12 +506,12 @@ 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)
|
||||
size_t write_buffer(net_buffer *buffer, uint32 offset, const void *data, size_t bytes)
|
||||
{
|
||||
net_buffer_chunk *chunk;
|
||||
uint32 offset_in_chunk;
|
||||
uint32 len;
|
||||
uint32 chunk_len;
|
||||
size_t len;
|
||||
size_t chunk_len;
|
||||
uint8 *from;
|
||||
uint8 *to;
|
||||
|
||||
@ -545,42 +542,39 @@ uint32 write_buffer(net_buffer *buffer, uint32 offset, const void *data, uint32
|
||||
return len;
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// --------------------------------------------------
|
||||
status_t add_buffer_attribute(net_buffer *buffer, const void *id, int type, ...)
|
||||
status_t add_buffer_attribute(net_buffer *buffer, string_token id, int type, ...)
|
||||
{
|
||||
net_attribute *attr;
|
||||
|
||||
status_t status;
|
||||
va_list args;
|
||||
|
||||
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_attribute *attr;
|
||||
net_buffer_chunk *chunk;
|
||||
uint32 offset;
|
||||
uint32 offset_in_chunk;
|
||||
uint32 size;
|
||||
size_t size;
|
||||
uint8 *ptr;
|
||||
|
||||
type = (type & NET_ATTRIBUTE_FLAGS_MASK);
|
||||
|
||||
va_start(args, type);
|
||||
offset = va_arg(args, int);
|
||||
size = va_arg(args, int);
|
||||
offset = va_arg(args, uint32);
|
||||
size = va_arg(args, size_t);
|
||||
va_end(args);
|
||||
|
||||
|
||||
chunk = find_buffer_chunk(buffer, offset, &offset_in_chunk, NULL);
|
||||
if (chunk == NULL) {
|
||||
delete_attribute(attr, &buffer->attributes);
|
||||
if (chunk == NULL)
|
||||
return B_BAD_VALUE;
|
||||
};
|
||||
|
||||
attr = new_attribute(&buffer->attributes, id);
|
||||
if (! attr)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
attr->size = size;
|
||||
|
||||
if (size < chunk->len - offset_in_chunk) {
|
||||
ptr = (uint8 *) chunk->data;
|
||||
ptr += offset_in_chunk;
|
||||
@ -614,26 +608,30 @@ status_t add_buffer_attribute(net_buffer *buffer, const void *id, int type, ...)
|
||||
};
|
||||
|
||||
attr->type = type | NET_ATTRIBUTE_IOVEC;
|
||||
}
|
||||
};
|
||||
|
||||
status = B_OK;
|
||||
|
||||
} else {
|
||||
// Not implemented
|
||||
return B_ERROR;
|
||||
}
|
||||
// default attribute types
|
||||
va_start(args, type);
|
||||
status = add_attribute(&buffer->attributes, id, type, args);
|
||||
va_end(args);
|
||||
};
|
||||
|
||||
return B_OK;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
status_t remove_buffer_attribute(net_buffer *buffer, const void *id)
|
||||
status_t remove_buffer_attribute(net_buffer *buffer, string_token id, int index)
|
||||
{
|
||||
net_attribute *attr;
|
||||
|
||||
if (! buffer)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
attr = find_attribute(buffer->attributes, id, NULL, NULL, NULL);
|
||||
attr = find_attribute(buffer->attributes, id, index, NULL, NULL, NULL);
|
||||
if (! attr)
|
||||
return B_NAME_NOT_FOUND;
|
||||
|
||||
@ -641,14 +639,14 @@ status_t remove_buffer_attribute(net_buffer *buffer, const void *id)
|
||||
}
|
||||
|
||||
|
||||
status_t find_buffer_attribute(net_buffer *buffer, const void *id, int *type, void **value, size_t *size)
|
||||
status_t find_buffer_attribute(net_buffer *buffer, string_token id, int index, int *type, void **value, size_t *size)
|
||||
{
|
||||
net_attribute *attr;
|
||||
|
||||
if (! buffer)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
attr = find_attribute(buffer->attributes, id, type, value, size);
|
||||
attr = find_attribute(buffer->attributes, id, index, type, value, size);
|
||||
if (! attr)
|
||||
return B_NAME_NOT_FOUND;
|
||||
|
||||
@ -656,7 +654,7 @@ status_t find_buffer_attribute(net_buffer *buffer, const void *id, int *type, vo
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark [buffer(s) queues functions]
|
||||
// #pragma mark -
|
||||
|
||||
// --------------------------------------------------
|
||||
net_buffer_queue * new_buffer_queue(size_t max_bytes)
|
||||
@ -807,7 +805,7 @@ size_t dequeue_buffer(net_buffer_queue *queue, net_buffer **buffer, bigtime_t t
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark [Helper functions]
|
||||
// #pragma mark -
|
||||
|
||||
// --------------------------------------------------
|
||||
static net_buffer_chunk * new_buffer_chunk(const void *data, uint32 len)
|
||||
@ -979,7 +977,7 @@ void dump_buffer(net_buffer *buffer)
|
||||
|
||||
}
|
||||
|
||||
// #pragma mark [Packets Purgatory functions]
|
||||
// #pragma mark -
|
||||
|
||||
// --------------------------------------------------
|
||||
static int32 buffers_purgatory_thread(void *data)
|
||||
|
@ -25,17 +25,17 @@ extern net_buffer * clone_buffer(net_buffer *from);
|
||||
extern net_buffer * split_buffer(net_buffer *from, uint32 offset);
|
||||
extern status_t merge_buffers(net_buffer *begin, net_buffer *end);
|
||||
|
||||
extern status_t add_to_buffer(net_buffer *buffer, uint32 offset, const void *data, uint32 bytes, buffer_chunk_free_func freethis);
|
||||
extern status_t remove_from_buffer(net_buffer *buffer, uint32 offset, uint32 bytes);
|
||||
extern status_t add_to_buffer(net_buffer *buffer, uint32 offset, const void *data, size_t bytes, buffer_chunk_free_func freethis);
|
||||
extern status_t remove_from_buffer(net_buffer *buffer, uint32 offset, size_t bytes);
|
||||
|
||||
extern status_t attach_buffer_free_element(net_buffer *buffer, void *arg1, void *arg2, buffer_chunk_free_func freethis);
|
||||
|
||||
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 size_t read_buffer(net_buffer *buffer, uint32 offset, void *data, size_t bytes);
|
||||
extern size_t write_buffer(net_buffer *buffer, uint32 offset, const void *data, size_t bytes);
|
||||
|
||||
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 status_t add_buffer_attribute(net_buffer *buffer, string_token id, int type, ...);
|
||||
extern status_t remove_buffer_attribute(net_buffer *buffer, string_token id, int index);
|
||||
extern status_t find_buffer_attribute(net_buffer *buffer, string_token id, int index, int *type, void **value, size_t *size);
|
||||
|
||||
extern void dump_buffer(net_buffer *buffer);
|
||||
|
||||
|
@ -10,7 +10,7 @@ void dump_memory
|
||||
(
|
||||
const char * prefix,
|
||||
const void * data,
|
||||
uint32 len
|
||||
size_t len
|
||||
)
|
||||
{
|
||||
uint32 i,j;
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef DUMP_H
|
||||
#define DUMP_H
|
||||
|
||||
extern void dump_memory(const char *prefix, const void *data, uint32 len);
|
||||
#include <SupportDefs.h>
|
||||
|
||||
extern void dump_memory(const char *prefix, const void *data, size_t len);
|
||||
|
||||
#endif
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "memory_pool.h"
|
||||
#include "layers_manager.h"
|
||||
#include "buffer.h"
|
||||
#include "attribute.h"
|
||||
#include "stack.h" // for string_{to|for}_token()
|
||||
|
||||
struct layers_list {
|
||||
@ -31,10 +32,8 @@ static status_t delete_layer(net_layer *layer);
|
||||
|
||||
extern memory_pool_module_info *g_memory_pool;
|
||||
|
||||
string_token g_joker_token = 0;
|
||||
|
||||
// #pragma mark [Start/Stop functions]
|
||||
|
||||
string_token g_joker_token = 0;
|
||||
string_token g_layers_trace_attr = 0;
|
||||
|
||||
// --------------------------------------------------
|
||||
status_t start_layers_manager(void)
|
||||
@ -43,6 +42,7 @@ status_t start_layers_manager(void)
|
||||
net_layer *layer;
|
||||
|
||||
g_joker_token = string_to_token("*");
|
||||
g_layers_trace_attr = string_to_token("layers_trace");
|
||||
|
||||
g_layers.first = NULL;
|
||||
|
||||
@ -132,7 +132,7 @@ status_t stop_layers_manager(void)
|
||||
|
||||
|
||||
|
||||
// #pragma mark [Public functions]
|
||||
// #pragma mark -
|
||||
|
||||
// --------------------------------------------------
|
||||
status_t register_layer(const char *name, const char *type, int priority,
|
||||
@ -243,41 +243,53 @@ net_layer * find_layer(const char *name)
|
||||
return layer;
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// --------------------------------------------------
|
||||
status_t add_layer_attribute(net_layer *layer, const void *id, int type, ...)
|
||||
{
|
||||
status_t status;
|
||||
va_list args;
|
||||
|
||||
va_start(args, type);
|
||||
|
||||
switch(type) {
|
||||
case NET_ATTRIBUTE_DATA:
|
||||
// hack
|
||||
layer->cookie = va_arg(args, void *);
|
||||
break;
|
||||
}
|
||||
|
||||
status = add_attribute(&layer->attributes, id, type, args);
|
||||
va_end(args);
|
||||
|
||||
return B_OK;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------
|
||||
status_t remove_layer_attribute(net_layer *layer, const void *id)
|
||||
status_t remove_layer_attribute(net_layer *layer, const void *id, int index)
|
||||
{
|
||||
return B_ERROR;
|
||||
net_attribute *attr;
|
||||
|
||||
if (! layer)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
attr = find_attribute(layer->attributes, id, index, NULL, NULL, NULL);
|
||||
if (! attr)
|
||||
return B_NAME_NOT_FOUND;
|
||||
|
||||
return delete_attribute(attr, &layer->attributes);
|
||||
}
|
||||
|
||||
|
||||
status_t find_layer_attribute(net_layer *layer, const void *id, int *type,
|
||||
void **attribute, size_t *size)
|
||||
status_t find_layer_attribute(net_layer *layer, const void *id, int index, int *type,
|
||||
void **value, size_t *size)
|
||||
{
|
||||
*attribute = &layer->cookie;
|
||||
net_attribute *attr;
|
||||
|
||||
if (! layer)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
attr = find_attribute(layer->attributes, id, index, type, value, size);
|
||||
if (! attr)
|
||||
return B_NAME_NOT_FOUND;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// --------------------------------------------------
|
||||
status_t send_layers_up(net_layer *layer, net_buffer *buffer)
|
||||
@ -289,6 +301,8 @@ status_t send_layers_up(net_layer *layer, net_buffer *buffer)
|
||||
if (!layer)
|
||||
return B_ERROR;
|
||||
|
||||
add_buffer_attribute(buffer, g_layers_trace_attr, NET_ATTRIBUTE_STRING, layer->name),
|
||||
|
||||
status = acquire_sem(g_layers.lock);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
@ -344,10 +358,13 @@ status_t send_layers_down(net_layer *layer, net_buffer *buffer)
|
||||
if (!layer)
|
||||
return B_ERROR;
|
||||
|
||||
|
||||
// #### TODO: lock the layer(s) above & below hierarchy
|
||||
if (!layer->layers_below)
|
||||
// no layers below this one
|
||||
return B_ERROR;
|
||||
|
||||
add_buffer_attribute(buffer, g_layers_trace_attr, NET_ATTRIBUTE_STRING, layer->name),
|
||||
|
||||
status = B_ERROR;
|
||||
i = 0;
|
||||
@ -358,15 +375,17 @@ status_t send_layers_down(net_layer *layer, net_buffer *buffer)
|
||||
continue;
|
||||
|
||||
status = below->module->process_output(below, buffer);
|
||||
if (status == B_OK)
|
||||
if (status == B_OK) {
|
||||
atomic_add(&below->use_count, 1);
|
||||
// TODO: resort this layer with previous one, if required.
|
||||
return status;
|
||||
};
|
||||
};
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// #pragma mark [Private functions]
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
// --------------------------------------------------
|
||||
static net_layer * new_layer(const char *name, const char *type, int priority,
|
||||
@ -405,6 +424,8 @@ static net_layer * new_layer(const char *name, const char *type, int priority,
|
||||
|
||||
layer->layers_above = NULL;
|
||||
layer->layers_below = NULL;
|
||||
|
||||
layer->attributes = NULL;
|
||||
|
||||
return layer;
|
||||
}
|
||||
@ -427,7 +448,21 @@ static status_t delete_layer(net_layer *layer)
|
||||
free(layer->layers_above);
|
||||
if (layer->layers_below)
|
||||
free(layer->layers_below);
|
||||
|
||||
|
||||
if (layer->attributes) {
|
||||
// Free layer attributes
|
||||
|
||||
net_attribute *attr;
|
||||
net_attribute *next_attr;
|
||||
|
||||
attr = layer->attributes;
|
||||
while (attr) {
|
||||
next_attr = attr->next;
|
||||
delete_attribute(attr, NULL);
|
||||
attr = next_attr;
|
||||
};
|
||||
};
|
||||
|
||||
return g_memory_pool->delete_pool_node(g_layers_pool, layer);
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,8 @@ extern status_t unregister_layer(net_layer *layer);
|
||||
extern net_layer * find_layer(const char *name);
|
||||
|
||||
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,
|
||||
extern status_t remove_layer_attribute(net_layer *layer, const void *id, int index);
|
||||
extern status_t find_layer_attribute(net_layer *layer, const void *id, int index,
|
||||
int *type, void **attribute, size_t *size);
|
||||
|
||||
extern status_t send_layers_up(net_layer *me, struct net_buffer *buffer);
|
||||
|
Loading…
Reference in New Issue
Block a user