Пример #1
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// UDP Layer must be initialized
// theIp and thePort cannot be 0 (Zero)
// Rejects a Peer's request for communication 
// Should only be used by App
GSUdpErrorCode gsUdpEngineRejectPeer(unsigned int theIp, unsigned short thePort)
{
	GSUdpRemotePeer aRemotePeer;	
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	int index;
	GS_ASSERT(aUdp->mInitialized);
	GS_ASSERT(theIp);
	GS_ASSERT(thePort);
	if (!aUdp->mInitialized)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Engine not initialized\n");
		return GS_UDP_NETWORK_ERROR;
	}

	if (theIp == 0 || thePort == 0)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Invalid parameter(s), check ip, port\n");
		return GS_UDP_PARAMETER_ERROR;
	}

	// Find the connection to reject in our array of peers
	aRemotePeer.mAddr = theIp;
	aRemotePeer.mPort = thePort;
	index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0);
	if (index != NOT_FOUND)
	{
		GSUdpRemotePeer *aPeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index);
		gt2Reject(aPeerFound->mConnection, NULL, 0);
		ArrayDeleteAt(aUdp->mRemotePeers, index);
	}
	return GS_UDP_NO_ERROR;
}
Пример #2
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// UDP Layer must be initialized
// theIp and thePort cannot be 0 (Zero)
// Based on an IP and port, the function will return the amount of free space 
// of a peer's buffer.
int gsUdpEngineGetPeerOutBufferFreeSpace(unsigned int theIp, unsigned short thePort)
{
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	GSUdpRemotePeer aRemotePeer, *aRemotePeerFound;
	int index;
	GS_ASSERT(aUdp->mInitialized);
	GS_ASSERT(theIp);
	GS_ASSERT(thePort);
	if (!aUdp->mInitialized)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Engine not initialized\n");
		return 0;
	}

	aRemotePeer.mAddr = theIp;
	aRemotePeer.mPort = thePort;
	index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0);
	if (index != NOT_FOUND)
	{
		aRemotePeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index);
		return gt2GetOutgoingBufferFreeSpace(aRemotePeerFound->mConnection);
	}
	return 0;
}
Пример #3
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// UDP Layer must be initialized
// Used obtain the peer's state 
// theIp and thePort cannot be 0 (Zero)
GSUdpErrorCode gsUdpEngineGetPeerState(unsigned int theIp, unsigned short thePort, GSUdpPeerState *thePeerState)
{
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	GSUdpRemotePeer aPeer, *aPeerFound;
	int index;
	GS_ASSERT(aUdp->mInitialized);
	GS_ASSERT(theIp);
	GS_ASSERT(thePort);
	GS_ASSERT(thePeerState != NULL);
	if (!aUdp->mInitialized)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_State, GSIDebugLevel_Debug, 
			"[Udp Engine] Engine not initialized\n");
		*thePeerState = GS_UDP_PEER_CLOSED;
		return GS_UDP_NOT_INITIALIZED;
	}

	aPeer.mAddr = theIp;
	aPeer.mPort = thePort;
	index = ArraySearch(aUdp->mRemotePeers, &aPeer, gsUdpRemotePeerCompare, 0, 0);
	if (index == NOT_FOUND)
	{
		*thePeerState = GS_UDP_PEER_CLOSED;
		return GS_UDP_NO_ERROR;
	}
	
	aPeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index);

	*thePeerState = (GSUdpPeerState)gt2GetConnectionState(aPeerFound->mConnection);
	return GS_UDP_NO_ERROR;
}
Пример #4
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// UDP Layer must be initialized
// When a message handler is done or shutting down, the message handler should remove
// itself from the UDP Layer
// The header cannot be empty
GSUdpErrorCode gsUdpEngineRemoveMsgHandler(char theHeader[GS_UDP_MSG_HEADER_LEN])
{
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	GSUdpMsgHandler aHandler;
	int index;
	
	GS_ASSERT(aUdp->mInitialized);
	GS_ASSERT(theHeader);
	if (!aUdp->mInitialized)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Engine not initialized\n");
		return GS_UDP_NETWORK_ERROR;
	}

	if (!theHeader || !theHeader[0])
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] invalid or empty header\n");
		return GS_UDP_PARAMETER_ERROR;
	}
	
	memcpy(aHandler.mHeader, theHeader, GS_UDP_MSG_HEADER_LEN);

	index = ArraySearch(aUdp->mMsgHandlers, &aHandler, gsUdpMsgHandlerCompare2, 0, 0);
	if (index != NOT_FOUND)
	{
		ArrayDeleteAt(aUdp->mMsgHandlers, index);
	}
	return GS_UDP_NO_ERROR;
}
Пример #5
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Requests for communication from a peer is handled by first checking if the 
// initial message has a message handler registered for it.  Otherwise 
// the message is passed onto the app.
void gsUdpConnAttemptCB(GT2Socket socket, GT2Connection connection, unsigned int ip, 
						unsigned short port, int latency, GT2Byte * message, int len)
{
	// Get the message handler for the connection 
	int index;
	GSUdpMsgHandler aHandler;
	GSUdpRemotePeer aRemotePeer;
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	char anAddr[GS_IP_ADDR_AND_PORT];
	
	gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
		"[Udp Engine] Connection attempt from %s\n", gt2AddressToString(ip, port, anAddr));
	//If there is a handler, automatically accept a connection if the initial message is
	//the same as the handler's registered initial message
	if (len >= GS_UDP_MSG_HEADER_LEN)
	{    
		memcpy(aHandler.mInitialMsg, message, GS_UDP_MSG_HEADER_LEN);
		
		aRemotePeer.mAddr = ip;
		aRemotePeer.mPort = port;
		aRemotePeer.mConnection = connection;
		
		ArrayAppend(aUdp->mRemotePeers, &aRemotePeer);
		index = ArraySearch(aUdp->mMsgHandlers, &aHandler, gsUdpMsgHandlerCompare, 0, 0);
		if (index != NOT_FOUND)
		{
			GT2ConnectionCallbacks aCallbacks;
			
			aCallbacks.closed = gsUdpClosedRoutingCB;
			aCallbacks.connected = gsUdpConnectedRoutingCB;
			aCallbacks.ping = gsUdpPingRoutingCB;
			aCallbacks.received = gsUdpReceivedRoutingCB;

	       
			// Automatically accept connections for Message Handlers
			gt2Accept(aRemotePeer.mConnection, &aCallbacks);	
			gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
				"[Udp Engine] Connection attempt auto-accepted for message handler\n");
			return;
		}
	}
	// all other messages go to the app
	if (aUdp->mAppConnAttempt) 
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
			"[Udp Engine] Connection attempt from %s, asking app to accept/reject\n", gt2AddressToString(ip, port, anAddr));
		aUdp->mAppConnAttempt(ip, port, latency, (unsigned char *)message, (unsigned int)len, aUdp->mAppUserData);
	}
	else 
	{
		// Reject any un-handled connections or unknown connections
		gt2Reject(connection, NULL, 0);
		ArrayRemoveAt(aUdp->mRemotePeers, ArrayLength(aUdp->mRemotePeers) -1);
	}
	GSI_UNUSED(socket);
	GSI_UNUSED(anAddr);
}
Пример #6
0
void TableEnter(HashTable table, const void *newElem)
{
	int hash, itempos;

	hash = table->hashfn(newElem, table->nbuckets);
	itempos = ArraySearch(table->buckets[hash], newElem, table->compfn, 0, 0);
	if (itempos == NOT_FOUND)
		ArrayAppend(table->buckets[hash], newElem);
	else
		ArrayReplaceAt(table->buckets[hash], newElem, itempos);
}
Пример #7
0
void *TableLookup(HashTable table, const void *elemKey)
{
	int hash, itempos;

	hash = table->hashfn(elemKey, table->nbuckets);
	itempos = ArraySearch(table->buckets[hash], elemKey, table->compfn, 0, 0);
	if (itempos == NOT_FOUND)
		return NULL;
	else
		return ArrayNth(table->buckets[hash], itempos);
}
Пример #8
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Lets the App and Message Handlers know a peer left
void gsUdpClosedRoutingCB(GT2Connection theConnection, GT2CloseReason reason)
{
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	GSUdpRemotePeer aRemotePeer;
	int index, len;
	GSUdpCloseReason aReason;
	char anAddr[GS_IP_ADDR_AND_PORT];

	if (reason == GT2CommunicationError || reason == GT2SocketError)
		aReason = GS_UDP_CLOSED_BY_COMM_ERROR;
	else if (reason == GT2NotEnoughMemory)
		aReason = GS_UDP_CLOSED_BY_LOW_MEM;
	else 
		aReason = (GSUdpCloseReason)reason;

	gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
		"[Udp Engine] Connection closed to %s\n", gt2AddressToString(gt2GetRemoteIP(theConnection), 
		gt2GetRemotePort(theConnection), anAddr));
	len = ArrayLength(aUdp->mMsgHandlers);
	for (index = 0; index < len; index++)
	{
		GSUdpMsgHandler *aHandler = (GSUdpMsgHandler *)ArrayNth(aUdp->mMsgHandlers, index);
		if (aHandler->mClosed)
		{			
			gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
				"[Udp Engine] Connection closed: passed to message handler\n");
			aHandler->mClosed(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), aReason, aHandler->mUserData);
		}	
	}
	
	if (aUdp->mAppClosed)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
			"[Udp Engine] Connection closed: passed to app\n");
		aUdp->mAppClosed(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), aReason, aUdp->mAppUserData);
	}

	aRemotePeer.mConnection = theConnection;
	index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare2, 0, 0);
	if (index != NOT_FOUND)
	{
		ArrayDeleteAt(aUdp->mRemotePeers, index);
	}
	GSI_UNUSED(anAddr);
}
Пример #9
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Any data received prompts the UDP layer to first find a higher level 
// message handler to handle the data.  If there was no message handler 
// found, the data is passed to the higher level app.
void gsUdpReceivedRoutingCB(GT2Connection theConnection, GT2Byte *theMessage, int theMessageLen, 
							GT2Bool reliable)
{
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	GSUdpMsgHandler aHandler;
	int index;
	char anAddr[GS_IP_ADDR_AND_PORT];	

	gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
		"[Udp Engine] Received data from %s\n", gt2AddressToString(gt2GetRemoteIP(theConnection), 
		gt2GetRemotePort(theConnection), anAddr));
	//If there is a handler, pass it to the handler
	//The header should not be stripped off
	if (theMessageLen >= GS_UDP_MSG_HEADER_LEN)
	{    
		memcpy(aHandler.mHeader, theMessage, GS_UDP_MSG_HEADER_LEN);

		index = ArraySearch(aUdp->mMsgHandlers, &aHandler, gsUdpMsgHandlerCompare2, 0, 0);
		if (index != NOT_FOUND)
		{
			GSUdpMsgHandler *aHandlerFound = (GSUdpMsgHandler *)ArrayNth(aUdp->mMsgHandlers, index);
			if (aHandlerFound->mReceived)
			{
				gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
					"[Udp Engine] Passed to message handler\n");
				aHandlerFound->mReceived(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), 
					theMessage + GS_UDP_MSG_HEADER_LEN, (unsigned int)(theMessageLen - GS_UDP_MSG_HEADER_LEN), reliable, aHandlerFound->mUserData);
				return;
			}
		}
	}

	if (aUdp->mAppRecvData) 
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
			"[Udp Engine] Passed to app\n");
		aUdp->mAppRecvData(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), theMessage, (unsigned int)theMessageLen, reliable,
			aUdp->mAppUserData);
	}
	GSI_UNUSED(anAddr);
}
Пример #10
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// UDP Layer must be initialized
// theIp and thePort cannot be 0 (Zero)
// Accepts a Peer's request for communication 
// Should only be used by App
GSUdpErrorCode gsUdpEngineAcceptPeer(unsigned int theIp, unsigned short thePort)
{	
	GSUdpRemotePeer aRemotePeer;	
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	int index;
	GS_ASSERT(aUdp->mInitialized);
	GS_ASSERT(theIp);
	GS_ASSERT(thePort);
	if (!aUdp->mInitialized)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Engine not initialized\n");
		return GS_UDP_NETWORK_ERROR;
	}

	if (theIp == 0 || thePort == 0)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Invalid parameter(s), check ip, port\n");
		return GS_UDP_PARAMETER_ERROR;
	}

	aRemotePeer.mAddr = theIp;
	aRemotePeer.mPort = thePort;
	index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0);
	if (index != NOT_FOUND)
	{
		GT2ConnectionCallbacks aCallbacks;
		
		GSUdpRemotePeer *aPeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index);
		
		aCallbacks.closed = gsUdpClosedRoutingCB;
		aCallbacks.connected = gsUdpConnectedRoutingCB;
		aCallbacks.ping = gsUdpPingRoutingCB;
		aCallbacks.received = gsUdpReceivedRoutingCB;
		
		gt2Accept(aPeerFound->mConnection, &aCallbacks);
	}
	return GS_UDP_NO_ERROR;
}
Пример #11
0
void Visitor() /* code block to perform visitor operation */
{
  int condnToWait,who,i,j, num;
  int talkingTime;
  int checkCorrectOperatorV;
  int phoneToUse,gotPhone;
  int thisActivate;
  int operatorToUse;
  int callPresident;

/* Some common parameters */


  char lockName[30];
  char condName1[30];
  char condName2[30];
  int presidentStatus;
  int phoneStatus;
  char printing[50];
  int lockID1, lockID2, lockID3, lockID4, lockID5, lockID6, condID1, condID2, condID3, condID4;
  int indOpLock[20], waitForOperVerCV[20], waitForCallerCV[20];
  int activate, authMechanism, freeOperators, operatorStatus;
  int repositoryMoney;
 

  presidentStatus = CreateSharedInt("presidentStatus",15,1);
  phoneStatus = CreateSharedInt("phoneStatus",11,NOOFPHONES);
  freeOperators = CreateSharedInt("freeOperators",13,1);
  operatorStatus = CreateSharedInt("operatorStatus",14,Nop);
  activate = CreateSharedInt("activate",sizeof("activate"),Nop);
  authMechanism = CreateSharedInt("authMechanism",sizeof("authMechanism"),Nop);
  repositoryMoney = CreateSharedInt("repositoryMoney",sizeof("repositoryMoney"),Nop);
 
  

  lockID1 = CreateLock("phoneLock",10);                  /* obtain a master lock for all phones */
  lockID2 = CreateLock("GlobalOpLock",12);     /* obtain a master lock for all the operators */
  lockID3 = CreateLock("visitorCountLock",17);     /* obtain a lock to keep track of the number of visitors permitted to make a call */
  lockID4 = CreateLock("NumSenators",12);
  lockID5 = CreateLock("NumVisitors",12);
  lockID6 = CreateLock("NumOperators",13);
  /*  displayLock = CreateLock("DispLock",7); */
  /* Lock **individualOperatorLock; */                            /* obtain an individual lock for every operator */
  condID1 = CreateCondition("presiNeedsPhone",16); /* condition variable for the condition that president needs phone */
  condID2 = CreateCondition("senatorNeedsPhone",18);     /* condition variable for the condition that senator needs phone */
  condID3 = CreateCondition("visitorNeedsPhone",18);     /* condition variable for the condition that visitor  needs phone */
  condID4 = CreateCondition("processCustomer",16);         /* condition variable to allow president/senator/visitor to make a call */
  for (i=0;i<Nop;i++)
    {
      Concatenate("OperatorLock",sizeof("OperatorLock"),i,lockName);
      Concatenate("waitForOpVer",sizeof("waitForOpVer"),i,condName1);
      Concatenate("waitForCaller",sizeof("waitForCaller"),i,condName2); 
      indOpLock[i] = CreateLock(lockName,sizeof(lockName));
      waitForOperVerCV[i] = CreateCondition(condName1,sizeof(condName1));
      waitForCallerCV[i] = CreateCondition(condName2,sizeof(condName2));
    } 
  
  
  
  /* End of common parameters */

  AcquireLock(lockID5);
  who = NumVisitor;
  NumVisitor++;
  ReleaseLock(lockID5);
  AcquireLock(lockID1);
  /* loop to check if the president or senator is waiting. If any one is waiting, then visitor has to wait before he/she can make a call. Otherwise visitor can go ahead */
  do
    {
      condnToWait = TRUE;      
      if(GetSharedInt(presidentStatus,0) == 1)
		condnToWait = TRUE;
      /* Check if some senator is already waiting! */
      else if(CheckCondWaitQueue(condID2)==1)
		{
		  /* Bad luck, there seems to be a senator.  */
		  condnToWait = TRUE;
		}
      else
		{
		  /*
	  for(i=0;i<NOOFPHONES;i++)
	    {
	      if(GetSharedInt(phoneStatus,i)==FREE)
		   {
			  phoneToUse = i;
			  SetSharedInt(phoneStatus,i,BUSY);
			  condnToWait = FALSE;
			  break;
		   }
	    }	*/
		phoneToUse = GetOneIndex(phoneStatus);
		if(phoneToUse!=NOOFPHONES)
			condnToWait = FALSE;
	}
      if(condnToWait)
	WaitCV(condID3,lockID1); /* visitor waits if there is a president or a senator already waitng to make a call. */
    }while(condnToWait);
  ReleaseLock(lockID1);
  /* Visitor has got a phone */
  /* Need to get an operator now */
  AcquireLock(lockID2);
  while(GetSharedInt(freeOperators,0)==0)
    WaitCV(condID4,lockID2);
  /* visitor has to wait if there are no free operators available */
  /* Some operator is available. Though I don't know who it is. Let us find out.   */ 
  /*
  for(j=0;j<Nop;j++)
    {
      if(GetSharedInt(operatorStatus,j)==FREE)
	{
	  operatorToUse = j;
	  break;
	}
    } */
	operatorToUse = GetOneIndex(operatorStatus);
  /* operator obtained */
  checkCorrectOperatorV = operatorToUse; /* check if the operator to whom the visitor pays money is the same as the one the permits/denies the visitor to make a call */
  AcquireLock(indOpLock[operatorToUse]);
  SetSharedInt(activate, operatorToUse, 2);
  SetSharedInt(operatorStatus, operatorToUse, BUSY);
  SetSharedInt(freeOperators, 0, GetSharedInt(freeOperators, 0) - 1);
  ReleaseLock(lockID2);
  SetSharedInt(authMechanism, operatorToUse, 3);  /* 1 for President | 2 for Senators | 3 for Visitors */
  SetSharedInt(repositoryMoney, operatorToUse, ((RandomFunction(100)-1)>80)?0:1); /* randomly generate whether the visitor pays $1 or not */
  /* If operator is sleeping, wake up */

  SignalCV(waitForCallerCV[operatorToUse],indOpLock[operatorToUse]);
  SignalCV(waitForCallerCV[operatorToUse],indOpLock[operatorToUse]);
  while(GetSharedInt(activate,operatorToUse)==2)
	  WaitCV(waitForOperVerCV[operatorToUse],indOpLock[operatorToUse]);
  thisActivate=0;
  thisActivate=GetSharedInt(activate, operatorToUse);  
  ReleaseLock(indOpLock[operatorToUse]);
  if (thisActivate==0) 
    {
	  /* visitor is denied access to phone beacause he/she didn't pay $1. */
      j=0;
      talkingTime=0;
      /* printf("Visitor%d \t  UNAVAILABLE \t %d/%d units \t %d \t   NOTAPPLICABLE    DENIED \t   Money paid is $0 - verified by operator 
	  %d \n",who+1,j,talkingTime,operatorToUse+1,checkCorrectOperatorV+1); */
	  /*	   AcquireLock(displayLock); */
	  Write("Visitor ",8,1);
	   num = who+1;
		itoa(printing,10,num);
	    Write(printing,sizeof(printing),1);
		Write(" \t UNAVAILABLE \t",100,1);	   
		num = j;
	    itoa(printing,10,num);
	    Write(printing,sizeof(printing),1);
	    Write("/",1,1);
	    num=talkingTime;
	    itoa(printing,10,num);
	    Write(printing,sizeof(printing),1);
	    Write(" units \t ",10,1);
	    num=operatorToUse+1;
	    itoa(printing,10,num);
	    Write(printing,sizeof(printing),1);
	    Write(" \t",6,1);	
	    Write(" NOTAPPLICABLE    DENIED \t   Money paid is $0 - verified by operator ",100,1);
	    num=checkCorrectOperatorV+1;
	    itoa(printing,10,num);
	    Write(printing,sizeof(printing),1);
	    Write(" \n",3,1);
		/*ReleaseLock(displayLock);*/
	Yield();

      /* printf("Access to Phone for visitor %d Denied by Operator %d!\n",who+1,operatorToUse+1); */
    }
  else if (thisActivate==1) /* visitor has paid $1. Operator verifies and visitor is allowed to make a call */
    {
      /* Now Talk */
      talkingTime = RandomFunction(5); /* randomly generate the amount of time the visitor will talk on the phone */
      /* loop for the visitor to talk on the phone for the randomly generated time period */
      for (i=1;i<=talkingTime;i++){
	/* printf("Visitor%d \t  %d \t\t %d/%d units \t %d \t   NOTAPPLICABLE    ACCEPTED \t   
	Money paid is $1 - verified by operator %d \n",who+1,phoneToUse+1,i,talkingTime,operatorToUse+1,checkCorrectOperatorV+1); */
	/*AcquireLock(displayLock);*/
	Write("Visitor ",8,1);
	   num = who+1;
		itoa(printing,10,num);
	    Write(printing,sizeof(printing),1);
		Write(" \t",2,1);
	    num = phoneToUse+1;
	    itoa(printing,10,num);
	    Write(printing,sizeof(printing),1);
	    Write("\t\t ",5,1);
		num = i;
	    itoa(printing,10,num);
	    Write(printing,sizeof(printing),1);
	    Write("/",1,1);
	    num=talkingTime;
	    itoa(printing,10,num);
	    Write(printing,sizeof(printing),1);
	    Write(" units \t ",10,1);
	    num=operatorToUse+1;
	    itoa(printing,10,num);
	    Write(printing,sizeof(printing),1);
	    Write(" \t",6,1);	
	    Write(" NOTAPPLICABLE    ACCEPTED \t   Money paid is $1 - verified by operator ",100,1);
	    num=checkCorrectOperatorV+1;
	    itoa(printing,10,num);
	    Write(printing,sizeof(printing),1);
	    Write(" \n",3,1);
		/*ReleaseLock(displayLock);*/
	/*Yield();*/
      }
      /* visitor is done talking */
      /* Set the phone status to be free */
    }
  AcquireLock(lockID1);
  SetSharedInt(phoneStatus,phoneToUse,FREE);
  if(GetSharedInt(presidentStatus,0)==0) /* president is not waking to talk */
    {
      if(CheckCondWaitQueue(condID2))
		SignalCV(condID2,lockID1); /* wake up the next senator waiting to talk */
      else
		SignalCV(condID3,lockID1); /* if no senator is waiting, then wake up the next visitor waiting to talk */
    }
  else /* president is waiting to talk, so senators and visitors will have to wait */
    {
      callPresident = TRUE;
	  /*
      for(i=0;i<NOOFPHONES;i++)
		if((i!=phoneToUse)&&(GetSharedInt(phoneStatus,i)==BUSY)) // check if even a single phone is busy other than the phone just used by the visitor which he/she sets to free 
	  {
	    callPresident = FALSE;
	    break;
	  }*/
		i = ArraySearch(phoneStatus, phoneToUse, BUSY);
		if(i!=NOOFPHONES)
			callPresident = FALSE;
      if(callPresident==TRUE)
	SignalCV(condID1,lockID1); /* if all phones are free, then no one is talking currently and so, signal the president */
    }
  /* visitor goes away and does not return. Remember visitors can make a maximum of just one call       */
  ReleaseLock(lockID1);	
  WriteMe("Visitor ");WriteNum(who + 1);WriteMe("Leaving\n");
  Exit(0);
}
Пример #12
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// UDP Layer must be initialized
// Sends a message to a peer using IP and Port
// An empty header constitutes the app sending this message.
// theIp and thePort cannot be 0 (Zero)
// 
// WARNING: Messages should not be greater than the outgoing buffer size minus the header 
// and the 7 byte header for reliable messages (used for internal gt2 operations). Most
// UDP fragmentation occurs if messages are bigger than 1500 bytes.  Also, some routers are 
// known to drop those packets that are larger than 1500 bytes.  The recommended outgoing 
// buffer size is the default (1460).  So take that, and subtract 16 for message handler header
// and reliable message header (if sending data reliably).
// freeSpace = 1460 - 16 - 7
GSUdpErrorCode gsUdpEngineSendMessage(unsigned int theIp, unsigned short thePort, 
									  char theHeader[GS_UDP_MSG_HEADER_LEN], unsigned char *theMsg, 
									  unsigned int theMsgLen, gsi_bool theReliable)
{
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	int aTotalMessageLen, index;
	GSUdpRemotePeer aRemotePeer, *aRemotePeerFound;
	GT2Byte *fullMessage;
	GT2Result aResult;
	GS_ASSERT(aUdp->mInitialized);
	GS_ASSERT(theIp);
	GS_ASSERT(thePort);
	if (!aUdp->mInitialized)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Engine not initialized\n");
		return GS_UDP_NETWORK_ERROR;
	}

	// Messages being sent with an empty header are treated as app messages
	if (!theHeader[0])
		aTotalMessageLen = (int)theMsgLen;
	else 
		aTotalMessageLen = (int)(GS_UDP_MSG_HEADER_LEN + theMsgLen);

	aRemotePeer.mAddr = theIp;
	aRemotePeer.mPort = thePort;

	index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0);
	if (index == NOT_FOUND)
	{
		char anAddr[GS_IP_ADDR_AND_PORT];
		gt2AddressToString(theIp, thePort, anAddr);
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_WarmError,
			"[Udp Engine] address not found for sending message\n", anAddr);
		return GS_UDP_ADDRESS_ERROR;
	}
	else
	{
		aRemotePeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index);
	}

	if (aTotalMessageLen > gt2GetOutgoingBufferSize(aRemotePeerFound->mConnection) && theReliable)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_WarmError,
			"[Udp Engine] Message Size too large, dropping message\n");
		return GS_UDP_MSG_TOO_BIG;
	}

	fullMessage = (GT2Byte *)gsimalloc((unsigned long)aTotalMessageLen);
	memcpy(fullMessage, theHeader, GS_UDP_MSG_HEADER_LEN);
	memcpy(fullMessage + GS_UDP_MSG_HEADER_LEN, theMsg, theMsgLen);
	// Send the message 
	// reliable messages will be kept in the outgoing buffers till they are sent
	aResult = gt2Send(aRemotePeerFound->mConnection, fullMessage, aTotalMessageLen, theReliable);
	gsifree(fullMessage);

	if (aResult != GT2Success)
		return GS_UDP_SEND_FAILED;
	return GS_UDP_NO_ERROR;
}
Пример #13
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// UDP Layer must be initialized
// theIp and thePort cannot be 0 (Zero)
// Starts a request to open a communication channel with another peer based on 
// IP and port.  
GSUdpErrorCode gsUdpEngineStartTalkingToPeer(unsigned int theIp, unsigned short thePort,
									  char theInitMsg[GS_UDP_MSG_HEADER_LEN], int timeOut)
{
	char anAddr[GS_IP_ADDR_AND_PORT];
	GSUdpRemotePeer aRemotePeer;	
	GSUdpMsgHandler aHandler;
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	GT2ConnectionCallbacks aCallbacks;
	int index;
	GS_ASSERT(aUdp->mInitialized);
	GS_ASSERT(theIp);
	GS_ASSERT(thePort);

	if (!aUdp->mInitialized)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Engine not initialized\n");
		return GS_UDP_NETWORK_ERROR;
	}
	
	if (theIp == 0 || thePort == 0)
	{
		gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
			"[Udp Engine] Invalid parameter(s), check ip, port");
		return GS_UDP_PARAMETER_ERROR;
	}
	
	aRemotePeer.mAddr = theIp;  // In Network Byte Order for GT2
	aRemotePeer.mPort = thePort;  // In Host Byte Order for GT2

	index = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0);
	if (index != NOT_FOUND)
	{
		GSUdpRemotePeer *aPeerFound = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, index);
		GT2ConnectionState aState = gt2GetConnectionState(aPeerFound->mConnection);
		if (aState == GT2Connected)
		{
			gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Debug,
				"[Udp Engine] Engine is already talking to remote address\n");
			return GS_UDP_ADDRESS_ALREADY_IN_USE;
		}
		else if (aState == GT2Connecting)
		{
			memcpy(aHandler.mInitialMsg, theInitMsg, GS_UDP_MSG_HEADER_LEN);
			
			index = ArraySearch(aUdp->mMsgHandlers, &aHandler, gsUdpMsgHandlerCompare, 0, 0);
			if (index != NOT_FOUND)
			{
				GSUdpMsgHandler *aHandlerFound = (GSUdpMsgHandler *)ArrayNth(aUdp->mMsgHandlers, index);
				ArrayAppend(aHandlerFound->mPendingConnections, aPeerFound);
			}
		}
	}	
	else
	{
		gt2AddressToString(theIp, thePort, anAddr);
		aCallbacks.closed = gsUdpClosedRoutingCB;
		aCallbacks.connected = gsUdpConnectedRoutingCB;
		aCallbacks.ping = gsUdpPingRoutingCB;
		aCallbacks.received = gsUdpReceivedRoutingCB;

		// start the connect without blocking since we want the engine to be as asynchronous as possible
		gt2Connect(aUdp->mSocket, &aRemotePeer.mConnection, anAddr, (unsigned char *)theInitMsg, GS_UDP_MSG_HEADER_LEN, timeOut, &aCallbacks, GT2False);

		ArrayAppend(aUdp->mRemotePeers, &aRemotePeer);
		
		memcpy(aHandler.mInitialMsg, theInitMsg, GS_UDP_MSG_HEADER_LEN);
		
		index = ArraySearch(aUdp->mMsgHandlers, &aHandler, gsUdpMsgHandlerCompare, 0, 0);
		if (index != NOT_FOUND)
		{
			GSUdpRemotePeer *aRemotePeerPtr = (GSUdpRemotePeer *)ArrayNth(aUdp->mRemotePeers, ArrayLength(aUdp->mRemotePeers) - 1);
			GSUdpMsgHandler *aHandlerFound = (GSUdpMsgHandler *)ArrayNth(aUdp->mMsgHandlers, index);
			ArrayAppend(aHandlerFound->mPendingConnections, &aRemotePeerPtr);
		}
		else
		{
			aUdp->mAppPendingConnections++;
		}
	}
	return GS_UDP_NO_ERROR;
}
Пример #14
0
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// When a peer has accepted a GT2Connection the UDP layer needs to let 
// higher level app or message handler know that it accepted the request to
// to message a peer.
void gsUdpConnectedRoutingCB(GT2Connection theConnection, GT2Result theResult, GT2Byte *theMessage,
							 int theMessageLen)
{
	GSUdpEngineObject *aUdp = gsUdpEngineGetEngine();
	int aIndex, len;
	GSUdpErrorCode aCode;
	char anAddr[GS_IP_ADDR_AND_PORT];

	switch(theResult)
	{
		case GT2NegotiationError:
			aCode = GS_UDP_REMOTE_ERROR;
			break;
		case GT2Rejected:
			aCode = GS_UDP_REJECTED;
			break;
		case GT2TimedOut:
			aCode = GS_UDP_TIMED_OUT;
			break;
		case GT2Success:
			aCode = GS_UDP_NO_ERROR;
			break;
		default: 
			aCode = GS_UDP_UNKNOWN_ERROR;
			break;
	}
	if (theResult == GT2Rejected)
	{
		int aRemotePeerIdx;
		GSUdpRemotePeer aRemotePeer;
		aRemotePeer.mAddr = gt2GetRemoteIP(theConnection);
		aRemotePeer.mPort = gt2GetRemotePort(theConnection);
		aRemotePeerIdx = ArraySearch(aUdp->mRemotePeers, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0);
		if (aRemotePeerIdx != NOT_FOUND)
		{
			gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
				"[Udp Engine] Connect rejected by %s\n", gt2AddressToString(gt2GetRemoteIP(theConnection), 
				gt2GetRemotePort(theConnection), anAddr));

			ArrayDeleteAt(aUdp->mRemotePeers, aRemotePeerIdx);
		}
	}

	len = ArrayLength(aUdp->mMsgHandlers);
	for (aIndex = 0; aIndex < len; aIndex++)
	{
		int aRemotePeerIdx;
		GSUdpRemotePeer aRemotePeer;
		GSUdpMsgHandler *aTempHandler = (GSUdpMsgHandler *)ArrayNth(aUdp->mMsgHandlers, aIndex);
		
		aRemotePeer.mAddr = gt2GetRemoteIP(theConnection);
		aRemotePeer.mPort = gt2GetRemotePort(theConnection);
		aRemotePeerIdx = ArraySearch(aTempHandler->mPendingConnections, &aRemotePeer, gsUdpRemotePeerCompare, 0, 0);
		if (aRemotePeerIdx != NOT_FOUND)
		{
			if (aTempHandler->mConnected)
			{	
				gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
					"[Udp Engine] Passing connect result to message handler\n");
				aTempHandler->mConnected(gt2GetRemoteIP(theConnection), gt2GetRemotePort(theConnection), 
					aCode, theResult == GT2Rejected ? gsi_true : gsi_false, aTempHandler->mUserData);				
			}
			ArrayDeleteAt(aTempHandler->mPendingConnections, aRemotePeerIdx);
			return;
		}
	}
	
	if (aUdp->mAppPendingConnections > 0)
	{
		if (aUdp->mAppConnected)
		{
			gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment, 
				"[Udp Engine] Passing connect result to app\n");
			aUdp->mAppConnected(gt2GetRemoteIP(theConnection),gt2GetRemotePort(theConnection), 
				aCode, theResult == GT2Rejected ? gsi_true : gsi_false, aUdp->mAppUserData);
		}
		aUdp->mAppPendingConnections--;
	}
	GSI_UNUSED(theMessage);
	GSI_UNUSED(theMessageLen);
	GSI_UNUSED(anAddr);
}