protected internal bool connect()
		{
			bool result = false;
			bool startReader = false;

			lock (lockSocket)
			{
				if (mrSocket == null)
				{
#if LOGGER
					logger.Info("Connecting to {0}:{1}", hostname, port);
#endif
					try
					{
						mrSocket = new SocketConnection(hostname, port, socketEncoding);
						result = mrSocket.IsConnected;
					}
#if LOGGER
					catch (Exception ex)
					{
						logger.Info("Connect - Exception  : {0}", ex.Message);
#else
					catch
					{
#endif
						result = false;
					}
					if (result)
					{
						if (this.mrReader == null)
						{
							mrReader = new ManagerReader(this);
							mrReaderThread = new Util.ThreadClass(new ThreadStart(this.mrReader.Run), "ManagerReader-" + DateTime.Now.Second);
							mrReader.Socket = mrSocket;
							startReader = true;
						}
						else
							mrReader.Socket = mrSocket;
						mrReader.Reinitialize();
					}
					else
						mrSocket = null;
				}
			}

			if (startReader)
				mrReaderThread.Start();

			return IsConnected();
		}
		/// <summary> Closes the socket connection.</summary>
		private void disconnect(bool withDie)
		{
			lock (lockSocket)
			{
				if (withDie)
				{
					reconnectEnable = false;
					reconnected = false;
					enableEvents = true;
				}

				if (mrReader != null)
				{
					if (withDie)
					{
						mrReader.Die = true;
						mrReader = null;
					}
					else
						mrReader.Socket = null;
				}

				if (this.mrSocket != null)
				{
					mrSocket.Close();
					mrSocket = null;
				}

				responseEventHandlers.Clear();
				responseHandlers.Clear();
				pingHandlers.Clear();
			}
		}
Example #3
0
		/// <summary>
		/// Reads line by line from the asterisk server, sets the protocol identifier as soon as it is
		/// received and dispatches the received events and responses via the associated dispatcher.
		/// </summary>
		/// <seealso cref="ManagerConnection.DispatchEvent(ManagerEvent)" />
		/// <seealso cref="ManagerConnection.DispatchResponse(Response.ManagerResponse)" />
		/// <seealso cref="ManagerConnection.setProtocolIdentifier(String)" />
		internal void  Run()
		{
			if (mrSocket == null)
				throw new SystemException("Unable to run: socket is null.");

			string line;

			while (true)
			{
				try
				{
					while (!die)
					{
						#region check line from *
						if (!is_logoff)
						{
							if (mrSocket != null && mrSocket.Initial)
							{
								Reinitialize();
							}
							else if (disconnect)
							{
								disconnect = false;
								mrConnector.DispatchEvent(new DisconnectEvent(mrConnector));
							}
						}
						if (lineQueue.Count == 0)
						{
                            if (lastPacketTime.AddMilliseconds(mrConnector.PingInterval) < DateTime.Now
                                && mrConnector.PingInterval > 0
                                && mrSocket != null
                                && !wait4identiier
                                && !is_logoff
                                )
                            {
                                if (pingHandler != null)
                                {
                                    if (pingHandler.Response == null)
                                    {
                                        // If one PingInterval from Ping without Pong then send Disconnect event
                                        mrConnector.RemoveResponseHandler(pingHandler);
                                        mrConnector.DispatchEvent(new DisconnectEvent(mrConnector));
                                    }
                                    pingHandler.Free();
                                    pingHandler = null;
								}
								else
								{
									// Send PING to *
									try
									{
										pingHandler = new ResponseHandler(new Action.PingAction(), null);
										mrConnector.SendAction(pingHandler.Action, pingHandler);
									}
									catch
									{
										disconnect = true;
										mrSocket = null;
									}
								}
								lastPacketTime = DateTime.Now;
							}
							Thread.Sleep(50);
							if (mrConnector.TraceCallerThread && mrConnector.CallerThread != null && mrConnector.CallerThread.ThreadState == ThreadState.Stopped)
							{
								die = true;
								break;
							}
							continue;
						}
						#endregion

						lastPacketTime = DateTime.Now;
						lock (((ICollection)lineQueue).SyncRoot)
							line = lineQueue.Dequeue().Trim();
#if LOGGER
						logger.Debug(line);
#endif
						#region processing Response: Follows
						if (processingCommandResult)
						{
							if (line == "--END COMMAND--")
							{
								Response.CommandResponse commandResponse = new Response.CommandResponse();
								Helper.SetAttributes(commandResponse, packet);
								commandResponse.Result = commandList;
								processingCommandResult = false;
								packet.Clear();
								mrConnector.DispatchResponse(commandResponse);
								continue;
							}
							else
							{
								string lineLower = line.ToLower(Helper.CultureInfo);
								if (lineLower.StartsWith("privilege: ")
									|| lineLower.StartsWith("actionid: ")
									|| lineLower.StartsWith("timestamp: ")
									|| lineLower.StartsWith("server: ")
									)
									Helper.AddKeyValue(packet, line);
								else
									commandList.Add(line);
							}
							continue;
						}
						#endregion

						#region collect key: value and ProtocolIdentifier
						if (!string.IsNullOrEmpty(line))
						{
							if (wait4identiier && line.StartsWith("Asterisk Call Manager"))
							{
								wait4identiier = false;
								ConnectEvent connectEvent = new ConnectEvent(mrConnector);
								connectEvent.ProtocolIdentifier = line;
								mrConnector.DispatchEvent(connectEvent);
								continue;
							}
							if (line.Trim().ToLower(Helper.CultureInfo) == "response: follows")
							{
								// Switch to wait "--END COMMAND--" mode
								processingCommandResult = true;
								packet.Clear();
								commandList.Clear();
								Helper.AddKeyValue(packet, line);
								continue;
							}
							Helper.AddKeyValue(packet, line);
							continue;
						}
						#endregion

						#region process events and responses

						if (packet.ContainsKey("event"))
							mrConnector.DispatchEvent(packet);

						else if (packet.ContainsKey("response"))
							mrConnector.DispatchResponse(packet);

						#endregion

						packet.Clear();
					}
					if(mrSocket != null)
						mrSocket.Close();
					break;
				}
#if LOGGER
				catch (Exception ex)
				{
					logger.Info("Exception : {0}", ex.Message);
#else
				catch
				{
#endif
				}

				if (die)
					break;

#if LOGGER
				logger.Info("No die, any error - send disconnect.");
#endif
				mrConnector.DispatchEvent(new DisconnectEvent(mrConnector));
			}
		}