예제 #1
0
		internal virtual void  sendProfile(string uri, string datum, ChannelImpl ch)
		{
			
			// Send the profile
			System.Text.StringBuilder sb = new System.Text.StringBuilder();
			
			sb.Append("<profile uri='");
			sb.Append(uri);
			
			if ((object) datum != null)
			{
				sb.Append("'><![CDATA[");
				sb.Append(datum);
				sb.Append("]]></profile>");
			}
			else
			{
				sb.Append("' />");
			}
			
			OutputDataStream ds = new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE, System.Text.Encoding.ASCII.GetBytes(sb.ToString()));
			
			// Store the Channel
			channels[ch.NumberAsString] = ch;
			((IMessageMSG) zero.AppData).sendRPY(ds);
		}
예제 #2
0
		/// <summary>The Initiator Oriented close channel call...but this one is not an
		/// external call, it's invoked from Channel.close();</summary>
		/// <param name="channel"></param>
		/// <param name="code"></param>
		/// <param name="xmlLang"></param>
		/// <exception cref="BEEPException" />
		internal virtual void  closeChannel(ChannelImpl channel, BEEPStatusCode code, string xmlLang)
		{
			
			// Construct Message
			System.Text.StringBuilder closeBuffer = new System.Text.StringBuilder();
			
			closeBuffer.Append("<close number='");
			closeBuffer.Append(channel.NumberAsString);
			closeBuffer.Append("' code='");
			closeBuffer.Append(code);
			
			if ((object) xmlLang != null)
			{
				closeBuffer.Append("' xml:lang='");
				closeBuffer.Append(xmlLang);
			}
			
			closeBuffer.Append("' />");
			
			// Lock necessary because we have to know the msgNo
			// before we send the message, in order to be able
			// to associate the reply with this start request
			CloseReplyListener reply = new CloseReplyListener(this, channel);
			lock (reply)
			{
				OutputDataStream ds = new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE, System.Text.Encoding.ASCII.GetBytes(closeBuffer.ToString()));
				
				this.zero.sendMSG(ds, reply);
				try
				{
					System.Threading.Monitor.Wait(reply);
				}
				catch (System.Threading.ThreadInterruptedException e)
				{
					log.error("Error waiting for reply", e);
					throw new BEEPException("Interrupted waiting for reply");
				}
			}
			
			// check the channel state and return the appropriate exception
			if (reply.isError())
			{
				throw reply.getError();
			}
			
			if (channel.getState() != core.ChannelState.STATE_CLOSED)
			{
				throw new BEEPException("Error channel state (" + channel.getState() + ")");
			}
			
			fireChannelClosed(channel);
		}
예제 #3
0
		internal virtual IChannel startChannelRequest(System.Collections.ICollection profiles, IRequestHandler handler, bool tuning)
		{
			string channelNumber = NextFreeChannelNumber;
			
			// create the message in a buffer and send it
			System.Text.StringBuilder startBuffer = new System.Text.StringBuilder();
			
			startBuffer.Append("<start number='");
			startBuffer.Append(channelNumber);
			if ((object) serverName != null && !sentServerName)
			{
				startBuffer.Append("' serverName='");
				startBuffer.Append(serverName);
			}
			startBuffer.Append("'>");
			
			foreach(StartChannelProfile p in profiles)
			{
				// @todo maybe we should check these against peerSupportedProfiles
				startBuffer.Append("<profile uri='");
				startBuffer.Append(p.uri);
				startBuffer.Append("' ");
				
				if ((object) p.data == null)
				{
					startBuffer.Append(" />");
				}
				else
				{
					if (p.base64Encoding)
					{
						startBuffer.Append("encoding='base64' ");
					}
					
					startBuffer.Append("><![CDATA[");
					startBuffer.Append(p.data);
					startBuffer.Append("]]></profile>");
				}
			}
			
			startBuffer.Append("</start>");
			
			// @todo handle the data element
			// Create a channel
			ChannelImpl ch = new ChannelImpl(null, channelNumber, handler, false, this);
			
			// Make a message
			OutputDataStream ds = new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE, System.Text.Encoding.ASCII.GetBytes(startBuffer.ToString()));
			
			if (tuning)
			{
				this.changeState(core.SessionState.SESSION_STATE_TUNING_PENDING);
				this.changeState(core.SessionState.SESSION_STATE_TUNING);
				this.zero.setState(core.ChannelState.STATE_TUNING);
			}
			
			// Tell Channel Zero to start us up
			StartReplyListener reply = new StartReplyListener(this, ch);
			lock (reply)
			{
				this.zero.sendMSG(ds, reply);
				try
				{
					System.Threading.Monitor.Wait(reply);
				}
				catch (System.Threading.ThreadInterruptedException e)
				{
					log.error("Interrupted waiting for reply", e);
					throw new BEEPException("Interrupted waiting for reply");
				}
			}
			
			// check the channel state and return the appropriate exception
			if (reply.isError())
			{
				throw reply.getError();
			}
			
			if (ch.getState() != core.ChannelState.STATE_ACTIVE)
			{
				throw new BEEPException("Error channel state (" + ch.getState() + ")");
			}
			
			if (tuning)
			{
				ch.setState(core.ChannelState.STATE_TUNING);
			}
			
			if ((object) serverName != null)
			{
				sentServerName = true;
			}
			
			fireChannelStarted(ch);
			return ch;
		}
예제 #4
0
		private void  sendGreeting()
		{
			log.debug("sendGreeting");
			
			// get the greeting from the session
			byte[] greeting = this.ProfileRegistry.getGreeting(this);
			ByteOutputDataStream f = new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE, greeting);
			
			IMessageMSG m = new MessageMSGImpl(this.zero, 0, null);
			
			// send the greeting
			m.sendRPY(f);
		}
예제 #5
0
		private void  receiveCloseChannelZero()
		{
			
			// closing the session
			// @todo fireEvent(SESSION_STATE_CLOSING);
			
			if (log.isDebugEnabled())
			{
				log.debug("Closing Session with " + channels.Count + " channels");
			}
			
			try
			{
				changeState(core.SessionState.SESSION_STATE_CLOSE_PENDING);
				changeState(core.SessionState.SESSION_STATE_CLOSING);
			}
			catch (BEEPException)
			{
				terminate("Error changing Session state to closing.");
				return ;
			}
			
			object[] keys = new object[channels.Keys.Count];
			channels.Keys.CopyTo(keys,0);

			foreach(object key in keys)
			{
				ChannelImpl ch = (ChannelImpl) channels[key];
				
				// if this channel is not zero, call the channel's scl
				if (ch.Number == 0)
				{
					continue;
				}
				
				IStartChannelListener scl = profileRegistry.getStartChannelListener(this.tuningProperties, ch.getProfile());
				
				// check locally first to see if it is ok to close the channel
				try
				{
					scl.CloseChannel(ch);

					channels.Remove(key);
				}
				catch (CloseChannelException e)
				{
					try
					{
						changeState(core.SessionState.SESSION_STATE_ACTIVE);
						
						enableIO();
						throw e;
					}
					catch (BEEPException)
					{
						terminate("Error changing Session state from closing " + "to active");
						
						return ;
					}
				}
				fireChannelClosed(ch);
			}
			
			OutputDataStream sds = new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE, OK_ELEMENT);
			
			try
			{
				((IMessageMSG) zero.AppData).sendRPY(sds);
			}
			catch (BEEPException)
			{
				terminate("Error sending RPY for <close> for channel 0");
				
				return ;
			}
			
			try
			{
				this.changeState(core.SessionState.SESSION_STATE_CLOSED);
			}
			catch (BEEPException e)
			{
				log.error("Error changing state", e);
			}
			
			fireSessionClosed();
		}
예제 #6
0
		/// <summary>This method is called when Channel Zero receives - from our
		/// session peer - a request to close a channel.</summary>
		/// <param name="channelNumber"></param>
		/// <param name="code"></param>
		/// <param name="xmlLang"></param>
		/// <param name="data"></param>
		/// <exception cref="BEEPException" />
		private void  receiveCloseChannel(string channelNumber, string code, string xmlLang, string data)
		{
			
			// @todo fix close channel
			if (channelNumber.Equals(CHANNEL_ZERO))
			{
				receiveCloseChannelZero();
				
				return ;
			}
			
			enableIO();
			
			ChannelImpl channel = (ChannelImpl) channels[channelNumber];
			
			if (channel == null)
			{
				throw new BEEPError(BEEPStatusCode.PARAMETER_INVALID, "Close requested for nonexistent channel");
			}
			
			try
			{
				IStartChannelListener scl = profileRegistry.getStartChannelListener(this.tuningProperties, channel.getProfile());
				
				scl.CloseChannel(channel);
				channel.setState(core.ChannelState.STATE_CLOSING);
			}
			catch (BEEPError x)
			{
				channel.setState(core.ChannelState.STATE_CLOSING);
				
				throw x;
			}
			
			// Send an ok
			OutputDataStream sds = new ByteOutputDataStream(MimeHeaders.BEEP_XML_CONTENT_TYPE, OK_ELEMENT);
			
			try
			{
				((IMessageMSG) zero.AppData).sendRPY(sds);
			}
			catch (BEEPException)
			{
				terminate("Error sending RPY for <close>");
				
				return ;
			}

			// We need to close the server socket at some point !
			this.disableIO();
			
			// We're past the CCL approval
			channel.setState(core.ChannelState.STATE_CLOSED);
			channels.Remove(channel.NumberAsString);
			fireChannelClosed(channel);
		}