554 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			554 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*********************************************************************
 | 
						|
* Copyright (c) Intel Corporation 2011 - 2020
 | 
						|
* SPDX-License-Identifier: Apache-2.0
 | 
						|
**********************************************************************/
 | 
						|
 | 
						|
#ifndef _MINCORE
 | 
						|
 | 
						|
#ifdef HAVE_CONFIG_H
 | 
						|
#include "config.h"
 | 
						|
#endif
 | 
						|
#include "LMEConnection.h"
 | 
						|
#include "LMS_if.h"
 | 
						|
#include "../microstack/ILibParsers.h"
 | 
						|
 | 
						|
#ifdef _POSIX
 | 
						|
#define UNREFERENCED_PARAMETER(P) (P)
 | 
						|
#endif
 | 
						|
 | 
						|
#define MEI_IO_TIMEOUT 1000
 | 
						|
 | 
						|
#ifndef FALSE
 | 
						|
#define FALSE 0
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef TRUE
 | 
						|
#define TRUE 1
 | 
						|
#endif
 | 
						|
 | 
						|
const unsigned int LME_RX_WINDOW_SIZE = 4096;
 | 
						|
int LME_sendMessage(struct LMEConnection* module, unsigned char *buffer, int len);
 | 
						|
void LME_doRX(struct LMEConnection* module, unsigned char *rxBuffer, unsigned int bytesRead);
 | 
						|
void LME_apfGlobalRequest(struct LMEConnection* module, unsigned char *rxBuffer, unsigned int bytesRead, int *status);
 | 
						|
void LME_Deinit(struct LMEConnection* module);
 | 
						|
 | 
						|
bool LME_IsInitialized(struct LMEConnection* module)
 | 
						|
{
 | 
						|
	// Lock il(_initLock);
 | 
						|
	bool ret = (bool)(module->initState == INIT_STATE_CONNECTED);
 | 
						|
	return ret;
 | 
						|
}
 | 
						|
 | 
						|
#ifdef WIN32
 | 
						|
DWORD WINAPI LME_Thread(void* obj)
 | 
						|
#else
 | 
						|
void LME_Thread(void* obj)
 | 
						|
#endif
 | 
						|
{
 | 
						|
#ifdef WIN32
 | 
						|
	HECI_VERSION version;
 | 
						|
#endif
 | 
						|
	int len = 0;
 | 
						|
	int bufsize = 0;
 | 
						|
	unsigned char* data = NULL;
 | 
						|
	struct LMEConnection* module = (struct LMEConnection*)obj;
 | 
						|
 | 
						|
	//printf("LMS THREAD START\r\n");
 | 
						|
 | 
						|
	do {
 | 
						|
		bufsize = heci_GetBufferSize(&(module->mei));
 | 
						|
		if ((data = (unsigned char*)malloc(bufsize)) == NULL) ILIBCRITICALEXIT(254);
 | 
						|
 | 
						|
		do {
 | 
						|
			len = heci_ReceiveMessage(&(module->mei), data, bufsize, 0xFFFFFFFF);
 | 
						|
			//printf("LMS THREAD READ LEN=%d\r\n", len);
 | 
						|
			if (len > 0 && data != NULL) LME_doRX(module, data, len);
 | 
						|
		} while (len >= 0);
 | 
						|
		
 | 
						|
		module->cb(module, module->cbParam, NULL, 0);
 | 
						|
		module->initState = INIT_STATE_DISCONNECTED;
 | 
						|
		free(data);
 | 
						|
		
 | 
						|
		// printf("LMS TRYING RECONNECT\r\n");
 | 
						|
 | 
						|
		while (module->exit == 0 && module->initState == INIT_STATE_DISCONNECTED)
 | 
						|
		{
 | 
						|
			// Setup the MEI interface with the LME GUID
 | 
						|
			#ifdef WIN32
 | 
						|
				if (heci_Init(&(module->mei), LMS_CLIENT) == TRUE && heci_GetHeciVersion(&(module->mei), &version) == TRUE && version.major >= LMS_PROTOCOL_VERSION) { module->initState = INIT_STATE_CONNECTED; }
 | 
						|
			#else
 | 
						|
				if (heci_Init(&(module->mei), 1) == TRUE && heci_GetProtocolVersion(&(module->mei)) >= LMS_PROTOCOL_VERSION) { module->initState = INIT_STATE_CONNECTED; }
 | 
						|
			#endif
 | 
						|
 | 
						|
			if (module->exit == 0 && module->initState == INIT_STATE_DISCONNECTED)
 | 
						|
			{
 | 
						|
				// printf("LMS THREAD SLEEP\r\n");
 | 
						|
#ifdef WIN32
 | 
						|
				Sleep(2000);
 | 
						|
#else
 | 
						|
				sleep(2);
 | 
						|
#endif
 | 
						|
			}
 | 
						|
			//if (module->initState == INIT_STATE_CONNECTED) printf("LMS THREAD RECONNECT\r\n");
 | 
						|
		}
 | 
						|
	}
 | 
						|
	while (module->exit == 0);
 | 
						|
 | 
						|
	// printf("LMS THREAD QUIT\r\n");
 | 
						|
	module->exit = 2;
 | 
						|
 | 
						|
#ifdef WIN32
 | 
						|
	return 0;
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
// Setup the LME connection
 | 
						|
bool LME_Init(struct LMEConnection* module, MEICallback cb, void *param)
 | 
						|
{
 | 
						|
#ifdef WIN32
 | 
						|
	HECI_VERSION version;
 | 
						|
#endif
 | 
						|
 | 
						|
	// Setup the state object
 | 
						|
	memset(module, 0, sizeof(struct LMEConnection));
 | 
						|
	module->initState = INIT_STATE_DISCONNECTED;
 | 
						|
	module->cb = cb;
 | 
						|
	module->cbParam = param;
 | 
						|
 | 
						|
	// Setup the MEI interface with the LME GUID
 | 
						|
#ifdef WIN32
 | 
						|
	if (heci_Init(&(module->mei), LMS_CLIENT) == FALSE || heci_GetHeciVersion(&(module->mei), &version) == FALSE || version.major < LMS_PROTOCOL_VERSION) { module->initState = INIT_STATE_DISCONNECTED; return FALSE; }
 | 
						|
#else
 | 
						|
	if (heci_Init(&(module->mei), 1) == FALSE || heci_GetProtocolVersion(&(module->mei)) < LMS_PROTOCOL_VERSION) { module->initState = INIT_STATE_DISCONNECTED; return FALSE; }
 | 
						|
#endif
 | 
						|
 | 
						|
	module->initState = INIT_STATE_CONNECTED;
 | 
						|
	if ((module->txBuffer = (unsigned char*)malloc(LME_GetMeiBufferSize(module))) == NULL) ILIBCRITICALEXIT(254);
 | 
						|
 | 
						|
	// Create the thread that will read the MEI/LME stream
 | 
						|
	ILibSpawnNormalThread((voidfp)(&LME_Thread), module);
 | 
						|
 | 
						|
	return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
// Disconnect the LME connection
 | 
						|
void LME_Deinit(struct LMEConnection* module)
 | 
						|
{
 | 
						|
	//printf("LME_Deinit()\r\n");
 | 
						|
	if (module == NULL) return;
 | 
						|
	if (module->initState == INIT_STATE_CONNECTED) { heci_Deinit(&(module->mei)); }
 | 
						|
	module->initState = INIT_STATE_DISCONNECTED;
 | 
						|
}
 | 
						|
 | 
						|
// Exit LME
 | 
						|
void LME_Exit(struct LMEConnection* module)
 | 
						|
{
 | 
						|
	int l = 0;
 | 
						|
 | 
						|
	//printf("LME_Exit()\r\n");
 | 
						|
	if (module == NULL) return;
 | 
						|
	if (module->exit == 0) module->exit = 1;
 | 
						|
	LME_Deinit(module);
 | 
						|
#ifdef WIN32
 | 
						|
	while (module->exit != 2 && l < 40) { Sleep(100); l++; }
 | 
						|
#else
 | 
						|
	/*
 | 
						|
	while (module->exit != 2 && l < 4)
 | 
						|
	{
 | 
						|
		printf("LME_Holding %d\r\n", l);
 | 
						|
		Sleep(1);
 | 
						|
		l++;
 | 
						|
	}
 | 
						|
	*/
 | 
						|
#endif
 | 
						|
	if (module->txBuffer != NULL && l < 40) { free(module->txBuffer); module->txBuffer = NULL; }
 | 
						|
}
 | 
						|
 | 
						|
// Send the APF disconnect message to the MEI
 | 
						|
bool LME_Disconnect(struct LMEConnection* module, APF_DISCONNECT_REASON_CODE reasonCode)
 | 
						|
{
 | 
						|
	unsigned char buf[sizeof(APF_DISCONNECT_MESSAGE)];
 | 
						|
	APF_DISCONNECT_MESSAGE *disconnectMessage = (APF_DISCONNECT_MESSAGE *)buf;
 | 
						|
	memset(disconnectMessage, 0, sizeof(buf));
 | 
						|
	disconnectMessage->MessageType = APF_DISCONNECT;
 | 
						|
	disconnectMessage->ReasonCode = htonl(reasonCode);
 | 
						|
	return (LME_sendMessage(module, buf, sizeof(buf)) == sizeof(buf));
 | 
						|
}
 | 
						|
 | 
						|
// Send the AFP service accept message to the MEI
 | 
						|
bool LME_ServiceAccept(struct LMEConnection* module, char* serviceName)
 | 
						|
{
 | 
						|
	int len;
 | 
						|
	int res;
 | 
						|
	int servicenamelen = (int)strnlen_s(serviceName, _MAX_PATH);
 | 
						|
	unsigned char *buf;
 | 
						|
	unsigned char *pCurrent;
 | 
						|
 | 
						|
	if (!LME_IsInitialized(module)) return FALSE;
 | 
						|
	if ((buf = (unsigned char*)malloc(sizeof(APF_SERVICE_ACCEPT_MESSAGE) + servicenamelen)) == NULL) ILIBCRITICALEXIT(254);
 | 
						|
	pCurrent = buf;
 | 
						|
 | 
						|
	*pCurrent = APF_SERVICE_ACCEPT;
 | 
						|
	++pCurrent;
 | 
						|
	*((unsigned int *)pCurrent) = htonl(servicenamelen);
 | 
						|
	pCurrent += 4;
 | 
						|
 | 
						|
	memcpy_s(pCurrent, sizeof(APF_SERVICE_ACCEPT_MESSAGE) + servicenamelen, serviceName, servicenamelen);
 | 
						|
	pCurrent += servicenamelen;
 | 
						|
 | 
						|
	len = (int)(pCurrent - buf);
 | 
						|
	res = LME_sendMessage(module, buf, len);
 | 
						|
	free(buf);
 | 
						|
 | 
						|
	return (res == len);
 | 
						|
}
 | 
						|
 | 
						|
bool LME_ProtocolVersion(struct LMEConnection* module, unsigned int majorversion, unsigned int minorversion, unsigned int triggerreason)
 | 
						|
{
 | 
						|
	APF_PROTOCOL_VERSION_MESSAGE protVersion;
 | 
						|
	memset(&protVersion, 0, sizeof(protVersion));
 | 
						|
	protVersion.MessageType = APF_PROTOCOLVERSION;
 | 
						|
	protVersion.MajorVersion = htonl(majorversion);
 | 
						|
	protVersion.MinorVersion = htonl(minorversion);
 | 
						|
	protVersion.TriggerReason = htonl(triggerreason);
 | 
						|
	return (LME_sendMessage(module, (unsigned char *)&protVersion, sizeof(protVersion)) == sizeof(protVersion));
 | 
						|
}
 | 
						|
 | 
						|
bool LME_TcpForwardReplySuccess(struct LMEConnection* module, unsigned int port)
 | 
						|
{
 | 
						|
	APF_TCP_FORWARD_REPLY_MESSAGE message;
 | 
						|
	memset(&message, 0, sizeof(message));
 | 
						|
	message.MessageType = APF_REQUEST_SUCCESS;
 | 
						|
	message.PortBound = htonl(port);
 | 
						|
	return (LME_sendMessage(module, (unsigned char *)&message, sizeof(message)) == sizeof(message));
 | 
						|
}
 | 
						|
 | 
						|
bool LME_SendShortMessage(struct LMEConnection* module, unsigned char buf)
 | 
						|
{
 | 
						|
	return (LME_sendMessage(module, &buf, sizeof(buf)) == sizeof(buf));
 | 
						|
}
 | 
						|
#define pCurrentOffset ((int)(pCurrent - buf))
 | 
						|
bool LME_ChannelOpenForwardedRequest(struct LMEConnection* module, unsigned int senderChannel, char* connectedIP, unsigned int connectedPort, char* originatorIP, unsigned int originatorPort)
 | 
						|
{
 | 
						|
	int res;
 | 
						|
	int connectedIPlen = (int)strnlen_s(connectedIP, _MAX_PATH);
 | 
						|
	int originatorIPlen = (int)strnlen_s(originatorIP, _MAX_PATH);
 | 
						|
	unsigned char *buf;
 | 
						|
	unsigned char *pCurrent;
 | 
						|
	int mallocSize = 5 + APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED) + 16 + connectedIPlen + 8 + originatorIPlen + 4;
 | 
						|
	if (!LME_IsInitialized(module)) return FALSE;
 | 
						|
 | 
						|
	if ((buf = (unsigned char*)malloc(mallocSize)) == NULL) ILIBCRITICALEXIT(254);
 | 
						|
	pCurrent = buf;
 | 
						|
 | 
						|
	if (strnlen_s(originatorIP, _MAX_PATH) > 63) { free(buf); return FALSE; }
 | 
						|
	*pCurrent = APF_CHANNEL_OPEN;
 | 
						|
	++pCurrent;
 | 
						|
 | 
						|
	*((unsigned int *)pCurrent) = htonl(APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED));
 | 
						|
	pCurrent += sizeof(unsigned int);
 | 
						|
 | 
						|
	memcpy_s(pCurrent, mallocSize - pCurrentOffset, APF_OPEN_CHANNEL_REQUEST_FORWARDED, APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED));
 | 
						|
	pCurrent += APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_FORWARDED);
 | 
						|
 | 
						|
	*((unsigned int *)pCurrent) = htonl(senderChannel);
 | 
						|
	pCurrent += sizeof(unsigned int);
 | 
						|
 | 
						|
	*((unsigned int *)pCurrent) = htonl(LME_RX_WINDOW_SIZE);
 | 
						|
	pCurrent += sizeof(unsigned int);
 | 
						|
 | 
						|
	*((unsigned int *)pCurrent) = 0xFFFFFFFF;
 | 
						|
	pCurrent += sizeof(unsigned int);
 | 
						|
 | 
						|
	*((unsigned int *)pCurrent) = htonl(connectedIPlen);
 | 
						|
	pCurrent += sizeof(unsigned int);
 | 
						|
 | 
						|
	memcpy_s(pCurrent, mallocSize - pCurrentOffset, connectedIP, connectedIPlen);
 | 
						|
	pCurrent += connectedIPlen;
 | 
						|
 | 
						|
	*((unsigned int *)pCurrent) = htonl(connectedPort);
 | 
						|
	pCurrent += sizeof(unsigned int);
 | 
						|
 | 
						|
	*((unsigned int *)pCurrent) = htonl((unsigned int)originatorIPlen);
 | 
						|
	pCurrent += sizeof(unsigned int);
 | 
						|
 | 
						|
	memcpy_s(pCurrent, mallocSize - pCurrentOffset, originatorIP, originatorIPlen);
 | 
						|
	pCurrent += originatorIPlen;
 | 
						|
 | 
						|
	*((unsigned int *)pCurrent) = htonl(originatorPort);
 | 
						|
	pCurrent += sizeof(unsigned int);
 | 
						|
 | 
						|
	res = LME_sendMessage(module, buf, (int)(pCurrent - buf));
 | 
						|
	free(buf);
 | 
						|
 | 
						|
	return (res == pCurrent - buf);
 | 
						|
}
 | 
						|
 | 
						|
bool LME_ChannelOpenReplySuccess(struct LMEConnection* module, unsigned int recipientChannel, unsigned int senderChannel)
 | 
						|
{
 | 
						|
	APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE message;
 | 
						|
	message.MessageType = APF_CHANNEL_OPEN_CONFIRMATION;
 | 
						|
	message.RecipientChannel = htonl(recipientChannel);
 | 
						|
	message.SenderChannel = htonl(senderChannel);
 | 
						|
	message.InitialWindowSize = htonl(LME_RX_WINDOW_SIZE);
 | 
						|
	message.Reserved = 0xFFFFFFFF;
 | 
						|
	return (LME_sendMessage(module, (unsigned char*)&message, sizeof(message)) == sizeof(message));
 | 
						|
}
 | 
						|
 | 
						|
bool LME_ChannelOpenReplyFailure(struct LMEConnection* module, unsigned int recipientChannel, unsigned int reason)
 | 
						|
{
 | 
						|
	APF_CHANNEL_OPEN_FAILURE_MESSAGE message;
 | 
						|
	message.MessageType = APF_CHANNEL_OPEN_FAILURE;
 | 
						|
	message.RecipientChannel = htonl(recipientChannel);
 | 
						|
	message.ReasonCode = htonl(reason);
 | 
						|
	message.Reserved = 0x00000000;
 | 
						|
	message.Reserved2 = 0x00000000;
 | 
						|
	return (LME_sendMessage(module, (unsigned char*)&message, sizeof(message)) == sizeof(message));
 | 
						|
}
 | 
						|
 | 
						|
bool LME_ChannelClose(struct LMEConnection* module, unsigned int recipientChannel, unsigned int senderChannel )
 | 
						|
{
 | 
						|
	APF_CHANNEL_CLOSE_MESSAGE message;
 | 
						|
	UNREFERENCED_PARAMETER( senderChannel );
 | 
						|
 | 
						|
	message.MessageType = APF_CHANNEL_CLOSE;
 | 
						|
	message.RecipientChannel = htonl(recipientChannel);
 | 
						|
	return (LME_sendMessage(module, (unsigned char*)&message, sizeof(message)) == sizeof(message));
 | 
						|
}
 | 
						|
 | 
						|
int LME_ChannelData(struct LMEConnection* module, unsigned int recipientChannel, unsigned int len, unsigned char *buffer)
 | 
						|
{
 | 
						|
	APF_CHANNEL_DATA_MESSAGE *message;
 | 
						|
	if (len > (LME_GetMeiBufferSize(module) - sizeof(APF_CHANNEL_DATA_MESSAGE)) || module->txBuffer == NULL) return -1;
 | 
						|
	message = (APF_CHANNEL_DATA_MESSAGE*)module->txBuffer;
 | 
						|
	message->MessageType = APF_CHANNEL_DATA;
 | 
						|
	message->RecipientChannel = htonl(recipientChannel);
 | 
						|
	message->DataLength = htonl(len);
 | 
						|
	memcpy_s(module->txBuffer + sizeof(APF_CHANNEL_DATA_MESSAGE), LME_GetMeiBufferSize(module) - sizeof(APF_CHANNEL_DATA_MESSAGE), buffer, len);
 | 
						|
	return LME_sendMessage(module, (unsigned char *)message, sizeof(APF_CHANNEL_DATA_MESSAGE) + len) - sizeof(APF_CHANNEL_DATA_MESSAGE);
 | 
						|
}
 | 
						|
 | 
						|
bool LME_ChannelWindowAdjust(struct LMEConnection* module, unsigned int recipientChannel, unsigned int len)
 | 
						|
{
 | 
						|
	APF_WINDOW_ADJUST_MESSAGE message;
 | 
						|
	message.MessageType = APF_CHANNEL_WINDOW_ADJUST;
 | 
						|
	message.RecipientChannel = htonl(recipientChannel);
 | 
						|
	message.BytesToAdd = htonl(len);
 | 
						|
	return (LME_sendMessage(module, (unsigned char *)&message, sizeof(message)) == sizeof(message));
 | 
						|
}
 | 
						|
 | 
						|
int LME_sendMessage(struct LMEConnection* module, unsigned char *buffer, int len)
 | 
						|
{
 | 
						|
	int result;
 | 
						|
	if (!LME_IsInitialized(module)) { return -1; }
 | 
						|
	result = heci_SendMessage(&(module->mei), buffer, len, MEI_IO_TIMEOUT);
 | 
						|
	if (result < 0) LME_Deinit(module);
 | 
						|
	return result;
 | 
						|
}
 | 
						|
 | 
						|
bool LME_checkMinMsgSize(unsigned char *buf, unsigned int bytesRead)
 | 
						|
{
 | 
						|
	switch (buf[0]) {
 | 
						|
	case APF_DISCONNECT:
 | 
						|
		if (bytesRead < sizeof(APF_DISCONNECT_MESSAGE)) { return FALSE; }
 | 
						|
		break;
 | 
						|
	case APF_SERVICE_REQUEST:
 | 
						|
		if (bytesRead < sizeof(APF_SERVICE_REQUEST_MESSAGE)) { return FALSE; }
 | 
						|
		if (bytesRead < (sizeof(APF_SERVICE_REQUEST_MESSAGE) + ntohl(((APF_SERVICE_REQUEST_MESSAGE *)buf)->ServiceNameLength))) { return FALSE; }
 | 
						|
		break;
 | 
						|
	case APF_USERAUTH_REQUEST:
 | 
						|
		if (bytesRead < (3 * sizeof(unsigned int))) { return FALSE; }
 | 
						|
		break;
 | 
						|
	case APF_GLOBAL_REQUEST:
 | 
						|
		if (bytesRead < (sizeof(APF_GENERIC_HEADER) + sizeof(UINT8))) { return FALSE; }
 | 
						|
		if (bytesRead < (sizeof(APF_GENERIC_HEADER) + sizeof(UINT8) + ntohl(((APF_GENERIC_HEADER *)buf)->StringLength))) { return FALSE; }
 | 
						|
		break;
 | 
						|
	case APF_CHANNEL_OPEN:
 | 
						|
		if (bytesRead < sizeof(APF_GENERIC_HEADER)) { return FALSE; }
 | 
						|
		if (bytesRead < (sizeof(APF_GENERIC_HEADER) + ntohl(((APF_GENERIC_HEADER *)buf)->StringLength))) { return FALSE; }
 | 
						|
		break;
 | 
						|
	case APF_CHANNEL_OPEN_CONFIRMATION:
 | 
						|
		if (bytesRead < sizeof(APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE)) { return FALSE; }
 | 
						|
		break;
 | 
						|
	case APF_CHANNEL_OPEN_FAILURE:
 | 
						|
		if (bytesRead < sizeof(APF_CHANNEL_OPEN_FAILURE_MESSAGE)) { return FALSE; }
 | 
						|
		break;
 | 
						|
	case APF_CHANNEL_CLOSE:
 | 
						|
		if (bytesRead < sizeof(APF_CHANNEL_CLOSE_MESSAGE)) { return FALSE; }
 | 
						|
		break;
 | 
						|
	case APF_CHANNEL_DATA:
 | 
						|
		if (bytesRead < sizeof(APF_CHANNEL_DATA_MESSAGE)) { return FALSE; }
 | 
						|
		if (bytesRead < (sizeof(APF_CHANNEL_DATA_MESSAGE) + ntohl(((APF_CHANNEL_DATA_MESSAGE *)buf)->DataLength))) { return FALSE; }
 | 
						|
		break;
 | 
						|
	case APF_CHANNEL_WINDOW_ADJUST:
 | 
						|
		if (bytesRead < sizeof(APF_WINDOW_ADJUST_MESSAGE)) { return FALSE; }
 | 
						|
		break;
 | 
						|
	case APF_PROTOCOLVERSION:
 | 
						|
		if (bytesRead < sizeof(APF_PROTOCOL_VERSION_MESSAGE)) { return FALSE; }
 | 
						|
		break;
 | 
						|
	default:
 | 
						|
		return FALSE;
 | 
						|
	}
 | 
						|
	return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
void LME_doRX(struct LMEConnection* module, unsigned char *rxBuffer, unsigned int bytesRead)
 | 
						|
{
 | 
						|
	if (bytesRead == 0) return;
 | 
						|
	if (!LME_checkMinMsgSize(rxBuffer, bytesRead)) { LME_Deinit(module); return; }
 | 
						|
	module->cb(module, module->cbParam, rxBuffer, bytesRead);
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
void LME_apfChannelOpen(struct LMEConnection* module, unsigned char *rxBuffer, unsigned int bytesRead, int *status)
 | 
						|
{
 | 
						|
	APF_GENERIC_HEADER *pHeader = (APF_GENERIC_HEADER *)rxBuffer;
 | 
						|
 | 
						|
	if (_strnicmp((char *)pHeader->String, APF_OPEN_CHANNEL_REQUEST_DIRECT, APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_DIRECT)) == 0)
 | 
						|
	{
 | 
						|
		unsigned int senderChannel = 0;
 | 
						|
 | 
						|
		LME_apfChannelOpenDirect(module, rxBuffer, bytesRead, &senderChannel, status);
 | 
						|
		if (LME_IsInitialized(module) && (*status == 1)) {
 | 
						|
			if (plugin.retry(rxBuffer, bytesRead) != LMS_DROPPED) { LME_apfChannelOpenDirect(module, rxBuffer, bytesRead, NULL, status); }
 | 
						|
		}
 | 
						|
 | 
						|
		if (LME_IsInitialized(module) && (*status == 1)) {
 | 
						|
			LME_ChannelOpenReplyFailure(module, senderChannel, OPEN_FAILURE_REASON_CONNECT_FAILED);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
void LME_apfChannelOpenDirect(struct LMEConnection* module, unsigned char *rxBuffer, unsigned int bytesRead, unsigned int *senderChannel, int *status)
 | 
						|
{
 | 
						|
	unsigned char *pCurrent;
 | 
						|
	APF_GENERIC_HEADER *pHeader = (APF_GENERIC_HEADER *)rxBuffer;
 | 
						|
 | 
						|
	if (bytesRead < sizeof(APF_GENERIC_HEADER) +
 | 
						|
	    ntohl(pHeader->StringLength) +
 | 
						|
	    7 + (5 * sizeof(unsigned int))) {
 | 
						|
		ILIBMESSAGE("apfChannelOpenDirect: Error receiving data from MEI\n");
 | 
						|
		LME_Deinit(module);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	pCurrent = rxBuffer + sizeof(APF_GENERIC_HEADER) +
 | 
						|
		APF_STR_SIZE_OF(APF_OPEN_CHANNEL_REQUEST_DIRECT);
 | 
						|
 | 
						|
	LMEChannelOpenRequestMessage channelOpenRequest;
 | 
						|
	channelOpenRequest.ChannelType = APF_CHANNEL_DIRECT;
 | 
						|
 | 
						|
	channelOpenRequest.SenderChannel = ntohl(*((unsigned int *)pCurrent));
 | 
						|
	if (senderChannel) {
 | 
						|
		*senderChannel = channelOpenRequest.SenderChannel;
 | 
						|
	}
 | 
						|
	pCurrent += sizeof(unsigned int);
 | 
						|
	channelOpenRequest.InitialWindow = ntohl(*((unsigned int *)pCurrent));
 | 
						|
	pCurrent += 2 * sizeof(unsigned int);
 | 
						|
 | 
						|
	unsigned int len = ntohl(*((unsigned int *)pCurrent));
 | 
						|
	pCurrent += sizeof(unsigned int);
 | 
						|
	channelOpenRequest.Address.append((char *)pCurrent, len);
 | 
						|
	pCurrent += len;
 | 
						|
	channelOpenRequest.Port = ntohl(*((unsigned int *)pCurrent));
 | 
						|
	pCurrent += sizeof(unsigned int);
 | 
						|
 | 
						|
	module->_cb(module, module->_cbParam, &channelOpenRequest, sizeof(channelOpenRequest), status);
 | 
						|
}
 | 
						|
*/
 | 
						|
 | 
						|
/*
 | 
						|
void LME_apfUserAuthRequest(struct LMEConnection* module, unsigned char *rxBuffer, unsigned int bytesRead, int *status)
 | 
						|
{
 | 
						|
	unsigned char *pCurrent = rxBuffer;
 | 
						|
 | 
						|
	++pCurrent;
 | 
						|
 | 
						|
	LMEUserAuthRequestMessage userAuthRequest;
 | 
						|
 | 
						|
	unsigned int len = ntohl(*((unsigned int *)pCurrent));
 | 
						|
	pCurrent += sizeof(unsigned int);
 | 
						|
 | 
						|
	if ((bytesRead - (pCurrent - rxBuffer)) < len) {
 | 
						|
		ILIBMESSAGE("_apfUserAuthRequest1: Error receiving data from MEI\n");
 | 
						|
		LME_Deinit(module);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	userAuthRequest.Username.append((char *)pCurrent, len);
 | 
						|
	pCurrent += len;
 | 
						|
 | 
						|
	if ((unsigned int)(bytesRead - (pCurrent - rxBuffer)) < sizeof(unsigned int)) {
 | 
						|
		ILIBMESSAGE("_apfUserAuthRequest2: Error receiving data from MEI\n");
 | 
						|
		LME_Deinit(module);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	len = ntohl(*((unsigned int *)pCurrent));
 | 
						|
	pCurrent += sizeof(unsigned int);
 | 
						|
 | 
						|
	if ((bytesRead - (pCurrent - rxBuffer)) < len) {
 | 
						|
		ILIBMESSAGE("_apfUserAuthRequest3: Error receiving data from MEI\n");
 | 
						|
		LME_Deinit(module);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	userAuthRequest.ServiceName.append((char *)pCurrent, len);
 | 
						|
	pCurrent += len;
 | 
						|
 | 
						|
	if ((unsigned int)(bytesRead - (pCurrent - rxBuffer)) < sizeof(unsigned int)) {
 | 
						|
		ILIBMESSAGE("_apfUserAuthRequest4: Error receiving data from MEI\n");
 | 
						|
		LME_Deinit(module);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	len = ntohl(*((unsigned int *)pCurrent));
 | 
						|
	pCurrent += sizeof(unsigned int);
 | 
						|
 | 
						|
	if ((bytesRead - (pCurrent - rxBuffer)) < len) {
 | 
						|
		ILIBMESSAGE("_apfUserAuthRequest5: Error receiving data from MEI\n");
 | 
						|
		LME_Deinit(module);
 | 
						|
		return;
 | 
						|
	}
 | 
						|
 | 
						|
	userAuthRequest.MethodName.append((char *)pCurrent, len);
 | 
						|
	pCurrent += len;
 | 
						|
 | 
						|
	if (_strnicmp(userAuthRequest.MethodName.c_str(), APF_AUTH_PASSWORD,
 | 
						|
			userAuthRequest.MethodName.size()) == 0) {
 | 
						|
 | 
						|
		if ((unsigned int)(bytesRead - (pCurrent - rxBuffer)) < sizeof(unsigned int) + 1) {
 | 
						|
			ILIBMESSAGE("_apfUserAuthRequest6: Error receiving data from MEI\n");
 | 
						|
			LME_Deinit(module);
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		++pCurrent;
 | 
						|
 | 
						|
		len = ntohl(*((unsigned int *)pCurrent));
 | 
						|
		pCurrent += sizeof(unsigned int);
 | 
						|
 | 
						|
		if ((bytesRead - (pCurrent - rxBuffer)) < len) {
 | 
						|
			ILIBMESSAGE("_apfUserAuthRequest7: Error receiving data from MEI\n");
 | 
						|
			LME_Deinit(module);
 | 
						|
			return;
 | 
						|
		}
 | 
						|
 | 
						|
		AuthPasswordData authData;
 | 
						|
		authData.Password.append((char *)pCurrent, len);
 | 
						|
		pCurrent += len;
 | 
						|
 | 
						|
		userAuthRequest.MethodData = &authData;
 | 
						|
	}
 | 
						|
 | 
						|
	module->_cb(module, module->_cbParam, &userAuthRequest, sizeof(userAuthRequest), status);
 | 
						|
}
 | 
						|
*/
 | 
						|
 | 
						|
unsigned int LME_GetMeiBufferSize(struct LMEConnection* module)
 | 
						|
{
 | 
						|
	return heci_GetBufferSize(&(module->mei));
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |