WTP can join and send cfg request

shell
7u83 6 months ago
parent 9307b05b46
commit c2cb96e5dc
  1. 59
      src/ac/discovery_cache.c
  2. 50
      src/ac/wtpman.c
  3. 4
      src/cw/Makefile
  4. 75
      src/cw/cfg.c
  5. 6
      src/cw/cfg.h
  6. 180
      src/cw/conn.c
  7. 37
      src/cw/conn.h
  8. 74
      src/cw/conn_init.c
  9. 19
      src/cw/cw.c
  10. 5
      src/cw/cw.h
  11. 19
      src/cw/cw_check_missing_mand.c
  12. 43
      src/cw/cw_in_check_disc_req.c
  13. 44
      src/cw/cw_in_check_join_req.c
  14. 47
      src/cw/cw_in_check_join_resp.c
  15. 37
      src/cw/cw_out_generic_indexed_enum.c
  16. 1
      src/cw/cw_read_ac_descriptor.c
  17. 6
      src/cw/cw_read_wtp_descriptor.c
  18. 1
      src/cw/cw_type_bstr16.c
  19. 6
      src/cw/cw_type_str.c
  20. 3
      src/cw/cw_type_struct.c
  21. 29
      src/cw/cw_write_descriptor_subelem.c
  22. 54
      src/cw/cw_write_radio_element.c
  23. 6
      src/cw/discovery.c
  24. 35
      src/cw/intavltree.c
  25. 15
      src/cw/intavltree.h
  26. 1
      src/cw/msgset.h
  27. 2
      src/cw/send.c
  28. 1
      src/cw/val.h
  29. 2
      src/mod/capwap/capwap_actions.c
  30. 2
      src/mod/capwap/capwap_in_vendor_specific_payload.c
  31. 2
      src/mod/capwap/capwap_in_wtp_descriptor.c
  32. 2
      src/mod/capwap/capwap_out_capwap_local_ip_address.c
  33. 9
      src/mod/capwap/capwap_out_wtp_descriptor.c
  34. 93
      src/mod/cisco/cisco_actions.c
  35. 47
      src/mod/cisco/cisco_in_ap_regulatory_domain.c
  36. 2
      src/mod/cisco/cisco_in_spam_vendor_specific.c
  37. 4
      src/mod/cisco/cisco_out_ac_descriptor.c
  38. 2
      src/mod/cisco/cisco_out_radio_generic.c
  39. 20
      src/mod/cisco/cisco_out_wtp_descriptor.c
  40. 16
      src/wtp/configure.c
  41. 11
      src/wtp/discovery.c
  42. 53
      src/wtp/join.c
  43. 15
      src/wtp/wtp_main.c

@ -4,6 +4,7 @@
#include "cw/mlist.h"
#include "mavl.h"
#include "cw/mod.h"
#include "cw/dbg.h"
#include "discovery_cache.h"
struct cw_DiscoveryCacheElem{
@ -108,15 +109,25 @@ errX:
void discovery_cache_add(struct cw_DiscoveryCache *cache,
struct sockaddr * addr, struct cw_Mod * mod_capwap, struct cw_Mod * mod_bindings)
{
{
cw_dbg(DBG_X,"////////////////////////// ADDD CAHCE ///////////////////////");
char str[128];
sock_addrtostr(addr,str,128,1);
printf("Add addr: %s\n",str);
}
struct cw_DiscoveryCacheElem * cur = cache->queue+cache->qpos;
if (cur->cmod!=NULL){
/* delete here */
cw_dbg(DBG_X,"DOIN MAVL DEL ----- ///////////");
void * ptr = &cur;
mavl_del(cache->byaddr,ptr);
mavl_del(cache->byaddr,ptr);
mavl_del(cache->byaddrp,ptr);
}
cur->cmod=mod_capwap;
cur->bmod=mod_bindings;
sock_copyaddr(&cur->addr,addr);
@ -144,9 +155,24 @@ int discovery_cache_get(struct cw_DiscoveryCache * cache,struct sockaddr *addr,
sock_copyaddr(&search.addr,addr);
search.ctrhi=search.ctrlo=0;
{
cw_dbg(DBG_X,"DISCOVERY CACHE ---------------------------- GET ENTER");
char str[128];
sock_addrtostr(addr,str,128,1);
printf("Add addr: %s\n",str);
}
search_ptr = &search;
result = mavl_get(cache->byaddrp ,&search_ptr);
if (result != NULL){
{
cw_dbg(DBG_X,"DISCOVERY CACHE ---------------------------- FOUND 1 with Port");
char str[128];
sock_addrtostr(addr,str,128,1);
printf("Add addr: %s\n",str);
}
elem = *result;
if (elem != NULL){
mavl_del(cache->byaddr,result);
@ -166,14 +192,37 @@ int discovery_cache_get(struct cw_DiscoveryCache * cache,struct sockaddr *addr,
result = mavl_get_first(cache->byaddr, &search_ptr);
if (result == NULL)
return 0;
{
cw_dbg(DBG_X,"DISCOVERY CACHE ---------------------------- DOUND BY ADDR");
char str[128];
sock_addrtostr(addr,str,128,1);
printf("Add addr: %s\n",str);
}
elem = *result;
if (elem != NULL){
cw_dbg(DBG_X,"elem != NULL");
{
cw_dbg(DBG_X,"DISCOVERY CACHE ---------------------------- DOUND BY ADDR");
char str[128];
sock_addrtostr(&elem->addr,str,128,1);
printf("ELEM addr: %s\n",str);
}
if (sock_cmpaddr((struct sockaddr*)&elem->addr,addr,0)!=0)
return 0;
mavl_del(cache->byaddr,result);
mavl_del(cache->byaddrp,result);
cw_dbg(DBG_X,"DOIN MAVL DEL HERO ----- ///////////");
mavl_del(cache->byaddr,&elem);
cw_dbg(DBG_X,"DOIN MAVL DEL HERXXXXXXO ----- ///////////");
mavl_del(cache->byaddrp,&elem);
cw_dbg(DBG_X,"DOIN MAVL DEL HERO 0000 ----- ///////////");
*modcapwap=elem->cmod;
*modbindings=elem->bmod;

@ -310,7 +310,7 @@ static void *wtpman_main(void *arg)
wtpman->conn->seqnum = 0;
conn = wtpman->conn;
wtpman->conn->remote_cfg = cw_cfg_create();
// wtpman->conn->remote_cfg = cw_cfg_create();
if (!wtpman->dtlsmode) {
@ -358,32 +358,6 @@ static void *wtpman_main(void *arg)
while (!cw_timer_timeout(timer)) {
if (conn->update_cfg != NULL) {
mavl_t tmp;
tmp = conn->local_cfg;
/* mavl_merge(conn->default_cfg, conn->local_cfg);*/
/* mavl_merge(conn->default_cfg, conn->remote_cfg);*/
conn->local_cfg = conn->update_cfg;
cw_dbg(DBG_INFO, "Updating WTP %s",
sock_addr2str(&conn->addr, sock_buf));
rc = cw_send_request(conn,
CAPWAP_MSG_CONFIGURATION_UPDATE_REQUEST);
mavl_merge(conn->remote_cfg, conn->update_cfg);
conn->update_cfg = NULL;
conn->local_cfg = tmp;
}
rc = cw_read_messages(wtpman->conn);
if (rc < 0) {
@ -627,13 +601,16 @@ void wtpman_destroy(struct wtpman *wtpman)
static void copy(struct cw_ElemHandlerParams * params)
{
struct wtpman * wtpman;
struct cw_Conn * conn;
wtpman = (struct wtpman*)params->conn->data;
conn = (struct cw_Conn*)params->conn;
cw_dbg(DBG_X,"------------- Here is the config we ve got from WTP ---------------- ");
cw_cfg_dump(params->cfg);
cw_dbg(DBG_X,"------------- This was the config we ve got from WTP ---------------- ");
cw_dbg(DBG_X,"Now copying:");
cw_cfg_copy(params->cfg,wtpman->wtp_cfg);
cw_cfg_copy(params->cfg,conn->local_cfg);
cw_dbg(DBG_X,"Copying done.");
}
@ -647,17 +624,32 @@ static int discovery_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_pt
static int join_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len)
{
struct cw_Conn * conn = (struct cw_Conn*)params->conn;
char filename[200];
cw_dbg(DBG_X,"JOIN Callback");
copy(params);
const char * wtpname = cw_cfg_get(conn->local_cfg,"wtp-name","default");
sprintf(filename,"wtp-join-%s.ckv",wtpname);
cw_cfg_save(filename,params->cfg);
cw_cfg_clear(params->cfg);
return 0;
}
static int update_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len)
{
struct cw_Conn * conn = (struct cw_Conn*)params->conn;
char filename[200];
cw_dbg(DBG_X,"UPDATE Callback");
copy(params);
cw_cfg_clear(params->cfg);
const char * wtpname = cw_cfg_get(conn->local_cfg,"wtp-name","default");
sprintf(filename,"wtp-status-%s.ckv",wtpname);
cw_cfg_save(filename,params->cfg);
return 0;
}

@ -34,7 +34,6 @@ CWSRC=\
cw_load_file.c\
cw_out_generic_with_index.c\
cw_out_radio_administrative_states.c\
cw_process_element.c\
cw_put_elem_radio_administrative_state.c\
cw_put_elem_radio_operational_state.c\
cw_put_image_data.c\
@ -77,6 +76,7 @@ CWSRC=\
# cw_in_generic.c\
# cw_out_generic.c\
#
# cw_process_element.c\
KTVSRC=\
cw_ktv_add.c\
@ -193,7 +193,6 @@ MISCSRC=\
format.c\
format_is_utf8.c\
fragman.c\
intavltree.c\
md5sum.c\
mod.c\
msgset.c\
@ -206,6 +205,7 @@ MISCSRC=\
message.c\
# intavltree.c\
# conn_q_wait_packet.c\
# conn_init.c\

@ -127,6 +127,7 @@ const char *cw_cfg_get_l(cw_Cfg_t ** cfg, const char * key, const char *def)
int i;
struct cw_Cfg_entry e, *r;
for(i=0; cfg[i]!=NULL; i++){
// cw_dbg(DBG_X,"GET_L IN: %p",cfg[i]);
e.key = key;
r = mavl_get(cfg[i], &e);
if (r!=NULL)
@ -456,7 +457,6 @@ int cw_cfg_read_from_file(FILE * f, cw_Cfg_t * cfg)
return errs;
}
int cw_cfg_load(const char *filename, cw_Cfg_t * cfg)
{
int errs;
@ -471,6 +471,42 @@ int cw_cfg_load(const char *filename, cw_Cfg_t * cfg)
return errno;
}
int cw_cfg_write_to_file(FILE *f, cw_Cfg_t * cfg)
{
mavliter_t it;
struct cw_Cfg_entry *e;
mavliter_init(&it, cfg);
mavliter_foreach(&it) {
int n;
e = mavliter_get(&it);
n=strlen(e->val);
if (n>0)
n-=1;
//printf("Write %s: \"%s\" - %d %d (%02x)\n",e->key,e->val,n,isspace(e->val[n]),e->val[n]);
if(isspace(e->val[0]) || isspace(e->val[n]))
fprintf(f,"%s: \"%s\"\n", e->key, e->val);
else
fprintf(f,"%s: %s\n", e->key, e->val);
//cw_dbg(dbglevel,"%s%s :%s: %s",prefix,data->key,type->get_type_name(data), value);
}
return 0;
}
int cw_cfg_save(const char *filename, cw_Cfg_t *cfg)
{
int rc;
FILE *f = fopen(filename, "wb");
if (!f)
return errno;
rc = cw_cfg_write_to_file(f, cfg);
fclose(f);
return rc;
}
void cw_cfg_iter_init(cw_Cfg_t * cfg, struct cw_Cfg_iter *cfi, const char *base)
{
@ -524,10 +560,12 @@ const char *cw_cfg_iter_next(struct cw_Cfg_iter *cfi, const char *key)
}
int cw_cfg_get_bool(cw_Cfg_t * cfg, const char * key, const char *def)
int cw_cfg_get_bool(cw_Cfg_t * cfg, const char * key, int def)
{
struct cw_Val v;
const char *s = cw_cfg_get(cfg,key,def);
const char *s = cw_cfg_get(cfg,key,NULL);
if (s==NULL)
return def;
CW_TYPE_BOOL->from_str(&v,s);
return v.val.boolean;
}
@ -688,19 +726,48 @@ void cw_cfg_clear(cw_Cfg_t *cfg)
int cw_cfg_base_exists(cw_Cfg_t * cfg, const char *key)
{
struct cw_Cfg_entry e, *result;
//cw_dbg(DBG_X,"LOOX FOR: %s",key);
e.key=key;
result = mavl_get_first(cfg,&e);
if (result == NULL)
return 0;
//cw_dbg(DBG_X,"BASEXXX: %s",result->key);
if (strlen(result->key)<strlen(key))
return 0;
//cw_dbg(DBG_X,"BASEXXX1: %d",strlen(key));
if (result->key[strlen(key)]!='/' && result->key[strlen(key)]!='.')
return 0;
//cw_dbg(DBG_X,"BASEXXX2: ");
if (strncmp(result->key,key,strlen(key))==0)
return 1;
cw_dbg(DBG_X,"BASEXXX3: ");
return 0;
}
int cw_cfg_base_exists_l(cw_Cfg_t ** cfgs, const char *key)
{
int i;
for(i=0; cfgs[i]; i++){
if (cw_cfg_base_exists(cfgs[i],key))
return 1;
}
cw_dbg(DBG_X,"NOX EXISIS: %s in %d",key,i);
return 0;
}
cw_Val_t * cw_cfg_get_val_l(cw_Cfg_t ** cfgs, const char *key, const struct cw_Type *type)
{
const char *s;
cw_Val_t * val;
s = cw_cfg_get_l(cfgs,key,NULL);
val = malloc(sizeof(cw_Val_t));
if (val==NULL)
return NULL;
val->type=type;
val->type->from_str(val,s);
return val;
}

@ -31,7 +31,7 @@ const char * cw_cfg_get(cw_Cfg_t * cfg, const char *key, const char *def);
const char *cw_cfg_iter_next(struct cw_Cfg_iter *cfi, const char *key);
void cw_cfg_iter_init(cw_Cfg_t * cfg, struct cw_Cfg_iter *cfi, const char *base);
int cw_cfg_get_bool(cw_Cfg_t * cfg, const char * key, const char *def);
int cw_cfg_get_bool(cw_Cfg_t * cfg, const char * key, int def);
uint16_t cw_cfg_get_word(cw_Cfg_t * cfg, char *key, uint16_t def);
void cw_cfg_set_int(cw_Cfg_t * cfg, const char * key, int val);
uint8_t cw_cfg_get_byte(cw_Cfg_t * cfg, char *key, uint8_t def);
@ -44,6 +44,10 @@ void cw_cfg_destroy(cw_Cfg_t *cfg);
void cw_cfg_clear(cw_Cfg_t *cfg);
int cw_cfg_base_exists(cw_Cfg_t * cfg, const char *key);
uint8_t cw_cfg_get_byte_l(cw_Cfg_t ** cfgs, char *key, uint8_t def);
cw_Val_t * cw_cfg_get_val_l(cw_Cfg_t ** cfgs, const char *key, const struct cw_Type *type);
int cw_cfg_base_exists_l(cw_Cfg_t ** cfgs, const char *key);
int cw_cfg_save(const char *filename, cw_Cfg_t *cfg);

@ -25,148 +25,6 @@
#include "dtls.h"
/**
* Put a message to a buffer
* This functions assumes, that a message header is
* alread initilaized in buffer
* Message alements are taken fom actiondef in #conn->action
*/
int cw_assemble_message(struct cw_Conn *conn, uint8_t * rawout)
{
char details[1024];
uint8_t *msgptr,*dst;
int type;
struct cw_MsgData * msg;
struct mlistelem * elem;
int len,l;
/* rawout is already initialized, so we can get
* msg type from buffer */
msgptr = rawout + cw_get_hdr_msg_offset(rawout);
type = cw_get_msg_type(msgptr);
/* look for message data */
msg = cw_msgset_get_msgdata(conn->msgset,type);
if (msg == NULL){
cw_log(LOG_ERR,"Error: Can't create message of type %d (%s) - no definition found.",
type, cw_strmsg(type));
return CAPWAP_RESULT_MSG_UNRECOGNIZED;
}
if (msg->preprocess){
msg->preprocess(conn);
}
cw_dbg(DBG_MSG_ASSEMBLY,"*** Assembling message of type %d (%s) ***",
msg->type, msg->name);
dst = msgptr+8;
len =0;
mlist_foreach(elem,msg->elements_list){
struct cw_ElemData * data;
struct cw_ElemHandler * handler;
struct cw_ElemHandlerParams params;
data = mlistelem_dataptr(elem);
handler = cw_msgset_get_elemhandler(conn->msgset,data->proto,data->vendor,data->id);
cw_dbg(DBG_MSG_ASSEMBLY," Add Elem: %d %d %d %s", data->proto, data->vendor, data->id, handler->name);
if (handler==NULL){
cw_log(LOG_ERR,"Can't put message element %d %d %d, no handler defined.",
data->proto,data->vendor,data->id);
continue;
}
if (handler->put == NULL){
if (data->mand){
cw_log(LOG_ERR,"Error: Can't add mandatory message element %d - %s, no put method defined",
handler->id, handler->name);
}
continue;
}
params.conn=conn;
params.cfg=conn->remote_cfg;
params.cfg_list[0]=params.cfg;
params.cfg_list[1]=conn->local_cfg;
params.cfg_list[2]=conn->global_cfg;
params.cfg_list[3]=NULL;
params.msgset=conn->msgset;
params.elemdata = data;
params.msgdata=msg;
params.debug_details=details;
*details=0;
/* if (strcmp(handler->key,"cisco/ap-led-flash-config")==0){
printf("flash config\n");
cisco/ap-led-flash-config/flash-enable
}*/
if (!data->mand){
if (!cw_cfg_base_exists(params.cfg,handler->key)){
cw_dbg(DBG_X,"nothing todo");
continue;
}
}
l = handler->put(handler,&params,dst+len);
/* if(l>0)
cw_dbg_elem(DBG_ELEM_OUT,conn,type,handler,dst+len,l);
* if (strlen(details)){
cw_dbg(DBG_ELEM_DETAIL," %s",params.debug_details);
}
*/ len += l;
}
cw_set_msg_elems_len(msgptr, len);
cw_dbg(DBG_MSG_ASSEMBLY,"*** Done assenmbling message of type %d (%s) ***",
msg->type, msg->name);
if (type & 1) {
/* It's a request, so we have to set seqnum */
int s = conn_get_next_seqnum(conn);
cw_set_msg_seqnum(msgptr,s);
}
{
printf ("----------------------------------- redecode -----------------------------\n");
uint8_t *elems_ptr;
int offset = cw_get_hdr_msg_offset(rawout);
uint8_t *msg_ptr = rawout + offset;
int elems_len = cw_get_msg_elems_len(msg_ptr);
elems_ptr = cw_get_msg_elems_ptr(msg_ptr);
cw_Cfg_t * cfg = cw_cfg_create();
struct cw_ElemHandlerParams params;
params.cfg=cfg;
params.msgset=conn->msgset;
params.msgdata=msg;
cw_decode_elements( &params, elems_ptr,elems_len);
cw_cfg_destroy(cfg);
printf ("----------------------------------- end redecode -----------------------------\n");
}
return CAPWAP_RESULT_SUCCESS;
}
struct msg_callback{
int type; /**< message type */
@ -199,6 +57,11 @@ void cw_conn_init(struct cw_Conn * conn)
conn->process_message=process_message;
conn->msg_callbacks = mavl_create(msg_callback_cmp,NULL,sizeof(struct msg_callback));
conn->update_cfg = cw_cfg_create();
cw_dbg(DBG_X,"Update CFG ist %p",conn->update_cfg);
conn->remote_cfg = cw_cfg_create();
conn->local_cfg = cw_cfg_create();
}
int cw_conn_set_msg_cb(struct cw_Conn *conn, int type, cw_MsgCallbackFun fun)
@ -464,8 +327,6 @@ int cw_in_check_generic(struct cw_Conn *conn, struct cw_action_in *a, uint8_t *
static int process_elements(struct cw_Conn *conn, uint8_t * rawmsg, int len,
struct sockaddr *from)
{
mavl_t mand_found;
mlist_t unrecognized;
struct cw_MsgData search;
struct cw_MsgData *message;
int result_code;
@ -615,16 +476,14 @@ static int process_elements(struct cw_Conn *conn, uint8_t * rawmsg, int len,
elems_ptr = cw_get_msg_elems_ptr(msg_ptr);
mand_found = mavl_create_conststr();
unrecognized = mlist_create(NULL, NULL, sizeof(uint8_t *));
cw_dbg(DBG_MSG_PARSING, "*** Parsing message of type %d - (%s) ***",
message->type, message->name);
memset(&params,0,sizeof(struct cw_ElemHandlerParams));
params.mand_found = mavl_create_conststr();
params.unrecognized = mlist_create(NULL, NULL, sizeof(uint8_t *));
params.cfg = cw_cfg_create();
params.cfg_list[0]=params.cfg;
params.cfg_list[1]=conn->local_cfg;
@ -633,7 +492,6 @@ static int process_elements(struct cw_Conn *conn, uint8_t * rawmsg, int len,
params.from = from;
params.msgdata = message;
params.mand_found = mand_found;
params.msgset=conn->msgset;
params.conn = conn;
@ -642,13 +500,14 @@ static int process_elements(struct cw_Conn *conn, uint8_t * rawmsg, int len,
/* all message elements are processed, do now after processing
by calling the "end" function for the message */
cw_check_missing_mand(message, mand_found);
if (params.mand_found)
cw_check_missing_mand(message, params.mand_found,conn->msgset->handlers_by_key);
cw_dbg(DBG_MSG_PARSING, "*** End parsing message of type %d (%s) ***",
message->type, message->name);
mavl_destroy(mand_found);
if (params.mand_found)
mavl_destroy(params.mand_found);
if (message->postprocess) {
message->postprocess(&params,elems_ptr, elems_len);
@ -662,7 +521,7 @@ static int process_elements(struct cw_Conn *conn, uint8_t * rawmsg, int len,
cw_cfg_clear(params.cfg);
}
conn->remote_cfg=params.cfg;
// conn->remote_cfg=params.cfg;
/* if we've got a request message, we always have to send a response message */
if (message->type & 1) {
@ -693,9 +552,10 @@ static int process_elements(struct cw_Conn *conn, uint8_t * rawmsg, int len,
*/
}
mlist_destroy(unrecognized);
if (params.unrecognized)
mlist_destroy(params.unrecognized);
cw_cfg_destroy(params.cfg);
conn->remote_cfg=NULL;
// conn->remote_cfg=NULL;
return result_code;
@ -955,8 +815,8 @@ void conn_destroy(struct cw_Conn * conn)
if (conn->local_cfg)
cw_cfg_destroy(conn->local_cfg);
if (conn->update_cfg)
cw_cfg_destroy(conn->update_cfg);
free(conn);
}

@ -38,7 +38,6 @@
/*#include "mbag.h"*/
#include "intavltree.h"
#include "bstr.h"
#include "msgset.h"
@ -70,13 +69,23 @@ struct cw_Conn {
int recv_timeout;
cw_Cfg_t * global_cfg; /**< This should set the global cfg of the program
which is using this conn object.
Teh global_cfg has to be treated read-only. */
cw_Cfg_t * local_cfg; /**< local_cfg contains overrides for global_cfg
wich are related to this conn object. */
mavl_t remote_cfg;
// mavl_t default_cfg;
mavl_t remote_cfg; /**< contains the configuration we now from the
device this conn object ist connected to.
Typically this is what we have got from discovery
response or join response in WTP mode.
And in AC mode this contains date receive from
configuration status request. */
mavl_t update_cfg;
mavl_t local_cfg;
mavl_t global_cfg;
bstr16_t session_id;
@ -90,9 +99,6 @@ struct cw_Conn {
uint8_t wbid;
/** Counter for mandatory message elements */
/* struct avltree *mand;*/
/** Actionsdefs - this defines the possible actions for
this conn object, so in the end this is the specification
@ -119,10 +125,6 @@ struct cw_Conn {
int last_seqnum_received;
int last_message_id_received;
// struct cwmsg req_msg;
// struct cwmsg resp_msg;
/** Buffer for outgoing request messages */
uint8_t req_buffer[CONN_MAX_MSG_LENGTH];
@ -141,17 +143,10 @@ struct cw_Conn {
int (*recv_packet) (struct cw_Conn*, uint8_t *, int);
int (*recv_packet_peek) (struct cw_Conn*, uint8_t *, int);
int (*send_packet) (struct cw_Conn*, const uint8_t *, int);
/*
// int (*recv_data_packet) (struct cw_Conn*, uint8_t *,int);
// int (*send_data_packet) (struct cw_Conn*, const uint8_t *, int);
*/
int (*readfrom) (struct cw_Conn*, uint8_t *, int, struct sockaddr_storage *);
int (*read) (struct cw_Conn*, uint8_t *, int);
int (*write) (struct cw_Conn*, const uint8_t *, int);
/*
// int (*write_data) (struct cw_Conn*, const uint8_t *, int);
*/
/* optional packet queue */
uint8_t **q;
int qsize;

@ -1,74 +0,0 @@
/*
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/>.
*/
/**
* @file
* @brief conn_init
*/
#include <string.h>
#include "conn.h"
#include "capwap.h"
#include "cw.h"
/*
static int write_header(struct cw_ElemHandler * handler, uint8_t * dst, int len)
{
if (handler->vendor)
return len + cw_put_elem_vendor_hdr(dst, handler->vendor, handler->id, len);
return len + cw_put_elem_hdr(dst, handler->id, len);
}
static int header_len(struct cw_ElemHandler * handler)
{
return handler->vendor ? 10 : 4;
}
*/
/**
* Basic initialization of a conn object
* @param conn conn object to initialize
*/
void conn_init(struct cw_Conn * conn)
{
memset(conn,0,sizeof(struct cw_Conn ));
conn->retransmit_interval=CAPWAP_RETRANSMIT_INTERVAL;
conn->max_retransmit=CAPWAP_MAX_RETRANSMIT;
conn->wait_dtls=CAPWAP_WAIT_DTLS;
conn->wait_join=CAPWAP_WAIT_JOIN;
conn->mtu_discovery=1;
// conn->capwap_mode = 0;
conn->strict_capwap=1;
conn->process_packet=conn_process_packet;
conn->process_message=process_message;
/*
conn->write_header = write_header;
conn->header_len = header_len;
*/
}

@ -40,6 +40,8 @@ int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams
{
int start, len, l;
// cw_dbg(DBG_X,"cw_out_generic (%s)%s",((struct cw_Type*)handler->type)->name,handler->key);
// cw_dbg(DBG_X,"Generic out!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
// cw_cfg_dump(params->cfg);
@ -48,7 +50,7 @@ int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams
start = params->msgset->header_len(handler);
len = ((const cw_Type_t*)(handler->type))->
write(params->cfg_list,handler->key,dst+start,handler->param);
// cw_dbg(DBG_X, "Type result is %d",len);
if (len == -1) {
const char *vendor="";
@ -69,6 +71,7 @@ int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams
, cw_strmsg(a->msg_id),a->item_id);
*/
}
return 0;
}
@ -114,19 +117,21 @@ int cw_out_radio_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerP
int radios;
len =0;
radios = cw_cfg_get_byte(params->cfg,"wtp-descriptor/max-radios",0);
radios = cw_cfg_get_byte_l(params->cfg_list,"wtp-descriptor/max-radios",0);
for(i=0;i<radios;i++){
l=0;
type = (struct cw_Type*)handler->type;
start = params->msgset->header_len(handler)+len;
sprintf(key,"radio.%d/%s",i,handler->key);
cw_dbg(DBG_X,"KEY: %s",key);
// cw_dbg(DBG_X,"KEY: %s",key);
l = type->write(params->cfg_list, key,dst+start+1,handler->param);
if (l==-1)
continue;
l += cw_put_byte(dst+start,i);
l += cw_put_byte(dst+start+l,i);
l += type->write(params->cfg_list, key,dst+start+l,handler->param);
l = params->msgset->write_header(handler,dst+len,l);
len+=l;

@ -348,7 +348,8 @@ struct cw_DescriptorSubelemDef {
int cw_check_missing_mand(struct cw_MsgData *msgdata, mavl_t keys );
//int cw_check_missing_mand(struct cw_MsgData *msgdata, mavl_t keys );
int cw_check_missing_mand(struct cw_MsgData *msgdata, mavl_t keys, mavl_t handlers_by_key );
@ -365,7 +366,7 @@ int cw_read_wtp_descriptor(mavl_t mbag, struct cw_Conn *conn,
struct cw_ElemHandler *eh, uint8_t * data, int len,
struct cw_DescriptorSubelemDef *allowed);
int cw_write_descriptor_subelem (uint8_t *dst, mavl_t ktvstore,
int cw_write_descriptor_subelem (uint8_t *dst, cw_Cfg_t ** cfg_list,
int subelem_id, const char * parent_key);
int cw_write_radio_element(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params, int idx,

@ -3,7 +3,7 @@
#include "dbg.h"
#include "log.h"
int cw_check_missing_mand(struct cw_MsgData *msgdata, mavl_t keys )
int cw_check_missing_mand(struct cw_MsgData *msgdata, mavl_t keys, mavl_t handlers_by_key )
{
mlistelem_t * elem;
char *mandkey, *result;
@ -26,7 +26,22 @@ int cw_check_missing_mand(struct cw_MsgData *msgdata, mavl_t keys )
}
mlist_foreach(elem,missing){
cw_dbg(DBG_RFC," Missing mandatory message element: %s", mlistelem_get_str(elem));
const char * str;
struct cw_ElemHandler search, *result;
str = mlistelem_get_str(elem);
search.key = str;
result = mavl_get(handlers_by_key,&search);
if (result == NULL){
cw_log(LOG_ERR,"Can't find handler for for key %s",str);
}
else {
cw_dbg(DBG_RFC,"Missing mandatory message element: %s: %d - %s",
str,result->id, result->name);
}
}
count = missing->count;

@ -1,43 +0,0 @@
#include "capwap.h"
#include "intavltree.h"
#include "log.h"
#include "dbg.h"
#include "sock.h"
int cw_in_check_disc_req(struct conn *conn, struct cw_action_in *a, uint8_t * data,
int len,struct sockaddr *from)
{
/*
char sock_buf[SOCK_ADDR_BUFSIZE];
cw_action_in_t *mlist[120];
int n = cw_check_missing_mand(mlist, conn, a);
conn->capwap_state = CW_STATE_NONE;
if (n && conn->strict_capwap) {
cw_dbg_missing_mand(DBG_MSG_ERR, conn, mlist, n, a);
// if mandatory elements are missing, in strict
// mode send no discovery response
cw_dbg(DBG_MSG_ERR,
"Ignoring Discovery Request from %s - missing mandatory elements.",
sock_addr2str(from,sock_buf));
return -1;
}
if ( n ) {
// put a warning here
cw_dbg_missing_mand(DBG_RFC, conn, mlist, n, a);
}
// ok, send response
conn->capwap_state = CAPWAP_STATE_JOIN;
*/
return 0;
}

@ -1,44 +0,0 @@
#include "capwap.h"
#include "intavltree.h"
#include "dbg.h"
#include "log.h"
#include "format.h"
#include "connlist.h"
int cw_in_check_join_req(struct conn *conn, struct cw_action_in *a, uint8_t * data,
int len,struct sockaddr *from)
{
/*
cw_action_in_t * mlist[60];
//Check for mandatory elements
int n = cw_check_missing_mand(mlist,conn,a);
if (n) {
if ( conn->strict_capwap ){
cw_dbg_missing_mand(DBG_MSG_ERR,conn,mlist,n,a);
conn->capwap_state=CAPWAP_STATE_JOIN;
return CW_RESULT_MISSING_MAND_ELEM;
}
cw_dbg_missing_mand(DBG_RFC,conn,mlist,n,a);
}
connlist_lock(conn->connlist);
struct conn *cc = connlist_get_by_session_id(conn->connlist,conn);
if (!cc){
connlist_add_by_session_id(conn->connlist,conn);
}
connlist_unlock(conn->connlist);
if (cc){
cw_dbg(DBG_ELEM_ERR,"Session already in use %s",format_bin2hex(conn->session_id,16));
conn->capwap_state=CAPWAP_STATE_JOIN;
return CW_RESULT_JOIN_FAILURE_SESSION_ALREADY_IN_USE;
}
// set result code to ok and change to configure state
mbag_set_dword(conn->outgoing,CW_ITEM_RESULT_CODE,0);
conn->capwap_state = CW_STATE_CONFIGURE;
*/
return 0;
}

@ -1,47 +0,0 @@
#include <errno.h>
#include "capwap.h"
#include "intavltree.h"
#include "dbg.h"
#include "log.h"
int cw_in_check_join_resp(struct conn *conn, struct cw_action_in *a, uint8_t * data,
int len,struct sockaddr *from)
{
/*
cw_action_in_t * mlist[60];
mbag_item_t * jresult = mbag_get(conn->incomming,CW_ITEM_RESULT_CODE);
if (jresult ) {
if (!cw_result_is_ok(jresult->u2.dword)){
return jresult->u2.dword;
}
}
// Check for mandatory elements
int n = cw_check_missing_mand(mlist,conn,a);
if (n && conn->strict_capwap) {
cw_dbg_missing_mand(DBG_MSG_ERR,conn,mlist,n,a);
conn->capwap_state=CAPWAP_STATE_JOIN;
errno=EAGAIN;
return -1; //CW_RESULT_MISSING_MAND_ELEM;
}
if (n){
cw_dbg_missing_mand(DBG_RFC,conn,mlist,n,a);
}
if ( jresult ) {
return jresult->u2.dword;
}
// set result code to ok and change to configure state
// mbag_set_dword(conn->outgoing,CW_ITEM_RESULT_CODE,0);
*/
return 0;
}

@ -1,17 +1,18 @@
#include "cw.h"
#include"dbg.h"
#include "cfg.h"
int cw_out_generic_indexed_enum(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst)
{
cw_dbg(DBG_X,"Fix: cw_out_generic_indexed_enum");
stop();
// cw_dbg(DBG_X,"Fix: cw_out_generic_indexed_enum %s",handler->key);
// stop();
/*
char key[CW_CFG_MAX_KEY_LEN];
int i;
cw_Val_t * result;
// cw_Val_t * result;
int len,start;
uint8_t * ob;
const cw_ValIndexed_t *ie;
@ -26,34 +27,42 @@ int cw_out_generic_indexed_enum(struct cw_ElemHandler * handler, struct cw_ElemH
e = ie->type;
for(i=0; e[i].name!=NULL; i++) {
int b;
sprintf(key,"%s/%s",handler->key,e[i].name);
//printf("Her is the Key: %s - %s\n",key, );
cw_dbg(DBG_X,"Her is the Key: %s %s\n",key,e[i].name);
result = cw_ktv_base_exists(params->cfg,key);
if (result==NULL)
b = cw_cfg_base_exists_l(params->cfg_list,handler->key);
if (!b){
stop();
continue;
}
start = params->msgset->header_len(handler);
len = 0;
if (ie->idxpos==0)
len = 1;
if (e[i].fun_out==NULL)
len += result->type->put(result,ob+start+len);
else
len += cw_ktv_write_struct(params->cfg,
NULL,e[i].type,key,ob+start+len);
if (e[i].fun_out==NULL){
stop();
// result =
// len += result->type->put(result,ob+start+len);
}
else{
len += ((cw_Type_t*)e[i].type)->write(params->cfg_list,key,ob+start+len,e[i].param);
// len += cw_ktv_write_struct(params->cfg,
// NULL,e[i].type,key,ob+start+len);
}
cw_set_byte(ob+start+ie->idxpos,e[i].value);
if (ie->idxpos==len)
len++;
ob += params->msgset->write_header(handler,ob,len);
// cw_val_destroy(result);
}
return ob-dst;
*/
return 0;
}

@ -33,7 +33,6 @@ int cw_read_ac_descriptor(mavl_t store,
{
CW_TYPE_STRUCT->read(params->cfg,eh->key,data,len,acstatus);
// cw_ktv_read_struct(params->remote_cfg,acstatus,eh->key,data,len);
if (!allowed)
allowed=allowed_default;

@ -39,10 +39,12 @@ int cw_read_wtp_descriptor(mavl_t cfg, struct cw_Conn *conn,
}
sprintf(key,"%s/%s",eh->key, "max-radios");
cw_ktv_add(cfg,key,CW_TYPE_BYTE,NULL,data,1);
// cw_ktv_add(cfg,key,CW_TYPE_BYTE,NULL,data,1);
CW_TYPE_BYTE->read(cfg,key,data,1,eh->param);
sprintf(key,"%s/%s",eh->key, CW_SKEY_RADIOS_IN_USE);
cw_ktv_add(cfg,key,CW_TYPE_BYTE,NULL,data+1,1);
// cw_ktv_add(cfg,key,CW_TYPE_BYTE,NULL,data+1,1);
CW_TYPE_BYTE->read(cfg,key,data,1,eh->param);

@ -21,6 +21,7 @@
#include "format.h"
#include "cw.h"
#include "val.h"
#include "dbg.h"
static void del ( struct cw_Val * data )

@ -105,6 +105,10 @@ static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, c
return l;
}
static int bwrite(cw_Cfg_t ** cfgs, const char *key, uint8_t *dst, const void * param)
{
return cw_generic_write_l(cfgs,CW_TYPE_STR,key,dst,param);
}
const struct cw_Type cw_type_str = {
@ -119,6 +123,8 @@ const struct cw_Type cw_type_str = {
get_type_name, /* get_type_name */
NULL,
bread,
bwrite,
};

@ -115,7 +115,7 @@ static int write_struct(cw_Cfg_t ** cfgs, const cw_ValStruct_t * stru, const ch
else{
struct cw_Type * type;
type = (struct cw_Type *)stru[i].type;
wrlen = type->write(cfgs,stru[i].key,dst+pos,stru[i].valguard);
wrlen = type->write(cfgs,key,dst+pos,stru[i].valguard);
/* result->valguard=stru[i].valguard;
@ -142,7 +142,6 @@ static int bwrite(cw_Cfg_t **cfgs, const char *key, uint8_t *dst, const void *
{
return write_struct(cfgs,param,key,dst);
cw_dbg(DBG_X,"Key: %s",key);
stop();
/*

@ -5,22 +5,23 @@
#include "dbg.h"
#include "cfg.h"
int cw_write_descriptor_subelem (uint8_t *dst, cw_Cfg_t * cfg,
int cw_write_descriptor_subelem (uint8_t *dst, cw_Cfg_t ** cfg_list,
int subelem_id, const char * parent_key )
{
char key[256];
uint32_t vendor;
bstr16_t version;
//bstr16_t version;
const char *vendor_s;
uint8_t *d;
/* d += cw_put_dword(d, bstrv_get_vendor_id(v));
d += cw_put_dword(d, (subelem_id << 16) | bstrv_len(v));
d += cw_put_data(d, bstrv_data(v), bstrv_len(v));
*/
sprintf (key, "%s/%s", parent_key, CW_SKEY_VENDOR);
vendor_s = cw_cfg_get (cfg, key, NULL);
vendor_s = cw_cfg_get_l (cfg_list, key, NULL);
if (vendor_s == NULL) {
cw_log (LOG_ERR, "Can't put subelem %s, no value of type Dword found.", key);
@ -28,11 +29,16 @@ int cw_write_descriptor_subelem (uint8_t *dst, cw_Cfg_t * cfg,
}
vendor = atoi(vendor_s);
sprintf (key, "%s/%s", parent_key, CW_SKEY_VERSION);
version = cw_cfg_get_bstr16 (cfg, key, NULL);
if (version == NULL) {
cw_Val_t * val = cw_cfg_get_val_l(cfg_list, key, CW_TYPE_BSTR16);
//version = cw_cfg_get_bstr16 (cfg, key, NULL);
if (val == NULL) {
cw_log (LOG_ERR, "Can't put subelem %s, no value of type Bstr16 found.", key);
return 0;
}
@ -44,10 +50,13 @@ int cw_write_descriptor_subelem (uint8_t *dst, cw_Cfg_t * cfg,
/* put version */
d += cw_put_dword (d, (subelem_id << 16) | bstr16_len(version));
d += cw_put_bstr16(d, version);
d += cw_put_dword (d, (subelem_id << 16) | val->type->len(val));
// d += cw_put_bstr16(d, version);
d += val->type->put(val,d);
cw_val_destroy(val);
free(version);
// free(version);
return d-dst;
}

@ -1,12 +1,12 @@
#include "cw.h"