viernes, 2 de junio de 2017

Enviar datos desde AJAX a PHP empleando una tabla dinamica dentro del mismo archivo





La verdad es que lo siguiente será un ejemplo muy básico, pero sé que puede ser de mucha utilidad para quienes estén buscando una información similar. En mi caso particular, hace un par de años estaba desarrollando una aplicación web, y dentro del panel de control necesitaba generar una tabla que pudiese almacenar datos en tiempo real de consultas a la base de datos. Hasta acá suena bastante sencillo, pero nunca me había tocado hacer algo parecido, y si bien manejaba a la perfección PHP, este no servia para lo que quería, ciertamente podía generar una tabla con una consulta en tiempo real, pero el documento se ejecutaba cada vez que llamaba a la función y no era la interacción que necesitaba para la experiencia del usuario.

Luego de mucho investigar descubrí las bondades de AJAX y pude solucionar el requerimiento. Pero como a muchos, me tocó investigar por varios días y hacer muchas funciones de prueba. Para poder comprender todo lo que puedes hacer con el AJAX dejaré el siguiente diagrama: 



Diagrama explicativo de como funciona AJAX

La cosa es que la tecnología es bastante sencilla de implementar leyendo la respectiva documentación, sin embargo hay que entender como funciona: Ya que hablamos de Javascript, se ejecuta del lado del cliente, ergo no estás realizando ninguna operación todavía realmente, simplemente estás manipulando datos de algún input o tabla, pero hasta no pasarlos a un lenguaje que realmente trabaje del lado del servidor web, no estás haciendo operaciones. He allí lo que nos reúne el día de hoy, un ejemplo practico del paso de datos de un formulario bajo la lógica

 HTML --> AJAX --> PHP 

Inicialmente vamos a crear el Formulario en HTML:

 <form method="post" id="testform" onsubmit="return false;">
<div class="input_form">
<select name ="Cliente" id ="Cliente" style="width:300px;border:1px solid #04467E;background-color:#FFFFFF;color:#2D4167;font-size:18px" onchange="this.style.width=500">
<option>Seleccionar cliente</option>
<?php echo $combobit; ?>
</select> 
  

  <br>
  <select name= "Producto" id="Producto" method="post" style="width:300px;border:1px solid #04467E;background-color:#FFFFFF;color:#2D4167;font-size:18px" onchange="this.style.width=500">
  <option>Producto</option>
  <?php echo $combobitt; ?>
  </select>    
  <input type="number" name="Cantidad" id="Cantidad" value="cantidad"  min="1" max="9999"  required > 
  </div><br>
   <br>
  <center><button id="bt_add" class="btn btn-default">Agregar</button></center> 
   <br>
   <br>
  
   </form>
   


  

  
  <table id="tabla" class="table table-bordered">
  <thead>
   <tr>
    <td>Nº</td>
    <td>Producto</td>
    <td>Cantidad</td>
   </tr>
  </thead>
 </table>
  
    <button id="bt_proce"  type="submit" name="submit" class="btn btn-default">Procesar</button>
    <button id="bt_del" class="btn btn-default">Eliminar</button>
    <button id="bt_delall" class="btn btn-default">Eliminar todo</button>


<p id="result"></p>
      
      
El Javascript y el AJAX:
<script>
 $(document).ready(function(){
  $('#bt_add').click(function(){
   agregar();
  });
  $('#bt_del').click(function(){
   eliminar(id_fila_selected);
  });
  $('#bt_delall').click(function(){
   eliminarTodasFilas();
  });
  $('#bt_proce').click(function(){
   procesar();
  });

 });
 
 var cont=0;
 var id_fila_selected=[];
 function agregar(){
  var producto = document.getElementById("Producto").value;
 var cantidad = document.getElementById("Cantidad").value;
  cont++;
 if (cont > 10){
  alert("Máximo 10 Renglones por factura");
 }else {
  var fila='<tr class="selected" id="fila'+cont+'" onclick="seleccionar(this.id);"><td>'+cont+'</td><td>'+producto+'</td><td>'+cantidad+'</td></tr>';
  $('#tabla').append(fila);
  reordenar();
 }}

 function seleccionar(id_fila){
  if($('#'+id_fila).hasClass('seleccionada')){
   $('#'+id_fila).removeClass('seleccionada');
  }
  else{
   $('#'+id_fila).addClass('seleccionada');
  }
  //2702id_fila_selected=id_fila;
  id_fila_selected.push(id_fila);
 }

 function eliminar(id_fila){
  /*$('#'+id_fila).remove();
  reordenar();*/
  for(var i=0; i<id_fila.length; i++){
   $('#'+id_fila[i]).remove();
  }
  reordenar();
 }

 function reordenar(){
  var num=1;
  $('#tabla tbody tr').each(function(){
   $(this).find('td').eq(0).text(num);
   num++;
  });
 }
 function eliminarTodasFilas(){
$('#tabla tbody tr').each(function(){
   $(this).remove();
  });

 }
 
  function procesar(){
  var myTableArray = [];
  $('#tabla tbody tr').each(function(){
  var arrayOfThisRow = [];
  var tableData = $(this).find('td');
   if (tableData.length > 0) {
   tableData.each(function() { arrayOfThisRow.push($(this).text()); });
   myTableArray.push(arrayOfThisRow);
  
        //JSON para envio
     var arreglo = myTableArray;
              var select = document.getElementById('Cliente');
              var empresa = select.value;
    // var dataString='arreglo='+arreglo;
     var dataString= 'arreglo='+arreglo;
     //var datadata= 'empresa'+empresa;
     

     
      //   var yourData  ='myTableArray'+myTableArray;
             
   
     
   }
     $.ajax({
              type:"POST",
     url: "hi.php",
        data: {dataString:dataString,empresa:empresa},
     cache: false,       
                 success: function(html) {
      $('#result').html(html);
      
                 
                    
                   // $('#result').html(data); // here html()

                 
                   
                  }                 
      //  alert(data);
                   // $('#testform')[0].reset();//reset the form
                   // $('#result').html(data); // here html()
                    //alert('Submitted');

             });
  
  });
  
 //  alert(myTableArray);   
  
  
  
 }


Como podemos notar, acá se encuentra el Javascript de la tabla dinámica y el AJAX que envía al archivo PHP de nombre "hi.php" 



 Y finalmente, el documento PHP que recibe los datos e imprime los resultados en el DIV "resultado":


 <?php 
$myString = $_POST['dataString']; 
$CLIENTE = $_POST['empresa']; 

print_r($myString);
echo ($CLIENTE);
?>


Y listo, ya podemos trabajar diatónicamente con una tabla y enviar el arreglo por AJAX a PHP y realizar operaciones con esas variables. 

Ciertamente mis ejemplos son bastante directos, pero están pensados en individuos con un nivel de conocimientos sobre la media en el área de programación. De cualquier forma, como les digo siempre. Puedo solventar cualquier duda en la caja de comentarios.


lunes, 6 de febrero de 2017

Arduino + Ethernet Shield: CSS Responsive control Web server

¿Todos queremos automatizar un proceso cierto? Todos buscamos la forma de mejorar nuestra calidad de vida empleando la tecnología. Pero en muchas ocasiones los precios van más allá de nuestro presupuesto, y allí es donde entra nuestro amigo Arduino. 

Somos inteligentes, sabemos programar y somos frikis .Partiendo de estas premisas y debido a que llegaste a mi sitio web, es muy probable que tengas un Arduino y que estés buscando la forma de sacarle provecho. Todos hicimos búsquedas similares, en mi caso el primer proyecto que me interesó fue el de un servidor web de domotica para controlar diferentes puntos del hogar. El único problema fue que cada proyecto ejemplo que encontraba era más feo que el anterior. 

Debido a la memoria reducida de nuestros Arduinos, estos servidores generalmente emplean únicamente HTML plano, dando un acabado muy Old School a los servidores; por ello me pregunté: ¿Por qué no hago entonces un servidor web estéticamente agradable y funcional? Y Aquí es donde empieza nuestro post actual. 


¿Qué necesitamos para el prototipo? 

  • Arduino UNO
  • Ethernet shield
  • Un protoboard
  • Cable para el proto
  • 4 LEDs y resistencias de 220Ohm
  • Arduino IDE
  • Router 



Explicación del proyecto

El Arduino será configurado con una dirección IP dentro de nuestra LAN, por ello será un host más. Adicionalmente, será programado para cargar vía HTTP una interfaz web atractiva al usuario mediante la cual podrá controlar diferentes funciones de su hogar (Luces, aire etc) en nuestro caso, ya que es un prototipo trabajaremos con encendido de LED. La interfaz será accesible desde cualquier tipo de dispositivo (responsive) y podrán ejecutarse ordenes dentro y fuera de la red local. 

¿Qué tal suena esto? Que vayas saliendo del trabajo o de la universidad, saques tu teléfono y mientras vas en camino enciendes tu aire ¿Atractivo no?


Bien, empecemos. 

Código del Arduino:




#include <SPI.h>
#include <Ethernet.h>


//Servo microservo; 
//int pos = 0; 
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };   //Direccion Fisica MAC
byte ip[] = { 192, 168, 1, 50 };                       // IP Local que usted debe configurar 
byte gateway[] = { 192, 168, 1, 254 };                   // Puerta de enlace
byte subnet[] = { 255, 255, 255, 0 };                  //Mascara de Sub Red
EthernetServer server(80);                             //Se usa el puerto 80 del servidor     
String readString;

void setup() {

  Serial.begin(9600);  // Inicializa el puerto serial 
   while (!Serial) {   // Espera a que el puerto serial sea conectado, Solo necesario para el Leonardo
    ; 
  }
  pinMode(2,OUTPUT);        // Se configura como salidas los puertos del 2 al 6
  pinMode(3,OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5,OUTPUT);
//  pinMode(6,OUTPUT);
//  microservo.attach(7);  // Se configura como Servo el Puerto 7
 
  Ethernet.begin(mac, ip, gateway, subnet); // Inicializa la conexion Ethernet y el servidor
  server.begin();
  Serial.print("El Servidor es: ");
  Serial.println(Ethernet.localIP());    // Imprime la direccion IP Local
}



void loop() {
  // Crea una conexion Cliente
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {   
      if (client.available()) {
        char c = client.read();
     
        //Lee caracter por caracter HTTP
        if (readString.length() < 100) {
          //Almacena los caracteres a un String
          readString += c;
          
         }

         // si el requerimiento HTTP fue finalizado
         if (c == 'n') {          
           Serial.println(readString); //Imprime en el monitor serial
     
          
          client.println("<html><head>");  
          //client.println("<meta http-equiv='content-type' content='text/html; charset=utf-8' />");

         
         // client.println("<script src='http://domoticaobertonica.000webhostapp.com/js/jquery.min.js'></script>");
          client.println("<script src='http://domoticaobertonica.000webhostapp.com/js/config.js'></script>");  
          client.println("<script src='http://domoticaobertonica.000webhostapp.com/js/skel.min.js'></script>"); // ESTE ES EL HOMBRE QUE ACTIVA EL TAMAÑO CORRECTO MOVIL
          client.println("<script src='https://use.fontawesome.com/d6622199c5.js'></script>");
         client.println("<link rel='stylesheet' href='http://domoticaobertonica.000webhostapp.com/CSS/skel-noscript.css' />");  
          client.println("<link rel='stylesheet'  href='http://domoticaobertonica.000webhostapp.com/CSS/style.css' />");
          client.println("<link rel='stylesheet' href='http://domoticaobertonica.000webhostapp.com/CSS/style-mobile.css' /></head><body><br/>");  
          client.println("<div class="container"><div class="row">");

          //cuadro 1
          client.println("<div class="4u"><section class="box box-style1"><span class="icon featured-icon icon-lightbulb"></span><h3>Luz del cuarto Principal</h3>");  
          client.println("<p><br><a href="/?B1"" class="button button-small">Encender rojo</a></span>");
          client.println("<p><br><a href="/?B2"" class="button button-small">Apagar Rojo</a></span>"); 
          client.println("<p><br><a href="/?B3"" class="button button-small">Encender Azul</a></span>"); 
          client.println("<p><br><a href="/?B4"" class="button button-small">Apagar Azul</a></span>"); 
          client.println("<p><br><a href="/?B5"" class="button button-small">Navidad</a></span>");
          client.println(" <p><a href="/?B6"" class="button button-small">Apagar Todos</a></span></p></section></div>");         
          client.println("</div></div></article></div></body></html>");
   
           delay(1);
           //detiene el cliente servidor
           client.stop();
           
           //control del arduino si un boton es presionado
                   
           if (readString.indexOf("?B1") >0){
               digitalWrite(2, HIGH);
           }
           if (readString.indexOf("?B2") >0){
               digitalWrite(2, LOW);
           }
           
           if (readString.indexOf("?B3") >0){
               digitalWrite(3, HIGH);
           }
           if (readString.indexOf("?B4") >0){
               digitalWrite(3, LOW);
           }
           
           
          

            if (readString.indexOf("?B5") >0){

               digitalWrite(2, HIGH);           
                 delay(1000); 
                 digitalWrite(3, HIGH);           
                 delay(1000); 
                 digitalWrite(4, HIGH);           
                 delay(1000); 
                 digitalWrite(5, HIGH);           
                 
           
           }       
        
           if (readString.indexOf("?B6") >0){
               digitalWrite(2, LOW);
               digitalWrite(3, LOW);
               digitalWrite(4, LOW);
               digitalWrite(5, LOW);
           }


           
           
          
          
            // Limpia el String(Cadena de Caracteres para una nueva lectura
            readString="";  
           
         }
       }
    }
}
}

Les recomiendo que utilicen el código a manera de referencia, si lo quieren emplear descarguen el original ya que es probable que algún fragmento de este haya sido modificado por Blogger. 



Recuerda que la configuración de red debe ser modificada en el código, empleando el segmento de red adecuado a tu LAN. Y también es importante que noten, que estoy haciendo referencias a ficheros CDN de JQUERY y varias hojas de estilo. Todas están hospedadas en servidores personales, por ello es probable que en algún punto estén caídas. Por ello también dejo el pack con los estilos y el JQUERY para que lo puedas hospedar en tu servidor y las referencias las puedas modificar.



¿Todo listo?

Ciertamente lo está el resultado es el siguiente: 




Sin embargo, tener acceso fuera de la LAN, necesitas hacer un foward del puerto 80 (en caso que uses el http por defecto) a la IP local del Arduino. Cosa que puedas entrar desde un navegador externo ingresando la IP publica y el router automáticamente haga el request al arduino. Tambien puede resultar practico configurar un DNS dinámico en red, de manera que sea un poco más cómodo el acceso mediante un nombre fácil de recordar y no una IP.

El esquema es el siguiente: 




Les dejo un vídeo demostrando la funcionalidad y como siempre, cualquier duda la pueden dejar en los comentarios.


 

Arduino + Ethernet Shield + Android = Home Assistant barato



Una casa automatizada y un asistente: Sueño de muchos y privilegio de unos pocos que pueden costearlo ¿Cierto? Bueno, en este articulo voy a refutar ese paradigma para demostrarte que con un poco de ingenio y conocimiento puedes tener una casa inteligente sin invertir más de 100$.

¿Qué necesitamos para el prototipo? 
  • Arduino UNO
  • Ethernet shield
  • Un protoboard
  • Cable para el proto
  • 2 LED y resistencias de 220Ohm
  • Arduino IDE
  • Android Studio (Para desarrollar la aplicación)




Explicación del proyecto: 

En síntesis el proyecto tiene como objetivo el desarrollo de un asistente que pueda ejecutar acciones dentro del hogar (como encender o apagar luces) interpretanto instrucciones por voz del usuario mediante una aplicación para dispositivos inteligentes.

En términos generales, se deben hacer dos cosas: Programar el arduino dentro de la red para que interprete y ejecute ordenes especificas, y realizar una aplicación capaz de interpretar comandos de voz (como "enciende la tv") y enviar las ordenes al arduino (todo bajo TCP/IP).

La aplicación interpreta y envía las ordenes, el arduino las recibe y las ejecuta, un esquema bastante fácil de entender ¿cierto? Manos a la obra.


Programando el Arduino: 

El código para el arduino como mencioné, debe tener asignada una dirección IP dentro del segmento de red del dispositivo Android que tendrá la aplicación que envía los comandos, esto es muy importante, de lo contrario no habrá comunicación. 

En el sketch estoy trabajando los pin del 1 al 5, para trabajar con 5 dispositivos diferentes. 



#include <SPI.h>
#include <Ethernet.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};

//la ip de tu arduino
IPAddress ip(192, 168, 1, 177);

// puerto web
EthernetServer server(80);

void setup() {
  pinMode(2,OUTPUT);        
  pinMode(3,OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5,OUTPUT);
  Serial.begin(9600);

  // Inicia el servidor web
  Ethernet.begin(mac, ip);
  server.begin();

}

void loop() {
  // Verifica si hay un cliente conectado
  EthernetClient client = server.available();
  
  if (client) { // si hay un cliente
    boolean currentLineIsBlank = true;
    String buffer = ""; // un buffer para el GET request
    
    while (client.connected()) {

      if (client.available()) {
        char c = client.read();// Lee los datos del cliente
        buffer += c; // Almacena los datos en el buffer
        
        if (c == '\n' && currentLineIsBlank) 
          // Inicia el request http
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");
          client.println(); // Blank line ==> end response
          break;
        }
        if (c == '\n') { // if New line
          currentLineIsBlank = true;
          buffer = "";  // Clear buffer
        } else if (c == '\r') { // If cariage return...
          //Read in the buffer if there was send "GET /?message=..."
          if(buffer.indexOf("GET /?message=")>=0) {
            // Read the message you said and see if it is a command
            if(buffer.indexOf("rory prende el aire")>=0) {
              digitalWrite(2, HIGH);
            }
            if(buffer.indexOf("rory prende la luz")>=0) {
              digitalWrite(3, HIGH);
            }   
            if(buffer.indexOf("rory apaga el aire")>=0) {
              digitalWrite(2, LOW);
            }
            if(buffer.indexOf("rory apaga la luz")>=0) {
              digitalWrite(3, LOW);
            }
          }
        } else {
          currentLineIsBlank = false;
        }
      }
    }
    delay(1);
    client.stop();
  }
}

NOTA: Se debe realizar un include a <SPI.h> <Ethernet.h>


Programando la APK

Para este punto necesitas desarrollar la aplicación que funcione como puente de comunicación entre tu teléfono y el Arduino. Es importante que si nunca has trabajado con Android estudio sepas, que lo fundamental que trabajaremos acá son 3 archivos: El Layout, el método principal y el XML de la permisología de la aplicación. 

Como interfaz únicamente utilicé un botón grande que activa la función para que el teléfono escuche tus instrucciones. 







Acá dejo el código del LAYOUT

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
    android:orientation="horizontal">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical">

        <ImageButton
            android:layout_width="200dp"
            android:layout_height="200dp"
            android:id="@+id/btn_speak"
            android:layout_gravity="center_horizontal"
            android:src="@drawable/abc_ic_voice_search_api_mtrl_alpha" ></ImageButton>

    </LinearLayout>

</LinearLayout>

Programando la clase mainactivity 

En esta fase se necesitan varias cosas, inicialmente se requiere el SpeechRecognizer y un tag para el debug: 


private SpeechRecognizer sr;
private static final String TAG = "MainActivity";
Ahora, en la función Oncreate necesitamos programarle la funcionalidad al boton que creamos en el Layout del paso anterior: 


ImageButton speakButton = (ImageButton) findViewById(R.id.btn_speak);
speakButton.setOnClickListener(this);
sr = SpeechRecognizer.createSpeechRecognizer(this);
sr.setRecognitionListener(new listener());

Ahora debemos crear la clase para el reconocimiento de voz: 


class listener implements RecognitionListener
{
    public void onReadyForSpeech(Bundle params)
    {}
    public void onBeginningOfSpeech()
    {}
    public void onRmsChanged(float rmsdB)
    {}
    public void onBufferReceived(byte[] buffer)
    {}
    public void onEndOfSpeech()
    {}
    public void onError(int error)
    {
        if(error != 7) {
            Log.d(TAG,  "error " +  error);
        }
    }
    public void onResults(Bundle results)
    {
        String str = ""; // Create new empty string
        // Get the results from the speech recognizer
        ArrayList data = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
 // If there is data
        if(data.size() != 0) {
            // Add all the data to a string
            for (int i = 0; i < data.size(); i++) {
                Log.d(TAG, "result " + data.get(i));
                str += data.get(i);
                str += " ";
            }
            // Create a lowercase string
            str = str.toLowerCase();
            // Send the GET request with message
            String message = "message=" + str;
            new Background_get().execute(message);
        }
    }
    public void onPartialResults(Bundle partialResults)
    {
        Log.d(TAG, "onPartialResults");
    }
    public void onEvent(int eventType, Bundle params)
    {
        Log.d(TAG, "onEvent " + eventType);
    }
}

Ahora debemos crear una funcion Onclick que active el Speech Listener del boton: 


public void onClick(View v) {
    if (v.getId() == R.id.btn_speak)
    {
        // Activate the speech listener
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE,"voice.recognition.test");

        intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS,5);
        sr.startListening(intent);
    }
}

Y finalmente lo más importante, la clase que envía las ordenes al Arduino:


private class Background_get extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... params) {
        try {
            /* Change the IP to the IP you set in the arduino sketch */
            URL url = new URL("http://192.168.1.177/?" + params[0]);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuilder result = new StringBuilder();
            String inputLine;
            while ((inputLine = in.readLine()) != null)
                result.append(inputLine).append("\n");

            in.close();
            connection.disconnect();
            return result.toString();

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }} 

Ahora solo debemos agregar los permisos necesarios en el AndroidManifest.xml:


<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.INTERNET" />


Conclusión

Las posibilidades son infinitas. Podemos programar cada pin del arduino para ejecutar una tarea diferente dentro de nuestro hogar, cosas tales como:

  • Encendido/Apagado de luces
  • Encendido/Apagado de luces por sector
  • Encendido/Apagado de Electrodomésticos
  • Encendido/Apagado de Aires acondicionado
  • Bajada/Subida de persianas
  • Apertura de cerraduras
Son solo unas cuantas posibilidades para tu proyecto de automatización casero. Y si, obviamente estamos trabajando con voltajes bajos, pero para eso existe un modulo de reles, y conectado en el siguiente esquema podrá ejecutar todas las funcionalidades que menciono: 


Finalmente les dejo un vídeo con la demostración del funcionamiento, espero que sea de utilidad la información que suministro y cualquier duda pueden dejar un comentario. Por cierto, el asistente, como pueden notar tanto en el video como en el código del Skecht, se llama "Rory" En honor a Rory Mercury, personaje del manga/anime GATE. 



miércoles, 11 de enero de 2017

Integrando A2 (A2softwaay) con PHP para hacer consultas desde un servidor Web



El siguiente articulo lo hago ya que he notado que existe muy poca información en la red al respecto, y muchas personas tienen la necesidad de integrar su sistema administrativo a cualquier modulo o desarrollo externo y no saben por donde empezar. 

Inicialmente, debemos tomar en cuenta que el sistema administrativo utiliza como "motor de base de datos" el DBISAM de Elevatesoft, "motor" no muy conocido para mi y que honestamente me pareció bastante primitivo, pero bueno, no es mi problema criticar las decisiones de sus desarrolladores. Como es el caso de todo motor nuevo que vayamos a implementar, debemos descargar los drivers ODBC. En el siguiente archivo dejaré todo lo necesario para que puedan iniciar con la instalación, adicionalmente incluyo el sistema de gestión para el DBISAM llamado DBSYS, con el mismo se pueden visualizar por interfaz y no por consola las tablas y realizar modificaciones de forma demasiado sencilla (en serio, demasiado).  

DRIVER Y DBSYS 

Una vez descargado el paquete, debemos descomprimir (obviamente) e instalar el driver. Una vez instalado, debemos ejecutar el administrador de orígenes de datos de ODBC (pulsando windows + R Y odbcad32) claro, esto depende de tu sistema operativo y de su arquitectura. 

La ventana que debes ver es la siguiente:



Una vez allí, debes darle click en agregar, y como previamente ya instalaste el driver ODBC este ya debe aparecer en tu lista, al seleccionarlo debes hacer click en finalizar.


 En la siguiente ventana, deberás asignar un nombre a la conexión



 Lo que sigue es bastante importante, debes seleccionar si las operaciones (CRUD) se harán de forma local o a un servidor especifico. 




 Lo que sigue es configurar la ruta en donde se encuentran las tablas de nuestra instalación de a2 (las tablas que queremos trabajar). Generalmente, dependiendo de en donde esté la instalación, la ruta deberá ser algo así: C:\a2Softway\Empre001\Data




 Las siguientes ventas son configuraciones adicionales un poco más especificas, puedes dejarlas por defecto siempre y cuando no tengas un requerimiento muy grande. En cualquier caso, si tienes alguna duda puedes dejarla en los comentarios.




 Al final del proceso verás el nombre que le asignaste a tu conexión y listo, teóricamente ya puedes hacer operaciones sobre la base de datos.



Realizando las consultas

El siguiente paso obviamente será verificar si tu conexión está funcionando realizando las consultas desde el lenguaje de tu preferencia. En este momento, asumiré que poseer conocimientos decentes en informática (ya que intentas realizar operaciones sobre una base de datos con un lenguaje y un modulo externo) las ventajas de realizar operaciones sobre estas tablas son infinitas, va de acuerdo a los requerimientos de tu desarrollo las tablas que quieras tocar. En este ejemplo específicamente realizaré una consulta utilizando PHP, en mi caso. Sin embargo, la estructura es muy similar en cualquier lenguaje que necesites emplear, lo que necesitas es:


1.- Un conector: en el caso de php es la variable $db igualada al método de conexión odbc_connect. Los parámetros iniciales del método deben permanecer, el resto representa la ruta, el usuario y la contraseña. En mi caso, estoy utilizando un servidor local xampp, por ello la ruta se dirige al servidor. Adicionalmente, mi conexión DBISAM no tiene clave. Esto es muy importante, ya que puede generar errores, por ello ese campo está en blanco.

$db = odbc_connect("DRIVER={DBISAM 4 ODBC Driver};ConnectionType=Local;CatalogName=c:/xampp/Data/;","admin","");


2.- Una consulta: La consulta ejemplo apunta a la tabla Sclientes del A2. Pide los campos FC_CODIGO, FC_DESCRIPCION, FC_TIPO, Que representan la cedula, el nombre del cliente y el tipo. Cabe destacar, que la variable "$cedula" se obtiene de un metodo _POST HTML, la misma puede ser modificada por el campo requerido para la consulta a gusto de cada quien. 


$res = odbc_exec($db,"SELECT FC_CODIGO, FC_DESCRIPCION, FC_TIPO, FROM Sclientes WHERE FC_CODIGO = '$CEDULA';");


3.- Un resulset: Es básicamente el arreglo que contiene los resultados de la consulta. En el caso de esta consulta, debe traer la lista de todos los clientes en la base de datos, con su nombre, cedula y tipo.


echo odbc_num_rows($res)." rows found"; while($row = odbc_fetch_array($res)) { print_r($row); }


Como ya he dicho, estos son los ingredientes básicos para poder realizar operaciones sobre tablas de A2 y cualquier sistema que utilice como motor el DBISAM, y en términos generales con cualquier motor sigue el mismo esquema. Los fragmentos del código utilizado están totalmente verificados y operativos, ya queda por parte del programador su correcta implementación. 

Finalmente, les dejo el código completo del proyecto, estoy seguro que como inicio será de mucha utilidad para los que intenten integrar A2 con cualquier otro tipo de sistema. Recuerden que lo actual, es una consulta web, por lo tanto el codigo contiene fragmentos de HTML, PHP e invocaciones a CSS externos que le dan estilo, las validaciones y el resto queda de su parte desarrollarlas. 

CocodriloChat: Chat en JAVA old school empleado Sockets e Hilos



El siguiente es un proyecto que realicé hace unos cuantos años en la universidad. Básicamente la idea era desarrollar un chat estable y multiplataforma, que permitiese múltiples conexiones a través de un servidor que estaba (en ese momento) hospedado en mi casa con un DNS dinámico. 

El proyecto todavía se puede mejorar, de hecho las últimas modificaciones tenían como objetivo la inclusión de emoticonos y ya los paquetes están creados. Creo que le puede ser de mucha utilidad a estudiantes y a personas que estén iniciando (o bueno, ya esto es un nivel medio-avanzado) en el mundo de la programación. De igual forma, les dejo la descripción del proyecto y como siempre, cualquier duda al momento de compilar o modificar pueden dejarla en los comentarios. 


CocodriloChat: Idea del Proyecto

La motivación para la realización de este proyecto es aumentar nuestros conocimientos en el manejo del lenguaje de programación, además de implementar el manejo de nuevos métodos y clases que no se han dado en el contenido de la carrera tales como Los Sockets e Hilos dentro de JAVA.

La implementación del programa servidor sigue las siguientes ideas:
  1. Se inicia el servidor
  2. El servidor se mantiene escuchando cualquier petición de un cliente para conectarse.
  3. El servidor acepta al cliente.
  4. El servidor lanza un hilo de comunicación con el cliente.
  5. Por el hilo se envían y reciben mensajes a través del servidor entre todos los clientes.
  6. Si el cliente cierra la comunicación el hilo se rompe y se corta la comunicación con ese cliente.
Para esto se ha empleado objetos de la clase ServerSocket y Socket para el servidor y cliente respectivamente que permiten la conexion entre cliente y servidor mientras que los Hilos sirven para hacer que el servidor se mantenga escuchando y no interrumpa su proceso mientras los clientes se comunican a través de mensajes.

A continuación unas definiciones:

Sockets: Los sockets no son más que puntos o mecanismos de comunicación entre procesos que permiten que un proceso hable ( emita o reciba información ) con otro proceso incluso estando estos procesos en distintas máquinas. Esta característica de interconectividad entre máquinas hace que el concepto de socket nos sirva de gran utilidad.
 
Hilos: Un hilo es un flujo de ejecución de código, y mediante hilos, podemos hacer que nuestros programas aparentemente realicen varias tareas al mismo tiempo.Por ejemplo, un código podría interaccionar con el usuario mientras realiza tareas de segundo plano de gran consumo de tiempo.Los hilos separados realmente no se ejecutan al mismo tiempo(a menos que se tenga una maquina multiprocesador); en realidad cada hilo obtiene secuencias de tiempo del mismo procesador.

Capturas: 


Pantalla de conexión 

Interfaz del chat

Selección de Avatares

Consola del servidor


Explotando Vulnerabilidades en los laboratorios de URBE


Lo siguiente que voy a describir en las próximas lineas, es la forma de explotar vulnerabilidades para la ejecución de comandos a través de la RED. Específicamente, éste caso practico se aplicó en los laboratorio de la Universidad Dr. Rafael Belloso Chacín (URBE). Es algo bastante básico, sin embargo demuestra la posibilidad de atacar diferentes entidades si no existe una correcta auditoria de seguridad dentro del esquema de red.

Aspectos iniciales: 

Para la ejecución de comandos en red es necesario poseer privilegios administrativos, algo que realmente no es difícil de obtener si el atacante sabe utilizar bien sus recursos. Para la obtención de las contraseñas administrativas existen varios métodos, uno de ellos es la ingeniería social, pero si tienes acceso a un computador dentro del dominio de red, todo será mucho más sencillo, utilizando un rubber ducky con los comandos adecuados o como mi caso, con una distro especifica para crackear contraseñas booteada desde un disco USB. 

En esta ocasión utilicé una imagen de Ophcrack en un pendrive y durante una clase obtuve acceso a todas las contraseñas registradas en el sistema. 

NOTA: En muchos casos prácticos, no será tan fácil ya que bajo entornos bien administrados, el BIOS no estará habilitado para bootear desde USB o simplemente estará bloqueado (pulsando F12 se va a forzar a las opciones de booteo), pero ya será cuestión de intentar con otras herramientas, si el sitio en particular posee una red WIFI abierta, ya tendríamos que ejecutar un ataque Man in the middle desde un equipo nuestro, empleando DNS spoofing con cualquier otra herramienta como Kali linux o WifiSlax

NOTA 2: Si el BIOS se encuentra bloqueado, con abrir el case del computador y quitarle la pila ya solucionas (hombre, existen soluciones para todo).

Ya con privilegios administrativos

Tener privilegios administrativos dentro de la red de una organización te genera un amplio abanico de posibilidades. En mi caso, mi intención era totalmente ética y a modo de broma solo me interesaba apagar ordenadores (especialmente a ciertos profesores) o colapsar un poco la red. El formato el comando para apagado en red es el siguiente: 


shutdown -s -f -m \\192.168.0.2 -t 0



¿Algo bastante sencillo no? Puedes hacer la prueba desde CMD. Pero ten en cuenta, que si la cuenta no posee privilegios obtendrás el siguiente mensaje: 




Muy bien, ahora que sabemos que nuestra cuenta tiene la opcion de apagar equipos en red, vamos a automatizarlo. 

Ejecutar comandos desde la consola quita mucho tiempo, además, si intentas hacer alguna fechoría, en general tendrás poco tiempo. Lo que hice fue una aplicación en java para poder realizar una ejecución masiva o especifica de un computador. Los laboratorios en URBE tienen máximo 32 computadoras, el método pide al usuario el nombre del laboratorio y el rango de donde a donde desea apagar. Acá dejo el método para que tengan una idea: 


public static void apagar(){ //exec("shutdown -s -t 3600"); String lab = JOptionPane.showInputDialog("Ingrese el laboratorio"); String dato; int num; dato = JOptionPane.showInputDialog("Ingrese a partir de que maquina"); num = Integer.parseInt(dato); JOptionPane.showConfirmDialog(null, "¿Seguro deseas apagar los equipos seleccionados?"); String barra= "\\\\"; while (num < 32) { exec("shutdown -s -f -m "+barra+""+lab+"-"+num+++" -t 0"); System.out.println("shutdown -s -f -m "+barra+""+lab+"-
"+num+++" -t 0"); }

Interfaz:  



4 opciones, y una interfaz bastante sencilla


Únicamente con ingresar la IP o el nombre del equipo se logra apagar


Comentarios finales: 

Muchos de ustedes se preguntarán: ¿Ajá apago computadoras y qué? 
Bueno, todas las maquinas dentro del dominio poseen una IP interna con la que podemos jugar, haciendo un escaneo extenso, podremos determinar que hay subneting y posteriormente atacar todo. ¿Sabes que pasa si apagas un servidor? ¿O si apagas todas las maquinas de una caja? COLAPSA TODO. En cualquier empresa si bien no es un ataque para robar información, representa una perdida de tiempo, dinero y seriedad.

El hecho de que éstos fallos existan no quiere decir que deben ser explotados. No hagan, cualquier logro obtenido debe ser un merito personal y debe ser debidamente informado (o hasta vendido si es el caso) a la empresa, pero siempre con ética. Ser hacker no es ser un pirata, los medios nos han llenado con esa definición absurda, un hacker es una persona con hambre de conocimientos, que siempre intenta llevar al limite cualquier sistema o tecnología.


Ah otra cosa. Recuerden siempre borrar toda huella. Si ejecutan algo parecido es probable que lleguen al computador en donde ejecutó, ergo no seas subnormal y si lo haces que sea de forma remota o desde una estación diferente.

Les dejo como siempre el proyecto en Netbeans: 




 

Copyright @ 2017 Pwned!!.