More work on CAPWAP VM
FossilOrigin-Name: 9d9a86d2bafe31253a6f505e874f188792539485bb4462f4d778e6c53ac3000b
This commit is contained in:
parent
ab8128a20f
commit
1158167262
@ -198,7 +198,7 @@ AP = RAD = WTP
|
|||||||
| ResetBtnState |
|
| ResetBtnState |
|
||||||
+-+-+-+-+-+-+-+-+
|
+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
Type: 128 for Cisco Rest Button State
|
Type: 128 for Cisco Reset Button State
|
||||||
Length: 1
|
Length: 1
|
||||||
|
|
||||||
ResetBtnState: 1 = Enabeled
|
ResetBtnState: 1 = Enabeled
|
||||||
|
@ -98,7 +98,13 @@ int readelem_cisco_rad_name(struct conn *conn,struct cw_action * a,uint8_t *data
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
int avlprint(void *priv, void *data)
|
||||||
|
{
|
||||||
|
struct cw_str * d = (struct cw_str*) data;
|
||||||
|
printf("String: %d - %s\n",d->id,d->str);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
int main (int argc, const char * argv[])
|
int main (int argc, const char * argv[])
|
||||||
{
|
{
|
||||||
@ -117,7 +123,19 @@ int main (int argc, const char * argv[])
|
|||||||
|
|
||||||
cw_dbg_opt_detail=DBG_DETAIL_ASC_DMP;
|
cw_dbg_opt_detail=DBG_DETAIL_ASC_DMP;
|
||||||
|
|
||||||
cw_register_actions_capwap_ac(&capwap_actions);
|
cw_register_actions_cipwap_ac(&capwap_actions);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
struct avltree *avlt = capwap_actions.strelem;
|
||||||
|
|
||||||
|
avltree_foreach_asc(avlt,avlprint,0);
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ac_global_init();
|
ac_global_init();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -353,6 +353,7 @@ static struct cwrmsg * wtpman_wait_for_message(struct wtpman * wtpman, time_t ti
|
|||||||
return cwrmsg;
|
return cwrmsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int conn_msg_processor(struct conn *conn);
|
||||||
|
|
||||||
|
|
||||||
static void wtpman_run_discovery(void *arg)
|
static void wtpman_run_discovery(void *arg)
|
||||||
@ -361,7 +362,6 @@ static void wtpman_run_discovery(void *arg)
|
|||||||
struct wtpman * wtpman = (struct wtpman *)arg;
|
struct wtpman * wtpman = (struct wtpman *)arg;
|
||||||
struct cwrmsg * cwrmsg;
|
struct cwrmsg * cwrmsg;
|
||||||
|
|
||||||
void conn_msg_processor(struct conn *conn);
|
|
||||||
|
|
||||||
time_t timer = cw_timer_start(10);
|
time_t timer = cw_timer_start(10);
|
||||||
|
|
||||||
@ -370,7 +370,6 @@ extern cw_actionlist_in_t the_tree;
|
|||||||
wtpman->conn->capwap_state=CW_STATE_DISCOVERY;
|
wtpman->conn->capwap_state=CW_STATE_DISCOVERY;
|
||||||
wtpman->conn->actions = &capwap_actions;
|
wtpman->conn->actions = &capwap_actions;
|
||||||
|
|
||||||
wtpman->conn->itemstore = cw_itemstore_create();
|
|
||||||
|
|
||||||
wtpman->conn->local = ac_config;
|
wtpman->conn->local = ac_config;
|
||||||
wtpman->conn->remote = cw_itemstore_create();
|
wtpman->conn->remote = cw_itemstore_create();
|
||||||
@ -379,6 +378,12 @@ extern cw_actionlist_in_t the_tree;
|
|||||||
conn_msg_processor(wtpman->conn);
|
conn_msg_processor(wtpman->conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct cw_item * wn = cw_itemstore_get(wtpman->conn->remote,CW_ITEM_WTP_NAME);
|
||||||
|
|
||||||
|
if (wn ) {
|
||||||
|
printf("WTP Name: %s\n",wn->data);
|
||||||
|
}
|
||||||
|
|
||||||
wtpman_remove(wtpman);
|
wtpman_remove(wtpman);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -594,16 +599,20 @@ wtpman->conn->capwap_state=CW_STATE_JOIN;
|
|||||||
wtpman->conn->capwap_state=CW_STATE_JOIN;
|
wtpman->conn->capwap_state=CW_STATE_JOIN;
|
||||||
wtpman->conn->actions = &capwap_actions;
|
wtpman->conn->actions = &capwap_actions;
|
||||||
|
|
||||||
wtpman->conn->itemstore = cw_itemstore_create();
|
// wtpman->conn->itemstore = cw_itemstore_create();
|
||||||
|
|
||||||
wtpman->conn->local = ac_config;
|
wtpman->conn->local = ac_config;
|
||||||
wtpman->conn->remote = cw_itemstore_create();
|
wtpman->conn->remote = cw_itemstore_create();
|
||||||
|
|
||||||
while ( !cw_timer_timeout(timer) && wtpman->conn->capwap_state==CW_STATE_JOIN){
|
while ( !cw_timer_timeout(timer) && wtpman->conn->capwap_state==CW_STATE_JOIN){
|
||||||
conn_msg_processor(wtpman->conn);
|
int rc = conn_msg_processor(wtpman->conn);
|
||||||
|
if (rc <0 ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
printf("Breaked\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
|
|
||||||
|
@ -169,12 +169,15 @@ CAPWAPOBJS= \
|
|||||||
capwap_strings_elem.o \
|
capwap_strings_elem.o \
|
||||||
itemstore.o \
|
itemstore.o \
|
||||||
cw_in_vendor_specific_payload.o \
|
cw_in_vendor_specific_payload.o \
|
||||||
cw_in_wtp_name.o \
|
|
||||||
cw_in_wtp_board_data.o \
|
cw_in_wtp_board_data.o \
|
||||||
cw_out_generic.o \
|
cw_out_generic.o \
|
||||||
cw_out_ac_descriptor.o \
|
cw_out_ac_descriptor.o \
|
||||||
cw_out_capwap_control_ip_addrs.o
|
cw_out_cisco_ac_descriptor.o \
|
||||||
|
cw_out_cisco_ap_timesync.o \
|
||||||
|
cw_out_capwap_control_ip_addrs.o \
|
||||||
|
strheap.o
|
||||||
|
|
||||||
|
#cw_in_wtp_name.o \
|
||||||
#cw_msgtostr.o \
|
#cw_msgtostr.o \
|
||||||
#cw_msgelemtostr.o \
|
#cw_msgelemtostr.o \
|
||||||
#cwmsg_addelem_ctrl_ip_addrs.o \
|
#cwmsg_addelem_ctrl_ip_addrs.o \
|
||||||
@ -265,6 +268,9 @@ CWACTION=action.o \
|
|||||||
cw_in_generic.o \
|
cw_in_generic.o \
|
||||||
cw_in_wtp_descriptor.o \
|
cw_in_wtp_descriptor.o \
|
||||||
cipwap_actions_ac.o \
|
cipwap_actions_ac.o \
|
||||||
|
cipwap_strings_elem.o \
|
||||||
|
cw_put_msg.o \
|
||||||
|
capwap_action_helpers.o \
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,6 +119,10 @@ static int cw_action_out_cmp(const void *elem1,const void *elem2)
|
|||||||
if (r!=0)
|
if (r!=0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
r = e1->vendor_id - e2->vendor_id;
|
||||||
|
if (r!=0)
|
||||||
|
return r;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,3 +167,6 @@ cw_action_out_t * cw_actionlist_out_add(cw_actionlist_out_t t, struct cw_action_
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "avltree.h"
|
#include "avltree.h"
|
||||||
#include "conn.h"
|
#include "conn.h"
|
||||||
#include "itemstore.h"
|
#include "itemstore.h"
|
||||||
|
#include "strheap.h"
|
||||||
|
|
||||||
|
|
||||||
/* Generic functions and structs */
|
/* Generic functions and structs */
|
||||||
@ -63,11 +64,12 @@ extern int cw_actionlist_in_register_actions(cw_actionlist_in_t t,cw_action_in_t
|
|||||||
struct cw_action_out{
|
struct cw_action_out{
|
||||||
uint32_t msg_id;
|
uint32_t msg_id;
|
||||||
uint32_t item_id;
|
uint32_t item_id;
|
||||||
|
uint32_t vendor_id;
|
||||||
uint16_t elem_id;
|
uint16_t elem_id;
|
||||||
|
|
||||||
int (*out)(struct conn * conn, uint32_t elem_id, uint8_t * dst ,struct cw_item * item);
|
int (*out)(struct conn * conn, struct cw_action_out *a, uint8_t * dst);
|
||||||
struct cw_item *(*get)(struct conn *conn,uint32_t item_id);
|
struct cw_item *(*get)(struct conn *conn,struct cw_action_out *a);
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
typedef struct cw_action_out cw_action_out_t;
|
typedef struct cw_action_out cw_action_out_t;
|
||||||
@ -84,6 +86,10 @@ extern int cw_actionlist_out_register_actions(cw_actionlist_out_t t,cw_action_ou
|
|||||||
struct cw_actiondef{
|
struct cw_actiondef{
|
||||||
cw_actionlist_in_t in;
|
cw_actionlist_in_t in;
|
||||||
cw_actionlist_out_t out;
|
cw_actionlist_out_t out;
|
||||||
|
|
||||||
|
cw_strheap_t strmsg;
|
||||||
|
cw_strheap_t strelem;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
/**
|
/**
|
||||||
* @file
|
* @file
|
||||||
* @brief Yet another AVL tree implementation
|
* @brief Yet another AVL tree implementation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -32,35 +32,36 @@
|
|||||||
* @param cmp pointer compare function
|
* @param cmp pointer compare function
|
||||||
* @param del pointer to delete function which is called when an element will be deletet
|
* @param del pointer to delete function which is called when an element will be deletet
|
||||||
* @return pointer to an #avltree struct
|
* @return pointer to an #avltree struct
|
||||||
*/
|
*/
|
||||||
struct avltree * avltree_create(int (*cmp)(const void*,const void*),void(*del)(void*))
|
struct avltree *avltree_create(int (*cmp) (const void *, const void *),
|
||||||
|
void (*del) (void *))
|
||||||
{
|
{
|
||||||
struct avltree * t = malloc(sizeof(struct avltree));
|
struct avltree *t = malloc(sizeof(struct avltree));
|
||||||
if (!t)
|
if (!t)
|
||||||
return NULL;
|
return NULL;
|
||||||
t->root=0;
|
t->root = 0;
|
||||||
t->count=0;
|
t->count = 0;
|
||||||
t->cmp=cmp;
|
t->cmp = cmp;
|
||||||
t->del=del;
|
t->del = del;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct avlnode * avlnode_create(void * data)
|
struct avlnode *avlnode_create(void *data)
|
||||||
{
|
{
|
||||||
struct avlnode * n = malloc(sizeof(struct avlnode));
|
struct avlnode *n = malloc(sizeof(struct avlnode));
|
||||||
if(!n)
|
if (!n)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
n->left=n->right=0;
|
n->left = n->right = 0;
|
||||||
n->bal=0;
|
n->bal = 0;
|
||||||
n->data = data;
|
n->data = data;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void avlnode_destroy(struct avltree *t,struct avlnode *n)
|
void avlnode_destroy(struct avltree *t, struct avlnode *n)
|
||||||
{
|
{
|
||||||
if(t->del){
|
if (t->del) {
|
||||||
t->del(n->data);
|
t->del(n->data);
|
||||||
}
|
}
|
||||||
free(n);
|
free(n);
|
||||||
@ -68,66 +69,62 @@ void avlnode_destroy(struct avltree *t,struct avlnode *n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int avltree_add0(struct avltree *t, struct avlnode ** parent, void ** data)
|
static int avltree_add0(struct avltree *t, struct avlnode **parent, void **data)
|
||||||
{
|
{
|
||||||
// struct avlnode * rn;
|
// struct avlnode * rn;
|
||||||
struct avlnode *tmp;
|
struct avlnode *tmp;
|
||||||
|
|
||||||
struct avlnode * n = *parent;
|
struct avlnode *n = *parent;
|
||||||
int rc=t->cmp(*data,n->data);
|
int rc = t->cmp(*data, n->data);
|
||||||
|
|
||||||
int bal;
|
int bal;
|
||||||
if (rc==0){
|
if (rc == 0) {
|
||||||
*data=n->data;
|
*data = n->data;
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc<0){
|
if (rc < 0) {
|
||||||
if (n->left)
|
if (n->left) {
|
||||||
{
|
bal = avltree_add0(t, &n->left, data);
|
||||||
bal = avltree_add0(t,&n->left,data);
|
if (bal > 1)
|
||||||
if (bal>1)
|
|
||||||
return bal;
|
return bal;
|
||||||
|
|
||||||
n->bal -=bal;
|
n->bal -= bal;
|
||||||
if (n->bal==0)
|
if (n->bal == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (n->bal==-2){
|
if (n->bal == -2) {
|
||||||
if (n->left->bal==-1){
|
if (n->left->bal == -1) {
|
||||||
n->bal=0;
|
n->bal = 0;
|
||||||
n->left->bal=0;
|
n->left->bal = 0;
|
||||||
*parent=n->left;
|
*parent = n->left;
|
||||||
tmp=n->left->right;
|
tmp = n->left->right;
|
||||||
n->left->right=n;
|
n->left->right = n;
|
||||||
n->left=tmp;
|
n->left = tmp;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (n->left->bal==1){
|
if (n->left->bal == 1) {
|
||||||
*parent=n->left->right;
|
*parent = n->left->right;
|
||||||
if ((*parent)->bal==1) {
|
if ((*parent)->bal == 1) {
|
||||||
n->bal=0;
|
n->bal = 0;
|
||||||
n->left->bal=-1;
|
n->left->bal = -1;
|
||||||
}
|
} else if ((*parent)->bal == -1) {
|
||||||
else if ((*parent)->bal==-1){
|
n->bal = 1;
|
||||||
n->bal=1;
|
n->left->bal = 0;
|
||||||
n->left->bal=0;
|
} else {
|
||||||
}
|
n->bal = 0;
|
||||||
else{
|
n->left->bal = 0;
|
||||||
n->bal=0;
|
|
||||||
n->left->bal=0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(*parent)->bal=0;
|
(*parent)->bal = 0;
|
||||||
n->left->right=(*parent)->left;
|
n->left->right = (*parent)->left;
|
||||||
(*parent)->left=n->left;
|
(*parent)->left = n->left;
|
||||||
tmp = (*parent)->right;
|
tmp = (*parent)->right;
|
||||||
(*parent)->right=n;
|
(*parent)->right = n;
|
||||||
n->left=tmp;
|
n->left = tmp;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("!!!!left bal = %i\n",n->left->bal);
|
//printf("!!!!left bal = %i\n",n->left->bal);
|
||||||
//exit(0);
|
//exit(0);
|
||||||
|
|
||||||
@ -137,67 +134,63 @@ static int avltree_add0(struct avltree *t, struct avlnode ** parent, void ** da
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* n->left is 0 */
|
/* n->left is 0 */
|
||||||
n->left=avlnode_create(*data);
|
n->left = avlnode_create(*data);
|
||||||
if (!n->left)
|
if (!n->left)
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
t->count++;
|
t->count++;
|
||||||
|
|
||||||
if(n->right==0){
|
if (n->right == 0) {
|
||||||
n->bal=-1;
|
n->bal = -1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n->bal=0;
|
n->bal = 0;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
} else {
|
||||||
else{
|
if (n->right) {
|
||||||
if (n->right){
|
bal = avltree_add0(t, &n->right, data);
|
||||||
bal = avltree_add0(t,&n->right,data);
|
if (bal > 1)
|
||||||
if(bal>1)
|
|
||||||
return bal;
|
return bal;
|
||||||
|
|
||||||
n->bal+=bal;
|
n->bal += bal;
|
||||||
if (n->bal==0)
|
if (n->bal == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (n->bal==2){
|
if (n->bal == 2) {
|
||||||
if (n->right->bal==1){
|
if (n->right->bal == 1) {
|
||||||
n->bal=0;
|
n->bal = 0;
|
||||||
n->right->bal=0;
|
n->right->bal = 0;
|
||||||
*parent=n->right;
|
*parent = n->right;
|
||||||
tmp=n->right->left;
|
tmp = n->right->left;
|
||||||
n->right->left=n;
|
n->right->left = n;
|
||||||
n->right=tmp;
|
n->right = tmp;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else if (n->right->bal == -1) {
|
||||||
else if(n->right->bal==-1){
|
*parent = n->right->left;
|
||||||
*parent=n->right->left;
|
|
||||||
|
|
||||||
if ((*parent)->bal==-1) {
|
if ((*parent)->bal == -1) {
|
||||||
n->bal=0;
|
n->bal = 0;
|
||||||
n->right->bal=1;
|
n->right->bal = 1;
|
||||||
}
|
} else if ((*parent)->bal == 1) {
|
||||||
else if ((*parent)->bal==1){
|
n->bal = -1;
|
||||||
n->bal=-1;
|
n->right->bal = 0;
|
||||||
n->right->bal=0;
|
} else {
|
||||||
}
|
n->bal = 0;
|
||||||
else{
|
n->right->bal = 0;
|
||||||
n->bal=0;
|
|
||||||
n->right->bal=0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(*parent)->bal=0;
|
(*parent)->bal = 0;
|
||||||
n->right->left=(*parent)->right;
|
n->right->left = (*parent)->right;
|
||||||
(*parent)->right=n->right;
|
(*parent)->right = n->right;
|
||||||
tmp = (*parent)->left;
|
tmp = (*parent)->left;
|
||||||
(*parent)->left=n;
|
(*parent)->left = n;
|
||||||
n->right=tmp;
|
n->right = tmp;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//printf("!!!!iright bal = %i\n",n->left->bal);
|
//printf("!!!!iright bal = %i\n",n->left->bal);
|
||||||
@ -211,16 +204,16 @@ static int avltree_add0(struct avltree *t, struct avlnode ** parent, void ** da
|
|||||||
|
|
||||||
/* n->right is 0 */
|
/* n->right is 0 */
|
||||||
|
|
||||||
n->right=avlnode_create(*data);
|
n->right = avlnode_create(*data);
|
||||||
if (!n->right)
|
if (!n->right)
|
||||||
return 3;
|
return 3;
|
||||||
|
|
||||||
t->count++;
|
t->count++;
|
||||||
if(n->left==0){
|
if (n->left == 0) {
|
||||||
n->bal=1;
|
n->bal = 1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
n->bal=0;
|
n->bal = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,18 +225,18 @@ static int avltree_add0(struct avltree *t, struct avlnode ** parent, void ** da
|
|||||||
* @data pointer to element
|
* @data pointer to element
|
||||||
* @return added alement or NULL if error.
|
* @return added alement or NULL if error.
|
||||||
*/
|
*/
|
||||||
void * avltree_add(struct avltree *t, void * data)
|
void *avltree_add(struct avltree *t, void *data)
|
||||||
{
|
{
|
||||||
if (t->root==0){
|
if (t->root == 0) {
|
||||||
t->root = avlnode_create(data);
|
t->root = avlnode_create(data);
|
||||||
if (t->root)
|
if (t->root)
|
||||||
t->count++;
|
t->count++;
|
||||||
return t->root->data;
|
return t->root->data;
|
||||||
}
|
}
|
||||||
void * d = data;
|
void *d = data;
|
||||||
int rc = avltree_add0(t,&t->root,&d);
|
int rc = avltree_add0(t, &t->root, &d);
|
||||||
|
|
||||||
if (rc>3)
|
if (rc > 3)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
@ -252,21 +245,21 @@ void * avltree_add(struct avltree *t, void * data)
|
|||||||
static void rot_l(struct avlnode *n, struct avlnode **parent)
|
static void rot_l(struct avlnode *n, struct avlnode **parent)
|
||||||
{
|
{
|
||||||
struct avlnode *tmp;
|
struct avlnode *tmp;
|
||||||
*parent=n->right;
|
*parent = n->right;
|
||||||
tmp=n->right->left;
|
tmp = n->right->left;
|
||||||
n->right->left=n;
|
n->right->left = n;
|
||||||
n->right=tmp;
|
n->right = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void rot_r(struct avlnode *n, struct avlnode **parent)
|
static void rot_r(struct avlnode *n, struct avlnode **parent)
|
||||||
{
|
{
|
||||||
struct avlnode *tmp;
|
struct avlnode *tmp;
|
||||||
*parent=n->left;
|
*parent = n->left;
|
||||||
tmp=n->left->right;
|
tmp = n->left->right;
|
||||||
n->left->right=n;
|
n->left->right = n;
|
||||||
n->left=tmp;
|
n->left = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -308,84 +301,79 @@ static int avltree_delete_hi(struct avlnode **parent, void **data)
|
|||||||
|
|
||||||
static void rot_rl(struct avlnode *n, struct avlnode **parent)
|
static void rot_rl(struct avlnode *n, struct avlnode **parent)
|
||||||
{
|
{
|
||||||
struct avlnode * tmp;
|
struct avlnode *tmp;
|
||||||
*parent=n->right->left;
|
*parent = n->right->left;
|
||||||
n->right->left=(*parent)->right;
|
n->right->left = (*parent)->right;
|
||||||
(*parent)->right=n->right;
|
(*parent)->right = n->right;
|
||||||
tmp = (*parent)->left;
|
tmp = (*parent)->left;
|
||||||
(*parent)->left=n;
|
(*parent)->left = n;
|
||||||
n->right=tmp;
|
n->right = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rot_lr(struct avlnode *n, struct avlnode **parent)
|
static void rot_lr(struct avlnode *n, struct avlnode **parent)
|
||||||
{
|
{
|
||||||
struct avlnode * tmp;
|
struct avlnode *tmp;
|
||||||
*parent=n->left->right;
|
*parent = n->left->right;
|
||||||
n->left->right=(*parent)->left;
|
n->left->right = (*parent)->left;
|
||||||
(*parent)->left=n->left;
|
(*parent)->left = n->left;
|
||||||
tmp = (*parent)->right;
|
tmp = (*parent)->right;
|
||||||
(*parent)->right=n;
|
(*parent)->right = n;
|
||||||
n->left=tmp;
|
n->left = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int adj_bal_l(struct avlnode *n, struct avlnode **parent)
|
static int adj_bal_l(struct avlnode *n, struct avlnode **parent)
|
||||||
{
|
{
|
||||||
if (n->right->bal==1){
|
if (n->right->bal == 1) {
|
||||||
n->bal=0;
|
n->bal = 0;
|
||||||
n->right->bal=0;
|
n->right->bal = 0;
|
||||||
rot_l(n,parent);
|
rot_l(n, parent);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else if (n->right->bal == 0) {
|
||||||
else if(n->right->bal==0){
|
n->bal = 1;
|
||||||
n->bal=1;
|
n->right->bal = -1;
|
||||||
n->right->bal=-1;
|
rot_l(n, parent);
|
||||||
rot_l(n,parent);
|
|
||||||
return 0;
|
return 0;
|
||||||
}else if(n->right->bal==-1){
|
} else if (n->right->bal == -1) {
|
||||||
// int rb;
|
// int rb;
|
||||||
n->bal=0;
|
n->bal = 0;
|
||||||
n->right->bal=0;
|
n->right->bal = 0;
|
||||||
// rb = n->right->left->bal;
|
// rb = n->right->left->bal;
|
||||||
n->right->left->bal=0;
|
n->right->left->bal = 0;
|
||||||
rot_rl(n,parent);
|
rot_rl(n, parent);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
// printf("adj bal l not handled \n");
|
||||||
|
// exit(0);
|
||||||
|
|
||||||
// printf("adj bal l not handled \n");
|
return -11; /* that should never happen */
|
||||||
// exit(0);
|
|
||||||
|
|
||||||
return -11; /* that should never happen */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int adj_bal_r(struct avlnode *n, struct avlnode **parent)
|
int adj_bal_r(struct avlnode *n, struct avlnode **parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (n->left->bal==-1){
|
if (n->left->bal == -1) {
|
||||||
n->bal=0;
|
n->bal = 0;
|
||||||
n->left->bal=0;
|
n->left->bal = 0;
|
||||||
rot_r(n,parent);
|
rot_r(n, parent);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
} else if (n->left->bal == 0) {
|
||||||
else if(n->left->bal==0){
|
n->bal = -1;
|
||||||
n->bal=-1;
|
n->left->bal = 1;
|
||||||
n->left->bal=1;
|
rot_r(n, parent);
|
||||||
rot_r(n,parent);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else if (n->left->bal == 1) {
|
||||||
else if(n->left->bal==1){
|
// int rb;
|
||||||
// int rb;
|
n->bal = 0;
|
||||||
n->bal=0;
|
n->left->bal = 0;
|
||||||
n->left->bal=0;
|
// rb = n->left->right->bal;
|
||||||
// rb = n->left->right->bal;
|
n->left->right->bal = 0;
|
||||||
n->left->right->bal=0;
|
rot_lr(n, parent);
|
||||||
rot_lr(n,parent);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
// printf("adj bal li left not handled \n");
|
||||||
// printf("adj bal li left not handled \n");
|
// exit(0);
|
||||||
// exit(0);
|
return -11; /* that should never happen */
|
||||||
return -11; /* that should never happen */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -393,29 +381,29 @@ int adj_bal_r(struct avlnode *n, struct avlnode **parent)
|
|||||||
|
|
||||||
static int avltree_del_lo(struct avlnode **parent, void **data)
|
static int avltree_del_lo(struct avlnode **parent, void **data)
|
||||||
{
|
{
|
||||||
struct avlnode * n = *parent;
|
struct avlnode *n = *parent;
|
||||||
|
|
||||||
if(n->left!=0){
|
if (n->left != 0) {
|
||||||
int bal = avltree_del_lo(&n->left,data);
|
int bal = avltree_del_lo(&n->left, data);
|
||||||
n->bal+=bal;
|
n->bal += bal;
|
||||||
if (n->bal==1){
|
if (n->bal == 1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (n->bal!=2)
|
if (n->bal != 2)
|
||||||
return bal;
|
return bal;
|
||||||
adj_bal_l(n,parent);
|
adj_bal_l(n, parent);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* found the lowest element */
|
/* found the lowest element */
|
||||||
|
|
||||||
*parent=n->right;
|
*parent = n->right;
|
||||||
*data = n->data;
|
*data = n->data;
|
||||||
free (n);
|
free(n);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
||||||
if (n->right){
|
if (n->right) {
|
||||||
free(n);
|
free(n);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -429,98 +417,98 @@ static int avltree_del_lo(struct avlnode **parent, void **data)
|
|||||||
|
|
||||||
int avltree_del0(struct avltree *t, struct avlnode **parent, void **data)
|
int avltree_del0(struct avltree *t, struct avlnode **parent, void **data)
|
||||||
{
|
{
|
||||||
struct avlnode * n = *parent;
|
struct avlnode *n = *parent;
|
||||||
int rc;
|
int rc;
|
||||||
int bal;
|
int bal;
|
||||||
|
rc = t->cmp(*data, n->data);
|
||||||
|
|
||||||
rc =t->cmp(*data,n->data);
|
if (rc == 0) {
|
||||||
|
if (n->right == 0 && n->left == 0) {
|
||||||
if (rc==0){
|
*parent = 0;
|
||||||
if (n->right == 0 && n->left ==0){
|
avlnode_destroy(t, n);
|
||||||
*parent=0;
|
|
||||||
avlnode_destroy(t,n);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n->right && n->left==0){
|
if (n->right && n->left == 0) {
|
||||||
*parent=n->right;
|
*parent = n->right;
|
||||||
avlnode_destroy(t,n);
|
avlnode_destroy(t, n);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n->left && n->right==0){
|
if (n->left && n->right == 0) {
|
||||||
avlnode_destroy(t,n);
|
avlnode_destroy(t, n);
|
||||||
*parent=n->left;
|
*parent = n->left;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* node has two childs */
|
/* node has two childs */
|
||||||
|
|
||||||
if (t->del){
|
if (t->del) {
|
||||||
t->del(n->data);
|
t->del(n->data);
|
||||||
}
|
}
|
||||||
t->count--;
|
t->count--;
|
||||||
bal = avltree_del_lo(&n->right,&n->data);
|
bal = avltree_del_lo(&n->right, &n->data);
|
||||||
n->bal-= bal;
|
n->bal -= bal;
|
||||||
if (n->bal==-1)
|
if (n->bal == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (n->bal != -2)
|
if (n->bal != -2)
|
||||||
return bal;
|
return bal;
|
||||||
|
|
||||||
return adj_bal_r(n,parent);
|
return adj_bal_r(n, parent);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc<0){
|
if (rc < 0) {
|
||||||
if (n->left)
|
if (n->left) {
|
||||||
{
|
bal = avltree_del0(t, &n->left, data);
|
||||||
bal = avltree_del0(t,&n->left,data);
|
if (bal == 2)
|
||||||
if (bal==2)
|
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
n->bal+=bal;
|
n->bal += bal;
|
||||||
if (n->bal==1)
|
if (n->bal == 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (n->bal!=2)
|
if (n->bal != 2)
|
||||||
return bal;
|
return bal;
|
||||||
|
|
||||||
return adj_bal_l(n,parent);
|
return adj_bal_l(n, parent);
|
||||||
}
|
}
|
||||||
return 2; /* not found */
|
return 2; /* not found */
|
||||||
}
|
} else { /* rc must be > 0 */
|
||||||
else { /* rc must be > 0 */
|
if (n->right) {
|
||||||
if (n->right){
|
bal = avltree_del0(t, &n->right, data);
|
||||||
bal = avltree_del0(t,&n->right,data);
|
if (bal == 2)
|
||||||
if (bal==2)
|
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
n->bal-=bal;
|
n->bal -= bal;
|
||||||
if (n->bal==-1)
|
if (n->bal == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (n->bal != -2)
|
if (n->bal != -2)
|
||||||
return bal;
|
return bal;
|
||||||
|
|
||||||
return adj_bal_r(n,parent);
|
return adj_bal_r(n, parent);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return 2; /* not found */
|
return 2; /* not found */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void * avltree_del(struct avltree *t, void *data)
|
void *avltree_del(struct avltree *t, void *data)
|
||||||
{
|
{
|
||||||
|
if (!t->root)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
void *d = data;
|
void *d = data;
|
||||||
int rc = avltree_del0(t,&t->root,&d);
|
int rc = avltree_del0(t, &t->root, &d);
|
||||||
if (rc==2)
|
if (rc == 2)
|
||||||
return 0;
|
return NULL;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -609,11 +597,13 @@ void walk(struct avlnode *n)
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
void avltree_destroy(struct avltree *t)
|
void avltree_destroy(struct avltree *t)
|
||||||
{
|
{
|
||||||
avltree_del_all(t);
|
avltree_del_all(t);
|
||||||
free (t);
|
free (t);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
//#include <time.h>
|
//#include <time.h>
|
||||||
|
@ -16,65 +16,81 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* yet another avl tree implementation!
|
* @file
|
||||||
|
* @brief Yet another avl tree implementation!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __AVLTREE_H
|
#ifndef __AVLTREE_H
|
||||||
#define __AVLTREE_H
|
#define __AVLTREE_H
|
||||||
|
|
||||||
#include <string.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
struct avlnode{
|
|
||||||
void * data;
|
struct avlnode {
|
||||||
struct avlnode * left;
|
void *data;
|
||||||
struct avlnode * right;
|
struct avlnode *left;
|
||||||
|
struct avlnode *right;
|
||||||
int bal;
|
int bal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct avltree{
|
struct avltree {
|
||||||
struct avlnode * root;
|
struct avlnode *root;
|
||||||
int (*cmp)(const void*,const void*);
|
int (*cmp) (const void *, const void *);
|
||||||
void(*del)(void*);
|
void (*del) (void *);
|
||||||
int count;
|
int count;
|
||||||
};
|
};
|
||||||
|
|
||||||
void avlnode_destroy(struct avltree *t,struct avlnode *n);
|
void avlnode_destroy(struct avltree *t, struct avlnode *n);
|
||||||
|
|
||||||
struct avltree * avltree_create(int (*cmp)(const void*,const void*),void(*del)(void*));
|
struct avltree *avltree_create(int (*cmp) (const void *, const void *),
|
||||||
void avltree_destroy(struct avltree *t);
|
void (*del) (void *));
|
||||||
|
//void avltree_destroy(struct avltree *t);
|
||||||
|
|
||||||
void avltree_del_all(struct avltree *t);
|
void avltree_del_all(struct avltree *t);
|
||||||
void * avltree_del(struct avltree *t, void *data);
|
void *avltree_del(struct avltree *t, void *data);
|
||||||
void * avltree_add(struct avltree *t, void *data);
|
void *avltree_add(struct avltree *t, void *data);
|
||||||
//void * avltree_get(struct avltree *t ,void *data);
|
//void * avltree_get(struct avltree *t ,void *data);
|
||||||
struct avlnode * avltree_get_node(struct avltree *t ,void *data);
|
struct avlnode *avltree_get_node(struct avltree *t, void *data);
|
||||||
|
|
||||||
extern int avltree_foreach_lr(struct avlnode *n, int (*callback)(void *,void *),void *cbpriv);
|
extern int avltree_foreach_lr(struct avlnode *n, int (*callback) (void *, void *),
|
||||||
extern int avltree_foreach_rl(struct avlnode *n, int (*callback)(void *,void *),void *cbpriv);
|
void *cbpriv);
|
||||||
int avltree_foreach_from_lr(struct avltree *t, struct avlnode *n, void *data,int (*callback)(void *,void *),void *cbpriv);
|
extern int avltree_foreach_rl(struct avlnode *n, int (*callback) (void *, void *),
|
||||||
|
void *cbpriv);
|
||||||
|
int avltree_foreach_from_lr(struct avltree *t, struct avlnode *n, void *data,
|
||||||
|
int (*callback) (void *, void *), void *cbpriv);
|
||||||
|
|
||||||
|
|
||||||
//extern void avltree_foreach(struct avltree *t, int (*callback)(void *,void*),void *cbpriv,int dir);
|
//extern void avltree_foreach(struct avltree *t, int (*callback)(void *,void*),void *cbpriv,int dir);
|
||||||
|
|
||||||
static inline void * avltree_get(struct avltree *t ,void *data){
|
static inline void *avltree_get(struct avltree *t, void *data)
|
||||||
struct avlnode * n = avltree_get_node(t,data);
|
{
|
||||||
|
struct avlnode *n = avltree_get_node(t, data);
|
||||||
if (!n)
|
if (!n)
|
||||||
return NULL;
|
return NULL;
|
||||||
return n->data;
|
return n->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void * avltree_replace_data(struct avltree *t ,void *data,int len) {
|
static inline void *avltree_replace_data(struct avltree *t, void *data, int len)
|
||||||
void * df = avltree_get(t,data);
|
{
|
||||||
if(!df)
|
void *df = avltree_get(t, data);
|
||||||
|
if (!df)
|
||||||
return NULL;
|
return NULL;
|
||||||
memcpy(df,data,len);
|
memcpy(df, data, len);
|
||||||
return df;
|
return df;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void avltree_destroy(struct avltree *t)
|
||||||
|
{
|
||||||
|
avltree_del_all(t);
|
||||||
|
free (t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#define avltree_find(t,d) avltree_get(t,d)
|
#define avltree_find(t,d) avltree_get(t,d)
|
||||||
#define avltree_insert(t,d) avltree_add(t,d)
|
#define avltree_insert(t,d) avltree_add(t,d)
|
||||||
//#define avltree_walk(t,dir) avltree_foreach(t,dir)
|
//#define avltree_walk(t,dir) avltree_foreach(t,dir)
|
||||||
@ -86,5 +102,3 @@ static inline void * avltree_replace_data(struct avltree *t ,void *data,int len)
|
|||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,14 +13,22 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief Implementation of avltree_get
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "avltree.h"
|
#include "avltree.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an AVL tree element.
|
||||||
|
* @param data Element to get
|
||||||
|
* @return pointer to element or NULL if not found.
|
||||||
|
*/
|
||||||
void * avltree_get(struct avltree *t ,void *data)
|
void * avltree_get(struct avltree *t ,void *data)
|
||||||
{
|
{
|
||||||
struct avlnode *n = t->root;
|
struct avlnode *n = t->root;
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "conn.h"
|
#include "conn.h"
|
||||||
|
|
||||||
#include "lwapp.h"
|
#include "lwapp.h"
|
||||||
|
#include "strheap.h"
|
||||||
|
|
||||||
/* capwap version and iana number */
|
/* capwap version and iana number */
|
||||||
#define CW_VERSION 0
|
#define CW_VERSION 0
|
||||||
@ -83,6 +84,9 @@ enum capwap_states {
|
|||||||
#define CWTH_FLAGS_T 0x100 /* bit 8 type of payload frame */
|
#define CWTH_FLAGS_T 0x100 /* bit 8 type of payload frame */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CAWAP header flags.
|
||||||
|
*/
|
||||||
#define CW_FLAG_HDR_R1 0x01 /* bit 0 reserved 1 */
|
#define CW_FLAG_HDR_R1 0x01 /* bit 0 reserved 1 */
|
||||||
#define CW_FLAG_HDR_R2 0x02 /* bit 1 reserved 2 */
|
#define CW_FLAG_HDR_R2 0x02 /* bit 1 reserved 2 */
|
||||||
#define CW_FLAG_HDR_R3 0x04 /* bit 2 reserved 3 */
|
#define CW_FLAG_HDR_R3 0x04 /* bit 2 reserved 3 */
|
||||||
@ -521,6 +525,9 @@ extern int cw_readmsg_configuration_update_request(uint8_t * elems, int elems_le
|
|||||||
#define cw_put_data lw_put_data
|
#define cw_put_data lw_put_data
|
||||||
#define cw_put_bstr lw_put_bstr
|
#define cw_put_bstr lw_put_bstr
|
||||||
|
|
||||||
|
#define cw_set_dword lw_set_dword
|
||||||
|
|
||||||
|
|
||||||
#define cw_get_byte lw_get_byte
|
#define cw_get_byte lw_get_byte
|
||||||
#define cw_get_word lw_get_word
|
#define cw_get_word lw_get_word
|
||||||
#define cw_get_dword lw_get_dword
|
#define cw_get_dword lw_get_dword
|
||||||
@ -557,6 +564,36 @@ extern int cw_readmsg_configuration_update_request(uint8_t * elems, int elems_le
|
|||||||
#define cw_get_hdr_msg_offset(th) (4*cw_get_hdr_hlen(th))
|
#define cw_get_hdr_msg_offset(th) (4*cw_get_hdr_hlen(th))
|
||||||
#define cw_get_hdr_msg_elems_offset(th) (cw_get_hdr_msg_offset(th)+8)
|
#define cw_get_hdr_msg_elems_offset(th) (cw_get_hdr_msg_offset(th)+8)
|
||||||
|
|
||||||
|
#define cw_set_hdr_preamble(th,v) ((*th)=v)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the HLEN field of a CAWAP Header
|
||||||
|
* @param th pointer to the header
|
||||||
|
* @param hlen velue to set (max. 5 bits)
|
||||||
|
*/
|
||||||
|
static inline void cw_set_hdr_hlen(uint8_t *th,int hlen){
|
||||||
|
uint32_t d = cw_get_dword(th);
|
||||||
|
d &= (0x1f << 19) ^ 0xffffffff;
|
||||||
|
d |= ((hlen) & 0x1f) <<19;
|
||||||
|
cw_set_dword(th,d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set CAPWAP header flags
|
||||||
|
* @param th pointer to header
|
||||||
|
* @param flags list of flags to set or unset
|
||||||
|
* @param set 1=set flag, 0=unset flag
|
||||||
|
*/
|
||||||
|
#define cw_set_hdr_flags(th,flags,set) \
|
||||||
|
( set ? ((*((uint32_t*)th)) |= htonl(flags)) : ((*((uint32_t*)th)) &= (0xffffffff^htonl(flags))) )
|
||||||
|
|
||||||
|
#define cw_set_hdr_flag_f(th,set) cw_set_hdr_flag(th, CW_FLAG_HDR_F)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Macros for message headers */
|
||||||
|
|
||||||
#define cw_get_msg_id(msgptr) (cw_get_dword(msgptr))
|
#define cw_get_msg_id(msgptr) (cw_get_dword(msgptr))
|
||||||
#define cw_get_msg_type(msgptr) cw_get_msg_id(msgptr)
|
#define cw_get_msg_type(msgptr) cw_get_msg_id(msgptr)
|
||||||
|
|
||||||
@ -565,15 +602,6 @@ extern int cw_readmsg_configuration_update_request(uint8_t * elems, int elems_le
|
|||||||
#define cw_get_msg_elems_ptr(msgptr) ((msgptr)+8)
|
#define cw_get_msg_elems_ptr(msgptr) ((msgptr)+8)
|
||||||
|
|
||||||
|
|
||||||
#define cw_set_hdr_preamble(th,v) ((*th)=v)
|
|
||||||
|
|
||||||
#define cw_set_hdr_flags(th,val,set) \
|
|
||||||
( set ? ((*((uint32_t*)th)) |= htonl(val)) : ((*((uint32_t*)th)) &= (0xffffffff^htonl(val))) )
|
|
||||||
|
|
||||||
#define cw_set_hdr_flag_f(th,set) cw_set_hdr_flag(th, CW_FLAG_HDR_F)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define cw_set_msg_id(msgptr,t) cw_put_dword(msgptr,t)
|
#define cw_set_msg_id(msgptr,t) cw_put_dword(msgptr,t)
|
||||||
#define cw_set_msg_type(msgptr,t) cw_set_msg_id(msgptr,t)
|
#define cw_set_msg_type(msgptr,t) cw_set_msg_id(msgptr,t)
|
||||||
#define cw_set_msg_seqnum(msgptr,s) cw_put_byte( (msgptr) +4,s);
|
#define cw_set_msg_seqnum(msgptr,s) cw_put_byte( (msgptr) +4,s);
|
||||||
@ -606,14 +634,14 @@ static inline int cw_get_hdr_msg_total_len(uint8_t * rawmsg)
|
|||||||
* @pram e pointer to element (uint8_t*)
|
* @pram e pointer to element (uint8_t*)
|
||||||
* @return type of element
|
* @return type of element
|
||||||
*/
|
*/
|
||||||
#define cw_get_elem_len(e) cw_get_word(e+2)
|
#define cw_get_elem_len(e) cw_get_word((e)+2)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a pointer to the data of a CAPWAP message element
|
* Get a pointer to the data of a CAPWAP message element
|
||||||
* @param e pointer to message element
|
* @param e pointer to message element
|
||||||
* @return pointer to data
|
* @return pointer to data
|
||||||
*/
|
*/
|
||||||
#define cw_get_elem_data(e) (e+4)
|
#define cw_get_elem_data(e) ((e)+4)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterate through message elements of a CAPWAP message
|
* Iterate through message elements of a CAPWAP message
|
||||||
@ -770,19 +798,11 @@ extern int cw_send_configuration_update_response(struct conn *conn, int seqnum,
|
|||||||
|
|
||||||
/* Message to text stuff */
|
/* Message to text stuff */
|
||||||
|
|
||||||
struct cw_strlist {
|
|
||||||
uint32_t id;
|
|
||||||
const char *str;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const char *cw_strlist_get_str(struct cw_strlist *s, int id);
|
|
||||||
|
|
||||||
|
|
||||||
/* Constants to string conversion lists */
|
/* Constants to string conversion lists */
|
||||||
extern struct cw_strlist capwap_strings_msg[];
|
extern struct cw_str capwap_strings_msg[];
|
||||||
extern struct cw_strlist capwap_strings_state[];
|
extern struct cw_str capwap_strings_state[];
|
||||||
extern struct cw_strlist capwap_strings_vendor[];
|
extern struct cw_str capwap_strings_vendor[];
|
||||||
extern struct cw_strlist capwap_strings_elem[];
|
extern struct cw_str capwap_strings_elem[];
|
||||||
|
|
||||||
|
|
||||||
#define cw_strmsg(id) cw_strlist_get_str(capwap_strings_msg,id)
|
#define cw_strmsg(id) cw_strlist_get_str(capwap_strings_msg,id)
|
||||||
@ -791,6 +811,13 @@ extern struct cw_strlist capwap_strings_elem[];
|
|||||||
#define cw_strvendor(id) cw_strlist_get_str(capwap_strings_vendor,id)
|
#define cw_strvendor(id) cw_strlist_get_str(capwap_strings_vendor,id)
|
||||||
|
|
||||||
|
|
||||||
|
#define cw_strelemp(p,id) cw_strheap_get((p)->strelem,id)
|
||||||
|
|
||||||
|
extern const char *cw_strlist_get_str(struct cw_str *s, int id);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int cw_process_msg(struct conn *conn, uint8_t * rawmsg, int len);
|
int cw_process_msg(struct conn *conn, uint8_t * rawmsg, int len);
|
||||||
|
|
||||||
|
|
||||||
@ -806,13 +833,18 @@ extern int cw_in_wtp_descriptor(struct conn *conn, struct cw_action_in *a, uint8
|
|||||||
int len);
|
int len);
|
||||||
|
|
||||||
//extern int cw_out_generic(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len);
|
//extern int cw_out_generic(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len);
|
||||||
extern int cw_out_generic(struct conn *conn, uint32_t elem_id, uint8_t * dst,
|
extern int cw_out_generic(struct conn *conn, struct cw_action_out *a, uint8_t * dst); //, struct cw_item *item);
|
||||||
struct cw_item *item);
|
|
||||||
extern int cw_out_ac_descriptor(struct conn *conn, uint32_t elem_id, uint8_t * dst,
|
|
||||||
struct cw_item *item);
|
|
||||||
extern int cw_out_capwap_control_ip_addrs(struct conn *conn, uint32_t elem_id,
|
|
||||||
uint8_t * dst, struct cw_item *item);
|
|
||||||
|
|
||||||
|
//extern int cw_out_ac_descriptor(struct conn *conn, uint32_t elem_id, uint8_t * dst,
|
||||||
|
//struct cw_item *item);
|
||||||
|
extern int cw_out_ac_descriptor(struct conn *conn,struct cw_action_out * a,uint8_t *dst); //,struct cw_item * item)
|
||||||
|
|
||||||
|
//extern int cw_out_capwap_control_ip_addrs(struct conn *conn, uint32_t elem_id,
|
||||||
|
// uint8_t * dst, struct cw_item *item);
|
||||||
|
|
||||||
|
extern int cw_out_capwap_control_ip_addrs(struct conn *conn,struct cw_action_out *a,uint8_t *dst) ;
|
||||||
|
|
||||||
|
extern int cw_put_msg(struct conn *conn, uint8_t * rawout);
|
||||||
|
|
||||||
|
|
||||||
struct cw_ac_status {
|
struct cw_ac_status {
|
||||||
@ -825,9 +857,42 @@ struct cw_ac_status {
|
|||||||
int dtls_policy;
|
int dtls_policy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put an cw_ac_stauts structure to a buffer
|
||||||
|
* @param dst destination buffer
|
||||||
|
* @param s #cw_ac_status to put
|
||||||
|
* @return number of bytes put
|
||||||
|
* This function is only useful (used) in conjunction with
|
||||||
|
* putting AC Descriptor message elements.
|
||||||
|
*/
|
||||||
|
static inline int cw_put_ac_status(uint8_t *dst, struct cw_ac_status *s){
|
||||||
|
uint8_t *d=dst;
|
||||||
|
|
||||||
|
d += cw_put_dword (d, (s->stations << 16) | (s->limit) );
|
||||||
|
d += cw_put_dword (d, (s->active_wtps <<16) | (s->max_wtps) );
|
||||||
|
d += cw_put_dword (d, (s->security<<24) | (s->rmac_field<<16) | (s->dtls_policy));
|
||||||
|
return d-dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline int cw_put_version(uint8_t *dst,uint16_t subelem_id, uint32_t vendor_id,bstr16_t data)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint8_t *d=dst;
|
||||||
|
d += cw_put_dword(d,vendor_id);
|
||||||
|
d += cw_put_dword(d, (subelem_id<<16) | bstr16_len(data));
|
||||||
|
d += cw_put_data(d,bstr16_data(data),bstr16_len(data));
|
||||||
|
return d-dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int cw_register_actions_capwap_ac(struct cw_actiondef *def);
|
int cw_register_actions_capwap_ac(struct cw_actiondef *def);
|
||||||
int cw_register_actions_cipwap_ac(struct cw_actiondef *def);
|
int cw_register_actions_cipwap_ac(struct cw_actiondef *def);
|
||||||
|
|
||||||
|
int cw_in_set_state_none(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len);
|
||||||
|
struct cw_item *cw_out_get_local(struct conn *conn, struct cw_action_out *a);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -61,7 +61,7 @@
|
|||||||
CW_ITEM_WTP_MAC_TYPE, /* ID to use store */ \
|
CW_ITEM_WTP_MAC_TYPE, /* ID to use store */ \
|
||||||
1, 1 /* min/max length */
|
1, 1 /* min/max length */
|
||||||
|
|
||||||
#define CW_ACTION_VENDOR_SPECIFIC_PAYLOAD \
|
#define CW_ACTION_IN_VENDOR_SPECIFIC_PAYLOAD \
|
||||||
CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, /* Element ID */ \
|
CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, /* Element ID */ \
|
||||||
cw_in_vendor_specific_payload, 0 /* start/end callback*/ \
|
cw_in_vendor_specific_payload, 0 /* start/end callback*/ \
|
||||||
|
|
||||||
|
@ -21,13 +21,7 @@
|
|||||||
#include "action.h"
|
#include "action.h"
|
||||||
#include "capwap_items.h"
|
#include "capwap_items.h"
|
||||||
#include "capwap_actions.h"
|
#include "capwap_actions.h"
|
||||||
|
#include "strheap.h"
|
||||||
int cw_in_set_state_none(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len)
|
|
||||||
{
|
|
||||||
conn->capwap_state=CW_STATE_NONE;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -58,8 +52,7 @@ cw_action_in_t capwap_actions_ac_in[] = {
|
|||||||
{0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_WTP_MAC_TYPE}
|
{0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_WTP_MAC_TYPE}
|
||||||
,
|
,
|
||||||
/* Vendor Specific Payload */
|
/* Vendor Specific Payload */
|
||||||
{0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ELEM_VENDOR_SPECIFIC_PAYLOAD,
|
{0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ACTION_IN_VENDOR_SPECIFIC_PAYLOAD}
|
||||||
cw_in_vendor_specific_payload, 0}
|
|
||||||
,
|
,
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------------*/
|
/* -------------------------------------------------------------------------------*/
|
||||||
@ -90,6 +83,9 @@ cw_action_in_t capwap_actions_ac_in[] = {
|
|||||||
/* Element WTP MAC Type */
|
/* Element WTP MAC Type */
|
||||||
{0, 0, CW_STATE_JOIN, CW_MSG_JOIN_REQUEST, CW_ACTION_IN_WTP_MAC_TYPE}
|
{0, 0, CW_STATE_JOIN, CW_MSG_JOIN_REQUEST, CW_ACTION_IN_WTP_MAC_TYPE}
|
||||||
,
|
,
|
||||||
|
/* Element Vendor Specific Payload */
|
||||||
|
{0, 0, CW_STATE_JOIN, CW_MSG_JOIN_REQUEST, CW_ACTION_IN_VENDOR_SPECIFIC_PAYLOAD}
|
||||||
|
,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -121,6 +117,7 @@ cw_action_in_t capwap_actions_ac_in[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
int cw_out_ac_name(uint8_t * dst, struct cw_item *item)
|
int cw_out_ac_name(uint8_t * dst, struct cw_item *item)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -130,13 +127,8 @@ int cw_out_ac_name(uint8_t * dst, struct cw_item *item)
|
|||||||
int len = cw_put_data(dst + 4, data, strlen((char *) data));
|
int len = cw_put_data(dst + 4, data, strlen((char *) data));
|
||||||
return len + cw_put_elem_hdr(dst, CW_ELEM_AC_NAME, len);
|
return len + cw_put_elem_hdr(dst, CW_ELEM_AC_NAME, len);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
struct cw_item *cw_get_local(struct conn *conn, uint32_t item_id)
|
|
||||||
{
|
|
||||||
struct cw_item i;
|
|
||||||
i.id = item_id;
|
|
||||||
return cw_itemstore_get(conn->local, item_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -145,26 +137,38 @@ cw_action_out_t capwap_actions_ac_out[] = {
|
|||||||
,
|
,
|
||||||
|
|
||||||
/* AC Descriptor */
|
/* AC Descriptor */
|
||||||
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_DESCRIPTOR,
|
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_DESCRIPTOR, 0
|
||||||
CW_ELEM_AC_DESCRIPTOR, cw_out_ac_descriptor, 0}
|
,CW_ELEM_AC_DESCRIPTOR, cw_out_ac_descriptor, 0}
|
||||||
,
|
,
|
||||||
|
|
||||||
/* AC Name */
|
/* AC Name */
|
||||||
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_NAME,
|
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_NAME, 0,
|
||||||
CW_ELEM_AC_NAME, cw_out_generic, cw_get_local}
|
CW_ELEM_AC_NAME, cw_out_generic, cw_out_get_local}
|
||||||
,
|
,
|
||||||
|
|
||||||
/* List of CAPWAP Control IPv4 and IPv6 addresses */
|
/* List of CAPWAP Control IPv4 and IPv6 addresses */
|
||||||
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_CAPWAP_CONTROL_IP_LIST,
|
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_CAPWAP_CONTROL_IP_LIST, 0,
|
||||||
0, cw_out_capwap_control_ip_addrs, cw_get_local}
|
0, cw_out_capwap_control_ip_addrs, cw_out_get_local}
|
||||||
,
|
,
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------------
|
||||||
|
* Join Response OUT
|
||||||
|
*/
|
||||||
|
{CW_MSG_JOIN_RESPONSE, CW_ITEM_NONE}
|
||||||
|
,
|
||||||
|
|
||||||
|
/* Result Code */
|
||||||
|
{CW_MSG_JOIN_RESPONSE, CW_ITEM_RESULT_CODE, 0,
|
||||||
|
CW_ELEM_RESULT_CODE, cw_out_generic, cw_out_get_local}
|
||||||
|
,
|
||||||
|
|
||||||
|
/* AC Descriptor */
|
||||||
|
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_DESCRIPTOR, 0
|
||||||
|
,CW_ELEM_AC_DESCRIPTOR, cw_out_ac_descriptor, 0}
|
||||||
|
,
|
||||||
|
|
||||||
|
|
||||||
{CW_MSG_JOIN_RESPONSE, CW_ITEM_AC_NAME}
|
|
||||||
,
|
|
||||||
{CW_MSG_JOIN_RESPONSE, CW_ITEM_RESULT_CODE}
|
|
||||||
,
|
|
||||||
|
|
||||||
|
|
||||||
{0, 0}
|
{0, 0}
|
||||||
@ -180,9 +184,18 @@ int cw_register_actions_capwap_ac(struct cw_actiondef *def)
|
|||||||
{
|
{
|
||||||
def->in = cw_actionlist_in_create();
|
def->in = cw_actionlist_in_create();
|
||||||
def->out = cw_actionlist_out_create();
|
def->out = cw_actionlist_out_create();
|
||||||
|
def->strmsg = cw_strheap_create();
|
||||||
|
def->strelem = cw_strheap_create();
|
||||||
|
|
||||||
cw_actionlist_in_register_actions(def->in, capwap_actions_ac_in);
|
cw_actionlist_in_register_actions(def->in, capwap_actions_ac_in);
|
||||||
cw_actionlist_out_register_actions(def->out, capwap_actions_ac_out);
|
cw_actionlist_out_register_actions(def->out, capwap_actions_ac_out);
|
||||||
|
|
||||||
|
int rc ;
|
||||||
|
rc = cw_strheap_register_strings(def->strmsg,capwap_strings_msg);
|
||||||
|
rc += cw_strheap_register_strings(def->strelem,capwap_strings_elem);
|
||||||
|
|
||||||
|
|
||||||
|
printf("Registered %d strings\n",rc);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#define CW_CISCO_DIRECT_SEQUENCE_CONTROL LW_ELEM_DIRECT_SEQUENCE_CONTROL /* 14 */
|
#define CW_CISCO_DIRECT_SEQUENCE_CONTROL LW_ELEM_DIRECT_SEQUENCE_CONTROL /* 14 */
|
||||||
#define CW_CISCO_SUPPORTED_RATES LW_ELEM_80211_RATE_SET /* 16 */
|
#define CW_CISCO_SUPPORTED_RATES LW_ELEM_80211_RATE_SET /* 16 */
|
||||||
|
|
||||||
|
#define CW_CISCO_MWAR_NAME LW_ELEM_AC_NAME /* 31 */
|
||||||
|
|
||||||
#define CW_CISCO_LOCATION_DATA LW_ELEM_LOCATION_DATA /* 35 */
|
#define CW_CISCO_LOCATION_DATA LW_ELEM_LOCATION_DATA /* 35 */
|
||||||
#define CW_CISCO_STATISTICS_TIMER LW_ELEM_STATISTICS_TIMER /* 37 */
|
#define CW_CISCO_STATISTICS_TIMER LW_ELEM_STATISTICS_TIMER /* 37 */
|
||||||
@ -92,15 +93,20 @@
|
|||||||
* @param dst destination buffer
|
* @param dst destination buffer
|
||||||
* @param time a unix timestamp
|
* @param time a unix timestamp
|
||||||
* @param type of time
|
* @param type of time
|
||||||
* @return number of bytes put (15)
|
* @return number of bytes put (5)
|
||||||
*/
|
*/
|
||||||
static inline int cw_addelem_cisco_ap_timesync(uint8_t * dst, time_t time, uint8_t type)
|
static inline int cw_put_cisco_ap_timesync(uint8_t * dst, time_t time, uint8_t type)
|
||||||
{
|
{
|
||||||
cw_put_dword(dst + 10, time);
|
cw_put_dword(dst , time);
|
||||||
cw_put_byte(dst + 14, type);
|
cw_put_byte(dst + 4, type);
|
||||||
return 5 + cw_put_elem_vendor_hdr(dst, CW_VENDOR_ID_CISCO, CW_CISCO_AP_TIMESYNC, 5);
|
return 5;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cw_out_cisco_ap_timesync(struct conn *conn,struct cw_action_out * a,uint8_t *dst);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a Cisco RAD Name message element to buffer
|
* Add a Cisco RAD Name message element to buffer
|
||||||
* @param dst destination buffer
|
* @param dst destination buffer
|
||||||
@ -184,6 +190,8 @@ extern const char * cw_cisco_id_to_str(int elem_id);
|
|||||||
int cw_readelem_cisco_wtp_radio_cfg(int elem_id,uint8_t *elem, int len,struct radioinfo *ri);
|
int cw_readelem_cisco_wtp_radio_cfg(int elem_id,uint8_t *elem, int len,struct radioinfo *ri);
|
||||||
int cw_addelem_cisco_wtp_radio_cfg(uint8_t*dst,struct radioinfo * ri);
|
int cw_addelem_cisco_wtp_radio_cfg(uint8_t*dst,struct radioinfo * ri);
|
||||||
|
|
||||||
|
extern int cw_out_cisco_ac_descriptor(struct conn *conn,struct cw_action_out * a,uint8_t *dst) ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -37,7 +37,12 @@ enum capwap_items {
|
|||||||
|
|
||||||
CW_ITEM_LOCATION_DATA,
|
CW_ITEM_LOCATION_DATA,
|
||||||
CW_ITEM_SESSION_ID,
|
CW_ITEM_SESSION_ID,
|
||||||
|
|
||||||
|
CW_ITEM_AC_TIMESTAMP,
|
||||||
|
|
||||||
|
|
||||||
|
/* CIPWAP and Cisco */
|
||||||
|
CW_ITEM_WTP_GROUP_NAME
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "capwap.h"
|
#include "capwap.h"
|
||||||
|
|
||||||
struct cw_strlist capwap_strings_elem[] = {
|
struct cw_str capwap_strings_elem[] = {
|
||||||
|
|
||||||
{CW_ELEM_AC_DESCRIPTOR, "AC Descriptor"},
|
{CW_ELEM_AC_DESCRIPTOR, "AC Descriptor"},
|
||||||
{CW_ELEM_AC_IPV4_LIST, "AC IPv4 List"},
|
{CW_ELEM_AC_IPV4_LIST, "AC IPv4 List"},
|
||||||
@ -55,12 +55,13 @@ struct cw_strlist capwap_strings_elem[] = {
|
|||||||
{CW_ELEM_RESERVED_46, "Reserved 46"},
|
{CW_ELEM_RESERVED_46, "Reserved 46"},
|
||||||
{CW_ELEM_WTP_RADIO_STATISTICS, "WTP Radio Statistics"},
|
{CW_ELEM_WTP_RADIO_STATISTICS, "WTP Radio Statistics"},
|
||||||
{CWMSGELEM_WTP_REBOOT_STATISTICS, "WTP Reboot Statistics"},
|
{CWMSGELEM_WTP_REBOOT_STATISTICS, "WTP Reboot Statistics"},
|
||||||
{CW_ELEM_WTP_STATIC_IP_ADDRESS_INFORMATION, "WTP Static IP Address Information"}
|
{CW_ELEM_WTP_STATIC_IP_ADDRESS_INFORMATION, "WTP Static IP Address Information"},
|
||||||
|
|
||||||
|
|
||||||
/* Cisco's CAPWAP definitions (CAPWAP draft 7) */
|
/* Cisco's CAPWAP definitions (CAPWAP draft 7) */
|
||||||
/* CW_ELEM_WTP_IPV4_IP_ADDRESS 42
|
/* CW_ELEM_WTP_IPV4_IP_ADDRESS 42
|
||||||
CW_ELEM_WTP_IPV6_IP_ADDRESS 43
|
CW_ELEM_WTP_IPV6_IP_ADDRESS 43
|
||||||
*/
|
*/
|
||||||
|
{0,"Unknown Element"}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "capwap.h"
|
#include "capwap.h"
|
||||||
|
|
||||||
struct cw_strlist capwap_strings_msg[] = {
|
struct cw_str capwap_strings_msg[] = {
|
||||||
{ CW_MSG_DISCOVERY_REQUEST, "Discovery Request" },
|
{ CW_MSG_DISCOVERY_REQUEST, "Discovery Request" },
|
||||||
{ CW_MSG_DISCOVERY_RESPONSE,"Discovery Response" },
|
{ CW_MSG_DISCOVERY_RESPONSE,"Discovery Response" },
|
||||||
{ CW_MSG_JOIN_REQUEST, "Join Request"},
|
{ CW_MSG_JOIN_REQUEST, "Join Request"},
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#include "capwap.h"
|
#include "capwap.h"
|
||||||
|
|
||||||
struct cw_strlist capwap_strings_state[] = {
|
struct cw_str capwap_strings_state[] = {
|
||||||
{ CW_STATE_DISCOVERY, "Discovery" },
|
{ CW_STATE_DISCOVERY, "Discovery" },
|
||||||
{ CW_STATE_JOIN,"Join" },
|
{ CW_STATE_JOIN,"Join" },
|
||||||
{ CW_STATE_RUN,"Run" },
|
{ CW_STATE_RUN,"Run" },
|
||||||
|
{ CW_STATE_CONFIGURE,"Configure" },
|
||||||
{ 0,"Undefined" }
|
{ 0,"Undefined" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "capwap.h"
|
#include "capwap.h"
|
||||||
|
|
||||||
|
|
||||||
struct cw_strlist capwap_strings_vendor[] = {
|
struct cw_str capwap_strings_vendor[] = {
|
||||||
{ CW_VENDOR_ID_CISCO, "Cisco" },
|
{ CW_VENDOR_ID_CISCO, "Cisco" },
|
||||||
{ CW_VENDOR_ID_ZYXEL, "Zyxel" },
|
{ CW_VENDOR_ID_ZYXEL, "Zyxel" },
|
||||||
{ CW_VENDOR_ID_FSF, "FSF"}
|
{ CW_VENDOR_ID_FSF, "FSF"}
|
||||||
|
@ -1,28 +1,71 @@
|
|||||||
|
|
||||||
#include "capwap.h"
|
#include "capwap.h"
|
||||||
|
#include "capwap_cisco.h"
|
||||||
#include "capwap_actions.h"
|
#include "capwap_actions.h"
|
||||||
|
#include "cipwap.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@file
|
||||||
|
*brief CIPWAP Actions
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cw_action_in_t cipwap_actions_ac_in[] = {
|
cw_action_in_t cipwap_actions_ac_in[] = {
|
||||||
|
|
||||||
/* Element Discovery Type */
|
/* -------------------------------------------------------------------------------
|
||||||
{0, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_ELEM_DISCOVERY_TYPE,
|
* Discovery Request IN
|
||||||
cw_in_generic, 0, CW_ITEMTYPE_BYTE, CW_ITEM_DISCOVERY_TYPE, 4, 4}
|
*/
|
||||||
|
|
||||||
|
{CW_VENDOR_ID_CISCO, 0, CW_STATE_DISCOVERY, CW_MSG_DISCOVERY_REQUEST, CW_CISCO_RAD_NAME,
|
||||||
|
cw_in_generic, 0, CW_ITEMTYPE_STR,CW_ITEM_WTP_NAME,1,512}
|
||||||
|
,
|
||||||
|
|
||||||
|
|
||||||
|
{CW_VENDOR_ID_CISCO, 0, CW_STATE_JOIN, CW_MSG_JOIN_REQUEST, CW_CISCO_AP_GROUP_NAME,
|
||||||
|
cw_in_generic, 0, CW_ITEMTYPE_STR,CW_ITEM_WTP_GROUP_NAME,1,512}
|
||||||
|
,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{0,0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern struct cw_item *cw_get_local(struct conn *conn, struct cw_action_out *a);
|
||||||
|
|
||||||
|
cw_action_out_t cipwap_actions_ac_out[] = {
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------------
|
||||||
|
* Discovery Response OUT
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* AC Descriptor (Cisco) */
|
||||||
|
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_DESCRIPTOR, 0 ,
|
||||||
|
CW_ELEM_AC_DESCRIPTOR, cw_out_cisco_ac_descriptor, 0}
|
||||||
|
,
|
||||||
|
|
||||||
|
/* Cisco AP Timesync - Important to get the WTP a DTLS
|
||||||
|
connection stablished*/
|
||||||
|
{CW_MSG_DISCOVERY_RESPONSE, CW_ITEM_AC_TIMESTAMP, CW_VENDOR_ID_CISCO,
|
||||||
|
CW_CISCO_AP_TIMESYNC, cw_out_cisco_ap_timesync, 0}
|
||||||
|
,
|
||||||
|
|
||||||
|
|
||||||
|
{0,0,0}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register CiPWAP actions
|
||||||
|
*/
|
||||||
int cw_register_actions_cipwap_ac(struct cw_actiondef *def)
|
int cw_register_actions_cipwap_ac(struct cw_actiondef *def)
|
||||||
{
|
{
|
||||||
cw_register_actions_capwap_ac(def);
|
cw_register_actions_capwap_ac(def);
|
||||||
|
|
||||||
|
|
||||||
cw_actionlist_in_register_actions(def->in, cipwap_actions_ac_in);
|
cw_actionlist_in_register_actions(def->in, cipwap_actions_ac_in);
|
||||||
// cw_actionlist_out_register_actions(def->out, capwap_actions_ac_out);
|
cw_actionlist_out_register_actions(def->out, cipwap_actions_ac_out);
|
||||||
|
cw_strheap_register_strings(def->strelem,cipwap_strings_elem);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief Connection object stuff
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __CONN_H
|
#ifndef __CONN_H
|
||||||
#define __CONN_H
|
#define __CONN_H
|
||||||
@ -35,14 +39,18 @@
|
|||||||
|
|
||||||
#include "itemstore.h"
|
#include "itemstore.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection Object
|
||||||
|
*/
|
||||||
struct conn {
|
struct conn {
|
||||||
int sock;
|
int sock;
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
int recv_timeout;
|
int recv_timeout;
|
||||||
|
|
||||||
cw_itemstore_t itemstore;
|
/** Basically used to store local conig data */
|
||||||
|
|
||||||
cw_itemstore_t local;
|
cw_itemstore_t local;
|
||||||
|
/** used to maintain the remote config, an AC holds here the WTP config.
|
||||||
|
A WTP holds here data about it's AC */
|
||||||
cw_itemstore_t remote;
|
cw_itemstore_t remote;
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,12 +32,15 @@ static int message_cb(void *p, uint8_t *rawmsg, int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void conn_msg_processor(struct conn *conn)
|
int conn_msg_processor(struct conn *conn)
|
||||||
{
|
{
|
||||||
uint8_t buf[2024];
|
uint8_t buf[2024];
|
||||||
int len = 2024;
|
int len = 2024;
|
||||||
|
|
||||||
int n = conn->read(conn, buf, len);
|
int n = conn->read(conn, buf, len);
|
||||||
|
if (n<0 )
|
||||||
|
return n;
|
||||||
|
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
conn_process_packet(conn, buf, n, cw_process_msg, conn);
|
conn_process_packet(conn, buf, n, cw_process_msg, conn);
|
||||||
|
|
||||||
|
@ -1,5 +1,38 @@
|
|||||||
#include "cw_log.h"
|
#include "cw_log.h"
|
||||||
#include "capwap.h"
|
#include "capwap.h"
|
||||||
|
#include "capwap_cisco.h"
|
||||||
|
#include "dbg.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int cw_format_vendor(char *dst, uint32_t vendor_id, int elem_id, const uint8_t * elem_data)
|
||||||
|
{
|
||||||
|
switch (vendor_id) {
|
||||||
|
case CW_VENDOR_ID_CISCO:
|
||||||
|
{
|
||||||
|
sprintf(dst, "%d - %s", elem_id,
|
||||||
|
cw_cisco_id_to_str(elem_id));
|
||||||
|
|
||||||
|
/* dive into LWAPP vendor specific decoding */
|
||||||
|
/*
|
||||||
|
if (elem_id == CW_CISCO_SPAM_VENDOR_SPECIFIC) {
|
||||||
|
uint32_t lw_elem_id = lw_get_word(elem_data + 4 + 6);
|
||||||
|
char b[256];
|
||||||
|
sprintf(b, "\n\t LWAPP Cisco Specific: %d - %s",
|
||||||
|
lw_elem_id, lw_cisco_id_to_str(lw_elem_id));
|
||||||
|
strcat(dst, b);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -7,7 +40,7 @@
|
|||||||
* print debug info for message elements
|
* print debug info for message elements
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void cw_dbg_elem_(int msg, int msgelem, const uint8_t * msgbuf, int len)
|
void cw_dbg_elem_(struct conn * conn, int msg, int msgelem, const uint8_t * msgbuf, int len)
|
||||||
{
|
{
|
||||||
if (!cw_dbg_is_level(DBG_ELEM))
|
if (!cw_dbg_is_level(DBG_ELEM))
|
||||||
return;
|
return;
|
||||||
@ -20,26 +53,26 @@ void cw_dbg_elem_(int msg, int msgelem, const uint8_t * msgbuf, int len)
|
|||||||
if (msgelem == CW_ELEM_VENDOR_SPECIFIC_PAYLOAD) {
|
if (msgelem == CW_ELEM_VENDOR_SPECIFIC_PAYLOAD) {
|
||||||
uint32_t vendor_id = ntohl(*((uint32_t *) msgbuf));
|
uint32_t vendor_id = ntohl(*((uint32_t *) msgbuf));
|
||||||
int type = ntohs(*((uint16_t *) (msgbuf + 4)));
|
int type = ntohs(*((uint16_t *) (msgbuf + 4)));
|
||||||
sprintf(vendorname, "%s/%s/%d",
|
|
||||||
(char *) cw_strelem(msgelem),
|
|
||||||
(char *) lw_vendor_id_to_str(vendor_id), type);
|
|
||||||
elemname = vendorname;
|
|
||||||
cw_format_vendor(vendor_details, vendor_id, type, msgbuf);
|
cw_format_vendor(vendor_details, vendor_id, type, msgbuf);
|
||||||
|
sprintf(vendorname, "%s/%s/%s",
|
||||||
|
cw_strelemp(conn->actions,msgelem),
|
||||||
|
(char *) lw_vendor_id_to_str(vendor_id), vendor_details);
|
||||||
|
elemname = vendorname;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
elemname = cw_strelem(msgelem);
|
elemname = cw_strelemp(conn->actions,msgelem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!cw_dbg_is_level(DBG_ELEM_DMP))
|
if (!cw_dbg_is_level(DBG_ELEM_DMP))
|
||||||
cw_dbg(DBG_ELEM,
|
cw_dbg(DBG_ELEM,
|
||||||
"%s, CAWPAP element: %d (%s), len=%d%s",
|
"%s, CAWPAP element: %d (%s), len=%d%s",
|
||||||
cw_strmsg(msg), msgelem, elemname, len, vendor_details);
|
cw_strmsg(msg), msgelem, elemname, len, "");
|
||||||
|
|
||||||
else
|
else
|
||||||
cw_dbg_dmp(DBG_ELEM, msgbuf, len,
|
cw_dbg_dmp(DBG_ELEM, msgbuf, len,
|
||||||
"%s, CAPWAP element: %d (%s), len=%d%s\n\tDump ...",
|
"%s, CAPWAP element: %d (%s), len=%d%s\n\tDump ...",
|
||||||
cw_strmsg(msg), msgelem, elemname, len, vendor_details);
|
cw_strmsg(msg), msgelem, elemname, len, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ int cw_in_generic(struct conn *conn,struct cw_action_in * a,uint8_t *data,int le
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cw_itemstore_set(conn->itemstore,a->item_id,a->itemtype,data,len);
|
cw_itemstore_set(conn->remote,a->item_id,a->itemtype,data,len);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action_in * a,uint
|
|||||||
|
|
||||||
as.vendor_id = cw_get_dword(data);
|
as.vendor_id = cw_get_dword(data);
|
||||||
as.elem_id = cw_get_word(data+4);
|
as.elem_id = cw_get_word(data+4);
|
||||||
// printf("Vendor Specific: %d, %d\n",as.vendor_id,as.elem_id);
|
|
||||||
|
|
||||||
af = cw_actionlist_in_get(conn->actions->in,&as);
|
af = cw_actionlist_in_get(conn->actions->in,&as);
|
||||||
|
|
||||||
@ -27,8 +26,6 @@ int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action_in * a,uint
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Found\n");
|
|
||||||
|
|
||||||
if (af->start) {
|
if (af->start) {
|
||||||
af->start(conn,af,data+6,len-6);
|
af->start(conn,af,data+6,len-6);
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ int cw_in_wtp_board_data(struct conn *conn, struct cw_action_in *a, uint8_t * da
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cw_itemstore_t itemstore = conn->itemstore;
|
cw_itemstore_t itemstore = conn->remote;
|
||||||
cw_itemstore_set_dword(itemstore, CW_ITEM_WTP_BOARD_VENDOR,cw_get_dword(data));
|
cw_itemstore_set_dword(itemstore, CW_ITEM_WTP_BOARD_VENDOR,cw_get_dword(data));
|
||||||
|
|
||||||
readsubelems_wtp_board_data(itemstore,data+4,len-4);
|
readsubelems_wtp_board_data(itemstore,data+4,len-4);
|
||||||
|
@ -34,7 +34,7 @@ static int readelem_wtp_descriptor(struct conn *conn, struct cw_action_in *a, ui
|
|||||||
if (len<6)
|
if (len<6)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
cw_itemstore_t itemstore = conn->itemstore;
|
cw_itemstore_t itemstore = conn->remote;
|
||||||
|
|
||||||
cw_itemstore_set_byte(itemstore,CW_ITEM_WTP_MAX_RADIOS,cw_get_byte(data));
|
cw_itemstore_set_byte(itemstore,CW_ITEM_WTP_MAX_RADIOS,cw_get_byte(data));
|
||||||
cw_itemstore_set_byte(itemstore,CW_ITEM_WTP_RADIOS_IN_USE,cw_get_byte(data+1));
|
cw_itemstore_set_byte(itemstore,CW_ITEM_WTP_RADIOS_IN_USE,cw_get_byte(data+1));
|
||||||
|
@ -13,14 +13,21 @@ void cw_init(struct conn * conn, uint8_t *buffer, int type, int seqnum, struct r
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cw_init_response(struct conn * conn, uint8_t *req)
|
void cw_init_response(struct conn * conn, uint8_t *req)
|
||||||
{
|
{
|
||||||
uint8_t *buffer=conn->resp_buffer;
|
uint8_t *buffer=conn->resp_buffer;
|
||||||
int hbytes = cw_get_hdr_msg_offset(req);
|
int shbytes = cw_get_hdr_msg_offset(req);
|
||||||
memcpy(buffer,req,hbytes);
|
int dhbytes;
|
||||||
|
memcpy(buffer,req,shbytes);
|
||||||
|
cw_set_hdr_hlen(buffer,2);
|
||||||
|
cw_set_hdr_flags(buffer,CW_FLAG_HDR_M,1);
|
||||||
|
dhbytes = cw_get_hdr_msg_offset(buffer);
|
||||||
|
|
||||||
uint8_t * msgptr = req+hbytes;
|
uint8_t * msgptr = req+shbytes;
|
||||||
uint8_t * dmsgptr = buffer+hbytes;
|
uint8_t * dmsgptr = buffer+dhbytes;
|
||||||
|
|
||||||
cw_set_msg_type(dmsgptr,cw_get_msg_type(msgptr)+1);
|
cw_set_msg_type(dmsgptr,cw_get_msg_type(msgptr)+1);
|
||||||
cw_set_msg_seqnum(dmsgptr,cw_get_msg_seqnum(msgptr));
|
cw_set_msg_seqnum(dmsgptr,cw_get_msg_seqnum(msgptr));
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
#include "capwap.h"
|
#include "capwap.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
int cw_put_subelem_version(uint8_t *dst,uint16_t subelem_id, uint32_t vendor_id,bstr16_t data)
|
int cw_put_subelem_version(uint8_t *dst,uint16_t subelem_id, uint32_t vendor_id,bstr16_t data)
|
||||||
{
|
{
|
||||||
printf("Vendor putter %d\n",vendor_id);
|
|
||||||
|
|
||||||
uint8_t *d=dst;
|
uint8_t *d=dst;
|
||||||
d += cw_put_dword(d,vendor_id);
|
d += cw_put_dword(d,vendor_id);
|
||||||
@ -16,10 +16,10 @@ printf("Vendor putter %d\n",vendor_id);
|
|||||||
d += cw_put_data(d,bstr16_data(data),bstr16_len(data));
|
d += cw_put_data(d,bstr16_data(data),bstr16_len(data));
|
||||||
return d-dst;
|
return d-dst;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
int cw_out_ac_descriptor(struct conn *conn,struct cw_action_out * a,uint8_t *dst)
|
||||||
int cw_out_ac_descriptor(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
uint8_t *d = dst+4;
|
uint8_t *d = dst+4;
|
||||||
@ -31,18 +31,14 @@ int cw_out_ac_descriptor(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cw_ac_status *s = (struct cw_ac_status*)(i->data);
|
d+=cw_put_ac_status(d ,(struct cw_ac_status*)(i->data));
|
||||||
|
|
||||||
d += cw_put_dword (d, (s->stations << 16) | (s->limit) );
|
|
||||||
d += cw_put_dword (d, (s->active_wtps <<16) | (s->max_wtps) );
|
|
||||||
d += cw_put_dword (d, (s->security<<24) | (s->rmac_field<<16) | (s->dtls_policy));
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
i = cw_itemstore_get(conn->local,CW_ITEM_AC_HARDWARE_VERSION);
|
i = cw_itemstore_get(conn->local,CW_ITEM_AC_HARDWARE_VERSION);
|
||||||
|
|
||||||
if ( i ) {
|
if ( i ) {
|
||||||
d += cw_put_subelem_version(d,CW_SUBELEM_AC_HARDWARE_VERSION,*((uint32_t*)(i->data)),i->data+4);
|
d += cw_put_version(d,CW_SUBELEM_AC_HARDWARE_VERSION,*((uint32_t*)(i->data)),i->data+4);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cw_dbg(DBG_ELEM_ERR, "Can't send hard version in AC descriptor, not set.");
|
cw_dbg(DBG_ELEM_ERR, "Can't send hard version in AC descriptor, not set.");
|
||||||
@ -52,7 +48,7 @@ int cw_out_ac_descriptor(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct
|
|||||||
i = cw_itemstore_get(conn->local,CW_ITEM_AC_SOFTWARE_VERSION);
|
i = cw_itemstore_get(conn->local,CW_ITEM_AC_SOFTWARE_VERSION);
|
||||||
|
|
||||||
if ( i ) {
|
if ( i ) {
|
||||||
d += cw_put_subelem_version(d,CW_SUBELEM_AC_SOFTWARE_VERSION,*((uint32_t*)(i->data)),i->data+4);
|
d += cw_put_version(d,CW_SUBELEM_AC_SOFTWARE_VERSION,*((uint32_t*)(i->data)),i->data+4);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cw_dbg(DBG_ELEM_ERR, "Can't send software version in AC descriptor, not set.");
|
cw_dbg(DBG_ELEM_ERR, "Can't send software version in AC descriptor, not set.");
|
||||||
@ -60,7 +56,7 @@ int cw_out_ac_descriptor(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct
|
|||||||
|
|
||||||
int len = d-dst-4;
|
int len = d-dst-4;
|
||||||
|
|
||||||
return len + cw_put_elem_hdr(dst,CW_ELEM_AC_DESCRIPTOR,len);
|
return len + cw_put_elem_hdr(dst,a->elem_id,len);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +41,10 @@ static int put_ip(void *priv, void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int cw_out_capwap_control_ip_addrs(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item)
|
int cw_out_capwap_control_ip_addrs(struct conn *conn,struct cw_action_out *a,uint8_t *dst)
|
||||||
{
|
{
|
||||||
|
struct cw_item * item = cw_itemstore_get(conn->local,a->item_id);
|
||||||
|
|
||||||
if ( !item ) {
|
if ( !item ) {
|
||||||
cw_log(LOG_ERR, "Can't send CAPWAP Local IPv4/IPv6 Address, not found");
|
cw_log(LOG_ERR, "Can't send CAPWAP Local IPv4/IPv6 Address, not found");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -9,27 +9,50 @@ int cw_put_item(uint8_t *dst,struct cw_item*item)
|
|||||||
{
|
{
|
||||||
switch (item->type){
|
switch (item->type){
|
||||||
case CW_ITEMTYPE_STR:
|
case CW_ITEMTYPE_STR:
|
||||||
printf("Outing str %s\n",item->data);
|
|
||||||
return cw_put_data(dst,item->data,strlen( (char*)item->data));
|
return cw_put_data(dst,item->data,strlen( (char*)item->data));
|
||||||
case CW_ITEMTYPE_BYTE:
|
case CW_ITEMTYPE_BYTE:
|
||||||
return cw_put_byte(dst,item->byte);
|
return cw_put_byte(dst,item->byte);
|
||||||
case CW_ITEMTYPE_WORD:
|
case CW_ITEMTYPE_WORD:
|
||||||
return cw_put_word(dst,item->word);
|
return cw_put_word(dst,item->word);
|
||||||
case CW_ITEMTYPE_DWORD:
|
case CW_ITEMTYPE_DWORD:
|
||||||
return cw_put_word(dst,item->dword);
|
return cw_put_dword(dst,item->dword);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cw_out_generic(struct conn *conn,uint32_t elem_id,uint8_t *dst,struct cw_item * item)
|
int cw_out_generic(struct conn *conn,struct cw_action_out *a,uint8_t *dst) // ,struct cw_item * item)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/* Get the item to put */
|
||||||
|
struct cw_item *item=NULL;
|
||||||
|
if (a->get){
|
||||||
|
item = a->get (conn,a);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Out generic item %p\n",item);
|
||||||
|
|
||||||
|
/* Size for msg elem header depends on
|
||||||
|
vendor specific payload */
|
||||||
|
int start = a->vendor_id ? 10:4;
|
||||||
|
|
||||||
|
|
||||||
int len;
|
int len;
|
||||||
if ( !item )
|
if ( !item )
|
||||||
len=0;
|
len=0;
|
||||||
else
|
else{
|
||||||
len = cw_put_item(dst+4,item);
|
printf("Putting it\n");
|
||||||
return len + cw_put_elem_hdr(dst,elem_id,len);
|
printf("To put: %d %s\n",len,item->data);
|
||||||
|
len = cw_put_item(dst+start,item);
|
||||||
|
printf("Putted: %d %s\n",len,item->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (a->vendor_id)
|
||||||
|
return len + cw_put_elem_vendor_hdr(dst,a->vendor_id,a->elem_id,len);
|
||||||
|
|
||||||
|
return len + cw_put_elem_hdr(dst,a->elem_id,len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -12,174 +12,26 @@
|
|||||||
#include "dbg.h"
|
#include "dbg.h"
|
||||||
|
|
||||||
|
|
||||||
|
//int cw_out_msg(struct conn *conn, uint8_t * rawout);
|
||||||
|
|
||||||
int snd_cb(void *c, void *d)
|
|
||||||
{
|
|
||||||
struct conn *conn = (struct conn *) c;
|
|
||||||
struct cw_action_in *a = (struct cw_action_in *) d;
|
|
||||||
|
|
||||||
if (a->start) {
|
|
||||||
a->start(conn, a, conn->resp_buffer, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern int cw_init_response(struct conn *conn, uint8_t * req);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct priv {
|
|
||||||
struct conn *conn;
|
|
||||||
uint8_t *buffer;
|
|
||||||
uint32_t msg_id;
|
|
||||||
int len;
|
|
||||||
};
|
|
||||||
|
|
||||||
int cw_additems_cb(void *p, void *i)
|
|
||||||
{
|
|
||||||
struct priv *priv = (struct priv *) p;
|
|
||||||
|
|
||||||
struct cw_item *item = (struct cw_item *) i;
|
|
||||||
|
|
||||||
printf("Item: %d - %d \n", priv->msg_id, item->id);
|
|
||||||
|
|
||||||
cw_action_out_t as;
|
|
||||||
as.item_id = item->id;
|
|
||||||
as.msg_id = priv->msg_id;
|
|
||||||
|
|
||||||
|
|
||||||
cw_action_out_t *a = cw_actionlist_out_get(priv->conn->actions->out, &as);
|
|
||||||
|
|
||||||
if (!a) {
|
|
||||||
printf("No out action found for %d\n", item->id);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Out action found\n");
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
int cw_additems( struct conn *conn,cw_itemstore_t itemstore)
|
|
||||||
{
|
|
||||||
struct priv priv;
|
|
||||||
priv.msg_id=CW_MSG_DISCOVERY_RESPONSE;
|
|
||||||
priv.conn=conn;
|
|
||||||
|
|
||||||
avltree_foreach_asc(itemstore, cw_additems_cb,&priv);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
int cb(void *p, void *ain)
|
|
||||||
{
|
|
||||||
cw_action_out_t *a = (cw_action_out_t *) ain;
|
|
||||||
struct priv *priv = (struct priv *) p;
|
|
||||||
if (priv->msg_id != a->msg_id)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!a->item_id)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
printf("Put Msg ID %d (%s) - %d\n", a->msg_id, cw_strmsg(a->msg_id), a->elem_id);
|
|
||||||
|
|
||||||
struct cw_item *item = NULL;
|
|
||||||
if (a->get)
|
|
||||||
item = a->get(priv->conn, a->item_id);
|
|
||||||
|
|
||||||
int l = 0;
|
|
||||||
|
|
||||||
uint8_t *buffer = priv->buffer + priv->len;
|
|
||||||
printf("Writing to %p\n", buffer);
|
|
||||||
|
|
||||||
|
|
||||||
if (a->out) {
|
|
||||||
l = a->out(priv->conn, a->elem_id, buffer, item);
|
|
||||||
printf("The length is %d\n", l);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("+++++++++++++++++++Adding %d to privlen\n", l);
|
|
||||||
priv->len += l;
|
|
||||||
printf("Priveln is now %d\n", priv->len);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int conn_send_msg(struct conn *conn, uint8_t * rawmsg);
|
int conn_send_msg(struct conn *conn, uint8_t * rawmsg);
|
||||||
|
|
||||||
int cw_send_response(struct conn *conn, uint8_t * rawmsg, int len)
|
int cw_send_response(struct conn *conn, uint8_t * rawmsg, int len)
|
||||||
{
|
{
|
||||||
struct priv priv;
|
// struct priv priv;
|
||||||
|
|
||||||
cw_init_response(conn, rawmsg);
|
cw_init_response(conn, rawmsg);
|
||||||
|
|
||||||
|
|
||||||
uint8_t *msgptr = rawmsg + cw_get_hdr_msg_offset(rawmsg);
|
// uint8_t *msgptr = rawmsg + cw_get_hdr_msg_offset(rawmsg);
|
||||||
|
|
||||||
cw_action_out_t as;
|
// cw_action_out_t as;
|
||||||
|
|
||||||
as.msg_id = cw_get_msg_type(msgptr) + 1;
|
|
||||||
as.item_id = CW_ITEM_NONE;
|
|
||||||
|
|
||||||
priv.msg_id = as.msg_id;
|
|
||||||
priv.conn = conn;
|
|
||||||
priv.len = 0;
|
|
||||||
priv.buffer = cw_get_hdr_msg_elems_ptr(conn->resp_buffer);
|
|
||||||
|
|
||||||
int off = cw_get_hdr_msg_offset(conn->resp_buffer);
|
|
||||||
printf("Offset is %d\n", off);
|
|
||||||
|
|
||||||
avltree_foreach_from_asc(conn->actions->out, &as, cb, &priv);
|
|
||||||
|
|
||||||
uint8_t *smptr = conn->resp_buffer + cw_get_hdr_msg_offset(conn->resp_buffer);
|
|
||||||
printf("Send Type: %d\n", cw_get_msg_type(smptr));
|
|
||||||
|
|
||||||
|
|
||||||
printf("The total msgelems length is %d\n", priv.len);
|
cw_put_msg(conn,conn->resp_buffer);
|
||||||
|
|
||||||
int offset = cw_get_hdr_msg_offset(conn->resp_buffer);
|
|
||||||
|
|
||||||
printf("Privlen = %d\n", priv.len);
|
|
||||||
cw_set_msg_elems_len(conn->resp_buffer + offset, priv.len);
|
|
||||||
|
|
||||||
int total = cw_get_hdr_msg_total_len(conn->resp_buffer);
|
|
||||||
|
|
||||||
printf("TOTAL lenz: %p %d\n", conn->resp_buffer, total);
|
|
||||||
|
|
||||||
conn_send_msg(conn, conn->resp_buffer);
|
conn_send_msg(conn, conn->resp_buffer);
|
||||||
|
return 1;
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
printf("The repoinse finder\n");
|
|
||||||
|
|
||||||
struct cw_action_in as,*af;
|
|
||||||
uint8_t * msg_ptr = rawmsg+cw_get_hdr_msg_offset(rawmsg);
|
|
||||||
|
|
||||||
as.msg_id = cw_get_msg_id(msg_ptr)+1;
|
|
||||||
if (as.msg_id & 1)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
printf("Message ID = %d\n",as.msg_id);
|
|
||||||
|
|
||||||
as.elem_id=0;
|
|
||||||
as.vendor_id=0;
|
|
||||||
as.proto=1;
|
|
||||||
as.capwap_state=1;
|
|
||||||
//avltree_foreach_from_asc(conn->msgtr, &as,snd_cb,conn);
|
|
||||||
|
|
||||||
printf("BLA\n");
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -248,7 +100,7 @@ int cw_process_msg(struct conn *conn, uint8_t * rawmsg, int len)
|
|||||||
as.elem_id = cw_get_elem_id(elem);
|
as.elem_id = cw_get_elem_id(elem);
|
||||||
int elem_len = cw_get_elem_len(elem);
|
int elem_len = cw_get_elem_len(elem);
|
||||||
|
|
||||||
cw_dbg_elem(as.msg_id, as.elem_id, cw_get_elem_data(elem), elem_len);
|
cw_dbg_elem(conn,as.msg_id, as.elem_id, cw_get_elem_data(elem), elem_len);
|
||||||
|
|
||||||
|
|
||||||
af = cw_actionlist_in_get(conn->actions->in, &as);
|
af = cw_actionlist_in_get(conn->actions->in, &as);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#include "capwap.h"
|
#include "capwap.h"
|
||||||
|
|
||||||
const char * cw_strlist_get_str(struct cw_strlist *s,int id)
|
const char * cw_strlist_get_str(struct cw_str *s,int id)
|
||||||
{
|
{
|
||||||
while ( s->id!=0){
|
while ( s->id!=0){
|
||||||
if (s->id==id)
|
if (s->id==id)
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
#ifndef __DBG_H
|
#ifndef __DBG_H
|
||||||
#define __DBG_H
|
#define __DBG_H
|
||||||
|
|
||||||
|
#include "conn.h"
|
||||||
|
|
||||||
|
void cw_dbg_elem_(struct conn * conn, int msg, int msgelem, const uint8_t * msgbuf, int len);
|
||||||
void cw_dbg_elem_(int msg, int msgelem, const uint8_t * msgbuf, int len);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef WITH_CW_LOG_DEBUG
|
#ifdef WITH_CW_LOG_DEBUG
|
||||||
|
|
||||||
#define cw_dbg_elem(msgtype,msgelemtype,msgbuf,msglen) cw_dbg_elem_(msgtype,msgelemtype,msgbuf,msglen)
|
#define cw_dbg_elem(conn,msgtype,msgelemtype,msgbuf,msglen) cw_dbg_elem_(conn,msgtype,msgelemtype,msgbuf,msglen)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user