Advertisement
Alior

Final call controller

Jun 11th, 2018
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.71 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System.Threading;
  5. using System.Net.Sockets;
  6. using System;
  7. using System.Net;
  8. using System.Diagnostics;
  9.  
  10. public class CallController : MonoBehaviour
  11. {
  12.     private static CallController controller = null;
  13.     public static CallController Instance
  14.     {
  15.         get
  16.         {
  17.             return controller;
  18.         }
  19.     }
  20.  
  21.     [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
  22.     private static void Init()
  23.     {
  24.         var go = new GameObject("Call controller");
  25.         DontDestroyOnLoad(go);
  26.  
  27.         controller = go.AddComponent<CallController>();
  28.     }
  29.  
  30.     private interface IOnCompleteCommandHandler
  31.     {
  32.         void OnComplete(CallController callController);
  33.     }
  34.  
  35.     private abstract class Command
  36.     {
  37.         public virtual float CommandTimeout
  38.         {
  39.             get
  40.             {
  41.                 return 20.0f;
  42.             }
  43.         }
  44.  
  45.         public abstract void Execute(CallController callController, Socket socket);
  46.     }
  47.  
  48.     private class CallCommand : Command, IOnCompleteCommandHandler
  49.     {
  50.         private readonly string number;
  51.  
  52.         public CallCommand(string number)
  53.         {
  54.             this.number = number;
  55.         }
  56.  
  57.         public override void Execute(CallController callController, Socket socket)
  58.         {
  59.             UnityEngine.Debug.Log("Executing call command to number: " + number);
  60.             socket.Send(System.Text.Encoding.ASCII.GetBytes(string.Format("call {0}", number)));
  61.  
  62.             callController.IsCalling = true;
  63.         }
  64.  
  65.         void IOnCompleteCommandHandler.OnComplete(CallController callController)
  66.         {
  67.             callController.IsCalling = false;
  68.         }
  69.     }
  70.  
  71.     private class EndCallCommand : Command, IOnCompleteCommandHandler
  72.     {
  73.         public override void Execute(CallController callController, Socket socket)
  74.         {
  75.             socket.Send(System.Text.Encoding.ASCII.GetBytes("raw_command AT+CHUP"));
  76.         }
  77.  
  78.         void IOnCompleteCommandHandler.OnComplete(CallController callController)
  79.         {
  80.             callController.IsCalling = false;
  81.         }
  82.     }
  83.  
  84.     Thread controlThread;
  85.  
  86.     private volatile bool isRunning = true;
  87.  
  88.     private object commandLocker = new object();
  89.     private Command command = null;
  90.  
  91.     private object ipLocker = new object();
  92.     private string ip = string.Empty;
  93.     public string Ip
  94.     {
  95.         get
  96.         {
  97.             lock (ipLocker)
  98.                 return ip;
  99.         }
  100.  
  101.         set
  102.         {
  103.             lock (ipLocker)
  104.                 ip = value;
  105.         }
  106.     }
  107.  
  108.  
  109.     private object isCallingLocker = new object();
  110.     private bool isCalling = false;
  111.     public bool IsCalling
  112.     {
  113.         get
  114.         {
  115.             lock (isCallingLocker)
  116.                 return isCalling;
  117.         }
  118.  
  119.         private set
  120.         {
  121.             lock (isCallingLocker)
  122.                 isCalling = value;
  123.         }
  124.     }
  125.  
  126.     private bool HasCommand
  127.     {
  128.         get
  129.         {
  130.             lock (commandLocker)
  131.                 return command != null;
  132.         }
  133.     }
  134.  
  135.     private void Start()
  136.     {
  137.         controlThread = new Thread(ControlThread);
  138.         controlThread.IsBackground = true;
  139.         controlThread.Start();
  140.     }
  141.  
  142.     private void AddCommand(Command command)
  143.     {
  144.         lock (commandLocker)
  145.         {
  146.             if (this.command != null)
  147.             {
  148.                 UnityEngine.Debug.Log("There is a command. You can't assign another one while this one is not finished");
  149.                 return;
  150.             }
  151.  
  152.             this.command = command;
  153.         }
  154.     }
  155.  
  156.     public void Call(string number)
  157.     {
  158.         if (IsCalling)
  159.         {
  160.             UnityEngine.Debug.LogError("Can't call. We are already calling!");
  161.             return;
  162.         }
  163.  
  164.         AddCommand(new CallCommand(number));
  165.     }
  166.  
  167.     public void EndCall()
  168.     {
  169.         if (!IsCalling)
  170.         {
  171.             UnityEngine.Debug.LogError("Can't stop calling. We don't calling now.");
  172.             return;
  173.         }
  174.  
  175.         AddCommand(new EndCallCommand());
  176.     }
  177.  
  178.     private void ControlThread()
  179.     {
  180.         byte[] buffer = new byte[65535];
  181.         while (isRunning)
  182.         {
  183.             Thread.Sleep(200);
  184.  
  185.             IPAddress ipAddress = default(IPAddress);
  186.             EndPoint endPoint = default(EndPoint);
  187.  
  188.             try
  189.             {
  190.                 ipAddress = IPAddress.Parse(Ip);
  191.                 endPoint = new IPEndPoint(ipAddress, 5551);
  192.             }
  193.             catch (System.Threading.ThreadAbortException abort)
  194.             {
  195.                 UnityEngine.Debug.Log("Exiting control thread");
  196.                 return;
  197.             }
  198.             catch (System.Exception ex)
  199.             {
  200.                 UnityEngine.Debug.LogException(ex);
  201.                 continue;
  202.             }
  203.  
  204.             Command commandToExecute = null;
  205.             lock (commandLocker)
  206.             {
  207.                 if (command == null)
  208.                     continue;
  209.  
  210.                 commandToExecute = command;
  211.                 command = null;
  212.             }
  213.  
  214.             try
  215.             {
  216.                 using (Socket socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
  217.                 {
  218.                     UnityEngine.Debug.Log("Executing command");
  219.  
  220.                     socket.Connect(endPoint);
  221.                     commandToExecute.Execute(this, socket);
  222.                     string receivedString = string.Empty;
  223.                     Stopwatch stopwatch = new Stopwatch();
  224.                     stopwatch.Start();
  225.                     do
  226.                     {
  227.                         if (socket.Available > 0)
  228.                         {
  229.                             int received = socket.Receive(buffer);
  230.                             if (received <= 0)
  231.                                 continue;
  232.  
  233.                             receivedString = System.Text.Encoding.UTF8.GetString(buffer, 0, received);
  234.  
  235.                             var callString = "calling";
  236.                             if (receivedString.StartsWith(callString))
  237.                             {
  238.                                 UnityEngine.Debug.Log("Reseting timeout. Got some result");
  239.                                 stopwatch.Reset();
  240.                                 stopwatch.Start();
  241.                             }
  242.  
  243.                             var finishString = "command finished";
  244.                             if (receivedString.StartsWith(finishString))
  245.                                 break;
  246.                         }
  247.  
  248.                         if (stopwatch.ElapsedMilliseconds > commandToExecute.CommandTimeout * 1000)
  249.                         {
  250.                             UnityEngine.Debug.LogError("Command has been timed out");
  251.                             break;
  252.                         }
  253.  
  254.                     } while (isRunning && !HasCommand);
  255.  
  256.                     if (commandToExecute is IOnCompleteCommandHandler)
  257.                         (commandToExecute as IOnCompleteCommandHandler).OnComplete(this);
  258.  
  259.                     UnityEngine.Debug.Log("Command execution has finished");
  260.                 }
  261.             }
  262.             catch (System.Threading.ThreadAbortException abort)
  263.             {
  264.                 UnityEngine.Debug.Log("Exiting control thread");
  265.                 return;
  266.             }
  267.             catch (System.Exception ex)
  268.             {
  269.                 UnityEngine.Debug.LogError("Error executing command");
  270.             }
  271.         }
  272.     }
  273.  
  274.     private void OnDestroy()
  275.     {
  276.         isRunning = false;
  277.         if (controlThread != null)
  278.             controlThread.Abort();
  279.     }
  280. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement