More work on CAPWAP state machine...

FossilOrigin-Name: c9f31c71d46610612aafb5b4935aece949463d88eb86e4c22afa6991346185eb
This commit is contained in:
7u83@mail.ru 2015-04-05 00:07:59 +00:00
parent fbd0c126fb
commit fcd4b31c85
42 changed files with 894 additions and 619 deletions

View File

@ -50,6 +50,7 @@ AC_OBJS = wtplist.o wtpman.o conf.o ac_main.o \
ac_interface.o \
socklist.o \
db.o \
ac_global.o
AC_SRCS = $(AC_OBJS:.o=.c)
AC_DEPS := $(AC_OBJS:.o=.d)
@ -61,6 +62,11 @@ AC_NAME = actube
# top-level rule, to compile everything.
all: $(AC_NAME)
%.o:%.c
@echo " CC "$<
@$(CC) -c $(CFLAGS) $< -o $@
$(AC_NAME): $(AC_OBJS)
$(CC) $(AC_OBJS) -o $(AC_NAME) $(LDFLAGS) $(LIBS)

View File

@ -12,42 +12,7 @@
#include "capwap.h"
#include "capwap_80211.h"
ACIPLIST * get_aciplist()
{
int i=0;
ACIPLIST * aciplist = aciplist_create();
if(!aciplist)
return 0;
for (i=0; i<socklist_len;i++){
if (socklist[i].type != SOCKLIST_UNICAST_SOCKET)
break;
struct sockaddr_storage sa;
unsigned int salen=sizeof(sa);
if ( getsockname(socklist[i].sockfd,(struct sockaddr*)&sa,&salen)<0)
continue;
ACIP * acip;
acip = malloc(sizeof(ACIP));
if (!acip)
continue;
sock_copyaddr(&acip->ip,(struct sockaddr*)&sa);
acip->wtp_count=0;
// printf ("Adding IP %s\n",sock_addr2str(&acip->ip));
aciplist_add(aciplist,acip);
}
return aciplist;
}
#include "aciplist.h"
@ -91,7 +56,7 @@ struct ac_info * get_acinfo()
acinfo->security|=AC_SECURITY_X;
acinfo->dtls_policy = AC_DTLS_POLICY_C | AC_DTLS_POLICY_D ;
// acinfo->dtls_policy = AC_DTLS_POLICY_C | AC_DTLS_POLICY_D ;
// acinfo->ac_ips = conf_ac_ips;
// acinfo->ac_ips_len=conf_ac_ips_len;
@ -101,11 +66,11 @@ struct ac_info * get_acinfo()
// acinfo->salist = conf_ac_ips;
// acinfo->salist_len = conf_ac_ips_len;
acinfo->aciplist=get_aciplist();
//acinfo->aciplist=get_aciplist();
/*
aciplist_foreach(acinfo->aciplist,pr,NULL);
*/
int i;
for (i=1; i<=4; i++){
acinfo->radioinfos[i].type=

View File

@ -38,7 +38,7 @@
#include "capwap_items.h"
#include "capwap_cisco.h"
#include "ac.h"
int ac_run();
@ -50,23 +50,8 @@ void alive_thread(void *data)
}
}
#include "cw_action.h"
#include "action.h"
cw_actionlist_t the_tree;
int dstart(struct conn *conn,struct cw_action_t * a,uint8_t *data,int len)
{
printf("DISCO STart Action!!\n");
uint8_t * rmac = cw_get_hdr_rmac(data);
printf ("This msg is for %s\n",sock_hwaddr2str(bstr_data(rmac), bstr_len(rmac)));
}
int readelem_discovery_type(struct conn *conn,struct cw_action * a,uint8_t *data,int len)
{
printf("Discovery Type = %d\n",*data);
cw_itemstore_set_byte(conn->itemstore,CW_ITEM_DISCOVERY_TYPE,*data);
}
/*
int readelem_vendor_specific_payload(struct conn *conn,struct cw_action * a,uint8_t *data,int len)
@ -99,6 +84,7 @@ int readelem_vendor_specific_payload(struct conn *conn,struct cw_action * a,uint
*/
/*
int readelem_cisco_rad_name(struct conn *conn,struct cw_action * a,uint8_t *data,int len)
{
printf("Here is the rad name reader\n");
@ -109,7 +95,7 @@ int readelem_cisco_rad_name(struct conn *conn,struct cw_action * a,uint8_t *data
}
printf("\n");
}
*/
@ -117,116 +103,32 @@ int readelem_cisco_rad_name(struct conn *conn,struct cw_action * a,uint8_t *data
int main (int argc, const char * argv[])
{
cw_actionlist_t t = cw_actionlist_create();
the_tree=t;
cw_action_t discovery_actions[] = {
{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST,-1,
dstart,0 },
{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_DISCOVERY_TYPE,
readelem_discovery_type,0 },
{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_VENDOR_SPECIFIC_PAYLOAD,
cw_in_vendor_specific_payload,0 },
{ CW_VENDOR_ID_CISCO,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_CISCO_RAD_NAME,
cw_in_wtp_name,0 },
{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_BOARD_DATA,
cw_in_wtp_board_data,0 },
/*
{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_DESCRIPTOR},
{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_FRAME_TUNNEL_MODE},
{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_MAC_TYPE},
*/
{ 0,0,0}
};
cw_action_t join_actions[] = {
{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST,-1,0,0},
{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_DISCOVERY_TYPE},
{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_BOARD_DATA},
{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_DESCRIPTOR},
{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_FRAME_TUNNEL_MODE},
{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_MAC_TYPE},
{0}
};
cw_register_actions(t,discovery_actions);
cw_register_actions(t,join_actions);
#define CW_NAME_DISCOVER_REQUEST "Discovery Request"
/*
int i;
for(i=0; discovery[i].capwap_state!=CW_STATE_MAX; i++){
printf("State: %d MSG_ID: %d ELEM_ID: %d\n",discovery[i].capwap_state,discovery[i].msg_id,discovery[i].elem_id);
void * rc = msgtree_add(t,&(discovery[i]));
printf("Added to tree %p\n",rc);
}
*/
/*
e.capwap_state=0;
e.msg_id = CW_MSG_DISCOVERY_REQUEST;
e.elem_id = CW_ELEM_AC_NAME;
e.name = "AC Name";
msgtree_add(t,&e);
*/
// send_image_file(0,"/home/tube/Downloads/c1130-rcvk9w8-tar.124-25e.JAP.tar");
cw_log_name="AC-Tube";
read_config("ac.conf");
// cw_log_debug_level=conf_debug_level;
cw_log(LOG_INFO,"Starting AC-Tube, Name=%s, ID=%s",conf_acname,conf_acid);
// cw_dbg_opt_level= DBG_CW_MSGELEM_DMP |
// DBG_CW_MSGELEM | DBG_CW_PKT| DBG_CW_RFC | DBG_ERR | DBG_CW_MSG | DBG_DTLS ; //| DBG_ALL;
cw_dbg_opt_detail=DBG_DETAIL_ASC_DMP;
// cw_log_dbg(DBG_CW_MSG,"Hello %s","World");
cw_register_actions_capwap_ac(&capwap_actions);
ac_global_init();
/*
db_init();
db_start();
db_ping();
pthread_t alth;
pthread_create (&alth, NULL, alive_thread, (void *)0);
#ifdef WITH_DTLS
*/
int rc=0;
dtls_init();
#endif
if (!socklist_init())
goto errX;
@ -234,13 +136,19 @@ msgtree_add(t,&e);
goto errX;
int rc = ac_run();
rc = ac_run();
errX:
wtplist_destroy();
socklist_destroy();
return rc;
}
void process_ctrl_packet(int index, struct sockaddr * addr, uint8_t * buffer, int len);
#define AC_PROTO_CAPWAP 0
#define AC_PROTO_LWAPP 1
@ -300,7 +208,7 @@ int ac_run()
get_acinfo();
//get_acinfo();
while(1){
@ -359,7 +267,7 @@ int ac_run()
void process_cw_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer, int len)
{
int sock = socklist[index].reply_sockfd;
// int sock = socklist[index].reply_sockfd;
char hdrstr[1024];
hdr_print(hdrstr,buffer,len);
@ -411,7 +319,7 @@ void process_cw_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer,
void process_lw_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer, int len)
{
int sock = socklist[index].reply_sockfd;
//int sock = socklist[index].reply_sockfd;
uint8_t * m = buffer+6;
uint32_t val = ntohl(*((uint32_t*)(m)));
@ -457,10 +365,10 @@ void process_lw_ctrl_packet(int index,struct sockaddr * addr, uint8_t * buffer,
return;
};
wtpman_lw_start(wtpman);
//wtpman_lw_start(wtpman);
}
wtpman_lw_addpacket(wtpman,buffer,len);
//wtpman_lw_addpacket(wtpman,buffer,len);
wtplist_unlock();
}

View File

@ -164,7 +164,7 @@ static int init_acid()
static int init_dtls()
{
if (conf_dtls_psk!=NULL){
conf_security=CWACSECURITY_FLAGS_S;
// conf_security=CW_SECURITY_FLAGS_S;
}
return 1;
@ -456,7 +456,7 @@ int init_bcast_addrs()
conf_bcast_addrs=malloc(t->count*sizeof(char*));
stravltree_foreach(t,add_bcast_addr,0,1);
stravltree_foreach_asc(t,add_bcast_addr,0);
stravltree_destroy(t);
freeifaddrs(ifa0);

View File

@ -34,6 +34,12 @@
#include "cw_util.h"
#include "capwap_items.h"
#include "ac.h"
extern struct cw_actiondef capwap_actions;
/* macro to convert our client ip to a string */
//#define CLIENT_IP (sock_addrtostr((struct sockaddr*)&wtpman->conn->addr, (char[64]){0},64))
@ -352,7 +358,6 @@ static struct cwrmsg * wtpman_wait_for_message(struct wtpman * wtpman, time_t ti
static void wtpman_run_discovery(void *arg)
{
struct wtpman * wtpman = (struct wtpman *)arg;
struct cwrmsg * cwrmsg;
@ -360,19 +365,20 @@ static void wtpman_run_discovery(void *arg)
time_t timer = cw_timer_start(10);
extern cw_actionlist_t the_tree;
wtpman->conn->capwap_state=CW_STATE_DISCOVERY;
wtpman->conn->msgtr=the_tree;
extern cw_actionlist_in_t the_tree;
wtpman->conn->itemstore = cw_itemstore_create();
wtpman->conn->capwap_state=CW_STATE_DISCOVERY;
wtpman->conn->actions = &capwap_actions;
wtpman->conn->itemstore = cw_itemstore_create();
wtpman->conn->local = ac_config;
wtpman->conn->remote = cw_itemstore_create();
while ( !cw_timer_timeout(timer) && wtpman->conn->capwap_state==CW_STATE_DISCOVERY){
conn_msg_processor(wtpman->conn);
}
// cwsend_discovery_response(wtpman->conn,cwrmsg->seqnum,&radioinfo,acinfo,&wtpman->wtpinfo);
wtpman_remove(wtpman);
return;
@ -460,7 +466,7 @@ static void wtpman_run_run(void *arg)
printf("Update now?\n");
/*
conn_prepare_request(conn,CW_MSG_CONFIGURATION_UPDATE_REQUEST);
cwmsg_addelem(&conn->req_msg,CW_ELEM_WTP_NAME,(uint8_t*)"Tube7u83",strlen("Tube7u83")+1);
cwmsg_addelem(&conn->req_msg,CWMSGELEM_LOCATION_DATA,(uint8_t*)"Berlin",strlen("Berlin")+1);
@ -475,7 +481,7 @@ static void wtpman_run_run(void *arg)
printf("Wait...\n");
conn_wait_for_message(conn,t);
}
*/
printf("Adding WLAN\n");
@ -581,10 +587,40 @@ static int wtpman_join(void *arg,time_t timer)
{
struct wtpman * wtpman = (struct wtpman *)arg;
extern cw_actionlist_t the_tree;
wtpman->conn->msgtr=the_tree;
extern cw_actionlist_in_t the_tree;
wtpman->conn->actions=&capwap_actions;
wtpman->conn->capwap_state=CW_STATE_JOIN;
wtpman->conn->capwap_state=CW_STATE_JOIN;
wtpman->conn->actions = &capwap_actions;
wtpman->conn->itemstore = cw_itemstore_create();
wtpman->conn->local = ac_config;
wtpman->conn->remote = cw_itemstore_create();
while ( !cw_timer_timeout(timer) && wtpman->conn->capwap_state==CW_STATE_JOIN){
conn_msg_processor(wtpman->conn);
}
exit(0);
/* timer = cw_timer_start(wtpman->conn->wait_join); */
int join_msgs[] = { CW_MSG_JOIN_REQUEST, -1 };
@ -1055,7 +1091,7 @@ void wtpman_lw_addpacket(struct wtpman *wtpman, uint8_t *packet, int len)
void wtpman_start(struct wtpman * wtpman,int dtlsmode)
{
if ( dtlsmode ){
cw_dbg(DBG_CW_INFO,"Starting wtpman in dtls mode");
cw_dbg(DBG_CW_INFO,"Starting wtpman in DTLS mode");
pthread_create (&wtpman->thread, NULL, (void *) &wtpman_run, (void *) wtpman);
}
else{

View File

@ -38,7 +38,10 @@ LOGOBJS=cw_log.o \
cw_log_debug.o \
cw_log_tofile.o \
cw_log_tosyslog.o \
cw_log_str2dbglevel.o
cw_log_str2dbglevel.o \
cw_dbg_elem.o
WTPINFOOBJS = wtpinfo_set_location.o \
@ -50,12 +53,15 @@ UTILOBJS= \
cw_rand.o \
cw_foreach_msgelem.o \
avltree.o \
avltree_get.o \
avltree_get_node.o \
avltree_del_all.o \
avltree_foreach.o \
avltree_foreach_lr.o \
avltree_foreach_rl.o \
avltree_foreach_from_lr.o \
stravltree.o \
cw_util.o \
cw_format_version.o
cw_format_version.o \
cw_msg_init.o
@ -70,7 +76,8 @@ LWAPPOBJS = \
lw_vendor_id_to_str.o \
lw_elem_id_to_str.o \
lw_msg_id_to_str.o \
lw_cisco_id_to_str.o
lw_cisco_id_to_str.o \
lw_put_sockaddr.o \
@ -90,7 +97,6 @@ CAPWAPOBJS= \
cwmsg_vaddelem.o \
cwmsg_addelem_ac_descriptor.o \
cwmsg_addelem_wtp_descriptor.o \
cwmsg_addelem_ctrl_ip_addrs.o \
cwmsg_addelem_wtp_radio_infos.o \
cwmsg_addelem_wtp_board_data.o \
cwmsg_addelem_cw_local_ip_addr.o \
@ -108,8 +114,6 @@ CAPWAPOBJS= \
cw_read_image_data_request.o \
cw_send_image_data_response.o \
cw_send_configuration_update_response.o \
cwsend_join_request.o \
cwsend_join_response.o \
cwread_join_response.o \
cwsend_echo_request.o \
cw_send_echo_response.o \
@ -121,7 +125,6 @@ CAPWAPOBJS= \
cwread_change_state_event_request.o\
cwread_wtp_event_request.o \
process_conf_status_request.o \
process_join_request.o \
wtpinfo_readelem_wtp_board_data.o \
wtpinfo_readelem_wtp_mac_type.o \
wtpinfo_readelem_wtp_radio_info.o \
@ -139,8 +142,6 @@ CAPWAPOBJS= \
acinfo_print.o \
lwmsg_init.o \
wtpinfo_lwreadelem_wtp_descriptor.o \
cw_msgelemtostr.o \
cw_msgtostr.o \
hdr_print.o \
cw_readelem_ecn_support.o \
cw_readelem_maximum_message_length.o \
@ -165,11 +166,19 @@ CAPWAPOBJS= \
capwap_strings_msg.o \
capwap_strings_state.o \
capwap_strings_vendor.o \
capwap_strings_elem.o \
itemstore.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_ac_descriptor.o \
cw_out_capwap_control_ip_addrs.o
#cw_msgtostr.o \
#cw_msgelemtostr.o \
#cwmsg_addelem_ctrl_ip_addrs.o \
#process_join_request.o \
#cw_ianavendoridtostr.o \
#cwmsg_addelem_result_code.o \
@ -180,10 +189,12 @@ CAPWAPOBJS= \
#cwmsg_addelem_session_id.o
# process_msgelems_discovery_request.o \
# cwsend_join_request.o \
#
# cwsend_image_data_request.o
# cwmsg_set_control_header.o
# process_msgelems.o \
# cwsend_join_response.o \
#
# SSL objects
@ -235,7 +246,8 @@ CONNOBJS= conn_create.o \
conn_send_request.o \
conn_wait_for_message.o \
conn_wait_for_request.o \
conn_init.o
conn_init.o \
conn_send_msg.o
@ -247,8 +259,12 @@ BSTROBJS= bstr_create.o \
FRAGOBJS=fragman.o
CWACTION=cw_action.o \
cw_process_msg.o
CWACTION=action.o \
cw_process_msg.o \
capwap_actions_ac.o \
cw_in_generic.o \
cw_in_wtp_descriptor.o
OBJS=$(CONNOBJS) $(FRAGOBJS) $(SOCKOBJS) $(CAPWAPOBJS) $(WTPINFOOBJS) \
@ -281,7 +297,7 @@ $(ARCH)/%.o:%.c
@mkdir -p $(ARCH)
@echo " CC "$<
@$(CC) -c $(CFLAGS) $< -o $@
@$(CC) -MM $(CFLAGS) $< > $*.d
# @$(CC) -MM $(CFLAGS) $< > $*.d
$(ARCH)/$(NAME) : $(OBJS)
@echo " AR $(ARCH)/$(NAME)"

View File

@ -117,8 +117,10 @@ printf("sublen type = %d\n",subtype);
int acinfo_readelem_ctrl_ip_addr(struct ac_info * acinfo, int type, uint8_t*msgelem,int len)
{
/*
switch (type){
case CWMSGELEM_CONTROL_IPV4_ADDRESS:
case CW_ELEM_CONTROL_IPV4_ADDRESS:
{
if (len!=6)
return -1;
@ -147,7 +149,7 @@ int acinfo_readelem_ctrl_ip_addr(struct ac_info * acinfo, int type, uint8_t*msge
return 1;
}
case CWMSGELEM_CONTROL_IPV6_ADDRESS:
case CW_ELEM_CONTROL_IPV6_ADDRESS:
{
if (len!=18)
return -1;
@ -176,6 +178,8 @@ int acinfo_readelem_ctrl_ip_addr(struct ac_info * acinfo, int type, uint8_t*msge
}
return 0;
*/
}

View File

@ -14,6 +14,7 @@
#include "radioinfo.h"
/*
struct acip{
struct sockaddr_storage ip;
int wtp_count;
@ -25,7 +26,9 @@ typedef struct avltree ACIPLIST;
ACIPLIST * aciplist_create();
#define aciplist_destroy(l) avltree_destroy(l)
#define aciplist_add(l,elem) avltree_add(l,elem)
#define aciplist_foreach(l,callback,cbpriv) avltree_foreach(l,callback,cbpriv,1)
#define aciplist_foreach(l,callback,cbpriv) avltree_foreach_asc(l,callback,cbpriv)
*/
/**
@ -58,7 +61,7 @@ struct ac_info{
struct sockaddr * salist;
int salist_len;
ACIPLIST * aciplist;
//ACIPLIST * aciplist;
uint8_t ecn_support;
struct sockaddr_storage local_ip;

View File

@ -57,7 +57,7 @@ int acinfo_print(char *str,const struct ac_info *acinfo)
s+=sprintf(s,"\tSecurity: %s\n",help);
help[0]=0;
if (acinfo->dtls_policy & AC_DTLS_POLICY_D){
/* if (acinfo->dtls_policy & AC_DTLS_POLICY_D){
strcpy(help,"dtls");
}
if (acinfo->dtls_policy & AC_DTLS_POLICY_C){
@ -65,7 +65,7 @@ int acinfo_print(char *str,const struct ac_info *acinfo)
strcat(help,"/");
strcat(help,"clear");
}
if (!strlen(help))
*/ if (!strlen(help))
strcpy(help,"Not set");
s+=sprintf(s,"\tDTLS policy: %s\n",help);

View File

@ -1,53 +1,73 @@
/*
This file is part of libcapwap.
libcapwap is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
libcapwap is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "acinfo.h"
#include "aciplist.h"
#include "avltree.h"
#include "sock.h"
static int acip_cmp(const void *x1, const void *x2)
{
struct acip * ip1 = (struct acip*)x1;
struct acip * ip2 = (struct acip*)x2;
struct cw_acip *ip1 = (struct cw_acip *) x1;
struct cw_acip *ip2 = (struct cw_acip *) x2;
if (ip1->ip.ss_family != ip2->ip.ss_family){
if (ip1->ip.ss_family != ip2->ip.ss_family) {
if (ip1->ip.ss_family == AF_INET)
return -1;
else
return 1;
}
if (ip1->ip.ss_family == AF_INET){
struct sockaddr_in * s2=(struct sockaddr_in*)&ip2->ip;
struct sockaddr_in * s1=(struct sockaddr_in*)&ip1->ip;
if (ip1->ip.ss_family == AF_INET) {
struct sockaddr_in *s2 = (struct sockaddr_in *) &ip2->ip;
struct sockaddr_in *s1 = (struct sockaddr_in *) &ip1->ip;
return memcmp(&s1->sin_addr,&s2->sin_addr,sock_addrlen((struct sockaddr*)s1));
return memcmp(&s1->sin_addr, &s2->sin_addr,
sock_addrlen((struct sockaddr *) s1));
}
if (ip1->ip.ss_family == AF_INET6){
struct sockaddr_in6 * s2=(struct sockaddr_in6*)&ip2->ip;
struct sockaddr_in6 * s1=(struct sockaddr_in6*)&ip1->ip;
if (ip1->ip.ss_family == AF_INET6) {
struct sockaddr_in6 *s2 = (struct sockaddr_in6 *) &ip2->ip;
struct sockaddr_in6 *s1 = (struct sockaddr_in6 *) &ip1->ip;
return memcmp(&s1->sin6_addr.s6_addr,&s2->sin6_addr.s6_addr,sock_addrlen((struct sockaddr*)s1));
return memcmp(&s1->sin6_addr.s6_addr, &s2->sin6_addr.s6_addr,
sock_addrlen((struct sockaddr *) s1));
}
return -1;
}
static void acip_del(void*d)
static void acip_del(void *d)
{
free(d);
}
ACIPLIST * aciplist_create()
cw_aciplist_t cw_aciplist_create()
{
struct avltree *t = avltree_create(acip_cmp,acip_del);
return t;
return avltree_create(acip_cmp, acip_del);
}

View File

@ -23,6 +23,8 @@
#ifndef __AVLTREE_H
#define __AVLTREE_H
#include <stdio.h>
struct avlnode{
void * data;
struct avlnode * left;
@ -46,17 +48,33 @@ void avltree_destroy(struct avltree *t);
void avltree_del_all(struct avltree *t);
void * avltree_del(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);
extern int avltree_foreach_lr(struct avlnode *n, int (*callback)(void *,void *),void *cbpriv);
extern int avltree_foreach_rl(struct avlnode *n, int (*callback)(void *,void *),void *cbpriv);
extern void avltree_foreach(struct avltree *t, int (*callback)(void *,void*),void *cbpriv,int dir);
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);
static inline void * avltree_get(struct avltree *t ,void *data){
struct avlnode * n = avltree_get_node(t,data);
if (!n)
return NULL;
return n->data;
}
#define avltree_find(t,d) avltree_get(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)
#define avltree_foreach_asc(t,cb,priv) avltree_foreach_lr((t)->root,cb,priv)
#define avltree_foreach_desc(t,cb,priv) avltree_foreach_rl((t)->root,cb,priv)
#define avltree_foreach_from_asc(t,d,cb,priv) avltree_foreach_from_lr(t,(t)->root,d,cb,priv);
#endif

View File

@ -18,18 +18,6 @@
#include "avltree.h"
int avltree_foreach_lr(struct avlnode *n, int (*callback)(void *,void *),void *cbpriv)
{
if (!n)
return 1;
if (!avltree_foreach_lr(n->left,callback,cbpriv))
return 0;
if (!callback(cbpriv,n->data))
return 0;
return avltree_foreach_lr(n->right,callback,cbpriv);
}
int avltree_foreach_rl(struct avlnode *n, int (*callback)(void *,void *),void *cbpriv)
{
if (!n)

View File

@ -24,7 +24,7 @@
#ifndef __BSTR_H
#define __BSTR_H
#include <string.h>
#include <stdint.h>
/**
@ -42,6 +42,7 @@ extern uint8_t * bstr_replace( bstr_t * dst, uint8_t * bstr);
extern int bstr_to_str(char *dst, bstr_t str,char * def);
/**
* Return the length of a bstr_t string.
*/
@ -50,7 +51,7 @@ extern int bstr_to_str(char *dst, bstr_t str,char * def);
/**
* Return the data of a bstr_t string.
*/
#define bstr_data(s) (s+1)
#define bstr_data(s) ((s)+1)
/**
* Return the actual size in memory a bstr_t string needs.
@ -63,5 +64,19 @@ extern int bstr_to_str(char *dst, bstr_t str,char * def);
#define BSTR_MAX_LEN 254
typedef uint8_t *bstr16_t;
#define bstr16_len(s) ( *((uint16_t*)(s)) )
#define bstr16_data(s) ((s)+2)
#define bstr16_size(l) (l+2)
#define BSTR16_MAX_LEN (0xffff-2)
static inline int bstr16_ncpy(uint8_t *dst,uint8_t*src,uint16_t len)
{
*((uint16_t*)dst)=len;
memcpy(dst+2,src,len);
return len+2;
}
#endif

View File

@ -58,9 +58,9 @@ enum capwapmodes {
/**
* CAWAP States
*/
*/
enum capwap_states {
CW_STATE_NONE=0,
CW_STATE_NONE = 0,
CW_STATE_DISCOVERY,
CW_STATE_JOIN,
CW_STATE_CONFIGURE,
@ -83,6 +83,18 @@ enum capwap_states {
#define CWTH_FLAGS_T 0x100 /* bit 8 type of payload frame */
#define CW_FLAG_HDR_R1 0x01 /* bit 0 reserved 1 */
#define CW_FLAG_HDR_R2 0x02 /* bit 1 reserved 2 */
#define CW_FLAG_HDR_R3 0x04 /* bit 2 reserved 3 */
#define CW_FLAG_HDR_K 0x08 /* bit 3 Keep alive flag */
#define CW_FLAG_HDR_M 0x10 /* bit 4 MAC Adress field present */
#define CW_FLAG_HDR_W 0x20 /* bit 5 wireless info present */
#define CW_FLAG_HDR_L 0x40 /* bit 6 last fragment */
#define CW_FLAG_HDR_F 0x80 /* bit 7 fragment */
#define CW_FLAG_HDR_T 0x100 /* bit 8 type of payload frame */
/* wireless binding ids */
#define CWTH_WBID_RESERVED1 0
#define CWTH_WBID_IEEE80211 1
@ -113,44 +125,45 @@ struct capwap_ctrlhdr
/* CAPWAP message types as defined in RFC 5416 */
#define CW_MSG_DISCOVERY_REQUEST 1
#define CW_MSG_DISCOVERY_RESPONSE 2
#define CW_MSG_JOIN_REQUEST 3
#define CW_MSG_JOIN_RESPONSE 4
#define CW_MSG_DISCOVERY_REQUEST 1
#define CW_MSG_DISCOVERY_RESPONSE 2
#define CW_MSG_JOIN_REQUEST 3
#define CW_MSG_JOIN_RESPONSE 4
#define CW_MSG_CONFIGURATION_STATUS_REQUEST 5
#define CW_MSG_CONFIGURATION_STATUS_RESPONSE 6
#define CW_MSG_CONFIGURATION_STATUS_REQUEST 5
#define CW_MSG_CONFIGURATION_STATUS_RESPONSE 6
#define CW_MSG_CONFIGURATION_UPDATE_REQUEST 7
#define CW_MSG_CONFIGURATION_UPDATE_RESPONSE 8
#define CW_MSG_CONFIGURATION_UPDATE_REQUEST 7
#define CW_MSG_CONFIGURATION_UPDATE_RESPONSE 8
#define CW_MSG_WTP_EVENT_REQUEST 9
#define CW_MSG_WTP_EVENT_RESPONSE 10
#define CW_MSG_WTP_EVENT_RESPONSE 10
#define CW_MSG_CHANGE_STATE_EVENT_REQUEST 11
#define CW_MSG_CHANGE_STATE_EVENT_RESPONSE 12
#define CW_MSG_CHANGE_STATE_EVENT_REQUEST 11
#define CW_MSG_CHANGE_STATE_EVENT_RESPONSE 12
#define CW_MSG_ECHO_REQUEST 13
#define CW_MSG_ECHO_RESPONSE 14
#define CW_MSG_ECHO_REQUEST 13
#define CW_MSG_ECHO_RESPONSE 14
#define CW_MSG_IMAGE_DATA_REQUEST 15
#define CW_MSG_IMAGE_DATA_RESPONSE 16
#define CW_MSG_IMAGE_DATA_REQUEST 15
#define CW_MSG_IMAGE_DATA_RESPONSE 16
#define CW_MSG_RESET_REQUEST 17
#define CW_MSG_RESET_RESPONSE 18
#define CW_MSG_RESET_REQUEST 17
#define CW_MSG_RESET_RESPONSE 18
#define CW_MSG_PRIMARY_DISCOVERY_REQUEST 19
#define CW_MSG_PRIMARY_DISCOVERY_RESPONSE 20
#define CW_MSG_PRIMARY_DISCOVERY_REQUEST 19
#define CW_MSG_PRIMARY_DISCOVERY_RESPONSE 20
/* Data Transfer Request 21
Data Transfer Response 22
Clear Configuration Request 23
Clear Configuration Response 24
Station Configuration Request 25
Station Configuration Response 26
*/
#define CW_MSG_DATA_TRANSFER_REQUEST 21
#define CW_MSG_DATA_TRANSFER_RESPONSE 22
#define CWMSG_MAXMSG 26
#define CW_MSG_CLEAR_CONFIGURATION_REQUEST 23
#define CW_MSG_CLEAR_CONFIGURATION_RESPONSE 24
#define CW_STATION_CONFIGURATION_REQUEST 25
#define CW_STATION_CONFIGURATION_RESPONSE 26
#define CW_MSG_MAXMSG 26
/*
@ -168,10 +181,10 @@ struct capwap_ctrlhdr
#define CW_ELEM_ADD_MAC_ACL_ENTRY 7
#define CW_ELEM_ADD_STATION 8
#define CW_ELEM_RESERVED_9 9
#define CWMSGELEM_CONTROL_IPV4_ADDRESS 10
#define CWMSGELEM_CONTROL_IPV6_ADDRESS 11
#define CWMSGELEM_CAPWAP_LOCAL_IPV4_ADDRESS 30
#define CWMSGELEM_CAPWAP_LOCAL_IPV6_ADDRESS 50
#define CW_ELEM_CAPWAP_CONTROL_IPV4_ADDRESS 10
#define CW_ELEM_CAPWAP_CONTROL_IPV6_ADDRESS 11
#define CW_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS 30
#define CW_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS 50
#define CW_ELEM_CAPWAP_TIMERS 12
#define CW_ELEM_CAPWAP_TRANSPORT_PROTOCOL 51 /* not in draft 7 */
#define CW_ELEM_DATA_TRANSFER_DATA 13
@ -180,7 +193,7 @@ struct capwap_ctrlhdr
#define CW_ELEM_DECRYPTION_ERROR_REPORT_PERIOD 16
#define CW_ELEM_DELETE_MAC_ACL_ENTRY 17
#define CW_ELEM_DELETE_STATION 18
#define CW_ELEM_RESEERVED_19 19
#define CW_ELEM_RESERVED_19 19
#define CW_ELEM_DISCOVERY_TYPE 20
#define CW_ELEM_DUPLICATE_IPV4_ADDRESS 21
#define CW_ELEM_DUPLICATE_IPV6_ADRESS 22
@ -190,7 +203,7 @@ struct capwap_ctrlhdr
#define CW_ELEM_IMAGE_IDENTIFIER 25
#define CW_ELEM_IMAGE_INFORMATION 26
#define CW_ELEM_INITIATE_DOWNLOAD 27
#define CWMSGELEM_LOCATION_DATA 28
#define CW_ELEM_LOCATION_DATA 28
#define CWMSGELEM_MAXIMUM_MESSAGE_LENGTH 29
#define CWMSGELEM_MTU_DISCOVERY_PADDING 52
#define CWMSGELEM_RADIO_ADMINISTRATIVE_STATE 31
@ -237,16 +250,25 @@ struct capwap_ctrlhdr
#define CWBOARDDATA_MACADDRESS 4
/* */
#define CWACSECURITY_FLAGS_R 1 /* Reserved */
#define CWACSECURITY_FLAGS_X 2 /* X.509 */
#define CWACSECURITY_FLAGS_S 4 /* DTLS psk */
/* AC Security flags for authentication */
#define CW_FLAG_AC_SECURITY_R 1 /* Reserved */
#define CW_FLAG_AC_SECURITY_X 2 /* X.509 */
#define CW_FLAG_AC_SECURITY_S 4 /* DTLS psk */
#define CWMSGSUBELEM_WTP_DESCRIPTOR_HARDWARE_VERSION 0
#define CWMSGSUBELEM_WTP_DESCRIPTOR_SOFTWARE_VERSION 1
#define CWMSGSUBELEM_WTP_DESCRIPTOR_BOOTLOADER_VERSION 2
#define CWMSGSUBELEM_WTP_DESCRIPTOR_OTHERSOFTWARE_VERSION 3
#define CW_FLAG_RMAC_RESERVED 0
#define CW_FLAG_RMAC_SUPPORTED 1
#define CW_FLAG_RMAC_NOT_SUPPORTED 2
#define CW_SUBELEM_WTP_HARDWARE_VERSION 0
#define CW_SUBELEM_WTP_SOFTWARE_VERSION 1
#define CW_SUBELEM_WTP_BOOTLOADER_VERSION 2
#define CW_SUBELEM_WTP_OTHERSOFTWARE_VERSION 3
#define CW_SUBELEM_AC_HARDWARE_VERSION 4
#define CW_SUBELEM_AC_SOFTWARE_VERSION 5
#include "wtpinfo.h"
#include "acinfo.h"
@ -315,8 +337,9 @@ extern int wtpinfo_set_radioinfo(struct wtpinfo *wtpinfo, uint8_t * msgelem, int
#define AC_SECURITY_S 4 /* PSK support */
/* AC dtls policy flags */
#define AC_DTLS_POLICY_C 2 /* Clear data channel support */
#define AC_DTLS_POLICY_D 4 /* DTLS Data channel support */
#define CW_FLAG_DTLS_POLICY_R 1 /* Clear data channel support */
#define CW_FLAG_DTLS_POLICY_C 2 /* Clear data channel support */
#define CW_FLAG_DTLS_POLICY_D 4 /* DTLS Data channel support */
@ -344,11 +367,12 @@ extern void cwmsg_addelem_wtp_board_data(struct cwmsg *cwmsg, struct wtpinfo *wt
extern void cwmsg_addelem_cw_local_ip_addr(struct cwmsg *msg, struct conn *conn);
//extern void cwmsg_addelem_wtp_radio_infos(struct cwmsg * cwmsg,struct wtpinfo * wtpinfo);
extern void cwmsg_addelem_wtp_radio_infos(struct cwmsg *msg, struct radioinfo *radioinfos);
extern void cwmsg_addelem_wtp_radio_infos(struct cwmsg *msg,
struct radioinfo *radioinfos);
//extern void cwmsg_addelem_result_code(struct cwmsg *msg, int rc);
extern void cwmsg_addelem_vendor_specific_payload(struct cwmsg *msg, int vendor_id, int type,
uint8_t * payload, int len);
extern void cwmsg_addelem_vendor_specific_payload(struct cwmsg *msg, int vendor_id,
int type, uint8_t * payload, int len);
//extern void cwsend_discovery_reponse(struct conn * conn, struct ac_info * acinfo);
//extern int process_msgelems(uint8_t * msgelems, int len,
@ -359,12 +383,14 @@ extern void cwmsg_addelem_vendor_specific_payload(struct cwmsg *msg, int vendor_
//void cwsend_discovery_response(struct conn * conn,int seqnum, struct radioinfo * radioinfo, struct ac_info * acinfo, struct wtpinfo * wtpinfo);
//
extern void cwsend_discovery_response(struct conn *conn, int seqnum, struct radioinfo *radioinfo,
struct ac_info *acinfo, struct wtpinfo *wtpinfo);
extern void cwsend_discovery_response(struct conn *conn, int seqnum,
struct radioinfo *radioinfo, struct ac_info *acinfo,
struct wtpinfo *wtpinfo);
extern int cwsend_discovery_request(struct conn *conn, struct radioinfo *radioinfo,
struct wtpinfo *wtpinfo);
extern void cwsend_join_response(struct conn *conn, int seqnum, int rc, struct radioinfo *radioinfo,
struct ac_info *acinfo, struct wtpinfo *wtpinfo);
extern void cwsend_join_response(struct conn *conn, int seqnum, int rc,
struct radioinfo *radioinfo, struct ac_info *acinfo,
struct wtpinfo *wtpinfo);
extern void cwread_discovery_request(struct wtpinfo *wtpinfo, uint8_t * msg, int len);
@ -375,14 +401,16 @@ extern void cwread_discovery_response(struct ac_info *acinfo, uint8_t * msg, int
extern void cwsend_image_data_response(struct conn *conn, int seqnum, int rc);
extern int cwsend_image_data_request(struct conn *conn, struct cwimage_data *data,
struct image_identifier *id);
extern int cwread_change_state_event_request(struct wtpinfo *wtpinfo, uint8_t * msg, int len);
extern int cwread_change_state_event_request(struct wtpinfo *wtpinfo, uint8_t * msg,
int len);
extern void cwsend_change_state_event_response(struct conn *conn, int seqnum,
struct radioinfo *radioinfo);
extern int cwread_wtp_event_request(struct wtpinfo *wtpinfo, uint8_t * msg, int len);
extern void cwread_configuration_status_request(struct wtpinfo *wtpinfo, uint8_t * msg, int len);
extern void cwread_configuration_status_request(struct wtpinfo *wtpinfo, uint8_t * msg,
int len);
extern void cwsend_conf_status_response(struct conn *conn, int seqnum, int rc,
struct radioinfo *radioinfo, struct ac_info *acinfo,
struct wtpinfo *wtpinfo);
struct radioinfo *radioinfo,
struct ac_info *acinfo, struct wtpinfo *wtpinfo);
extern void cwsend_unknown_response(struct conn *conn, int seqnum, int unknow_request);
@ -390,20 +418,24 @@ extern void cwsend_unknown_response(struct conn *conn, int seqnum, int unknow_re
extern int hdr_print(char *str, uint8_t * packet, int len);
extern int cw_readelem_ecn_support(uint8_t * ecn_support, int type, uint8_t * msgelem, int len);
extern int cw_readelem_maximum_message_length(uint16_t * dst, int type, uint8_t * msgelem, int len);
extern int cw_readelem_ecn_support(uint8_t * ecn_support, int type, uint8_t * msgelem,
int len);
extern int cw_readelem_maximum_message_length(uint16_t * dst, int type, uint8_t * msgelem,
int len);
extern int cw_readelem_ac_name(uint8_t ** dst, int type, uint8_t * msgelem, int len);
extern int cw_readelem_wtp_reboot_statistics(struct wtp_reboot_statistics *s, int type,
uint8_t * msgelem, int len);
extern int cw_readelem_cw_local_ip_addr(struct sockaddr *local_ip, int type, uint8_t * msgelem,
int len);
extern int cw_readelem_cw_local_ip_addr(struct sockaddr *local_ip, int type,
uint8_t * msgelem, int len);
extern int cw_readelem_radio_administrative_state(struct radioinfo *radioinfo, int type,
uint8_t * msgelem, int len);
extern int cw_readelem_radio_operational_state(struct radioinfo *radioinfo, int type,
uint8_t * msgelem, int len);
extern int cw_readelem_statistics_timer(uint16_t * timer, int type, uint8_t * msgelem, int len);
extern int cw_readelem_result_code(uint32_t * result_code, int type, uint8_t * msgelem, int len);
extern int cw_readelem_statistics_timer(uint16_t * timer, int type, uint8_t * msgelem,
int len);
extern int cw_readelem_result_code(uint32_t * result_code, int type, uint8_t * msgelem,
int len);
extern int cw_readelem_mtu_discovery_padding(int type, uint8_t * msgelem, int len);
extern int cw_readelem_vendor_specific_payload(void *data, int msgtype, int elemtype,
uint8_t * msgelem, int len);
@ -424,14 +456,14 @@ extern int cw_readelem_vendor_specific_payload(void *data, int msgtype, int elem
#define CW_RESULT_JOIN_RESOURCE_DEPLETION 4
#define CW_RESULT_JOIN_UNKNOWN_SOURCE 5
#define CW_RESULT_JOIN_FAILURE_INCORRECT_DATA 6
#define CW_RESULT_JOIN_FAILURE_SESSION_ALREADY_IN_USE 7
#define CW_RESULT_JOIN_FAILURE_WTP_HARDWARE_NOT_SUPPORTED 8
#define CW_RESULT_JOIN_FAILURE_BINDING_NOT_SUPPORTED 9
#define CW_RESULT_RESET_FAILURE_UNABLE_TO_RESET 10
#define CW_RESULT_JOIN_FAILURE_SESSION_ALREADY_IN_USE 7
#define CW_RESULT_JOIN_FAILURE_WTP_HARDWARE_NOT_SUPPORTED 8
#define CW_RESULT_JOIN_FAILURE_BINDING_NOT_SUPPORTED 9
#define CW_RESULT_RESET_FAILURE_UNABLE_TO_RESET 10
#define CW_RESULT_RESET_FAILURE_FIRMWARE_WRITE_ERROR 11
#define CW_RESULT_RESET_FAILURE_FIRMWARE_WRITE_ERROR 11
#define CW_RESULT_CONFIGURATION_FAILURE 12 //Configuration Failure (Unable to Apply Requested Configuration
#define CW_RESULT_CONFIGURATION_FAILURE 12 //Configuration Failure (Unable to Apply Requested Configuration
// - Service Provided Anyhow)
/*
@ -464,18 +496,20 @@ extern int cw_readelem_vendor_specific_payload(void *data, int msgtype, int elem
extern void cw_read_image_data_request(struct cwimage_data *, uint8_t * msg, int len);
extern int cw_readelem_ac_descriptor(struct ac_info *acinfo, int type, uint8_t * msgelem, int len);
extern int cw_readelem_capwap_local_ip_addr(struct sockaddr *local_ip, int type, uint8_t * msgelem,
int len);
extern int cw_readelem_ac_descriptor(struct ac_info *acinfo, int type, uint8_t * msgelem,
int len);
extern int cw_readelem_capwap_local_ip_addr(struct sockaddr *local_ip, int type,
uint8_t * msgelem, int len);
extern int cw_send_echo_response(struct conn *conn, int seqnum, struct radioinfo *radioinfo);
extern int cw_send_echo_response(struct conn *conn, int seqnum,
struct radioinfo *radioinfo);
extern int cw_handle_echo_request(void *d);
extern void cw_send_image_file(struct conn *conn, FILE * infile);
extern int cw_readmsg_configuration_status_response(uint8_t * elems, int elems_len);
extern int cw_readmsg_configuration_update_request(uint8_t *elems,int elems_len);
extern int cw_readmsg_configuration_update_request(uint8_t * elems, int elems_len);
@ -521,6 +555,7 @@ extern int cw_readmsg_configuration_update_request(uint8_t *elems,int elems_len)
#define cw_get_hdr_flag_t(th) ((ntohl( *((uint32_t*)th)) & CWTH_FLAGS_T ) ? 1:0)
#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_msg_id(msgptr) (cw_get_dword(msgptr))
#define cw_get_msg_type(msgptr) cw_get_msg_id(msgptr)
@ -529,8 +564,33 @@ extern int cw_readmsg_configuration_update_request(uint8_t *elems,int elems_len)
#define cw_get_msg_elems_len(msgptr) ( cw_get_word( (msgptr) +5 )-3)
#define cw_get_msg_elems_ptr(msgptr) ((msgptr)+8)
static inline uint8_t * cw_get_hdr_msg_elems_ptr(uint8_t *m){
return cw_get_msg_elems_ptr( m+cw_get_hdr_msg_offset(m) );
#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_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_elems_len(msgptr,n) (cw_put_word((msgptr)+5,(n+3)))
#define cw_set_msg_flags(msgptr,f) (cw_put_byte( (msgptr)+7,f))
static inline uint8_t *cw_get_hdr_msg_elems_ptr(uint8_t * m)
{
return cw_get_msg_elems_ptr(m + cw_get_hdr_msg_offset(m));
}
static inline int cw_get_hdr_msg_total_len(uint8_t * rawmsg)
{
int offset = cw_get_hdr_msg_offset(rawmsg);
return offset + cw_get_msg_elems_len(rawmsg + offset)+8 ;
}
/**
@ -593,8 +653,8 @@ static inline uint8_t * cw_get_hdr_msg_elems_ptr(uint8_t *m){
* @len length of vendor specific data
* @return the number of bytes put (always 10)
*/
static inline int cw_put_elem_vendor_hdr(uint8_t * dst, uint32_t vendorid, uint16_t elemid,
uint16_t len)
static inline int cw_put_elem_vendor_hdr(uint8_t * dst, uint32_t vendorid,
uint16_t elemid, uint16_t len)
{
cw_put_elem_hdr(dst, CW_ELEM_VENDOR_SPECIFIC_PAYLOAD, len + 6);
@ -604,6 +664,11 @@ static inline int cw_put_elem_vendor_hdr(uint8_t * dst, uint32_t vendorid, uint1
}
#define cw_put_sockaddr lw_put_sockaddr
/**
* Add a message element to a buffer
* @param dst pointer to buffer
@ -625,19 +690,19 @@ static inline int cw_addelem_bstr(uint8_t * dst, uint16_t type, const bstr_t bst
}
static inline int cw_addelem_result_code(uint8_t *dst,uint32_t code)
static inline int cw_addelem_result_code(uint8_t * dst, uint32_t code)
{
cw_put_dword(dst+4,code);
return 4+ cw_put_elem_hdr(dst, CW_ELEM_RESULT_CODE, 4);
cw_put_dword(dst + 4, code);
return 4 + cw_put_elem_hdr(dst, CW_ELEM_RESULT_CODE, 4);
}
static inline int cw_addelem_radio_operational_state(uint8_t *dst, struct radioinfo * ri)
static inline int cw_addelem_radio_operational_state(uint8_t * dst, struct radioinfo *ri)
{
cw_put_byte(dst+4+0,ri->rid);
cw_put_byte(dst+4+1,ri->state);
cw_put_byte(dst+4+2,ri->cause);
return 3+ cw_put_elem_hdr(dst, CW_ELEM_RADIO_OPERATIONAL_STATE, 3);
cw_put_byte(dst + 4 + 0, ri->rid);
cw_put_byte(dst + 4 + 1, ri->state);
cw_put_byte(dst + 4 + 2, ri->cause);
return 3 + cw_put_elem_hdr(dst, CW_ELEM_RADIO_OPERATIONAL_STATE, 3);
}
@ -660,16 +725,20 @@ static inline int cw_addelem_radio_operational_state(uint8_t *dst, struct radioi
cw_put_data(dst+10,data,len))
*/
extern int cw_addelem_vendor_specific_payload(uint8_t * dst, uint32_t vendorid, uint16_t elemid,
uint8_t * data, uint16_t len);
extern int cw_addelem_vendor_specific_payload(uint8_t * dst, uint32_t vendorid,
uint16_t elemid, uint8_t * data,
uint16_t len);
extern void cw_prepare_configuration_status_request(struct conn *conn, struct radioinfo *radioinfo,
extern void cw_prepare_configuration_status_request(struct conn *conn,
struct radioinfo *radioinfo,
struct wtpinfo *wtpinfo);
extern void cw_prepare_change_state_event_request(struct conn *conn, struct radioinfo *radioinfo,
extern void cw_prepare_change_state_event_request(struct conn *conn,
struct radioinfo *radioinfo,
struct wtpinfo *wtpinfo);
extern int cw_send_configuration_update_response(struct conn * conn,int seqnum,struct radioinfo * radioinfo);
extern int cw_send_configuration_update_response(struct conn *conn, int seqnum,
struct radioinfo *radioinfo);
#define cw_addelem_ac_name(dst,name) \
@ -701,31 +770,62 @@ extern int cw_send_configuration_update_response(struct conn * conn,int seqnum,s
/* Message to text stuff */
struct cw_strlist {
struct cw_strlist {
uint32_t id;
const char * str;
const char *str;
};
extern const char * cw_strlist_get_str(struct cw_strlist *s,int id);
extern const char *cw_strlist_get_str(struct cw_strlist *s, int id);
/* Constants to string conversion lists */
extern struct cw_strlist capwap_strings_msg[];
extern struct cw_strlist capwap_strings_state[];
extern struct cw_strlist capwap_strings_vendor[];
extern struct cw_strlist capwap_strings_elem[];
#define cw_strmsg(id) cw_strlist_get_str(capwap_strings_msg,id)
#define cw_strelem(id) cw_strlist_get_str(capwap_strings_elem,id)
#define cw_strstate(id) cw_strlist_get_str(capwap_strings_state,id)
#define cw_strvendor(id) cw_strlist_get_str(capwap_strings_vendor,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);
extern int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action * a,uint8_t *data,int len);
extern int cw_in_wtp_name(struct conn *conn,struct cw_action * a,uint8_t *data,int len);
extern int cw_in_wtp_board_data(struct conn *conn, struct cw_action *a, uint8_t * data, int len);
extern int cw_in_generic(struct conn *conn, struct cw_action_in *a, uint8_t * data,
int len);
extern int cw_in_vendor_specific_payload(struct conn *conn, struct cw_action_in *a,
uint8_t * data, int len);
extern int cw_in_wtp_name(struct conn *conn, struct cw_action_in *a, uint8_t * data,
int len);
extern int cw_in_wtp_board_data(struct conn *conn, struct cw_action_in *a, uint8_t * data,
int len);
extern int cw_in_wtp_descriptor(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,
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);
struct cw_ac_status {
int stations;
int limit;
int active_wtps;
int max_wtps;
int security;
int rmac_field;
int dtls_policy;
};
int cw_register_actions_capwap_ac(struct cw_actiondef *def);
#endif

View File

@ -1,3 +1,5 @@
#ifndef __CAPWAP_ITEMS_H
#define __CAPWAP_ITEMS_H
enum capwap_items {
CW_ITEM_NONE=0,
@ -8,6 +10,37 @@ enum capwap_items {
CW_ITEM_WTP_BOARD_MACADDRESS,
CW_ITEM_WTP_BOARD_ID,
CW_ITEM_WTP_BOARD_REVISION,
CW_ITEM_WTP_BOARD_SERIALNO
CW_ITEM_WTP_BOARD_SERIALNO,
CW_ITEM_WTP_MAC_TYPE,
CW_ITEM_WTP_FRAME_TUNNEL_MODE,
CW_ITEM_WTP_RADIOS_IN_USE,
CW_ITEM_WTP_MAX_RADIOS,
CW_ITEM_WTP_HARDWARE_VENDOR,
CW_ITEM_WTP_HARDWARE_VERSION,
CW_ITEM_WTP_SOFTWARE_VENDOR,
CW_ITEM_WTP_SOFTWARE_VERSION,
CW_ITEM_WTP_BOOTLOADER_VENDOR,
CW_ITEM_WTP_BOOTLOADER_VERSION,
CW_ITEM_WTP_OTHERSOFTWARE_VENDOR,
CW_ITEM_WTP_OTHERSOFTWARE_VERSION,
CW_ITEM_AC_NAME,
CW_ITEM_AC_DESCRIPTOR,
CW_ITEM_RESULT_CODE,
CW_ITEM_AC_STATUS,
CW_ITEM_AC_HARDWARE_VERSION,
CW_ITEM_AC_SOFTWARE_VERSION,
CW_ITEM_AC_IP_LIST,
CW_ITEM_CAPWAP_CONTROL_IP_LIST,
CW_ITEM_LOCATION_DATA,
CW_ITEM_SESSION_ID,
};
#endif

View File

@ -12,8 +12,8 @@ struct cw_strlist capwap_strings_elem[] = {
{CW_ELEM_ADD_MAC_ACL_ENTRY, "Add MAC ACL Entry"},
{CW_ELEM_ADD_STATION, "Add Station"},
{CW_ELEM_RESERVED_9, "Reserved 9"},
{CW_ELEM_CONTROL_IPV4_ADDRESS, "Control IPv4 Address"},
{CW_ELEM_CONTROL_IPV6_ADDRESS, "Controll IPv6 Address"},
{CW_ELEM_CAPWAP_CONTROL_IPV4_ADDRESS, "Control IPv4 Address"},
{CW_ELEM_CAPWAP_CONTROL_IPV6_ADDRESS, "Controll IPv6 Address"},
{CW_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS, "CAWPAP Local IPv4 Address"},
{CW_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS, "CAPWAP Local IPv6 Address"},
{CW_ELEM_CAPWAP_TIMERS, "CAPWAP Timers"},
@ -34,7 +34,7 @@ struct cw_strlist capwap_strings_elem[] = {
{CW_ELEM_IMAGE_IDENTIFIER, "Image Identifier"},
{CW_ELEM_IMAGE_INFORMATION, "Image Information"},
{CW_ELEM_INITIATE_DOWNLOAD, "Initiate Download"},
{CWMSGELEM_LOCATION_DATA, "Location Data"},
{CW_ELEM_LOCATION_DATA, "Location Data"},
{CWMSGELEM_MAXIMUM_MESSAGE_LENGTH, "Maximum Message Length"},
{CWMSGELEM_MTU_DISCOVERY_PADDING, "MTU Discovery Padding"},
{CWMSGELEM_RADIO_ADMINISTRATIVE_STATE, "Radio Administrative State"},

View File

@ -31,7 +31,7 @@
#include "wtpinfo.h"
#include "cw_action.h"
#include "action.h"
#include "itemstore.h"
@ -42,8 +42,13 @@ struct conn {
cw_itemstore_t itemstore;
cw_itemstore_t local;
cw_itemstore_t remote;
struct avltree *msgtr;
struct cw_actiondef *actions;
// struct avltree *msgtr;
uint8_t capwap_state;
@ -72,8 +77,11 @@ struct conn {
struct cwmsg req_msg;
struct cwmsg resp_msg;
uint8_t req_buffer[65536];
uint8_t resp_buffer[65536];
/** Buffer for outgoing response messages */
uint8_t resp_buffer[65536];
int mtu; /* max mtu, could be changed during discovery */
int mtu_discovery; /* 0 mtu discovery turned off, 1 discovery tuned on */

View File

@ -203,7 +203,7 @@ void conn_process_packet(struct conn * conn, uint8_t *packet, int len,int (*cb)(
cwrmsg.rid=(val>>14) & 0x1f;
*/
printf ("Offs is %d RML is %d\n",offs,cw_get_hdr_rmac_len(packet));
//printf ("Offs is %d RML is %d\n",offs,cw_get_hdr_rmac_len(packet));
/* Check Radio MAC if preset */
if (cw_get_hdr_flag_m(packet)){
@ -229,8 +229,8 @@ printf ("Offs is %d RML is %d\n",offs,cw_get_hdr_rmac_len(packet));
cw_dbg_packet(conn,f+4,*(uint32_t*)f);
extern int cw_process_msg(struct conn * conn,uint8_t*msg,int len);
cw_process_msg(conn,f+4,*(uint32_t*)f);
// extern int cw_process_msg(struct conn * conn,uint8_t*msg,int len);
// cw_process_msg(conn,f+4,*(uint32_t*)f);
printf("Received a fragmented packetm should process it");
exit(0);
@ -247,8 +247,8 @@ exit(0);
return;
}
extern int cw_process_msg(struct conn * conn,uint8_t*msg,int len);
cw_process_msg(conn,packet,len);
//extern int cw_process_msg(struct conn * conn,uint8_t*msg,int len);
//cw_process_msg(conn,packet,len);
//if (!cwrmsg_init_ctrlhdr(conn,&cwrmsg,packet+hlen,len-hlen) ){
@ -256,7 +256,6 @@ cw_process_msg(conn,packet,len);
// return;
//}
printf("Next big thing\n");
//msg_4*((val >> 19) & 0x1f);
process_message(conn,packet,len,cb,cbarg);
return;

View File

@ -1,80 +0,0 @@
#include <stdlib.h>
#include <string.h>
#include "cw_action.h"
static inline int cw_action_cmp(const void *elem1,const void *elem2)
{
struct cw_action * e1 = (struct cw_action*)elem1;
struct cw_action * e2 = (struct cw_action*)elem2;
int r;
r = e1->elem_id - e2->elem_id;
if (r!=0)
return r;
r = e1->msg_id - e2->msg_id;
if (r!=0)
return r;
r = e1->capwap_state - e2->capwap_state;
if (r!=0)
return r;
r = e1->vendor_id - e2->vendor_id;
if (r!=0)
return r;
return 0;
}
/*
static void cw_action_del(void*d)
{
free(d);
}
*/
cw_action_t * cw_actionlist_add(cw_actionlist_t t, struct cw_action * a)
{
struct cw_action *an = malloc(sizeof(struct cw_action));
if (!an)
return NULL;
memcpy(an,a,sizeof(struct cw_action));
return avltree_add(t,an);
}
struct cw_action * cw_actionlist_get(cw_actionlist_t t,struct cw_action *a)
{
return avltree_get(t,a);
}
cw_actionlist_t cw_actionlist_create()
{
return avltree_create(cw_action_cmp,free); //cw_action_del);
}
int cw_register_actions(cw_actionlist_t t,cw_action_t * actions)
{
while(actions->capwap_state){
// cw_action_t *a = actions;
// printf("State: %d MSG_ID: %d ELEM_ID: %d\n",a->capwap_state,a->msg_id,a->elem_id);
cw_action_t * rc = cw_actionlist_add(t,actions);
if (rc==0)
return 0;
actions++;
}
return 1;
}

View File

@ -1,45 +0,0 @@
#ifndef __MSGTREE_H
#define __MSGTREE_H
#include <stdint.h>
#include "avltree.h"
#include "conn.h"
struct cw_action{
uint32_t vendor_id;
uint8_t proto;
uint8_t capwap_state;
uint32_t msg_id;
uint16_t elem_id;
int (*start)(struct conn *conn,struct cw_action *a,uint8_t*data,int len);
int (*end)(struct conn *conn,struct cw_action *a,uint8_t*elem,int len);
uint16_t min_len;
uint16_t max_len;
uint8_t capwap_state_next;
const char *name;
};
typedef struct cw_action cw_action_t;
typedef struct avltree * cw_actionlist_t;
extern cw_actionlist_t cw_actionlist_create();
extern cw_action_t * cw_actionlist_get(cw_actionlist_t t,cw_action_t *a);
extern cw_action_t * cw_actionlist_add(cw_actionlist_t t,cw_action_t *a);
extern int cw_register_actions(cw_actionlist_t t,cw_action_t * actions);
int check(uint8_t *elem,int len);
#endif

View File

@ -9,16 +9,16 @@
/**
* Default handler for Vendor Specific Payload message elements.
*/
int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action * a,uint8_t *data,int len)
int cw_in_vendor_specific_payload(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len)
{
cw_action_t as,*af;
cw_action_in_t as,*af;
as = *a;
as.vendor_id = cw_get_dword(data);
as.elem_id = cw_get_word(data+4);
printf("Vendor Specific: %d, %d\n",as.vendor_id,as.elem_id);
// printf("Vendor Specific: %d, %d\n",as.vendor_id,as.elem_id);
af = cw_actionlist_get(conn->msgtr,&as);
af = cw_actionlist_in_get(conn->actions->in,&as);
if (!af) {
cw_log(DBG_ELEM,"Can't handle Vendor Specific Payload %s/%d, in msg %d (%s) in %s state.",

View File

@ -4,7 +4,7 @@
#include "itemstore.h"
int cw_in_wtp_name(struct conn *conn,struct cw_action * a,uint8_t *data,int len)
int cw_in_wtp_name(struct conn *conn,struct cw_action_in * a,uint8_t *data,int len)
{
if (len > 512){
cw_dbg(DBG_CW_RFC, "WTP Name too long, must not exceed 512, len is %d",len);

View File

@ -307,25 +307,25 @@ void cw_dbg_msgelem_(int msg, int msgelem, const uint8_t * msgbuf, int len)
uint32_t vendor_id = ntohl(*((uint32_t *) msgbuf));
int type = ntohs(*((uint16_t *) (msgbuf + 4)));
sprintf(vendorname, "%s/%s/%d",
(char *) cw_msgelemtostr(msgelem),
(char *) cw_strelem(msgelem),
(char *) lw_vendor_id_to_str(vendor_id), type);
elemname = vendorname;
cw_format_vendor(vendor_details, vendor_id, type, msgbuf);
} else {
elemname = cw_msgelemtostr(msgelem);
elemname = cw_strelem(msgelem);
}
if (!cw_dbg_is_level(DBG_ELEM_DMP))
cw_dbg(DBG_ELEM,
"%s, CAWPAP element: type=%d (%s), len=%d%s",
cw_msgtostr(msg), msgelem, elemname, len, vendor_details);
cw_strmsg(msg), msgelem, elemname, len, vendor_details);
else
cw_dbg_dmp(DBG_ELEM, msgbuf, len,
"%s, CAPWAP element: type=%d (%s), len=%d%s\n\tDump ...",
cw_msgtostr(msg), msgelem, elemname, len, vendor_details);
cw_strmsg(msg), msgelem, elemname, len, vendor_details);
}
@ -369,6 +369,6 @@ void cw_dbg_missing_mand_elems_(struct conn *conn, int msgtype, int *mand)
if (cw_is_missing_mand_elems(mand)) {
char str[512];
cw_get_missing_mand_elems(str, mand);
cw_dbg(DBG_CW_RFC, "Missing msgelems in %s: %s", cw_msgtostr(msgtype), str);
cw_dbg(DBG_CW_RFC, "Missing msgelems in %s: %s", cw_strmsg(msgtype), str);
}
}

View File

@ -26,8 +26,8 @@ struct cw_dbg_cfgstrs cw_dbg_cfgstrs[] = {
{"info",DBG_CW_INFO},
{"msg",DBG_MSG},
{"msgelem",DBG_ELEM},
{"msgelem_dmp",DBG_ELEM_DMP},
{"elem",DBG_ELEM},
{"elem_dmp",DBG_ELEM_DMP},
{"rfc",DBG_CW_RFC},
{"pkt_in",DBG_CW_PKT_IN},
{"pkt_out",DBG_CW_PKT_OUT},

View File

@ -4,19 +4,190 @@
#include "conn.h"
#include "capwap.h"
#include "capwap_items.h"
#include "sock.h"
#include "cw_action.h"
#include "action.h"
#include "cw_log.h"
#include "dbg.h"
int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len)
int snd_cb(void *c, void *d)
{
struct cw_action as,*af;
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 cw_send_response(struct conn *conn, uint8_t * rawmsg, int len)
{
struct priv priv;
cw_init_response(conn, rawmsg);
uint8_t *msgptr = rawmsg + cw_get_hdr_msg_offset(rawmsg);
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);
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);
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");
*/
}
int cw_process_msg(struct conn *conn, uint8_t * rawmsg, int len)
{
struct cw_action_in as, *af,*afm;
uint8_t *msg_ptr = rawmsg + cw_get_hdr_msg_offset(rawmsg);
int elems_len = cw_get_msg_elems_len(msg_ptr);
/*
@ -44,62 +215,64 @@ int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len)
*/
/* prepare struct for search operation */
as.elem_id=-1;
as.capwap_state=conn->capwap_state;
as.capwap_state = conn->capwap_state;
as.msg_id = cw_get_msg_id(msg_ptr);
as.vendor_id=0;
as.vendor_id = 0;
as.elem_id = -1;
as.proto=0;
/* Search for state/message combination */
af = cw_actionlist_get(conn->msgtr,&as);
afm = cw_actionlist_in_get(conn->actions->in, &as);
/* Check if message is comes in right state */
if ( !af ){
cw_dbg(DBG_MSG_ERR,"Message type %d (%s) not allowed in %s State.",
as.msg_id,cw_strmsg(as.msg_id),cw_strstate(as.capwap_state));
/* Check if message comes in right state */
if (!afm) {
cw_dbg(DBG_MSG_ERR, "Message type %d (%s) not allowed in %s State.",
as.msg_id, cw_strmsg(as.msg_id), cw_strstate(as.capwap_state));
return 0;
}
if (af->start){
af->start(conn,af,rawmsg,len);
/* Execute start processor for message */
if (afm->start) {
afm->start(conn, afm, rawmsg, len);
}
uint8_t * elems_ptr = cw_get_msg_elems_ptr(msg_ptr);
uint8_t *elems_ptr = cw_get_msg_elems_ptr(msg_ptr);
uint8_t *elem;
cw_foreach_elem(elem,elems_ptr,elems_len) {
cw_foreach_elem(elem, elems_ptr, elems_len) {
as.elem_id = cw_get_elem_id(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);
af = cw_actionlist_get(conn->msgtr,&as);
af = cw_actionlist_in_get(conn->actions->in, &as);
if (!af) {
cw_dbg(DBG_ELEM_ERR,"Element %d not aallowed in msg %d (%s)",as.elem_id,as.msg_id,cw_strmsg(as.msg_id));
cw_dbg(DBG_ELEM_ERR, "Element %d not allowed in msg %d (%s)",
as.elem_id, as.msg_id, cw_strmsg(as.msg_id));
continue;
}
printf("Elem OK: %d, %d\n",as.elem_id,elem_len);
if (af->start) {
af->start(conn,af,cw_get_elem_data(elem),elem_len);
af->start(conn, af, cw_get_elem_data(elem), elem_len);
}
}
cw_send_response(conn, rawmsg, len);
if (afm->end) {
afm->end(conn, afm, rawmsg, len);
}
return 0;
}

View File

@ -54,7 +54,7 @@ static int imgdata_request(void * ptr,int type,uint8_t* msgelem,int len)
cw_dbg_msgelem(CW_MSG_IMAGE_DATA_REQUEST, type, msgelem, len);
cw_dbg(DBG_ALL,"Reading image data req msgelem, type=%d - %s ,len=%d\n",type,cw_msgelemtostr(type),len);
cw_dbg(DBG_ALL,"Reading image data req msgelem, type=%d - %s ,len=%d\n",type,cw_strelem(type),len);
if (cw_readelem_image_identifier(ptr,type,msgelem,len))
return 1;

View File

@ -8,7 +8,7 @@
int cw_readelem_capwap_local_ip_addr(struct sockaddr * local_ip, int type, uint8_t * msgelem, int len)
{
switch (type){
case CWMSGELEM_CAPWAP_LOCAL_IPV4_ADDRESS:
case CW_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS:
case CW_ELEM_WTP_IPV4_IP_ADDRESS:
{
if (len!=4)
@ -23,7 +23,7 @@ int cw_readelem_capwap_local_ip_addr(struct sockaddr * local_ip, int type, uint8
return 1;
}
#ifdef WITH_IPV6
case CWMSGELEM_CAPWAP_LOCAL_IPV6_ADDRESS:
case CW_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS:
case CW_ELEM_WTP_IPV6_IP_ADDRESS:
{
if (len!=16)

View File

@ -48,7 +48,7 @@ void cw_get_missing_mand_elems(char *dst, int *l)
const char * k = "";
for (i=0; l[i]!=-1; i++){
if(l[i]){
s += sprintf(s,"%s[%s]",k,cw_msgelemtostr(l[i]));
s += sprintf(s,"%s[%s]",k,cw_strelem(l[i]));
k=",";
}

View File

@ -61,7 +61,6 @@ void cw_get_missing_mand_elems(char *dst, int *l);
extern const char * cw_msgelemtostr(int elem);
extern const char * cw_msgtostr(int type);
#endif

View File

@ -26,34 +26,34 @@
#include "sock.h"
//static int cwmsg_addelem_acip(struct cwmsg * msg,ACIP *ip,int ctr)
static int cwmsg_addelem_acip(void * priv,void *data) //,int ctr)
static int cwmsg_addelem_acip(void *priv, void *data) //,int ctr)
{
// cw_log_debug2("Adding Ctrl IP %s",sock_addr2str((struct sockaddr*)data));
// cw_log_debug2("Adding Ctrl IP %s",sock_addr2str((struct sockaddr*)data));
struct cwmsg * msg = (struct cwmsg*)priv;
ACIP * acip = (ACIP*)data;
struct cwmsg *msg = (struct cwmsg *) priv;
ACIP *acip = (ACIP *) data;
uint8_t ipmsg [18];
uint8_t ipmsg[18];
switch (acip->ip.ss_family){
switch (acip->ip.ss_family) {
case AF_INET:
{
struct sockaddr_in * sain = (struct sockaddr_in*)&acip->ip;
memcpy(ipmsg,&sain->sin_addr.s_addr, sizeof(sain->sin_addr.s_addr));
*((uint16_t*)(ipmsg+4))= htons(acip->wtp_count); /* number of wtps */
cwmsg_addelem(msg,CWMSGELEM_CONTROL_IPV4_ADDRESS,ipmsg,6);
}
break;
#ifdef WITH_IPV6
{
struct sockaddr_in *sain = (struct sockaddr_in *) &acip->ip;
memcpy(ipmsg, &sain->sin_addr.s_addr, sizeof(sain->sin_addr.s_addr));
*((uint16_t *) (ipmsg + 4)) = htons(acip->wtp_count); /* number of wtps */
cwmsg_addelem(msg, CW_ELEM_CONTROL_IPV4_ADDRESS, ipmsg, 6);
}
break;
#ifdef WITH_IPV6
case AF_INET6:
{
struct sockaddr_in6 * sain = (struct sockaddr_in6*)&acip->ip;
memcpy(ipmsg,&sain->sin6_addr.s6_addr, sizeof(sain->sin6_addr.s6_addr));
*((uint16_t*)(ipmsg+16))= htons(acip->wtp_count); /* number of wtps */
cwmsg_addelem(msg,CWMSGELEM_CONTROL_IPV6_ADDRESS,ipmsg,18);
}
break;
#endif
{
struct sockaddr_in6 *sain = (struct sockaddr_in6 *) &acip->ip;
memcpy(ipmsg, &sain->sin6_addr.s6_addr, sizeof(sain->sin6_addr.s6_addr));
*((uint16_t *) (ipmsg + 16)) = htons(acip->wtp_count); /* number of wtps */
cwmsg_addelem(msg, CW_ELEM_CONTROL_IPV6_ADDRESS, ipmsg, 18);
}
break;
#endif
}
return 1;
}
@ -61,8 +61,8 @@ static int cwmsg_addelem_acip(void * priv,void *data) //,int ctr)
void cwmsg_addelem_ctrl_ip_addrs(struct cwmsg *msg, struct ac_info *acinfo)
{
// printf("Counter in the list: %i\n",acinfo->aciplist->count);
aciplist_foreach(acinfo->aciplist,cwmsg_addelem_acip,msg);
// printf("Counter in the list: %i\n",acinfo->aciplist->count);
aciplist_foreach(acinfo->aciplist, cwmsg_addelem_acip, msg);
}

View File

@ -48,7 +48,7 @@ cw_mode = CWMODE_CISCO;
if (cw_mode == CWMODE_CISCO)
id = CW_ELEM_WTP_IPV4_IP_ADDRESS;
else
id = CWMSGELEM_CAPWAP_LOCAL_IPV4_ADDRESS;
id = CW_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS;
printf("Sending local ip %s\n",sock_addr2str(sain));
@ -63,7 +63,7 @@ printf("Sending local ip %s\n",sock_addr2str(sain));
if (cw_mode == CWMODE_CISCO)
id = CW_ELEM_WTP_IPV6_IP_ADDRESS;
else
id = CWMSGELEM_CAPWAP_LOCAL_IPV6_ADDRESS;
id = CW_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS;
struct sockaddr_in6 * sain = (struct sockaddr_in6*)&a;
return cwmsg_addelem(msg,id,(uint8_t*)&sain->sin6_addr,16);
}

View File

@ -50,15 +50,15 @@ void cwmsg_addelem_wtp_descriptor(struct cwmsg * cwmsg, struct wtpinfo * wtpinfo
/* hardware version subelem*/
len+=wtpdesc_addsubelem(d+len,CWMSGSUBELEM_WTP_DESCRIPTOR_HARDWARE_VERSION,
len+=wtpdesc_addsubelem(d+len,CW_SUBELEM_WTP_HARDWARE_VERSION,
wtpinfo->hardware_vendor_id,wtpinfo->hardware_version);
/* software version subelem*/
len+=wtpdesc_addsubelem(d+len,CWMSGSUBELEM_WTP_DESCRIPTOR_SOFTWARE_VERSION,
len+=wtpdesc_addsubelem(d+len,CW_SUBELEM_WTP_SOFTWARE_VERSION,
wtpinfo->software_vendor_id,wtpinfo->software_version);
/* bootloader version subelem*/
len+=wtpdesc_addsubelem(d+len,CWMSGSUBELEM_WTP_DESCRIPTOR_BOOTLOADER_VERSION,
len+=wtpdesc_addsubelem(d+len,CW_SUBELEM_WTP_BOOTLOADER_VERSION,
wtpinfo->bootloader_vendor_id,wtpinfo->bootloader_version);
cwmsg_addelem(cwmsg,CW_ELEM_WTP_DESCRIPTOR,d,len);

View File

@ -19,7 +19,7 @@ void cwsend_join_response(struct conn *conn, int seqnum, int rc, struct radioinf
cwmsg_addelem_ac_descriptor(cwmsg, acinfo,wtpinfo);
cwmsg_addelem(cwmsg, CW_ELEM_AC_NAME, acinfo->ac_name, strlen((char *) acinfo->ac_name));
cwmsg_addelem(cwmsg, CWMSGELEM_ECN_SUPPORT, &acinfo->ecn_support, sizeof(uint8_t));
cwmsg_addelem_ctrl_ip_addrs(cwmsg, acinfo);
// cwmsg_addelem_ctrl_ip_addrs(cwmsg, acinfo);
// cwmsg_addelem_cw_local_ip_addr(cwmsg,conn);

View File

@ -8,38 +8,48 @@
static inline void cw_itemstore_del_data(void *e)
{
struct cw_item * item = (struct cw_item*)e;
if (item->type==CW_ITEMTYPE_DATA)
free (item->data);
struct cw_item *item = (struct cw_item *) e;
switch (item->type) {
case CW_ITEMTYPE_DATA:
case CW_ITEMTYPE_STR:
case CW_ITEMTYPE_BSTR:
case CW_ITEMTYPE_VERSION:
case CW_ITEMTYPE_FUN:
free(item->data);
break;
case CW_ITEMTYPE_AVLTREE:
avltree_destroy(item->data);
}
}
static void cw_itemstore_del(void * e)
static void cw_itemstore_del(void *e)
{
cw_itemstore_del_data(e);
free(e);
free(e);
}
static int cw_itemstore_cmp(const void *x1,const void*x2)
static int cw_itemstore_cmp(const void *x1, const void *x2)
{
return ((struct cw_item*)x1)->id - ((struct cw_item*)x2)->id;
return ((struct cw_item *) x1)->id - ((struct cw_item *) x2)->id;
}
cw_itemstore_t cw_itemstore_create()
{
return avltree_create(cw_itemstore_cmp,cw_itemstore_del);
return avltree_create(cw_itemstore_cmp, cw_itemstore_del);
}
struct cw_item * cw_item_create(cw_itemstore_t s,uint32_t id)
struct cw_item *cw_item_create(cw_itemstore_t s, uint32_t id)
{
struct cw_item is;
is.id=id;
is.id = id;
struct cw_item *i=avltree_get(s,&is);
struct cw_item *i = avltree_get(s, &is);
if (i) {
cw_itemstore_del_data(i);
return i;
@ -48,118 +58,184 @@ struct cw_item * cw_item_create(cw_itemstore_t s,uint32_t id)
i = malloc(sizeof(struct cw_item));
if (!i)
return 0;
i->id=id;
return avltree_add(s,i);
i->id = id;
return avltree_add(s, i);
}
int cw_itemstore_set_byte(cw_itemstore_t s,uint32_t id,uint8_t byte)
int cw_itemstore_set_byte(cw_itemstore_t s, uint32_t id, uint8_t byte)
{
struct cw_item *i = cw_item_create(s,id);
struct cw_item *i = cw_item_create(s, id);
if (!i)
return 0;
i->byte=byte;
i->type=CW_ITEMTYPE_BYTE;
i->byte = byte;
i->type = CW_ITEMTYPE_BYTE;
return 1;
}
int cw_itemstore_set_word(cw_itemstore_t s,uint32_t id,uint32_t word)
int cw_itemstore_set_word(cw_itemstore_t s, uint32_t id, uint32_t word)
{
struct cw_item *i = cw_item_create(s,id);
struct cw_item *i = cw_item_create(s, id);
if (!i)
return 0;
i->word=word;
i->type=CW_ITEMTYPE_WORD;
i->word = word;
i->type = CW_ITEMTYPE_WORD;
return 1;
}
int cw_itemstore_set_dword(cw_itemstore_t s,uint32_t id,uint32_t dword)
int cw_itemstore_set_dword(cw_itemstore_t s, uint32_t id, uint32_t dword)
{
struct cw_item *i = cw_item_create(s,id);
struct cw_item *i = cw_item_create(s, id);
if (!i)
return 0;
i->dword=dword;
i->type=CW_ITEMTYPE_DWORD;
i->dword = dword;
i->type = CW_ITEMTYPE_DWORD;
return 1;
}
int cw_itemstore_set_str(cw_itemstore_t s,uint32_t id,char *str)
int cw_itemstore_set_str(cw_itemstore_t s, uint32_t id, const char *str)
{
struct cw_item *i = cw_item_create(s,id);
struct cw_item *i = cw_item_create(s, id);
if (!i)
return 0;
i->type=CW_ITEMTYPE_DATA;
i->data=strdup(str);
i->type = CW_ITEMTYPE_STR;
i->data = strdup(str);
return 1;
}
int cw_itemstore_set_strn(cw_itemstore_t s,uint32_t id,const char *str,int n)
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);
struct cw_item *i = cw_item_create(s, id);
if (!i)
return 0;
i->type=CW_ITEMTYPE_DATA;
i->data=strndup(str,n);
i->type = CW_ITEMTYPE_DATA;
i->data = strndup(str, n);
return 1;
}
int cw_itemstore_set_ptr(cw_itemstore_t s, uint32_t id, void*ptr)
int cw_itemstore_set_ptr(cw_itemstore_t s, uint32_t id, void *ptr)
{
struct cw_item *i = cw_item_create(s,id);
struct cw_item *i = cw_item_create(s, id);
if (!i)
return 0;
i->type=CW_ITEMTYPE_DATA;
i->data=ptr;
i->type = CW_ITEMTYPE_DATA;
i->data = ptr;
return 1;
}
int cw_itemstore_set_bstrn(cw_itemstore_t s, uint32_t id, uint8_t *data,int len)
int cw_itemstore_set_bstrn(cw_itemstore_t s, uint32_t id, uint8_t * data, int len)
{
struct cw_item *i = cw_item_create(s,id);
struct cw_item *i = cw_item_create(s, id);
if (!i)
return 0;
i->type=CW_ITEMTYPE_DATA;
i->data=bstr_create(data,len);
i->type = CW_ITEMTYPE_BSTR;
i->data = bstr_create(data, len);
return 1;
}
int cw_itemstore_set_const_ptr(cw_itemstore_t s, uint32_t id, void*ptr)
int cw_itemstore_set_const_ptr(cw_itemstore_t s, uint32_t id, void *ptr)
{
struct cw_item *i = cw_item_create(s,id);
struct cw_item *i = cw_item_create(s, id);
if (!i)
return 0;
i->type=CW_ITEMTYPE_CONST_DATA;
i->data=ptr;
i->type = CW_ITEMTYPE_CONST_DATA;
i->data = ptr;
return 1;
}
/*
struct cw_item * i = malloc(sizeof(struct cw_item));
if ( !i)
int cw_itemstore_set_version(cw_itemstore_t s, uint32_t id, uint32_t vendor_id,
uint8_t * versionstr, int len)
{
struct cw_item *i = cw_item_create(s, id);
if (!i)
return 0;
i->id=id;
i->type=CW_ITEMTYPE_BYTE;
i->byte=byte;
struct cw_item * r = avltree_add(s,i);
if (r!=i) {
r->byte=byte;
free(i);
i->type = CW_ITEMTYPE_VERSION;
uint8_t *ptr = malloc(bstr16_size(len) + 4);
i->data = ptr;
if (!ptr)
return 1;
*((uint32_t *) ptr) = vendor_id;
bstr16_ncpy(ptr + 4, versionstr, len);
return 1;
}
int cw_itemstore_set_avltree(cw_itemstore_t s, uint32_t id, struct avltree *t)
{
struct cw_item *i = cw_item_create(s, id);
if (!i)
return 0;
i->type = CW_ITEMTYPE_AVLTREE;
i->data = t;
return 1;
}
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;
}
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 1;
*/
/*
char * cw_itemstore_get_str(cw_itemstore_t s,uint32_t id)
{
// struct cw_item * item = avltree_get(s,id);
return item->data;
}
*/
//cw_itemstore_set_str(
// cw_item_t item = (cw_item_t) avltree_get(t,a);
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);
}
}
}

View File

@ -32,7 +32,13 @@ enum cw_cfgtem_types{
CW_ITEMTYPE_WORD,
CW_ITEMTYPE_DWORD,
CW_ITEMTYPE_DATA,
CW_ITEMTYPE_CONST_DATA
CW_ITEMTYPE_CONST_DATA,
CW_ITEMTYPE_STR,
CW_ITEMTYPE_BSTR,
CW_ITEMTYPE_VERSION,
CW_ITEMTYPE_AVLTREE,
CW_ITEMTYPE_FUN,
};
struct cw_item {
@ -59,9 +65,20 @@ static inline struct cw_item * cw_itemstore_get(cw_itemstore_t s, uint32_t id)
extern cw_itemstore_t cw_itemstore_create();
extern int cw_itemstore_set_strn(cw_itemstore_t s,uint32_t id,const char *str,int n);
extern int cw_itemstore_set_str(cw_itemstore_t s,uint32_t id,const char *str);
extern int cw_itemstore_set_ptr(cw_itemstore_t s, uint32_t id, void*ptr);
extern int cw_itemstore_set_bstrn(cw_itemstore_t s, uint32_t id, uint8_t *data,int len);
extern int cw_itemstore_set_dword(cw_itemstore_t s,uint32_t id,uint32_t dword);
extern int cw_itemstore_set_byte(cw_itemstore_t s,uint32_t id,uint8_t byte);
extern int cw_itemstore_set_version(cw_itemstore_t s, uint32_t id, uint32_t vendor_id, uint8_t * versionstr, int len);
extern void *cw_item_get_data_ptr(struct cw_item *item);
extern void cw_item_release_data_ptr(struct cw_item *item, void *data);
int cw_itemstore_set_fun(cw_itemstore_t s, uint32_t id,
void *(*funget) (void *arg),
void (*funfree) (void *arg, void *data), void *arg);
#endif

View File

@ -24,8 +24,9 @@
#include "lwapp.h"
/**
* Calculate the 16-bit checksum for LWAPP image data message
* elements with opcode 3 - also used by Cisco in CAPWAP
* Calculate the 16-bit checksum for LWAPP Image Data message
* elements with opcode 3 (see RFC5412)
* This is also used by Cisco in CAPWAP
* @param d pointer to data to calulate the checksum for
* @param len length of data
* @return the calculated checksum.
@ -48,3 +49,4 @@ uint16_t lw_checksum(uint8_t * d, int len)
return (~sum) & 0xffff;
}

View File

@ -167,6 +167,15 @@
#define lw_put_dword(dst,dw)\
(*((uint32_t*)(dst)) = htonl(dw),4)
#define lw_set_byte(dst,b) \
(*(dst)=b);
#define lw_set_word(dst,b) \
(*((uint16_t*)(dst)) = htons(w))
#define lw_set_dword(dst,dw)\
(*((uint32_t*)(dst)) = htonl(dw))
#define lw_get_byte(src)\
(*(uint8_t*)(src))
@ -204,6 +213,9 @@ static inline int lw_put_elem_hdr(uint8_t *dst,uint8_t type,uint16_t len)
return 3;
}
extern int lw_put_sockaddr(uint8_t *dst, struct sockaddr_storage *addr);
extern int lw_put_cisco_path_mtu(uint8_t *dst, uint16_t max, uint16_t padding);
#define lw_put_certificate(dst,cert,len) lw_put_data(dst,cert,len)
extern int lw_put_ac_descriptor(uint8_t * dst, struct ac_info * acinfo);

View File

@ -61,6 +61,7 @@ extern char * sock_get_primary_if(int family);
#define sock_hwaddr2idstr(s,l) ( sock_hwaddrtostr( s,l, (char[64]){0}, "" ) )
#define sock_addrfamily(addr) ( ((struct sockaddr_storage*)(addr))->ss_family )
#endif /* __SOCK_H */

View File

@ -6,7 +6,8 @@
extern struct avltree * stravltree_create();
const char * stravltree_add(struct avltree * t, const char * str);
#define stravltree_destroy(t) avltree_destroy(t)
#define stravltree_foreach(t,f,p,d) avltree_foreach(t,f,p,d)
#define stravltree_foreach_asc(t,f,p) avltree_foreach_asc(t,f,p)
#define stravltree_foreach_desc(t,f,p) avltree_foreach_desc(t,f,p)
#endif

View File

@ -28,7 +28,7 @@ int wtpinfo_readelem_ecn_support(struct wtpinfo * wtpinfo, int type, uint8_t * m
int cw_readelem_cw_local_ip_addr(struct sockaddr * local_ip, int type, uint8_t * msgelem, int len)
{
switch (type){
case CWMSGELEM_CAPWAP_LOCAL_IPV4_ADDRESS:
case CW_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS:
{
if (len!=4)
return -1;
@ -42,7 +42,7 @@ int cw_readelem_cw_local_ip_addr(struct sockaddr * local_ip, int type, uint8_t *
return 1;
}
#ifdef WITH_IPV6
case CWMSGELEM_CAPWAP_LOCAL_IPV6_ADDRESS:
case CW_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS:
{
if (len!=16)
return -1;
@ -69,7 +69,7 @@ int wtpinfo_readelem_cw_local_ip_addr(struct wtpinfo * wtpinfo, int type, uint8_
{
switch (type){
case CWMSGELEM_CAPWAP_LOCAL_IPV4_ADDRESS:
case CW_ELEM_CAPWAP_LOCAL_IPV4_ADDRESS:
{
if (len!=4)
return -1;
@ -83,7 +83,7 @@ int wtpinfo_readelem_cw_local_ip_addr(struct wtpinfo * wtpinfo, int type, uint8_
return 1;
}
#ifdef WITH_IPV6
case CWMSGELEM_CAPWAP_LOCAL_IPV6_ADDRESS:
case CW_ELEM_CAPWAP_LOCAL_IPV6_ADDRESS:
{
if (len!=16)
return -1;

View File

@ -8,7 +8,7 @@
int wtpinfo_readelem_location_data(struct wtpinfo * wtpinfo, int type, uint8_t * msgelem, int len)
{
if (type != CWMSGELEM_LOCATION_DATA)
if (type != CW_ELEM_LOCATION_DATA)
return 0;
cw_setstr(&wtpinfo->location,msgelem,len);

View File

@ -85,18 +85,18 @@ static int wtpinfo_readelem_wtp_descriptor_(struct wtpinfo * wtpinfo, int type,
cw_dbg(DBG_MSG,"Reading WTP descriptor subelement, type=%d,len=%d",subtype,sublen);
switch(subtype){
case CWMSGSUBELEM_WTP_DESCRIPTOR_HARDWARE_VERSION:
case CW_SUBELEM_WTP_HARDWARE_VERSION:
wtpinfo->hardware_vendor_id=vendor_id;
cw_setstr(&wtpinfo->hardware_version,msgelem+i,sublen);
wtpinfo->hardware_version_len=sublen;
break;
case CWMSGSUBELEM_WTP_DESCRIPTOR_SOFTWARE_VERSION:
case CW_SUBELEM_WTP_SOFTWARE_VERSION:
wtpinfo->software_vendor_id=vendor_id;
bstr_replace(&wtpinfo->software_version,bstr_create(msgelem+i,sublen));
wtpinfo->software_version_len=sublen;
break;
case CWMSGSUBELEM_WTP_DESCRIPTOR_BOOTLOADER_VERSION:
case CW_SUBELEM_WTP_BOOTLOADER_VERSION:
wtpinfo->bootloader_vendor_id=vendor_id;
cw_setstr(&wtpinfo->bootloader_version,msgelem+i,sublen);
wtpinfo->bootloader_version_len=sublen;