Lots done in move to typeless
This commit is contained in:
parent
b158544f1a
commit
459e2e2aeb
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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\
|
||||
|
83
src/cw/cfg.c
83
src/cw/cfg.c
@ -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;
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
664
src/cw/conn.c
664
src/cw/conn.c
@ -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,¶ms,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(¶ms,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(¶ms,elems_ptr, elems_len);
|
||||
}
|
||||
|
||||
cw_MsgCallbackFun cb_fun = cw_conn_get_msg_cb(conn,message->type);
|
||||
if (cb_fun != NULL){
|
||||
result_code = cb_fun(¶ms,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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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(¶ms,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(¶ms,elems_ptr, elems_len);
|
||||
}
|
||||
|
||||
|
||||
if (message->postprocess) {
|
||||
// message->postprocess(conn);
|
||||
message->postprocess(¶ms,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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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){
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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){
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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 = {
|
||||
|
@ -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;*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
};
|
||||
|
@ -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;*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -15,6 +15,7 @@
|
||||
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
#include <string.h>
|
||||
|
||||
#include "mavl.h"
|
||||
#include "mavltypes.h"
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "mavl.h"
|
||||
|
||||
void *mavl_replace(struct mavl *t,const void *data, int * replaced){
|
||||
|
@ -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;*/
|
||||
};
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
@ -367,10 +367,14 @@ static struct cw_ElemHandler handlers[] = {
|
||||
CAPWAP_ELEM_CAPWAP_TIMERS, /* Element ID */
|
||||
0, 0, /* Vendor / Proto */
|
||||
2, 2, /* min/max length */
|
||||
capwap_timers, /* type */
|
||||
CW_TYPE_STRUCT, /* type */
|
||||
"capwap-timers", /* Key */
|
||||
cw_in_generic_struct, /* get */
|
||||
cw_out_generic_struct /* put */
|
||||
cw_in_generic, /* get */
|
||||
cw_out_generic, /* put */
|
||||
NULL,
|
||||
NULL,
|
||||
capwap_timers,
|
||||
|
||||
}
|
||||
,
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user