コード例 #1
0
ファイル: shell.c プロジェクト: 7u83/actube
void show_aps (FILE *out)
{
	struct connlist * cl;
	mavliter_t it;
	wtplist_lock();
	
	cl = wtplist_get_connlist();
	
	
	mavliter_init (&it, cl->by_addr);
	fprintf (out, "IP\t\t\twtp-name\n");
	mavliter_foreach (&it) {
		cw_KTV_t * result;
		char addr[SOCK_ADDR_BUFSIZE];
		char wtp_name[CAPWAP_MAX_WTP_NAME_LEN];
		struct conn * conn;
		conn = mavliter_get_ptr (&it);
		
		sock_addr2str_p (&conn->addr, addr);
		
		result = cw_ktv_get (conn->remote_cfg, "wtp-name", NULL);
		
		if (result == NULL) {
			strcpy (wtp_name, "");
			
		} else {
			result->type->to_str (result, wtp_name, CAPWAP_MAX_WTP_NAME_LEN);
		}
		
		
		fprintf (out, "%s\t\t%s\n", addr, wtp_name);
	}
	wtplist_unlock();
}
コード例 #2
0
ファイル: wtpman.c プロジェクト: yskcg/actube
static int wtpman_establish_dtls(void *arg)
{
	struct wtpman *wtpman = (struct wtpman *) arg;

	/* setup cipher */
	wtpman->conn->dtls_cipher = conf_sslcipher;

	/* setup DTSL certificates */
	int dtls_ok = 0;
	if (conf_sslkeyfilename && conf_sslcertfilename) {


		wtpman->conn->dtls_key_file = conf_sslkeyfilename;
		wtpman->conn->dtls_cert_file = conf_sslcertfilename;
		wtpman->conn->dtls_key_pass = conf_sslkeypass;
		wtpman->conn->dtls_verify_peer = conf_dtls_verify_peer;
		cw_dbg(DBG_DTLS, "Using key file %s", wtpman->conn->dtls_key_file);
		cw_dbg(DBG_DTLS, "Using cert file %s", wtpman->conn->dtls_cert_file);
		dtls_ok = 1;
	}

	/* setup DTLS psk */
	if (conf_dtls_psk) {
		wtpman->conn->dtls_psk = conf_dtls_psk;
		wtpman->conn->dtls_psk_len = strlen(conf_dtls_psk);
		dtls_ok = 1;
	}

	if (!dtls_ok) {
		cw_log(LOG_ERR,
		       "Can't establish DTLS session, neither psk nor certs set in config file.");
		return 0;
	}

	/* try to accept the connection */
	if (!dtls_accept(wtpman->conn)) {
		cw_dbg(DBG_DTLS, "Error establishing DTLS session with %s",
		       sock_addr2str_p(&wtpman->conn->addr));
		return 0;
	}

	cw_dbg(DBG_DTLS, "DTLS session established with %s, cipher=%s",
	       sock_addr2str_p(&wtpman->conn->addr), dtls_get_cipher(wtpman->conn));

	return 1;
}
コード例 #3
0
ファイル: wtpman.c プロジェクト: 7u83/actube
static int wtpman_dtls_setup(void *arg)
{
	char cipherstr[512];

	char sock_buf[SOCK_ADDR_BUFSIZE];
	struct wtpman *wtpman = (struct wtpman *) arg;

	/* try to accept the connection */
	if (!dtls_accept(wtpman->conn)) {
		cw_dbg(DBG_DTLS, "Error establishing DTLS session with %s",
		       sock_addr2str_p(&wtpman->conn->addr,sock_buf));
		return 0;
	}

	cw_dbg(DBG_DTLS, "DTLS session established with %s, %s",
	       sock_addr2str_p(&wtpman->conn->addr,sock_buf), dtls_get_cipher(wtpman->conn,cipherstr));

	return 1;
}
コード例 #4
0
ファイル: conn_process_packet.c プロジェクト: yskcg/actube
static struct cw_actiondef *load_mods(struct conn *conn, uint8_t * rawmsg, int len,
				      int elems_len, struct sockaddr *from)
{

	struct mod_ac *cmod =
	    detect_mod(conn, rawmsg, len, elems_len, from, MOD_MODE_CAPWAP);
	if (cmod == MOD_NULL) {
		cw_dbg(DBG_MSG_ERR,
		       "Can't find mod to handle connection from %s , discarding message",
		       sock_addr2str_p(from));
		return NULL;
	}

	struct mod_ac *bmod =
	    detect_mod(conn, rawmsg, len, elems_len, from, MOD_MODE_BINDINGS);

	cw_dbg(DBG_INFO, "Mods deteced: %s,%s", cmod->name, bmod->name);

	struct cw_actiondef *ad = mod_cache_add(conn,cmod, bmod);

	return ad;




/*
	if (bindins_mod) {
		cw_dbg(DBG_INFO, "Using mod '%s' to handle CAWPAP for %s", mod->name,
		       sock_addr2str_p(from));
		conn->detected=1;
	}
	else{
//              errno = EAGAIN;
//              return -1;
	}


	mod = detect_mod(conn, rawmsg, len, elems_len, from, MOD_DETECT_BINDINGS);
	if (mod) {
		cw_dbg(DBG_INFO, "Using bindings '%s' to handle %s", mod->name,
		       sock_addr2str_p(from));
		conn->detected=1;
	}
	else{
		cw_dbg(DBG_MSG_ERR, "Can't detect bindings ... for %s",
		       sock_addr2str_p(from));
	}

	
	return 0;
	*/
}
コード例 #5
0
ファイル: wtpman.c プロジェクト: yskcg/actube
static void reset_echointerval_timer(struct wtpman *wtpman)
{
	uint16_t ct = mbag_get_word(wtpman->conn->local, CW_ITEM_CAPWAP_TIMERS,
				    CAPWAP_MAX_DISCOVERY_INTERVAL << 8 |
				    CAPWAP_ECHO_INTERVAL);

	/* start echinterval timer and put 2 seconds for "safety" on it */

	wtpman->echointerval_timer = cw_timer_start(2+ (ct & 0xff));
	db_ping_wtp(sock_addr2str_p(&wtpman->conn->addr), conf_acname);
//	cw_dbg(DBG_X, "Starting capwap timer: %d", wtpman->echointerval_timer);

}
コード例 #6
0
ファイル: shell.c プロジェクト: 7u83/actube
void con (FILE *out)
{
	struct connlist * cl;
	mavliter_t it;
	
	
	
	wtplist_lock();
	
	cl = wtplist_get_connlist();
	
	
	mavliter_init (&it, cl->by_addr);
	fprintf (out, "IP\t\t\twtp-name\n");
	mavliter_foreach (&it) {
		cw_KTV_t * result;
		char addr[SOCK_ADDR_BUFSIZE];
		char wtp_name[CAPWAP_MAX_WTP_NAME_LEN];
		struct conn * conn;
		conn = mavliter_get_ptr (&it);
		
		sock_addr2str_p (&conn->addr, addr);
		
		result = cw_ktv_get (conn->remote_cfg, "wtp-name", NULL);
		
		if (result == NULL) {
			strcpy (wtp_name, "");
			
		} else {
			result->type->to_str (result, wtp_name, CAPWAP_MAX_WTP_NAME_LEN);
		}
		
		
		fprintf (out, "Con!! %s\t\t%s\n", addr, wtp_name);
		
		{
			mavl_t update;
			update = cw_ktv_create();
			cw_ktv_set_byte(update,"radio.255/admin-state",1);
			conn->update_cfg=update;
		}


		fprintf(out,"\n");

	}
	wtplist_unlock();
}
コード例 #7
0
ファイル: wtpman.c プロジェクト: 7u83/actube
static void wtpman_run_dtls(void *arg)
{
	char sock_buf[SOCK_ADDR_BUFSIZE];
	struct wtpman *wtpman = (struct wtpman *) arg;



	/* reject connections to our multi- or broadcast sockets */
	if (socklist[wtpman->socklistindex].type != SOCKLIST_UNICAST_SOCKET) {
		cw_dbg(DBG_DTLS, "Dropping connection from %s to non-unicast socket.",
		       sock_addr2str_p(&wtpman->conn->addr,sock_buf));
		wtpman_remove(wtpman);
		return;
	}
/*//      time_t timer = cw_timer_start(wtpman->conn->wait_dtls);*/

	/* establish dtls session */
	if (!wtpman_dtls_setup(wtpman)) {
		wtpman_remove(wtpman);
		return;
	}

	wtpman_main(arg);
}
コード例 #8
0
ファイル: shell.c プロジェクト: 7u83/actube
void * run_shell (void * arg)
{
	struct sockaddr_storage server, client;
	socklen_t client_size;
	char sockstr[SOCK_ADDR_BUFSIZE];
	
	int rc;
	const char * addr = "127.0.0.1:5000";
	int sockfd, clientsock;
	int yes;
while(1){
	

	rc = sock_strtoaddr (addr, (struct sockaddr*) &server);
	
	if (! rc) {
		cw_log (LOG_ERR, "Can't parse address '%s', %s", addr, strerror (errno));
	}
	
	sockfd = socket ( ( (struct sockaddr*) &server)->sa_family, SOCK_STREAM, 0);
	
	yes = 1;
	/* reuse address */
	setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof (yes));
	
	
	/* bind address */
	rc =  bind (sockfd, (struct sockaddr*) &server, sizeof (server));
	
	if (rc) {
		cw_log (LOG_ERR, "Can't bind socket address '%s', %s", addr, strerror (errno));
	}
	
	rc = listen (sockfd, 5);
	
	if (rc) {
		cw_log (LOG_ERR, "Can't listen on address '%s', %s", addr, strerror (errno));
	}
	
	
	client_size = sizeof (client);
	clientsock = accept (sockfd, (struct sockaddr*) &client, &client_size);
	
	if (clientsock > 0) {
		sock_addr2str_p (&client, sockstr);
		cw_dbg (DBG_INFO, "Acceptiong session from %s", sockstr);
		printf("New shell lopp\n");
		shell_loop (fdopen (clientsock, "a+"));
		printf("end shell lopp\n");
		close (clientsock);
		printf("close clsock\n");
	}
	
	
	
	cw_dbg (DBG_INFO,"Accepting shell session %i, %s", rc, strerror (errno));
}	
	
	
	
	return NULL;
}
コード例 #9
0
ファイル: wtpman.c プロジェクト: 7u83/actube
static void * wtpman_main(void *arg)
{
	mavl_t r;
	int rc ;
	time_t timer;
	char sock_buf[SOCK_ADDR_BUFSIZE];
	struct conn *conn;
	int last_state;

	struct wtpman *wtpman = (struct wtpman *) arg;

	wtpman->conn->seqnum = 0;
	conn = wtpman->conn;

	wtpman->conn->remote_cfg = cw_ktv_create(); 
	

	/* We were invoked with an unencrypted packet, 
	 * so assume, it is a discovery request */
	if (!wtpman->dtlsmode){
		wtpman_run_discovery(arg);
		wtpman_remove(wtpman);
		return NULL;
	}


	/* reject connections to our multi- or broadcast sockets */
	if (socklist[wtpman->socklistindex].type != SOCKLIST_UNICAST_SOCKET) {
		cw_dbg(DBG_DTLS,"Reject multi");
		wtpman_remove(wtpman);
		return NULL;
	}
	
	conn->capwap_state = CAPWAP_STATE_DTLS_SETUP;
	/* establish dtls session */
	if (!wtpman_dtls_setup(wtpman)) {
		wtpman_remove(wtpman);
		return NULL;
	}
	
	/*last_state = conn->capwap_state;
	conn->capwap_state = CAPWAP_STATE_JOIN;
*/
	conn->capwap_prevstate = CAPWAP_STATE_DTLS_SETUP;
	conn->capwap_state = CAPWAP_STATE_JOIN;
	rc = 0;
	
	while (1){
	
		int wait_join;
		int wait_change_state;
		
		
		
		if (!cw_run_state_machine(conn, &timer)){
			cw_dbg(DBG_INFO,"WTP died");
					wtpman_remove(wtpman);
				return NULL;		
		};
		




	/*	
		switch (conn->capwap_transition){
			case CW_TRANSITION(CAPWAP_STATE_DTLS_SETUP, CAPWAP_STATE_JOIN):
			{

				wait_join = cw_ktv_get_word(conn->global_cfg,"wait-join",CAPWAP_WAIT_JOIN);
				timer = cw_timer_start(wait_join);
				break;
			}
			case CW_TRANSITION(CAPWAP_STATE_JOIN, CAPWAP_STATE_JOIN):
			{	
				char wtpname[CAPWAP_MAX_WTP_NAME_LEN];
				cw_KTV_t * result;
				result = cw_ktv_get(conn->remote_cfg,"wtp-name",NULL);
				result->type->to_str(result,wtpname,CAPWAP_MAX_WTP_NAME_LEN);
				cw_dbg(DBG_INFO, "WTP joined: '%s', IP %s.",
					wtpname,
					sock_addr2str(&conn->addr,sock_buf)
					);
				break;
			}
			case CW_TRANSITION(CAPWAP_STATE_JOIN,CAPWAP_STATE_TIMEOUT):
			{
				cw_dbg(DBG_MSG_ERR, "No join request from %s after %d seconds, WTP died.",
				sock_addr2str(&wtpman->conn->addr,sock_buf), wait_join);
				wtpman_remove(wtpman);
				return NULL;
				break;
			}
			case CW_TRANSITION(CAPWAP_STATE_JOIN, CAPWAP_STATE_CONFIGURE):
			{
				
				wait_change_state = cw_ktv_get_word(conn->global_cfg,
					"capwap-timers/change-state-pending-timer",
					CAPWAP_TIMER_CHANGE_STATE_PENDING_TIMER);
				break;
			}
			case CW_TRANSITION(CAPWAP_STATE_CONFIGURE,CAPWAP_STATE_TIMEOUT):
			{
				cw_dbg(DBG_MSG_ERR, "No Change State Event Request %s after %d seconds, WTP died.",
				sock_addr2str(&wtpman->conn->addr,sock_buf), wait_change_state);
				wtpman_remove(wtpman);
				return NULL;
				break;
			}

		}
		
*/



		
		while (!cw_timer_timeout(timer)) {
			if (conn->update_cfg != NULL){
				mavl_t tmp;
		

				tmp = conn->local_cfg;

				mavl_merge(conn->default_cfg, conn->local_cfg);
				mavl_merge(conn->default_cfg, conn->remote_cfg);

				conn->local_cfg=conn->update_cfg;
								



								
				cw_dbg(DBG_INFO, "Updating WTP %s",sock_addr2str(&conn->addr,sock_buf));

				rc = cw_send_request(conn, CAPWAP_MSG_CONFIGURATION_UPDATE_REQUEST);
				conn->update_cfg=NULL;
				conn->local_cfg=tmp;
			}

			
			rc = cw_read_messages(wtpman->conn);
			if (rc < 0) {
				if (errno == EAGAIN)
					continue;
			}
			break;
		}
		
		if(rc<0){
			conn->capwap_prevstate = conn->capwap_state;
			conn->capwap_state = CAPWAP_STATE_TIMEOUT;
		}

	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	




	/* dtls is established, goto join state */

	conn->capwap_state = CAPWAP_STATE_JOIN;
	if (!wtpman_join(wtpman)) {
		wtpman_remove(wtpman);
		return NULL;
	}



	cw_dbg(DBG_INFO, "WTP from %s has joined with session id: %s",
			sock_addr2str_p(&conn->addr,sock_buf),
			format_bin2hex(conn->session_id,16));


exit(0);

/*
//	cw_dbg(DBG_INFO, "Creating data thread");
//	pthread_t thread;
//	pthread_create(&thread, NULL, (void *) wtpman_run_data, (void *) wtpman);
*/

	/* here the WTP has joined, now we assume an image data request  
	   or a configuration status request. Nothing else. 
	 */

	rc = 0;
	while (!cw_timer_timeout(timer)
	       && wtpman->conn->capwap_state == CAPWAP_STATE_CONFIGURE) {
		rc = cw_read_messages(wtpman->conn);
		if (rc < 0) {
			if (errno != EAGAIN)
				break;
		}
	}

cw_dbg_ktv_dump(conn->remote_cfg,DBG_INFO,"-------------dump------------","DMP","---------end dump --------");

	if (!cw_result_is_ok(rc)) {
		cw_dbg(DBG_INFO, "WTP Problem: %s", cw_strrc(rc));
		wtpman_remove(wtpman);
		return NULL;

	}


	if (conn->capwap_state == CW_STATE_IMAGE_DATA) {
		wtpman_image_data(wtpman);
		return NULL;
	}



	conn->capwap_state = CAPWAP_STATE_RUN;
/*
	// XXX testing ...
//	DBGX("Cofig to sql", "");
//	props_to_sql(conn,conn->incomming,0);
//	radios_to_sql(conn);
*/

	/*conn->msg_end=msg_end_handler;*/
	/* The main run loop */
	reset_echointerval_timer(wtpman);

	rc = 0;
	while (wtpman->conn->capwap_state == CAPWAP_STATE_RUN) {
		rc = cw_read_messages(wtpman->conn);
		if (rc < 0) {
			if (errno != EAGAIN)
				break;
		}

/*//		cw_dbg(DBG_X, "Time left: %d",
//*/
	       /*cw_timer_timeleft(wtpman->echointerval_timer);*/
	       
		if (cw_timer_timeout(wtpman->echointerval_timer)) {

			cw_dbg(DBG_INFO, "Lost connection to WTP:%s",
			       sock_addr2str_p(&conn->addr,sock_buf));
			break;
		}
/*
//		mavl_del_all(conn->outgoing);
//		conn_clear_upd(conn,1);

//	props_to_sql(conn,conn->incomming,0);
//	radios_to_sql(conn);
*/


	
		r = db_get_update_tasks(conn, sock_addr2str(&conn->addr,sock_buf));
		if (r) {

	/*		
//			if (!conn->outgoing->count)
//				continue;
*/
			cw_dbg(DBG_INFO, "Updating WTP %s",sock_addr2str(&conn->addr,sock_buf));

			rc = cw_send_request(conn, CAPWAP_MSG_CONFIGURATION_UPDATE_REQUEST);

/*
//			mavl_merge(conn->config, conn->outgoing);
//			mavl_destroy(conn->outgoing);
//			conn->outgoing = mbag_create();
//			props_to_sql(conn,conn->incomming,0);
//			radios_to_sql(conn);
//			mavl_destroy(r);
*/
		}

		r = db_get_radio_tasks(conn, sock_addr2str(&conn->addr,sock_buf));
		if (r) {

/*
			//			if (!conn->radios_upd->count)
//				continue;
*/
			cw_dbg(DBG_INFO, "Updating Radios for %s",sock_addr2str(&conn->addr,sock_buf));
			rc = cw_send_request(conn, CAPWAP_MSG_CONFIGURATION_UPDATE_REQUEST);

/*
//			conn_clear_upd(conn,1);

//			mavl_destroy(conn->radios_upd);
//			conn->radios_upd=mbag_i_create();


//			radios_to_sql(conn);
*/
			/*
			rc = cw_send_request(conn, CW_MSG_CONFIGURATION_UPDATE_REQUEST);
			mavl_merge(conn->config, conn->outgoing);
			mavl_destroy(conn->outgoing);
			conn->outgoing = mbag_create();
			config_to_sql(conn);
			radios_to_sql(conn);
			mavl_destroy(r);
			*/
		}



	}

	db_ping_wtp(sock_addr2str_p(&conn->addr,sock_buf), "");
	wtpman_remove(wtpman);
	return NULL;
}
コード例 #10
0
ファイル: dbg.c プロジェクト: yskcg/actube
/**
 * Format a Packet Header
 */
int cw_format_pkt_hdr(char *dst,int level,struct conn *conn, uint8_t * packet, int len,struct sockaddr *from)
{
	char *s=dst;
	switch (level) {
		case DBG_PKT_IN:
			if (cw_get_hdr_flag_f(packet)){
				s+=sprintf(s,"Fragment from %s",sock_addr2str_p(from));
			}
			else{
				s+=sprintf(s,"From %s",sock_addr2str_p(from));
			}
			break;
		case DBG_PKT_OUT:
			if (cw_get_hdr_flag_f(packet)){
				s+=sprintf(s,"Fragment to %s",sock_addr2str(from));
			}
			else{
				s+=sprintf(s,"To %s",sock_addr2str(from));
			}
			break;
	}
	s+=sprintf(s," l=%d: ",len);

	int preamble = cw_get_hdr_preamble(packet); 
	if (preamble==01){
		s+=sprintf(s," (encrypted)");
		return s-dst;
	}

	if (len<4)
		goto abort;
		
/*		
	if (cw_get_hdr_flag_f(packet)){
		s+=sprintf(s," (fragmented)");
	}
*/
	int hlen = cw_get_hdr_hlen(packet); 
	int rid = cw_get_hdr_rid(packet);
	int wbid = cw_get_hdr_wbid(packet);
	s+=sprintf(s," H:%d R:%02d W:%02d",hlen,rid,wbid);


	s+=sprintf(s," Flgs:");
	s+=format_hdr_flags(s,packet);

	if (len<8)
		goto abort;
	int frag_id = cw_get_hdr_fragid(packet);
	int frag_offs = cw_get_hdr_fragoffset(packet);
	s+=sprintf(s," Frag/Offs:%d/%d",frag_id,frag_offs);


	if (cw_get_hdr_flag_m(packet)) {
		/* rmac is present, print the rmac */
		int rmac_len=cw_get_hdr_rmac_len(packet);
		int plen=rmac_len;
		if (rmac_len+8>len) 
			plen=len-8;
		if (rmac_len>10) 
			plen=10;
		
		s+=sprintf(s," R-MAC:");
		s+=format_mac(s,cw_get_hdr_rmac_data(packet),plen);
		if (rmac_len>10){
			s+=sprintf(s," ... (len=%d)",rmac_len);
		}
	}

	if (cw_get_hdr_flag_w(packet)){
		/* print wireless specific info */
		int ws_len = cw_get_hdr_ws_len(packet);
		int plen = ws_len > 20 ? 20:ws_len;
		s+=sprintf(s," WS:");
		s+=format_hexu(s,cw_get_hdr_ws_data(packet),plen);
		if (ws_len>20){
			s+=sprintf(s," ... (len=%d)",ws_len);
		}
	}

	

	return s-dst;	


	
abort:
	s+=sprintf(s," Incomplete...");
	return s-dst;

}
コード例 #11
0
ファイル: wtpman.c プロジェクト: yskcg/actube
static void wtpman_run(void *arg)
{


	struct wtpman *wtpman = (struct wtpman *) arg;

	wtpman->conn->seqnum = 0;
	struct conn *conn = wtpman->conn;




	/* reject connections to our multi- or broadcast sockets */
/*	if (socklist[wtpman->socklistindex].type != SOCKLIST_UNICAST_SOCKET) {
		cw_dbg(DBG_DTLS, "Dropping connection from %s to non-unicast socket.",
		       CLIENT_IP);
		wtpman_remove(wtpman);
		return;
	}
*/

	time_t timer = cw_timer_start(wtpman->conn->wait_dtls);

	/* establish dtls session */
/*	if (!wtpman_establish_dtls(wtpman)) {
		wtpman_remove(wtpman);
		return;
	}
*/

	/* dtls is established, goto join state */
	if (!wtpman_join(wtpman, timer)) {
		wtpman_remove(wtpman);
		return;
	}


	conn->msg_start = msg_start_handler;


	cw_dbg(DBG_INFO, "WTP from %s has joined with session id: %s",
			sock_addr2str_p(&conn->addr),
			format_bin2hex(conn->session_id,16));




//	cw_dbg(DBG_INFO, "Creating data thread");
//	pthread_t thread;
//	pthread_create(&thread, NULL, (void *) wtpman_run_data, (void *) wtpman);


	/* here the WTP has joined, now we assume an image data request  
	   or an configuration status request. Nothing else. 
	 */

	int rc = 0;
	while (!cw_timer_timeout(timer)
	       && wtpman->conn->capwap_state == CW_STATE_CONFIGURE) {
		rc = cw_read_messages(wtpman->conn);
		if (rc < 0) {
			if (errno != EAGAIN)
				break;
		}
	}

	if (!cw_rcok(rc)) {
		cw_dbg(DBG_INFO, "WTP Problem: %s", cw_strrc(rc));
		wtpman_remove(wtpman);
		return;

	}


	if (conn->capwap_state == CW_STATE_IMAGE_DATA) {
		wtpman_image_data(wtpman);
		return;
	}



	conn->capwap_state = CW_STATE_RUN;

	// XXX testing ...
//	DBGX("Cofig to sql", "");
	props_to_sql(conn,conn->incomming,0);
	radios_to_sql(conn);


	conn->msg_end=msg_end_handler;
	/* The main run loop */
	reset_echointerval_timer(wtpman);

	rc = 0;
	while (wtpman->conn->capwap_state == CW_STATE_RUN) {
		rc = cw_read_messages(wtpman->conn);
		if (rc < 0) {
			if (errno != EAGAIN)
				break;
		}

//		cw_dbg(DBG_X, "Time left: %d",
//		       cw_timer_timeleft(wtpman->echointerval_timer));
		if (cw_timer_timeout(wtpman->echointerval_timer)) {

			cw_dbg(DBG_INFO, "Lost connection to WTP:%s",
			       sock_addr2str_p(&conn->addr));
			break;
		}

		mavl_del_all(conn->outgoing);
		conn_clear_upd(conn,1);

//	props_to_sql(conn,conn->incomming,0);
//	radios_to_sql(conn);



		mavl_conststr_t r;
		r = db_get_update_tasks(conn, sock_addr2str(&conn->addr));
		if (r) {

			if (!conn->outgoing->count)
				continue;

			cw_dbg(DBG_INFO, "Updating WTP %s",sock_addr2str(&conn->addr));

			rc = cw_send_request(conn, CW_MSG_CONFIGURATION_UPDATE_REQUEST);
			mavl_merge(conn->config, conn->outgoing);
			mavl_destroy(conn->outgoing);
			conn->outgoing = mbag_create();
			props_to_sql(conn,conn->incomming,0);
			radios_to_sql(conn);
			mavl_destroy(r);
		}

		r = db_get_radio_tasks(conn, sock_addr2str(&conn->addr));
		if (r) {

			if (!conn->radios_upd->count)
				continue;

			cw_dbg(DBG_INFO, "Updating Radios for %s",sock_addr2str(&conn->addr));
			rc = cw_send_request(conn, CW_MSG_CONFIGURATION_UPDATE_REQUEST);


			conn_clear_upd(conn,1);

//			mavl_destroy(conn->radios_upd);
//			conn->radios_upd=mbag_i_create();


			radios_to_sql(conn);

			/*
			rc = cw_send_request(conn, CW_MSG_CONFIGURATION_UPDATE_REQUEST);
			mavl_merge(conn->config, conn->outgoing);
			mavl_destroy(conn->outgoing);
			conn->outgoing = mbag_create();
			config_to_sql(conn);
			radios_to_sql(conn);
			mavl_destroy(r);
			*/
		}



	}

	db_ping_wtp(sock_addr2str_p(&conn->addr), "");
	wtpman_remove(wtpman);
	return;
}