Lots done in move to typeless
This commit is contained in:
		@ -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 */
 | 
			
		||||
@ -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,
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	,
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
@ -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 */
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user