📄 ha.c
字号:
/* Reset the Ctbus resource */
pCtbusInfo = &(pTrunkResInfo->CtbusInfo);
pCtbusInfo->un8Trunk = (TBX_UINT8)un32Count1;
pCtbusInfo->un8Timeslot = (TBX_UINT8)un32Count2;
pCtbusInfo->hCtbusResource = (TB640_RESOURCE_HANDLE)NULL;
un32CtbusIdx = ((un32Count1 * TB640_ISDN_MAX_TIMESLOT_IN_TRUNK) + un32Count2) * 2;
pCtbusInfo->un8CtbusStream = (TBX_UINT8)(un32CtbusIdx / TB640_ISDN_MAX_TIMESLOT_PER_CTBUS_STREAM);
pCtbusInfo->un8CtbusTimeslot = (TBX_UINT8)(un32CtbusIdx % TB640_ISDN_MAX_TIMESLOT_PER_CTBUS_STREAM);
un32NbCtbus++;
}
/* Reset stack information */
pTrunkInfo->hStack = (TB640_ISDN_HANDLE)NULL;
pTrunkInfo->fStackAvailable = TBX_FALSE;
}
}
/* Empty the hash tables */
if (pAdapterInfo->hTrunkHash != NULL)
{
TBXHashDestroy (pAdapterInfo->hTrunkHash);
pAdapterInfo->hTrunkHash = NULL;
}
if (pAdapterInfo->hTrunkResHash != NULL)
{
TBXHashDestroy (pAdapterInfo->hTrunkResHash);
pAdapterInfo->hTrunkResHash = NULL;
}
if (pAdapterInfo->hStackHash != NULL)
{
TBXHashDestroy (pAdapterInfo->hStackHash);
pAdapterInfo->hStackHash = NULL;
}
if (pAdapterInfo->hCtBusHash != NULL)
{
/* Empty the hash tables */
TBXHashDestroy (pAdapterInfo->hCtBusHash);
pAdapterInfo->hCtBusHash = NULL;
}
/* Re-allocate the hash tables for fast reverse lookup */
pAdapterInfo->hTrunkHash = TBXHashCreate (
pAdapterInfo->un32NbTrunk,
TB640IsdnTrunkGetKey,
NULL);
if (pAdapterInfo->hTrunkHash == NULL)
{
TBX_EXIT_ERROR(TBX_RESULT_OUT_OF_MEMORY, 0, "Unable to allocate hash table");
}
pAdapterInfo->hTrunkResHash = TBXHashCreate (
(pAdapterInfo->un32NbTrunk * TB640_ISDN_MAX_TIMESLOT_IN_TRUNK),
TB640IsdnTrunkResourceGetKey,
NULL);
if (pAdapterInfo->hTrunkResHash == NULL)
{
TBX_EXIT_ERROR(TBX_RESULT_OUT_OF_MEMORY, 0, "Unable to allocate hash table");
}
pAdapterInfo->hStackHash = TBXHashCreate (
pAdapterInfo->un32NbTrunk,
TB640IsdnStackGetKey,
NULL);
if (pAdapterInfo->hStackHash == NULL)
{
TBX_EXIT_ERROR(TBX_RESULT_OUT_OF_MEMORY, 0, "Unable to allocate hash table");
}
pAdapterInfo->hCtBusHash = TBXHashCreate (
un32NbCtbus,
TB640IsdnCtBusResourcesGetKey,
NULL);
if (pAdapterInfo->hCtBusHash == NULL)
{
TBX_EXIT_ERROR(TBX_RESULT_OUT_OF_MEMORY, 0, "Unable to allocate hash table");
}
/* Unlock all other operation lib threads */
for (un32Count1=0; un32Count1<(pAdapterInfo->un32NbOperationLib-1); un32Count1++)
{
TBX_SEM_GIV(pAdapterInfo->AttachOrDetachOpDoneSem);
}
TB640_ISDN_LOG (TRACE_LEVEL_3, "Standby procedures completed for adapter %s. Waiting for discovery...\n", pAdapterInfo->szAdapterName);
g_fRefreshDisplay |= (TB640_ISDN_CLI_CLEAR_BEFORE_REFRESH | TB640_ISDN_CLI_REFRESH_DISPLAY);
}
/* Refresh the display */
g_fRefreshDisplay |= (TB640_ISDN_CLI_REFRESH_DISPLAY | TB640_ISDN_CLI_CLEAR_BEFORE_REFRESH);
/* End of the code (skip to cleanup) */
TBX_EXIT_SUCCESS (TBX_RESULT_OK);
}
/*---------------------------------------------------------------------------------------------------------------------------
| Error handling section
*--------------------------------------------------------------------------------------------------------------------------*/
ERROR_HANDLING
{
/* Print error message */
TB640_ISDN_LOG (TRACE_LEVEL_ALWAYS, "%s (Result = 0x%08X, %s, line %d)\n", TBX_ERROR_DESCRIPTION, TBX_ERROR_RESULT, __FILE__, TBX_ERROR_LINE);
}
/*---------------------------------------------------------------------------------------------------------------------------
| Cleanup section
*--------------------------------------------------------------------------------------------------------------------------*/
CLEANUP
{
}
RETURN;
}
/*-------------------------------------------------------------------------------------------------------------------------------
|
| TB640IsdnAdapterAddedHandler: This function is called by the operation library when it detects that an adapter has been
| removed (or is no longer usable).
|
| in_pvAppContext : User-defined context
|
| Note : ~
|
| Return : No return value
|
*------------------------------------------------------------------------------------------------------------------------------*/
TBX_RESULT TB640IsdnAdapterAddedHandler (
IN PTBX_VOID in_pvAppContext)
{
TBX_BOOL fPerformSync;
TBX_BOOL fSyncFailed;
TBX_UINT32 un32NbAttach;
TBX_UINT32 un32AdapterIdx;
TBX_UINT32 un32OpLibIdx;
TBX_UINT32 un32Count1;
TBX_UINT32 un32Count;
TBX_RESULT result;
TBX_MSG_HANDLE hMsg;
TBX_FILTER_HANDLE hFilter;
PTB640_MSG_ADAPTER_OP_ATTACH pMsg;
PTB640_REQ_ADAPTER_OP_ATTACH pReq;
PTB640_RSP_ADAPTER_OP_ATTACH pRsp;
PTBX_EVT_API_NOTIF_ADAPTER_ADDED pEvtAdapterAdded;
PTB640_ISDN_ADAPTER_INFO pAdapterInfo;
/*---------------------------------------------------------------------------------------------------------------------------
| Code section
*--------------------------------------------------------------------------------------------------------------------------*/
CODE
{
/* Initialize local variables */
hFilter = NULL;
hMsg = NULL;
fPerformSync = TBX_FALSE;
fSyncFailed = TBX_FALSE;
un32NbAttach = 0;
/* Retrieve the adapter index and operation lib index */
TB640_ISDN_RETRIEVE_APP_CONTEXT (in_pvAppContext, un32AdapterIdx, un32OpLibIdx);
pAdapterInfo = &(g_AppContext->ahAdapterInfo [un32AdapterIdx]);
/* If the adapter is already sync'ed, ignore this */
if (pAdapterInfo->fSynced)
{
TBX_EXIT_SUCCESS (TBX_RESULT_OK);
}
/* Lock the adapter state semaphore */
TBX_SEM_GET(pAdapterInfo->AdapterSem, TBX_SEM_WAIT_FOREVER);
/*
* Check if the adapter is already tagged as "detached". This is necessary since we will receive one event
* per operation lib.
*/
if (pAdapterInfo->fAttached == TBX_FALSE)
{
/* Indicate the removal */
pAdapterInfo->fAttached = TBX_TRUE;
TB640_ISDN_LOG (TRACE_LEVEL_3, "Adapter %s insertion detected. Sync procedures engaged...\n", pAdapterInfo->szAdapterName);
g_fRefreshDisplay |= (TB640_ISDN_CLI_CLEAR_BEFORE_REFRESH | TB640_ISDN_CLI_REFRESH_DISPLAY);
}
/* Check if we are the last operation lib to flag the removal */
pAdapterInfo->un32NbSyncReceived++;
if (pAdapterInfo->un32NbSyncReceived == pAdapterInfo->un32NbOperationLib)
{
fPerformSync = TBX_TRUE;
pAdapterInfo->un32NbSyncReceived = 0;
}
/* Unlock the adapter state semaphore */
TBX_SEM_GIV(pAdapterInfo->AdapterSem);
/* Either wait for sync or do the sync depending if we are the last operation lib to have received the attach event */
if (fPerformSync == TBX_FALSE)
{
TB640IsdnUnlockFromOpLibIdx( pAdapterInfo, un32OpLibIdx );
TBX_SEM_GET(pAdapterInfo->AttachOrDetachOpDoneSem, TBX_SEM_WAIT_FOREVER);
TB640IsdnLockFromOpLibIdx( pAdapterInfo, un32OpLibIdx );
}
else
{
/* Lock all remaining operation lib semaphore (which should be free now) */
for (un32Count=0; un32Count<pAdapterInfo->un32NbOperationLib; un32Count++)
{
if (un32OpLibIdx != un32Count)
{
TB640IsdnLockFromOpLibIdx( pAdapterInfo, un32Count );
}
}
/* Let's try 5 attach */
for (un32NbAttach=0; un32NbAttach<TB640_ISDN_RESYNC_NB_ATTACH_ATTEMPT; un32NbAttach++)
{
/* Assume everything is ok at this point */
fSyncFailed = TBX_FALSE;
/* Format the "attach" request */
result = TBXGetMsg (g_AppContext->hTbxLib, sizeof(*pMsg), &hMsg);
if (TBX_RESULT_FAILURE (result))
{
TB640_ISDN_LOG (TRACE_LEVEL_3, "Unable to allocate attach request to adapter %s.\n", pAdapterInfo->szAdapterName);
g_fRefreshDisplay |= (TB640_ISDN_CLI_CLEAR_BEFORE_REFRESH | TB640_ISDN_CLI_REFRESH_DISPLAY);
fSyncFailed = TBX_TRUE;
}
/* Send the attach request to the newly discovered adapter */
if (!fSyncFailed)
{
/* Format the message header */
TBX_FORMAT_MSG_HEADER ( \
hMsg, \
TB640_MSG_ID_ADAPTER_OP_ATTACH, \
TBX_MSG_TYPE_REQUEST, \
sizeof(*pMsg), \
pAdapterInfo->hAdapter, \
0, \
0);
/* Format the message payload */
pMsg = (PTB640_MSG_ADAPTER_OP_ATTACH)TBX_MSG_PAYLOAD_POINTER (hMsg);
pReq = &(pMsg->Request);
pReq->un32MsgVersion = 1;
pReq->fEnableAutoReattach = TBX_TRUE;
/* Send the message */
result = TBXSendMsg (g_AppContext->hTbxLib, hMsg, &hFilter);
hMsg = NULL;
if (TBX_RESULT_FAILURE(result))
{
TB640_ISDN_LOG (TRACE_LEVEL_3, "Unable to send attach request to adapter %s.\n", pAdapterInfo->szAdapterName);
g_fRefreshDisplay |= (TB640_ISDN_CLI_CLEAR_BEFORE_REFRESH | TB640_ISDN_CLI_REFRESH_DISPLAY);
fSyncFailed = TBX_TRUE;
}
}
/* Wait for the response */
if (!fSyncFailed)
{
result = TBXReceiveMsg (g_AppContext->hTbxLib, hFilter, TB640_ISDN_RESYNC_ATTACH_REQUEST_TIMEOUT_MSEC, &hMsg);
if (TBX_RESULT_FAILURE(result))
{
TB640_ISDN_LOG (TRACE_LEVEL_3, "Didn't receive attach response from adapter %s.\n", pAdapterInfo->szAdapterName);
g_fRefreshDisplay |= (TB640_ISDN_CLI_CLEAR_BEFORE_REFRESH | TB640_ISDN_CLI_REFRESH_DISPLAY);
fSyncFailed = TBX_TRUE;
}
else
{
/* Update the adapter info */
TBXGetAdapterInfo
(
g_AppContext->hTbxLib,
pAdapterInfo->hAdapter,
&pAdapterInfo->AdapterInfo
);
}
}
/* Check if the attach was successful */
if (!fSyncFailed)
{
pMsg = (PTB640_MSG_ADAPTER_OP_ATTACH)TBX_MSG_PAYLOAD_POINTER (hMsg);
pRsp = &(pMsg->Response);
if (TBX_RESULT_FAILURE(pRsp->Result))
{
TB640_ISDN_LOG (TRACE_LEVEL_3, "Re-attach refused for adapter %s.\n", pAdapterInfo->szAdapterName);
g_fRefreshDisplay |= (TB640_ISDN_CLI_CLEAR_BEFORE_REFRESH | TB640_ISDN_CLI_REFRESH_DISPLAY);
fSyncFailed = TBX_TRUE;
}
}
/* Destroy the received response */
if (hMsg != NULL)
{
TBXReleaseMsg (g_AppContext->hTbxLib, hMsg);
hMsg = NULL;
}
/* Destroy the implicit filter */
if (hFilter != NULL)
{
TBXDestroyMsgFilter (g_AppContext->hTbxLib, hFilter);
hFilter = NULL;
}
/* If the attach succeded, continue */
if (!fSyncFailed)
{
break;
}
}
/* Then, let's resync the trunks and trunk resources */
if (!fSyncFailed)
{
TB640_ISDN_LOG (TRACE_LEVEL_3, "Sync'ing trunk and trunk resources for adapter %s\n", pAdapterInfo->szAdapterName);
g_fRefreshDisplay |= (TB640_ISDN_CLI_CLEAR_BEFORE_REFRESH | TB640_ISDN_CLI_REFRESH_DISPLAY);
result = TB640IsdnAdapterResyncTrunk (in_pvAppContext);
if (TBX_RESULT_FAILURE (result))
{
TB640_ISDN_LOG (TRACE_LEVEL_3, "Conflict detection during trunk/trunkres re-sync of adapter %s.\n", pAdapterInfo->szAdapterName);
g_fRefreshDisplay |= (TB640_ISDN_CLI_CLEAR_BEFORE_REFRESH | TB640_ISDN_CLI_REFRESH_DISPLAY);
fSyncFailed = TBX_TRUE;
}
else
{
/* Create missing trunk resource */
TB640IsdnAllocateTrunkResources (un32AdapterIdx, un32AdapterIdx+1, TBX_FALSE);
}
}
/* Then, let's resync the ctbus res */
if (!fSyncFailed)
{
TB640_ISDN_LOG (TRACE_LEVEL_3, "Sync'ing Ctbus resources for adapter %s\n", pAdapterInfo->szAdapterName);
g_fRefreshDisplay |= (TB640_ISDN_CLI_CLEAR_BEFORE_REFRESH | TB640_ISDN_CLI_REFRESH_DISPLAY);
result = TB640IsdnAdapterResyncCtbusRes (in_pvAppContext);
if (TBX_RESULT_FAILURE (result))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -