2015-03-31 08:07:41 +02:00
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "itemstore.h"
|
2015-04-07 07:42:36 +02:00
|
|
|
#include "capwap.h"
|
2015-03-31 08:07:41 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static inline void cw_itemstore_del_data(void *e)
|
|
|
|
{
|
2015-04-05 02:07:59 +02:00
|
|
|
struct cw_item *item = (struct cw_item *) e;
|
2015-04-10 17:14:55 +02:00
|
|
|
|
2015-04-05 02:07:59 +02:00
|
|
|
switch (item->type) {
|
|
|
|
case CW_ITEMTYPE_DATA:
|
|
|
|
case CW_ITEMTYPE_STR:
|
|
|
|
case CW_ITEMTYPE_BSTR:
|
2015-04-07 07:42:36 +02:00
|
|
|
case CW_ITEMTYPE_BSTR16:
|
|
|
|
case CW_ITEMTYPE_VENDORSTR:
|
2015-04-05 02:07:59 +02:00
|
|
|
case CW_ITEMTYPE_FUN:
|
|
|
|
free(item->data);
|
|
|
|
break;
|
|
|
|
case CW_ITEMTYPE_AVLTREE:
|
|
|
|
avltree_destroy(item->data);
|
|
|
|
}
|
2015-03-31 08:07:41 +02:00
|
|
|
}
|
|
|
|
|
2015-04-05 02:07:59 +02:00
|
|
|
static void cw_itemstore_del(void *e)
|
2015-03-31 08:07:41 +02:00
|
|
|
{
|
|
|
|
|
|
|
|
cw_itemstore_del_data(e);
|
2015-04-05 02:07:59 +02:00
|
|
|
free(e);
|
2015-03-31 08:07:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-04-05 02:07:59 +02:00
|
|
|
static int cw_itemstore_cmp(const void *x1, const void *x2)
|
2015-03-31 08:07:41 +02:00
|
|
|
{
|
2015-04-05 02:07:59 +02:00
|
|
|
return ((struct cw_item *) x1)->id - ((struct cw_item *) x2)->id;
|
2015-03-31 08:07:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cw_itemstore_t cw_itemstore_create()
|
|
|
|
{
|
2015-04-05 02:07:59 +02:00
|
|
|
return avltree_create(cw_itemstore_cmp, cw_itemstore_del);
|
2015-03-31 08:07:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-04-05 02:07:59 +02:00
|
|
|
struct cw_item *cw_item_create(cw_itemstore_t s, uint32_t id)
|
2015-03-31 08:07:41 +02:00
|
|
|
{
|
|
|
|
struct cw_item is;
|
2015-04-05 02:07:59 +02:00
|
|
|
is.id = id;
|
2015-03-31 08:07:41 +02:00
|
|
|
|
2015-04-05 02:07:59 +02:00
|
|
|
struct cw_item *i = avltree_get(s, &is);
|
2015-03-31 08:07:41 +02:00
|
|
|
if (i) {
|
|
|
|
cw_itemstore_del_data(i);
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = malloc(sizeof(struct cw_item));
|
|
|
|
if (!i)
|
|
|
|
return 0;
|
2015-04-05 02:07:59 +02:00
|
|
|
i->id = id;
|
|
|
|
return avltree_add(s, i);
|
2015-03-31 08:07:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-04-05 02:07:59 +02:00
|
|
|
int cw_itemstore_set_byte(cw_itemstore_t s, uint32_t id, uint8_t byte)
|
2015-03-31 08:07:41 +02:00
|
|
|
{
|
2015-04-05 02:07:59 +02:00
|
|
|
struct cw_item *i = cw_item_create(s, id);
|
2015-03-31 08:07:41 +02:00
|
|
|
if (!i)
|
|
|
|
return 0;
|
2015-04-05 02:07:59 +02:00
|
|
|
i->byte = byte;
|
|
|
|
i->type = CW_ITEMTYPE_BYTE;
|
2015-03-31 08:07:41 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-04-05 02:07:59 +02:00
|
|
|
int cw_itemstore_set_word(cw_itemstore_t s, uint32_t id, uint32_t word)
|
2015-03-31 08:07:41 +02:00
|
|
|
{
|
2015-04-05 02:07:59 +02:00
|
|
|
struct cw_item *i = cw_item_create(s, id);
|
2015-03-31 08:07:41 +02:00
|
|
|
if (!i)
|
|
|
|
return 0;
|
2015-04-05 02:07:59 +02:00
|
|
|
i->word = word;
|
|
|
|
i->type = CW_ITEMTYPE_WORD;
|
2015-03-31 08:07:41 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-04-05 02:07:59 +02:00
|
|
|
int cw_itemstore_set_dword(cw_itemstore_t s, uint32_t id, uint32_t dword)
|
2015-03-31 08:07:41 +02:00
|
|
|
{
|
2015-04-05 02:07:59 +02:00
|
|
|
struct cw_item *i = cw_item_create(s, id);
|
2015-03-31 08:07:41 +02:00
|
|
|
if (!i)
|
|
|
|
return 0;
|
2015-04-10 17:14:55 +02:00
|
|
|
|
2015-04-05 02:07:59 +02:00
|
|
|
i->dword = dword;
|
|
|
|
i->type = CW_ITEMTYPE_DWORD;
|
2015-03-31 08:07:41 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-04-05 02:07:59 +02:00
|
|
|
int cw_itemstore_set_str(cw_itemstore_t s, uint32_t id, const char *str)
|
2015-03-31 08:07:41 +02:00
|
|
|
{
|
2015-04-05 02:07:59 +02:00
|
|
|
struct cw_item *i = cw_item_create(s, id);
|
2015-03-31 08:07:41 +02:00
|
|
|
if (!i)
|
|
|
|
return 0;
|
2015-04-05 02:07:59 +02:00
|
|
|
i->type = CW_ITEMTYPE_STR;
|
|
|
|
i->data = strdup(str);
|
2015-03-31 08:07:41 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-04-07 07:42:36 +02:00
|
|
|
int cw_itemstore_set_data(cw_itemstore_t s, uint32_t id, const uint8_t *data, int len)
|
2015-03-31 08:07:41 +02:00
|
|
|
{
|
2015-04-05 02:07:59 +02:00
|
|
|
struct cw_item *i = cw_item_create(s, id);
|
2015-03-31 08:07:41 +02:00
|
|
|
if (!i)
|
|
|
|
return 0;
|
2015-04-05 02:07:59 +02:00
|
|
|
i->type = CW_ITEMTYPE_DATA;
|
2015-04-07 07:42:36 +02:00
|
|
|
i->data = malloc(len);
|
|
|
|
if(!i->data)
|
|
|
|
return 1;
|
|
|
|
memcpy(i->data,data,len);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int cw_itemstore_set_strn(cw_itemstore_t s, uint32_t id, const char *str, int n)
|
|
|
|
{
|
|
|
|
struct cw_item *i = cw_item_create(s, id);
|
|
|
|
if (!i)
|
|
|
|
return 0;
|
|
|
|
i->type = CW_ITEMTYPE_STR;
|
2015-04-05 02:07:59 +02:00
|
|
|
i->data = strndup(str, n);
|
2015-03-31 08:07:41 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-04-05 02:07:59 +02:00
|
|
|
int cw_itemstore_set_ptr(cw_itemstore_t s, uint32_t id, void *ptr)
|
2015-03-31 19:26:25 +02:00
|
|
|
{
|
2015-04-05 02:07:59 +02:00
|
|
|
struct cw_item *i = cw_item_create(s, id);
|
2015-03-31 19:26:25 +02:00
|
|
|
if (!i)
|
|
|
|
return 0;
|
2015-04-05 02:07:59 +02:00
|
|
|
i->type = CW_ITEMTYPE_DATA;
|
|
|
|
i->data = ptr;
|
2015-03-31 19:26:25 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-04-10 21:44:05 +02:00
|
|
|
cw_item_t * cw_itemstore_set_bstrn(cw_itemstore_t s, uint32_t id, uint8_t * data, int len)
|
2015-03-31 19:26:25 +02:00
|
|
|
{
|
2015-04-05 02:07:59 +02:00
|
|
|
struct cw_item *i = cw_item_create(s, id);
|
2015-03-31 19:26:25 +02:00
|
|
|
if (!i)
|
2015-04-10 21:44:05 +02:00
|
|
|
return NULL;
|
2015-04-05 02:07:59 +02:00
|
|
|
i->type = CW_ITEMTYPE_BSTR;
|
|
|
|
i->data = bstr_create(data, len);
|
2015-04-10 21:44:05 +02:00
|
|
|
return i;
|
2015-03-31 19:26:25 +02:00
|
|
|
}
|
|
|
|
|
2015-04-07 07:42:36 +02:00
|
|
|
int cw_itemstore_set_bstr16n(cw_itemstore_t s, uint32_t id, uint8_t * data, int len)
|
|
|
|
{
|
|
|
|
struct cw_item *i = cw_item_create(s, id);
|
|
|
|
if (!i)
|
|
|
|
return 0;
|
|
|
|
i->type = CW_ITEMTYPE_BSTR16;
|
|
|
|
i->data = bstr16_create(data, len);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-04-05 02:07:59 +02:00
|
|
|
|
2015-04-13 11:00:46 +02:00
|
|
|
cw_item_t * cw_itemstore_set_const_ptr(cw_itemstore_t s, uint32_t id, void *ptr)
|
2015-03-31 19:26:25 +02:00
|
|
|
{
|
2015-04-05 02:07:59 +02:00
|
|
|
struct cw_item *i = cw_item_create(s, id);
|
2015-03-31 19:26:25 +02:00
|
|
|
if (!i)
|
|
|
|
return 0;
|
2015-04-05 02:07:59 +02:00
|
|
|
i->type = CW_ITEMTYPE_CONST_DATA;
|
|
|
|
i->data = ptr;
|
2015-04-13 11:00:46 +02:00
|
|
|
return i;
|
2015-03-31 19:26:25 +02:00
|
|
|
}
|
2015-04-05 02:07:59 +02:00
|
|
|
|
2015-04-07 07:42:36 +02:00
|
|
|
int cw_itemstore_set_vendorstr(cw_itemstore_t s, uint32_t id, uint32_t vendor_id,
|
|
|
|
uint8_t * vendorstr, int len)
|
2015-04-05 02:07:59 +02:00
|
|
|
{
|
|
|
|
struct cw_item *i = cw_item_create(s, id);
|
|
|
|
if (!i)
|
2015-03-31 08:07:41 +02:00
|
|
|
return 0;
|
2015-04-07 07:42:36 +02:00
|
|
|
|
|
|
|
i->type = CW_ITEMTYPE_VENDORSTR;
|
|
|
|
i->data = vendorstr_create(vendor_id,vendorstr,len);
|
2015-04-05 02:07:59 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int cw_itemstore_set_avltree(cw_itemstore_t s, uint32_t id, struct avltree *t)
|
2015-03-31 08:07:41 +02:00
|
|
|
{
|
2015-04-05 02:07:59 +02:00
|
|
|
struct cw_item *i = cw_item_create(s, id);
|
|
|
|
if (!i)
|
|
|
|
return 0;
|
|
|
|
i->type = CW_ITEMTYPE_AVLTREE;
|
|
|
|
i->data = t;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-03-31 08:07:41 +02:00
|
|
|
|
2015-04-05 02:07:59 +02:00
|
|
|
struct cw_item_fundef {
|
|
|
|
void *(*get) (void *arg);
|
|
|
|
void (*free) (void *arg, void *data);
|
|
|
|
void *arg;
|
|
|
|
};
|
|
|
|
|
|
|
|
int cw_itemstore_set_fun(cw_itemstore_t s, uint32_t id,
|
|
|
|
void *(*funget) (void *arg),
|
|
|
|
void (*funfree) (void *arg, void *data), void *arg)
|
|
|
|
{
|
|
|
|
struct cw_item *i = cw_item_create(s, id);
|
|
|
|
if (!i)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
struct cw_item_fundef *fundef = malloc(sizeof(struct cw_item_fundef));
|
|
|
|
i->data = fundef;
|
|
|
|
if (!fundef)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
fundef->get = funget;
|
|
|
|
fundef->free = funfree;
|
|
|
|
fundef->arg = arg;
|
|
|
|
i->type=CW_ITEMTYPE_FUN;
|
|
|
|
|
|
|
|
return 1;
|
2015-03-31 08:07:41 +02:00
|
|
|
}
|
|
|
|
|
2015-04-05 02:07:59 +02:00
|
|
|
void *cw_item_get_data_ptr(struct cw_item *item)
|
|
|
|
{
|
|
|
|
switch (item->type) {
|
|
|
|
case CW_ITEMTYPE_FUN:
|
|
|
|
{
|
|
|
|
struct cw_item_fundef *fundef =
|
|
|
|
(struct cw_item_fundef *) item->data;
|
|
|
|
if (!fundef)
|
|
|
|
return NULL;
|
|
|
|
return fundef->get(fundef->arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return item->data;
|
|
|
|
}
|
2015-03-31 08:07:41 +02:00
|
|
|
|
|
|
|
|
2015-04-05 02:07:59 +02:00
|
|
|
void cw_item_release_data_ptr(struct cw_item *item, void *data)
|
|
|
|
{
|
|
|
|
switch (item->type) {
|
|
|
|
case CW_ITEMTYPE_FUN:
|
|
|
|
{
|
|
|
|
struct cw_item_fundef *fundef =
|
|
|
|
(struct cw_item_fundef *) item->data;
|
|
|
|
if (!fundef)
|
|
|
|
return;
|
|
|
|
if (!fundef->free)
|
|
|
|
return;
|
|
|
|
|
|
|
|
return fundef->free(fundef->arg, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2015-04-07 07:42:36 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int cw_itemstore_set(cw_itemstore_t itemstore, uint32_t item_id, int item_type, uint8_t *data, int len)
|
|
|
|
{
|
|
|
|
switch (item_type) {
|
|
|
|
case CW_ITEMTYPE_BYTE:
|
|
|
|
cw_itemstore_set_byte(itemstore,item_id,*data);
|
|
|
|
break;
|
2015-04-10 17:14:55 +02:00
|
|
|
case CW_ITEMTYPE_WORD:
|
|
|
|
cw_itemstore_set_word(itemstore,item_id,*data);
|
|
|
|
break;
|
|
|
|
case CW_ITEMTYPE_DWORD:
|
|
|
|
cw_itemstore_set_dword(itemstore,item_id,*data);
|
|
|
|
break;
|
2015-04-07 07:42:36 +02:00
|
|
|
case CW_ITEMTYPE_STR:
|
|
|
|
cw_itemstore_set_strn(itemstore,item_id,(char*)data,len);
|
|
|
|
break;
|
|
|
|
case CW_ITEMTYPE_BSTR:
|
|
|
|
cw_itemstore_set_bstrn(itemstore,item_id,data,len);
|
|
|
|
break;
|
|
|
|
case CW_ITEMTYPE_DATA:
|
|
|
|
cw_itemstore_set_data(itemstore,item_id,data,len);
|
|
|
|
break;
|
|
|
|
case CW_ITEMTYPE_VENDORSTR:
|
|
|
|
cw_itemstore_set_vendorstr(itemstore,item_id,
|
|
|
|
cw_get_dword(data),data+4,len-4);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|