📄 dk_client.c
字号:
/* dk_client.c - contians functions related to dk_client side of application */
/* Copyright (c) 2000 Atheros Communications, Inc., All Rights Reserved */
#ident "ACI $Id: //depot/sw/src/ap/os/vxworks/target/proj/mdk-spirit/client/dk_client.c#26 $, $Header: //depot/sw/src/ap/os/vxworks/target/proj/mdk-spirit/client/dk_client.c#26 $"
/*
modification history
--------------------
01/01/2002 sharmat created
*/
/*
DESCRIPTION
Contains functions related to dk_client side of application. Including the main
function, the stuff for the communications channel etc.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dk_common.h"
#include "dk_cmds.h"
#include "dk_client.h"
#include "dk_ver.h"
#include "hw.h"
#include "hwext.h"
#include "athreg.h"
#include "manlib.h"
#include "devlibif.h"
#include "misclibif.h"
#ifdef ENDIAN_SWAP
#include "endian_func.h"
#endif
// VxWorks 'C' library doesnt have stricmp or strcasecmp function.
#ifdef VXWORKS
#define stricmp (strcmp)
#endif
// thread info
#define MAX_THREADS 8
#define MAX_CLIENTS_PER_THREAD 8
#define INVALID_ENTRY -1
struct dkThreadInfo {
A_INT32 inUse;
A_UINT32 threadId;
OS_SOCK_INFO *pOSSock;
PIPE_CMD *PipeBuffer_p;
CMD_REPLY *ReplyCmd_p;
A_UINT16 devIndex[MAX_CLIENTS_PER_THREAD];
A_INT32 devNum[MAX_CLIENTS_PER_THREAD];
A_UINT32 numClients;
A_UINT16 currentDevIndex;
};
struct dkThreadInfo dkThreadArray[MAX_THREADS];
int numThreads;
static A_UINT32 sem;
// FORWARD DECLARATIONS
void connectThread
(
void *param
);
A_STATUS commandDispatch
(
struct dkThreadInfo *dkThread
);
void putThreadEntry(struct dkThreadInfo *dkThread);
void initThreadArray();
struct dkThreadInfo *getThreadEntry();
static A_INT32 addClientToThread
(
struct dkThreadInfo *dkThread,
A_UINT16 devIndex,
A_UINT32 devNum
);
static void removeClientFromThread
(
struct dkThreadInfo *dkThread,
A_UINT16 devIndex
);
/**************************************************************************
* main - main function
*
* RETURNS: N/A
*/
A_INT32 mdk_main(A_INT32 debugMode)
{
OS_SOCK_INFO *pOSSock; /* Pointer to socket info data */
A_STATUS status;
OS_SOCK_INFO *pOSClientSock;
struct dkThreadInfo *dkThread;
A_UINT32 threadId;
A_INT32 i;
// display our startup message
#ifdef ART
uiPrintf("Starting ART Client... \n");
#else
uiPrintf("Starting MDK Client... \n");
#endif
uiPrintf("Waiting for connection from Host \n");
status = A_OK;
// perform environment initialization
if ( A_ERROR == envInit((A_BOOL)debugMode) ) {
uiPrintf("Error: Unable to initialize the environment... Closing down!\n");
return 0;
}
initThreadArray();
/* Create the socket for dk_master to connect to. */
pOSSock = osSockListen(0);
if (!pOSSock) {
uiPrintf("Error: Something went wrong with socket creation... Closing down!\n");
envCleanup(TRUE);
return 0;
}
sem = semInit();
if (!sem) {
uiPrintf("Error: semInit failed... Closing down! \n");
osSockClose(pOSSock);
envCleanup(TRUE);
return 0;
}
while (1) {
pOSClientSock = osSockAccept(pOSSock);
if (!pOSClientSock) {
uiPrintf("Error: Something went wrong with socket creation... Closing down!\n");
break;
}
uiPrintf("Socket connection to master established. Waiting for commands....\n");
uiPrintf("Connection established with %s : Port %d \n",pOSClientSock->hostname,pOSClientSock->port_num);
semLock(sem);
dkThread = getThreadEntry();
if (!dkThread) {
uiPrintf("Error: Max Thread Limit Exceeded \n");
osSockClose(pOSClientSock);
break;
}
semUnLock(sem);
dkThread->pOSSock = pOSClientSock;
/* create the thread that will wait for commands */
status = osThreadCreate(connectThread, (void *)dkThread, MDK_CLIENT,MDK_CLIENT_PRIO, &threadId);
if ( A_FAILED(status) ) {
putThreadEntry(dkThread);
osSockClose(pOSClientSock);
uiPrintf("Error: Unable to start connectThread()... Closing down!\n");
break;
}
dkThread->threadId = threadId;
}
semLock(sem);
for (i=0;i<MAX_THREADS;i++) {
if (dkThreadArray[i].inUse) {
osThreadKill(dkThreadArray[i].threadId);
A_FREE(dkThreadArray[i].ReplyCmd_p);
A_FREE(dkThreadArray[i].PipeBuffer_p);
osSockClose(dkThreadArray[i].pOSSock);
putThreadEntry(dkThread);
}
}
semUnLock(sem);
semClose(sem);
// close the master socket
osSockClose(pOSSock);
// cleanup the library
m_devlibCleanup();
// clean up anything that was allocated and close the driver
envCleanup(TRUE);
return 0;
}
void printVersion()
{
uiPrintf(MDK_CLIENT_VER1);
uiPrintf(MDK_CLIENT_VER2);
}
void connectThread (void *pparam)
{
A_UINT32 numBytes;
OS_SOCK_INFO *pOSSock;
A_UINT32 cmdLen;
A_STATUS status;
A_BOOL bGoodRead;
PIPE_CMD *PipeBuffer_p = NULL;
CMD_REPLY *ReplyCmd_p = NULL;
struct dkThreadInfo *dkThread;
A_INT32 i;
printVersion();
dkThread = (struct dkThreadInfo *)pparam;
pOSSock = (OS_SOCK_INFO *)dkThread->pOSSock;
q_uiPrintf("connectThread() started... \n");
semLock(sem);
PipeBuffer_p = (PIPE_CMD *)A_MALLOC(sizeof(PIPE_CMD));
if ( NULL == PipeBuffer_p ) {
uiPrintf("Error: Unable to malloc Receive Pipe Buffer struct... Closing down!\n");
osSockClose(pOSSock);
putThreadEntry(dkThread);
semUnLock(sem);
return;
}
ReplyCmd_p = (CMD_REPLY *)A_MALLOC(sizeof(CMD_REPLY));
if ( NULL == ReplyCmd_p ) {
uiPrintf("Error: Unable to malloc Reply Pipe Buffer struct... Closing down!\n");
A_FREE(PipeBuffer_p);
osSockClose(pOSSock);
putThreadEntry(dkThread);
semUnLock(sem);
return;
}
dkThread->ReplyCmd_p = ReplyCmd_p;
dkThread->PipeBuffer_p = PipeBuffer_p;
semUnLock(sem);
while ( 1 ) {
bGoodRead = FALSE;
numBytes = 0;
if ( osSockRead(pOSSock, (A_UINT8 *)(&cmdLen), sizeof(cmdLen)) ) {
#ifdef ENDIAN_SWAP
cmdLen = ltob_l(cmdLen);
#endif
if ((cmdLen == 0) || (cmdLen > sizeof(PIPE_CMD))) {
uiPrintf("Error: Pipe write size too large or zero length\n");
pOSSock->sockDisconnect = 1;
break;
}
PipeBuffer_p->cmdLen = cmdLen;
// Received the length field already.
// Read the command structure of the specified length.
numBytes = osSockRead(pOSSock, (((A_UINT8 *)PipeBuffer_p)+sizeof(PipeBuffer_p->cmdLen)), cmdLen);
if ( numBytes == cmdLen) {
bGoodRead = TRUE;
}
}
if ( !bGoodRead ) {
pOSSock->sockDisconnect = 1;
break;
}
status = commandDispatch(dkThread);
if ( A_FAILED(status) ) {
uiPrintf("Error: Problem in commandDispatch()!\n");
pOSSock->sockDisconnect = 1;
break;
}
if ( pOSSock->sockClose || pOSSock->sockDisconnect ) {
break;
}
}
semLock(sem);
A_FREE(ReplyCmd_p);
A_FREE(PipeBuffer_p);
for (i=0;i<MAX_CLIENTS_PER_THREAD;i++) {
if (dkThread->devNum[i] != INVALID_ENTRY) {
closeMLIB(dkThread->devNum[i]);
}
if (dkThread->devIndex[i] != (A_UINT16)INVALID_ENTRY) {
deviceCleanup(dkThread->devIndex[i]);
}
}
osSockClose(pOSSock);
putThreadEntry(dkThread);
semUnLock(sem);
return;
}
/**************************************************************************
* processInitF2Cmd - Process INIT_F2_CMD command
*
* RETURNS: 0 processed OK, an Error code if it is not
*/
A_UINT32 processInitF2Cmd
(
struct dkThreadInfo *dkThread
)
{
PIPE_CMD *pCmd;
A_UINT32 cmdLen;
CMD_REPLY *ReplyCmd_p;
A_UCHAR *replyBuf;
MDK_WLAN_DEV_INFO *pdevInfo;
A_INT32 devNum;
A_UINT32 devIndex;
pCmd = dkThread->PipeBuffer_p;
cmdLen = pCmd->cmdLen;
ReplyCmd_p = dkThread->ReplyCmd_p;
replyBuf = (A_UCHAR *)(ReplyCmd_p->cmdBytes);
/* check that the size is appropriate before we access */
if ( cmdLen != sizeof(pCmd->CMD_U.INIT_F2_CMD)+sizeof(pCmd->cmdID) ) {
uiPrintf("Error, command Len is not equal to size of INIT_F2_CMD\n");
return(COMMS_ERR_BAD_LENGTH);
}
#ifdef ENDIAN_SWAP
pCmd->CMD_U.INIT_F2_CMD.whichF2 = ltob_l(pCmd->CMD_U.INIT_F2_CMD.whichF2);
#endif
devIndex = pCmd->CMD_U.INIT_F2_CMD.whichF2;
q_uiPrintf("F2 to init = %d\n", devIndex);
/* validate the F2 required; see that it is a valid index */
if (devIndex > WLAN_MAX_DEV ) {
/* don't have a large enough array to accommodate this device */
uiPrintf("Error: devInfo array not large enough, only support %d devices\n", WLAN_MAX_DEV);
return(COMMS_ERR_INDEX_TOO_LARGE);
}
if (devIndex == 0) {
uiPrintf("Error: Cannot have a zero index \n");
return(COMMS_ERR_DEV_INIT_FAIL);
}
semLock(sem);
devIndex = devIndex - 1;
if (A_FAILED(deviceInit((A_UINT16)(devIndex))) ) {
uiPrintf("Error: Failed call to deviceInit() \n");
semUnLock(sem);
return(COMMS_ERR_DEV_INIT_FAIL);
}
pdevInfo = globDrvInfo.pDevInfoArray[devIndex];
devNum = initializeMLIB(pdevInfo);
if (devNum == -1) {
uiPrintf("Cannot initalize MLIB \n");
semUnLock(sem);
return(COMMS_ERR_DEV_INIT_FAIL);
}
if (addClientToThread(dkThread,(A_UINT16)devIndex,devNum) < 0) {
uiPrintf("Cannot add thread to client \n");
semUnLock(sem);
return(COMMS_ERR_DEV_INIT_FAIL);
}
// make this the current device
dkThread->currentDevIndex = (A_UINT16)devIndex;
semUnLock(sem);
*((A_UINT32 *)replyBuf) = devNum;
#ifdef ENDIAN_SWAP
*((A_UINT32 *)replyBuf) = btol_l(*((A_UINT32 *)replyBuf));
#endif
return (0);
}
/**************************************************************************
* processMemReadCmd - Process MEM_READ_CMD command
*
* RETURNS: 0 processed OK, an Error code if it is not
*/
A_UINT32 processMemReadCmd
(
struct dkThreadInfo *dkThread
)
{
PIPE_CMD *pCmd;
A_UINT32 cmdLen;
CMD_REPLY *ReplyCmd_p;
A_UCHAR *replyBuf;
pCmd = dkThread->PipeBuffer_p;
cmdLen = pCmd->cmdLen;
ReplyCmd_p = dkThread->ReplyCmd_p;
replyBuf = (A_UCHAR *)(ReplyCmd_p->cmdBytes);
/* check that the size is appropriate before we access */
if( cmdLen != sizeof(pCmd->CMD_U.MEM_READ_CMD)+sizeof(pCmd->cmdID) )
{
uiPrintf("Error, command Len is not equal to size of MEM_READ_CMD\n");
return(COMMS_ERR_BAD_LENGTH);
}
#ifdef ENDIAN_SWAP
pCmd->CMD_U.MEM_READ_CMD.readSize = ltob_l(pCmd->CMD_U.MEM_READ_CMD.readSize);
pCmd->CMD_U.MEM_READ_CMD.readAddr = ltob_l(pCmd->CMD_U.MEM_READ_CMD.readAddr);
#endif
/* read the memory */
switch(pCmd->CMD_U.MEM_READ_CMD.readSize)
{
#ifndef ART
case 8:
*((A_UINT32 *)replyBuf) = (A_UINT32)hwMemRead8(dkThread->currentDevIndex,pCmd->CMD_U.MEM_READ_CMD.readAddr);
break;
case 16:
*((A_UINT32 *)replyBuf) = (A_UINT32)hwMemRead16(dkThread->currentDevIndex,pCmd->CMD_U.MEM_READ_CMD.readAddr);
break;
#endif
case 32:
*((A_UINT32 *)replyBuf) = hwMemRead32(dkThread->currentDevIndex,pCmd->CMD_U.MEM_READ_CMD.readAddr);
break;
default:
return(COMMS_ERR_BAD_MEM_SIZE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -