Beispiel #1
0
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);
		}
	}

	
	
}
Beispiel #2
0
static void wtpman_run_discovery(void *arg)
{


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

	time_t timer = cw_timer_start(10);

	extern cw_actionlist_in_t the_tree;

	wtpman->conn->capwap_state = CW_STATE_DISCOVERY;
	wtpman->conn->actions = &capwap_actions;

	wtpman->conn->outgoing = mbag_create();
	wtpman->conn->incomming = mbag_create();

	while (!cw_timer_timeout(timer)
	       && wtpman->conn->capwap_state == CW_STATE_DISCOVERY) {
		cw_read_messages(wtpman->conn);
	}

	struct mbag_item *wn = mbag_get(wtpman->conn->incomming, CW_ITEM_WTP_NAME);

	if (wn) {
//              printf("WTP Name: %s\n", wn->data);
//              exit(0);
	}

	wtpman_remove(wtpman);
	return;

}
Beispiel #3
0
static void wtpman_run_discovery(void *arg)
{
	struct wtpman *wtpman = (struct wtpman *) arg;

	time_t timer = cw_timer_start(10);

	wtpman->conn->capwap_state = CAPWAP_STATE_DISCOVERY;


	while (!cw_timer_timeout(timer)
	       && wtpman->conn->capwap_state == CAPWAP_STATE_DISCOVERY) {
		int rc;
		rc = cw_read_messages(wtpman->conn);
		if (cw_result_is_ok(rc)){
			wtpman->conn->capwap_state=CAPWAP_STATE_JOIN;
			
			cw_dbg(DBG_INFO,"Discovery has detected mods: %s %s", 
				wtpman->conn->cmod->name,wtpman->conn->bmod->name);

			wtplist_lock();
			discovery_cache_add(discovery_cache,(struct sockaddr*)&wtpman->conn->addr,
				wtpman->conn->cmod,wtpman->conn->bmod);
			wtplist_unlock();
			
		}
	}

	return;
}
Beispiel #4
0
int run()
{



	struct conn *conn = get_conn();
	conn->capwap_state = CW_STATE_RUN;

	do {

		int echo_interval = mbag_get_word(conn->config,CW_ITEM_CAPWAP_TIMERS,CAPWAP_TIMERS)&0xff;
		time_t timer = cw_timer_start(echo_interval);
		int rc;

		


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

			if ( !cw_rcok(rc))
				break;

		}
		if (rc<0 && errno == EAGAIN){
			rc = cw_send_request(conn,CW_MSG_ECHO_REQUEST);
		
			if (!cw_rcok(rc)) {
				cw_log(LOG_ERR,"Error in run state: %d %s",rc,cw_strrc(rc));
				break;
			}
			continue;
		}

		if (!cw_rcok(rc)) {
			cw_log(LOG_ERR,"Error in run state: %d %s",rc,cw_strrc(rc));
			break;
		}
		



	} while (conn->capwap_state == CW_STATE_RUN);



//      int rc = cw_send_request(conn,CW_MSG_CHANGE_STATE_EVENT_REQUEST);

//      if ( !cw_rcok(rc) ) {
//              cw_strresult(rc);
//      }

	return 0;
}
Beispiel #5
0
static int wtpman_join(void *arg, time_t timer)
{
	struct wtpman *wtpman = (struct wtpman *) arg;
	struct conn *conn = wtpman->conn;

	wtpman->conn->outgoing = mbag_create();
	wtpman->conn->incomming = mbag_create();
	conn->config = conn->incomming;
//      wtpman->conn->local = ac_config;

	mbag_set_str(conn->local, CW_ITEM_AC_NAME, conf_acname);



	wtpman->conn->capwap_state = CW_STATE_JOIN;
//	wtpman->conn->actions = &capwap_actions;

//      wtpman->conn->itemstore = mbag_create();


	cw_dbg(DBG_INFO, "Join State - %s", sock_addr2str(&conn->addr));

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

	if (rc != 0) {
		cw_log(LOG_ERR, "Error joining WTP %s", cw_strerror(rc));
		return 0;

	}


	if (wtpman->conn->capwap_state == CW_STATE_JOIN) {
		cw_dbg(DBG_MSG_ERR, "No join request from %s after %d seconds, WTP died.",
		       sock_addr2str(&wtpman->conn->addr), wtpman->conn->wait_dtls);

		return 0;
	}


	return 1;


}
Beispiel #6
0
int cw_send_request(struct conn *conn,int msg_id)
{
	time_t timer;
	int i;
	int rc;
	char sock_buf[SOCK_ADDR_BUFSIZE];
	cw_init_request(conn, msg_id);
	if ( cw_put_msg(conn, conn->req_buffer) == -1 ){
		errno=ENOMSG;
		return -1;
	}
	conn_send_msg(conn, conn->req_buffer);

	

	rc=-1;
	for (i=0; i<conn->max_retransmit && rc<0; i++){
		if ( i>0 ){
			cw_log(LOG_WARNING,"Retransmitting request ... %d",i);
		}
		timer = cw_timer_start(conn->retransmit_interval);
		while (!cw_timer_timeout(timer) && rc<0){
	
        	        rc =cw_read_messages(conn);
			if(rc<0){
				if (errno!=EAGAIN)
					break;
			}

		}
		if (rc<0){
			if(errno!=EAGAIN)
				break;
			
		}

	}

	if ( rc <0 && errno != EAGAIN) {
		cw_log(LOG_ERR,"Can't read from %s: %s",sock_addr2str(&conn->addr,sock_buf),strerror(errno));
	}
	if ( rc <0 && errno == EAGAIN) {
		errno=ETIMEDOUT;
		rc=-1;
	}

	return rc;
}
Beispiel #7
0
int dtls_gnutls_bio_wait(gnutls_transport_ptr_t ptr, unsigned int ms)
{
	struct conn * conn = (struct conn*)ptr;
	time_t timer = cw_timer_start(ms/1000);
	int rc;

	uint8_t buffer[5];

	do {
		rc = conn->recv_packet_peek(conn,buffer,sizeof(buffer));

	}while(!cw_timer_timeout(timer) && rc==GNUTLS_E_AGAIN);

	return rc;

}
Beispiel #8
0
static int wtpman_join(void *arg)
{
	int rc;
	char sock_buf[SOCK_ADDR_BUFSIZE];
	struct wtpman *wtpman = (struct wtpman *) arg;
	struct conn *conn = wtpman->conn;
	time_t timer, wait_join;

	cw_dbg(DBG_INFO, "Join State - %s", sock_addr2str(&conn->addr,sock_buf));
	
	wait_join = cw_ktv_get_word(conn->global_cfg,"wait-join",CAPWAP_WAIT_JOIN);

	timer = cw_timer_start(wait_join);


	while (!cw_timer_timeout(timer) && wtpman->conn->capwap_state == CAPWAP_STATE_JOIN) {
		rc = cw_read_messages(wtpman->conn);
		if (rc < 0) {
			if (errno == EAGAIN)
				continue;
				
			break;
		}
		cw_dbg_ktv_dump(conn->remote_cfg,DBG_INFO,
		"-------------dump------------",
		"DMP","---------end dump --------");
	}

	if (rc != 0) {
		cw_log(LOG_ERR, "Error joining WTP %s", cw_strerror(rc));
		return 0;
	}


	if (wtpman->conn->capwap_state != CAPWAP_STATE_JOIN_COMPLETE) {
		cw_dbg(DBG_MSG_ERR, "No join request from %s after %d seconds, WTP died.",
		       sock_addr2str(&wtpman->conn->addr,sock_buf), wait_join);

		return 0;
	}


	return 1;


}
int dtls_openssl_connect(struct conn *conn)
{
	if (!conn->dtls_data)
		conn->dtls_data =
		    dtls_openssl_data_create(conn, DTLSv1_client_method(),
					     dtls_openssl_bio_method());

	struct dtls_openssl_data *d = (struct dtls_openssl_data *) conn->dtls_data;
	if (!d)
		return 0;

//	if (conn->dtls_psk)
//		SSL_set_psk_client_callback(d->ssl, psk_client_cb);

	int rc;

	errno =0;
	time_t timer = cw_timer_start(10);
	do {
		rc = SSL_connect(d->ssl);
	}while(rc!=1 && errno==EAGAIN && !cw_timer_timeout(timer));
	

	if (rc == 1) {
		cw_dbg(DBG_DTLS,"SSL connect successfull!");
		conn->read = dtls_openssl_read;
		conn->write = dtls_openssl_write;
		return 1;
	}

	rc = dtls_openssl_log_error(0, rc, "DTLS connect");




	return 0;
}
Beispiel #10
0
static int run_discovery(struct conn *conn)
{
//      conn->incomming = mbag_create();


	conn->capwap_state = CW_STATE_DISCOVERY;
	mbag_set_byte(conn->outgoing, CW_ITEM_DISCOVERY_TYPE,
			      CW_DISCOVERY_TYPE_UNKNOWN);


	cw_init_request(conn, CW_MSG_DISCOVERY_REQUEST);
	cw_put_msg(conn, conn->req_buffer);
	conn_send_msg(conn, conn->req_buffer);


	time_t timer = cw_timer_start(0);


	while (!cw_timer_timeout(timer)
	       && conn->capwap_state == CW_STATE_DISCOVERY) {
		mavl_del_all(conn->incomming);

		int rc = cw_read_from(conn);

		if (rc<0) {
			if (errno==EAGAIN)
				continue;

			cw_log(LOG_ERROR,"Error reading messages: %s",strerror(errno));
			break;
		}
	}


	mbag_t discs;
	discs = mbag_get_mavl(conn->remote, CW_ITEM_DISCOVERIES);


	if (!discs) {
		cw_log(LOG_ERR,"No discovery responses received");
		return 0;
	}

	int i;

	cw_aciplist_t list = cw_select_ac(conn, discs);



	DEFINE_AVLITER(ii,list);
	avliter_foreach(&ii){
		cw_acip_t * ip = avliter_get(&ii);

	}

	

	mavl_del_all(conn->remote);

	mbag_set_mavl(conn->local,CW_ITEM_CAPWAP_CONTROL_IP_ADDRESS_LIST,list);

	return 1;
}
Beispiel #11
0
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;
}
Beispiel #12
0
int dtls_gnutls_accept(struct conn *conn)
{
	char sock_buf[SOCK_ADDR_BUFSIZE];
	char cookie_buf[SOCK_ADDR_BUFSIZE];
	struct dtls_gnutls_data *d;
	uint8_t buffer[2048];
	int tlen, rc;
	time_t c_timer;
	int bits;

	gnutls_datum_t cookie_key;
	gnutls_dtls_prestate_st prestate;




	gnutls_key_generate(&cookie_key, GNUTLS_COOKIE_KEY_SIZE);
	cw_dbg(DBG_DTLS, "Session cookie for %s generated: %s",
	       sock_addr2str(&conn->addr, sock_buf),
	       sock_hwaddrtostr((uint8_t *) (&cookie_key),
				sizeof(cookie_key), cookie_buf, ""));


	memset(&prestate, 0, sizeof(prestate));

	tlen = dtls_gnutls_bio_read(conn, buffer, sizeof(buffer));

	gnutls_dtls_cookie_send(&cookie_key, &conn->addr, sizeof(conn->addr),
				&prestate, (gnutls_transport_ptr_t) conn,
				dtls_gnutls_bio_write);

	rc = -1;



	c_timer = cw_timer_start(10);

	while (!cw_timer_timeout(c_timer)) {

		tlen = conn_q_recv_packet_peek(conn, buffer, sizeof(buffer));

		if (tlen < 0 && errno == EAGAIN)
			continue;
		if (tlen < 0) {
			/* something went wrong, we should log a message */
			continue;
		}

		rc = gnutls_dtls_cookie_verify(&cookie_key,
					       &conn->addr,
					       sizeof(conn->addr), buffer + 4, tlen - 4,
					       &prestate);

		if (rc < 0) {
			cw_dbg(DBG_DTLS, "Cookie couldn't be verified: %s",
			       gnutls_strerror(rc));
			dtls_gnutls_bio_read(conn, buffer, sizeof(buffer));
			continue;
		}

		break;

	}

	if (rc < 0) {
		cw_log(LOG_ERR, "Cookie couldn't be verified: %s", gnutls_strerror(rc));
		return 0;
	}


	cw_dbg(DBG_DTLS, "Cookie verified! Starting handshake with %s ...",
	       sock_addr2str(&conn->addr, sock_buf));



	d = dtls_gnutls_data_create(conn, GNUTLS_SERVER | GNUTLS_DATAGRAM);
	if (!d)
		return 0;


	if (conn->dtls_psk_enable) {
		gnutls_psk_server_credentials_t cred;
		rc = gnutls_psk_allocate_server_credentials(&cred);
		if (rc != 0) {
			cw_log(LOG_ERR,"gnutls_psk_allocate_server_credentials() failed.");
		}
		/* GnuTLS will call psk_creds to ask for the key associated with the
		client's username.*/
		gnutls_psk_set_server_credentials_function(cred, psk_creds);
		/* // Pass the "credentials" to the GnuTLS session. GnuTLS does NOT make an
		// internal copy of the information, so we have to keep the 'cred' structure
		// in memory (and not modify it) until we're done with this session.*/
		rc = gnutls_credentials_set(d->session, GNUTLS_CRD_PSK, cred);
		if (rc != 0) {
			cw_log(LOG_ERR,"gnutls_credentials_set() failed.\n");
		}

	}




	/* Generate Diffie-Hellman parameters - for use with DHE
	 * kx algorithms. When short bit length is used, it might
	 * be wise to regenerate parameters often.
	 */
	/*bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY); */
	bits = conn->dtls_dhbits;

	gnutls_dh_params_init(&d->dh_params);

	cw_dbg(DBG_DTLS, "Generating DH params, %d", bits);
	gnutls_dh_params_generate2(d->dh_params, bits);
	cw_dbg(DBG_DTLS, "DH params generated, %d", bits);
	gnutls_certificate_set_dh_params(d->x509_cred, d->dh_params);

	gnutls_certificate_server_set_request(d->session, GNUTLS_CERT_REQUEST);
	gnutls_dtls_prestate_set(d->session, &prestate);

	c_timer = cw_timer_start(10);
	do {
		rc = gnutls_handshake(d->session);
	} while (!cw_timer_timeout(c_timer) && rc == GNUTLS_E_AGAIN);



	if (rc < 0) {
		cw_log(LOG_ERR, "Error in handshake with %s: %s",
		       sock_addr2str(&conn->addr, sock_buf), gnutls_strerror(rc));
		return 0;
	}


	cw_dbg(DBG_DTLS, "Handshake with %s successful.",
	       sock_addr2str(&conn->addr, sock_buf));

	conn->dtls_data = d;
	conn->read = dtls_gnutls_read;
	conn->write = dtls_gnutls_write;

	return 1;
}
Beispiel #13
0
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;
}