Categorias
api hotspot html integra????o ip linux mikrotik rede ssl tcp windows

Adicionando uma p??gina de cadastro de usu??rios (Hotspot) em ASP.NET no Mikrotik

Cada projeto que pego, ?? uma aventura nova a ser encarada! Dessa vez me adentrei no universo de Linux, rede, SSH, infra e tudo o que ?? direito. Quem n??o conhece, a Mikrotik ?? uma empresa de grande refer??ncia no que tange em equipamentos para redes de computadores. Seu principal destaque ?? o RouterOS que ?? sistema operacional que torna o roteador um poderoso gerente de rede. Dentro do Mikrotik (irei me referenciar sempre dessa forma generalizando como um produto), h?? o HotSpot. Com ele pode-se gerenciar quem ir?? autenticar na rede para usar a internet (ou apenas a intranet), banda usada, taxa de transfer??ncia e outras funcionalidades por usu??rio ou de forma geral. Um exemplo de uso desse sistema ?? de quando voc?? vai a uma rede corporativa onde precisa autenticar-se para usar a internet… ?? isso!

Qual ?? o objetivo desse artigo ent??o? A princ??pio ?? apenas obter as p??ginas originais de hotspot do Mikrotik, colocar um redirecionador para uma p??gina externa, criar uma p??gina externa de cadastro de usu??rio (para que possa acessar a rede) e fazer funcionar. N??o ensinarei como configurar ou criar o hotspot. Pela net h?? v??rios tutoriais muito bons sobre o assunto e tamb??m n??o ?? de minha ??rea. Recomendo fortemente o f??rum da Under-Linux que l?? o pessoal manja muito no assunto.

Nesse artigo usei o Mikrotik MKBR100 que ?? bem f??cil de usar: basta plugar o cabo de rede da internet, do servidor e da energia. Pronto!

Para acessar seu SO, deve-se utilizar o Winbox como se fosse um daqueles players de m??quina virtual ou OpenSSH. Vamos l?? colocar a m??o na massa!

Conecte o cabo de rede de seu PC (ou servidor) na porta (interface) ether2 do Mikrotik. Agora conecte outro cabo na ether1 para os outros computadores da rede (ou roteador simples). Porqu?? na ether1? Estou considerando que o hotspot est?? configurado para monitorar essa interface enquanto a ether2 ser?? utilizado para que o servidor de comunique com o aparelho. Seria algo do tipo:

V?? em IP > Address no Mikrotik para que sejam configuradas as interfaces e sejam endere??ados conforme os exemplos abaixo:

  • ether1: 192.168.88.1
  • ether2: 192.168.88.2

Somente atrav??s de IP que ser?? poss??vel enviar os arquivos do hotspot. Se ficar conectando, via MAC, pelo Winbox, voc?? ter?? a mensagem de erro: “router has been disconnected” (logo, conecte-se usando a ether2 – 192.168.88.2). E outra coisa ??: se n??o seguir o esquema acima, outros erros voc?? ter??, como:

could not connect to … no response
could not connect to … connection refused

could not connect to … network is unreachable
could not fetch index from … not found

Tudo isso por causa de configura????o apenas! ?? bom deixar o IP do servidor fixo para que possa dar permiss??o de porta, firewall, etc. No caso deixei como 192.168.88.30 (que no caso era minha pr??pria m??quina). Uma dica: ??s vezes d?? um reboot no aparelho!

O pr??ximo passo ?? ativar a porta da API que o Mikrotik disp??e para integra????o com linguagens de programa????o. ?? atrav??s dela que iremos conectar e fazer a comunica????o. S?? que precisamos ativ??-la. V?? em IP > Services e ative a API na porta 8728.

Tamb??m libere, no Firewall, as portas para conex??o tanto do sistema quanto do Winbox (pelo IP), sen??o quando estiver acessando pela p??gina de cadastro, ir?? surgir o erro: “nenhuma conex??o p??de ser feita porque a m??quina de destino as recusou ativamente ..:8728.”.

Para permitir a navega????o e envio de informa????es, adicione as permiss??es no Walled Garden.

Vejam que at?? o momento tudo ?? configura????o e nada de programa????o. Continuemos…

Agora vamos em Files e selecione todos os arquivos da pasta hotspot, arraste para sua ??rea de trabalho que ser?? copiado. Para enviar fa??a o processo inverso… Se estiver acessando pelo IP vai dar certo, sen??o cair?? a conex??o (lembra que disse acima?).

Abra o HTML da p??gina login.html e acione um link para a p??gina de cadastro que ficar?? hospedada no servidor. Adicionei o link <a href=“http://192.168.88.30/mikrotik/cadastro.aspx”>cadastre-se</a> . Customize as demais p??ginas como desejar e as envie de volta. Praticamente terminamos de trabalhar no Mikrotik.

Agora vem o mais simples: criar a p??gina ASP.NET. Voc?? pode utilizar qualquer linguagem de programa????o que possa usar TCP na comunica????o e que a API suporte: PHP, Delphi, C, C++, C#, Flash, Ruby on Rails, Java, Python, VB.NET, etc.

Fa??a o download da classe MK, em C# (eles j?? disp??e de classes prontas para outras linguagens tamb??m), nesse link aqui e adicione no seu projeto. Agora crie um Web Form adicionando os campos que queira trabalhar. No meu exemplo, s?? quis login (username) e senha. Adicione um Button e um m??todo para executar o cadastro do usu??rio conforme exemplo abaixo:

             // Autentica????o
            MK mikrotik = new MK(“192.168.88.2”);
            if (!mikrotik.Login(“admin”, “”))
            {
                ScriptManager.RegisterStartupScript(Page, typeof(Page), “alert”, “alert(‘Houve um problema de comunica????o com o Hotspot! Por favor, tente mais tarde.’);”, true);
                mikrotik.Close();
                return;
            }

            // Requisi????o
            mikrotik.Send(“/ip/hotspot/user/add”);
            mikrotik.Send(“=name=” + nome.Text);
            mikrotik.Send(“=password=” + senha.Text, true);

            //Retorno
            string retorno = string.Empty;
            foreach (string h in mikrotik.Read())
            {
                if (retorno != string.Empty)
                    retorno += “, “;
                retorno += h;
            }

            // Fecha objeto
            mikrotik.Close();

            // Valida????o
            if (retorno.ToLower().Contains(“!done=ret=”))
                ScriptManager.RegisterStartupScript(Page, typeof(Page), “alert”, “alert(‘Cadastro realizado com sucesso!’); location.href=’http://192.168.88.1/login.html’;”, true);
            else if (retorno.ToLower().Contains(“message=failure: already have user with this name for this server”))
                ScriptManager.RegisterStartupScript(Page, typeof(Page), “alert”, “alert(‘J?? existe um usu??rio com esse nome!’);”, true);
            else
                ScriptManager.RegisterStartupScript(Page, typeof(Page), “alert”, “alert(‘Falha no cadastro: “ + retorno + “!’);”, true);

Voc?? poderia n??o s?? fazer o cadastro de usu??rio no hotspot como tamb??m executar qualquer comando (SSH) no Mikrotik. Lembrando que eu atropelei muita coisa a?? no que diz respeito a configura????o do dispositivo na qual disse logo no in??cio que n??o era minha finalidade. Voc??s observaram que a parte de programa????o ?? bem simples do que configura????o… e com certeza ??! Agora nunca ir?? sair de minha cabe??a a palavra Mikrotik Mikrotik Mikrotik Mikrotik Mikrotik … Por favor, qualquer erro ou informa????o adicional me avise!

[]’s

UPDATE: disponibilizei uma implementa????o no post http://thiagomarcal.blogspot.com.br/2016/09/implementacao-do-aspnet-c-com-o.html

Categorias
dicas ip microterminal rede tcp windows

Comunicando com microterminal em ASP.NET

Quem j?? foi em supermercado e nunca viu aquelas maquininhas que o operador fica digitando? Pois ??… estamos falando dela mesma. Parece ser f??cil seu uso, mas quem come??a a trabalhar com elas ?? de perder os cabelos.

Nesse artigo veremos como comunicar com um microterminal via TCP/IP e trocar informa????es (ida e volta). Para isso vamos utilizar o modelo da Gertec MT 720. Uma breve descri????o do aparelho e seu uso (retirado daqui):

“O MT 720 ?? um excelente microterminal que opera em rede Ethernet com protocolos TCP-IP. Seu teclado com 20 teclas program??veis pode ser utilizado com fun????es espec??ficas de atalhos para agilizar a opera????o.

As teclas re-legend??veis permitem a identifica????o da fun????o de cada tecla. O display com back light (iluminado), com 20 caracteres por 2 linhas, permite facilmente a visualiza????o da informa????o, principalmente em ambientes que possuem pouca ilumina????o, como bares noturnos, por exemplo.

Atrav??s de uma porta de teclado (AT/PS2) e mais 3 portas Seriais (RS-232) ?? poss??vel a conex??o de perif??ricos como: Leitor de C??digo de Barras, Display de Cliente, Balan??a, Impressora, etc.

O MT 720 ?? ideal para aplica????es de Cart??o de Consumo, solu????es para Bares, Lanchonetes, Restaurantes Self-Service, Livrarias, Papelarias, apontamento de produ????o em Ind??strias.”

Na pr??pria p??gina do dispositivo (citada acima) tem alguns downloads de arquivos, dentre eles alguns c??digos-fontes com exemplos de como fazer a comunica????o bem como realizar as opera????es pelas quais foi criado. Um por??m: s?? tem dispon??veis nas linguagens C++, Delphi e VB (n??o ?? VB.NET).

Da?? pensamos: “sem problemas! ?? s?? converter pra VB.NET a partir do VB”… Tamb??m pensei nisso e n??o consegui! Dando uma olhada de perto no c??digo-fonte d?? para saber que as proezas encontradas s??o s?? poss??veis por artif??cios que a linguagem oferece: por exemplo, ponteiros. Quem j?? programou em VB via a grande flexibilidade da linguagem de fazer tudo o que quer e do jeito que era mais conveniente. Maravilha! Pena que tenhamos que seguir certos padr??es. Fica a dica: se n??o quiser perder tempo, pegue logo o c??digo prontinho l?? na p??gina do fabricante (vem tamb??m no CD quando compra o aparelho) e utilize. De prefer??ncia use o Delphi e em seguida em VB. Se quiser aventurar vamos com C#…

Se escolheu C# siga lendo pois, em diante, veremos como fazer… Teremos os seguintes objetivos na implementa????o:

  1. Criar uma ??nica aplica????o que ir?? receber e enviar os dados;
  2. Exibir o que foi digitado tanto no microterminal quanto no monitor.

Instala????o

Leia o manual do usu??rio aqui. Em resumo: ligue o microterminal na rede el??trica e conecte na porta traseira um cabo RJ-45 no dispositivo e a rede. Em seguida configure, no microterminal, o IP do Servidor (no meu caso, considerei minha m??quina local com o IP 192.168.1.100, por exemplo). Demais configura????es a seu gosto…

Implementa????o

Criemos um Windows Form. Coloquei alguns controles para embelezar a aplica????o…

O mais importante ?? adicionar um objeto Timer. Os demais coloquei para gerar a aplica????o final (que ficar?? no tray – perto do rel??gio – e outras coisas fru-frus). Configure seu Timer com Interval de 50. Pegue a DLL pmtg.dll e copie para sua aplica????o. Eu disse copie! Voc?? n??o conseguir?? aplicar Reference sobre ela. Clique com o bot??o direito sobre a DLL e escolha Properties. Em Copy to Output Directory coloque Copy Always.

Agora vamos ao c??digo! Clique sobre o WinForm e escolha View Code. Cole os c??digos abaixo para que possamos us??-las no form:

        // VARI??VEIS
        IntPtr v_Hwnd;
        int statusCard;
        int statusSerial;
        int MsgReceiveData = 1;
        string[] dados = new string[255];


        // INICIALIZA????O DE FUN????ES EXTERNAS
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int mt_startserver(IntPtr mywhnd, int conecmsg, int commumsg);
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern void mt_finishserver();
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int mt_getkey(int id, StringBuilder str);
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int mt_backspace(int id);
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int mt_dispstr(int id, string str);
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int mt_dispch(int id, char ch);
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int mt_dispclrln(int id, int lin);
        [DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]]
        public static extern int mt_gotoxy(int id, int lin, int col);

Em seguida adicionamos as duas fun????es primordiais: in??cio (quando carregar o formul??rio) e t??rmino (quando fechar o formul??rio):

        private void MicroTerminal_Load(object sender, EventArgs e)
        {
            v_Hwnd = this.Handle;
            statusCard = 0;
            statusSerial = 0;
            if (mt_startserver(v_Hwnd, 0, MsgReceiveData) == 1)
            {
                temporizadorLista.Enabled = true;
            }
            else
                MessageBox.Show(“N??o foi poss??vel carregar os m??dulos de conex??o ?? leitora!”);
        }

        private void MicroTerminal_FormClosed(object sender, FormClosedEventArgs e)
        {
            temporizadorLista.Enabled = false;
            mt_finishserver();
        }

Lembrando que esses eventos devem estar configurados (n??o ?? apenas copiar e colar o c??digo, lembra? deve-se indicar l?? em Events do Form). Com isso, ao fazer o primeiro teste, sua aplica????o j?? estar?? recebendo dados do microterminal. Em seguida devemos adicionar um evento Tick ao Timer. Ou seja, a cada 50 milisegundos (lembra que colocamos com esse valor) ir?? ser executado um determinado m??todo.

Antes disso vamos criar um m??todo que ir?? limpar a tela do microterminal e reiniciar os dados de entrada:

                 private void ReiniciaEntrada(int i)
        {
            // Limpa as duas linhas e o que foi armazenado
            dados[i] = “”;
            mt_dispclrln(i, 1);
            mt_dispclrln(i, 2);
            // Coloca o cursor na primeira linha e prepara o display
            mt_gotoxy(i, 1, 0);
            mt_dispstr(i, “Numero: “);
            mt_gotoxy(i, 2, 0);
        }

Enfim adicionamos o c??digo que ir?? ler temporariamente cada leitora conectada ?? rede e coletar/processar os dados de acordo com o que desejar. No meu caso deixei o seguinte:

        private void temporizadorLista_Tick(object sender, EventArgs e)
        {
            StringBuilder rntStr = new StringBuilder();
            int i = 0;
            // Loop em toda faixa de Ips ??teis: cada leitora conectada na rede
            while (i < 255)
            {
                // Captura algo do teclado
                if (mt_getkey(i, rntStr) == 1)
                {
                    string chrAsHex = ((int)rntStr[0]).ToString(“x”);
                    // Entrada do display caso seja um n??mero
                    if ((chrAsHex == “3030”) || (chrAsHex == “30”) || (chrAsHex == “31”) || (chrAsHex == “32”) || (chrAsHex == “33”) || (chrAsHex == “34”) || (chrAsHex == “35”) || (chrAsHex == “36”) || (chrAsHex == “37”) || (chrAsHex == “38”) || (chrAsHex == “39”))
                    {
                        if (dados[i].Length >= 20)
                            dados[i] = dados[i].Substring(0, 19) + rntStr[0];
                        else
                            dados[i] += rntStr[0];
                        mt_dispch(i, rntStr[0]);
                    }
                    // Se for um ENTER, d?? a entrada na tela para mostrar
                    else if (chrAsHex == “d”)
                    {
                        // Captura e trata a entrada
                        if (dados[i] != “”)
                        {
                            // Faz o processamento do que desejar em dados[i]
                        }
                        // Limpa tela
                        ReiniciaEntrada(i);
                    }
                    // Se for um ESC, apaga tudo
                    else if (chrAsHex == “1b”)
                    {
                        // Limpa tela
                        ReiniciaEntrada(i);
                    }
                    // Se for backspace apaga ??ltimo caractere do display
                    else if (chrAsHex == “8”)
                    {
                        if (dados[i].Length > 0)
                            dados[i] = dados[i].Substring(0, dados[i].Length – 1);
                        mt_backspace(i);
                    }
                    // Se apertar * toca o som
                    else if (chrAsHex == “2a”)
                    {
                        // Toca um sonzinho… depois publico o c??digo de tocar som!
                    }
                }
                i++;
            }
        }

Feito! Rode sua aplica????o e digite algo no teclado do microterminal e ver?? que o que est?? sendo digitado est?? indo tanto para a aplica????o quanto para o display (no microterminal). A sa??da seria algo do tipo:

Se precisar de sa??da na tela crie um outro WinForm que ocupe toda tela (sua) e captura o que est?? no display do microterminal. Assim ?? mais f??cil! Ou fa??a do jeito que sua imagina????o mandar! O mais dif??cil j?? passou…

Para quem quiser capturar os IPs de cada microterminal, utilize os m??todos:

[DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern TTABSOCK mt_connectlist();

ou

[DllImport(“pmtg.dll”, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern StringBuilder mt_ipfromid(int id);

Nessas fun????es tem algumas particularidades muito chatinhas de se trabalhar (veja no manual das fun????es) por isso deixei de lado. Principalmente a classe:

    [StructLayout(LayoutKind.Sequential)]
    public struct TTABSOCK
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 255)]
        public UInt32[] TSOCK;
    }

Quem quiser se aventurar nela, fica a?? a dica. Esse artigo merecia at?? uma v??deo-aula, mas a pregui??a ??s vezes ?? muito forte! ?? at?? legalzinho ter esses desafios, mas ??s vezes se torna muito chato quando n??o consegue. Enfim, quanto menos se estressar, melhor! Ent??o tente usar as implementa????es que j?? a Gertec j?? disponibilizou, caso n??o queira aventurar, a menos que precise de algo mais espec??fico.
Falar que nem Marcoratti: “eu sei, ?? apenas ASP.NET, mas eu gosto!”

Categorias
dicas dll google ip salvador

Localiza????o de Usu??rio: Obter Cidade e Estado pelo IP em ASP.NET

A um certo tempo atr??s isso era um pouco complicado de ser feito ou fic??vamos dependentes (muito) de ferramentas de terceiros. Hoje, claramente, posso afirmar que temos mais flexibilidade por??m continuamos atrelados. Mas n??o seja por isso! A Google disponibilizou uma API inovadora que nos ajuda nesse caso e em muitos outros (relativo ao GoogleMaps). O GoogleMaps.Subgurim.NET ?? um avan??ado controle do GoogleMaps para o ASP.NET e permite uma gama de manipula????es sobre suas funcionalidades e a que iremos demonstrar aqui ?? a de obter informa????es do usu??rio pelo IP (no site deles pode encontrar bem como c??digos avan??ados e demais exemplos). Em contrapartida, ?? preciso de um arquivo extra contendo faixas de IP distribu??das pelo mundo. Ent??o a MaxMind disponibilizou tamb??m um arquivo bin??rio contendo essas informa????es gratuitamente. Voc?? pode obter o arquivo aqui ou aqui (a diferen??a ?? que um ?? o link direto e o outro ?? a p??gina geral que pode-se obter em outros formatos). Esse arquivo ?? mensalmente atualizando inserindo novas faixas, logo, deixo o dica para dar sempre uma atualizada quando poss??vel (com isso aumenta mais a precis??o mas hoje, com esse arquivo, j?? realiza uma boa cobertura).
Para in??cio dos trabalhos, baixe o componente GoogleMaps.Subgurim.NET e o arquivo de faixas GeoLiteCity.dat. Crie um novo Web Site. Adicione a GMaps.dll na pasta Bin do projeto e copie o GeoLiteCity.dat tamb??m (coloque em outra pasta afim de organiz??-los – no meu caso coloquei em uma pasta chamada Data). Agora escreva o seguinte c??digo abaixo:

using Subgurim.Controles;

private void ObtemInfoUser()
{
    string database = Server.MapPath(“~/Data/GeoLiteCity.dat”);
    LookupService servico = new LookupService(database);
    Location localizacao = servico.getLocation(Request.ServerVariables[“REMOTE_ADDR”]);
    if (localizacao != null)
    {
        Response.Write(“Cidade: “ + localizacao.city + “<br />”);
        Response.Write(“Pa??s: “ + localizacao.countryName + “<br />”);
        Response.Write(“C??digo do Pa??s: “ + localizacao.countryCode + “<br />”);
        Response.Write(“Regi??o: “ + localizacao.region + “<br />”);
        Response.Write(“C??digo da ??rea: “ + localizacao.area_code + “<br />”);
        Response.Write(“Latitude: “ + localizacao.latitude + “<br />”);
        Response.Write(“Longitudade: “ + localizacao.longitude);
    }
}
 
Voc?? deve obter a sa??da algo do tipo:
 
Cidade: Salvador
Pa??s: Brazil
C??digo do Pa??s: BR
Regi??o: 5
C??digo da ??rea: 0
Latitude: -12,7636
Longitude: -15,2821
 
* Obs: a latitude e longitude s??o dados fict??cios que eu coloquei 😉
 
Se voc?? estiver testando localmente, n??o ter?? resultado pois o Request.ServerVariables[“REMOTE_ADDR”] ir?? trazer o valor 127.0.0.1. Para saber seu IP externo acesse o MeuIp e substitua-o para visualizar os valores e valid??-los. Em breve estarei escrevendo outros artigos mostrando como aproveitar bem a API do GoogleMaps bem como demais funcionalidades. At?? mais!

UPDATE: Ap??s ler, vejam aqui sobre o pl??gio que fizeram com meu artigo e depois acusaram que eu que copiei. Quem l?? o blog sabe como eu escrevo e como expresso minhas id??ias…