#include "p2p_test.h" unsigned int wps_pin_checksum(unsigned int pin) { unsigned int accum = 0; while( pin ) { accum += pin % 10; pin /= 10; accum += 3 * (pin % 10); pin /= 10; } return( accum % 10 ); } char lower(char s) { if(('A' <= s) && (s <= 'Z')) return ( s = 'a' + (s - 'A') ); return s; } int p2p_check_success(struct p2p *p) { int ret = 0; if( p->status == P2P_STATE_GONEGO_OK ) ret = 1; return ret; } int read_all_sta(struct p2p *p) { int sta_count = 0; FILE *pf; memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "%s all_sta > supp_status.txt", p->apcli_path); system( p->cmd ); pf = fopen( "./supp_status.txt", "r" ); if ( pf ) { while( !feof( pf ) ){ memset( p->parse, 0x00, CMD_SZ ); fgets( p->parse, CMD_SZ, pf ); if( strncmp( p->parse, "dot11RSNAStatsSTAAddress=", 25) == 0 ) { sta_count++; if( p->no_sta_connected == sta_count ) return _TRUE; } } fclose( pf ); } return _FALSE; } void do_wps(struct p2p *p) { FILE *pf = NULL; int ret = _FALSE, parsing_ok = _FALSE; do { memset( p->cmd, 0x00, CMD_SZ ); if( p->ap_open == _TRUE ) { if(p->wps_info==1 || p->wps_info==2) sprintf( p->cmd, "%s wps_pin any %d > supp_status.txt", p->apcli_path, p->pin); else if(p->wps_info==3) sprintf( p->cmd, "%s wps_pbc any > supp_status.txt", p->apcli_path); } else if(p->wpa_open == _TRUE) { if(p->connect_go==1) { if(p->wps_info==1 || p->wps_info==2) sprintf( p->cmd, "%s wps_pin %s %d > supp_status.txt ", p->wpacli_path, p->peer_devaddr, p->pin); else if(p->wps_info==3) sprintf( p->cmd, "%s wps_pbc %s > supp_status.txt ", p->wpacli_path, p->peer_devaddr); } else if( strncmp(p->peer_ifaddr, "00:00:00:00:00:00", 17)==0 ) { if(p->wps_info==1 || p->wps_info==2) sprintf( p->cmd, "%s wps_pin any %d > supp_status.txt ", p->wpacli_path, p->pin); else if(p->wps_info==3) sprintf( p->cmd, "%s wps_pbc any > supp_status.txt ", p->wpacli_path); } else { if(p->wps_info==1 || p->wps_info==2) sprintf( p->cmd, "%s wps_pin %s %d > supp_status.txt ", p->wpacli_path, p->peer_ifaddr, p->pin); else if(p->wps_info==3) sprintf( p->cmd, "%s wps_pbc %s > supp_status.txt ", p->wpacli_path, p->peer_ifaddr); } } system( p->cmd ); pf = fopen( "./supp_status.txt", "r" ); if ( pf ) { while( !feof( pf ) ){ memset(p->parse, 0x00, CMD_SZ); fgets(p->parse, CMD_SZ, pf); if(p->ap_open == _TRUE) { if( (p->wps_info==1 || p->wps_info==2) && (strncmp(p->parse, "", 2) == 0) ) parsing_ok = _TRUE; else if( (p->wps_info==3) && (strncmp(p->parse, "OK", 2) == 0) ) parsing_ok = _TRUE; } else if(p->wpa_open == _TRUE) { if( (p->wps_info==1 || p->wps_info==2) && (strncmp(p->parse, "Selected", 8) == 0) ) parsing_ok = _TRUE; else if( (p->wps_info==3) && (strncmp(p->parse, "OK", 2) == 0) ) parsing_ok = _TRUE; } if( parsing_ok == _TRUE ) { ret = _TRUE; p->wpsing = _TRUE; } } fclose( pf ); } if( ret == 0 ) usleep( HOSTAPD_INIT_TIME ); } while( ret == 0 ); } void p2p_enable(struct p2p *p) { p->have_p2p_dev = 0; p->connect_go = 0; if(p->enable == -1 ) { if(p->wpa_open == _TRUE){ p->wpa_open = _FALSE; system("killall wpa_supplicant"); #ifdef DHCP system("killall dhclient"); #endif } if(p->ap_open == _TRUE){ p->ap_open = _FALSE; system("killall hostapd"); #ifdef DHCP system("killall dhcpd"); #endif } memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_set enable=0", p->ifname); system( p->cmd ); return; } p->p2p_get=0; memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_set enable=%d", p->ifname, p->enable); system( p->cmd ); if( p->enable == P2P_ROLE_DISABLE ) { p->wps_info = 0; p->pin = 12345670; p2p_status(p, 0); p2p_role(p, 0); if(p->res == 0) { p->res = 1; } if(p->res_go == 0) { p->res_go = 1; } p->wpa_open = _FALSE; system("killall wpa_supplicant"); #ifdef DHCP system("killall dhclient"); #endif system("clear"); p->ap_open = _FALSE; system("killall hostapd"); #ifdef DHCP system("killall dhcpd"); #endif system("clear"); } else if( p->enable == P2P_ROLE_DEVICE ) { char msg[5] = "NULL"; #ifdef P2P_AUTO p->res = pthread_create(&p->pthread, NULL, &polling_status, (void *)p); #endif if( p->res !=0 ) { p->p2p_get=1; memset( p->print_line, 0x00, CMD_SZ ); sprintf( p->print_line, "Thread creation failed" ); } if(p->wpa_open == _TRUE){ p->wpa_open = _FALSE; system("killall wpa_supplicant"); #ifdef DHCP system("killall dhclient"); #endif } if(p->ap_open == _TRUE){ p->ap_open = _FALSE; system("killall hostapd"); #ifdef DHCP system("killall dhcpd"); #endif } p->intent = 1; p2p_intent(p); p2p_set_opch(p, NULL, 0); usleep(50000); p2p_softap_ssid(p, NULL, 0); p2p_setDN(p); p2p_role(p, 0); p2p_scan(p); } else if( p->enable == P2P_ROLE_CLIENT ) { if(p->ap_open == _TRUE){ p->ap_open = _FALSE; system("killall hostapd"); #ifdef DHCP system("killall dhcpd"); #endif } p2p_status(p, 0); p2p_role(p, 0); p2p_intent(p); } else if( p->enable == P2P_ROLE_GO ) { if(p->wpa_open == _TRUE){ p->wpa_open = _FALSE; system("killall wpa_supplicant"); #ifdef DHCP system("killall dhclient"); #endif } p2p_status(p, 0); p2p_role(p, 0); p2p_intent(p); p2p_set_opch(p, NULL, 0); usleep(50000); p2p_softap_ssid(p, NULL, 0); p2p_setDN(p); if(p->ap_open != _TRUE) { memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "%s -B %s > temp.txt",p->ap_path, p->ap_conf); system( p->cmd ); p->ap_open = _TRUE; } #ifdef P2P_AUTO p->res_go = pthread_create(&p->pthread_go, NULL, &polling_client, (void *)p); #endif if( p->res_go != 0 ) { p->p2p_get=1; memset( p->print_line, 0x00, CMD_SZ ); sprintf( p->print_line, "Thread creation failed" ); } } } void p2p_scan(struct p2p *p) { p->p2p_get=0; if( p->enable >= P2P_ROLE_DEVICE ) { p->have_p2p_dev=1; memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwlist %s scan > scan.txt", p->ifname ); system( p->cmd ); p2p_status(p, 0); } else { p->p2p_get=1; memset( p->print_line, 0x00, CMD_SZ ); sprintf( p->print_line, "%s", p->scan_msg ); } } void scan_result(struct p2p *p) { FILE *pf=NULL; int no_dev=0; char cms[30] = { 0x00 }; char dns[SSID_SZ] = { 0x00 }; char parse[100] = { 0x00 }; struct scan *pscan_pool; pf = fopen( "./scan.txt", "r" ); if ( pf ) { p->count_line=0; while( (!feof( pf )) && (no_dev < SCAN_POOL_NO)) { memset( parse, 0x00, CMD_SZ ); fgets( parse, CMD_SZ, pf ); if(parse[0] == '\n' || parse[0] == '\0') break; if( strncmp(parse+10, "Scan completed :", 16) == 0 ) { printf("* NO DEVICE NAME BSSID GO CONFIG METHOD *\n"); p->count_line++; } else if( strncmp(parse+20, "Address:", 8) == 0 ) { pscan_pool = &p->scan_pool[no_dev]; memset( pscan_pool->addr, 0x00, sizeof(struct scan) ); strncpy( pscan_pool->addr, parse+29, 17); } else if( strncmp(parse+20, "ESSID:", 6) == 0 ) { pscan_pool = &p->scan_pool[no_dev]; p2p_wps_cm(p, pscan_pool->addr, cms); p2p_device_name(p, pscan_pool->addr, dns); if( strncmp(parse+26, "\"DIRECT-\"", 9) == 0 ) { printf("*[%02d] %-25s %s %-38s*\n",no_dev+1, dns, pscan_pool->addr, cms); } else { printf("*[%02d] %-25s %s * %-38s*\n",no_dev+1, dns, pscan_pool->addr, cms); pscan_pool->go = 1; } p->count_line++; no_dev++; } } if( p->count_line < (SCAN_POOL_NO + 1) ) { for(p->count_line; p->count_line < SCAN_POOL_NO+1; p->count_line++ ) printf("* *\n"); } fclose( pf ); } } void p2p_setDN(struct p2p *p) { memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_set setDN=%s", p->ifname, p->dev_name); system( p->cmd ); } void p2p_intent(struct p2p *p) { p->p2p_get=0; memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_set intent=%d", p->ifname, p->intent); system( p->cmd ); } void p2p_wpsinfo(struct p2p *p) { p->p2p_get=0; memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_set got_wpsinfo=%d", p->ifname, p->wps_info); system( p->cmd ); } void p2p_pincode(struct p2p *p, char *ins_no, char *ins_no_again) { int pin_check=0; p->p2p_get=0; p->show_scan_result = 1; ui_screen(p); printf("%s", ins_no); scanf("%d",&pin_check); while( wps_pin_checksum(pin_check) != 0 ) { p->show_scan_result = 1; ui_screen(p); printf("%s", ins_no_again); scanf("%d",&pin_check); } p->pin = pin_check; } void p2p_devaddr(struct p2p *p) { int c; struct scan *pscan_pool; p->p2p_get=0; scanf("%d", &c); pscan_pool = &p->scan_pool[c-1]; strncpy(p->peer_devaddr, pscan_pool->addr, 17); if( pscan_pool->go == 1) p->connect_go = 1; } void p2p_role(struct p2p *p, int flag) { FILE *pf=NULL; memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_get role > status.txt", p->ifname); system( p->cmd ); pf = fopen( "./status.txt", "r" ); if ( pf ) { while( !feof( pf ) ){ memset( p->parse, 0x00, CMD_SZ ); fgets( p->parse, CMD_SZ, pf ); if( strncmp( p->parse, "Role", 4) == 0 ) { p->role = atoi( &p->parse[ 5 ] ); if(flag==1){ p->p2p_get=1; sprintf( p->print_line, "Role=%s", naming_role(p->role)); } break; } } fclose( pf ); } } void p2p_status(struct p2p *p, int flag) { FILE *pf=NULL; memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_get status > status.txt", p->ifname); system( p->cmd ); pf = fopen( "./status.txt", "r" ); if ( pf ) { while( !feof( pf ) ){ memset( p->parse, 0x00, CMD_SZ ); fgets( p->parse, CMD_SZ, pf ); if( strncmp( p->parse, "Status", 6) == 0 ) { p->status = atoi( &p->parse[ 7 ] ); if(flag==1){ p->p2p_get=1; sprintf( p->print_line, "Status=%s", naming_status(p->status)); } break; } } fclose( pf ); } } void change_hostapd_op_ch(struct p2p *p, int op_ch) { FILE *pfin = NULL; FILE *pfout = NULL; char parse[CMD_SZ] = { 0x00 }; char cmd[CMD_SZ] = { 0x00 }; pfin = fopen( p->ap_conf, "r" ); pfout = fopen( "./p2p_hostapd_temp.conf", "w" ); if( pfin && pfout ) { while( !feof( pfin ) ){ memset( parse, 0x00, CMD_SZ ); fgets( parse, CMD_SZ, pfin ); if(strncmp(parse, "channel=", 8) == 0) { memset(parse, 0x00, CMD_SZ); sprintf( parse, "channel=%d\n", op_ch ); fputs( parse, pfout ); } else fputs(parse, pfout); } } else { return; } if( pfin != NULL ) fclose( pfin ); if( pfout != NULL ) fclose( pfout ); memset( cmd, 0x00, CMD_SZ); sprintf( cmd, "rm -rf %s", p->ap_conf ); system( cmd ); memset( cmd, 0x00, CMD_SZ); sprintf( cmd, "mv ./p2p_hostapd_temp.conf %s", p->ap_conf ); system( cmd ); return; } void p2p_get_opch(struct p2p *p) { FILE *pf=NULL; int peer_op_ch = 0; memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_get op_ch > cm.txt", p->ifname); system( p->cmd ); pf = fopen( "./cm.txt", "r" ); if ( pf ) { while( !feof( pf ) ){ memset( p->parse, 0x00, CMD_SZ ); fgets( p->parse, CMD_SZ, pf ); if( strncmp( p->parse, "Op_ch", 5) == 0 ) { peer_op_ch = atoi( &p->parse[ 6 ] ); if( peer_op_ch != p->op_ch ) { change_hostapd_op_ch( p, peer_op_ch ); } break; } } fclose( pf ); } } void p2p_prov_disc_no_addr(struct p2p *p, char *msg) { p->p2p_get=1; memset( p->print_line, 0x00, CMD_SZ ); sprintf( p->print_line, "%s", msg); } #ifdef P2P_AUTO void p2p_prov_disc(struct p2p *p, char *msg, char *dis_msg, char *label_msg) { int wps_cm, retry_count=0; char prov[100] = { 0x00 }; p->p2p_get=0; p->show_scan_result = 1; ui_screen(p); printf("%s", msg); scanf("%d",&wps_cm); if(p->res == 0) { p->res = 1; } memset( p->cmd, 0x00, CMD_SZ ); if( wps_cm == 0 ) sprintf( p->cmd, "iwpriv %s p2p_set prov_disc=%s_display", p->ifname, p->peer_devaddr); else if( wps_cm == 1 ) sprintf( p->cmd, "iwpriv %s p2p_set prov_disc=%s_keypad", p->ifname, p->peer_devaddr); else if( wps_cm == 2 ) sprintf( p->cmd, "iwpriv %s p2p_set prov_disc=%s_pbc", p->ifname, p->peer_devaddr); else if( wps_cm == 3 ) sprintf( p->cmd, "iwpriv %s p2p_set prov_disc=%s_label", p->ifname, p->peer_devaddr); system( p->cmd ); strcpy( prov, p->cmd ); usleep(500000); p2p_status( p, 0 ); while( p->status != P2P_STATE_RX_PROVISION_DIS_RSP && retry_count < MAX_PROV_RETRY) { usleep( PROV_WAIT_TIME ); retry_count++; p2p_status( p, 0 ); if( (retry_count % PROV_RETRY_INTERVAL) == 0) system( prov ); } if( p->status == P2P_STATE_RX_PROVISION_DIS_RSP ) { switch(wps_cm) { case 0: p->wps_info=1; break; case 1: p->wps_info=2; break; case 2: p->wps_info=3; break; case 3: p->wps_info=1; break; } if( wps_cm==1 || wps_cm==2 ) { p2p_wpsinfo(p); if(p->connect_go == 1) p2p_client_mode(p); else p2p_set_nego(p); } else if( wps_cm==0 || wps_cm==3 ) { ui_screen(p); if( wps_cm ==0 ) printf("%s", dis_msg); else if( wps_cm == 3 ) printf("%s", label_msg); scanf("%d",&p->pin); p2p_wpsinfo(p); if(p->connect_go == 1) p2p_client_mode(p); else p2p_set_nego(p); } } else { p->p2p_get = 1; memset( p->print_line, 0x00, CMD_SZ ); sprintf( p->print_line, "Issue provision discovery fail" ); ui_screen(p); #ifdef P2P_AUTO pthread_create(&p->pthread, NULL, &polling_status, (void *)p); #endif } } #else // This mode is without the following procedures: // 1.set config method // 2.start group negotiation // 3.start wpa_supplicant or hostapd void p2p_prov_disc(struct p2p *p, char *msg, char *dis_msg, char *label_msg) { int wps_cm; p->p2p_get=0; p->show_scan_result = 1; ui_screen(p); printf("%s", msg); scanf("%d",&wps_cm); memset( p->cmd, 0x00, CMD_SZ ); if( wps_cm == 0 ) sprintf( p->cmd, "iwpriv %s p2p_set prov_disc=%s_display", p->ifname, p->peer_devaddr); else if( wps_cm == 1 ) sprintf( p->cmd, "iwpriv %s p2p_set prov_disc=%s_keypad", p->ifname, p->peer_devaddr); else if( wps_cm == 2 ) sprintf( p->cmd, "iwpriv %s p2p_set prov_disc=%s_pbc", p->ifname, p->peer_devaddr); else if( wps_cm == 3 ) sprintf( p->cmd, "iwpriv %s p2p_set prov_disc=%s_label", p->ifname, p->peer_devaddr); system( p->cmd ); } #endif void p2p_set_nego(struct p2p *p) { FILE *pf=NULL; int retry_count = 0, success = 0; int retry = NEGO_RETRY_INTERVAL, query = NEGO_QUERY_INTERVAL; p->p2p_get=1; memset( p->print_line, 0x00, CMD_SZ ); strcpy( p->print_line, p->nego_msg); ui_screen(p); memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_set nego=%s ", p->ifname, p->peer_devaddr); system( p->cmd ); usleep( PRE_NEGO_INTERVAL ); p2p_status(p, 0); while( !p2p_check_success(p) && (retry_count < 120 / NEGO_QUERY_INTERVAL )) { retry_count++; if( (retry_count % ( retry / query ) )==0 ) { memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_set nego=%s ", p->ifname, p->peer_devaddr); system( p->cmd ); usleep( NEGO_QUERY_INTERVAL ); p2p_status(p, 1); } else { ui_screen(p); usleep( NEGO_QUERY_INTERVAL ); p2p_status(p, 1); } } if( p2p_check_success(p) ) { p2p_role(p ,0); p->p2p_get = 1; memset( p->print_line, 0x00, CMD_SZ ); sprintf( p->print_line, "%s", p->ok_msg ); p2p_ifaddr(p); ui_screen(p); if( p->role == P2P_ROLE_CLIENT ) { p2p_client_mode(p); } else if( p->role == P2P_ROLE_GO ) { p2p_get_opch(p); p2p_go_mode(p); } } else { p->p2p_get = 1; p2p_status(p, 0); memset( p->print_line, 0x00, CMD_SZ ); sprintf( p->print_line, "Status= %d, %s", p->status, p->fail_msg ); ui_screen(p); #ifdef P2P_ATUO pthread_create(&p->pthread, NULL, &polling_status, (void *)p); #endif } } //After negotiation success, get peer device's interface address. void p2p_ifaddr(struct p2p *p) { FILE *pf=NULL; char addr_12[12] = { 0x00 }; int i; /* peer_ifaddr */ memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_get peer_ifa > status.txt", p->ifname); system( p->cmd ); pf = fopen( "./status.txt", "r" ); if ( pf ) { while( !feof( pf ) ){ memset( p->parse, 0x00, CMD_SZ ); fgets( p->parse, CMD_SZ, pf ); if( strncmp( p->parse, "MAC", 3) == 0 ) { strncpy( p->peer_ifaddr, p->parse+4, 17 ); break; } } fclose( pf ); } } void p2p_client_mode(struct p2p *p) { FILE *pf = NULL; int count = 0, ret = 0; int inactive_count = 0, inactive_restart = 0; if(p->wpa_open==_TRUE) return; else p->wpa_open = _TRUE; p2p_ifaddr(p); memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "%s -i %s -c %s -B ",p->wpa_path, p->ifname, p->wpa_conf); system( p->cmd ); p->p2p_get=1; memset( p->print_line, 0x00, CMD_SZ ); strcpy( p->print_line, "Start wpa_supplicant"); ui_screen(p); usleep( SUPPLICANT_INIT_TIME ); do_wps(p); usleep( SUPPLICANT_INTERVAL ); while( count < WPS_RETRY ) //query status { memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "%s status > supp_status.txt", p->wpacli_path); system( p->cmd ); pf = fopen( "./supp_status.txt", "r" ); if ( pf ) { while( !feof( pf ) ){ memset( p->parse, 0x00, CMD_SZ ); fgets( p->parse, CMD_SZ, pf ); if( strncmp( p->parse, "wpa_state=", 10) == 0 ) { int i; if( strncmp( p->parse, "wpa_state=COMPLETED", 19) == 0 ){ count = WPS_RETRY; p->wpsing = _FALSE; #ifdef DHCP memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "dhclient %s", p->ifname); system( p->cmd ); #endif //DHCP } else if( strncmp( p->parse, "wpa_state=INACTIVE", 18) == 0 ){ inactive_count++; if( (inactive_count % 5)== 0) { if( p->wps_info == 2 ) { memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "%s wps_pin %s %d > supp_status.txt ", p->wpacli_path, p->peer_ifaddr, p->pin); system( p->cmd ); inactive_restart = 1; } } } if( inactive_restart == 1 ) { inactive_restart = 0; p->p2p_get=1; memset(p->print_line, 0x00, CMD_SZ); sprintf(p->print_line, "Restart WPS"); ui_screen(p); } else { p->p2p_get=1; memset(p->print_line, 0x00, CMD_SZ); for(i=0; iparse[i] == '\n'){ p->parse[i] = ' '; } } sprintf(p->print_line, "%s", p->parse); ui_screen(p); } break; } } fclose( pf ); } count++; usleep( SUPPLICANT_INTERVAL ); } p->wpsing = _FALSE; } void p2p_go_mode(struct p2p *p) { int count = 0, i = -1; char addr_lower[18]; p2p_ifaddr(p); p->no_sta_connected++; p->p2p_get=1; memset( p->print_line, 0x00, CMD_SZ ); strcpy( p->print_line, "Start hostapd"); ui_screen(p); if(p->ap_open != _TRUE) { memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "%s -B %s > temp.txt",p->ap_path, p->ap_conf); system( p->cmd ); usleep( HOSTAPD_INIT_TIME ); p->ap_open = _TRUE; } do_wps(p); usleep( HOSTAPD_INTERVAL ); while( count < WPS_RETRY ) //query status { if( read_all_sta(p) == _TRUE ) { count = WPS_RETRY; p->wpsing = _FALSE; p->p2p_get=1; memset(p->print_line, 0x00, CMD_SZ); for(i=0; iparse[i] == '\n'){ p->parse[i] = ' '; } } sprintf(p->print_line, "%s", p->parse); ui_screen(p); #ifdef DHCP memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "ifconfig %s 192.168.1.254", p->ifname); system( p->cmd ); usleep(50000); system( "/etc/rc.d/init.d/dhcpd start" ); system( "clear" ); #endif //DHCP //After starting hostapd and doing WPS connection successful, //We create a thread to query driver if some other p2p devices connected. p2p_status(p, 0); usleep(50000); #ifdef P2P_AUTO p->res_go = pthread_create(&p->pthread_go, NULL, &polling_client, (void *)p); if( p->res_go != 0 ) { p->p2p_get=1; memset( p->print_line, 0x00, CMD_SZ ); sprintf( p->print_line, "Thread creation failed" ); } #endif break; } else { if( count == WPS_RETRY) break; count++; usleep( HOSTAPD_INTERVAL ); p->p2p_get=1; memset( p->print_line, 0x00, CMD_SZ ); sprintf( p->print_line, "hostapd open, count:%d", count); ui_screen(p); } } p->wpsing = _FALSE; } void p2p_get_hostapd_conf(struct p2p *p) { FILE *pf = NULL; pf = fopen( p->ap_conf, "r" ); if ( pf ) { while( !feof( pf ) ){ memset(p->parse, 0x00, CMD_SZ); fgets(p->parse, CMD_SZ, pf); if(strncmp(p->parse, "ssid=", 5) == 0) { strcpy( p->apd_ssid, p->parse+5 ); } else if(strncmp(p->parse, "channel=", 8) == 0) { p->op_ch = atoi( p->parse+8 ); } else if(strncmp(p->parse, "device_name=", 12) == 0) { int i; p->dev_name[0] = '"'; strncpy( p->dev_name+1, p->parse+12, 32 ); for(i=31; i>0; i--) { if(p->dev_name[i] == '\n') { p->dev_name[i]='"'; p->dev_name[i+1]=' '; break; } } } } fclose( pf ); } } void p2p_set_opch(struct p2p *p, char *msg, int print) { if(print == 1) { p->show_scan_result = 1; ui_screen(p); printf("%s", msg); scanf("%d",&p->op_ch); } memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_set op_ch=%d", p->ifname, p->op_ch); system( p->cmd ); } void p2p_softap_ssid(struct p2p *p, char *msg, int print) { if(print == 1) { p->show_scan_result = 1; ui_screen(p); printf("%s", msg); scanf("%s",p->apd_ssid); } memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_set ssid=%s ", p->ifname, p->apd_ssid); system( p->cmd ); } void p2p_listen_ch(struct p2p *p, char *msg) { p->show_scan_result = 1; ui_screen(p); printf("%s", msg); scanf("%d",&p->listen_ch); memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_set listen_ch=%d ", p->ifname, p->listen_ch); system( p->cmd ); } //When receive provision discovery request, //it can show which device address that are connected. void p2p_peer_devaddr(struct p2p *p, char *peer_devaddr) { FILE *pf = NULL; char addr_12[12] = { 0x00 }; int i; memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_get peer_deva > peer.txt", p->ifname); system( p->cmd ); pf = fopen( "./peer.txt", "r" ); if ( pf ) { memset( p->parse, 0x00, CMD_SZ ); fgets( p->parse, CMD_SZ, pf ); fgets( p->parse, CMD_SZ, pf ); strncpy(addr_12, p->parse, 12 ); for(i=0; i<6; i++) { p->peer_devaddr[3*i] = addr_12[2*i]; p->peer_devaddr[3*i+1] = addr_12[2*i+1]; if(i==5) p->peer_devaddr[3*i+2] = '\0'; else p->peer_devaddr[3*i+2] = ':'; } fclose( pf ); } } //When receive provision discovery request, //it can show which config method that want to be as WPS connection. void p2p_peer_req_cm(struct p2p *p, char *peer_req_cm) { FILE *pf = NULL; memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_get req_cm > peer.txt", p->ifname); system( p->cmd ); pf = fopen( "./peer.txt", "r" ); if ( pf ) { while( !feof( pf ) ){ memset( p->parse, 0x00, CMD_SZ ); fgets( p->parse, CMD_SZ, pf ); if( strncmp( p->parse, "CM", 2) == 0 ) { strncpy( peer_req_cm, p->parse+3, 3 ); break; } } fclose( pf ); } } //When be regotiated passsively and successfully, //it will show peer device's peer device address and request config method void p2p_peer_info(struct p2p *p, char *peer_devaddr, char *peer_req_cm) { p->p2p_get=1; memset( p->print_line, 0x00, CMD_SZ ); sprintf( p->print_line, "Peer address:%s, req_cm: %s ", peer_devaddr, peer_req_cm); } //After scan, it will get other devices' supported config methods. void p2p_wps_cm(struct p2p *p, char *scan_addr, char *cms) { FILE *pf = NULL; int cm=0, i=0; char parse[100] = {0x00}; memset( cms, 0x00, 30 ); memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_get2 wpsCM=%s > cm.txt", p->ifname, scan_addr); system( p->cmd ); pf = fopen( "./cm.txt", "r" ); if ( pf ) { while( !feof( pf ) ){ memset( parse, 0x00, CMD_SZ ); fgets( parse, CMD_SZ, pf ); if( strncmp( parse, "M=", 2 ) == 0 ) { cm = atoi( &parse[ 2 ] ); if((cm & WPS_CONFIG_METHOD_LABEL) == WPS_CONFIG_METHOD_LABEL){ strncpy( cms+i, " LAB", 4 ); i=i+4; } if((cm & WPS_CONFIG_METHOD_DISPLAY) == WPS_CONFIG_METHOD_DISPLAY){ if((cm & WPS_CONFIG_METHOD_VDISPLAY) == WPS_CONFIG_METHOD_VDISPLAY){ strncpy( cms+i, " VDIS", 5 ); i=i+5; }else if((cm & WPS_CONFIG_METHOD_PDISPLAY) == WPS_CONFIG_METHOD_PDISPLAY){ strncpy( cms+i, " PDIS", 5 ); i=i+5; }else{ strncpy( cms+i, " DIS", 4 ); i=i+4; } } if((cm & WPS_CONFIG_METHOD_E_NFC) == WPS_CONFIG_METHOD_E_NFC){ strncpy( cms+i, " ENFC", 5 ); i=i+5; } if((cm & WPS_CONFIG_METHOD_I_NFC) == WPS_CONFIG_METHOD_I_NFC){ strncpy( cms+i, " INFC", 5 ); i=i+5; } if((cm & WPS_CONFIG_METHOD_NFC) == WPS_CONFIG_METHOD_NFC){ strncpy( cms+i, " NFC", 4 ); i=i+4; } if((cm & WPS_CONFIG_METHOD_PBC) == WPS_CONFIG_METHOD_PBC){ if((cm & WPS_CONFIG_METHOD_VPBC) == WPS_CONFIG_METHOD_VPBC){ strncpy( cms+i, " VPBC", 5 ); i=i+5; }else if((cm & WPS_CONFIG_METHOD_PPBC) == WPS_CONFIG_METHOD_PPBC){ strncpy( cms+i, " PPBC", 5 ); i=i+5; }else{ strncpy( cms+i, " PBC", 4 ); i=i+4; } } if((cm & WPS_CONFIG_METHOD_KEYPAD) == WPS_CONFIG_METHOD_KEYPAD){ strncpy( cms+i, " PAD", 4 ); i=i+4; } break; } } fclose( pf ); } } //After scan, it will get other devices' device name. void p2p_device_name(struct p2p *p, char *scan_addr, char *dns) { FILE *pf = NULL; int i; char parse[100] = {0x00}; memset( dns, 0x00, 32 ); memset( p->cmd, 0x00, CMD_SZ ); sprintf( p->cmd, "iwpriv %s p2p_get2 devN=%s > cm.txt", p->ifname, scan_addr); system( p->cmd ); pf = fopen( "./cm.txt", "r" ); if ( pf ) { while( !feof( pf ) ){ memset( parse, 0x00, CMD_SZ ); fgets( parse, CMD_SZ, pf ); if( strncmp( parse, "N=", 2) == 0 ) { strncpy( dns, parse+2, 32); for( i=0; i<32; i++) { if(*(dns+i) == '\n'){ *(dns+i) = ' ' ; break; } } break; } } fclose( pf ); } } //Successively query local device status with interval "POLLING_INTERVAL" //when status == P2P_STATE_RX_PROVISION_DIS_REQ, //it require user to insert corresponding WPS config method void *polling_status(void *arg) { struct p2p *p=(struct p2p*)arg; while( p->res == 0 ){ p2p_status(p, 0); if( (p->status == P2P_STATE_RX_PROVISION_DIS_REQ) || (p->status == P2P_STATE_GONEGO_FAIL) ) { p->thread_trigger = THREAD_DEVICE ; char peer_devaddr[18]; char peer_req_cm[4]; memset( peer_devaddr, 0x00, 18); memset( peer_req_cm, 0x00, 4); p2p_peer_devaddr(p, peer_devaddr); p2p_peer_req_cm(p, peer_req_cm); p2p_peer_info(p, p->peer_devaddr, peer_req_cm); ui_screen(p); //strncpy(p->peer_devaddr, peer_devaddr, 17); if( (strncmp( peer_req_cm, "dis", 3) == 0) || (strncmp( peer_req_cm, "lab", 3) == 0) ) { printf("Here is your PIN, insert c to continue: %d\n", p->pin); } else if( (strncmp( peer_req_cm, "pbc", 3) == 0) ) { printf("Please push b to accept:\n"); } else if( (strncmp( peer_req_cm, "pad", 3) == 0) ) { printf("Please insert peer PIN code:\n"); } break; } usleep( POLLING_INTERVAL ); } return NULL; } //If p2p device becomes GO, we still polling driver status //to check whether some other p2p devices connected void *polling_client(void *arg) { struct p2p *p=(struct p2p*)arg; while( p->res_go == 0 ){ if( p->no_sta_connected > 0 && ( p->wpsing == _FALSE ) ) { if( read_all_sta(p) == _FALSE ) { p->no_sta_connected--; } } p2p_status(p, 0); if( p->status == P2P_STATE_RX_PROVISION_DIS_REQ || p->status == P2P_STATE_GONEGO_FAIL || p->status == P2P_STATE_GONEGO_ING ) { p->thread_trigger = THREAD_GO ; char peer_devaddr[18]; char peer_req_cm[4]; memset( peer_devaddr, 0x00, 18); memset( peer_req_cm, 0x00, 4); p2p_peer_devaddr(p, peer_devaddr); p2p_peer_req_cm(p, peer_req_cm); p2p_peer_info(p, p->peer_devaddr, peer_req_cm); ui_screen(p); //strncpy(p->peer_devaddr, peer_devaddr, 17); if( (strncmp( peer_req_cm, "dis", 3) == 0) || (strncmp( peer_req_cm, "lab", 3) == 0) ) { printf("Here is your PIN, insert c to continue: %d\n", p->pin); } else if( (strncmp( peer_req_cm, "pbc", 3) == 0) ) { printf("Please push b to accept:\n", p->status); } else if( (strncmp( peer_req_cm, "pad", 3) == 0) ) { printf("Please insert peer PIN code:\n"); } break; } usleep( POLLING_INTERVAL ); } return NULL; }