Digging deepter into VM concepts...
FossilOrigin-Name: ba6454642f17c0f87106cb6af12689457433d44ba1fe2dd1ef920dba7be2ef27
This commit is contained in:
parent
97a8506278
commit
0d9a3ad8c7
@ -35,7 +35,8 @@
|
|||||||
#include "socklist.h"
|
#include "socklist.h"
|
||||||
|
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
|
#include "capwap_items.h"
|
||||||
|
#include "capwap_cisco.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -53,11 +54,61 @@ void alive_thread(void *data)
|
|||||||
|
|
||||||
cw_actionlist_t the_tree;
|
cw_actionlist_t the_tree;
|
||||||
|
|
||||||
int dstart(struct conn *conn,struct cw_action a,uint8_t *data,int len)
|
int dstart(struct conn *conn,struct cw_action_t * a,uint8_t *data,int len)
|
||||||
{
|
{
|
||||||
printf("DISCO STart Action!!\n");
|
printf("DISCO STart Action!!\n");
|
||||||
|
|
||||||
|
uint8_t * rmac = cw_get_hdr_rmac(data);
|
||||||
|
printf ("This msg is for %s\n",sock_hwaddr2str(bstr_data(rmac), bstr_len(rmac)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int readelem_discovery_type(struct conn *conn,struct cw_action * a,uint8_t *data,int len)
|
||||||
|
{
|
||||||
|
printf("Discovery Type = %d\n",*data);
|
||||||
|
cw_itemstore_set_byte(conn->itemstore,CW_ITEM_DISCOVERY_TYPE,*data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int readelem_vendor_specific_payload(struct conn *conn,struct cw_action * a,uint8_t *data,int len)
|
||||||
|
{
|
||||||
|
cw_action_t as,*af;
|
||||||
|
as = *a;
|
||||||
|
|
||||||
|
as.vendor_id = cw_get_dword(data);
|
||||||
|
as.elem_id = cw_get_word(data+4);
|
||||||
|
printf("Vendor Specific: %d, %d\n",as.vendor_id,as.elem_id);
|
||||||
|
|
||||||
|
af = cw_actionlist_get(conn->msgtr,&as);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (!af) {
|
||||||
|
printf("Msg unknown\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Found\n");
|
||||||
|
|
||||||
|
if (af->start) {
|
||||||
|
af->start(conn,af,data+6,len-6);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int readelem_cisco_rad_name(struct conn *conn,struct cw_action * a,uint8_t *data,int len)
|
||||||
|
{
|
||||||
|
printf("Here is the rad name reader\n");
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; i<len; i++) {
|
||||||
|
printf("%c",data[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main (int argc, const char * argv[])
|
int main (int argc, const char * argv[])
|
||||||
@ -69,27 +120,38 @@ the_tree=t;
|
|||||||
|
|
||||||
|
|
||||||
cw_action_t discovery_actions[] = {
|
cw_action_t discovery_actions[] = {
|
||||||
{ CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST,-1,0,0,
|
{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST,-1,
|
||||||
dstart
|
dstart,0 },
|
||||||
},
|
|
||||||
{CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_DISCOVERY_TYPE},
|
{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_DISCOVERY_TYPE,
|
||||||
{CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_BOARD_DATA},
|
readelem_discovery_type,0 },
|
||||||
{CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_DESCRIPTOR},
|
|
||||||
{CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_FRAME_TUNNEL_MODE},
|
{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_VENDOR_SPECIFIC_PAYLOAD,
|
||||||
{CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_MAC_TYPE},
|
readelem_vendor_specific_payload,0 },
|
||||||
{0}
|
|
||||||
|
{ CW_VENDOR_ID_CISCO,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_CISCO_RAD_NAME,
|
||||||
|
readelem_cisco_rad_name,0 },
|
||||||
|
|
||||||
|
|
||||||
|
{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_BOARD_DATA},
|
||||||
|
{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_DESCRIPTOR},
|
||||||
|
{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_FRAME_TUNNEL_MODE},
|
||||||
|
{ 0,0,CW_STATE_DISCOVERY,CW_MSG_DISCOVERY_REQUEST, CW_ELEM_WTP_MAC_TYPE},
|
||||||
|
|
||||||
|
|
||||||
|
{ 0,0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cw_action_t join_actions[] = {
|
cw_action_t join_actions[] = {
|
||||||
|
|
||||||
{CW_STATE_JOIN,CW_MSG_JOIN_REQUEST,-1,0,0},
|
{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST,-1,0,0},
|
||||||
{CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_DISCOVERY_TYPE},
|
{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_DISCOVERY_TYPE},
|
||||||
{CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_BOARD_DATA},
|
{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_BOARD_DATA},
|
||||||
{CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_DESCRIPTOR},
|
{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_DESCRIPTOR},
|
||||||
{CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_FRAME_TUNNEL_MODE},
|
{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_FRAME_TUNNEL_MODE},
|
||||||
{CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_MAC_TYPE},
|
{0,0,CW_STATE_JOIN,CW_MSG_JOIN_REQUEST, CW_ELEM_WTP_MAC_TYPE},
|
||||||
{0}
|
{0}
|
||||||
|
|
||||||
|
|
||||||
|
@ -356,15 +356,32 @@ static void wtpman_run_discovery(void *arg)
|
|||||||
struct wtpman * wtpman = (struct wtpman *)arg;
|
struct wtpman * wtpman = (struct wtpman *)arg;
|
||||||
struct cwrmsg * cwrmsg;
|
struct cwrmsg * cwrmsg;
|
||||||
|
|
||||||
|
void conn_msg_processor(struct conn *conn);
|
||||||
|
|
||||||
|
time_t timer = cw_timer_start(10);
|
||||||
|
|
||||||
extern cw_actionlist_t the_tree;
|
extern cw_actionlist_t the_tree;
|
||||||
wtpman->conn->capwap_state=CW_STATE_DISCOVERY;
|
wtpman->conn->capwap_state=CW_STATE_DISCOVERY;
|
||||||
wtpman->conn->msgtr=the_tree;
|
wtpman->conn->msgtr=the_tree;
|
||||||
|
|
||||||
|
wtpman->conn->itemstore = cw_itemstore_create();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
time_t timer = cw_timer_start(10);
|
while ( !cw_timer_timeout(timer) && wtpman->conn->capwap_state==CW_STATE_DISCOVERY){
|
||||||
|
conn_msg_processor(wtpman->conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cwsend_discovery_response(wtpman->conn,cwrmsg->seqnum,&radioinfo,acinfo,&wtpman->wtpinfo);
|
||||||
|
wtpman_remove(wtpman);
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
timer = cw_timer_start(10);
|
||||||
cwrmsg = wtpman_wait_for_message(wtpman, timer);
|
cwrmsg = wtpman_wait_for_message(wtpman, timer);
|
||||||
|
|
||||||
if ( !cwrmsg )
|
if ( !cwrmsg )
|
||||||
@ -415,8 +432,6 @@ wtpman->conn->msgtr=the_tree;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
cwsend_discovery_response(wtpman->conn,cwrmsg->seqnum,&radioinfo,acinfo,&wtpman->wtpinfo);
|
cwsend_discovery_response(wtpman->conn,cwrmsg->seqnum,&radioinfo,acinfo,&wtpman->wtpinfo);
|
||||||
|
|
||||||
|
|
||||||
wtpman_remove(wtpman);
|
wtpman_remove(wtpman);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,7 +160,11 @@ CAPWAPOBJS= \
|
|||||||
cw_readmsg_configuration_status_request.o \
|
cw_readmsg_configuration_status_request.o \
|
||||||
cw_cisco_id_to_str.o\
|
cw_cisco_id_to_str.o\
|
||||||
cw_readelem_cisco_wtp_radio_cfg.o \
|
cw_readelem_cisco_wtp_radio_cfg.o \
|
||||||
cw_addelem_cisco_wtp_radio_cfg.o
|
cw_addelem_cisco_wtp_radio_cfg.o \
|
||||||
|
cw_strlist_get_str.o \
|
||||||
|
capwap_msg_strings.o \
|
||||||
|
capwap_state_strings.o \
|
||||||
|
itemstore.o
|
||||||
|
|
||||||
|
|
||||||
#cw_ianavendoridtostr.o \
|
#cw_ianavendoridtostr.o \
|
||||||
|
@ -63,8 +63,10 @@ enum capwap_states {
|
|||||||
CW_STATE_NONE=0,
|
CW_STATE_NONE=0,
|
||||||
CW_STATE_DISCOVERY,
|
CW_STATE_DISCOVERY,
|
||||||
CW_STATE_JOIN,
|
CW_STATE_JOIN,
|
||||||
|
CW_STATE_CONFIGURE,
|
||||||
|
CW_STATE_IMAGE,
|
||||||
CW_STATE_UPDATE,
|
CW_STATE_UPDATE,
|
||||||
CW_STATE_RUN,
|
CW_STATE_RUN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -122,8 +124,8 @@ struct capwap_ctrlhdr
|
|||||||
#define CW_MSG_CONFIGURATION_UPDATE_REQUEST 7
|
#define CW_MSG_CONFIGURATION_UPDATE_REQUEST 7
|
||||||
#define CW_MSG_CONFIGURATION_UPDATE_RESPONSE 8
|
#define CW_MSG_CONFIGURATION_UPDATE_RESPONSE 8
|
||||||
|
|
||||||
#define CWMSG_WTP_EVENT_REQUEST 9
|
#define CW_MSG_WTP_EVENT_REQUEST 9
|
||||||
#define CWMSG_WTP_EVENT_RESPONSE 10
|
#define CW_MSG_WTP_EVENT_RESPONSE 10
|
||||||
|
|
||||||
#define CW_MSG_CHANGE_STATE_EVENT_REQUEST 11
|
#define CW_MSG_CHANGE_STATE_EVENT_REQUEST 11
|
||||||
#define CW_MSG_CHANGE_STATE_EVENT_RESPONSE 12
|
#define CW_MSG_CHANGE_STATE_EVENT_RESPONSE 12
|
||||||
@ -137,8 +139,8 @@ struct capwap_ctrlhdr
|
|||||||
#define CW_MSG_RESET_REQUEST 17
|
#define CW_MSG_RESET_REQUEST 17
|
||||||
#define CW_MSG_RESET_RESPONSE 18
|
#define CW_MSG_RESET_RESPONSE 18
|
||||||
|
|
||||||
#define CWMSG_PRIMARY_DISCOVERY_REQUEST 19
|
#define CW_MSG_PRIMARY_DISCOVERY_REQUEST 19
|
||||||
#define CWMSG_PRIMARY_DISCOVERY_RESPONSE 20
|
#define CW_MSG_PRIMARY_DISCOVERY_RESPONSE 20
|
||||||
|
|
||||||
/* Data Transfer Request 21
|
/* Data Transfer Request 21
|
||||||
Data Transfer Response 22
|
Data Transfer Response 22
|
||||||
@ -503,6 +505,9 @@ extern int cw_readmsg_configuration_update_request(uint8_t *elems,int elems_len)
|
|||||||
#define cw_get_hdr_hlen(th) ((ntohl(((uint32_t*)th)[0]) >> 19) & 0x1f)
|
#define cw_get_hdr_hlen(th) ((ntohl(((uint32_t*)th)[0]) >> 19) & 0x1f)
|
||||||
|
|
||||||
#define cw_get_hdr_rmac(th) (th+8)
|
#define cw_get_hdr_rmac(th) (th+8)
|
||||||
|
#define cw_get_hdr_rmac_len(th) (*(th+8))
|
||||||
|
#define cw_get_hdr_rmac_size(th) cw_get_hdr_rmac_len(th)
|
||||||
|
#define cw_get_hdr_rmac_data(th) (th+9)
|
||||||
|
|
||||||
#define cw_get_hdr_flag_r1(th) ((ntohl( *((uint32_t*)th)) & CWTH_FLAGS_R1 ) ? 1:0)
|
#define cw_get_hdr_flag_r1(th) ((ntohl( *((uint32_t*)th)) & CWTH_FLAGS_R1 ) ? 1:0)
|
||||||
#define cw_get_hdr_flag_r2(th) ((ntohl( *((uint32_t*)th)) & CWTH_FLAGS_R2 ) ? 1:0)
|
#define cw_get_hdr_flag_r2(th) ((ntohl( *((uint32_t*)th)) & CWTH_FLAGS_R2 ) ? 1:0)
|
||||||
@ -524,6 +529,10 @@ extern int cw_readmsg_configuration_update_request(uint8_t *elems,int elems_len)
|
|||||||
#define cw_get_msg_elems_len(msgptr) ( cw_get_word( (msgptr) +5 )-3)
|
#define cw_get_msg_elems_len(msgptr) ( cw_get_word( (msgptr) +5 )-3)
|
||||||
#define cw_get_msg_elems_ptr(msgptr) ((msgptr)+8)
|
#define cw_get_msg_elems_ptr(msgptr) ((msgptr)+8)
|
||||||
|
|
||||||
|
static inline uint8_t * cw_get_hdr_msg_elems_ptr(uint8_t *m){
|
||||||
|
return cw_get_msg_elems_ptr( m+cw_get_hdr_msg_offset(m) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get length of a CAPWAP message elemet
|
* Get length of a CAPWAP message elemet
|
||||||
* @param e pointer to element (uint8_t*)
|
* @param e pointer to element (uint8_t*)
|
||||||
@ -540,7 +549,7 @@ extern int cw_readmsg_configuration_update_request(uint8_t *elems,int elems_len)
|
|||||||
#define cw_get_elem_len(e) cw_get_word(e+2)
|
#define cw_get_elem_len(e) cw_get_word(e+2)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a pinter to the data of a CAPWAP message element
|
* Get a pointer to the data of a CAPWAP message element
|
||||||
* @param e pointer to message element
|
* @param e pointer to message element
|
||||||
* @return pointer to data
|
* @return pointer to data
|
||||||
*/
|
*/
|
||||||
@ -688,4 +697,25 @@ extern int cw_send_configuration_update_response(struct conn * conn,int seqnum,s
|
|||||||
#define cwmsg_addelem_radio_operational_state(cwmsg,ri) \
|
#define cwmsg_addelem_radio_operational_state(cwmsg,ri) \
|
||||||
(cwmsg)->pos+=cw_addelem_radio_operational_state((cwmsg)->msgelems+(cwmsg)->pos,ri)
|
(cwmsg)->pos+=cw_addelem_radio_operational_state((cwmsg)->msgelems+(cwmsg)->pos,ri)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Message to text stuff */
|
||||||
|
|
||||||
|
struct cw_strlist {
|
||||||
|
uint32_t id;
|
||||||
|
const char * str;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const char * cw_strlist_get_str(struct cw_strlist *s,int id);
|
||||||
|
|
||||||
|
|
||||||
|
extern struct cw_strlist capwap_msg_strings[];
|
||||||
|
extern struct cw_strlist capwap_state_strings[];
|
||||||
|
|
||||||
|
#define cw_strmsg(id) cw_strlist_get_str(capwap_msg_strings,id)
|
||||||
|
#define cw_strstate(id) cw_strlist_get_str(capwap_state_strings,id)
|
||||||
|
|
||||||
|
|
||||||
|
int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -33,20 +33,25 @@
|
|||||||
|
|
||||||
#include "cw_action.h"
|
#include "cw_action.h"
|
||||||
|
|
||||||
struct conn{
|
#include "itemstore.h"
|
||||||
|
|
||||||
|
struct conn {
|
||||||
int sock;
|
int sock;
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
int recv_timeout;
|
int recv_timeout;
|
||||||
|
|
||||||
cw_actionlist_t msgtr;
|
cw_itemstore_t itemstore;
|
||||||
|
|
||||||
|
|
||||||
|
struct avltree *msgtr;
|
||||||
|
|
||||||
uint8_t capwap_state;
|
uint8_t capwap_state;
|
||||||
|
|
||||||
FRAGMAN * fragman;
|
FRAGMAN *fragman;
|
||||||
// void (* process_message)(void *,uint8_t *,uint8_t *, int);
|
// void (* process_message)(void *,uint8_t *,uint8_t *, int);
|
||||||
|
|
||||||
// void (* process_message)(void *,struct cwrmsg *); //uint8_t *,uint8_t *, int);
|
// void (* process_message)(void *,struct cwrmsg *); //uint8_t *,uint8_t *, int);
|
||||||
// void * pmsgarg;
|
// void * pmsgarg;
|
||||||
|
|
||||||
int fragid;
|
int fragid;
|
||||||
|
|
||||||
@ -55,10 +60,10 @@ struct conn{
|
|||||||
int last_seqnum_received;
|
int last_seqnum_received;
|
||||||
int last_message_id_received;
|
int last_message_id_received;
|
||||||
|
|
||||||
// struct cwmsg * last_response;
|
// struct cwmsg * last_response;
|
||||||
// struct cwmsg swm;
|
// struct cwmsg swm;
|
||||||
// int last_response_seqnum;
|
// int last_response_seqnum;
|
||||||
// int last_response_rid;
|
// int last_response_rid;
|
||||||
|
|
||||||
struct cwrmsg cwrmsg;
|
struct cwrmsg cwrmsg;
|
||||||
uint8_t cwrmsg_buffer[65536];
|
uint8_t cwrmsg_buffer[65536];
|
||||||
@ -75,36 +80,36 @@ struct conn{
|
|||||||
|
|
||||||
/* receive and send methods */
|
/* receive and send methods */
|
||||||
|
|
||||||
int (*recv_packet)(struct conn *, uint8_t *,int);
|
int (*recv_packet) (struct conn *, uint8_t *, int);
|
||||||
int (*recv_packet_peek)(struct conn *, uint8_t *,int);
|
int (*recv_packet_peek) (struct conn *, uint8_t *, int);
|
||||||
int (*send_packet)(struct conn *, const uint8_t *, int);
|
int (*send_packet) (struct conn *, const uint8_t *, int);
|
||||||
|
|
||||||
int (*read)(struct conn *, uint8_t*, int);
|
int (*read) (struct conn *, uint8_t *, int);
|
||||||
int (*write)(struct conn *, const uint8_t*, int);
|
int (*write) (struct conn *, const uint8_t *, int);
|
||||||
|
|
||||||
/* optional packet queue */
|
/* optional packet queue */
|
||||||
uint8_t ** q;
|
uint8_t **q;
|
||||||
int qsize;
|
int qsize;
|
||||||
int qrpos;
|
int qrpos;
|
||||||
int qwpos;
|
int qwpos;
|
||||||
sem_t q_sem;
|
sem_t q_sem;
|
||||||
uint8_t * cur_packet;
|
uint8_t *cur_packet;
|
||||||
int cur_packet_len;
|
int cur_packet_len;
|
||||||
int cur_packet_pos;
|
int cur_packet_pos;
|
||||||
|
|
||||||
/* dtls stuff */
|
/* dtls stuff */
|
||||||
int (*dtls_start)(struct conn*);
|
int (*dtls_start) (struct conn *);
|
||||||
int (*dtls_accept)(struct conn*);
|
int (*dtls_accept) (struct conn *);
|
||||||
|
|
||||||
char * dtls_psk;
|
char *dtls_psk;
|
||||||
int dtls_psk_len;
|
int dtls_psk_len;
|
||||||
|
|
||||||
char * dtls_cert_file;
|
char *dtls_cert_file;
|
||||||
char * dtls_key_file;
|
char *dtls_key_file;
|
||||||
char * dtls_key_pass;
|
char *dtls_key_pass;
|
||||||
|
|
||||||
void * dtls_data;
|
void *dtls_data;
|
||||||
char * dtls_cipher;
|
char *dtls_cipher;
|
||||||
int dtls_error;
|
int dtls_error;
|
||||||
uint8_t dtls_cookie[8];
|
uint8_t dtls_cookie[8];
|
||||||
int dtls_verify_peer;
|
int dtls_verify_peer;
|
||||||
@ -122,7 +127,7 @@ struct conn{
|
|||||||
|
|
||||||
|
|
||||||
/* used to link the conn obj with other objects */
|
/* used to link the conn obj with other objects */
|
||||||
void * data;
|
void *data;
|
||||||
|
|
||||||
/* misc */
|
/* misc */
|
||||||
int capwap_mode;
|
int capwap_mode;
|
||||||
@ -130,8 +135,8 @@ struct conn{
|
|||||||
int strict_capwap;
|
int strict_capwap;
|
||||||
|
|
||||||
|
|
||||||
int (*request_handler) (void*);
|
int (*request_handler) (void *);
|
||||||
void * request_handler_param;
|
void *request_handler_param;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -140,26 +145,28 @@ struct conn{
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct conn * conn_create(int sock, struct sockaddr * addr, int qsize);
|
struct conn *conn_create(int sock, struct sockaddr *addr, int qsize);
|
||||||
struct conn * conn_create_noq(int sock, struct sockaddr * addr);
|
struct conn *conn_create_noq(int sock, struct sockaddr *addr);
|
||||||
|
|
||||||
|
|
||||||
extern int conn_send_cwmsg(struct conn * conn, struct cwmsg * cwmsg);
|
extern int conn_send_cwmsg(struct conn *conn, struct cwmsg *cwmsg);
|
||||||
extern void conn_process_packet(struct conn * conn, uint8_t *packet, int len,int(*cb)(void*,struct cwrmsg*),void *cbarg);
|
extern void conn_process_packet(struct conn *conn, uint8_t * packet, int len,
|
||||||
extern struct cwrmsg * conn_get_message(struct conn * conn);
|
int (*cb) (void *, uint8_t *,int len), void *cbarg);
|
||||||
|
|
||||||
extern int conn_send_packet(struct conn * conn,const uint8_t * buffer, int len);
|
extern uint8_t *conn_get_message(struct conn *conn);
|
||||||
extern void conn_destroy(struct conn * conn);
|
|
||||||
|
|
||||||
uint8_t * conn_q_get_packet(struct conn * conn);
|
extern int conn_send_packet(struct conn *conn, const uint8_t * buffer, int len);
|
||||||
extern int conn_q_recv_packet(struct conn * conn, uint8_t * buffer,int len);
|
extern void conn_destroy(struct conn *conn);
|
||||||
extern int conn_q_recv_packet_peek(struct conn * conn, uint8_t * buffer,int len);
|
|
||||||
|
|
||||||
extern int conn_recv_packet(struct conn* conn,uint8_t *buf,int len);
|
uint8_t *conn_q_get_packet(struct conn *conn);
|
||||||
extern int conn_recv_packet_peek(struct conn* conn,uint8_t *buf,int len);
|
extern int conn_q_recv_packet(struct conn *conn, uint8_t * buffer, int len);
|
||||||
|
extern int conn_q_recv_packet_peek(struct conn *conn, uint8_t * buffer, int len);
|
||||||
|
|
||||||
extern int conn_send_response(struct conn * conn,struct cwmsg * cwmsg,int seqnum);
|
extern int conn_recv_packet(struct conn *conn, uint8_t * buf, int len);
|
||||||
extern struct cwrmsg * conn_get_response(struct conn * conn);
|
extern int conn_recv_packet_peek(struct conn *conn, uint8_t * buf, int len);
|
||||||
|
|
||||||
|
extern int conn_send_response(struct conn *conn, struct cwmsg *cwmsg, int seqnum);
|
||||||
|
extern struct cwrmsg *conn_get_response(struct conn *conn);
|
||||||
|
|
||||||
|
|
||||||
#define conn_get_next_seqnum(conn) (conn->seqnum=((conn->seqnum+1)&0xff))
|
#define conn_get_next_seqnum(conn) (conn->seqnum=((conn->seqnum+1)&0xff))
|
||||||
@ -171,38 +178,38 @@ extern struct cwrmsg * conn_get_response(struct conn * conn);
|
|||||||
struct connlist {
|
struct connlist {
|
||||||
/* struct conn ** connlist; */
|
/* struct conn ** connlist; */
|
||||||
|
|
||||||
struct avltree * t;
|
struct avltree *t;
|
||||||
int len;
|
int len;
|
||||||
pthread_mutex_t connlist_mutex;
|
pthread_mutex_t connlist_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct connlist * connlist_create(int len);
|
struct connlist *connlist_create(int len);
|
||||||
void connlist_lock(struct connlist * cl);
|
void connlist_lock(struct connlist *cl);
|
||||||
void connlist_unlock(struct connlist * cl);
|
void connlist_unlock(struct connlist *cl);
|
||||||
void conlist_destroy(struct connlist * cl);
|
void conlist_destroy(struct connlist *cl);
|
||||||
struct conn * connlist_get(struct connlist * cl, const struct sockaddr * addr);
|
struct conn *connlist_get(struct connlist *cl, const struct sockaddr *addr);
|
||||||
struct conn * connlist_add(struct connlist * cl, struct conn * conn);
|
struct conn *connlist_add(struct connlist *cl, struct conn *conn);
|
||||||
void connlist_remove(struct connlist *cl,struct conn * conn);
|
void connlist_remove(struct connlist *cl, struct conn *conn);
|
||||||
void connlist_destroy(struct connlist * cl);
|
void connlist_destroy(struct connlist *cl);
|
||||||
void conn_q_add_packet(struct conn * conn,uint8_t *packet,int len);
|
void conn_q_add_packet(struct conn *conn, uint8_t * packet, int len);
|
||||||
|
|
||||||
struct image_identifier;
|
struct image_identifier;
|
||||||
struct cwimage_data;
|
struct cwimage_data;
|
||||||
|
|
||||||
extern void conn_prepare_request(struct conn * conn, int type);
|
extern void conn_prepare_request(struct conn *conn, int type);
|
||||||
extern int conn_prepare_image_data_request(struct conn * conn, struct cwimage_data *, struct image_identifier *id );
|
extern int conn_prepare_image_data_request(struct conn *conn, struct cwimage_data *,
|
||||||
extern void conn_detect_capwap(struct conn * conn, struct wtpinfo * wtpinfo);
|
struct image_identifier *id);
|
||||||
struct cwrmsg * conn_send_request(struct conn * conn);
|
extern void conn_detect_capwap(struct conn *conn, struct wtpinfo *wtpinfo);
|
||||||
struct cwrmsg * conn_wait_for_message(struct conn * conn, time_t timer);
|
struct cwrmsg *conn_send_request(struct conn *conn);
|
||||||
|
struct cwrmsg *conn_wait_for_message(struct conn *conn, time_t timer);
|
||||||
|
|
||||||
struct cwrmsg * conn_wait_for_request(struct conn * conn, int *msglist, time_t timer);
|
struct cwrmsg *conn_wait_for_request(struct conn *conn, int *msglist, time_t timer);
|
||||||
|
|
||||||
|
|
||||||
#define conn_is_error(conn) (conn->dtls_error)
|
#define conn_is_error(conn) (conn->dtls_error)
|
||||||
|
|
||||||
void conn_init(struct conn * conn);
|
void conn_init(struct conn *conn);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __CONLIST_H */
|
#endif /* __CONLIST_H */
|
||||||
|
|
||||||
|
@ -16,25 +16,37 @@ struct args {
|
|||||||
struct cwrmsg *cwrmsg;
|
struct cwrmsg *cwrmsg;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int pmessage(void *p, struct cwrmsg *cwrmsg)
|
static int message_cb(void *p, uint8_t *rawmsg, int len)
|
||||||
{
|
{
|
||||||
struct args *args = (struct args *) p;
|
struct args *args = (struct args *) p;
|
||||||
struct conn *conn = args->conn;
|
struct conn *conn = args->conn;
|
||||||
|
memcpy(conn->cwrmsg_buffer, rawmsg, len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
memcpy(&conn->cwrmsg, cwrmsg, sizeof(struct cwrmsg));
|
memcpy(&conn->cwrmsg, cwrmsg, sizeof(struct cwrmsg));
|
||||||
memcpy(conn->cwrmsg_buffer, cwrmsg->msgelems,
|
|
||||||
cwrmsg->msgelems_len);
|
|
||||||
conn->cwrmsg.msgelems = conn->cwrmsg_buffer;
|
conn->cwrmsg.msgelems = conn->cwrmsg_buffer;
|
||||||
|
*/
|
||||||
args->cwrmsg = &conn->cwrmsg;
|
args->cwrmsg = &conn->cwrmsg;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void conn_msg_processor(struct conn *conn)
|
||||||
|
{
|
||||||
|
uint8_t buf[2024];
|
||||||
|
int len = 2024;
|
||||||
|
|
||||||
|
int n = conn->read(conn, buf, len);
|
||||||
|
if (n > 0)
|
||||||
|
conn_process_packet(conn, buf, n, cw_process_msg, conn);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct cwrmsg *conn_get_message(struct conn *conn)
|
|
||||||
|
|
||||||
|
uint8_t *conn_get_message(struct conn *conn)
|
||||||
{
|
{
|
||||||
struct args args;
|
struct args args;
|
||||||
args.cwrmsg = 0;
|
args.cwrmsg = 0;
|
||||||
@ -44,18 +56,20 @@ struct cwrmsg *conn_get_message(struct conn *conn)
|
|||||||
|
|
||||||
int n = conn->read(conn, buf, len);
|
int n = conn->read(conn, buf, len);
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
conn_process_packet(conn, buf, n, pmessage, &args);
|
conn_process_packet(conn, buf, n, message_cb, &args);
|
||||||
|
|
||||||
|
|
||||||
if (args.cwrmsg) {
|
if (args.cwrmsg) {
|
||||||
|
cw_dbg(DBG_MSG,"Message recieved from %s",sock_addr2str(&conn->addr));
|
||||||
|
/*
|
||||||
cw_dbg(DBG_MSG,
|
cw_dbg(DBG_MSG,
|
||||||
"Received message from %s, type=%d - %s, seq=%d",
|
"Received message from %s, type=%d - %s, seq=%d",
|
||||||
sock_addr2str(&conn->addr), args.cwrmsg->type,
|
sock_addr2str(&conn->addr), args.cwrmsg->type,
|
||||||
cw_msgtostr(args.cwrmsg->type),
|
cw_msgtostr(args.cwrmsg->type),
|
||||||
args.cwrmsg->seqnum);
|
args.cwrmsg->seqnum);
|
||||||
|
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
return args.cwrmsg;
|
return conn->cwrmsg_buffer;
|
||||||
}
|
}
|
||||||
|
@ -34,11 +34,11 @@ struct cwrmsg * conn_get_response(struct conn * conn)
|
|||||||
if (conn->dtls_error)
|
if (conn->dtls_error)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"Retransmitting message, type=%d,seq=%d",cwmsg->type,cwmsg->seqnum);
|
cw_dbg(DBG_MSG_ERR,"Retransmitting message, type=%d,seq=%d",cwmsg->type,cwmsg->seqnum);
|
||||||
conn_send_cwmsg(conn,&conn->req_msg);
|
conn_send_cwmsg(conn,&conn->req_msg);
|
||||||
|
|
||||||
}
|
}
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"Max retransmit's reached, message type=%d,seq=%d",cwmsg->type,cwmsg->seqnum);
|
cw_dbg(DBG_MSG_ERR,"Max retransmit's reached, message type=%d,seq=%d",cwmsg->type,cwmsg->seqnum);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -74,31 +74,38 @@ static int cwrmsg_init_ctrlhdr(struct conn * conn, struct cwrmsg * cwrmsg, uint8
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int process_message(struct conn * conn,struct cwrmsg *cwrmsg,int (*cb)(void*,struct cwrmsg *),void *cbarg)
|
static int process_message(struct conn * conn,uint8_t *rawmsg,int rawlen,int (*cb)(void*,uint8_t *,int),void *cbarg)
|
||||||
{
|
{
|
||||||
if (!(cwrmsg->type & 0x1)) {
|
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. */
|
/* It's a response message, no further examination required. */
|
||||||
cb(cbarg,cwrmsg);
|
cb(cbarg,rawmsg,rawlen);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* It's a request message, check if seqnum is right and if
|
/* It's a request message, check if seqnum is right and if
|
||||||
* we have already sent a response message*/
|
* we have already sent a response message*/
|
||||||
|
|
||||||
|
uint8_t seqnum = cw_get_msg_seqnum(msgptr);
|
||||||
|
|
||||||
int s1=conn->last_seqnum_received;
|
int s1=conn->last_seqnum_received;
|
||||||
int s2=cwrmsg->seqnum;
|
int s2=seqnum;
|
||||||
int sd=s2-s1;
|
int sd=s2-s1;
|
||||||
|
|
||||||
if ((sd>0 && sd<128) || (sd<0 && sd<-128) || s1<0){
|
if ((sd>0 && sd<128) || (sd<0 && sd<-128) || s1<0){
|
||||||
/* seqnum is ok, normal message processing */
|
/* seqnum is ok, normal message processing */
|
||||||
conn->last_seqnum_received=cwrmsg->seqnum;
|
conn->last_seqnum_received=seqnum;
|
||||||
cb(cbarg,cwrmsg);
|
cb(cbarg,rawmsg,rawlen);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sd != 0)
|
if (sd != 0)
|
||||||
{
|
{
|
||||||
cw_dbg(DBG_CW_MSG_ERR,
|
cw_dbg(DBG_MSG_ERR,
|
||||||
"Discarding message from %s, old seqnum, seqnum = %d, last seqnum=%d",
|
"Discarding message from %s, old seqnum, seqnum = %d, last seqnum=%d",
|
||||||
sock_addr2str(&conn->addr),s2,s1);
|
sock_addr2str(&conn->addr),s2,s1);
|
||||||
|
|
||||||
@ -108,15 +115,15 @@ static int process_message(struct conn * conn,struct cwrmsg *cwrmsg,int (*cb)(vo
|
|||||||
/* the received request message was retransmitte by our peer,
|
/* the received request message was retransmitte by our peer,
|
||||||
* let's retransmit our response message if we have one*/
|
* let's retransmit our response message if we have one*/
|
||||||
|
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"Retransmitted request message from %s detected, seqnum=%d, type=%d",
|
cw_dbg(DBG_MSG_ERR,"Retransmitted request message from %s detected, seqnum=%d, type=%d",
|
||||||
sock_addr2str(&conn->addr),s2,cwrmsg->type);
|
sock_addr2str(&conn->addr),s2,type);
|
||||||
|
|
||||||
if (conn->resp_msg.type-1 != cwrmsg->type ){
|
if (conn->resp_msg.type-1 != type ){
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"No cached response for retransmission, request seqnum=%d,in cache=%d",s2,conn->resp_msg.type );
|
cw_dbg(DBG_MSG_ERR,"No cached response for retransmission, request seqnum=%d,in cache=%d",s2,conn->resp_msg.type );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"Retransmitting response message to %s, seqnum=%d",
|
cw_dbg(DBG_MSG_ERR,"Retransmitting response message to %s, seqnum=%d",
|
||||||
sock_addr2str(&conn->addr),s2);
|
sock_addr2str(&conn->addr),s2);
|
||||||
conn_send_cwmsg(conn,&conn->resp_msg);
|
conn_send_cwmsg(conn,&conn->resp_msg);
|
||||||
return 1;
|
return 1;
|
||||||
@ -154,72 +161,68 @@ static void cw_dbg_packet(struct conn * conn, uint8_t * packet, int len)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void conn_process_packet(struct conn * conn, uint8_t *packet, int len,int (*cb)(void*,struct cwrmsg*),void *cbarg)
|
void conn_process_packet(struct conn * conn, uint8_t *packet, int len,int (*cb)(void*,uint8_t *,int),void *cbarg)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (len<8){
|
if (len<8){
|
||||||
/* packet too short */
|
/* packet too short */
|
||||||
cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, packet too short, len=%d",sock_addr2str(&conn->addr),len);
|
cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, packet too short, len=%d",sock_addr2str(&conn->addr),len);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t val = ntohl(*((uint32_t*)packet));
|
int preamble = cw_get_hdr_preamble(packet);
|
||||||
|
|
||||||
int preamble = val >> 24;
|
|
||||||
if ( (preamble & 0xf0) != CW_VERSION){
|
if ( (preamble & 0xf0) != CW_VERSION){
|
||||||
/* wrong version */
|
/* wrong version */
|
||||||
cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, wrong version, version=%d",sock_addr2str(&conn->addr),(preamble&0xf0)>>8);
|
cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, wrong version, version=%d",sock_addr2str(&conn->addr),(preamble&0xf0)>>8);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (preamble & 0xf ) {
|
if (preamble & 0xf ) {
|
||||||
/* decode dtls */
|
/* decode dtls */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* log this packet */
|
||||||
cw_dbg_packet(conn,packet,len);
|
cw_dbg_packet(conn,packet,len);
|
||||||
|
|
||||||
|
|
||||||
int hlen = 4*((val >> 19) & 0x1f);
|
int offs = cw_get_hdr_msg_offset(packet);
|
||||||
|
|
||||||
|
|
||||||
int payloadlen = len - hlen;
|
int payloadlen = len - offs;
|
||||||
if (payloadlen<0){
|
if (payloadlen<0){
|
||||||
cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, hlen greater than len, hlen=%d",sock_addr2str(&conn->addr),hlen);
|
cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, header length greater than len, hlen=%d",sock_addr2str(&conn->addr),offs);
|
||||||
/* EINVAL */
|
/* EINVAL */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
struct cwrmsg cwrmsg;
|
struct cwrmsg cwrmsg;
|
||||||
cwrmsg.wbid=(val>>9) & 0x1f;
|
cwrmsg.wbid=(val>>9) & 0x1f;
|
||||||
cwrmsg.rid=(val>>14) & 0x1f;
|
cwrmsg.rid=(val>>14) & 0x1f;
|
||||||
|
*/
|
||||||
|
|
||||||
|
printf ("Offs is %d RML is %d\n",offs,cw_get_hdr_rmac_len(packet));
|
||||||
|
|
||||||
|
/* Check Radio MAC if preset */
|
||||||
|
if (cw_get_hdr_flag_m(packet)){
|
||||||
|
|
||||||
if (val & CWTH_FLAGS_M){
|
if (cw_get_hdr_rmac_len(packet)+8>offs){
|
||||||
|
|
||||||
if (*(packet+8)+8>hlen){
|
|
||||||
/* wrong rmac size */
|
/* wrong rmac size */
|
||||||
cw_dbg(DBG_CW_PKT_ERR,"Discarding packet, wrong rmac size, size=%d",*(packet+8));
|
cw_dbg(DBG_CW_PKT_ERR,"Discarding packet, wrong R-MAC size, size=%d",*(packet+8));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(cwrmsg.rmac, packet+8,8);
|
// memcpy(cwrmsg.rmac, packet+8,8);
|
||||||
}
|
|
||||||
else{
|
|
||||||
cwrmsg.rmac[0]=0;
|
|
||||||
}
|
}
|
||||||
|
// else{
|
||||||
|
// cwrmsg.rmac[0]=0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
if (val & CWTH_FLAGS_F){ /* fragmented */
|
if (cw_get_hdr_flag_f(packet)){ /* fragmented */
|
||||||
uint8_t * f;
|
uint8_t * f;
|
||||||
f = fragman_add(conn->fragman, packet,hlen,payloadlen);
|
f = fragman_add(conn->fragman, packet,offs,payloadlen);
|
||||||
if (f==NULL)
|
if (f==NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -229,12 +232,17 @@ void conn_process_packet(struct conn * conn, uint8_t *packet, int len,int (*cb)(
|
|||||||
extern int cw_process_msg(struct conn * conn,uint8_t*msg,int len);
|
extern int cw_process_msg(struct conn * conn,uint8_t*msg,int len);
|
||||||
cw_process_msg(conn,f+4,*(uint32_t*)f);
|
cw_process_msg(conn,f+4,*(uint32_t*)f);
|
||||||
|
|
||||||
|
printf("Received a fragmented packetm should process it");
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
/*
|
||||||
if (!cwrmsg_init_ctrlhdr(conn,&cwrmsg,f+4,*(uint32_t*)f)){
|
if (!cwrmsg_init_ctrlhdr(conn,&cwrmsg,f+4,*(uint32_t*)f)){
|
||||||
free(f);
|
free(f);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
process_message(conn,&cwrmsg,cb,cbarg);
|
*/
|
||||||
|
process_message(conn,f+4,*(uint32_t*)f,cb,cbarg);
|
||||||
|
|
||||||
free (f);
|
free (f);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -243,13 +251,14 @@ extern int cw_process_msg(struct conn * conn,uint8_t*msg,int len);
|
|||||||
cw_process_msg(conn,packet,len);
|
cw_process_msg(conn,packet,len);
|
||||||
|
|
||||||
|
|
||||||
if (!cwrmsg_init_ctrlhdr(conn,&cwrmsg,packet+hlen,len-hlen) ){
|
//if (!cwrmsg_init_ctrlhdr(conn,&cwrmsg,packet+hlen,len-hlen) ){
|
||||||
// cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, len=%d (too short)",sock_addr2str(&conn->addr));
|
// cw_dbg(DBG_CW_PKT_ERR,"Discarding packet from %s, len=%d (too short)",sock_addr2str(&conn->addr));
|
||||||
return;
|
// return;
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
printf("Next big thing\n");
|
||||||
process_message(conn,&cwrmsg,cb,cbarg);
|
//msg_4*((val >> 19) & 0x1f);
|
||||||
|
process_message(conn,packet,len,cb,cbarg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ struct cwrmsg * conn_send_request(struct conn * conn)
|
|||||||
|
|
||||||
time_t r_timer = cw_timer_start(conn->retransmit_interval);
|
time_t r_timer = cw_timer_start(conn->retransmit_interval);
|
||||||
if (i!=0)
|
if (i!=0)
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"Retransmitting message, type=%d,seq=%d",cwmsg->type,cwmsg->seqnum);
|
cw_dbg(DBG_MSG_ERR,"Retransmitting message, type=%d,seq=%d",cwmsg->type,cwmsg->seqnum);
|
||||||
|
|
||||||
conn_send_cwmsg(conn,&conn->req_msg);
|
conn_send_cwmsg(conn,&conn->req_msg);
|
||||||
cwrmsg = conn_wait_for_message(conn,r_timer);
|
cwrmsg = conn_wait_for_message(conn,r_timer);
|
||||||
@ -55,7 +55,7 @@ struct cwrmsg * conn_send_request(struct conn * conn)
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"Max retransmit's reached, message type=%d,seq=%d",cwmsg->type,cwmsg->seqnum);
|
cw_dbg(DBG_MSG_ERR,"Max retransmit's reached, message type=%d,seq=%d",cwmsg->type,cwmsg->seqnum);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,13 +22,20 @@ static inline int cw_action_cmp(const void *elem1,const void *elem2)
|
|||||||
if (r!=0)
|
if (r!=0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
r = e1->vendor_id - e2->vendor_id;
|
||||||
|
if (r!=0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
static void cw_action_del(void*d)
|
static void cw_action_del(void*d)
|
||||||
{
|
{
|
||||||
free(d);
|
free(d);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
cw_action_t * cw_actionlist_add(cw_actionlist_t t, struct cw_action * a)
|
cw_action_t * cw_actionlist_add(cw_actionlist_t t, struct cw_action * a)
|
||||||
{
|
{
|
||||||
@ -49,15 +56,15 @@ struct cw_action * cw_actionlist_get(cw_actionlist_t t,struct cw_action *a)
|
|||||||
|
|
||||||
cw_actionlist_t cw_actionlist_create()
|
cw_actionlist_t cw_actionlist_create()
|
||||||
{
|
{
|
||||||
return avltree_create(cw_action_cmp,cw_action_del);
|
return avltree_create(cw_action_cmp,free); //cw_action_del);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int cw_register_actions(cw_actionlist_t t,cw_action_t * actions)
|
int cw_register_actions(cw_actionlist_t t,cw_action_t * actions)
|
||||||
{
|
{
|
||||||
while(actions->capwap_state){
|
while(actions->capwap_state){
|
||||||
cw_action_t *a = actions;
|
// cw_action_t *a = actions;
|
||||||
printf("State: %d MSG_ID: %d ELEM_ID: %d\n",a->capwap_state,a->msg_id,a->elem_id);
|
// printf("State: %d MSG_ID: %d ELEM_ID: %d\n",a->capwap_state,a->msg_id,a->elem_id);
|
||||||
cw_action_t * rc = cw_actionlist_add(t,actions);
|
cw_action_t * rc = cw_actionlist_add(t,actions);
|
||||||
if (rc==0)
|
if (rc==0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -6,16 +6,22 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "avltree.h"
|
#include "avltree.h"
|
||||||
|
#include "conn.h"
|
||||||
|
|
||||||
struct cw_action{
|
struct cw_action{
|
||||||
|
uint32_t vendor_id;
|
||||||
|
uint8_t proto;
|
||||||
uint8_t capwap_state;
|
uint8_t capwap_state;
|
||||||
uint32_t msg_id;
|
uint32_t msg_id;
|
||||||
uint16_t elem_id;
|
uint16_t elem_id;
|
||||||
uint32_t vendor_id;
|
|
||||||
uint16_t vendor_elem_id;
|
|
||||||
|
|
||||||
int (*start)(struct conn *conn,struct cw_action *a,uint8_t*data,int len);
|
int (*start)(struct conn *conn,struct cw_action *a,uint8_t*data,int len);
|
||||||
int (*end)(struct conn *conn,struct cw_action *a,uint8_t*data,int len);
|
int (*end)(struct conn *conn,struct cw_action *a,uint8_t*elem,int len);
|
||||||
|
|
||||||
|
uint16_t min_len;
|
||||||
|
uint16_t max_len;
|
||||||
|
|
||||||
|
uint8_t capwap_state_next;
|
||||||
|
|
||||||
|
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define DBG_MSG 0x00000001 /* Parsed CAPWAP/LWAPP messages */
|
#define DBG_MSG 0x00000001 /* Parsed CAPWAP/LWAPP messages */
|
||||||
#define DBG_MSG_ERR 0x00000001
|
|
||||||
|
|
||||||
#define DBG_ELEM 0x00000002 /* Parsed CAPWAP/LWAPP message elements */
|
#define DBG_ELEM 0x00000002 /* Parsed CAPWAP/LWAPP message elements */
|
||||||
#define DBG_ELEM_DMP 0x00000004 /* Dump CAPWAP message elements */
|
#define DBG_ELEM_DMP 0x00000004 /* Dump CAPWAP message elements */
|
||||||
@ -47,8 +46,9 @@
|
|||||||
#define DBG_CW_PKT_DMP 0x00000080 /* Dump packts */
|
#define DBG_CW_PKT_DMP 0x00000080 /* Dump packts */
|
||||||
#define DBG_CW_PKT_DTL 0x00000100
|
#define DBG_CW_PKT_DTL 0x00000100
|
||||||
#define DBG_CW_PKT_ERR 0x00000200
|
#define DBG_CW_PKT_ERR 0x00000200
|
||||||
#define DBG_CW_MSG_ERR 0x00000400 /* Errors in CAPWAP messages */
|
#define DBG_MSG_ERR 0x00000400 /* Errors in CAPWAP messages */
|
||||||
#define DBG_CW_IMG_DTL 0x00000800 /* Detail about image transfer */
|
#define DBG_CW_IMG_DTL 0x00000800 /* Detail about image transfer */
|
||||||
|
#define DBG_ELEM_ERR 0x00001000
|
||||||
|
|
||||||
/* driver specific debugs */
|
/* driver specific debugs */
|
||||||
#define DBG_DRV 0x00010000
|
#define DBG_DRV 0x00010000
|
||||||
@ -69,7 +69,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#define DBG_DETAIL_ALL 0xffffffff
|
#define DBG_DETAIL_ALL 0xffffffff
|
||||||
#define DBG_ERR (DBG_CW_MSG_ERR | DBG_CW_PKT_ERR)
|
#define DBG_ERR (DBG_MSG_ERR | DBG_CW_PKT_ERR)
|
||||||
|
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
|
@ -35,8 +35,9 @@ struct cw_dbg_cfgstrs cw_dbg_cfgstrs[] = {
|
|||||||
{"pkt",(DBG_CW_PKT_IN | DBG_CW_PKT_OUT)},
|
{"pkt",(DBG_CW_PKT_IN | DBG_CW_PKT_OUT)},
|
||||||
{"pkt_dmp",DBG_CW_PKT_DMP},
|
{"pkt_dmp",DBG_CW_PKT_DMP},
|
||||||
{"pkt_err",DBG_CW_PKT_ERR},
|
{"pkt_err",DBG_CW_PKT_ERR},
|
||||||
{"msg_err",DBG_CW_MSG_ERR},
|
{"msg_err",DBG_MSG_ERR},
|
||||||
{"img_dtl",DBG_CW_IMG_DTL},
|
{"img_dtl",DBG_CW_IMG_DTL},
|
||||||
|
{"elem_err",DBG_ELEM_ERR},
|
||||||
|
|
||||||
{"dtls",DBG_DTLS},
|
{"dtls",DBG_DTLS},
|
||||||
{"dtls_dietail",DBG_DTLS_DETAIL},
|
{"dtls_dietail",DBG_DTLS_DETAIL},
|
||||||
|
@ -45,9 +45,9 @@ const char * cw_msgtostr(int type)
|
|||||||
case CW_MSG_CONFIGURATION_UPDATE_RESPONSE:
|
case CW_MSG_CONFIGURATION_UPDATE_RESPONSE:
|
||||||
return "configuration update response";
|
return "configuration update response";
|
||||||
|
|
||||||
case CWMSG_WTP_EVENT_REQUEST:
|
case CW_MSG_WTP_EVENT_REQUEST:
|
||||||
return "wtp event request";
|
return "wtp event request";
|
||||||
case CWMSG_WTP_EVENT_RESPONSE:
|
case CW_MSG_WTP_EVENT_RESPONSE:
|
||||||
return "wtp event response";
|
return "wtp event response";
|
||||||
|
|
||||||
|
|
||||||
@ -83,9 +83,9 @@ const char * cw_msgtostr(int type)
|
|||||||
Reset Request 17
|
Reset Request 17
|
||||||
Reset Response 18
|
Reset Response 18
|
||||||
*/
|
*/
|
||||||
case CWMSG_PRIMARY_DISCOVERY_REQUEST:
|
case CW_MSG_PRIMARY_DISCOVERY_REQUEST:
|
||||||
return "primary discovery request";
|
return "primary discovery request";
|
||||||
case CWMSG_PRIMARY_DISCOVERY_RESPONSE:
|
case CW_MSG_PRIMARY_DISCOVERY_RESPONSE:
|
||||||
return "primary discovery response";
|
return "primary discovery response";
|
||||||
|
|
||||||
/* Data Transfer Request 21
|
/* Data Transfer Request 21
|
||||||
|
@ -4,25 +4,61 @@
|
|||||||
|
|
||||||
#include "conn.h"
|
#include "conn.h"
|
||||||
#include "capwap.h"
|
#include "capwap.h"
|
||||||
|
#include "sock.h"
|
||||||
#include "cw_action.h"
|
#include "cw_action.h"
|
||||||
|
#include "cw_log.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len)
|
int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len)
|
||||||
{
|
{
|
||||||
struct cw_action as,*af;
|
struct cw_action as,*af;
|
||||||
|
|
||||||
|
|
||||||
uint8_t * msg_ptr = rawmsg+cw_get_hdr_msg_offset(rawmsg);
|
uint8_t * msg_ptr = rawmsg+cw_get_hdr_msg_offset(rawmsg);
|
||||||
|
|
||||||
|
int elems_len = cw_get_msg_elems_len(msg_ptr);
|
||||||
|
/*
|
||||||
|
if (8+elems_len != len){
|
||||||
|
cw_dbg(DBG_MSG_ERR,"Discarding message from %s, msgelems len=%d, data len=%d, (strict capwap) ",
|
||||||
|
sock_addr2str(&conn->addr),elems_len,len-8);
|
||||||
|
|
||||||
|
if (conn_is_strict_capwap(conn)){
|
||||||
|
cw_dbg(DBG_MSG_ERR,"Discarding message from %s, msgelems len=%d, data len=%d, (strict capwap) ",
|
||||||
|
sock_addr2str(&conn->addr),elems_len,len-8);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (8+elems_len < len){
|
||||||
|
cw_dbg(DBG_CW_RFC,"Packet from from %s has %d bytes extra data.",
|
||||||
|
sock_addr2str(&conn->addr),len-8-elems_len);
|
||||||
|
elems_len=len-8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (8+elems_len > len){
|
||||||
|
cw_dbg(DBG_CW_RFC,"Packet from from %s hass msgelems len of %d bytes but has only %d bytes of data, truncating.",
|
||||||
|
sock_addr2str(&conn->addr),elems_len,len-8);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* prepare struct for search operation */
|
/* prepare struct for search operation */
|
||||||
as.elem_id=-1;
|
as.elem_id=-1;
|
||||||
as.capwap_state=conn->capwap_state;
|
as.capwap_state=conn->capwap_state;
|
||||||
as.msg_id = cw_get_msg_id(msg_ptr);
|
as.msg_id = cw_get_msg_id(msg_ptr);
|
||||||
|
as.vendor_id=0;
|
||||||
|
|
||||||
|
|
||||||
/* Search for state/message combination */
|
/* Search for state/message combination */
|
||||||
af = cw_actionlist_get(conn->msgtr,&as);
|
af = cw_actionlist_get(conn->msgtr,&as);
|
||||||
|
|
||||||
|
/* Check if message is comes in right state */
|
||||||
if ( !af ){
|
if ( !af ){
|
||||||
printf("Error - Message not found: %d\n",as.msg_id);
|
cw_dbg(DBG_MSG_ERR,"Message type %d (%s) not allowed in %s State.",
|
||||||
|
as.msg_id,cw_strmsg(as.msg_id),cw_strstate(as.capwap_state));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +67,6 @@ int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len)
|
|||||||
af->start(conn,af,rawmsg,len);
|
af->start(conn,af,rawmsg,len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int elems_len = cw_get_msg_elems_len(msg_ptr);
|
|
||||||
uint8_t * elems_ptr = cw_get_msg_elems_ptr(msg_ptr);
|
uint8_t * elems_ptr = cw_get_msg_elems_ptr(msg_ptr);
|
||||||
|
|
||||||
|
|
||||||
@ -43,6 +78,8 @@ int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len)
|
|||||||
as.elem_id = cw_get_elem_id(elem);
|
as.elem_id = cw_get_elem_id(elem);
|
||||||
int elem_len = cw_get_elem_len(elem);
|
int elem_len = cw_get_elem_len(elem);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
af = cw_actionlist_get(conn->msgtr,&as);
|
af = cw_actionlist_get(conn->msgtr,&as);
|
||||||
|
|
||||||
if (!af) {
|
if (!af) {
|
||||||
@ -51,6 +88,9 @@ int cw_process_msg(struct conn * conn,uint8_t * rawmsg,int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("Elem OK: %d, %d\n",as.elem_id,elem_len);
|
printf("Elem OK: %d, %d\n",as.elem_id,elem_len);
|
||||||
|
if (af->start) {
|
||||||
|
af->start(conn,af,cw_get_elem_data(elem),elem_len);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ int cw_readelem_image_identifier(struct cwimage_data *data, int type,uint8_t *ms
|
|||||||
data->vendor_id = ntohl(*((uint32_t*)msgelem));
|
data->vendor_id = ntohl(*((uint32_t*)msgelem));
|
||||||
|
|
||||||
if (len >= 1024) {
|
if (len >= 1024) {
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"Image identifier too long (>1024), truncating");
|
cw_dbg(DBG_MSG_ERR,"Image identifier too long (>1024), truncating");
|
||||||
len = 1024;
|
len = 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ int cw_readelem_80211_wtp_radio_info(void *dst,int type,uint8_t *msgelem, int le
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (len!=5){
|
if (len!=5){
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"Discarding msgelem 80211_WTP_RADIO_INFO, wrong size, len=%d\n",len);
|
cw_dbg(DBG_MSG_ERR,"Discarding msgelem 80211_WTP_RADIO_INFO, wrong size, len=%d\n",len);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ int cw_readelem_ac_name(uint8_t **dst, int type,uint8_t *msgelem, int len)
|
|||||||
|
|
||||||
if (len > 512 ) {
|
if (len > 512 ) {
|
||||||
cw_dbg(DBG_CW_RFC,"AC name too long, max. 512 bytes allowed (RFC 5415)");
|
cw_dbg(DBG_CW_RFC,"AC name too long, max. 512 bytes allowed (RFC 5415)");
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"AC name truncated to 512 bytes");
|
cw_dbg(DBG_MSG_ERR,"AC name truncated to 512 bytes");
|
||||||
len = 512;
|
len = 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ int lw_readelem_wtp_board_data(struct wtpinfo *wtpinfo, int type, uint8_t *msgel
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ( len != 46 ) {
|
if ( len != 46 ) {
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"LWAPP msg size wrong. (WTP BOARD DATA) must be 46");
|
cw_dbg(DBG_MSG_ERR,"LWAPP msg size wrong. (WTP BOARD DATA) must be 46");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ int lw_readelem_wtp_name(uint8_t ** dst, int type, uint8_t * msgelem, int len)
|
|||||||
|
|
||||||
|
|
||||||
if (len>254){
|
if (len>254){
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"Truncating WTP_NAME msgelem to 254, wrong size, type=%d,len=%d",type,len);
|
cw_dbg(DBG_MSG_ERR,"Truncating WTP_NAME msgelem to 254, wrong size, type=%d,len=%d",type,len);
|
||||||
len=254;
|
len=254;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ int wtpinfo_readelem_discovery_type(struct wtpinfo * wtpinfo, int type, uint8_t
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (len!=1){
|
if (len!=1){
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"Discarding WTP_DISCOVERY_TYPE msgelem, wrong size, type=%d,len=%d",type,len);
|
cw_dbg(DBG_MSG_ERR,"Discarding WTP_DISCOVERY_TYPE msgelem, wrong size, type=%d,len=%d",type,len);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ static int wtpinfo_readelem_wtp_descriptor_(struct wtpinfo * wtpinfo, int type,
|
|||||||
do {
|
do {
|
||||||
if (i+8>len)
|
if (i+8>len)
|
||||||
{
|
{
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"WTP descriptor subelement to long, length=%d>%d",i+8,len);
|
cw_dbg(DBG_MSG_ERR,"WTP descriptor subelement to long, length=%d>%d",i+8,len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ static int wtpinfo_readelem_wtp_descriptor_(struct wtpinfo * wtpinfo, int type,
|
|||||||
i+=8;
|
i+=8;
|
||||||
|
|
||||||
if (sublen+i>len){
|
if (sublen+i>len){
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"WTP descriptor subelement too long, length = %d",sublen);
|
cw_dbg(DBG_MSG_ERR,"WTP descriptor subelement too long, length = %d",sublen);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ static int wtpinfo_readelem_wtp_descriptor_(struct wtpinfo * wtpinfo, int type,
|
|||||||
wtpinfo->bootloader_version_len=sublen;
|
wtpinfo->bootloader_version_len=sublen;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"Unknown WTP descriptor subelement, type = %d",subtype);
|
cw_dbg(DBG_MSG_ERR,"Unknown WTP descriptor subelement, type = %d",subtype);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i+=sublen;
|
i+=sublen;
|
||||||
|
@ -11,7 +11,7 @@ int wtpinfo_readelem_wtp_frame_tunnel_mode(struct wtpinfo * wtpinfo, int type, u
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (len!=1){
|
if (len!=1){
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"Discarding WTP_DISCOVERY_TYPE msgelem, wrong size, type=%d,len=%d",type,len);
|
cw_dbg(DBG_MSG_ERR,"Discarding WTP_DISCOVERY_TYPE msgelem, wrong size, type=%d,len=%d",type,len);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
wtpinfo->frame_tunnel_mode=*msgelem;
|
wtpinfo->frame_tunnel_mode=*msgelem;
|
||||||
|
@ -10,7 +10,7 @@ int wtpinfo_readelem_wtp_mac_type(struct wtpinfo * wtpinfo, int type, uint8_t *
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (len!=1){
|
if (len!=1){
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"Discarding WTP_MAC_TYPE msgelem, wrong size, type=%d,len=%d",type,len);
|
cw_dbg(DBG_MSG_ERR,"Discarding WTP_MAC_TYPE msgelem, wrong size, type=%d,len=%d",type,len);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ int wtpinfo_readelem_wtp_name(struct wtpinfo * wtpinfo, int type, uint8_t * msge
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (len>512){
|
if (len>512){
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"Truncating WTP_NAME msgelem to 512, wrong size, type=%d,len=%d",type,len);
|
cw_dbg(DBG_MSG_ERR,"Truncating WTP_NAME msgelem to 512, wrong size, type=%d,len=%d",type,len);
|
||||||
len=512;
|
len=512;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ int wtpinfo_readelem_wtp_radio_info(struct wtpinfo * wtpinfo,int type,uint8_t *m
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (len!=5){
|
if (len!=5){
|
||||||
cw_dbg(DBG_CW_MSG_ERR,"Discarding msgelem WTP_RADIO_INFO, wrong size, len=%d\n",len);
|
cw_dbg(DBG_MSG_ERR,"Discarding msgelem WTP_RADIO_INFO, wrong size, len=%d\n",len);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user