Some work on wtp and ktv config files
FossilOrigin-Name: 3747732055809fd587f96cff65c389a0878a09a197947c1e68a76f605bdb44a0
This commit is contained in:
@ -32,7 +32,7 @@
|
||||
*/
|
||||
uint8_t * bstrv_create_from_str(uint32_t vendor_id,const char *s)
|
||||
{
|
||||
int l = strlen(s);
|
||||
/*int l = strlen(s);
|
||||
if (s[0]!='.')
|
||||
return bstrv_create(vendor_id,(uint8_t*)s,l);
|
||||
|
||||
@ -45,7 +45,7 @@ uint8_t * bstrv_create_from_str(uint32_t vendor_id,const char *s)
|
||||
if (s[1]!='x')
|
||||
return bstrv_create(vendor_id,(uint8_t*)s,l);
|
||||
|
||||
/* the string starts with ".x" - read hexbytes */
|
||||
// the string starts with ".x" - read hexbytes
|
||||
l-=2;
|
||||
int msize=l/2;
|
||||
if(l&1)
|
||||
@ -60,6 +60,7 @@ uint8_t * bstrv_create_from_str(uint32_t vendor_id,const char *s)
|
||||
|
||||
cw_format_scan_hex_bytes(bstrv_data(mem),s+2,l);
|
||||
return mem;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
@ -747,7 +747,7 @@ extern int cw_in_check_disc_req(struct conn *conn, struct cw_action_in *a, uint8
|
||||
int cw_in_check_disc_resp(struct conn *conn, struct cw_action_in *a, uint8_t * data,
|
||||
int len,struct sockaddr *from);
|
||||
|
||||
int cw_check_missing_mand(cw_action_in_t ** out, struct conn *conn, cw_action_in_t * a);
|
||||
|
||||
int cw_in_check_join_req(struct conn *conn, struct cw_action_in *a, uint8_t * data,
|
||||
int len,struct sockaddr *from);
|
||||
extern int cw_in_check_img_data_req_wtp(struct conn *conn, struct cw_action_in *a,
|
||||
|
@ -308,6 +308,7 @@ extern int conn_recvfrom_packet(struct conn *conn, uint8_t * buf, int len,
|
||||
int conn_send_msg(struct conn * conn, uint8_t *rawmsg);
|
||||
int cw_read_from(struct conn * conn);
|
||||
|
||||
int conn_send_msg(struct conn *conn, uint8_t * rawmsg);
|
||||
|
||||
void conn_clear_upd(struct conn *conn, int merge);
|
||||
|
||||
|
@ -30,11 +30,11 @@
|
||||
|
||||
#include "stravltree.h"
|
||||
#include "mod.h"
|
||||
#include "msget.h"
|
||||
#include "msgset.h"
|
||||
|
||||
#include "ktv.h"
|
||||
|
||||
#include "kvt.h"
|
||||
|
||||
int conn_send_msg(struct conn *conn, uint8_t * rawmsg);
|
||||
|
||||
|
||||
|
||||
@ -193,7 +193,7 @@ static struct cw_MsgSet *load_msg_set(struct conn *conn, uint8_t * rawmsg, int l
|
||||
}
|
||||
|
||||
bmod =
|
||||
cw_mod_detect(conn, rawmsg, len, elems_len, from, MOD_MODE_BINDINGS);
|
||||
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);
|
||||
|
||||
@ -506,6 +506,8 @@ exit(0);
|
||||
|
||||
/* all message elements are processed, do now after processing
|
||||
by calling the "end" function for the message */
|
||||
|
||||
cw_check_missing_mand(message,mand_found);
|
||||
|
||||
{
|
||||
|
||||
@ -517,7 +519,7 @@ exit(0);
|
||||
|
||||
mavliter_foreach(&it){
|
||||
char value[500];
|
||||
struct cw_KVT * data;
|
||||
struct cw_KTV * data;
|
||||
data = mavliter_get(&it);
|
||||
type = data->type;
|
||||
type->to_str(data,value,0);
|
||||
|
60
src/cw/conn_send_msg.c
Normal file
60
src/cw/conn_send_msg.c
Normal file
@ -0,0 +1,60 @@
|
||||
#include "conn.h"
|
||||
#include "cw.h"
|
||||
#include "dbg.h"
|
||||
|
||||
int conn_send_msg(struct conn * conn, uint8_t *rawmsg)
|
||||
{
|
||||
uint8_t * ptr;
|
||||
int packetlen;
|
||||
int fragoffset,hlen,mtu;
|
||||
|
||||
packetlen = cw_get_hdr_msg_total_len(rawmsg);
|
||||
|
||||
cw_dbg_msg(DBG_MSG_OUT, conn,rawmsg, packetlen,(struct sockaddr*)&conn->addr);
|
||||
|
||||
/* Zyxel doesn't count msg element length from
|
||||
behind seqnum */
|
||||
if (conn->capwap_mode == CW_MODE_ZYXEL){
|
||||
/* // XXX val-=3; */
|
||||
}
|
||||
|
||||
|
||||
ptr = rawmsg;
|
||||
|
||||
fragoffset = 0;
|
||||
|
||||
hlen = cw_get_hdr_hlen(rawmsg)*4;
|
||||
|
||||
mtu = conn->mtu;
|
||||
|
||||
while (packetlen>mtu){
|
||||
cw_set_hdr_flags(rawmsg,CAPWAP_FLAG_HDR_F,1);
|
||||
cw_put_dword(ptr+4, conn->fragid<<16 | fragoffset<<3 );
|
||||
|
||||
cw_dbg_pkt(DBG_PKT_OUT,conn,ptr,mtu,(struct sockaddr*)&conn->addr);
|
||||
|
||||
if (conn->write(conn,ptr,mtu)<0)
|
||||
return -1;
|
||||
|
||||
/* // XXX Fragmentation stuff.. */
|
||||
ptr +=mtu-hlen;
|
||||
fragoffset+=(mtu-hlen)/8;
|
||||
|
||||
packetlen-=mtu-hlen;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (fragoffset)
|
||||
cw_set_hdr_flags(rawmsg,CAPWAP_FLAG_HDR_F | CAPWAP_FLAG_HDR_L,1);
|
||||
else
|
||||
cw_set_hdr_flags(rawmsg,CAPWAP_FLAG_HDR_F,0);
|
||||
|
||||
cw_put_dword(ptr+4, conn->fragid<<16 | fragoffset<<3 );
|
||||
|
||||
|
||||
cw_dbg_pkt(DBG_PKT_OUT,conn,ptr,packetlen,(struct sockaddr*)&conn->addr);
|
||||
|
||||
return conn->write(conn,ptr,packetlen-0);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include "lw.h"
|
||||
#include "capwap.h"
|
||||
#include "msget.h"
|
||||
#include "msgset.h"
|
||||
|
||||
/**
|
||||
* @defgroup CW CW
|
||||
@ -310,6 +310,9 @@ struct cw_DescriptorSubelemDef {
|
||||
#define CW_REPLACE 4
|
||||
|
||||
|
||||
int cw_check_missing_mand(struct cw_MsgData *msgdata, mavl_t keys );
|
||||
|
||||
|
||||
|
||||
extern int cw_read_descriptor_subelems(mavl_t store, const char * key, uint8_t * data, int len,
|
||||
struct cw_DescriptorSubelemDef *elems);
|
||||
|
@ -2,17 +2,31 @@
|
||||
#include "capwap.h"
|
||||
#include "dbg.h"
|
||||
|
||||
int cw_check_missing_mand(cw_action_in_t ** out, struct conn * conn, cw_action_in_t *a)
|
||||
int cw_check_missing_mand(struct cw_MsgData *msgdata, mavl_t keys )
|
||||
{
|
||||
mlistelem_t * elem;
|
||||
char *mandkey, *result;
|
||||
|
||||
mlist_foreach(elem, msgdata->mand_keys){
|
||||
mandkey = mlistelem_get_str(elem);
|
||||
|
||||
result = mavl_get_str(keys,mandkey);
|
||||
if (result == NULL){
|
||||
printf("Missing\n");
|
||||
}
|
||||
else printf("Ok\n");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
cw_action_in_t as;
|
||||
/* cw_action_in_t as;
|
||||
|
||||
as.capwap_state = a->capwap_state;
|
||||
as.msg_id = a->msg_id;
|
||||
as.vendor_id = 0;
|
||||
as.elem_id = 0;
|
||||
as.proto=0;
|
||||
*/
|
||||
/// TODO XXXX
|
||||
/*
|
||||
DEFINE_AVLITER(it,conn->actions->in);
|
||||
@ -36,3 +50,4 @@ int cw_check_missing_mand(cw_action_in_t ** out, struct conn * conn, cw_action_i
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@ int cw_in_check_cfg_update_req(struct conn *conn, struct cw_action_in *a, uint8_
|
||||
cw_action_in_t * mlist[60];
|
||||
|
||||
/* Check for mandatory elements */
|
||||
int n = cw_check_missing_mand(mlist,conn,a);
|
||||
/* int n = cw_check_missing_mand(mlist,conn,a);
|
||||
if (n) {
|
||||
if ( conn->strict_capwap ){
|
||||
cw_dbg_missing_mand(DBG_MSG_ERR,conn,mlist,n,a);
|
||||
@ -22,7 +22,7 @@ int cw_in_check_cfg_update_req(struct conn *conn, struct cw_action_in *a, uint8_
|
||||
}
|
||||
cw_dbg_missing_mand(DBG_RFC,conn,mlist,n,a);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/* set result code to ok and change to configure state */
|
||||
mbag_set_dword(conn->outgoing,CW_ITEM_RESULT_CODE,0);
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "vendors.h"
|
||||
|
||||
/*
|
||||
void cw_get_wtp_name(struct conn *conn,struct sockaddr *addr)
|
||||
{
|
||||
|
||||
@ -30,7 +31,7 @@ int cw_detect_capwap(struct conn *conn)
|
||||
mbag_item_t * item = mbag_get(is,CW_ITEM_WTP_SOFTWARE_VERSION);
|
||||
if (item) {
|
||||
bstrv_t s = item->u2.data;
|
||||
uint32_t v = bstrv_get_vendor_id(s);
|
||||
uint32_t v = bstrv_get_vendor_id(s);
|
||||
|
||||
switch(v) {
|
||||
case CW_VENDOR_ID_CISCO:
|
||||
@ -62,3 +63,5 @@ int cw_in_check_cipwap_join_req(struct conn *conn, struct cw_action_in *a, uint8
|
||||
|
||||
return rc;
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
int cw_in_check_disc_req(struct conn *conn, struct cw_action_in *a, uint8_t * data,
|
||||
int len,struct sockaddr *from)
|
||||
{
|
||||
/*
|
||||
char sock_buf[SOCK_ADDR_BUFSIZE];
|
||||
|
||||
cw_action_in_t *mlist[120];
|
||||
@ -20,8 +21,8 @@ int cw_in_check_disc_req(struct conn *conn, struct cw_action_in *a, uint8_t * da
|
||||
|
||||
if (n && conn->strict_capwap) {
|
||||
cw_dbg_missing_mand(DBG_MSG_ERR, conn, mlist, n, a);
|
||||
/* if mandatory elements are missing, in strict
|
||||
mode send no discovery response */
|
||||
// if mandatory elements are missing, in strict
|
||||
// mode send no discovery response
|
||||
cw_dbg(DBG_MSG_ERR,
|
||||
"Ignoring Discovery Request from %s - missing mandatory elements.",
|
||||
sock_addr2str(from,sock_buf));
|
||||
@ -29,14 +30,14 @@ int cw_in_check_disc_req(struct conn *conn, struct cw_action_in *a, uint8_t * da
|
||||
}
|
||||
|
||||
if ( n ) {
|
||||
/* put a warning here */
|
||||
// put a warning here
|
||||
cw_dbg_missing_mand(DBG_RFC, conn, mlist, n, a);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ok, send response */
|
||||
// ok, send response
|
||||
conn->capwap_state = CAPWAP_STATE_JOIN;
|
||||
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ int cw_in_check_generic_req(struct conn *conn, struct cw_action_in *a, uint8_t *
|
||||
cw_action_in_t * mlist[60];
|
||||
|
||||
/* Check for mandatory elements */
|
||||
int n = cw_check_missing_mand(mlist,conn,a);
|
||||
/* int n = cw_check_missing_mand(mlist,conn,a);
|
||||
if (n) {
|
||||
if ( conn->strict_capwap ){
|
||||
cw_dbg_missing_mand(DBG_MSG_ERR,conn,mlist,n,a);
|
||||
@ -21,7 +21,7 @@ int cw_in_check_generic_req(struct conn *conn, struct cw_action_in *a, uint8_t *
|
||||
}
|
||||
cw_dbg_missing_mand(DBG_RFC,conn,mlist,n,a);
|
||||
}
|
||||
|
||||
*/
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
@ -11,9 +11,9 @@ int cw_in_check_generic_resp(struct conn *conn, struct cw_action_in *a, uint8_t
|
||||
int len,struct sockaddr *from)
|
||||
{
|
||||
|
||||
|
||||
/* Check if the message contains a result code and
|
||||
if it indicates an errror */
|
||||
/*
|
||||
//Check if the message contains a result code and
|
||||
if it indicates an errror //
|
||||
mbag_item_t * result = mbag_get(conn->incomming,CW_ITEM_RESULT_CODE);
|
||||
|
||||
if (result ) {
|
||||
@ -24,21 +24,21 @@ int cw_in_check_generic_resp(struct conn *conn, struct cw_action_in *a, uint8_t
|
||||
|
||||
cw_action_in_t * mlist[60];
|
||||
|
||||
/* Check for mandatory elements */
|
||||
// Check for mandatory elements
|
||||
int n = cw_check_missing_mand(mlist,conn,a);
|
||||
if (n && conn->strict_capwap) {
|
||||
cw_dbg_missing_mand(DBG_MSG_ERR,conn,mlist,n,a);
|
||||
errno=EAGAIN;
|
||||
return -1; /* CW_RESULT_MISSING_MAND_ELEM */
|
||||
// return -1; /* CW_RESULT_MISSING_MAND_ELEM
|
||||
}
|
||||
if (n){
|
||||
cw_dbg_missing_mand(DBG_RFC,conn,mlist,n,a);
|
||||
}
|
||||
|
||||
/* if we hava a result code, return it */
|
||||
// if we hava a result code, return it
|
||||
if ( result ) {
|
||||
return result->u2.dword;
|
||||
}
|
||||
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ int cw_in_check_img_data_req_ac(struct conn *conn, struct cw_action_in *a, uint8
|
||||
int len,struct sockaddr *from)
|
||||
{
|
||||
/* Check for mandatory elements */
|
||||
cw_action_in_t * mlist[60];
|
||||
/* cw_action_in_t * mlist[60];
|
||||
int n = cw_check_missing_mand(mlist,conn,a);
|
||||
if (n) {
|
||||
cw_dbg_missing_mand(DBG_ELEM,conn,mlist,n,a);
|
||||
@ -52,5 +52,5 @@ int cw_in_check_img_data_req_ac(struct conn *conn, struct cw_action_in *a, uint8
|
||||
|
||||
|
||||
return CAPWAP_RESULT_IMAGE_DATA_ERROR;
|
||||
|
||||
*/
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ int cw_in_check_img_data_req_wtp(struct conn *conn, struct cw_action_in *a, uint
|
||||
|
||||
|
||||
/* Check for mandatory elements */
|
||||
cw_action_in_t * mlist[60];
|
||||
/* cw_action_in_t * mlist[60];
|
||||
int n = cw_check_missing_mand(mlist,conn,a);
|
||||
if (n) {
|
||||
cw_dbg_missing_mand(DBG_ELEM,conn,mlist,n,a);
|
||||
@ -62,5 +62,5 @@ int cw_in_check_img_data_req_wtp(struct conn *conn, struct cw_action_in *a, uint
|
||||
|
||||
|
||||
return CAPWAP_RESULT_IMAGE_DATA_ERROR;
|
||||
|
||||
*/
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ int cw_in_check_img_data_resp(struct conn *conn, struct cw_action_in *a, uint8_t
|
||||
cw_action_in_t * mlist[60];
|
||||
|
||||
/* Check for mandatory elements */
|
||||
int n = cw_check_missing_mand(mlist,conn,a);
|
||||
/* int n = cw_check_missing_mand(mlist,conn,a);
|
||||
if (n) {
|
||||
cw_dbg_missing_mand(DBG_ELEM,conn,mlist,n,a);
|
||||
conn->capwap_state=CAPWAP_STATE_JOIN;
|
||||
@ -29,7 +29,7 @@ int cw_in_check_img_data_resp(struct conn *conn, struct cw_action_in *a, uint8_t
|
||||
if ( iresult ) {
|
||||
return iresult->u2.dword;
|
||||
}
|
||||
|
||||
*/
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
@ -10,10 +10,10 @@
|
||||
int cw_in_check_join_req(struct conn *conn, struct cw_action_in *a, uint8_t * data,
|
||||
int len,struct sockaddr *from)
|
||||
{
|
||||
|
||||
/*
|
||||
cw_action_in_t * mlist[60];
|
||||
|
||||
/* Check for mandatory elements */
|
||||
//Check for mandatory elements
|
||||
int n = cw_check_missing_mand(mlist,conn,a);
|
||||
if (n) {
|
||||
if ( conn->strict_capwap ){
|
||||
@ -36,9 +36,9 @@ int cw_in_check_join_req(struct conn *conn, struct cw_action_in *a, uint8_t * da
|
||||
return CW_RESULT_JOIN_FAILURE_SESSION_ALREADY_IN_USE;
|
||||
}
|
||||
|
||||
/* set result code to ok and change to configure state */
|
||||
// set result code to ok and change to configure state
|
||||
mbag_set_dword(conn->outgoing,CW_ITEM_RESULT_CODE,0);
|
||||
conn->capwap_state = CW_STATE_CONFIGURE;
|
||||
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,3 +0,0 @@
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
int cw_in_check_join_resp(struct conn *conn, struct cw_action_in *a, uint8_t * data,
|
||||
int len,struct sockaddr *from)
|
||||
{
|
||||
|
||||
/*
|
||||
cw_action_in_t * mlist[60];
|
||||
|
||||
mbag_item_t * jresult = mbag_get(conn->incomming,CW_ITEM_RESULT_CODE);
|
||||
@ -21,7 +21,7 @@ int cw_in_check_join_resp(struct conn *conn, struct cw_action_in *a, uint8_t * d
|
||||
}
|
||||
|
||||
|
||||
/* Check for mandatory elements */
|
||||
// Check for mandatory elements
|
||||
int n = cw_check_missing_mand(mlist,conn,a);
|
||||
if (n && conn->strict_capwap) {
|
||||
cw_dbg_missing_mand(DBG_MSG_ERR,conn,mlist,n,a);
|
||||
@ -40,8 +40,8 @@ int cw_in_check_join_resp(struct conn *conn, struct cw_action_in *a, uint8_t * d
|
||||
return jresult->u2.dword;
|
||||
}
|
||||
|
||||
/* set result code to ok and change to configure state */
|
||||
// set result code to ok and change to configure state
|
||||
// mbag_set_dword(conn->outgoing,CW_ITEM_RESULT_CODE,0);
|
||||
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "msget.h"
|
||||
#include "kvt.h"
|
||||
#include "msgset.h"
|
||||
#include "ktv.h"
|
||||
#include "log.h"
|
||||
|
||||
int cw_in_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams * params,
|
||||
@ -12,7 +12,7 @@ int cw_in_generic(struct cw_ElemHandler * handler, struct cw_ElemHandlerParams *
|
||||
cw_log(LOG_ERR,"Can't handle element: %s, no type defined",handler->name);
|
||||
return 0;
|
||||
}
|
||||
cw_kvt_add(params->conn->remote_cfg, handler->key, handler->type, elem_data,elem_len);
|
||||
cw_ktv_add(params->conn->remote_cfg, handler->key, handler->type, elem_data,elem_len);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -171,7 +171,7 @@ int cw_put_elem_result_code(uint8_t * dst, uint32_t code)
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
int cw_put_version(uint8_t * dst, uint16_t subelem_id, bstrv_t v)
|
||||
{
|
||||
uint8_t *d = dst;
|
||||
@ -180,6 +180,7 @@ int cw_put_version(uint8_t * dst, uint16_t subelem_id, bstrv_t v)
|
||||
d += cw_put_data(d, bstrv_data(v), bstrv_len(v));
|
||||
return d - dst;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
int cw_put_elem_radio_operational_state(uint8_t * dst, int rid, int state, int cause) {
|
||||
|
@ -1,13 +1,13 @@
|
||||
#include "kvt.h"
|
||||
#include "ktv.h"
|
||||
#include "cw.h"
|
||||
|
||||
#include "log.h"
|
||||
#include "dbg.h"
|
||||
|
||||
const char * cw_kvt_add(mavl_t kvtstore, const char *key, const struct cw_Type *type,
|
||||
const char * cw_ktv_add(mavl_t kvtstore, const char *key, const struct cw_Type *type,
|
||||
const uint8_t * data, int len)
|
||||
{
|
||||
cw_KVT_t mdata, *mresult;
|
||||
cw_KTV_t mdata, *mresult;
|
||||
int exists;
|
||||
|
||||
/* cw_dbg(DBG_ELEM,"KVStore (%p,%d) add elem (%s): %s", kvstore, kvstore->count,
|
6
src/cw/cw_ktv_mavlcmp.c
Normal file
6
src/cw/cw_ktv_mavlcmp.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "ktv.h"
|
||||
|
||||
int cw_ktv_mavlcmp(const void *v1, const void *v2)
|
||||
{
|
||||
return strcmp(((cw_KTV_t *) v1)->key, ((cw_KTV_t *) v2)->key);
|
||||
}
|
8
src/cw/cw_ktv_mavlcmp_type_by_name.c
Normal file
8
src/cw/cw_ktv_mavlcmp_type_by_name.c
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
#include "ktv.h"
|
||||
|
||||
int cw_ktv_mavlcmp_type_by_name (const void *v1, const void *v2)
|
||||
{
|
||||
return strcmp ( (*((struct cw_Type**) v1))->name,
|
||||
(*((struct cw_Type**) v2))->name);
|
||||
}
|
@ -2,11 +2,11 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#include "kvt.h"
|
||||
#include "ktv.h"
|
||||
|
||||
void cw_kvt_mavldel(void *data)
|
||||
void cw_ktv_mavldel(void *data)
|
||||
{
|
||||
struct cw_KVT *kvt = data;
|
||||
struct cw_KTV *kvt = data;
|
||||
|
||||
if (kvt->type->del)
|
||||
kvt->type->del(data);
|
8
src/cw/cw_ktv_read_file.c
Normal file
8
src/cw/cw_ktv_read_file.c
Normal file
@ -0,0 +1,8 @@
|
||||
|
||||
#include "ktv.h"
|
||||
|
||||
cw_kvt_read_file(mavl_t ktv, mavl_t types)
|
||||
{
|
||||
|
||||
|
||||
}
|
229
src/cw/cw_ktv_readline.c
Normal file
229
src/cw/cw_ktv_readline.c
Normal file
@ -0,0 +1,229 @@
|
||||
#include <ctype.h>
|
||||
|
||||
#include "ktv.h"
|
||||
|
||||
struct parser {
|
||||
int line;
|
||||
int pos;
|
||||
int prevpos;
|
||||
char error[256];
|
||||
};
|
||||
|
||||
static int get_char(FILE * f, struct parser *p)
|
||||
{
|
||||
int c;
|
||||
c = fgetc (f);
|
||||
p->pos++;
|
||||
if (c=='\n'){
|
||||
p->prevpos=p->pos;
|
||||
p->line ++;
|
||||
p->pos=0;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static void unget_char(int c, FILE *f, struct parser *p){
|
||||
ungetc(c,f);
|
||||
if (c=='\n'){
|
||||
p->line--;
|
||||
p->pos=p->prevpos;
|
||||
}
|
||||
else
|
||||
p->pos--;
|
||||
}
|
||||
|
||||
static int skip_chars (FILE *f, const char * chars, struct parser * p )
|
||||
{
|
||||
int c;
|
||||
|
||||
while ( (c = get_char (f, p)) != EOF) {
|
||||
if (strchr (chars, c))
|
||||
continue;
|
||||
return c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static int skip_to_chars (FILE *f, const char *chars, struct parser * p)
|
||||
{
|
||||
int c;
|
||||
|
||||
while ( (c = get_char (f, p)) != EOF) {
|
||||
if (strchr (chars, c))
|
||||
return c;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int read_key (FILE *f, char *key, int max_len, struct parser * p)
|
||||
{
|
||||
int c,n;
|
||||
|
||||
do {
|
||||
c = skip_chars (f, " \t\n\a\v", p);
|
||||
if (c == '#') {
|
||||
c = skip_to_chars (f, "\n\a",p);
|
||||
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (c != EOF);
|
||||
|
||||
|
||||
n=0;
|
||||
while(c!=EOF && n<max_len){
|
||||
if (!isalnum(c) && !strchr("_/-()@#|{}[]",c)/*strchr(": \t\n\a",c)*/){
|
||||
unget_char(c,f,p);
|
||||
break;
|
||||
}
|
||||
|
||||
key[n]=c;
|
||||
c=get_char(f,p);
|
||||
n++;
|
||||
|
||||
}
|
||||
key[n]=0;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static int skip_to_colon(FILE *f,struct parser * p)
|
||||
{
|
||||
int c;
|
||||
c = skip_chars (f, " \t", p);
|
||||
if (c!=':'){
|
||||
if (c=='\n'){
|
||||
unget_char(c,f,p);
|
||||
sprintf(p->error,"Error at line %d, pos %d: Unexpected EOL, collon expected.", p->line, p->pos);
|
||||
return 0;
|
||||
}
|
||||
sprintf(p->error,"Error at line %d, pos %d: Collon expected.", p->line, p->pos);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int read_type(FILE *f, char *type, int max_len, struct parser *p)
|
||||
{
|
||||
int c,n;
|
||||
|
||||
if (!skip_to_colon(f,p))
|
||||
return -1;
|
||||
|
||||
c = skip_chars (f, " \t", p);
|
||||
|
||||
if (c==':'){
|
||||
unget_char(c,f,p);
|
||||
sprintf(type,"");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!isalpha(c)){
|
||||
if (c=='\n'){
|
||||
unget_char(c,f,p);
|
||||
sprintf(p->error,"Error at line %d, pos %d: Unexpected EOL.", p->line, p->pos);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(p->error,"Error at line %d, pos %d: Letter expected.", p->line, p->pos);
|
||||
return -1;
|
||||
}
|
||||
|
||||
n=0;
|
||||
while(c!=EOF && n<max_len){
|
||||
if (!isalnum(c) && !strchr("_/-.()@#|{}[]",c)/*strchr(": \t\n\a",c)*/){
|
||||
unget_char(c,f,p);
|
||||
break;
|
||||
}
|
||||
|
||||
type[n]=c;
|
||||
c=get_char(f,p);
|
||||
n++;
|
||||
}
|
||||
type[n]=0;
|
||||
return n;
|
||||
}
|
||||
|
||||
static int read_val(FILE *f, char *val, int max_len, struct parser *p){
|
||||
int c,n,quote;
|
||||
if (!skip_to_colon(f,p))
|
||||
return -1;
|
||||
c = skip_chars (f, " \t", p);
|
||||
if (c=='"'){
|
||||
quote=1;
|
||||
c=get_char(f,p);
|
||||
}
|
||||
else{
|
||||
quote=0;
|
||||
}
|
||||
n=0;
|
||||
while(c!=EOF && n<max_len){
|
||||
if (quote && c=='"'){
|
||||
break;
|
||||
}
|
||||
if (c=='\n'){
|
||||
break;
|
||||
}
|
||||
if (quote){
|
||||
if (c=='\\'){
|
||||
c = get_char(f,p);
|
||||
switch(c){
|
||||
case 'n':
|
||||
c='\n';
|
||||
break;
|
||||
case '\\':
|
||||
break;
|
||||
case '"':
|
||||
break;
|
||||
default:
|
||||
unget_char(c,f,p);
|
||||
c='\\';
|
||||
}
|
||||
}
|
||||
}
|
||||
val[n++]=c;
|
||||
c=get_char(f,p);
|
||||
}
|
||||
|
||||
|
||||
if(!quote && n>0){
|
||||
while(n>0){
|
||||
if (isspace(val[n-1]))
|
||||
n--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
val[n]=0;
|
||||
|
||||
return n;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int cw_ktv_read_line (FILE *f, char * key, char * type, char *val)
|
||||
{
|
||||
int n;
|
||||
|
||||
struct parser p;
|
||||
p.line=1;
|
||||
p.pos=0;
|
||||
p.prevpos=0;
|
||||
|
||||
n = read_key (f,key,CW_KTV_MAX_KEY_LEN,&p);
|
||||
n = read_type (f,type,CW_KTV_MAX_KEY_LEN,&p);
|
||||
if (n==-1){
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = read_val (f,val,CW_KTV_MAX_KEY_LEN,&p);
|
||||
if (n==-1){
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#include "kvt.h"
|
||||
|
||||
int cw_kvt_mavlcmp(const void *v1, const void *v2)
|
||||
{
|
||||
return strcmp(((cw_KVT_t *) v1)->key, ((cw_KVT_t *) v2)->key);
|
||||
}
|
@ -47,7 +47,7 @@ int cw_out_wtp_descriptor(struct conn *conn, struct cw_action_out *a, uint8_t *
|
||||
|
||||
mbag_item_t * i;
|
||||
i = mbag_get(mbag,CW_ITEM_WTP_HARDWARE_VERSION);
|
||||
if ( i ) {
|
||||
/* if ( i ) {
|
||||
d += cw_put_version(d,CW_SUBELEM_WTP_HARDWARE_VERSION,i->u2.data);
|
||||
}
|
||||
else {
|
||||
@ -77,7 +77,7 @@ int cw_out_wtp_descriptor(struct conn *conn, struct cw_action_out *a, uint8_t *
|
||||
else {
|
||||
cw_log(LOG_INFO, "Can't send Other Version in WTP descriptor, not set.");
|
||||
}
|
||||
|
||||
*/
|
||||
int len = d-dst-4;
|
||||
return len + cw_put_elem_hdr(dst,a->elem_id,len);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ int cw_process_element(struct cw_ElemHandlerParams *params, int proto, int vendo
|
||||
struct cw_ElemData * elem_data, elem_data_search;
|
||||
|
||||
/* try to retrieve a handler for this message element */
|
||||
handler = cw_msgset_get_elemhandler(params->conn->msgset,0, 0, elem_id);
|
||||
handler = cw_msgset_get_elemhandler(params->conn->msgset,proto, vendor, elem_id);
|
||||
if (!handler) {
|
||||
cw_dbg(DBG_ELEM_ERR, "Unrecognized message element: %d, ignoring",
|
||||
elem_id);
|
||||
@ -28,8 +28,8 @@ int cw_process_element(struct cw_ElemHandlerParams *params, int proto, int vendo
|
||||
|
||||
/* check if this message element in the current message allowed */
|
||||
elem_data_search.id=elem_id;
|
||||
elem_data_search.proto=0;
|
||||
elem_data_search.vendor=0;
|
||||
elem_data_search.proto=proto;
|
||||
elem_data_search.vendor=vendor;
|
||||
elem_data = mavl_find(params->msgdata->elements_tree,&elem_data_search);
|
||||
if (!elem_data){
|
||||
cw_dbg(DBG_ELEM_ERR, "Element %d - %s, not allowed here",
|
||||
|
@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "cw.h"
|
||||
#include "kvt.h"
|
||||
#include "ktv.h"
|
||||
#include "dbg.h"
|
||||
#include "keys.h"
|
||||
|
||||
@ -69,11 +69,11 @@ int cw_read_descriptor_subelems(mavl_t cfg, const char * parent_key,
|
||||
|
||||
/* vendor */
|
||||
sprintf(key,"%s/%s/%s",parent_key,elems[i].key,CW_KEY_VENDOR);
|
||||
cw_kvt_add(cfg,key,CW_TYPE_DWORD,data + sub,4);
|
||||
cw_ktv_add(cfg,key,CW_TYPE_DWORD,data + sub,4);
|
||||
|
||||
/* version */
|
||||
sprintf(key,"%s/%s/%s",parent_key,elems[i].key,CW_KEY_VERSION);
|
||||
cw_kvt_add(cfg,key,CW_TYPE_BSTR16,data+sub+8,l);
|
||||
cw_ktv_add(cfg,key,CW_TYPE_BSTR16,data+sub+8,l);
|
||||
|
||||
sprintf(dbgstr, "%s", key);
|
||||
cw_dbg_version_subelem(DBG_SUBELEM, dbgstr, subtype, vendor_id, data+sub+8,l);
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "capwap.h"
|
||||
#include "capwap_items.h"
|
||||
#include "dbg.h"
|
||||
#include "kvt.h"
|
||||
#include "ktv.h"
|
||||
|
||||
|
||||
static struct cw_DescriptorSubelemDef allowed_default[] = {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#include "capwap.h"
|
||||
#include "capwap_items.h"
|
||||
#include "kvt.h"
|
||||
#include "ktv.h"
|
||||
#include "keys.h"
|
||||
|
||||
|
||||
@ -32,10 +32,10 @@ int cw_read_wtp_descriptor_7(mavl_t cfg, struct conn *conn,
|
||||
/* md.kv.key=strdup(key);
|
||||
mavl_replace (cfg, cw_type_byte.get(&md,data,1));
|
||||
*/
|
||||
cw_kvt_add(cfg,key,CW_TYPE_BYTE,data,1);
|
||||
cw_ktv_add(cfg,key,CW_TYPE_BYTE,data,1);
|
||||
|
||||
sprintf(key,"%s/%s",eh->key, "radios_in_use");
|
||||
cw_kvt_add(cfg,key,CW_TYPE_BYTE,data+1,1);
|
||||
cw_ktv_add(cfg,key,CW_TYPE_BYTE,data+1,1);
|
||||
|
||||
/* md.kv.key=strdup(key);
|
||||
mavl_replace (cfg, cw_type_byte.get(&md,data+1,1));
|
||||
|
@ -45,7 +45,7 @@ int cw_read_wtp_descriptor_versions(mbag_t mbag, uint8_t * data, int len)
|
||||
free(dmpmem);
|
||||
|
||||
switch (subtype) {
|
||||
case CW_SUBELEM_WTP_HARDWARE_VERSION:
|
||||
/* case CW_SUBELEM_WTP_HARDWARE_VERSION:
|
||||
mbag_set_bstrv(mbag,
|
||||
CW_ITEM_WTP_HARDWARE_VERSION,
|
||||
vendor_id, data + i, sublen);
|
||||
@ -69,7 +69,7 @@ int cw_read_wtp_descriptor_versions(mbag_t mbag, uint8_t * data, int len)
|
||||
"Unknown WTP descriptor subelement, type = %d",
|
||||
subtype);
|
||||
break;
|
||||
}
|
||||
*/ }
|
||||
i += sublen;
|
||||
|
||||
}
|
||||
|
@ -20,15 +20,15 @@
|
||||
|
||||
#include "format.h"
|
||||
#include "cw.h"
|
||||
#include "kvt.h"
|
||||
#include "ktv.h"
|
||||
|
||||
|
||||
static void del ( struct cw_KVT * data )
|
||||
static void del ( struct cw_KTV * data )
|
||||
{
|
||||
free ( data->val.ptr );
|
||||
}
|
||||
|
||||
static struct cw_KVT *get ( struct cw_KVT * data, const uint8_t * src, int len )
|
||||
static struct cw_KTV *get ( struct cw_KTV * data, const uint8_t * src, int len )
|
||||
{
|
||||
uint8_t * s;
|
||||
s = bstr16_create ( src, len );
|
||||
@ -41,12 +41,12 @@ static struct cw_KVT *get ( struct cw_KVT * data, const uint8_t * src, int len )
|
||||
return data;
|
||||
}
|
||||
|
||||
static int put ( const struct cw_KVT *data, uint8_t * dst )
|
||||
static int put ( const struct cw_KTV *data, uint8_t * dst )
|
||||
{
|
||||
return cw_put_bstr16 ( dst, data->val.ptr );
|
||||
}
|
||||
|
||||
static int to_str ( const struct cw_KVT *data, char *dst, int max_len )
|
||||
static int to_str ( const struct cw_KTV *data, char *dst, int max_len )
|
||||
{
|
||||
char *d;
|
||||
d = dst;
|
||||
@ -63,7 +63,7 @@ static int to_str ( const struct cw_KVT *data, char *dst, int max_len )
|
||||
return d - dst;
|
||||
}
|
||||
|
||||
static struct cw_KVT *from_str ( struct cw_KVT * data, const char *src )
|
||||
static struct cw_KTV *from_str ( struct cw_KTV * data, const char *src )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -19,26 +19,26 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cw.h"
|
||||
#include "kvt.h"
|
||||
#include "ktv.h"
|
||||
|
||||
static cw_KVT_t *get(cw_KVT_t * data, const uint8_t * src, int len)
|
||||
static cw_KTV_t *get(cw_KTV_t * data, const uint8_t * src, int len)
|
||||
{
|
||||
data->type = &cw_type_byte;
|
||||
data->val.byte = cw_get_byte(src);
|
||||
return data;
|
||||
}
|
||||
|
||||
static int put(const cw_KVT_t *data, uint8_t * dst)
|
||||
static int put(const cw_KTV_t *data, uint8_t * dst)
|
||||
{
|
||||
return cw_put_byte(dst, data->val.byte);
|
||||
}
|
||||
|
||||
static int to_str(const cw_KVT_t *data, char *dst, int max_len)
|
||||
static int to_str(const cw_KTV_t *data, char *dst, int max_len)
|
||||
{
|
||||
return sprintf(dst, "%d", data->val.byte);
|
||||
}
|
||||
|
||||
static cw_KVT_t *from_str(cw_KVT_t * data, const char *src)
|
||||
static cw_KTV_t *from_str(cw_KTV_t * data, const char *src)
|
||||
{
|
||||
data->val.byte = atoi(src);
|
||||
return data;
|
||||
|
@ -19,26 +19,26 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cw.h"
|
||||
#include "kvt.h"
|
||||
#include "ktv.h"
|
||||
|
||||
static struct cw_KVT *get(struct cw_KVT * data, const uint8_t * src, int len)
|
||||
static struct cw_KTV *get(struct cw_KTV * data, const uint8_t * src, int len)
|
||||
{
|
||||
data->type = &cw_type_dword;
|
||||
data->val.dword = cw_get_dword(src);
|
||||
return data;
|
||||
}
|
||||
|
||||
static int put(const struct cw_KVT *data, uint8_t * dst)
|
||||
static int put(const struct cw_KTV *data, uint8_t * dst)
|
||||
{
|
||||
return cw_put_dword(dst, data->val.dword);
|
||||
}
|
||||
|
||||
static int to_str(const struct cw_KVT *data, char *dst, int max_len)
|
||||
static int to_str(const struct cw_KTV *data, char *dst, int max_len)
|
||||
{
|
||||
return sprintf(dst, "%d", data->val.dword);
|
||||
}
|
||||
|
||||
static struct cw_KVT *from_str(struct cw_KVT * data, const char *src)
|
||||
static struct cw_KTV *from_str(struct cw_KTV * data, const char *src)
|
||||
{
|
||||
data->val.dword = atoi(src);
|
||||
return data;
|
||||
|
@ -18,28 +18,28 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "kvt.h"
|
||||
#include "ktv.h"
|
||||
#include "cw.h"
|
||||
|
||||
|
||||
static struct cw_KVT *get(struct cw_KVT * data, const uint8_t * src, int len)
|
||||
static struct cw_KTV *get(struct cw_KTV * data, const uint8_t * src, int len)
|
||||
{
|
||||
data->type = &cw_type_word;
|
||||
data->val.word = cw_get_word(src);
|
||||
return data;
|
||||
}
|
||||
|
||||
static int put(const cw_KVT_t *data, uint8_t * dst)
|
||||
static int put(const cw_KTV_t *data, uint8_t * dst)
|
||||
{
|
||||
return cw_put_word(dst, data->val.word);
|
||||
}
|
||||
|
||||
static int to_str(const cw_KVT_t *data, char *dst, int max_len)
|
||||
static int to_str(const cw_KTV_t *data, char *dst, int max_len)
|
||||
{
|
||||
return sprintf(dst, "%d", data->val.word);
|
||||
}
|
||||
|
||||
static cw_KVT_t *from_str(cw_KVT_t * data, const char *src)
|
||||
static cw_KTV_t *from_str(cw_KTV_t * data, const char *src)
|
||||
{
|
||||
data->val.word = atoi(src);
|
||||
return data;
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include "capwap_cisco.h"
|
||||
#include "lwapp_cisco.h"
|
||||
#include "cw.h"
|
||||
#include "msget.h"
|
||||
#include "msgset.h"
|
||||
|
||||
|
||||
|
||||
|
@ -2,20 +2,23 @@
|
||||
#define __KVT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mavl.h"
|
||||
|
||||
struct cw_KVT {
|
||||
#define CW_KTV_MAX_KEY_LEN 1024
|
||||
|
||||
struct cw_KTV {
|
||||
char *key;
|
||||
const struct cw_Type *type;
|
||||
union {
|
||||
uint32_t dword;
|
||||
uint16_t word;
|
||||
uint8_t byte;
|
||||
void *ptr;
|
||||
} val;
|
||||
const struct cw_Type *type;
|
||||
};
|
||||
typedef struct cw_KVT cw_KVT_t;
|
||||
typedef struct cw_KTV cw_KTV_t;
|
||||
|
||||
|
||||
struct cw_Type {
|
||||
@ -23,22 +26,22 @@ struct cw_Type {
|
||||
const char *name;
|
||||
|
||||
/** A pointer to a function to delete elements of this type */
|
||||
void (*del) (struct cw_KVT * data);
|
||||
void (*del) (struct cw_KTV * data);
|
||||
|
||||
/** A method to put this object to a buffer */
|
||||
int (*put) (const struct cw_KVT * data, uint8_t * dst);
|
||||
int (*put) (const struct cw_KTV * data, uint8_t * dst);
|
||||
|
||||
/** The get method */
|
||||
struct cw_KVT *(*get) (struct cw_KVT * data, const uint8_t * src, int len);
|
||||
struct cw_KTV *(*get) (struct cw_KTV * data, const uint8_t * src, int len);
|
||||
|
||||
/** A pointer to a function to convert elements of this type to a string.
|
||||
This function is mainly used to store elements to an SQL database
|
||||
or to json strings */
|
||||
int (*to_str) (const struct cw_KVT * data, char *dst, int max_len);
|
||||
int (*to_str) (const struct cw_KTV * data, char *dst, int max_len);
|
||||
|
||||
/** Cereate an item of this type from a string, which was previously
|
||||
created by the #del function. */
|
||||
struct cw_KVT *(*from_str) (struct cw_KVT * data, const char *src);
|
||||
struct cw_KTV *(*from_str) (struct cw_KTV * data, const char *src);
|
||||
|
||||
/*
|
||||
int (*def)(void *, void *);
|
||||
@ -58,13 +61,20 @@ extern const struct cw_Type cw_type_bstr16;
|
||||
/*
|
||||
void cw_kvstore_mavl_delete(const void *data);
|
||||
*/
|
||||
const char *cw_kvt_add(mavl_t kvstore, const char *key, const struct cw_Type *type,
|
||||
const char *cw_ktv_add(mavl_t kvstore, const char *key, const struct cw_Type *type,
|
||||
const uint8_t * data, int len);
|
||||
|
||||
int cw_kvt_mavlcmp(const void *v1, const void *v2);
|
||||
void cw_kvt_mavldel(void *data);
|
||||
int cw_ktv_mavlcmp(const void *v1, const void *v2);
|
||||
int cw_ktv_mavlcmp_type_by_name(const void *v1,const void *v2);
|
||||
|
||||
#define cw_kvt_create()\
|
||||
mavl_create(cw_kvt_mavlcmp, cw_kvt_mavldel, sizeof(cw_KVT_t))
|
||||
void cw_ktv_mavldel(void *data);
|
||||
|
||||
#define cw_ktv_create()\
|
||||
mavl_create(cw_ktv_mavlcmp, cw_ktv_mavldel, sizeof(cw_KTV_t))
|
||||
|
||||
#define cw_ktv_create_types_tree()\
|
||||
mavl_create(cw_ktv_mavlcmp_type_by_name,NULL,sizeof(struct cw_Type *))
|
||||
|
||||
int cw_ktv_read_line (FILE *f, char * key, char * type, char *val);
|
||||
|
||||
#endif /* __KVT_H */
|
@ -281,7 +281,7 @@ int mavl_cmpstr(const void *p1, const void *p2);
|
||||
#define mavl_create_conststr() mavl_create_ptr(mavl_cmpstr,NULL)
|
||||
|
||||
void * mavl_get_ptr ( mavl_t tree, void * search );
|
||||
void * mavl_add_ptr ( mavl_t tree, void *ptr );
|
||||
void * mavl_add_ptr ( mavl_t tree, const void *ptr );
|
||||
|
||||
#define mavl_add_str(tree,str) mavl_add_ptr(tree,str)
|
||||
#define mavl_get_str(tree,search) ((char *)(mavl_get_ptr(tree,search)))
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "mavl.h"
|
||||
|
||||
void *mavl_add_ptr(mavl_t tree, void *ptr){
|
||||
void *mavl_add_ptr(mavl_t tree, const void *ptr){
|
||||
void * result;
|
||||
result = mavl_add(tree,&ptr,NULL);
|
||||
if (result)
|
||||
|
@ -64,10 +64,13 @@ typedef struct mlist * mlist_t;
|
||||
mlist_t mlist_create(int (*cmp) (const void *v1, const void *v2), void (*del)(void *), size_t data_size);
|
||||
|
||||
struct mlistelem *mlist_append(mlist_t l, void *data);
|
||||
void mlist_destroy(mlist_t l);
|
||||
|
||||
extern struct mlistelem *mlist_find(mlist_t l, struct mlistelem *start, void *data);
|
||||
extern struct mlistelem *mlist_replace(mlist_t l, struct mlistelem *start, void *data);
|
||||
|
||||
|
||||
|
||||
#define mlist_add mlist_append
|
||||
/**
|
||||
* @}
|
||||
@ -75,6 +78,14 @@ extern struct mlistelem *mlist_replace(mlist_t l, struct mlistelem *start, void
|
||||
|
||||
#define mlist_foreach(elem,list)\
|
||||
for (elem=list->first; elem; elem=elem->next)
|
||||
|
||||
|
||||
#define mlistelem_get_ptr(elem) (*((void**)(mlistelem_dataptr(elem))))
|
||||
#define mlistelem_get_str(elem) mlistelem_get_ptr(elem)
|
||||
#define mlist_create_conststr() mlist_create(NULL,NULL,sizeof(const char*))
|
||||
mlistelem_t * mlist_append_ptr (mlist_t list, void * ptr);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
6
src/cw/mlist_append_ptr.c
Normal file
6
src/cw/mlist_append_ptr.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "mlist.h"
|
||||
|
||||
mlistelem_t * mlist_append_ptr (mlist_t list, void * ptr)
|
||||
{
|
||||
return mlist_append (list, &ptr);
|
||||
}
|
15
src/cw/mlist_destroy.c
Normal file
15
src/cw/mlist_destroy.c
Normal file
@ -0,0 +1,15 @@
|
||||
#include "mlist.h"
|
||||
|
||||
void mlist_destroy(mlist_t l){
|
||||
mlistelem_t * elem, * next;
|
||||
elem = l->first;
|
||||
while (elem){
|
||||
if (l->del != NULL){
|
||||
l->del(mlistelem_dataptr(elem));
|
||||
}
|
||||
next = elem->next;
|
||||
free(elem);
|
||||
elem=next;
|
||||
}
|
||||
free(l);
|
||||
}
|
22
src/cw/mod.c
22
src/cw/mod.c
@ -31,7 +31,7 @@
|
||||
#include "log.h"
|
||||
#include "file.h"
|
||||
#include "cw.h"
|
||||
#include "cw/msget.h"
|
||||
#include "cw/msgset.h"
|
||||
|
||||
static void (*actions_registered_cb) (struct cw_Mod * capwap, struct cw_Mod * bindings,
|
||||
struct cw_actiondef * actions) = NULL;
|
||||
@ -178,9 +178,13 @@ static int mod_cmp_mlist(const void *e1, const void *e2){
|
||||
|
||||
|
||||
|
||||
static const char * mod_path="./";
|
||||
static const char * mod_path="";
|
||||
|
||||
void cw_mod_set_mod_path(const char * path){
|
||||
/**
|
||||
* @brief Set module path, where to search for modules
|
||||
* @param path Path to search
|
||||
*/
|
||||
void cw_mod_set_path(const char * path){
|
||||
mod_path = path;
|
||||
}
|
||||
|
||||
@ -209,11 +213,14 @@ struct cw_Mod * cw_mod_load(const char * mod_name){
|
||||
/* Search for the module in mods_loaded, to see if it is
|
||||
* already loaded or was statically linked */
|
||||
|
||||
cw_dbg(DBG_MOD,"MOD: Load module '%s'",mod_name);
|
||||
|
||||
memset(&search,0,sizeof(search));
|
||||
search.name=mod_name;
|
||||
|
||||
mod = mavl_find_ptr(mods_loaded,&search);
|
||||
if (mod){
|
||||
cw_dbg(DBG_MOD,"MOD: Module already loaded '%s'",mod_name);
|
||||
return mod;
|
||||
}
|
||||
|
||||
@ -232,6 +239,8 @@ struct cw_Mod * cw_mod_load(const char * mod_name){
|
||||
if (filename==NULL)
|
||||
return NULL;
|
||||
|
||||
cw_dbg(DBG_MOD, "MOD: loading module from file: %s", filename);
|
||||
|
||||
/* Open the DLL */
|
||||
handle = dlopen(filename,RTLD_NOW);
|
||||
|
||||
@ -256,7 +265,7 @@ struct cw_Mod * cw_mod_load(const char * mod_name){
|
||||
cw_log(LOG_ERR,"Can' add module %s",mod_name);
|
||||
goto errX;
|
||||
}
|
||||
|
||||
cw_dbg(DBG_MOD, "MOD: %s sucessfull loaded, calling init now.",filename);
|
||||
mod->init();
|
||||
errX:
|
||||
free(filename);
|
||||
@ -277,7 +286,6 @@ struct cw_Mod * cw_mod_add_to_list(struct cw_Mod * mod ){
|
||||
}
|
||||
|
||||
elem = mlist_append(mods_list,&mod);
|
||||
printf("Append mod %p\n",mod);
|
||||
if (elem == NULL)
|
||||
return NULL;
|
||||
return mlistelem_dataptr(elem);
|
||||
@ -297,11 +305,11 @@ struct cw_Mod * cw_mod_detect(struct conn *conn,
|
||||
|
||||
|
||||
mlist_foreach(e,mods_list){
|
||||
/// 1312
|
||||
/* /// 1312 */
|
||||
struct cw_Mod * mod = *(struct cw_Mod**)(mlistelem_dataptr(e)); /* = e->data;*/
|
||||
cw_dbg(DBG_MOD,"Checking mod: %s",mod->name);
|
||||
|
||||
printf("Got the mod %p\n",mod);
|
||||
/*printf("Got the mod %p\n",mod);*/
|
||||
/* if there is no detect method, skip */
|
||||
if (!mod->detect)
|
||||
continue;
|
||||
|
@ -36,7 +36,7 @@ struct cw_actiondef;
|
||||
|
||||
enum {
|
||||
CW_MOD_MODE_CAPWAP,
|
||||
MOD_MODE_BINDINGS
|
||||
CW_MOD_MODE_BINDINGS
|
||||
};
|
||||
|
||||
|
||||
@ -102,7 +102,7 @@ struct cw_Mod * cw_mod_detect(struct conn *conn,
|
||||
struct cw_MsgSet *cw_mod_get_msg_set(struct conn *conn,
|
||||
struct cw_Mod * capwap_mod, struct cw_Mod *bindings_mod);
|
||||
|
||||
void cw_mod_set_mod_path(const char * path);
|
||||
void cw_mod_set_path(const char * path);
|
||||
|
||||
#define CW_MOD_MAX_MOD_NAME_LEN 128
|
||||
#define CW_MOD_INTERFACE_FUNCTION_NAME_SUFFIX "_get_interface"
|
||||
|
@ -6,7 +6,8 @@
|
||||
#include "dbg.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "msget.h"
|
||||
#include "msgset.h"
|
||||
#include "ktv.h"
|
||||
|
||||
static int cmp_cw_elemhandler_by_id(const void *elem1, const void *elem2)
|
||||
{
|
||||
@ -129,6 +130,12 @@ struct cw_MsgSet *cw_msgset_create()
|
||||
cw_msgset_destroy(set);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
set->types_tree = cw_ktv_create_types_tree();
|
||||
if (set->types_tree == NULL){
|
||||
cw_msgset_destroy(set);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return set;
|
||||
}
|
||||
@ -149,6 +156,7 @@ static int update_msgdata(struct cw_MsgSet *set, struct cw_MsgData *msgdata,
|
||||
{
|
||||
struct cw_ElemDef *elemdef;
|
||||
struct cw_ElemData ed, *result;
|
||||
mavliter_t it;
|
||||
|
||||
/* iterate through all defined elements */
|
||||
for (elemdef = msgdef->elements; elemdef->id; elemdef++) {
|
||||
@ -164,6 +172,14 @@ static int update_msgdata(struct cw_MsgSet *set, struct cw_MsgData *msgdata,
|
||||
elemdef->proto, elemdef->vendor, elemdef->id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (handler->type != NULL){
|
||||
if (mavl_add_ptr( set->types_tree, handler->type ) == NULL){
|
||||
cw_log(LOG_ERR, "Can't add type from handler: %s", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ed.id = elemdef->id;
|
||||
ed.proto = elemdef->proto;
|
||||
@ -183,6 +199,27 @@ static int update_msgdata(struct cw_MsgSet *set, struct cw_MsgData *msgdata,
|
||||
}
|
||||
}
|
||||
|
||||
if (msgdata->mand_keys!=NULL){
|
||||
mlist_destroy(msgdata->mand_keys);
|
||||
}
|
||||
msgdata->mand_keys = mlist_create_conststr();
|
||||
|
||||
mavliter_init(&it,msgdata->elements_tree);
|
||||
mavliter_foreach(&it){
|
||||
struct cw_ElemHandler *handler;
|
||||
result = mavliter_get(&it);
|
||||
|
||||
handler = cw_msgset_get_elemhandler(set,
|
||||
result->proto,
|
||||
result->vendor, result->id);
|
||||
if (result->mand){
|
||||
mlist_append_ptr(msgdata->mand_keys,(void*)handler->key);
|
||||
cw_dbg(DBG_MOD," Add mandatory key: %s",handler->key);
|
||||
}
|
||||
/*//printf("Have Result %d %d - %s\n",result->id,result->mand, handler->key);*/
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -220,6 +257,7 @@ int cw_msgset_add(struct cw_MsgSet *set,
|
||||
if (!exists) {
|
||||
msg->elements_tree = mavl_create(cmp_elemdata, NULL,
|
||||
sizeof(struct cw_ElemData));
|
||||
msg->mand_keys=NULL;
|
||||
}
|
||||
|
||||
/* Overwrite the found message */
|
||||
@ -235,6 +273,18 @@ int cw_msgset_add(struct cw_MsgSet *set,
|
||||
|
||||
update_msgdata(set, msg, msgdef);
|
||||
}
|
||||
|
||||
{
|
||||
mavliter_t it;
|
||||
cw_dbg(DBG_MOD," Known types:");
|
||||
mavliter_init(&it,set->types_tree);
|
||||
mavliter_foreach(&it){
|
||||
struct cw_Type * t = mavliter_get_ptr(&it);
|
||||
cw_dbg(DBG_MOD, " Type: %s", t->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ struct cw_MsgSet {
|
||||
mavl_t msgdata;
|
||||
mavl_t handlers_by_id;
|
||||
mavl_t handlers_by_key;
|
||||
mavl_t types_tree;
|
||||
|
||||
};
|
||||
|
||||
@ -70,6 +71,7 @@ struct cw_MsgData{
|
||||
int receiver;
|
||||
mavl_t elements_tree;
|
||||
mlist_t elements_list;
|
||||
mlist_t mand_keys; /**< Keys of mandatory elements */
|
||||
};
|
||||
|
||||
|
@ -11,63 +11,6 @@
|
||||
|
||||
|
||||
|
||||
int conn_send_msg(struct conn * conn, uint8_t *rawmsg)
|
||||
{
|
||||
|
||||
int packetlen = cw_get_hdr_msg_total_len(rawmsg);
|
||||
|
||||
cw_dbg(DBG_X,"Here is a conn_send_msg for anything");
|
||||
|
||||
cw_dbg_msg(DBG_MSG_OUT, conn,rawmsg, packetlen,(struct sockaddr*)&conn->addr);
|
||||
|
||||
|
||||
/* Zyxel doesn't count msg element length from
|
||||
behind seqnum */
|
||||
if (conn->capwap_mode == CW_MODE_ZYXEL){
|
||||
// XXX val-=3;
|
||||
}
|
||||
|
||||
|
||||
uint8_t * ptr = rawmsg;
|
||||
|
||||
int fragoffset = 0;
|
||||
|
||||
int hlen = cw_get_hdr_hlen(rawmsg)*4;
|
||||
|
||||
int mtu = conn->mtu;
|
||||
|
||||
while (packetlen>mtu){
|
||||
cw_set_hdr_flags(rawmsg,CAPWAP_FLAG_HDR_F,1);
|
||||
cw_put_dword(ptr+4, conn->fragid<<16 | fragoffset<<3 );
|
||||
|
||||
cw_dbg_pkt(DBG_PKT_OUT,conn,ptr,mtu,(struct sockaddr*)&conn->addr);
|
||||
|
||||
if (conn->write(conn,ptr,mtu)<0)
|
||||
return -1;
|
||||
|
||||
// XXX Fragmentation stuff..
|
||||
ptr +=mtu-hlen;
|
||||
fragoffset+=(mtu-hlen)/8;
|
||||
|
||||
packetlen-=mtu-hlen;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (fragoffset)
|
||||
cw_set_hdr_flags(rawmsg,CAPWAP_FLAG_HDR_F | CAPWAP_FLAG_HDR_L,1);
|
||||
else
|
||||
cw_set_hdr_flags(rawmsg,CAPWAP_FLAG_HDR_F,0);
|
||||
|
||||
cw_put_dword(ptr+4, conn->fragid<<16 | fragoffset<<3 );
|
||||
|
||||
|
||||
cw_dbg_pkt(DBG_PKT_OUT,conn,ptr,packetlen,(struct sockaddr*)&conn->addr);
|
||||
|
||||
return conn->write(conn,ptr,packetlen-0);
|
||||
}
|
||||
|
||||
|
||||
int conn_send_data_msg(struct conn * conn, uint8_t *rawmsg,int len)
|
||||
{
|
||||
int packetlen = len;
|
||||
|
Reference in New Issue
Block a user