📄 dk_client.c
字号:
/* dk_client.c - contians functions related to dk_client side of application */
/* Copyright (c) 2000 Atheros Communications, Inc., All Rights Reserved */
/* $Id: $ */
/*
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 "wlantype.h"
#include "dk_cmds.h"
#include "dk_client.h"
#include "dk_ver.h"
#if defined(PHOENIX)
#include "rtc_reg.h"
#include "phs_lib_includes.h"
#include "phs_defs.h"
#endif
#if defined (DOS_CLIENT)
#include "common_hwext.h"
#endif
#if defined(VXWORKS) || defined(ECOS)
#include "hw.h"
#include "hwext.h"
#endif
#if defined(PREDATOR) || defined(PHOENIX) || defined(DRAGON)
#include "flash_ops.h"
#endif
#if defined(VXWORKS) || defined(MDK_AP)
#ifdef AR5315
#include "ar531xPlusreg.h"
#endif
#ifdef AR5312
#include "ar531xreg.h"
#endif
#else
//#ifdef PREDATOR
//#include "ar5211reg.h"
//#else
//#include "ar5210reg.h"
//#endif
#if (!defined(ECOS) && !defined(SENAO_AP))
#include "common_hw.h"
#endif
#endif
#include "perlarry.h"
#if defined(THIN_CLIENT_BUILD)
#else // THIN_CLIENT_BUILD
#include "athreg.h"
#include "manlib.h"
#include "devlibif.h"
#endif // THIN_CLIENT_BUILD
#include "misclibif.h"
#include "stats_routines.h"
#ifdef LINUX
#include "termios.h"
#endif
#ifdef ENDIAN_SWAP
#include "endian_func.h"
#endif
#include "dk_common.h"
// VxWorks 'C' library doesnt have stricmp or strcasecmp function.
#ifdef VXWORKS
#define stricmp (strcmp)
#endif
// thread info
#ifdef ECOS
#define MAX_THREADS 1
#define MAX_CLIENTS_PER_THREAD 1
#else
#define MAX_THREADS 2
#define MAX_CLIENTS_PER_THREAD 2
#endif
#define INVALID_ENTRY -1
#ifdef PREDATOR
extern A_UINT32 cal_offset;
#endif
#ifdef PHOENIX
struct phsChannelToggle pPCT;
#endif
A_UINT32 sent_bytes=0, received_bytes=0;
#ifndef MALLOC_ABSENT
#else
#include "global_vars.h"
#endif
struct dkThreadInfo {
A_INT32 inUse;
A_UINT32 threadId;
OS_SOCK_INFO *pOSSock;
PIPE_CMD *PipeBuffer_p;
CMD_REPLY *ReplyCmd_p;
A_UINT32 devIndex[MAX_CLIENTS_PER_THREAD];
A_INT32 devNum[MAX_CLIENTS_PER_THREAD];
A_UINT32 numClients;
A_UINT32 currentDevIndex;
};
struct dkThreadInfo dkThreadArray[MAX_THREADS];
int numThreads;
static A_UINT32 sem;
// FORWARD DECLARATIONS
extern void connectThread ( void *param);
extern A_STATUS commandDispatch ( struct dkThreadInfo *dkThread);
extern void putThreadEntry(struct dkThreadInfo *dkThread);
extern void initThreadArray(void);
struct dkThreadInfo *getThreadEntry(void);
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, A_UINT16 port)
{
OS_SOCK_INFO *pOSSock; /* Pointer to socket info data */
A_STATUS status;
OS_SOCK_INFO *pOSClientSock;
struct dkThreadInfo *dkThread;
A_UINT32 threadId, reg;
A_INT32 i, comport_established=0;
// display our startup message
port = SOCK_PORT_NUM;
#ifdef SERIAL_COMN
port = COM1_PORT_NUM;
#endif
#ifdef USB_COMN
port = USB_PORT_NUM;
#endif
#ifdef MBOX_COMN
port = MBOX_PORT_NUM;
#endif
#ifdef ART
uiPrintf("Starting ART Client... \n");
#else
uiPrintf("Starting MDK Client... \n");
#endif
uiPrintf("Waiting for connection from Host ... \n");
#ifdef PHOENIX
diag_printf("Waiting for connection from Host (Pheonix.....)\n");
/*
apRegWrite32(0xffffd10c, 0x7);
apRegWrite32(0xffffd024, 0x1c0000);
diag_printf("Waiting for connection from Host \n");
asm volatile (
"mcr p15, 0, r0, c7, c0, 4\n"
);
diag_printf(".\n");
*/
#endif
#ifdef PREDATOR
reg = sysRegRead(AR5523_RESET);
reg &= ~RESET_GPIO;
sysRegWrite(AR5523_RESET, reg);
uDelay(100);
sysRegWrite(AR5523_GPIO_BASE_ADDRESS+0x8, 0x0);
sysRegWrite(AR5523_GPIO_BASE_ADDRESS+0x0, 0xf);
#endif
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();
#ifndef DOS_CLIENT
/* Create the socket for dk_master to connect to. */
pOSSock = osSockListen(0, port);
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;
}
#endif
q_uiPrintf("port = %d\n", port);
while (1) {
if (port == SOCK_PORT_NUM) {
#ifndef DOS_CLIENT
pOSClientSock = osSockAccept(pOSSock);
#else
pOSClientSock = osSockListen(0, port);
#endif
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);
}
else {
pOSClientSock = pOSSock;
if (comport_established) {
milliSleep(100); // this will loop infinitely
continue;
}
else comport_established = 1;
}
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 defined(ECOS)
putThreadEntry(dkThread);
comport_established = 0;
#endif
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);
#ifndef MALLOC_ABSENT
A_FREE(dkThreadArray[i].ReplyCmd_p);
A_FREE(dkThreadArray[i].PipeBuffer_p);
#endif
osSockClose(dkThreadArray[i].pOSSock);
putThreadEntry(dkThread);
}
}
#ifndef DOS_CLIENT
semUnLock(sem);
semClose(sem);
// close the master socket
osSockClose(pOSSock);
#endif
#if defined(THIN_CLIENT_BUILD)
#else // THIN_CLIENT_BUILD
// cleanup the library
m_devlibCleanup();
// clean up anything that was allocated and close the driver
envCleanup(TRUE);
#endif // THIN_CLIENT_BUILD
return 0;
}
void printVersion(void)
{
uiPrintf(MDK_CLIENT_VER1);
uiPrintf(MDK_CLIENT_VER2);
}
void connectThread (void *pparam)
{
A_INT32 numBytes;
OS_SOCK_INFO *pOSSock;
A_UINT16 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;
semLock(sem);
#ifndef MALLOC_ABSENT
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;
}
#else
PipeBuffer_p = &gPipeBuffer;
ReplyCmd_p = &gReplyCmd;
#endif
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_s(cmdLen);
#endif
if ((cmdLen == 0) || (cmdLen > sizeof(PIPE_CMD))) {
uiPrintf("Error: Pipe write size too large or zero length:cmdLen=%d\n", cmdLen);
pOSSock->sockDisconnect = 1;
break;
}
PipeBuffer_p->cmdLen = cmdLen;
//uiPrintf("RCL:%d:", cmdLen);
#ifdef _DEBUG_RD
q_uiPrintf("cmdLen=%d\n", cmdLen);
#endif
// 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;
}
#ifdef USB_COMN
uiPrintf("DC:%d::", dkThread->PipeBuffer_p->cmdID);
#else
q_uiPrintf("Dispatching command %d at port_num=%d\n", dkThread->PipeBuffer_p->cmdID, pOSSock->port_num);
#endif
status = commandDispatch(dkThread);
if ( A_FAILED(status) ) {
uiPrintf("Error: Problem in commandDispatch()!\n");
pOSSock->sockDisconnect = 1;
break;
}
if ( pOSSock->sockClose || pOSSock->sockDisconnect ) {
if (pOSSock->port_num != SOCK_PORT_NUM) {
pOSSock->sockClose = 0;
#if !defined(PHOENIX)
pOSSock->sockDisconnect = 0;
#endif
#ifdef LINUX
tcflush(pOSSock->sockfd, TCIOFLUSH);
#endif
for (i=0;i<MAX_CLIENTS_PER_THREAD;i++) {
if (dkThread->devIndex[i] != (A_UINT32)INVALID_ENTRY) {
#if defined(THIN_CLIENT_BUILD)
#else // THIN_CLIENT_BUILD
closeMLIB(dkThread->devNum[i]);
#endif // THIN_CLIENT_BUILD
dkThread->devNum[i] = INVALID_ENTRY;
deviceCleanup((A_UINT16)dkThread->devIndex[i]);
dkThread->devIndex[i] = (A_UINT32)INVALID_ENTRY;
dkThread->numClients--;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -