예제 #1
0
        public async void ListenerCallback(IAsyncResult result)
        {
            HttpListener listener = (HttpListener)result.AsyncState;

            if (!listener.IsListening)
            {
                string err_msg = "!listener.IsListening";
                Log.Debug(TAG, err_msg);
                logsDB.AddLogRow(LogStatusesEnum.Error, err_msg, TAG);
                return;
            }
            // Call EndGetContext to complete the asynchronous operation.
            HttpListenerContext context = listener.EndGetContext(result);
            HttpListenerRequest request = context.Request;
            string remote_ip_address    = request.RemoteEndPoint.Address.ToString();

            string s_request = $"ListenerCallback() - request: {request.Url} from > {remote_ip_address}";

            Log.Debug(TAG, s_request);
            logsDB.AddLogRow(LogStatusesEnum.Info, s_request, TAG);

            // Obtain a response object.
            HttpListenerResponse response = context.Response;

            Android.Net.Uri uri = Android.Net.Uri.Parse(request.Url.ToString());

            string pt    = uri.GetQueryParameter("pt");
            string dir   = uri.GetQueryParameter("dir");
            string mdid  = uri.GetQueryParameter("mdid");
            string v     = uri.GetQueryParameter("v");
            string value = uri.GetQueryParameter("value");
            string st    = uri.GetQueryParameter("st");
            string m     = uri.GetQueryParameter("m");
            string click = uri.GetQueryParameter("click");
            string cnt   = uri.GetQueryParameter("cnt");

            HardwareModel hardware;
            string        hw_name = string.Empty;

            lock (DatabaseContext.DbLocker)
            {
                using (DatabaseContext db = new DatabaseContext(gs.DatabasePathBase))
                {
                    hardware = db.Hardwares.FirstOrDefault(x => x.Address == remote_ip_address);
                }
            }

            hw_name = hardware?.Name ?? string.Empty;
            if (string.IsNullOrEmpty(hw_name))
            {
                hw_name = remote_ip_address;
            }
            else
            {
                hw_name += $" ({remote_ip_address})";
            }

            string bot_message = $"Сообщение от устройства \"{hw_name}\": {Environment.NewLine}";

            if (!string.IsNullOrWhiteSpace(pt))
            {
                if (Regex.IsMatch(pt, @"^\d+$"))
                {
                    PortModel portHardware = null;
                    int       pt_num_int   = -1;
                    pt_num_int = int.Parse(pt);
                    if (pt_num_int > -1 && hardware != null)
                    {
                        lock (DatabaseContext.DbLocker)
                        {
                            using (DatabaseContext db = new DatabaseContext(gs.DatabasePathBase))
                            {
                                portHardware = db.Ports.FirstOrDefault(x => x.HardwareId == hardware.Id && x.PortNumb == pt_num_int);
                            }
                        }
                        if (portHardware != null)
                        {
                            Log.Debug(TAG, "Поиск триггера");

                            List <ScriptModel> scripts_triggers = null;
                            lock (DatabaseContext.DbLocker)
                            {
                                using (DatabaseContext db = new DatabaseContext(gs.DatabasePathBase))
                                {
                                    scripts_triggers = db.Scripts.Where(x => x.TriggerPortId == portHardware.Id).Include(x => x.Commands).ToList();
                                }
                            }
                            if (scripts_triggers != null && scripts_triggers.Count > 0)
                            {
                                Log.Debug(TAG, $"Нaйдено триггеров: {scripts_triggers.Count}");
                                foreach (ScriptModel trigger_script in scripts_triggers)
                                {
                                    string url_request_port_state = $"http://{hardware.Address}/{hardware.Password}/?pt={pt}&cmd=get";
                                    Log.Debug(TAG, $"Зпрос состояния порта: {url_request_port_state}");

                                    HttpWebRequest request_port_state = new HttpWebRequest(new Uri(url_request_port_state))
                                    {
                                        Timeout = 5000
                                    };
                                    try
                                    {
                                        using (HttpWebResponse response_port_state = (HttpWebResponse)request_port_state.GetResponse())
                                        {
                                            if (response_port_state.StatusCode == HttpStatusCode.OK)
                                            {
                                                string responseFromServer = string.Empty;

                                                using (Stream dataStream = response_port_state.GetResponseStream())
                                                    using (StreamReader reader = new StreamReader(dataStream))
                                                    {
                                                        responseFromServer = reader.ReadToEnd();
                                                    }
                                                if (string.IsNullOrEmpty(responseFromServer))
                                                {
                                                    //"Пустой ответ устройства.";
                                                    continue;
                                                }
                                                else if (responseFromServer.ToLower() == "unauthorized")
                                                {
                                                    //"Пароль, указаный в настройкх устройства не подошёл.";
                                                    continue;
                                                }
                                                else
                                                {
                                                    Log.Debug(TAG, $"Cостояние порта: {responseFromServer}");
                                                    if ((trigger_script.TriggerPortState == true && !responseFromServer.ToLower().StartsWith("on/")) || (trigger_script.TriggerPortState == false && responseFromServer.ToLower().StartsWith("off/")))
                                                    {
                                                        continue;
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                //$"Ошибка выполнения запроса. StatusCode:\"{response.StatusCode}\"; StatusDescription:\"{response.StatusDescription}\"";
                                                continue;
                                            }
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        //$"Сбой обработки команды:{ex.Message}";
                                        continue;
                                    }


                                    TaskModel task;
                                    lock (DatabaseContext.DbLocker)
                                    {
                                        using (DatabaseContext db = new DatabaseContext(gs.DatabasePathBase))
                                        {
                                            task = new TaskModel()
                                            {
                                                Name = "http trigger",
                                                TaskInitiatorType = TaskInitiatorsTypes.Trigger,
                                                TaskInitiatorId   = hardware.Id,
                                                ScriptId          = trigger_script.Id
                                            };
                                            db.Tasks.Add(task);
                                            db.SaveChanges();
                                        }
                                    }

                                    BackgroundWorker bw = new BackgroundWorker();
                                    bw.DoWork             += new DoWorkEventHandler(aForegroundService.RunScriptAction);
                                    bw.ProgressChanged    += (object sender, ProgressChangedEventArgs e) => { };
                                    bw.RunWorkerCompleted += (object sender, RunWorkerCompletedEventArgs e) => { };
                                    bw.RunWorkerAsync(task);
                                }
                            }
                        }
                    }

                    if (!string.IsNullOrWhiteSpace(pt) && string.IsNullOrWhiteSpace(portHardware?.Name))
                    {
                        pt = $"Порт: P{pt}; ";
                    }
                    else
                    {
                        pt = $"Порт: \"{portHardware.Name}\" (P{pt}); ";
                    }
                }
                else
                {
                    pt = $"Порт: {pt}; ";
                }
                bot_message += $"{pt}";
            }

            if (!string.IsNullOrWhiteSpace(m))
            {
                m            = (m == "1" ? "Освобождние после длительного удержания" : $"Длительное удержание") + "; ";
                bot_message += $"{m}";
            }

            if (!string.IsNullOrWhiteSpace(click))
            {
                click        = (click == "1" ? "обычный клик" : "двойной клик") + "; ";
                bot_message += $"{click}";
            }

            if (!string.IsNullOrWhiteSpace(dir))
            {
                if (dir == "0")//падение значения
                {
                    dir = "Значение опустилось ниже порога; ";
                }
                else if (dir == "1")//повышение знчения
                {
                    dir = "Значение превышает пороговое; ";
                }
                else
                {
                    dir = $"ошибка определения вектора 'dir':{dir}; ";
                }
                bot_message += $"{dir}";
            }

            if (!string.IsNullOrWhiteSpace(mdid))
            {
                mdid         = $"mdid=\"{mdid}\"; ";
                bot_message += $"{mdid}";
            }

            if (!string.IsNullOrWhiteSpace(st))
            {
                st           = $"st=\"{st}\"; ";
                bot_message += $"{st}";
            }

            if (!string.IsNullOrWhiteSpace(v))
            {
                v            = $"v=\"{v}\"; ";
                bot_message += $"{v}";
            }

            if (!string.IsNullOrWhiteSpace(value))
            {
                value        = $"value=\"{value}\"; ";
                bot_message += $"{value}";
            }

            string token = Preferences.Get(Constants.TELEGRAM_TOKEN, string.Empty);

            if (!string.IsNullOrWhiteSpace(token))
            {
                TelegramClientCore telegramClient = new TelegramClientCore(token);
                if (telegramClient?.Me != null)
                {
                    List <UserModel> users;
                    lock (DatabaseContext.DbLocker)
                    {
                        using (DatabaseContext db = new DatabaseContext(gs.DatabasePathBase))
                        {
                            users = db.Users.Where(x => x.AlarmSubscriber).ToList();
                        }
                    }

                    List <TelegramUserModel> t_users;
                    foreach (UserModel user in users)
                    {
                        lock (DatabaseContext.DbLocker)
                        {
                            using (DatabaseContext db = new DatabaseContext(gs.DatabasePathBase))
                            {
                                t_users = db.TelegramUsers.Where(xx => xx.LinkedUserId == user.Id).ToList();
                            }
                        }
                        foreach (TelegramUserModel telegramUser in t_users)
                        {
                            await telegramClient.sendMessage(telegramUser.TelegramId.ToString(), bot_message.Trim());
                        }
                    }
                }
            }

            string log_msg = $"incoming http request (from > {remote_ip_address}): {request.Url.Query}";
            //log_msg = "telegramClient?.Me == null";
            //Log.Info(TAG, log_msg);
            //using (LogsContext log = new LogsContext())
            //{
            //    log.AddLogRow(LogStatusesEnum.Info, log_msg, TAG);
            //}

            // Construct a response.
            string responseString = "Hello world!";

            byte[] buffer = Encoding.UTF8.GetBytes(responseString);
            // Get a response stream and write the response to it.
            response.ContentLength64 = buffer.Length;
            System.IO.Stream output = response.OutputStream;
            await output.WriteAsync(buffer, 0, buffer.Length);

            // You must close the output stream.
            output.Close();
            result = httpServer.BeginGetContext(new AsyncCallback(ListenerCallback), httpServer);
        }
예제 #2
0
        /// <summary>
        /// Сканировать входящий Telegram.Update
        /// </summary>
        public void UpdateNew(Update u)
        {
            IncUpdate = u;
            UpdateNew();

            Log.WriteLine((IsAdminSender ? "Administrator" : "User") + FullNameSender, IsAdminSender ? LogStatusEnum.Notice : LogStatusEnum.Norma);

            if (ChatType == ChatTypes.Group || ChatType == ChatTypes.Supergroup)
            {
                Regex rex = new Regex(@"^/\w[\w\d_]+@" + telegram_client.Me.username + "$", RegexOptions.IgnoreCase);
                if (CompositionTypes.Exists(x => x == TelegramDataTypes.Text) && rex.IsMatch(IncUpdate.message.text))
                {
                    telegram_client.sendMessage(IncUpdate.message.chat.id.ToString(), "Для общения с ботом напишите ему напрямую @" + telegram_client.Me.username, null, false, false, IncUpdate.message.chat.id);
                    return;
                }
                if (ScanSpamMatches.Count > 0)
                {
                    NotifyAdmins(MatchesReport);

                    if (AutoDelete && !IsAdminSender && ScanSpamMatches.Exists(x => x.LevelMatch == LevelMatches.Block))
                    {
                        telegram_client.deleteMessage(u.message.chat.id.ToString(), u.message.message_id);
                    }
                }
            }

            if (!string.IsNullOrEmpty(WebhookAddress) && !string.IsNullOrEmpty(hmac_key) && !string.IsNullOrEmpty(hmac_secret))
            {
                string postData = glob_tools.SerialiseJSON(this);
                string responsebody;
                //
                HttpWebRequest request;
                Stream         requestStream;
                request             = (HttpWebRequest)WebRequest.Create(WebhookAddress);
                request.ContentType = "application/json";
                request.Method      = "POST";

                HmacHttpWebRequest hmacHttp = new HmacHttpWebRequest(hmac_key, hmac_secret);
                request = hmacHttp.SignRequest(request);

                requestStream = request.GetRequestStream();
                byte[] byteArray = Encoding.UTF8.GetBytes(postData);
                request.ContentLength = byteArray.Length;
                requestStream.Write(byteArray, 0, byteArray.Length);
                requestStream.Close();

                try
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        if (!hmacHttp.VerifyResponse(response))
                        {
                            Log.WriteLine("Ответ API Webhook не подписан или подписан не действительной поджписью", LogStatusEnum.Alarm);
                            return;
                        }
                        Log.WriteLine("HMAC API Webhook подпись проверена", LogStatusEnum.Happi);
                        using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8, true))
                        {
                            if (response.StatusCode == HttpStatusCode.OK)
                            {
                                responsebody = reader.ReadToEnd();
                                if (string.IsNullOrEmpty(responsebody))
                                {
                                    Log.WriteLine("API HMAC JSON - вернул пустой ответ", LogStatusEnum.Alarm);
                                }
                                else
                                {
                                    try
                                    {
                                        ResultHmacResponseClass resultHmac = (ResultHmacResponseClass)glob_tools.DeSerialiseJSON(typeof(ResultHmacResponseClass), responsebody);
                                        Log.Write("API HMAC JSON - прочитан ");
                                        Log.WriteLine(resultHmac.status.ToString("g"), resultHmac.status == StatusResult.Ok ? LogStatusEnum.Happi : LogStatusEnum.Alarm);
                                    }
                                    catch (Exception e)
                                    {
                                        Log.WriteLine("API HMAC JSON - ошибка. " + e.Message, LogStatusEnum.Alarm);
                                    }
                                }
                            }
                            else
                            {
                                Log.WriteLine("API HTTP-CODE: " + response.StatusCode.ToString("g") + ". HTTP-DESC: " + response.StatusDescription + ".", LogStatusEnum.Alarm);
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Log.WriteLine("API HMAC JSON - HTTP-ошибка. " + e.Message, LogStatusEnum.Alarm);
                }
            }
        }