realtek-RTL8812AU/WiFi_Direct_User_Interface/p2p_api_test_linux.c
2019-11-08 18:09:53 +01:00

1377 lines
30 KiB
C

#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; i<CMD_SZ; i++){
if(p->parse[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; i<CMD_SZ; i++){
if(p->parse[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;
}