rveppclient.c

来自「h.248协议源码」· C语言 代码 · 共 361 行

C
361
字号
#if (0)
******************************************************************************
Filename   :
Description:
******************************************************************************
                Copyright (c) 1999 RADVision Inc.
************************************************************************
NOTICE:
This document contains information that is proprietary to RADVision LTD.
No part of this publication may be reproduced in any form whatsoever 
without written prior approval by RADVision LTD..

RADVision LTD. reserves the right to revise this publication and make 
changes without obligation to notify any person of such revisions or 
changes.
******************************************************************************
$Revision:$
$Date:$
$Author: S. Cipolli$
******************************************************************************
#endif
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "rvstr.h"
#include "rvmem.h"
#include "rvlog.h"
#include "rvdefalloc.h"
#include "rveppclient.h"

/* EppClientEndpoint */
RvEppClientEndpoint* rvEppClientEndpointConstruct(RvEppClientEndpoint* ece,
  const char* name, const char* param, 
  const char* ip, RvInetPort port) {

	if (rvSocketConstructUdp(&ece->s, 0) == NULL)
		return NULL;

	if ((!strcmp(param, "ipphone")) || (!strcmp(param, "analogphone"))) {
		strcpy(ece->profile, param);
		strcpy(ece->packages, "");
	}
	else {
		strcpy(ece->packages, param);
		strcpy(ece->profile, "");
	}
	strcpy(ece->name, name);
	strcpy(ece->ip, ip);
	ece->port = port;

	return ece;
}

void rvEppClientEndpointDestruct(RvEppClientEndpoint* ece) {
	rvSocketDestruct(&ece->s);
}

static void rvEppClientEndpointAsyncSend(RvEppClientEndpoint* ece, char* msg, size_t size) {
	/* Note: size is the total size of the msg buffer not the length */
#ifndef RV_IO_NONE
	printf("Sending (async): %s\n", msg);
#endif
	rvSocketSendToInetEx(&ece->s, msg, strlen(msg), 
	  rvEppClientEndpointGetIp(ece), rvEppClientEndpointGetPort(ece));
}

static void rvEppClientEndpointSend(RvEppClientEndpoint* ece, char* msg, size_t size) {
	/* Note: size is the total size of the msg buffer not the length */
	RvSocketAddr fromAddr;
	int len;
#ifndef RV_IO_NONE
	printf("Sending (sync): %s\n", msg);
#endif
	rvSocketSendToInetEx(&ece->s, msg, strlen(msg), 
	  rvEppClientEndpointGetIp(ece), rvEppClientEndpointGetPort(ece));

	len = rvSocketRecvFrom(&ece->s, msg, size, &fromAddr);
	msg[len] = '\0';
#ifndef RV_IO_NONE
	printf("Received: %s\n", msg);
#endif
}

/* EppClient */

static void rvEppClientRemoveEndpoint(RvEppClient* ec, const char* endpointName) {
	RvPtrListIter i;

	for (i = rvPtrListBegin(&ec->endpoints); 
	  i != rvPtrListEnd(&ec->endpoints);
	  i = rvPtrListIterNext(i)) {
		RvEppClientEndpoint* ece = rvPtrListIterData(i);
		if (strcmp(endpointName, rvEppClientEndpointGetName(ece)) == 0) {
			ec->eUnregister(ec, ece, ec->data);
			rvPtrListErase(&ec->endpoints, i);
			rvMemFree(ece);
			break;
		}
	}
}

static void rvEppClientAddEndpoint(RvEppClient* ec, RvEppClientEndpoint* ece) {
	rvEppClientRemoveEndpoint(ec, rvEppClientEndpointGetName(ece));
	rvPtrListPushBack(&ec->endpoints, ece);
	ec->eRegister(ec, ece, ec->data);
}

static void rvEppClientWrapper(RvThread* thread, void* data) {
	RvEppClient* ec = (RvEppClient*)data;
	char err[128];
	char msg[256];
	char* command;
	char* endpointName;
	RvSocketAddr fromAddr;
	RvStrTok tokenizer;

	while (!ec->done) {
		int len = rvSocketRecvFrom(&ec->s, msg, sizeof(msg), &fromAddr);
		if (len < 0)
			continue;
		msg[len] = '\0';
#ifndef RV_IO_NONE
		printf("Received: %s\n", msg);
#endif
		rvStrTokConstruct(&tokenizer, " \t\n", msg);
		
		command = rvStrTokGetToken(&tokenizer);
		endpointName = rvStrTokGetToken(&tokenizer);

		if (strcmp(command, "register") == 0) {
			RvEppClientEndpoint* ece = rvMemAlloc(sizeof(RvEppClientEndpoint));
			char* param = rvStrTokGetToken(&tokenizer);
			char* ip = rvStrTokGetToken(&tokenizer);
			RvInetPort port = atoi(rvStrTokGetToken(&tokenizer));

			/* Remove endpoint if it is already registered */
			rvEppClientRemoveEndpoint(ec, endpointName);
			
			/* Construct endpoint */
			if (rvEppClientEndpointConstruct(ece, endpointName, param, 
			  ip, port) == NULL) {
				rvMemFree(ece);
				sprintf(err, "rvEppClientWrapper: Unable to construct endpoint");
				rvLogError(&rvLog, err);
			}
			
			/* Add endpoint to client */
			rvEppClientAddEndpoint(ec, ece);
		
		} else if (strcmp(command, "event") == 0) {
			RvPtrListIter i;
			for (i = rvPtrListBegin(&ec->endpoints); 
			  i != rvPtrListEnd(&ec->endpoints);
			  i = rvPtrListIterNext(i)) {
				RvEppClientEndpoint* ece = rvPtrListIterData(i);
				if (strcmp(endpointName, rvEppClientEndpointGetName(ece)) == 0) {
					char* event = rvStrTokGetToken(&tokenizer);
					char* params = rvStrTokGetToken(&tokenizer);
					ec->eEvent(ec, ece, event, params, ec->data);
					break;
				}			
			}
		} else if (strcmp(command, "unregister") == 0) {
				rvEppClientRemoveEndpoint(ec, endpointName);
		} else {
			sprintf(err, "rvEppClientWrapper: Unknown EPP event %s", command);
			rvLogError(&rvLog, err);
		}

		rvStrTokDestruct(&tokenizer);
	}
}

RvEppClient* rvEppClientConstruct(RvEppClient* ec, RvInetPort port,
  RvEppClientRegister eRegister, 
  RvEppClientEvent eEvent,
  RvEppClientUnregister eUnregister, void *data) {

	ec->eRegister = eRegister;
	ec->eEvent = eEvent;
	ec->eUnregister = eUnregister;
	ec->data = data;

	rvPtrListConstruct(&ec->endpoints, &rvDefaultAlloc);
	
	if (rvSocketConstructUdp(&ec->s, port) == NULL)
		return NULL;

	if (rvThreadConstruct(&ec->thread, "EPP Client", RV_PRIORITYVALUE_NORMAL, 32768, rvEppClientWrapper, ec) == NULL)
		return NULL;

	ec->done = rvFalse;
	rvThreadStart(&ec->thread);
	
	return ec;
}

void rvEppClientDestruct(RvEppClient* ec) {
	ec->done = rvTrue;
	rvSocketDestruct(&ec->s);
	rvThreadDestruct(&ec->thread);
	while(rvPtrListSize(&ec->endpoints))
	{
		RvEppClientEndpoint *ece = rvPtrListFront(&ec->endpoints);
		rvEppClientEndpointDestruct(ece);
		rvMemFree(ece);
		rvPtrListPopFront(&ec->endpoints);
	}
	rvPtrListDestruct(&ec->endpoints);
}

RvEppConnId rvEppClientOpen(RvEppClient* ec, RvEppClientEndpoint* ece,
   RvEppConnParameters* connParams) {
	char msg[256];
	RvStrTok tokenizer;
	char* token;
	char connParamStr[128];

	sprintf(msg, "open %s %s", ece->name, rvEppConnParametersEncode(connParams, connParamStr));
	rvEppClientEndpointSend(ece, msg, sizeof(msg));

	rvStrTokConstruct(&tokenizer, " \t\n", msg);
	token = rvStrTokGetToken(&tokenizer);
	if (strcmp(token, "reply") == 0) {
		token = rvStrTokGetToken(&tokenizer);
		if (strcmp(token, "nak") != 0)
			return atoi(token);
	}

	return (-1);
}

RvBool rvEppClientModify(RvEppClient* ec, RvEppClientEndpoint* ece, 
  RvEppConnId connId, RvEppConnParameters* connParams) {
	char msg[256];
	RvStrTok tokenizer;
	char* token;
	char connParamStr[128];

	sprintf(msg, "modify %d %s", connId, 
	  rvEppConnParametersEncode(connParams, connParamStr));
	rvEppClientEndpointSend(ece, msg, sizeof(msg));
	
	rvStrTokConstruct(&tokenizer, " \t\n", msg);
	token = rvStrTokGetToken(&tokenizer);
	if (strcmp(token, "reply") == 0) {
		token = rvStrTokGetToken(&tokenizer);
		if (strcmp(token, "ack") == 0)
			return  rvTrue;
	}

	return rvFalse;
}


char* rvEppClientQuery(RvEppClient* ec, RvEppClientEndpoint* ece, const char* termConnId,
  const char* propertyName, OUT char* propertyValue) {
	char msg[256];
	RvStrTok tokenizer;
	char* token;
	char* property;

	sprintf(msg, "query %s %s", termConnId, propertyName);
	rvEppClientEndpointSend(ece, msg, sizeof(msg));

	rvStrTokConstruct(&tokenizer, " \t\n", msg);
	token = rvStrTokGetToken(&tokenizer);
	if (strcmp(token, "reply") == 0) {
		/* Don't use the tokenizer to get the property,
		   because there may be spaces in the middle */
		/* Look for the first non space after token */
		/*token = rvStrTokGetToken(&tokenizer);*/
		property = rvStrFindFirstNotOf(token+strlen(token)+1," ");
		if (strcmp(property, "nak") != 0) {
				strcpy(propertyValue, property);
			return propertyValue;
		}
	}

	return NULL;
}

RvBool rvEppClientSet(RvEppClient* ec, RvEppClientEndpoint* ece, const char* termConnId, 
										const char* propertyName, const char* propertyValue) {
	char msg[256];
	RvStrTok tokenizer;
	char* token;

	sprintf(msg, "set %s %s %s", termConnId, propertyName, propertyValue);
	rvEppClientEndpointSend(ece, msg, sizeof(msg));

	rvStrTokConstruct(&tokenizer, " \t\n", msg);
	token = rvStrTokGetToken(&tokenizer);
	if (strcmp(token, "reply") == 0) {
		token = rvStrTokGetToken(&tokenizer);
		if (strcmp(token, "ack") == 0)
			return  rvTrue;
	}

	return rvFalse;
}

RvInetPort rvEppClientGetPort(RvEppClient* ec, RvEppClientEndpoint* ece, 
  RvEppConnId connId) {
	char propertyValue[32];
	char id[32];

	sprintf(id, "%d", connId);
	if (rvEppClientQuery(ec, ece, id, "port", propertyValue))
		return atoi(propertyValue);

	return 0;
}


RvBool rvEppClientClose(RvEppClient* ec, RvEppClientEndpoint* ece, RvEppConnId connId) {
	char msg[256];

	sprintf(msg, "close %d", connId);
	rvEppClientEndpointAsyncSend(ece, msg, sizeof(msg));
	return rvTrue;
}
RvBool rvEppClientStart(RvEppClient* ec, RvEppClientEndpoint* ece, const char* signal) {
	char msg[256];
	RvStrTok tokenizer;
	char* token;

	sprintf(msg, "start %s %s", ece->name, signal);
	rvEppClientEndpointSend(ece, msg, sizeof(msg));

	rvStrTokConstruct(&tokenizer, " \t\n", msg);
	token = rvStrTokGetToken(&tokenizer);
	if (strcmp(token, "reply") == 0) {
		token = rvStrTokGetToken(&tokenizer);
		if (strcmp(token, "ack") == 0)
			return  rvTrue;
	}

	return rvFalse;
}

RvBool rvEppClientStop(RvEppClient* ec, RvEppClientEndpoint* ece, const char* signal) {
	char msg[256];
	RvStrTok tokenizer;
	char* token;

	sprintf(msg, "stop %s %s", ece->name, signal);
	rvEppClientEndpointSend(ece, msg, sizeof(msg));
	
	rvStrTokConstruct(&tokenizer, " \t\n", msg);
	token = rvStrTokGetToken(&tokenizer);
	if (strcmp(token, "reply") == 0) {
		token = rvStrTokGetToken(&tokenizer);
		if (strcmp(token, "ack") == 0)
			return  rvTrue;
	}

	return rvFalse;  
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?