diff --git a/src/ac/dataman.c b/src/ac/dataman.c new file mode 100644 index 00000000..eb536101 --- /dev/null +++ b/src/ac/dataman.c @@ -0,0 +1,227 @@ +#include + +#include "cw/mavl.h" +#include "cw/sock.h" +#include "cw/timer.h" +#include "cw/cw.h" +#include "cw/format.h" + +#include "cw/log.h" +#include "cw/dbg.h" + +#include "wtplist.h" +#include "dataman.h" + + +struct mavl *dataman_list; +pthread_mutex_t dataman_list_mutex; + +static int cmp(const void *d1, const void *d2) +{ + struct netconn *nc1 = ((struct dataman *) d1)->nc; + struct netconn *nc2 = ((struct dataman *) d1)->nc; + + int r = nc1->sock - nc2->sock; + if (r != 0) + return r; + + return sock_cmpaddr((struct sockaddr *) &nc1->addr, + (struct sockaddr *) &nc2->addr, 1); + +} + + +int dataman_list_init() +{ + dataman_list = mavl_create(cmp, NULL); + if (!dataman_list) + return 0; + + if (pthread_mutex_init(&dataman_list_mutex,NULL)){ + mavl_destroy(dataman_list); + return 0; + } + + return 1; +} + + + +void dataman_destroy(struct dataman *dm) +{ + if (!dm) + return; + netconn_destroy(dm->nc); +} + +struct dataman *dataman_create(int sock, struct sockaddr *addr) +{ + struct dataman *dm = malloc(sizeof(struct dataman)); + if (!dm) + return NULL; + + dm->nc = netconn_create(sock, addr, 100); + return dm; +} + + +struct dataman *dataman_list_get(int sock, struct sockaddr *addr) +{ + struct netconn search_nc; + struct dataman search_dm; + + search_nc.sock = sock; + sock_copyaddr (&search_nc.addr,addr); + + search_dm.nc = &search_nc; + + struct dataman *dm = mavl_get(dataman_list, &search_dm); + + cw_dbg(DBG_X,"Getting dataman %p",dm); + return dm; +} + +struct dataman *dataman_list_add(struct dataman *dm) +{ + + cw_dbg(DBG_X,"Adding dataman %p\n",dm); + return mavl_add(dataman_list, dm); +} + + + +int dataman_process_keep_alive(struct netconn *nc, uint8_t *rawmsg, int len) +{ + struct dataman * dm = (struct dataman *)(nc->data); + + uint8_t *msgptr = rawmsg + cw_get_hdr_msg_offset(rawmsg); + + + int elems_len = cw_get_datamsg_elems_len(msgptr); + uint8_t * elems_ptr = cw_get_datamsg_elems_ptr(msgptr); + uint8_t * elem; + + cw_foreach_elem(elem, elems_ptr, elems_len) { + + if (cw_get_elem_id(elem) == CW_ELEM_SESSION_ID){ + uint8_t sessid[16]; + memset(sessid,0,16); + + int sessid_len = cw_get_elem_len(elem); + + printf("Sess id len = %d\n",sessid_len); + + memcpy(sessid,cw_get_elem_data(elem),sessid_len); + + struct wtpman * wtpman = wtplist_get_by_session_id(sessid); + if (wtpman){ + if (!dm->wtpman) + dm->wtpman=wtpman; + + uint8_t buffer[128]; + uint8_t * dl = cw_init_data_keep_alive_msg(buffer,NULL); + uint8_t * d=dl+2; + + int l = cw_put_elem_session_id(d,sessid,sessid_len); + cw_put_word(dl,l); + + int total_len = dl-buffer + l+2; + printf("len len %d\n",l); + printf("Total len = %d\n",total_len); + + netconn_send_capwap_msg(nc,buffer,total_len); + return len; + + + + + + + printf("Found!i yes I vae found it\n"); + + } + + + + int l = cw_get_elem_len(elem); + + printf("ElemID: %d, len = %d\n", cw_get_elem_id(elem),l); + char cb[64]; + format_hex(cb,sessid,16); + printf("Session ID: %s",cb); + + + + + } + + + + } + + errno=EAGAIN; + return -1; +} + +int dataman_process_message0(struct netconn *nc, uint8_t * rawmsg, int len, + struct sockaddr *from) +{ + /* The very first data message MUST be a keep-alive message */ + if (!cw_get_hdr_flag_k(rawmsg)){ + errno = EAGAIN; + return -1; + } + + return dataman_process_keep_alive(nc,rawmsg,len); +} + +int dataman_process_message(struct netconn *nc, uint8_t * rawmsg, int len, + struct sockaddr *from) +{ + if (cw_get_hdr_flag_k(rawmsg)){ + return dataman_process_keep_alive(nc,rawmsg,len); + } + + cw_dbg(DBG_X,"There was someting else than dataman"); + return 1; + +} + +void dataman_run(struct dataman *dm) +{ + time_t timer = cw_timer_start(2); + + dm->nc->process_packet=netconn_process_packet; + dm->nc->process_message=dataman_process_message0; + dm->nc->data = dm; + + while (!cw_timer_timeout(timer)){ + netconn_read_messages(dm->nc); + } + + if (!dm->wtpman){ + cw_log(LOG_ERR,"Data session not associated"); + dataman_destroy(dm); + return; + } + + cw_dbg(DBG_X,"Data channel established"); + dm->nc->process_message=dataman_process_message; + + while (1){ + time_t timer = cw_timer_start(2); + while (!cw_timer_timeout(timer)){ + netconn_read_messages(dm->nc); + } + } + + + +} + +void dataman_start(struct dataman * dm) +{ + pthread_create(&dm->thread, NULL, (void *) dataman_run, + (void *) dm); + +} diff --git a/src/ac/dataman.h b/src/ac/dataman.h new file mode 100644 index 00000000..f7c12c2e --- /dev/null +++ b/src/ac/dataman.h @@ -0,0 +1,33 @@ +#ifndef __DATAMAN_H +#define __DATAMAN_H + +#include + +#include "cw/netconn.h" + +#include "wtpman.h" + +struct dataman { + struct netconn *nc; + pthread_t thread; + struct wtpman * wtpman; + + +}; + +extern int dataman_list_init(); +struct dataman *dataman_list_add(struct dataman *dm); +extern struct dataman *dataman_list_get(int sock, struct sockaddr *addr); + + +extern struct dataman *dataman_create(int sock, struct sockaddr *addr); +extern void dataman_start(struct dataman * dm); + +extern pthread_mutex_t dataman_list_mutex; + +#define dataman_list_lock() pthread_mutex_lock(&dataman_list_mutex) +#define dataman_list_unlock() pthread_mutex_unlock(&dataman_list_mutex) + +#define dataman_add_packet(dm,data,len) (netconn_q_add_packet(dm->nc,data,len)) + +#endif