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; }
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; }
int ac_global_init() { // mod_set_actions_registered_cb(setup_actions); ac_config = mbag_create(); mbag_set_str(ac_config, CW_ITEM_AC_NAME, conf_acname); mbag_set_ptr(ac_config, CW_ITEM_AC_STATUS, &ac_status); ac_status.stations = 0; ac_status.limit = 1000; ac_status.active_wtps = 10; ac_status.max_wtps = 200; ac_status.security = CW_FLAG_AC_SECURITY_X | CW_FLAG_AC_SECURITY_S; ac_status.rmac_field = CW_FLAG_RMAC_SUPPORTED; ac_status.dtls_policy = CW_FLAG_DTLS_POLICY_C; // | CW_FLAG_DTLS_POLICY_D; mbag_set_bstrv(ac_config, CW_ITEM_AC_HARDWARE_VERSION, 0, bstr_data(conf_hardware_version), bstr_len(conf_hardware_version)); mbag_set_bstrv(ac_config, CW_ITEM_AC_SOFTWARE_VERSION, 0, bstr_data(conf_software_version), bstr_len(conf_software_version)); mbag_set_str(ac_config,CW_ITEM_AC_IMAGE_DIR,conf_image_dir); // mbag_set_avltree(ac_config, CW_ITEM_AC_IP_LIST, aciplist); mbag_set_fun(ac_config, CW_ITEM_CAPWAP_CONTROL_IP_ADDRESS_LIST, get_iplist,release_iplist,(void*)771); return 1; }
int cw_in_radio_generic(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len, struct sockaddr *from) { const cw_itemdef_t * idef = cw_itemdef_get(conn->actions->radioitems,a->item_id,CW_ITEM_NONE); if (!idef){ cw_log(LOG_ERR,"No definition found for %s",a->item_id); return 0; } int rid = cw_get_byte(data); mbag_t radio = mbag_i_get_mbag(conn->radios, rid, NULL); if (!radio) { if (a->vendor_id != 0 || ( (a->vendor_id == 0) && (a->msg_id != CW_MSG_DISCOVERY_REQUEST && a->msg_id != CW_MSG_JOIN_REQUEST) )) { cw_dbg(DBG_ELEM_ERR, "Radio not found %d", rid); return 0; } mbag_i_set_mbag(conn->radios,rid,mbag_create()); radio = mbag_i_get_mbag(conn->radios, rid, NULL); } int rc = mbag_set_from_buf(radio,idef->type,a->item_id,data+1,len-1); if (!rc){ cw_log(LOG_ERR, "Can't handle item type %s in definition for incomming msg %d (%s) - %d, cw_in_radio_generic.", idef->type->name, a->msg_id, cw_strmsg(a->msg_id), a->elem_id); } return rc; }
/** * Basic initialization of a conn object * @param conn conn object to initialize */ void conn_init(struct conn * conn) { memset(conn,0,sizeof(struct conn)); conn->retransmit_interval=CAPWAP_RETRANSMIT_INTERVAL; conn->max_retransmit=CAPWAP_MAX_RETRANSMIT; conn->wait_dtls=CAPWAP_WAIT_DTLS; conn->wait_join=CAPWAP_WAIT_JOIN; conn->mtu_discovery=1; conn->capwap_mode = CW_MODE_AUTO; conn->strict_capwap=1; conn->remote = mbag_create(); conn->process_packet=conn_process_packet; conn->process_message=process_message; conn->config = mbag_create(); conn->config_upd=mbag_create(); }
static void update_radios(struct conn * conn, mbag_t result) { MAVLITER_DEFINE (it,conn->radios_upd); mavliter_foreach(&it){ struct mbag_item * item = mavliter_get(&it); int rid = item->iid; mbag_t radio = mbag_i_get_mbag(conn->radios,rid,NULL); if (!radio){ cw_dbg(DBG_ELEM_ERR,"Can't find radio with id %d",rid); continue; } mbag_t iresult = mbag_create(); mbag_i_set_mbag(result,rid,iresult); update_radio(conn,rid,item->data,radio,iresult); } }
int cw_in_check_disc_resp(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len,struct sockaddr *from) { cw_action_in_t *mlist[20]; // int n = cw_check_missing_mand(mlist, conn, a); //cw_dbg(DBG_INFO,"This response came from: %s",sock_addr2str(&conn->addr)); /* if mandatory elements are missing, ignore this response */ /* if (n && conn->strict_capwap) { cw_dbg_missing_mand(DBG_MSG_ERR, conn, mlist, n, a); cw_dbg(DBG_MSG_ERR, "Ignoring Discovery Response from %s - missing mandatory elements.", sock_addr2str(from)); errno = EAGAIN; return -1; } if (n) { cw_dbg_missing_mand(DBG_RFC, conn, mlist, n, a); } */ /* we have all AC information in the incomming buffer */ mbag_t discs; discs = mbag_get_mavl_c(conn->remote, CW_ITEM_DISCOVERIES, mbag_i_create); //mavl_del_all(discs); //exit(0); if ( !discs ) { cw_log(LOG_ERR,"Can't allocate store for disc resp"); errno = ENOMEM; return -1; } mbag_i_set_mavl(discs,discs->count,conn->incomming); conn->incomming = mbag_create(); return 0; }
static void do_update(struct conn * conn) { if (!update) return; update=0; mbag_t result = mbag_create(); update_radios(conn,result); cw_dbg(DBG_INFO, "Saving configuration ..."); cfg_to_json(); /* Change State ... */ int rc = cw_send_request(conn,CW_MSG_CHANGE_STATE_EVENT_REQUEST); if ( !cw_rcok(rc) ) { cw_strresult(rc); return ; } }
int cw_in_radio_generic(struct conn *conn, struct cw_action_in *a, uint8_t * data, int len, struct sockaddr *from) { if (!check_len(conn, a, data, len, from)) return 0; int rid = cw_get_byte(data); mbag_t radio = mbag_i_get_mbag(conn->radios, rid, NULL); if (!radio) { if (a->vendor_id != 0 || ( (a->vendor_id == 0) && (a->msg_id != CW_MSG_DISCOVERY_REQUEST && a->msg_id != CW_MSG_JOIN_REQUEST) )) { cw_dbg(DBG_ELEM_ERR, "Radio not found %d", rid); return 0; } mbag_i_set_mbag(conn->radios,rid,mbag_create()); } return 1; }
int main() { signal (SIGINT, sig_handler); wtpconf_preinit(); if (!read_config("./wtp_uci.conf")) { return 1; } // cw_dbg_opt_level = conf_dbg_level; if (!wtpconf_init()){ return 1; }; cw_dbg_opt_display = DBG_DISP_ASC_DMP | DBG_DISP_COLORS; dtls_init(); the_conn = conn_create_noq(-1, NULL); struct conn *conn = the_conn; conn->radios = mbag_i_create(); conn->radios_upd=mbag_i_create(); mbag_i_set_mbag(conn->radios,0,mbag_create()); mbag_i_set_mbag(conn->radios_upd,0,mbag_create()); #define CWMOD "cisco" #define CWBIND "cisco" //#define CWMOD "capwap" //#define CWBIND "capwap80211" struct mod_wtp *mod = modload_wtp(CWMOD); if (!mod) { printf("Can't load mod capwap\n"); exit(0); } mod->init(); mod->register_actions(&capwap_actions,MOD_MODE_CAPWAP); mod = modload_wtp(CWBIND); if (!mod) { printf("Can't load mod capwap80211\n"); exit(0); } int rc = mod->register_actions(&capwap_actions,MOD_MODE_BINDINGS); conn->detected = 1; conn->dtls_verify_peer=0; conn->dtls_mtu = 12000; conn->actions = &capwap_actions; conn->outgoing = mbag_create(); conn->incomming = mbag_create(); conn->local = mbag_create(); conn->config = mbag_create(); the_conn->strict_capwap = 0; cfg_from_json(conn); setup_conf(conn); mbag_t r; // r = mbag_i_get_mbag(conn->radios,0,NULL); r = conn->radios; MAVLITER_DEFINE(it,r); mavliter_foreach(&it){ struct mbag_item *i=mavliter_get(&it); printf("RID = %d\n",i->iid); printf("DATA: %p\n",i->data); mbag_t radio= (mbag_t)i->data; struct mbag_item *mri = mbag_get(radio,CW_RADIOITEM80211_WTP_RADIO_INFORMATION); if (!mri){ printf("Setting to 8 %p %p\n",mri,r); mbag_set_dword(radio,CW_RADIOITEM80211_WTP_RADIO_INFORMATION,1); } else{ printf("MRI %p\n",mri); } } mod_init_config(mod,conn->config); cfg_to_json(); mbag_t mb = mbag_get_mbag(conn->config, CW_ITEM_WTP_BOARD_DATA, NULL); printf("mbag %p\n", mb); cw_acpriolist_t acprios = cw_acpriolist_create(); cw_acpriolist_set(acprios, "Master AC", strlen("Master AC"), 1); cw_acpriolist_set(acprios, "AC8new", strlen("AC8new"), 12); mbag_set_byte(conn->local, CW_ITEM_WTP_MAC_TYPE, CW_WTP_MAC_TYPE_SPLIT); mbag_set_byte(conn->local, CW_ITEM_WTP_FRAME_TUNNEL_MODE, CW_WTP_FRAME_TUNNEL_MODE_E); conn->wbid=1; // cw_set_msg_end_callback(conn->actions,CW_STATE_RUN,CW_MSG_CONFIGURATION_UPDATE_REQUEST,handle_update_req); if (!discovery()) return -1; if (!join()) return -1; if (!configure()) return -1; cw_dbg(DBG_X,"Saveing config 0"); cfg_to_json(); changestate(); run(); //image_update(); return 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; }