Lots done in move to typeless

This commit is contained in:
7u83 2022-08-14 12:26:34 +02:00
parent b158544f1a
commit 459e2e2aeb
52 changed files with 1128 additions and 883 deletions

View File

@ -178,20 +178,6 @@ int main (int argc, char *argv[])
/*
cw_Cfg_t * tcfg = cw_cfg_create();
cw_cfg_set(tcfg,"tube.0","hallo");
cw_cfg_set(tcfg,"tube.1","welt");
cw_cfg_set(tcfg,"tube.2","der guten laune");
cw_cfg_dump(tcfg);
printf("Next Index: %d\n",cw_cfg_get_next_index(tcfg,"kinder"));
exit(0);
*/
/* parse arguments */
parse_args (argc, argv, &bootcfg);
@ -214,6 +200,39 @@ int main (int argc, char *argv[])
cw_log_name = "AC-Tube";
/*
{
int rc;
cw_Cfg_t * cfg = global_cfg;
struct cw_Cfg_entry e, *result;
e.key="hi";
rc = cw_cfg_base_exists(cfg,"ac-descriptor");
if (!rc ){
printf("No!\n");
return 0;
}
printf("RESULT: %d\n",rc);
cw_cfg_set(tcfg,"tube.0","hallo");
cw_cfg_set(tcfg,"tube.1","welt");
cw_cfg_set(tcfg,"tube.2","der guten laune");
cw_cfg_dump(tcfg);
printf("Next Index: %d\n",cw_cfg_get_next_index(tcfg,"kinder"));
exit(0);
}
*/
start_shell();

View File

@ -54,3 +54,15 @@ ac-descriptor/stations: 0
capwap-control-ip-address/address.0: 192.168.0.14
#
# CAPWAP Timers
#
capwap-timers/change-state-pending-timer: Word: 3
capwap-timers/data-check-timer: Word: 10
capwap-timers/echo-interval :Byte: 30
capwap-timers/max-discovery-interval :Byte: 10

View File

@ -131,10 +131,13 @@ void set_cmd(struct shelldata *sd, const char *str)
{
struct cw_Conn * conn;
struct cw_Val_Reader r;
char key[CW_KTV_MAX_KEY_LEN];
char type[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
char type[CW_CFG_MAX_KEY_LEN];
char val[2048];
cw_ktv_init_str_reader(&r,str,strlen(str));
stop();
// cw_ktv_init_str_reader(&r,str,strlen(str));
cw_ktv_parse_string(&r,key,type,val);
/*cw_ktv_parse_string(key,type,val, 2048);*/
@ -145,7 +148,7 @@ void set_cmd(struct shelldata *sd, const char *str)
void del_cmd(struct shelldata *sd, const char *str)
{
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
sscanf(str,"%s",key);
cw_ktv_del_sub(sd->update_cfg,key);
}
@ -342,7 +345,7 @@ void execute_cmd (struct shelldata * sd, const char *str)
return;
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
char type[128];
char val[2048];

View File

@ -37,7 +37,6 @@
#include "ac.h"
#include "conf.h"
#include "db.h"
#include "socklist.h"
#include "wtpman.h"
#include "wtplist.h"
@ -617,27 +616,49 @@ void wtpman_destroy(struct wtpman *wtpman)
{
if (wtpman->conn)
conn_destroy(wtpman->conn);
if (wtpman->wtp_cfg)
cw_cfg_destroy(wtpman->wtp_cfg);
free(wtpman);
}
static void discovery_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len)
static void copy(struct cw_ElemHandlerParams * params)
{
cw_dbg(DBG_X,"Discovery->Callback");
struct wtpman * wtpman;
wtpman = (struct wtpman*)params->conn->data;
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_dbg(DBG_X,"Copying done.");
}
static void join_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len)
static int discovery_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len)
{
struct wtpman * wtpman = (struct wtpman *)params->conn->data;
cw_dbg(DBG_X,"JOIN->Callback");
wtpman->pjoin(params,elems_ptr,elems_len);
cw_dbg(DBG_X,"DISCOVERY Callback");
copy(params);
cw_cfg_clear(params->cfg);
return 0;
}
static void update_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len)
static int join_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len)
{
struct wtpman * wtpman = (struct wtpman *)params->conn->data;
cw_dbg(DBG_X,"UPDATE->Callback");
if ( wtpman->pupdate )
wtpman->pupdate(params,elems_ptr,elems_len);
cw_dbg(DBG_X,"JOIN Callback");
copy(params);
cw_cfg_clear(params->cfg);
return 0;
}
static int update_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len)
{
cw_dbg(DBG_X,"UPDATE Callback");
copy(params);
cw_cfg_clear(params->cfg);
return 0;
}
@ -646,8 +667,8 @@ static void update_cb(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr,
static setup_complete(struct cw_Conn *conn)
{
struct wtpman * wtpman = (struct wtpman *)conn->data;
wtpman->pjoin = cw_msgset_set_postprocess(conn->msgset,CAPWAP_MSG_JOIN_REQUEST,join_cb);
wtpman->pupdate = cw_msgset_set_postprocess(conn->msgset,CAPWAP_MSG_CONFIGURATION_STATUS_REQUEST,update_cb);
// wtpman->pjoin = cw_msgset_set_postprocess(conn->msgset,CAPWAP_MSG_JOIN_REQUEST,join_cb);
// wtpman->pupdate = cw_msgset_set_postprocess(conn->msgset,CAPWAP_MSG_CONFIGURATION_STATUS_REQUEST,update_cb);
cw_dbg(DBG_X,"SETUP COMPLETE");
}
@ -704,6 +725,8 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr,
}
wtpman->conn->global_cfg = global_cfg;
wtpman->conn->local_cfg = cw_cfg_create();
wtpman->wtp_cfg = cw_cfg_create();
wtpman->conn->role = CW_ROLE_AC;
wtpman->conn->data=wtpman;
@ -716,6 +739,17 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr,
CAPWAP_MSG_DISCOVERY_REQUEST,
discovery_cb);
cw_conn_set_msg_cb(wtpman->conn,
CAPWAP_MSG_JOIN_REQUEST,
join_cb);
cw_conn_set_msg_cb(wtpman->conn,
CAPWAP_MSG_CONFIGURATION_STATUS_REQUEST,
update_cb);
// wtpman->conn->mods = conf_mods;
wtpman->conn->strict_capwap = conf_strict_capwap;
@ -764,7 +798,7 @@ struct wtpman *wtpman_create(int socklistindex, struct sockaddr *srcaddr,
void wtpman_addpacket(struct wtpman *wtpman, uint8_t * packet, int len)
{
cw_dbg(DBG_X,"ADD PACKET DETECTED %d",wtpman->conn->detected);
// cw_dbg(DBG_X,"ADD PACKET DETECTED %d",wtpman->conn->detected);
conn_q_add_packet(wtpman->conn, packet, len);
}

View File

@ -38,10 +38,7 @@ struct wtpman {
from a .ckv file on startup.
*/
cw_MsgCallbackFun pdiscovery;
cw_MsgCallbackFun pjoin;
cw_MsgCallbackFun pupdate;
cw_Cfg_t * wtp_cfg;

View File

@ -3,6 +3,7 @@ MFDEPS=../Defs.mak
CWSRC=\
cw.c\
cw_check_missing_mand.c\
cw_clock_lap.c\
cw_dbg_elem.c\
@ -16,12 +17,6 @@ CWSRC=\
cw_in_ac_name_with_priority.c\
cw_in_capwap_local_ipv4_address.c\
cw_in_capwap_local_ipv6_address.c\
cw_in_check_disc_req.c\
cw_in_check_img_data_req_ac.c\
cw_in_check_img_data_req_wtp.c\
cw_in_check_join_req.c\
cw_in_check_join_resp.c\
cw_in_generic.c\
cw_in_generic_with_index.c\
cw_in_generic_struct.c\
cw_in_radio_generic_struct.c\
@ -37,7 +32,6 @@ CWSRC=\
cw_in_wtp_reboot_statistics.c\
cw_is_printable.c\
cw_load_file.c\
cw_out_generic.c\
cw_out_generic_with_index.c\
cw_out_radio_administrative_states.c\
cw_process_element.c\
@ -75,6 +69,14 @@ CWSRC=\
cw_detect_nat.c\
cw_read_from.c \
# cw_in_check_disc_req.c\
# cw_in_check_img_data_req_ac.c\
# cw_in_check_img_data_req_wtp.c\
# cw_in_check_join_req.c\
# cw_in_check_join_resp.c\
# cw_in_generic.c\
# cw_out_generic.c\
KTVSRC=\
cw_ktv_add.c\
cw_ktv_cast.c\
@ -103,9 +105,9 @@ KTVSRC=\
cw_ktv_base_exists.c\
cw_ktv_save.c\
cw_ktv_del_sub.c\
cw_ktv_parser.c\
cfg.c\
# cw_ktv_parser.c\
LWSRC=\
lw_addelem.c\
@ -179,7 +181,6 @@ MISCSRC=\
conn_destroy.c\
connlist.c\
conn_prepare_image_data_request.c\
conn_process_packet.c\
cw_decode_msg.c \
conn_q_add_packet.c\
conn_q_get_packet.c\
@ -200,13 +201,15 @@ MISCSRC=\
send.c\
strheap.c\
netconn.c\
conn.c
conn.c \
val.c
# conn_q_wait_packet.c\
# conn_init.c\
# conn_create.c\
# conn_send_request.c\
# cw_put_msg.c\
# conn_process_packet.c\
DTLSSRC+=\
dtls_bio.c\
@ -216,7 +219,7 @@ DTLSSRC+=\
RADIOSRC=\
cw_out_radio_generic.c\
cw_out_radio_generic_struct.c\
cw_read_radio_generic.c\
cw_in_radio_generic.c\
MAVLSRC=\
mavl_get_ptr.c\

View File

@ -122,6 +122,20 @@ const char *cw_cfg_get(cw_Cfg_t * cfg, const char *key, const char *def)
return r->val;
}
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++){
e.key = key;
r = mavl_get(cfg[i], &e);
if (r!=NULL)
return r->val;
}
return def;
}
const char *cw_cfg_get2(cw_Cfg_t *cfg1, cw_Cfg_t *cfg2, const char *key, const char *def)
{
return cw_cfg_get(cfg1, key, cw_cfg_get(cfg2,key,def));
@ -527,7 +541,7 @@ uint8_t cw_cfg_get_byte(cw_Cfg_t * cfg, char *key, uint8_t def)
if (s==NULL)
return def;
CW_TYPE_BYTE->from_str(&v,s);
return v.val.word;
return v.val.byte;
}
@ -596,7 +610,6 @@ int cw_cfg_set_val(cw_Cfg_t * cfg, const char *key, const struct cw_Type *type,
memset(&mdata,0,sizeof(cw_Val_t));
mdata.type=type;
mdata.valguard=valguard;
cw_dbg(DBG_X,"SETVAL FOR TYPE: %s",type->name);
mresult = type->get(&mdata,data,len);
if (!mresult){
cw_log(LOG_ERR, "Can't create cfg element for key %s of type %s: %s",
@ -611,3 +624,69 @@ cw_dbg(DBG_X,"SETVAL FOR TYPE: %s",type->name);
type->del(&mdata);
return 1;
}
void cw_cfg_copy(cw_Cfg_t *src, cw_Cfg_t *dst)
{
mavliter_t it;
mavliter_init(&it, src);
mavliter_foreach(&it) {
int exists;
struct cw_Cfg_entry * old_elem,*e, new_elem;
e = mavliter_get(&it);
new_elem.key = cw_strdup(e->key);
new_elem.val = cw_strdup(e->val);
old_elem = mavl_insert(dst,&new_elem,&exists);
if (!exists){
cw_dbg(DBG_X, "New: %s: %s",new_elem.key,new_elem.val);
continue;
}
if (strcmp(new_elem.val,old_elem->val)==0){
free((void*)new_elem.key);
free((void*)new_elem.val);
continue;
}
cw_dbg(DBG_X, "Replace: %s: %s (old: %s)",new_elem.key, new_elem.val, old_elem->val);
if(dst->del){
dst->del(old_elem);
}
memcpy(old_elem,&new_elem,dst->data_size);
}
}
void cw_cfg_destroy(cw_Cfg_t *cfg)
{
mavl_destroy(cfg);
}
void cw_cfg_clear(cw_Cfg_t *cfg)
{
mavl_del_all(cfg);
}
int cw_cfg_base_exists(cw_Cfg_t * cfg, const char *key)
{
struct cw_Cfg_entry e, *result;
e.key=key;
result = mavl_get_first(cfg,&e);
if (result == NULL)
return 0;
if (strlen(result->key)<strlen(key))
return 0;
if (result->key[strlen(key)]!='/' && result->key[strlen(key)]!='.')
return 0;
if (strncmp(result->key,key,strlen(key))==0)
return 1;
return 0;
}

View File

@ -38,6 +38,14 @@ uint8_t cw_cfg_get_byte(cw_Cfg_t * cfg, char *key, uint8_t def);
bstr16_t cw_cfg_get_bstr16(cw_Cfg_t * cfg, const char * key, const char *def);
int cw_cfg_set_bstr16(cw_Cfg_t * cfg, const char * key, bstr16_t str);
int cw_cfg_get_next_index(cw_Cfg_t * cfg, const char *key);
const char *cw_cfg_get_l(cw_Cfg_t ** cfg, const char * key, const char *def);
void cw_cfg_copy(cw_Cfg_t *src, cw_Cfg_t *dst);
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);
int cw_cfg_set_val(cw_Cfg_t * cfg, const char *key, const struct cw_Type *t, const void * valguard, const uint8_t * data, int len);

View File

@ -40,9 +40,6 @@ int cw_assemble_message(struct cw_Conn *conn, uint8_t * rawout)
struct mlistelem * elem;
int len,l;
//cw_dbg(DBG_INFO, "Number of elements in ktv: %d",conn->local_cfg->count);
/* cw_dbg_ktv_dump(conn->local_cfg,DBG_CFG_DMP,"Local CFG","LOCAL:","End Local CFG");*/
/* rawout is already initialized, so we can get
* msg type from buffer */
msgptr = rawout + cw_get_hdr_msg_offset(rawout);
@ -72,7 +69,7 @@ int cw_assemble_message(struct cw_Conn *conn, uint8_t * rawout)
data = mlistelem_dataptr(elem);
handler = cw_msgset_get_elemhandler(conn->msgset,data->proto,data->vendor,data->id);
// cw_dbg(DBG_X,"Elem: %d %d %d %s\n", data->proto, data->vendor, data->id, handler->name);
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);
@ -91,7 +88,11 @@ int cw_assemble_message(struct cw_Conn *conn, uint8_t * rawout)
params.conn=conn;
params.cfg=conn->remote_cfg;
params.default_cfg=conn->default_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;
@ -107,7 +108,13 @@ int cw_assemble_message(struct cw_Conn *conn, uint8_t * rawout)
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);
@ -138,12 +145,11 @@ int cw_assemble_message(struct cw_Conn *conn, uint8_t * 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);
mavl_t * cfg = cw_cfg_create();
cw_Cfg_t * cfg = cw_cfg_create();
struct cw_ElemHandlerParams params;
params.cfg=cfg;
params.default_cfg=NULL;
params.msgset=conn->msgset;
params.msgdata=msg;
@ -202,6 +208,7 @@ int cw_conn_set_msg_cb(struct cw_Conn *conn, int type, cw_MsgCallbackFun fun)
cb.type = type;
cb.fun = fun;
mavl_insert(conn->msg_callbacks,&cb,&exists);
return 1;
}
cw_MsgCallbackFun cw_conn_get_msg_cb(struct cw_Conn *conn, int type)
@ -288,3 +295,646 @@ struct cw_Conn * cw_conn_create(int sock, struct sockaddr * addr, int qsize)
}
/**
* Init response message header
*/
void cw_init_response(struct cw_Conn *conn, uint8_t * req)
{
uint8_t *buffer;
int shbytes, dhbytes;
uint8_t *msgptr, *dmsgptr;
buffer = conn->resp_buffer;
shbytes = cw_get_hdr_msg_offset(req);
memcpy(buffer, req, shbytes);
cw_set_hdr_rmac(buffer, conn->base_rmac);
/*
// cw_set_hdr_hlen(buffer, 2);
// cw_set_hdr_flags(buffer, CW_FLAG_HDR_M, 1);
*/
dhbytes = cw_get_hdr_msg_offset(buffer);
msgptr = req + shbytes;
dmsgptr = buffer + dhbytes;
cw_set_msg_type(dmsgptr, cw_get_msg_type(msgptr) + 1);
cw_set_msg_seqnum(dmsgptr, cw_get_msg_seqnum(msgptr));
cw_set_msg_flags(dmsgptr, 0);
}
void cw_init_request(struct cw_Conn *conn, int msg_id)
{
uint8_t *buffer = conn->req_buffer;
uint8_t *msgptr;
/* zero the first 8 bytes */
cw_set_dword(buffer + 0, 0);
cw_set_dword(buffer + 4, 0);
/* unencrypted */
cw_set_hdr_preamble(buffer, CAPWAP_VERSION << 4 | 0);
cw_set_hdr_rmac(buffer, conn->base_rmac);
/*
//cw_set_hdr_hlen(buffer, 2);
*/
cw_set_hdr_wbid(buffer, conn->wbid);
cw_set_hdr_rid(buffer, 0);
msgptr = cw_get_hdr_msg_offset(buffer) + buffer;
cw_set_msg_type(msgptr, msg_id);
cw_set_msg_flags(msgptr, 0);
cw_set_msg_elems_len(msgptr, 0);
}
void cw_init_data_msg(struct cw_Conn *conn)
{
uint8_t *buffer = conn->req_buffer;
cw_set_dword(buffer + 0, 0);
cw_set_dword(buffer + 4, 0);
/* unencrypted */
cw_set_hdr_preamble(buffer, CAPWAP_VERSION << 4 | 0);
}
/**
* send a response
*/
int cw_send_response(struct cw_Conn *conn, uint8_t * rawmsg, int len)
{
int rc;
cw_init_response(conn, rawmsg);
rc = cw_assemble_message(conn, conn->resp_buffer);
if (!cw_result_is_ok(rc))
return 0;
conn_send_msg(conn, conn->resp_buffer);
return 1;
}
/**
* Special case error message, which is sent when an unexpected messages
* was received or something else happened.
* @param conn conection
* @param rawmsg the received request message, which the response belongs to
* @param result_code result code to send
* @return 1
*/
int cw_send_error_response(struct cw_Conn *conn, uint8_t * rawmsg,
uint32_t result_code)
{
uint8_t *out, *dst;
int l;
cw_init_response(conn, rawmsg);
out = conn->resp_buffer;
dst = cw_get_hdr_msg_elems_ptr(out);
l = cw_put_elem_result_code(dst, result_code);
cw_set_msg_elems_len(out + cw_get_hdr_msg_offset(out), l);
conn_send_msg(conn, conn->resp_buffer);
return 1;
}
static struct cw_MsgSet *load_msg_set(struct cw_Conn *conn, uint8_t * rawmsg,
int len, int elems_len,
struct sockaddr *from)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
struct cw_Mod *cmod, *bmod;
cmod =
cw_mod_detect(conn, rawmsg, len, elems_len, from,
CW_MOD_MODE_CAPWAP);
if (cmod == MOD_NULL) {
cw_dbg(DBG_MSG_ERR,
"Can't find mod to handle connection from %s, discarding message",
sock_addr2str_p(from, sock_buf));
return NULL;
}
bmod =
cw_mod_detect(conn, rawmsg, len, elems_len, from,
CW_MOD_MODE_BINDINGS);
cw_dbg(DBG_INFO, "Mods deteced: %s,%s", cmod->name, bmod->name);
conn->cmod = cmod;
conn->bmod = bmod;
return cw_mod_get_msg_set(conn, cmod, bmod);
}
/*
int cw_in_check_generic(struct cw_Conn *conn, struct cw_action_in *a, uint8_t * data,
int len,struct sockaddr *from)
{
// if (cw_is_request(a->msg_id)){
// return cw_in_check_generic_req(conn,a,data,len,from);
// }
// return cw_in_check_generic_resp(conn,a,data,len,from);
}
*/
/*
void cw_read_elem(struct cw_ElemHandler * handler, struct cw_Conn * conn,
uint8_t * elem_data, int elem_len, struct sockaddr * from){
mavldata_t data, *result;
char str[30];
result = handler->type->get(&data,elem_data,elem_len);
handler->type->to_str(result,str,30);
printf("Read %d-%s: %s %s\n", handler->id, handler->name, handler->key, str);
//mavl_insert(conn->remote_cfg
}
*/
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;
cw_State_t *ui;
uint8_t *elems_ptr;
struct cw_ElemHandlerParams params;
char sock_buf[SOCK_ADDR_BUFSIZE]; /**< to hold str from sockaddr2str */
/*struct cw_action_in as, *af, *afm; */
int offset = cw_get_hdr_msg_offset(rawmsg);
uint8_t *msg_ptr = rawmsg + offset;
int elems_len = cw_get_msg_elems_len(msg_ptr);
int payloadlen = len - offset;
/* pre-check message */
if (payloadlen - 8 != elems_len) {
if (conn->strict_hdr) {
cw_dbg(DBG_MSG_ERR,
"Discarding message from %s, msgelems len=%d, payload len=%d, (Strict CAPWAP) ",
sock_addr2str(&conn->addr, sock_buf), elems_len,
payloadlen - 8);
errno = EAGAIN;
return -1;
}
if (elems_len < payloadlen - 8) {
cw_dbg(DBG_RFC,
"Packet from from %s has %d bytes of extra data, ignoring.",
sock_addr2str(&conn->addr, sock_buf),
payloadlen - 8 - elems_len);
elems_len = len - 8;
}
if (elems_len > payloadlen - 8) {
cw_dbg(DBG_RFC,
"Packet from from %s has msgelems len of %d bytes, but has only %d bytes of data, truncating.",
sock_addr2str(&conn->addr, sock_buf), elems_len,
payloadlen - 8);
elems_len = payloadlen - 8;
}
}
/* Detect the connecting WTP type */
if (!conn->detected) {
struct cw_MsgSet *set =
load_msg_set(conn, rawmsg, len, elems_len, from);
if (!set) {
/*
//cw_log(LOG_ERR, "Error");
*/
errno = EAGAIN;
return -1;
}
conn->cmod->setup_cfg(conn);
conn->msgset = set;
conn->detected = 1;
if (conn->setup_complete)
conn->setup_complete(conn);
}
/** debug the received message */
cw_dbg_msg(DBG_MSG_IN, conn, rawmsg, len, from);
/* prepare struct for search operation */
search.type = cw_get_msg_id(msg_ptr);
/* Search message */
message = mavl_get(conn->msgset->msgdata, &search);
result_code = 0;
if (!message) {
/* Message is unknown */
if (search.type & 1) {
cw_dbg(DBG_MSG_ERR,
"Message type %d [%s] unrecognized, sending response.",
search.type, cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
result_code = CAPWAP_RESULT_MSG_UNRECOGNIZED;
cw_send_error_response(conn, rawmsg, result_code);
errno = EAGAIN;
return -1;
}
cw_dbg(DBG_MSG_ERR,
"Message type %d [%s] unrecognized, discarding.",
search.type, cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
errno = EAGAIN;
return -1;
}
/* Throw away unexpected messages */
/* maybe we have to check this too: if (!(message->type & 1))
* means unexpected response message
* */
if (!(message->receiver & conn->role)) {
cw_dbg(DBG_MSG_ERR,
"Message type %d (%s) unexpected/illegal in %s State, discarding.",
search.type, cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
errno = EAGAIN;
return -1;
}
/* Check if current state is in state of message */
ui = message->states;
for (ui = message->states; ui->state; ui++) {
/* printf("Comparing %d and %d\n", conn->capwap_state, ui->state);*/
if (ui->state == conn->capwap_state) {
break;
}
}
if (!ui->state) {
/* Message found, but it was in wrong state */
cw_dbg(DBG_MSG_ERR,
"Message type %d (%s) not allowed in %s State, sending response.",
search.type, cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
result_code = CAPWAP_RESULT_MSG_INVALID_IN_CURRENT_STATE;
cw_send_error_response(conn, rawmsg, result_code);
errno = EAGAIN;
return -1;
}
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);
params.cfg = cw_cfg_create(); //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.from = from;
params.msgdata = message;
params.mand_found = mand_found;
params.msgset=conn->msgset;
params.conn = conn;
cw_decode_elements(&params,elems_ptr, elems_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);
cw_dbg(DBG_MSG_PARSING, "*** End parsing message of type %d (%s) ***",
message->type, message->name);
mavl_destroy(mand_found);
if (message->postprocess) {
message->postprocess(&params,elems_ptr, elems_len);
}
cw_MsgCallbackFun cb_fun = cw_conn_get_msg_cb(conn,message->type);
if (cb_fun != NULL){
result_code = cb_fun(&params,elems_ptr, elems_len);
}
else{
cw_cfg_clear(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) {
if (result_code > 0) {
/* the end method gave us an result code>0, so
send an error message */
cw_send_error_response(conn, rawmsg, result_code);
} else if (result_code == 0) {
cw_cfg_set_int(params.cfg, "result-code",
result_code);
if (ui->next) {
conn->capwap_prevstate = conn->capwap_state;
conn->capwap_state = ui->next;
}
/* All is ok, send regular response message */
cw_send_response(conn, rawmsg, len);
} else {
/* the request message is ignored, no response
will be sent */
errno = EAGAIN;
}
} else {
/*
* Whe have got a response message.
* Put further actions here, if needed.
*/
}
cw_cfg_destroy(params.cfg);
return result_code;
}
int process_message(struct cw_Conn *conn, uint8_t * rawmsg, int rawlen,
struct sockaddr *from)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
uint8_t seqnum;
int s1, s2, sd;
uint8_t *msgptr = rawmsg + cw_get_hdr_msg_offset(rawmsg);
uint32_t type = cw_get_msg_type(msgptr);
if (!(type & 0x1)) {
/* It's a response message, no further examination required. */
return process_elements(conn, rawmsg, rawlen, from);
}
/* It's a request message, check if seqnum is right and if
* we have already sent a response message*/
seqnum = cw_get_msg_seqnum(msgptr);
s1 = conn->last_seqnum_received;
s2 = seqnum;
sd = s2 - s1;
if ((sd > 0 && sd < 128) || (sd < 0 && sd < -128) || s1 < 0) {
/* seqnum is ok, normal message processing */
conn->last_seqnum_received = seqnum;
return process_elements(conn, rawmsg, rawlen, from);
}
if (sd != 0) {
cw_dbg(DBG_MSG_ERR,
"Discarding message from %s, old seqnum, seqnum = %d, last seqnum=%d",
sock_addr2str(&conn->addr, sock_buf), s2, s1);
errno = EAGAIN;
return -1;
}
/* the received request message was retransmittet by our peer,
* let's retransmit our response message if we have one*/
cw_dbg(DBG_MSG_ERR,
"Retransmitted request message from %s detected, seqnum=%d, type=%d",
sock_addr2str(&conn->addr, sock_buf), s2, type);
if (cw_get_hdr_msg_type(conn->resp_buffer) - 1 != type) {
/* cw_dbg(DBG_MSG_ERR,
"No cached response for retransmission, request seqnum=%d,in cache=%d",
s2, conn->resp_msg.type);*/
errno = EAGAIN;
return -1;
}
cw_dbg(DBG_MSG_ERR, "Retransmitting response message to %s, seqnum=%d",
sock_addr2str(&conn->addr, sock_buf), s2);
/*// XXX untested */
conn_send_msg(conn, conn->resp_buffer);
errno = EAGAIN;
return -1;
}
/*
* Process an incomming CAPWAP packet, assuming the packet is already decrypted
* @param conn conection object
* @param packet pointer to packet data
* @param len lenght of packet data
*/
int conn_process_packet2(struct cw_Conn *conn, uint8_t * packet, int len,
struct sockaddr *from)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
int preamble;
int offs;
int payloadlen;
if (len < 8) {
/* packet too short */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, packet too short, len=%d, at least 8 expected.",
sock_addr2str(&conn->addr, sock_buf), len);
errno = EAGAIN;
return -1;
}
preamble = cw_get_hdr_preamble(packet);
if ((preamble & 0xf0) != (CAPWAP_VERSION << 4)) {
/* wrong version */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, wrong version, version=%d, version %d expected.",
sock_addr2str(&conn->addr, sock_buf),
(preamble & 0xf0) >> 4, CAPWAP_VERSION);
errno = EAGAIN;
return -1;
}
if (preamble & 0xf) {
/* Encrypted data, this shuold never happen here */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, encrypted data after decryption ...",
sock_addr2str(&conn->addr, sock_buf));
errno = EAGAIN;
return -1;
}
offs = cw_get_hdr_msg_offset(packet);
payloadlen = len - offs;
if (payloadlen < 0) {
/* Eleminate messages with wrong header size */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, header length (%d) greater than packet len (%d).",
sock_addr2str(&conn->addr, sock_buf), offs, len);
errno = EAGAIN;
return -1;
}
/* Check if Radio MAC is present */
if (cw_get_hdr_flag_m(packet)) {
if (cw_get_hdr_rmac_len(packet) + 8 > offs) {
/* wrong rmac size */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, wrong R-MAC size, size=%d",
sock_addr2str(&conn->addr, sock_buf),
*(packet + 8));
errno = EAGAIN;
return -1;
}
}
if (cw_get_hdr_flag_f(packet)) {
/* fragmented, add the packet to fragman */
uint8_t *f;
int rc;
f = fragman_add(conn->fragman, packet, offs, payloadlen);
if (f == NULL) {
errno = EAGAIN;
return -1;
}
cw_dbg_pkt(DBG_PKT_IN, conn, f + 4, *(uint32_t *) f, from);
/*// cw_dbg_msg(DBG_MSG_IN, conn, f + 4, *(uint32_t *) f, from);*/
/* // XXX: Modify fragman to not throw away CAPWAP headers*/
rc = conn->process_message(conn, f + 4, *(uint32_t *) f, from);
free(f);
return rc;
}
/* not fragmented, we have a complete message */
/*// cw_dbg_msg(DBG_MSG_IN, conn, packet, len, from);*/
return conn->process_message(conn, packet, len, from);
}
int conn_process_packet(struct cw_Conn *conn, uint8_t * packet, int len,
struct sockaddr *from)
{
/* show this packet in debug output */
cw_dbg_pkt(DBG_PKT_IN, conn, packet, len, from);
return conn_process_packet2(conn, packet, len, from);
}
int conn_process_data_packet(struct cw_Conn *conn, uint8_t * packet, int len,
struct sockaddr *from)
{
/* show this packet in debug output */
cw_dbg_pkt(DBG_PKT_IN, conn, packet, len, from);
return conn_process_packet2(conn, packet, len, from);
}
/**
* Used as main message loop
*/
int cw_read_messages(struct cw_Conn *conn)
{
uint8_t buf[2024];
int len = 2024;
int n = conn->read(conn, buf, len);
if (n < 0)
return n;
if (n > 0) {
return conn->process_packet(conn, buf, n,
(struct sockaddr *) &conn->addr);
}
errno = EAGAIN;
return -1;
}

View File

@ -174,12 +174,12 @@ struct cw_Conn {
struct cw_Mod *cmod, *bmod;
char *dtls_cert_file;
char *dtls_key_file;
char *dtls_key_pass;
const char *dtls_cert_file;
const char *dtls_key_file;
const char *dtls_key_pass;
void *dtls_data;
char *dtls_cipher;
const char *dtls_cipher;
int dtls_error;
uint8_t dtls_cookie[8];
@ -317,5 +317,10 @@ void conn_clear_upd(struct cw_Conn*conn, int merge);
int cw_conn_set_msg_cb(struct cw_Conn *conn, int type, cw_MsgCallbackFun fun);
cw_MsgCallbackFun cw_conn_get_msg_cb(struct cw_Conn *conn, int type);
int cw_decode_element(struct cw_ElemHandlerParams *params, int proto,
int vendor, int elem_id, uint8_t * data, int len);
int cw_decode_elements(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len);
#endif /* __CONN_H */

View File

@ -38,643 +38,3 @@
/**
* Init response message header
*/
void cw_init_response(struct cw_Conn *conn, uint8_t * req)
{
uint8_t *buffer;
int shbytes, dhbytes;
uint8_t *msgptr, *dmsgptr;
buffer = conn->resp_buffer;
shbytes = cw_get_hdr_msg_offset(req);
memcpy(buffer, req, shbytes);
cw_set_hdr_rmac(buffer, conn->base_rmac);
/*
// cw_set_hdr_hlen(buffer, 2);
// cw_set_hdr_flags(buffer, CW_FLAG_HDR_M, 1);
*/
dhbytes = cw_get_hdr_msg_offset(buffer);
msgptr = req + shbytes;
dmsgptr = buffer + dhbytes;
cw_set_msg_type(dmsgptr, cw_get_msg_type(msgptr) + 1);
cw_set_msg_seqnum(dmsgptr, cw_get_msg_seqnum(msgptr));
cw_set_msg_flags(dmsgptr, 0);
}
void cw_init_request(struct cw_Conn *conn, int msg_id)
{
uint8_t *buffer = conn->req_buffer;
uint8_t *msgptr;
/* zero the first 8 bytes */
cw_set_dword(buffer + 0, 0);
cw_set_dword(buffer + 4, 0);
/* unencrypted */
cw_set_hdr_preamble(buffer, CAPWAP_VERSION << 4 | 0);
cw_set_hdr_rmac(buffer, conn->base_rmac);
/*
//cw_set_hdr_hlen(buffer, 2);
*/
cw_set_hdr_wbid(buffer, conn->wbid);
cw_set_hdr_rid(buffer, 0);
msgptr = cw_get_hdr_msg_offset(buffer) + buffer;
cw_set_msg_type(msgptr, msg_id);
cw_set_msg_flags(msgptr, 0);
cw_set_msg_elems_len(msgptr, 0);
}
void cw_init_data_msg(struct cw_Conn *conn)
{
uint8_t *buffer = conn->req_buffer;
cw_set_dword(buffer + 0, 0);
cw_set_dword(buffer + 4, 0);
/* unencrypted */
cw_set_hdr_preamble(buffer, CAPWAP_VERSION << 4 | 0);
}
/**
* send a response
*/
int cw_send_response(struct cw_Conn *conn, uint8_t * rawmsg, int len)
{
int rc;
cw_init_response(conn, rawmsg);
rc = cw_assemble_message(conn, conn->resp_buffer);
if (!cw_result_is_ok(rc))
return 0;
conn_send_msg(conn, conn->resp_buffer);
return 1;
}
/**
* Special case error message, which is sent when an unexpected messages
* was received or something else happened.
* @param conn conection
* @param rawmsg the received request message, which the response belongs to
* @param result_code result code to send
* @return 1
*/
int cw_send_error_response(struct cw_Conn *conn, uint8_t * rawmsg,
uint32_t result_code)
{
uint8_t *out, *dst;
int l;
cw_init_response(conn, rawmsg);
out = conn->resp_buffer;
dst = cw_get_hdr_msg_elems_ptr(out);
l = cw_put_elem_result_code(dst, result_code);
cw_set_msg_elems_len(out + cw_get_hdr_msg_offset(out), l);
conn_send_msg(conn, conn->resp_buffer);
return 1;
}
static struct cw_MsgSet *load_msg_set(struct cw_Conn *conn, uint8_t * rawmsg,
int len, int elems_len,
struct sockaddr *from)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
struct cw_Mod *cmod, *bmod;
cmod =
cw_mod_detect(conn, rawmsg, len, elems_len, from,
CW_MOD_MODE_CAPWAP);
if (cmod == MOD_NULL) {
cw_dbg(DBG_MSG_ERR,
"Can't find mod to handle connection from %s, discarding message",
sock_addr2str_p(from, sock_buf));
return NULL;
}
bmod =
cw_mod_detect(conn, rawmsg, len, elems_len, from,
CW_MOD_MODE_BINDINGS);
cw_dbg(DBG_INFO, "Mods deteced: %s,%s", cmod->name, bmod->name);
conn->cmod = cmod;
conn->bmod = bmod;
return cw_mod_get_msg_set(conn, cmod, bmod);
}
/*
int cw_in_check_generic(struct cw_Conn *conn, struct cw_action_in *a, uint8_t * data,
int len,struct sockaddr *from)
{
// if (cw_is_request(a->msg_id)){
// return cw_in_check_generic_req(conn,a,data,len,from);
// }
// return cw_in_check_generic_resp(conn,a,data,len,from);
}
*/
/*
void cw_read_elem(struct cw_ElemHandler * handler, struct cw_Conn * conn,
uint8_t * elem_data, int elem_len, struct sockaddr * from){
mavldata_t data, *result;
char str[30];
result = handler->type->get(&data,elem_data,elem_len);
handler->type->to_str(result,str,30);
printf("Read %d-%s: %s %s\n", handler->id, handler->name, handler->key, str);
//mavl_insert(conn->remote_cfg
}
*/
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;
cw_State_t *ui;
uint8_t *elems_ptr;
uint8_t *elem;
struct cw_ElemHandlerParams params;
char sock_buf[SOCK_ADDR_BUFSIZE]; /**< to hold str from sockaddr2str */
/*struct cw_action_in as, *af, *afm; */
int offset = cw_get_hdr_msg_offset(rawmsg);
uint8_t *msg_ptr = rawmsg + offset;
int elems_len = cw_get_msg_elems_len(msg_ptr);
int payloadlen = len - offset;
/* pre-check message */
if (payloadlen - 8 != elems_len) {
if (conn->strict_hdr) {
cw_dbg(DBG_MSG_ERR,
"Discarding message from %s, msgelems len=%d, payload len=%d, (Strict CAPWAP) ",
sock_addr2str(&conn->addr, sock_buf), elems_len,
payloadlen - 8);
errno = EAGAIN;
return -1;
}
if (elems_len < payloadlen - 8) {
cw_dbg(DBG_RFC,
"Packet from from %s has %d bytes of extra data, ignoring.",
sock_addr2str(&conn->addr, sock_buf),
payloadlen - 8 - elems_len);
elems_len = len - 8;
}
if (elems_len > payloadlen - 8) {
cw_dbg(DBG_RFC,
"Packet from from %s has msgelems len of %d bytes, but has only %d bytes of data, truncating.",
sock_addr2str(&conn->addr, sock_buf), elems_len,
payloadlen - 8);
elems_len = payloadlen - 8;
}
}
/* Detect the connecting WTP type */
if (!conn->detected) {
struct cw_MsgSet *set =
load_msg_set(conn, rawmsg, len, elems_len, from);
if (!set) {
/*
//cw_log(LOG_ERR, "Error");
*/
errno = EAGAIN;
return -1;
}
conn->cmod->setup_cfg(conn);
conn->msgset = set;
conn->detected = 1;
if (conn->setup_complete)
conn->setup_complete(conn);
}
/** debug the received message */
cw_dbg_msg(DBG_MSG_IN, conn, rawmsg, len, from);
/* prepare struct for search operation */
search.type = cw_get_msg_id(msg_ptr);
/* Search message */
message = mavl_get(conn->msgset->msgdata, &search);
result_code = 0;
if (!message) {
/* Message is unknown */
if (search.type & 1) {
cw_dbg(DBG_MSG_ERR,
"Message type %d [%s] unrecognized, sending response.",
search.type, cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
result_code = CAPWAP_RESULT_MSG_UNRECOGNIZED;
cw_send_error_response(conn, rawmsg, result_code);
errno = EAGAIN;
return -1;
}
cw_dbg(DBG_MSG_ERR,
"Message type %d [%s] unrecognized, discarding.",
search.type, cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
errno = EAGAIN;
return -1;
}
/* Throw away unexpected messages */
/* maybe we have to check this too: if (!(message->type & 1))
* means unexpected response message
* */
if (!(message->receiver & conn->role)) {
cw_dbg(DBG_MSG_ERR,
"Message type %d (%s) unexpected/illegal in %s State, discarding.",
search.type, cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
errno = EAGAIN;
return -1;
}
/* Check if current state is in state of message */
ui = message->states;
for (ui = message->states; ui->state; ui++) {
/* printf("Comparing %d and %d\n", conn->capwap_state, ui->state);*/
if (ui->state == conn->capwap_state) {
break;
}
}
if (!ui->state) {
/* Message found, but it was in wrong state */
cw_dbg(DBG_MSG_ERR,
"Message type %d (%s) not allowed in %s State, sending response.",
search.type, cw_strmsg(search.type),
cw_strstate(conn->capwap_state));
result_code = CAPWAP_RESULT_MSG_INVALID_IN_CURRENT_STATE;
cw_send_error_response(conn, rawmsg, result_code);
errno = EAGAIN;
return -1;
}
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);
params.cfg = cw_cfg_create(); //conn->remote_cfg;
params.default_cfg = NULL;
params.from = from;
params.msgdata = message;
params.mand_found = mand_found;
params.msgset=conn->msgset;
params.conn = conn;
cw_decode_elements(&params,elems_ptr, elems_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);
cw_dbg(DBG_MSG_PARSING, " *** End parsing message of type %d (%s) ***",
message->type, message->name);
mavl_destroy(mand_found);
/* cw_dbg_ktv_dump(conn->remote_cfg,DBG_CFG_DMP,
" *** Remote CFG dump ***", "CFG:", " *** End of remote CFG dump");
*/
cw_MsgCallbackFun cb_fun = cw_conn_get_msg_cb(conn,message->type);
if (cb_fun != NULL){
cb_fun(&params,elems_ptr, elems_len);
}
if (message->postprocess) {
// message->postprocess(conn);
message->postprocess(&params,elems_ptr, elems_len);
}
/* if we've got a request message, we always have to send a response message */
if (message->type & 1) {
if (result_code > 0) {
/* the end method gave us an result code>0, so
send an error message */
cw_send_error_response(conn, rawmsg, result_code);
} else if (result_code == 0) {
cw_ktv_set_dword(conn->local_cfg, "result-code",
result_code);
if (ui->next) {
conn->capwap_prevstate = conn->capwap_state;
conn->capwap_state = ui->next;
}
/* All is ok, send regular response message */
cw_send_response(conn, rawmsg, len);
} else {
/* the request message is ignored, no response
will be sent */
errno = EAGAIN;
}
} else {
/*
* Whe have got a response message.
* Put further actions here, if needed.
*/
}
return result_code;
}
int process_message(struct cw_Conn *conn, uint8_t * rawmsg, int rawlen,
struct sockaddr *from)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
uint8_t seqnum;
int s1, s2, sd;
uint8_t *msgptr = rawmsg + cw_get_hdr_msg_offset(rawmsg);
uint32_t type = cw_get_msg_type(msgptr);
if (!(type & 0x1)) {
/* It's a response message, no further examination required. */
return process_elements(conn, rawmsg, rawlen, from);
}
/* It's a request message, check if seqnum is right and if
* we have already sent a response message*/
seqnum = cw_get_msg_seqnum(msgptr);
s1 = conn->last_seqnum_received;
s2 = seqnum;
sd = s2 - s1;
if ((sd > 0 && sd < 128) || (sd < 0 && sd < -128) || s1 < 0) {
/* seqnum is ok, normal message processing */
conn->last_seqnum_received = seqnum;
return process_elements(conn, rawmsg, rawlen, from);
}
if (sd != 0) {
cw_dbg(DBG_MSG_ERR,
"Discarding message from %s, old seqnum, seqnum = %d, last seqnum=%d",
sock_addr2str(&conn->addr, sock_buf), s2, s1);
errno = EAGAIN;
return -1;
}
/* the received request message was retransmittet by our peer,
* let's retransmit our response message if we have one*/
cw_dbg(DBG_MSG_ERR,
"Retransmitted request message from %s detected, seqnum=%d, type=%d",
sock_addr2str(&conn->addr, sock_buf), s2, type);
if (cw_get_hdr_msg_type(conn->resp_buffer) - 1 != type) {
/* cw_dbg(DBG_MSG_ERR,
"No cached response for retransmission, request seqnum=%d,in cache=%d",
s2, conn->resp_msg.type);*/
errno = EAGAIN;
return -1;
}
cw_dbg(DBG_MSG_ERR, "Retransmitting response message to %s, seqnum=%d",
sock_addr2str(&conn->addr, sock_buf), s2);
/*// XXX untested */
conn_send_msg(conn, conn->resp_buffer);
errno = EAGAIN;
return -1;
}
/*
* Process an incomming CAPWAP packet, assuming the packet is already decrypted
* @param conn conection object
* @param packet pointer to packet data
* @param len lenght of packet data
*/
int conn_process_packet2(struct cw_Conn *conn, uint8_t * packet, int len,
struct sockaddr *from)
{
char sock_buf[SOCK_ADDR_BUFSIZE];
int preamble;
int offs;
int payloadlen;
if (len < 8) {
/* packet too short */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, packet too short, len=%d, at least 8 expected.",
sock_addr2str(&conn->addr, sock_buf), len);
errno = EAGAIN;
return -1;
}
preamble = cw_get_hdr_preamble(packet);
if ((preamble & 0xf0) != (CAPWAP_VERSION << 4)) {
/* wrong version */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, wrong version, version=%d, version %d expected.",
sock_addr2str(&conn->addr, sock_buf),
(preamble & 0xf0) >> 4, CAPWAP_VERSION);
errno = EAGAIN;
return -1;
}
if (preamble & 0xf) {
/* Encrypted data, this shuold never happen here */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, encrypted data after decryption ...",
sock_addr2str(&conn->addr, sock_buf));
errno = EAGAIN;
return -1;
}
offs = cw_get_hdr_msg_offset(packet);
payloadlen = len - offs;
if (payloadlen < 0) {
/* Eleminate messages with wrong header size */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, header length (%d) greater than packet len (%d).",
sock_addr2str(&conn->addr, sock_buf), offs, len);
errno = EAGAIN;
return -1;
}
/* Check if Radio MAC is present */
if (cw_get_hdr_flag_m(packet)) {
if (cw_get_hdr_rmac_len(packet) + 8 > offs) {
/* wrong rmac size */
cw_dbg(DBG_PKT_ERR,
"Discarding packet from %s, wrong R-MAC size, size=%d",
sock_addr2str(&conn->addr, sock_buf),
*(packet + 8));
errno = EAGAIN;
return -1;
}
}
if (cw_get_hdr_flag_f(packet)) {
/* fragmented, add the packet to fragman */
uint8_t *f;
int rc;
f = fragman_add(conn->fragman, packet, offs, payloadlen);
if (f == NULL) {
errno = EAGAIN;
return -1;
}
cw_dbg_pkt(DBG_PKT_IN, conn, f + 4, *(uint32_t *) f, from);
/*// cw_dbg_msg(DBG_MSG_IN, conn, f + 4, *(uint32_t *) f, from);*/
/* // XXX: Modify fragman to not throw away CAPWAP headers*/
rc = conn->process_message(conn, f + 4, *(uint32_t *) f, from);
free(f);
return rc;
}
/* not fragmented, we have a complete message */
/*// cw_dbg_msg(DBG_MSG_IN, conn, packet, len, from);*/
return conn->process_message(conn, packet, len, from);
}
int conn_process_packet(struct cw_Conn *conn, uint8_t * packet, int len,
struct sockaddr *from)
{
/* show this packet in debug output */
cw_dbg_pkt(DBG_PKT_IN, conn, packet, len, from);
return conn_process_packet2(conn, packet, len, from);
}
int conn_process_data_packet(struct cw_Conn *conn, uint8_t * packet, int len,
struct sockaddr *from)
{
/* show this packet in debug output */
cw_dbg_pkt(DBG_PKT_IN, conn, packet, len, from);
return conn_process_packet2(conn, packet, len, from);
}
/**
* Used as main message loop
*/
int cw_read_messages(struct cw_Conn *conn)
{
uint8_t buf[2024];
int len = 2024;
int n = conn->read(conn, buf, len);
if (n < 0)
return n;
if (n > 0) {
return conn->process_packet(conn, buf, n,
(struct sockaddr *) &conn->addr);
}
errno = EAGAIN;
return -1;
}

View File

@ -3,7 +3,7 @@
#include "dbg.h"
#define CW_MODE_ZYXEL 7
extern cw_send_msg(struct cw_Conn * conn,uint8_t * msg);
extern int cw_send_msg(struct cw_Conn * conn,uint8_t * msg);
int conn_send_msg(struct cw_Conn * conn, uint8_t *rawmsg)
{
@ -34,7 +34,7 @@ mtu = 9440;
mtu = mtu >> 3;
mtu = mtu << 3;
printf("packetlenX = %d (%d)\n",packetlen,hlen);
// printf("packetlenX = %d (%d)\n",packetlen,hlen);
int offset = cw_get_hdr_msg_offset(rawmsg);
return cw_send_msg(conn,rawmsg+offset);

View File

@ -17,7 +17,7 @@ int cw_in_generic_enum(struct cw_ElemHandler * handler, struct cw_ElemHandlerPar
{
int val;
const cw_ValEnum_t * e;
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
struct cw_ElemHandler thandler;
val = cw_get_byte(elem_data+1);

View File

@ -11,7 +11,7 @@ int cw_in_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerP
cw_dbg(DBG_X,"STRUCT KEY: %s",handler->key);
stop();
const char * key;
char tmpkey[CW_KTV_MAX_KEY_LEN];
char tmpkey[CW_CFG_MAX_KEY_LEN];
if (handler->mkkey != NULL){

View File

@ -5,7 +5,7 @@ int cw_in_generic_with_index(struct cw_ElemHandler *eh,
struct cw_ElemHandlerParams *params,
uint8_t * data, int len)
{
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
int idx;
cw_dbg(DBG_X,"Fix cw_in_generic_with_index");

View File

@ -10,12 +10,12 @@
int cw_in_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params,
uint8_t * elem_data, int elem_len)
{
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
int idx;
cw_dbg(DBG_X,"Fix cw_in_idx_generic_struct");
exit(1);
stop();
if (!handler->type){
cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name);

View File

@ -13,7 +13,7 @@ int cw_in_radio_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHa
stop();
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
int radio;
if (!handler->type){

View File

@ -1,4 +1,5 @@
#include "val.h"
#include "cfg.h"
void * ktvn(struct mavl *t ,const void *search)
{
@ -45,7 +46,7 @@ void * ktvn(struct mavl *t ,const void *search)
int cw_ktv_idx_get(mavl_t ktv, const char *key)
{
char ikey[CW_KTV_MAX_KEY_LEN];
char ikey[CW_CFG_MAX_KEY_LEN];
cw_Val_t search, * result;
char *d;
@ -75,7 +76,7 @@ int cw_ktv_idx_get(mavl_t ktv, const char *key)
int cw_ktv_idx_get_next(mavl_t ktv, const char *key, int n)
{
char ikey[CW_KTV_MAX_KEY_LEN];
char ikey[CW_CFG_MAX_KEY_LEN];
cw_Val_t search, * result;
char *d;
int i;

View File

@ -1,10 +1,10 @@
#include "val.h"
#include "cfg.h"
int cw_ktv_read_file(FILE * file, mavl_t ktv, mavl_t types)
{
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
char type[256];
char val[2048];

View File

@ -1,10 +1,11 @@
#include "val.h"
#include "dbg.h"
#include "cfg.h"
int cw_ktv_read_struct(mavl_t ktv,const cw_ValStruct_t * stru, const char *pkey,
uint8_t * data, int len)
{
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
int pos, i,l;
cw_Val_t * result;

View File

@ -1,6 +1,7 @@
#include <ctype.h>
#include "val.h"
#include "cfg.h"
struct parser {
int line;
@ -10,13 +11,14 @@ struct parser {
int quote;
FILE *f;
int (*getc)(struct parser *);
void (*ungetc)(struct parser *)
void (*ungetc)(struct parser *);
};
/*
static int pgetc(struct parser *parser)
{
return fgetc(parser->f);
}
}*/
static int get_char(struct parser *p)
{
@ -290,13 +292,13 @@ int cw_ktv_read_line (FILE *f, char * key, char * type, char *val)
p.quote=0;
p.f=f;
n = read_key (&p,key,CW_KTV_MAX_KEY_LEN);
n = read_type (&p,type,CW_KTV_MAX_KEY_LEN);
n = read_key (&p,key,CW_CFG_MAX_KEY_LEN);
n = read_type (&p,type,CW_CFG_MAX_KEY_LEN);
if (n==-1){
return -1;
}
n = read_val (&p,val,CW_KTV_MAX_KEY_LEN);
n = read_val (&p,val,CW_CFG_MAX_KEY_LEN);
if (n==-1){
return -1;
}

View File

@ -1,11 +1,12 @@
#include "val.h"
#include "dbg.h"
#include "log.h"
#include "cfg.h"
int cw_ktv_write_struct(mavl_t ktv, mavl_t def, const cw_ValStruct_t * stru, const char *pkey,
uint8_t * dst)
{
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
int pos, i;
cw_Val_t * result;

View File

@ -1,55 +0,0 @@
#include "cw.h"
#include "dbg.h"
#include "log.h"
#include "msgset.h"
#include "val.h"
int cw_out_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst)
{
int start, len, l;
// cw_dbg(DBG_X,"Generic out!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
// cw_cfg_dump(params->cfg);
// cw_dbg(DBG_X,"Generic out!!!!!!!!!!!!!!!!!!!!!!!!!!!! ENDDUMP");
start = params->msgset->header_len(handler);
len = ((const cw_Type_t*)(handler->type))->
write(params->cfg_list,handler->key,dst+start,handler->param);
if (len == -1) {
const char *vendor="";
if ( handler->vendor ) {
vendor=cw_strvendor(handler->vendor);
}
if ( params->elemdata->mand) {
cw_log(LOG_ERR,
"Can't put mandatory element %s %d-(%s) into %s. No value for '%s' found.",
vendor, handler->id, handler->name, params->msgdata->name
, handler->key
);
}
else{
/* cw_dbg(DBG_WARN,"No output for element %s%d -(%s) in %s. Item %s not found.",
vendor,
a->elem_id, cw_strelemp(conn->actions, a->elem_id)
, cw_strmsg(a->msg_id),a->item_id);
*/
}
return 0;
}
l = params->msgset->write_header(handler,dst,len);
return l;
}

View File

@ -6,10 +6,10 @@ int cw_out_generic_indexed_enum(struct cw_ElemHandler * handler, struct cw_ElemH
, uint8_t * dst)
{
cw_dbg(DBG_X,"Fix: cw_out_generic_indexed_enum");
exit(1);
stop();
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
int i;
cw_Val_t * result;
int len,start;

View File

@ -10,6 +10,7 @@
int cw_out_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst)
{
cw_dbg(DBG_X,"Key: %s",handler->key);
stop();
@ -39,7 +40,7 @@ int cw_out_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandler
start = params->msgset->header_len(handler);
len = cw_ktv_write_struct(params->cfg,
params->default_cfg,
params->cfg,
handler->type,handler->key,dst+start);
return params->msgset->write_header(handler,dst,len);

View File

@ -7,7 +7,7 @@ int cw_out_generic_with_index(struct cw_ElemHandler * eh,
{
stop();
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
int idx;
cw_Val_t * result, search;
int len,start;

View File

@ -8,7 +8,7 @@ int cw_out_idx_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHan
stop();
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
struct cw_Val * elem, search;
int i;
int idx, sr;

View File

@ -1,33 +1,36 @@
#include "cw.h"
#include "dbg.h"
#include "cfg.h"
int cw_ktv_idx_get_next(mavl_t ktv, const char *key, int n);
int cw_out_radio_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst)
{
stop();
char key[CW_CFG_MAX_KEY_LEN];
struct cw_Type * type;
int len,i,l;
int len,i,l,start;
int radios;
len =0;
/* int idx=0;*/
/* while(1){
char key[CW_KTV_MAX_KEY_LEN];
sprintf(key,"radio.%d",idx);
idx = cw_ktv_idx_get_next(params->conn->local_cfg,key,idx);
idx++;
}
*/
radios = cw_ktv_get_byte(params->cfg,"wtp-descriptor/max-radios",0);
radios = cw_cfg_get_byte(params->cfg,"wtp-descriptor/max-radios",0);
for(i=0;i<radios;i++){
l = cw_write_radio_element(handler,params,i,dst+len);
cw_dbg_elem(DBG_ELEM_OUT,NULL,params->msgdata->type,handler,dst,l);
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);
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;
}
return len;
}

View File

@ -7,6 +7,7 @@ int cw_ktv_idx_get_next(mavl_t ktv, const char *key, int n);
int cw_out_radio_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params
, uint8_t * dst)
{
cw_dbg(DBG_X,"KEY: %s",handler->key);
stop();
int i,l, offset;
@ -20,7 +21,7 @@ int cw_out_radio_generic_struct(struct cw_ElemHandler * handler, struct cw_ElemH
i=-1;
while(1){
char basekey[CW_KTV_MAX_KEY_LEN];
char basekey[CW_CFG_MAX_KEY_LEN];
cw_Val_t * result;
i = cw_ktv_idx_get_next(params->cfg,"radio",i+1);
@ -51,7 +52,7 @@ int cw_out_traverse0(struct cw_ElemHandler * handler, struct cw_ElemHandlerParam
{
char *sl;
int l;
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
int len;
len = 0;
@ -70,7 +71,7 @@ printf("Next: %s\n", next);
for (i=0;i<stack[0];i++){
printf("I=%i\n",stack[i+1]);
}
l= cw_ktv_write_struct(params->cfg,params->default_cfg,
l= cw_ktv_write_struct(params->cfg,params->cfg,
handler->type,key,dst+offset);
printf("Write struct len %i\n",l);
@ -101,7 +102,7 @@ printf("current is %s\n", current);
cw_dbg_ktv_dump(params->cfg,DBG_INFO,"start"," ", "end" );
i=-1;
while(1){
char basekey[CW_KTV_MAX_KEY_LEN];
char basekey[CW_CFG_MAX_KEY_LEN];
cw_Val_t * result;
i = cw_ktv_idx_get_next(params->cfg,key,i+1);
@ -130,7 +131,7 @@ int cw_out_traverse(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams
{
char current[CW_KTV_MAX_KEY_LEN];
char current[CW_CFG_MAX_KEY_LEN];
int stack[10];
stack[0]=0;

View File

@ -7,7 +7,7 @@
static int get_psk(struct cw_Conn *conn, const char *username, uint8_t ** psk,
unsigned int *len)
{
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
cw_Val_t *result;
sprintf(key, "%s/%s", "psk", username);
result = cw_ktv_get(conn->local_cfg, key, CW_TYPE_BSTR16);
@ -39,8 +39,8 @@ static int get_psk(struct cw_Conn *conn, const char *username, uint8_t ** psk,
int cw_setup_dtls(struct cw_Conn *conn, mavl_t cfg, const char *prefix,
char *default_cipher)
{
char key[CW_KTV_MAX_KEY_LEN];
char *ssl_cert, *ssl_key;
char key[CW_CFG_MAX_KEY_LEN];
const char *ssl_cert, *ssl_key;
uint8_t security;
security = 0;

View File

@ -101,6 +101,11 @@ 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_BOOL,key,dst,param);
}
const struct cw_Type cw_type_bool = {
@ -114,5 +119,6 @@ const struct cw_Type cw_type_bool = {
data, /* data */
get_type_name, /* get_type_name */
NULL,
bread
bread,
bwrite
};

View File

@ -163,11 +163,11 @@ static int xput(uint8_t * dst,const char *s)
static int bwrite(cw_Cfg_t *cfg, const char *key, uint8_t *dst, const void * param)
static int bwrite(cw_Cfg_t **cfg, const char *key, uint8_t *dst, const void * param)
{
const char *s;
s = cw_cfg_get(cfg,key,NULL);
s = cw_cfg_get_l(cfg,key,NULL);
if (s==NULL)
return -1;
return xput(dst,s);

View File

@ -140,22 +140,9 @@ static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, c
return 1;
}
static int bwrite(cw_Cfg_t *cfg, const char *key, uint8_t *dst, const void * param)
static int bwrite(cw_Cfg_t ** cfgs, const char *key, uint8_t *dst, const void * param)
{
cw_Val_t val;
int l;
const char *s;
memset(&val,0,sizeof(cw_Val_t));
val.valguard=param;
s = cw_cfg_get(cfg,key,NULL);
if (s==NULL)
return -1;
from_str(&val,s);
l = put(&val,dst);
if(val.type->del)
val.type->del(&val);
return l;
return cw_generic_write_l(cfgs,CW_TYPE_BYTE,key,dst,param);
}
const struct cw_Type cw_type_byte = {

View File

@ -68,6 +68,8 @@ static int cast(cw_Val_t * data)
static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, const void *param)
{
uint32_t val;
//cw_ValValRange_t * valrange = (cw_ValValRange_t *) param;
//const char *str;
@ -83,10 +85,11 @@ static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, c
}
static int bwrite(cw_Cfg_t *cfg, const char *key, uint8_t *dst, const void * param)
static int bwrite(cw_Cfg_t **cfgs, const char *key, uint8_t *dst, const void * param)
{
return cw_generic_write_l(cfgs,CW_TYPE_DWORD,key,dst,param);
cw_Val_t val;
/* cw_Val_t val;
int l;
const char *s;
memset(&val,0,sizeof(cw_Val_t));
@ -98,7 +101,7 @@ static int bwrite(cw_Cfg_t *cfg, const char *key, uint8_t *dst, const void * pa
l = put(&val,dst);
if(val.type->del)
val.type->del(&val);
return l;
return l;*/
}

View File

@ -1,11 +1,13 @@
#include "cw.h"
#include "val.h"
#include "dbg.h"
#include "log.h"
static int read_struct(cw_Cfg_t * cfg,const cw_ValStruct_t * stru, const char *pkey,
const uint8_t * data, int len)
{
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
int pos, i,l;
@ -43,10 +45,7 @@ static int read_struct(cw_Cfg_t * cfg,const cw_ValStruct_t * stru, const char *p
l=stru[i].type->read(cfg,key,data+pos,l,stru[i].valguard);
// result = cw_ktv_add(ktv,key,stru[i].type,stru[i].valguard,data+pos,l);
// stru[i].type->to_str(result,dbstr,100);
// cw_dbg(DBG_ELEM_DETAIL, "Read (%d): %s: %s",pos,key,dbstr);
// printf("READ STRUCT (%d): %s: %s\n",pos,key,dbstr);
if (stru[i].len==-1){
@ -75,6 +74,113 @@ static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, c
}
static int write_struct(cw_Cfg_t ** cfgs, const cw_ValStruct_t * stru, const char *pkey,
uint8_t * dst)
{
char key[CW_CFG_MAX_KEY_LEN];
int pos, i;
const char * result;
int wrlen;
cw_Val_t val;
memset(&val,0,sizeof(cw_Val_t));
pos=0; i=0;
for(i=0; stru[i].type != NULL;i++){
if (stru[i].position!=-1){
pos=stru[i].position;
}
if (stru[i].len!=-1)
memset(dst+pos,0,stru[i].len);
if (stru[i].key!=NULL)
sprintf(key,"%s/%s",pkey,stru[i].key);
else
sprintf(key,"%s",pkey);
result = cw_cfg_get_l(cfgs,key,NULL);
if(result) {
// char s[2048];
// result->type->to_str(result,s,2048);
// printf("Content: '%s'\n",s);
}
if (result == NULL){
cw_log(LOG_ERR,"Can't put %s, no value found, filling wth zeros.",key);
memset(dst+pos,0,stru[i].len);
}
else{
struct cw_Type * type;
type = (struct cw_Type *)stru[i].type;
wrlen = type->write(cfgs,stru[i].key,dst+pos,stru[i].valguard);
/* result->valguard=stru[i].valguard;
if (cw_ktv_cast(result,stru[i].type)==NULL){
cw_log(LOG_ERR,"Can't cast key '%s' from %s to %s",key,result->type->name,stru[i].type->name);
}
result->type->put(result,dst+pos);*/
}
if (stru[i].len!=-1)
pos+=stru[i].len;
else
pos+=wrlen; //result->type->len(result);
}
return pos;
}
static int bwrite(cw_Cfg_t **cfgs, const char *key, uint8_t *dst, const void * param)
{
return write_struct(cfgs,param,key,dst);
cw_dbg(DBG_X,"Key: %s",key);
stop();
/*
int start;
int len;
cw_Val_t search;
const char *result;
if (!handler->type){
cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name);
return 0;
}
search.key = (char*)handler->key;
result = mavl_get_first(params->cfg,&search);
if (result == NULL ){
if (params->elemdata->mand)
cw_log(LOG_ERR,"Can't put mandatory message element %s, no data available",handler->name);
return 0;
}
if (strncmp(result->key,handler->key, strlen(handler->key))!=0){
if (params->elemdata->mand)
cw_log(LOG_ERR,"Can't put mandatory message element %s, no data available",handler->name);
return 0;
}
start = params->msgset->header_len(handler);
len = cw_ktv_write_struct(params->cfg,
params->cfg,
handler->type,handler->key,dst+start);
return params->msgset->write_header(handler,dst,len);
*/
}
@ -90,6 +196,6 @@ const struct cw_Type cw_type_struct = {
NULL, /* get_type_name */
NULL,
bread,
NULL
bwrite
};

View File

@ -79,22 +79,23 @@ static int bread(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, c
return 2;
}
static int bwrite(cw_Cfg_t *cfg, const char *key, uint8_t *dst, const void * param)
static int bwrite(cw_Cfg_t **cfgs, const char *key, uint8_t *dst, const void * param)
{
return cw_generic_write_l(cfgs,CW_TYPE_WORD,key,dst,param);
cw_Val_t val;
/* cw_Val_t val;
int l;
const char *s;
memset(&val,0,sizeof(cw_Val_t));
val.valguard=param;
s = cw_cfg_get(cfg,key,NULL);
s = cw_cfg_get_l(cfg,key,NULL);
if (s==NULL)
return -1;
from_str(&val,s);
l = put(&val,dst);
if(val.type->del)
val.type->del(&val);
return l;
return l;*/
}

View File

@ -1,13 +1,14 @@
#include "cw.h"
#include "dbg.h"
int cw_write_radio_element(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params, int idx
, uint8_t * dst)
{
return 0;
stop();
return 0;
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
cw_Val_t *elem, search;
int len;
uint8_t * d;

View File

@ -1,6 +1,8 @@
#include "mavl.h"
#include "mavltypes.h"
#include <string.h>
int mavl_cmpstr (const void *s1, const void *s2)
{
return strcmp( *((const char**)s1), *((const char**)s2));

View File

@ -15,6 +15,7 @@
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include "mavl.h"
#include "mavltypes.h"

View File

@ -1,3 +1,5 @@
#include <string.h>
#include "mavl.h"
void *mavl_replace(struct mavl *t,const void *data, int * replaced){

View File

@ -33,7 +33,7 @@ struct cw_ElemHandlerParams {
// cw_Val_t * elem;
char * debug_details;
cw_Cfg_t * cfg;
cw_Cfg_t * default_cfg;
cw_Cfg_t * cfg_list[10];
};
@ -87,7 +87,6 @@ struct cw_MsgDef{
struct cw_ElemDef * elements;
int (*preprocess)(struct cw_Conn * conn);
// int (*postprocess)(struct conn * conn);
int (*postprocess)(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len);
/* uint8_t next_state;*/
@ -106,7 +105,6 @@ struct cw_MsgData{
mlist_t mand_keys; /**< Keys of mandatory elements */
int (*preprocess)(struct cw_Conn * conn);
//int (*postprocess)(struct conn * conn);
int (*postprocess)(struct cw_ElemHandlerParams * params, uint8_t * elems_ptr, int elems_len);
/* uint8_t next_state;*/
};

View File

@ -97,7 +97,7 @@ cw_send_msg( struct cw_Conn * conn, uint8_t *msg)
{
uint8_t buf[MAX_MTU];
int fragoffset,hlen,mtu;
int packetlen, msglen;
int msglen;
mtu = conn->mtu;
@ -121,7 +121,7 @@ cw_send_msg( struct cw_Conn * conn, uint8_t *msg)
hlen = cw_get_hdr_hlen(buf)*4;
packetlen = hlen + cw_get_msg_elems_len(msg) + 8;
//packetlen = hlen + cw_get_msg_elems_len(msg) + 8;
msglen = cw_get_msg_elems_len(msg) + 8;

View File

@ -21,7 +21,7 @@
* @{
*/
#define CW_KTV_MAX_KEY_LEN 1024
//#define CW_KTV_MAX_KEY_LEN 1024
typedef struct mavl cw_Cfg_t;
@ -94,7 +94,7 @@ struct cw_Type {
int (*cast)(cw_Val_t *);
int (*read)(cw_Cfg_t *cfg, const char * key, const uint8_t *src, int len, const void * param);
int (*write)(cw_Cfg_t *cfg, const char *key, uint8_t *dst, const void * param);
int (*write)(cw_Cfg_t ** cfg, const char *key, uint8_t *dst, const void * param);
};
typedef struct cw_Type cw_Type_t;
@ -248,6 +248,7 @@ struct cw_Val_Reader {
void cw_ktv_init_str_reader(struct cw_Val_Reader *r, const char * str, int len);
int cw_ktv_parse_string(struct cw_Val_Reader *r, char *key, char *type, char *val);
int cw_generic_write_l(cw_Cfg_t **cfg, const struct cw_Type*type, const char *key, uint8_t *dst, const void * param);
/**
* @} KTV

View File

@ -354,7 +354,7 @@ static struct cw_ElemHandler handlers[] = {
CW_TYPE_STRUCT, /* type */
"admin-state", /* Key */
cw_in_radio_generic, /* get */
cw_out_radio_generic_struct, /* put */
cw_out_radio_generic, /* put */
NULL,
NULL,
radio_admin_state, /* type */
@ -365,12 +365,16 @@ static struct cw_ElemHandler handlers[] = {
{
"CAPWAP Timers", /* name */
CAPWAP_ELEM_CAPWAP_TIMERS, /* Element ID */
0, 0, /* Vendor / Proto */
2, 2, /* min/max length */
capwap_timers, /* type */
"capwap-timers", /* Key */
cw_in_generic_struct, /* get */
cw_out_generic_struct /* put */
0, 0, /* Vendor / Proto */
2, 2, /* min/max length */
CW_TYPE_STRUCT, /* type */
"capwap-timers", /* Key */
cw_in_generic, /* get */
cw_out_generic, /* put */
NULL,
NULL,
capwap_timers,
}
,
{

View File

@ -18,7 +18,7 @@ static int put_ac_status(mavl_t global, mavl_t local, uint8_t *dst, const char *
uint8_t *d = dst;
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
d += cw_put_word(d,cw_ktv_get_word(global,"ac-descriptor/stations",0));
@ -56,12 +56,13 @@ static int put_ac_status(mavl_t global, mavl_t local, uint8_t *dst, const char *
int capwap_out_ac_descriptor(struct cw_ElemHandler * eh,
struct cw_ElemHandlerParams * params, uint8_t * dst)
{
int len,l;
stop();
/* int len,l;
uint8_t *d = dst+4;
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
d+=put_ac_status(params->cfg,
params->default_cfg,
params->global_cfg,
d, eh->key);
sprintf(key,"%s/%s",eh->key,CW_SKEY_HARDWARE);
@ -76,7 +77,7 @@ int capwap_out_ac_descriptor(struct cw_ElemHandler * eh,
l = len + cw_put_elem_hdr(dst,eh->id,len);
cw_dbg_elem(DBG_ELEM_OUT,NULL,params->msgdata->type,eh,dst,l);
return l;
*/
return 0;
}

View File

@ -29,7 +29,7 @@ static int cw_put_encryption_subelems(uint8_t *dst,int capwap_mode)
int capwap_out_wtp_descriptor(struct cw_ElemHandler * eh,
struct cw_ElemHandlerParams * params, uint8_t * dst)
{
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
int len,l;
/* // XXX Dummy WTP Descriptor Header */
uint8_t *d;

View File

@ -218,7 +218,7 @@ static cw_ValStruct_t cisco_mac_operation75[]={
static cw_ValStruct_t cisco_ap_power_injector_config[]={
{CW_TYPE_BYTE,"state",1,-1},
{CW_TYPE_BYTE,"selection",1,-1},
{CW_TYPE_BSTR16,"sitch-mac-address",6,-1},
{CW_TYPE_BSTR16,"switch-mac-address",6,-1},
{NULL,NULL,0,0}
};
@ -250,8 +250,8 @@ int cisco_out_ap_regulatory_domain(struct cw_ElemHandler * eh,
struct cw_ElemHandlerParams * params, uint8_t * dst)
{
char key[CW_KTV_MAX_KEY_LEN];
char testkey[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
char testkey[CW_CFG_MAX_KEY_LEN];
int idx;
void * type;
cw_Val_t * result, search;
@ -336,7 +336,6 @@ static cw_ValStruct_t cisco_direct_sequence_control70[]={
};
static cw_ValStruct_t cisco_antenna_payload70[]={
{CW_TYPE_BYTE,"radio-id",1,-1},
{CW_TYPE_BYTE,"diversity-selection",1,-1},
{CW_TYPE_BYTE,"antenna-mode",1,-1},
{CW_TYPE_BYTE,"number-of-antennas",1,-1},
@ -402,6 +401,7 @@ static cw_ValStruct_t cisco_wtp_radio_config75[]={
static cw_ValStruct_t cisco_tx_power[]={
{CW_TYPE_BYTE,"radio-id",1,-1},
{CW_TYPE_BYTE,"reserved",1,-1},
{CW_TYPE_WORD,"current-tx-power",2,-1},
{NULL,NULL,0,0}
@ -558,7 +558,7 @@ static int cisco_in_lw_del_wlan(struct cw_ElemHandler *eh,
stop();
int wlan_id, radio_id;
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
radio_id=cw_get_byte(data);
wlan_id=cw_get_word(data+1);
@ -633,7 +633,7 @@ static cw_ValValRange_t oper_val_cause[]={
static cw_ValStruct_t cisco_radio_oper_state[]={
{CW_TYPE_BYTE, "state", 1, -1, oper_val_state},
{CW_TYPE_BYTE, "cause", 1, -1,oper_val_cause},
{CW_TYPE_BYTE, "cause", 1, -1, oper_val_cause},
{NULL,NULL,0,0}
};
@ -720,7 +720,7 @@ static int cisco_data(struct cw_ElemHandler *eh,
uint8_t * data, int len)
{
int wlan_id, radio_id;
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
radio_id=cw_get_byte(data);
wlan_id=cw_get_word(data+1);
@ -1206,10 +1206,14 @@ static struct cw_ElemHandler handlers70[] = {
CW_CISCO_DIRECT_SEQUENCE_CONTROL, /* Element ID */
CW_VENDOR_ID_CISCO,0, /* Vendor / Proto */
9,9, /* min/max length */
cisco_direct_sequence_control70, /* type */
CW_TYPE_STRUCT, /* type */
"cisco/direct-sequence-control", /* Key */
cw_in_radio_generic_struct, /* get */
cw_out_radio_generic_struct /* put */
cw_in_radio_generic, /* get */
cw_out_radio_generic, /* put */
NULL, /* mkkey */
NULL,
cisco_direct_sequence_control70, /* param */
}
,
@ -1221,9 +1225,9 @@ static struct cw_ElemHandler handlers70[] = {
9,9, /* min/max length */
CW_TYPE_STRUCT, /* type */
"cisco/antenna-payload", /* Key */
cw_in_generic, /* get */
cw_out_radio_generic_struct, /* put */
cw_mkradiokey,
cw_in_radio_generic, /* get */
cw_out_radio_generic, /* put */
NULL, /* mkkey */
NULL,
cisco_antenna_payload70,
@ -1622,11 +1626,14 @@ static struct cw_ElemHandler handlers70[] = {
CAPWAP_ELEM_RADIO_OPERATIONAL_STATE, /* Element ID */
0,0, /* Vendor / Proto */
3,3, /* min/max length */
cisco_radio_oper_state, /* type */
CW_TYPE_STRUCT, /* type */
"operational-state", /* Key */
cw_in_radio_generic_struct, /* get */
cw_out_radio_generic_struct, /* put */
NULL /* mkkey */
cw_in_radio_generic, /* get */
cw_out_radio_generic, /* put */
NULL, /* mkkey */
NULL,
cisco_radio_oper_state /* paam */
}
,
@ -1669,7 +1676,7 @@ static struct cw_ElemHandler handlers70[] = {
},
{
"CAPWAP Timers", /* name */
"CAPWAP Timers (Cisco)", /* name */
CISCO_ELEM_CAPWAP_TIMERS, /* Element ID */
0, 0, /* Vendor / Proto */
2, 2, /* min/max length */

View File

@ -15,8 +15,8 @@ int cisco_out_radio_generic(struct cw_ElemHandler * handler, struct cw_ElemHandl
int radios;
len =0;
radios = cw_cfg_get_byte(params->cfg,"wtp-descriptor/max-radios","0");
radios = cw_cfg_get_byte(params->cfg,"wtp-descriptor/max-radios",0);
cw_dbg(DBG_X,"NUM RADIOS: %d",radios);
for(i=0;i<radios+0;i++){
l = cw_write_radio_element(handler,params,i,dst+len);
// cw_dbg_elem(DBG_ELEM_OUT,NULL,params->msgdata->type,handler,dst+len,l);

View File

@ -10,7 +10,7 @@ int cisco_out_wtp_descriptor(struct cw_ElemHandler * eh,
stop();
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
int len;
/* // XXX Dummy WTP Descriptor Header */
uint8_t *d;

View File

@ -38,7 +38,7 @@ int cw_select_ac(mavl_t local_cfg, struct cw_DiscoveryResult * dis)
/* for each discovery response */
mlist_foreach(e, dis->results) {
char acname[CAPWAP_MAX_AC_NAME_LEN + 1];
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
mavl_t remote_cfg;
cw_Val_t *val, *ipval;
int prio, i;

View File

@ -121,7 +121,7 @@ static void do_update(struct cw_Conn * conn)
void clean_cfg(mavl_t cfg)
{
char key[CW_KTV_MAX_KEY_LEN];
char key[CW_CFG_MAX_KEY_LEN];
cw_Val_t search;
int i;
int max;