/*
 * Windows port of asd command line utility
 *
 * Copyright 2002, Broadcom Corporation
 * All Rights Reserved.
 *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
 * the contents of this file may not be disclosed to third parties, copied or
 * duplicated in any form, in whole or in part, without the prior written
 * permission of Broadcom Corporation.
 *
 */

#include <Winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>


#include "wfa_debug.h"
#include "wfa_sock.h"
#include "wfa_main.h"
#include "wfa_types.h"
#include "wfa_tg.h"
#include "wfa_miscs.h"
#include "wfa_cmds.h"

#ifndef SIOCGIWNAME
#define SIOCGIWNAME 0x8B01
#endif

#define RECV_OFFSET 22

extern unsigned short wfa_defined_debug;
extern tgStream_t *theStreams;
extern char PingStr[];
tgStream_t *findStreamProfile(int id);
HANDLE processHandle = NULL;
HANDLE processThread = NULL; 

void
asd_sleep(int SleepTime)
{

	Sleep(SleepTime * 1000);

}

void
uapsd_sleep(int SleepTime)
{

	usleep(SleepTime/1000);

}

void 
asd_closeSocket(int sockfd)
{
	closesocket(sockfd);

}

void
asd_shutDown(int Sockfd)
{

	shutdown(Sockfd, SD_SEND);
}

void 
wfaGetSockOpt(int sockfd, int* tosval, socklen_t* size)
{
	getsockopt(sockfd, IPPROTO_IP, IP_TOS, (char FAR*)tosval, size);
}

int 
wfaSetSockOpt(int sockfd, int* tosval, int size)
{
	int sockOpt;
	sockOpt = setsockopt(sockfd, IPPROTO_IP, IP_TOS, (char FAR*)tosval, size);
	return sockOpt;
}

int
exec_process_cnclient (char *buf, char *rwl_client_path, int rwl_wifi_flag)
{
	unsigned int  position;
	char gCmdStr[WFA_CMD_STR_SZ];
	int timeout_count = 30;
	FILE *tmpfd;
	/* Create Process related variables */
	PROCESS_INFORMATION ProcessInfo;
	char Args[WFA_BUFF_512];
	TCHAR pDefaultCMD[WFA_BUFF_512];
	STARTUPINFO StartupInfo;
	
	if (rwl_wifi_flag){
		/*The server can be in different channel after association
		 *Hence we issue a findserver and then find out if it has
		 *been associated to return the right status
		 */	
	
		memset(Args, 0, WFA_BUFF_512);
		sprintf(Args, "%s", (const char *)buf);
		memset(&ProcessInfo, 0, sizeof(ProcessInfo));
		memset(&StartupInfo, 0, sizeof(StartupInfo));
		StartupInfo.cb = sizeof(StartupInfo);
		/*  "/C" option - Do the command and EXIT the command processor */
		_tcscpy(pDefaultCMD, _T("cmd.exe /C "));
		_tcscat(pDefaultCMD, Args);
		if(!CreateProcess(NULL,(LPTSTR)pDefaultCMD, NULL,NULL,FALSE,FALSE,NULL,NULL,
			&StartupInfo,&ProcessInfo)){
				processHandle = ProcessInfo.hProcess;
				processThread = ProcessInfo.hThread; 
				return FALSE;
		}
		asd_sleep(3);
		sprintf(gCmdStr, "%s findserver", rwl_client_path);
		exec_process(gCmdStr);
	}
	else {
		exec_process(buf);
	}
	
	/* while cnClient associates in the child, parent looks 
	 * for association if it has happened
	 * If it has not associated within a loop of 30, it comes out
	 * as not associated
	 */ 
	while(timeout_count > 0){
		strcpy(gCmdStr, rwl_client_path);
		strcat(gCmdStr, " assoc >");
		if((tmpfd = asd_Config(gCmdStr,TEMP_FILE_PATH)) == NULL){
			DPRINT_ERR(WFA_ERR, "\nassoc failed\n");
			return FALSE;
			}
		if((FileSearch(tmpfd, L"Not associated", &position))== -1) {
			Cleanup_File(tmpfd);
			break;
		}
		Cleanup_File(tmpfd);
		asd_sleep(1);
		timeout_count--;
	}
	if(timeout_count)
		return TRUE;
	else
		return FALSE;
}

void
exec_process(char* command)
{
	char wl_cmd[WFA_BUFF_256];
	memset(wl_cmd,0,sizeof(wl_cmd));
	strncpy(wl_cmd, command, strlen(command));
	DPRINT_INFO(WFA_OUT,"%s\n",wl_cmd);
	asd_Config(wl_cmd," ");
}

int
Start_Socket_Service()
{
	int err = 0;
	WORD wVersionRequested;
	WSADATA wsaData;
	/* Initialize winsock library */
	wVersionRequested = MAKEWORD( 2, 2 );
	err = WSAStartup(wVersionRequested, &wsaData);
	return err;
}

int
Stop_Socket_Service()
{
	return WSACleanup();
}

char * strtok_r(char *s1, const char *s2, char **lasts)
{
	char *ret;

	if (s1 == NULL)
		s1 = *lasts;

	while(*s1 && strchr(s2, *s1))
		++s1;

	if(*s1 == '\0')
		return NULL;

	ret = s1;

	while(*s1 && !strchr(s2, *s1))
		++s1;

	if(*s1)
		*s1++ = '\0';

	*lasts = s1;

	return ret;
} 

int strcasecmp(const char *s1, const char *s2)
{
	const unsigned char *us1 = (const unsigned char *)s1;
	const unsigned char *us2 = (const unsigned char *)s2;

	while (tolower(*us1) == tolower(*us2)) {
		if (*us1++ == '\0')
			return (0);
		us2++;
	}
	return (tolower(*us1) - tolower(*us2));
}

int strncasecmp(const char *s1,const char *s2, unsigned int length)
{
	unsigned char u1, u2;

	for (; length != 0; length--, s1++, s2++) {
		u1 = (unsigned char) *s1;
		u2 = (unsigned char) *s2;

		if (tolower(u1) != tolower(u1)) {
			return tolower(u1) - tolower(u1);
		}
		if (u1 == '\0') {
			return 0;
		}
	}
	return 0;
}

__inline int wmemcmp(const wchar_t *_S1, const wchar_t *_S2, size_t _N)
        {for (; 0 < _N; ++_S1, ++_S2, --_N)
                if (*_S1 != *_S2)
                        return (*_S1 < *_S2 ? -1 : +1);
        return (0); }
__inline wchar_t *wmemcpy(wchar_t *_S1, const wchar_t *_S2, size_t _N)
        {wchar_t *_Su1 = _S1;
        for (; 0 < _N; ++_Su1, ++_S2, --_N)
                *_Su1 = *_S2;
        return (_S1); }
__inline wchar_t *wmemmove(wchar_t *_S1, const wchar_t *_S2, size_t _N)
        {wchar_t *_Su1 = _S1;
        if (_S2 < _Su1 && _Su1 < _S2 + _N)
                for (_Su1 += _N, _S2 += _N; 0 < _N; --_N)
                        *--_Su1 = *--_S2;
        else
                for (; 0 < _N; --_N)
                        *_Su1++ = *_S2++;
        return (_S1); }
__inline wchar_t *wmemset(wchar_t *_S, wchar_t _C, size_t _N)
        {wchar_t *_Su = _S;
        for (; 0 < _N; ++_Su, --_N)
                *_Su = _C;
        return (_S); }

int GetPingStat(FILE* pFile, const wchar_t* lpszSearchString , unsigned int *recv,unsigned int *sent, const char* delim) 
{ 
	unsigned long ulFileSize, ulBufferSize; 
	wchar_t lpBuffer[WFA_BUFF_512];
	char mbsbuffer[WFA_BUFF_512], str[WFA_BUFF_128];
	unsigned int *ulCurrentPosition, *ulReceived, *ulsent;
	int retval;

	ulCurrentPosition=recv;
	ulReceived= recv;
	ulsent = sent; 

	//make sure we were passed a valid, if it isn't return -1 
	if ((!pFile)||(!lpszSearchString)) { 
		return -1; 
	} 

	//get the size of the file 
	fseek(pFile,0,SEEK_END); 

	ulFileSize=ftell(pFile); 

	fseek(pFile,0,SEEK_SET); 

	//if the file is empty return -1 
	if (!ulFileSize) { 
		return -1; 
	} 

	//get the length of the string we're looking for, this is 
	//the size the buffer will need to be 
	ulBufferSize=wcslen(lpszSearchString); 

	if (ulBufferSize>ulFileSize) { 
		return -1; 
	} 

	*ulCurrentPosition=0; 

	//this is where the actual searching will happen, what happens 
	//here is we set the file pointer to the current position 
	//is incrimented by one each pass, then we read the size of 
	//the buffer into the buffer and compare it with the string 
	//we're searching for, if the string is found we return the 
	//position at which it is found 
	while (*ulCurrentPosition<ulFileSize-ulBufferSize) { 
		fseek(pFile,*ulCurrentPosition,SEEK_SET); 
		wmemset(lpBuffer, 0, WFA_BUFF_512);
		//read ulBufferSize bytes from the file 
		fread(mbsbuffer,1,ulBufferSize,pFile); 

		retval = mbstowcs(lpBuffer, mbsbuffer, strlen(mbsbuffer)); 

		//if the data read matches the string we're looking for
		//read from the offset where recieve data starts 
		if (!wmemcmp(lpBuffer, lpszSearchString, ulBufferSize)) { 
			fread(str, 1, RECV_OFFSET, pFile);
			*ulReceived = atoi(str);
			strtok(str, (const char*)ulReceived);
			//fread(str,1,ulBufferSize,pFile);
			//strtok(str, delim);
			*ulsent= atoi(str);
			//return the position the string was found at 
			return *ulCurrentPosition; 
		} 

		++*ulCurrentPosition; 
	} 
	return -1;
} 

int GetStats(FILE* pFile, const wchar_t* lpszSearchString , unsigned int *pos, const char* delim) 
{ 

	char* lpBuffer;
	char* str;
    char mbsString[128];
	unsigned long ulFileSize, ulBufferSize; 	
	unsigned int *ulCurrentPosition;
	ulCurrentPosition = pos;

	memset(mbsString, 0, 128);
	/* convert the wide character search string to multibyte */
	wcstombs(mbsString,lpszSearchString, wcslen(lpszSearchString) );
	/* make sure we were passed a valid, if it isn't return -1 */
	if ((!pFile)||(!lpszSearchString)) { 
		return -1; 
	} 

	/* get the size of the file */
	fseek(pFile,0,SEEK_END); 

	ulFileSize=ftell(pFile); 

	fseek(pFile,0,SEEK_SET); 

	/* if the file is empty return -1 */
	if (!ulFileSize) { 
		return -1; 
	} 

	/* get the length of the string we're looking for, this is 
	 * the size the buffer will need to be */
	ulBufferSize=wcslen(lpszSearchString); 

	if (ulBufferSize>ulFileSize) { 
		return -1; 
	} 
    /* allocate the memory for the buffer */
     lpBuffer=(char*)malloc(strlen(mbsString)); 
	 str = (char*)malloc(strlen(mbsString));
	/* if malloc() returned a null pointer (which probably means 
     * there is not enough memory) then return -1  */
	 if (!lpBuffer ) 
    { 
        return -1; 
    } 
	*ulCurrentPosition=0; 

	/* this is where the actual searching will happen, what happens 
	 * here is we set the file pointer to the current position 
	 * is incrimented by one each pass, then we read the size of 
	 * the buffer into the buffer and compare it with the string 
	 * we're searching for, if the string is found we return the 
	 * position at which it is found */

	while (*ulCurrentPosition<ulFileSize-ulBufferSize) { 
		fseek(pFile,*ulCurrentPosition,SEEK_SET); 
		/* if the data read matches the string we're looking for */
		fread(lpBuffer,1,ulBufferSize,pFile); 
		if (!memcmp(lpBuffer,mbsString,ulBufferSize)) 
        { 
			fread(str,1,ulBufferSize,pFile);
			strtok(str, delim);
			*ulCurrentPosition = atoi(str);

			/* free the buffer */
			if(lpBuffer != NULL || str != NULL){
				free(lpBuffer); 
				free(str);
			}
			/* return the position the string was found at */
			return *ulCurrentPosition; 
		} 
        /* incriment the current position by one */
		++*ulCurrentPosition; 
    } 

    /* if we made it this far the string was not found in the file 
     * so we free the buffer */
    if(lpBuffer != NULL || str != NULL){
			free(str);
            free(lpBuffer); 
	} 
	return -1;
} 

int FileSearch(FILE* pFile, const wchar_t* lpszSearchString , unsigned int *pos) 
{ 
	
	char* lpBuffer;
	 char mbsString[128];
	unsigned long ulFileSize = 0, ulBufferSize;
	unsigned long *ulCurrentPosition;
	ulCurrentPosition= pos;
	memset(mbsString, 0, 128);
	/* convert the wide character search string to multibyte */
	wcstombs(mbsString,lpszSearchString, wcslen(lpszSearchString) );
	/* make sure we were passed a valid, if it isn't return -1 */
	if ((!pFile)||(!lpszSearchString)) { 
		return -1; 
	} 

	/* get the size of the file */
	fseek(pFile,0,SEEK_END); 

	ulFileSize=ftell(pFile); 

	fseek(pFile,0,SEEK_SET); 

	/* if the file is empty return -1 */
	if (!ulFileSize) { 
		return -1; 
	} 

	/* get the length of the string we're looking for, this is 
	 * the size the buffer will need to be */
	ulBufferSize=wcslen(lpszSearchString); 

	if (ulBufferSize > ulFileSize) { 
		return -1; 
	} 

    /* allocate the memory for the buffer */
     lpBuffer=(char*)malloc(strlen(mbsString)); 
	/* if malloc() returned a null pointer (which probably means 
     * there is not enough memory) then return -1 */

	 if (!lpBuffer ) 
    { 
        return -1; 
    } 
	*ulCurrentPosition=0; 

	/* this is where the actual searching will happen, what happens 
	 * here is we set the file pointer to the current position 
	 * is incrimented by one each pass, then we read the size of 
	 * the buffer into the buffer and compare it with the string 
	 * we're searching for, if the string is found we return the 
	 * position at which it is found */
	while (*ulCurrentPosition<ulFileSize-ulBufferSize) { 
		fseek(pFile,*ulCurrentPosition,SEEK_SET); 
		/* if the data read matches the string we're looking for */
		  fread(lpBuffer,1,ulBufferSize,pFile); 
		if (!memcmp(lpBuffer,mbsString,ulBufferSize)) 
		{ 
			/* free the buffer */
			if(lpBuffer != NULL)
            free(lpBuffer); 
			/* return the position the string was found at */
			return *ulCurrentPosition; 
		} 

		/* incriment the current position by one */
		++*ulCurrentPosition; 
	} 
    /* if we made it this far the string was not
     * found in the file so we free the buffer */
    if(lpBuffer != NULL)
            free(lpBuffer); 
	return -1;
} 

unsigned int uGetLocalIP()
{
	char szHostName[WFA_BUFF_256];
	struct hostent*	HostData;

	GetHostName(szHostName, WFA_BUFF_256);
	HostData = gethostbyname(szHostName);
	if (HostData == NULL)
		return 0;

	return *((unsigned int*)HostData->h_addr);
}

char* GetHostName(char* buf, int len) 
{
	if (gethostname(buf, len) == SOCKET_ERROR)
		return NULL;
	return buf;
}

int wfa_Winitime_diff(SYSTEMTIME *t1, SYSTEMTIME *t2)
{
	int dtime;
	int sec = t2->wSecond - t1->wSecond;
	int msec = (t2->wMilliseconds - t1->wMilliseconds);

	if(msec < 0)
	{
		sec -=1;
		msec += 1000;
	}

	dtime = sec*1000 + msec;
	return dtime;
}

int wfa_Win_estimate_timer_latency()
{
	SYSTEMTIME t1, t2, tp2;
	int sleep =2;
	int latency =0;

	GetSystemTime(&t1);
	usleep(sleep);

	GetSystemTime(&t2); 

	tp2.wMilliseconds = t1.wMilliseconds  +20;
	if( tp2.wMilliseconds >= 1000) {
		tp2.wSecond = t1.wSecond +1;
		tp2.wMilliseconds -= 1000;
	}
	else
		tp2.wSecond = t1.wSecond;

	return latency = (t2.wSecond - tp2.wSecond)  + (t2.wMilliseconds - tp2.wMilliseconds); 
}


FILE* asd_Config(char *strFunct, char *strstrParams)
{
	FILE* fp = NULL;
	PROCESS_INFORMATION ProcessInfo;
	char Args[WFA_BUFF_512];
	TCHAR pDefaultCMD[WFA_BUFF_512];
	STARTUPINFO StartupInfo;
	ULONG rc;

	Args[0]= 0;
	memset(Args, 0, WFA_BUFF_512);
	sprintf(Args, "%s %s", (const char *)strFunct, (const char *)strstrParams);
	memset(&ProcessInfo, 0, sizeof(ProcessInfo));
	memset(&StartupInfo, 0, sizeof(StartupInfo));
	StartupInfo.cb = sizeof(StartupInfo);
	/*  "/C" option - Do the command and EXIT the command processor */
	_tcscpy(pDefaultCMD, _T("cmd.exe /C "));
	_tcscat(pDefaultCMD, Args);

	if(!CreateProcess(NULL,(LPTSTR)pDefaultCMD, NULL,NULL,FALSE,FALSE,NULL,NULL,&StartupInfo,&ProcessInfo))
	{
		processHandle = ProcessInfo.hProcess;
		processThread = ProcessInfo.hThread; 
		printf("CreateProcess function failed\n");
		return NULL;
	}

	WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
	if(!GetExitCodeProcess(ProcessInfo.hProcess, &rc))
		rc = 0;

	CloseHandle(ProcessInfo.hThread);
	CloseHandle(ProcessInfo.hProcess);
	if(strlen(strstrParams) > 1){
		if((fp = fopen(TEMP_FILE_PATH, "r+")) == NULL){
			printf("fopen failed\n");
			return NULL;
		}
	}
	return fp;
}

void Cleanup_File(FILE* fp)
{
	fclose(fp);
	if (!DeleteFile(TEMP_FILE_PATH)) {
		printf("DeleteFile Failed with error:%d\n",GetLastError());
	}
}

void p_error(char *errorString)
{
	printf("%s %d",errorString, GetLastError());
}
