Monday, 25 March 2013

Network evaluator problems

We are using a lot of samsung devices, and in our evaluator we have found a lot of ASU=99.
This is a very strange bug... by the way in accord to this google issue : https://code.google.com/p/android/issues/detail?id=18336 we followed the solution posted here using
java reflection, and getting the private method int getGsmSignalBar() from android.telephony.SignalStrength.

 
package it.myapkexample.com;

import ...

public class SignalService extends Service implements ISynchronizationListener {
 public Context _context;
 private Timer timer = new Timer();
 private static final long UPDATE_INTERVAL = 1000;
 private ArrayList queque;
 private ConnectivityManager _connectivity;
 private final IBinder mBinder = new MyBinder();
 private String method_to_calling = null;

 int QUEUE_SIZE = 8;
 int POSITIVE_ESTIMATE = 1;
 int NEGATIVE_ESTIMATE = 0;
 int PERCENTUAL_POSITIVE_SIGNAL_WIFI = 45;
 int PERCENTUAL_POSITIVE_SIGNAL_CELLULAR = 5;
 Replicator _r;
 SignalStrengthListener signalStrengthListener;
 SignalStrength mSignalStrength;

 // 993
 // 994 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
 // 995 // asu = 0 (-113dB or less) is very weak
 // 996 // signal, its better to show 0 bars to the user in such
 // cases.
 // 997 // asu = 99 is a special case, where the signal strength
 // is unknown.
 // 998 if (asu <= 2 || asu == 99) iconLevel = 0;
 // 999 else if (asu >= 12) iconLevel = 4;
 // 1000 else if (asu >= 8) iconLevel = 3;
 // 1001 else if (asu >= 5) iconLevel = 2;
 // 1002 else iconLevel = 1;

 public boolean REQUEST_ESTIMATE = false;
 private boolean REQUEST_SYNCRO = false;
 int asu = 0;

 private boolean SYNC = false;

 public void onCreate() {

  super.onCreate();
  QUEUE_SIZE = Integer.parseInt(Setup.getPropertyValue("queue_size"));
  POSITIVE_ESTIMATE = Integer.parseInt(Setup.getPropertyValue("positive_estimate"));
  NEGATIVE_ESTIMATE = Integer.parseInt(Setup.getPropertyValue("negative_estimate"));
  PERCENTUAL_POSITIVE_SIGNAL_WIFI = Integer.parseInt(Setup.getPropertyValue("percentual_positive_wifi"));
  PERCENTUAL_POSITIVE_SIGNAL_CELLULAR = Integer.parseInt(Setup.getPropertyValue("percentual_positive_data_c"));

  signalStrengthListener = new SignalStrengthListener();
  ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).listen(signalStrengthListener, SignalStrengthListener.LISTEN_SIGNAL_STRENGTHS);
  _connectivity = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
  if (queque == null)
   queque = new ArrayList();

  startChecking();
 }

 public int queueGetCurrent() {
  return queque.get(queque.size() - 1);
 }

 public int queueGetLast() {
  return queque.get(queque.size() - 2);
 }

 public void startChecking() {

  timer.scheduleAtFixedRate(new TimerTask() {

   @Override
   public void run() {
    if ((queque.size() >= 2) && (queueGetLast() == 1) && (queueGetCurrent() == 0)) {
     Intent in = new Intent();
     in.putExtra("NETWORK_VALIDATE", false);
     in.setAction("it.overit.trasportopazienti.networkQuality");
     if (_context != null)
      _context.sendBroadcast(in);
    }

    if (queque.size() == QUEUE_SIZE) {

     boolean _es = false;
     // Qui ci sarà la chiamata all'intent
     _es = estimate();
     sendSignalQualityNT(_es);

     if (REQUEST_ESTIMATE) {
      if (_es) {
       REQUEST_ESTIMATE = false;
       if (SYNC) {
        SYNC = false;
        bg_sync_tp();
       }
      }

      // Controllo fino a quando non c'è una valutazione
      // positiva!
      else {
       // handleUIRequest("Valutazione network negativa, richiesta di sincronizzazione in coda!");
       // Toast.makeText(getApplicationContext(),
       // "Valutazione network negativa, richiesta di sincronizzazione in coda!",
       // 1).show();
       REQUEST_ESTIMATE = true;
      }
     }
     queque = new ArrayList();

    } else
     checkInfo();
   }
  }, 0, UPDATE_INTERVAL);
  Log.i(getClass().getSimpleName(), "Timer signal strenght started.");
 }

 public void sendSignalQualityNT(Boolean value) {
  Intent in = new Intent();
  in.putExtra("NETWORK_VALIDATE", value);
  in.setAction("it.overit.trasportopazienti.networkQuality");
  if (_context != null)
   _context.sendBroadcast(in);

 }

 public void noway() {
  FormManager.showAlert(_context, "rear");
 }

 protected void handleUIRequest(String message) {
  UIHandler uiHandler = null;
  HandlerThread uiThread = new HandlerThread("UIHandler");
  uiThread.start();
  uiHandler = new UIHandler(uiThread.getLooper(), getApplicationContext());
  Message msg = uiHandler.obtainMessage(UIHandler.DISPLAY_UI_TOAST);
  msg.obj = message;
  uiHandler.sendMessage(msg);
 }

 public void checkInfo() {
  _connectivity = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
  NetworkInfo _net_info = _connectivity.getActiveNetworkInfo();
  android.net.NetworkInfo wifi = _connectivity.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
  android.net.NetworkInfo mobile = _connectivity.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

  if (wifi.isConnectedOrConnecting()) {
   if (_net_info != null && _net_info.isConnected()) {
    WifiManager wifi_info = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    int MIN_RSSI = -100;
    int MAX_RSSI = -55;
    int levels = 101;
    int rssi = wifi_info.getConnectionInfo().getRssi();
    // Log.e("Wifi signal", "" + rssi);
    if (rssi <= MIN_RSSI) {
     queque.add(NEGATIVE_ESTIMATE);
    } else if (rssi >= MAX_RSSI) {
     // Log.i("Percentual wifi : ", "" + (levels - 1));
     queque.add(POSITIVE_ESTIMATE);
    } else {
     float inputRange = (MAX_RSSI - MIN_RSSI);
     float outputRange = (levels - 1);
     int percentual = ((int) ((float) (rssi - MIN_RSSI) * outputRange / inputRange));
     if (percentual > PERCENTUAL_POSITIVE_SIGNAL_WIFI)
      queque.add(POSITIVE_ESTIMATE);
    }
   }
  } else if (mobile.isConnectedOrConnecting()) {

   if (_net_info != null && _net_info.isConnected()) {

    Log.e("Mobile signal", "" + asu);
    if ((asu <= 3) || (asu == 99)) // || (asu < 4)
     queque.add(NEGATIVE_ESTIMATE);
    else if (asu > PERCENTUAL_POSITIVE_SIGNAL_CELLULAR)
     queque.add(POSITIVE_ESTIMATE);
    else
     queque.add(NEGATIVE_ESTIMATE);
   }
  } else
   queque.add(NEGATIVE_ESTIMATE);

 }


 public class SignalStrengthListener extends PhoneStateListener {
  @Override
  public void onSignalStrengthsChanged(android.telephony.SignalStrength signalStrength) {
   Integer value = -1;
   Method m;
   try {
    m = SignalStrength.class.getMethod("getGsmSignalBar");
    value = (Integer) m.invoke(signalStrength);
    Log.e("Value signal Bar", "" + value);
   } catch (Exception e) {
   }
   asu = signalStrength.getGsmSignalStrength();
   if (asu == 99) {
    if (value == 4) {
     asu = 18;
    } else if (value == 3) {
     asu = 9;
    } else if (value == 2) {
     asu = 3;
    } else
     asu = 1;
   }
   super.onSignalStrengthsChanged(signalStrength);
  }
 }

 public class MyBinder extends Binder {
  public SignalService getService() {
   return SignalService.this;
  }
 }

 @Override
 public IBinder onBind(Intent intent) {
  return mBinder;
 }

 @Override
 public void onDestroy() {
  super.onDestroy();
  if (timer != null) {
   timer.cancel();
  }
  Log.i(getClass().getSimpleName(), "Timer signal strenght started.");
 }

 public void request_estimate(Context context) {
  this._context = context;
  
  REQUEST_ESTIMATE = true;
 }

 public void request_estimate(Context context, Boolean sync) {

  this._context = context;
  if (sync) {

   if (!SYNC)
    handleUIRequest("Sync Request!");
   // Toast.makeText(_context,
   // "Richiesta sincronizzazione, previa verifica network dati!",
   // 1).show();
  }
  SYNC = true;
  REQUEST_ESTIMATE = true;
 }

 public boolean estimate() {

  // REQUEST_ESTIMATE = false;
  int percentual = (howManyTrue() / QUEUE_SIZE) * 100;
  // Log.i("Percentual :", "" + percentual);
  if (percentual >= 60)
   return true;
  else
   return false;

 }

 public int howManyTrue() {
  int r = 0;
  for (int i = 0; i < queque.size(); i++)
   if (queque.get(i) == 1)
    r++;
  return r;
 }

 @Override
 public Context getContext() {
  // TODO Auto-generated method stub
  return null;
 }



 

}




Wednesday, 23 January 2013

Network quality evaluator.

I need a service for the network evalutation.
In this one we have a timer (1sec) used to check if  the network data signal is > of a parameter (PERCENTUAL_POSITIVE_SIGNAL_CELLULAR in case of mobile netwrok, PERCENTUAL_POSITIVE_SIGNAL_WIFI in case of wifi network) and put the evaluation in a queue. When the network check is required the queue is scanned and if we have 60% of positive values we are in ONLINE condition, otherwise not.
Maybe someone is looking for something similar. Enjoy.
 
package it.myapkexample.com;


import java.util.ArrayList;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

public class SignalService extends Service  {
 public Context _context;
 private Timer timer = new Timer();
 private static final long UPDATE_INTERVAL = 1000;
 private ArrayList queque;
 private ConnectivityManager _connectivity;
 private final IBinder mBinder = new MyBinder();
 private String method_to_calling = null;

 final int QUEUE_SIZE = 8;
 final int POSITIVE_ESTIMATE = 1;
 final int NEGATIVE_ESTIMATE = 0;
 final int PERCENTUAL_POSITIVE_SIGNAL_WIFI = 45;
 final int PERCENTUAL_POSITIVE_SIGNAL_CELLULAR = 8;
 Replicator _r;
 SignalStrengthListener signalStrengthListener;
 // 993
 // 994 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
 // 995 // asu = 0 (-113dB or less) is very weak
 // 996 // signal, its better to show 0 bars to the user in such
 // cases.
 // 997 // asu = 99 is a special case, where the signal strength
 // is unknown.
 // 998 if (asu <= 2 || asu == 99) iconLevel = 0;
 // 999 else if (asu >= 12) iconLevel = 4;
 // 1000 else if (asu >= 8) iconLevel = 3;
 // 1001 else if (asu >= 5) iconLevel = 2;
 // 1002 else iconLevel = 1;

 public boolean REQUEST_ESTIMATE = false;
 private boolean REQUEST_SYNCRO = false;
 int asu = 0;

 public void onCreate() {
  super.onCreate();
  Setup.getPropertyValue("QUEUE_SIZE");
  signalStrengthListener = new SignalStrengthListener();
  ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).listen(signalStrengthListener, SignalStrengthListener.LISTEN_SIGNAL_STRENGTHS);
  _connectivity = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
  if (queque == null)
   queque = new ArrayList();

  startChecking();
 }

 public int queueGetCurrent() {
  return queque.get(queque.size() - 1);
 }

 public int queueGetLast() {
  return queque.get(queque.size() - 2);
 }

 public void startChecking() {

  timer.scheduleAtFixedRate(new TimerTask() {

   @Override
   public void run() {
    if ((queque.size() >= 2) && (queueGetLast() == 1) && (queueGetCurrent() == 0)) {
     Intent in = new Intent();
     in.putExtra("NETWORK_VALIDATE", false);
     in.setAction("it.overit.trasportopazienti.networkQuality");
     if (_context != null)
      _context.sendBroadcast(in);
    }

    if (queque.size() == QUEUE_SIZE) {

     boolean _es = false;
     // Qui ci sarà la chiamata all'intent
     _es = estimate();
     sendSignalQualityNT(_es);

     if (REQUEST_ESTIMATE) {
      if (_es) {
      //Our method to do something after positive evalutation of network signal
       bg_sync_tp(); 
       REQUEST_ESTIMATE = false;
      }
      else {
       Toast.makeText(_context, "Valutazione network negativa, richiesta di sincronizzazione in coda!", 1).show();
       REQUEST_ESTIMATE = true;
      }
     }
     queque = new ArrayList();

    } else
     checkInfo();
   }
  }, 0, UPDATE_INTERVAL);
  Log.i(getClass().getSimpleName(), "Timer signal strenght started.");
 }

 

 public void noway() {
  FormManager.showAlert(_context, "rear");
 }

 public void checkInfo() {
  NetworkInfo _net_info = _connectivity.getActiveNetworkInfo();
  android.net.NetworkInfo wifi = _connectivity.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
  android.net.NetworkInfo mobile = _connectivity.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);

  if (wifi.isConnectedOrConnecting()) {
   if (_net_info != null && _net_info.isConnected()) {
    WifiManager wifi_info = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    int MIN_RSSI = -100;
    int MAX_RSSI = -55;
    int levels = 101;
    int rssi = wifi_info.getConnectionInfo().getRssi();
    Log.e("Wifi signal", "" + rssi);
    if (rssi <= MIN_RSSI) {
     queque.add(NEGATIVE_ESTIMATE);
    } else if (rssi >= MAX_RSSI) {
     Log.i("Percentual wifi : ", "" + (levels - 1));
     queque.add(POSITIVE_ESTIMATE);
    } else {
     float inputRange = (MAX_RSSI - MIN_RSSI);
     float outputRange = (levels - 1);
     int percentual = ((int) ((float) (rssi - MIN_RSSI) * outputRange / inputRange));
     if (percentual > PERCENTUAL_POSITIVE_SIGNAL_WIFI)
      queque.add(POSITIVE_ESTIMATE);
    }
   }
  } else if (mobile.isConnectedOrConnecting()) {

   if (_net_info != null && _net_info.isConnected()) {
    Log.e("Mobile signal",""+asu);
    if ((asu <= 22 || asu == 99) || (asu <= 5))
     queque.add(NEGATIVE_ESTIMATE);
    else if (asu >= PERCENTUAL_POSITIVE_SIGNAL_CELLULAR)
     queque.add(POSITIVE_ESTIMATE);
    else
     queque.add(NEGATIVE_ESTIMATE);
   }
  } else
   queque.add(NEGATIVE_ESTIMATE);

 }
 public class SignalStrengthListener extends PhoneStateListener {
  @Override
  public void onSignalStrengthsChanged(android.telephony.SignalStrength signalStrength) {
   int asu = signalStrength.getGsmSignalStrength();
   super.onSignalStrengthsChanged(signalStrength);
  }
 }
 
 public class MyBinder extends Binder {
  public SignalService getService() {
   return SignalService.this;
  }
 }

 @Override
 public IBinder onBind(Intent intent) {
  return mBinder;
 }

 @Override
 public void onDestroy() {
  super.onDestroy();
  if (timer != null) {
   timer.cancel();
  }
  Log.i(getClass().getSimpleName(), "Timer signal strenght started.");
 }

 public void request_estimate(Context context) {
  this._context = context;
  REQUEST_ESTIMATE = true;
 }

 public void request_estimate(Context context, Boolean sync) {

  this._context = context;
  if (sync) {

   Log.i("INFO", "Sync request");
   Toast.makeText(_context, "Network validatation", 1).show();
  }
 
  REQUEST_ESTIMATE = true;
 }

 public boolean estimate() {

  // REQUEST_ESTIMATE = false;
  int percentual = (howManyTrue() / QUEUE_SIZE) * 100;
  // Log.i("Percentual :", "" + percentual);
  if (percentual >= 60)
   return true;
  else
   return false;

 }

 public int howManyTrue() {
  int r = 0;
  for (int i = 0; i < queque.size(); i++)
   if (queque.get(i) == 1)
    r++;
  return r;
 }

 @Override
 public Context getContext() {
  // TODO Auto-generated method stub
  return null;
 }

 public synchronized void bg_sync_tp() {


 //DO something here
 }

 
 
 

}



Tuesday, 30 October 2012

Storing a bootable .iso into a flash media in osX

'Morning,  Yesterday i had to burn an ubuntu.iso image into an usb drive to update my laptop.
OsX DiskUtility doesn't support the restore option from an .iso image, so you have to convert your .iso image into a compatible one as .dmg or .img. These are the steps :


1- Run diskutil list to get the current list of devices
2- Insert your flash media (usb/hd or semething else)
3- Run diskutil list again and determine the device node assigned to your flash media (e.g. /dev/disk2)
4- Run diskutil and unmount disk /dev/diskN (replace N with the disk number from the last command; in the previous example,N would be 2)
5- Execute sudo dd if=/path/to/downloaded.img of=/dev/rdiskN bs=1m (replace /path/to/downloaded.img with the path where    he image file is located;for example, ./ubuntu.img or ./ubuntu.dmg).
6- Using /dev/rdisk instead of /dev/disk may be faster.

If you see the error dd: Invalid number '1m', you are using GNU dd. Use the same command but replace bs=1m with bs=1M.
If you see the error dd: /dev/diskN: Resource busy, make sure the disk is not in use.
Start the 'Disk Utility.app' and unmount (don't eject) the drive.
Run diskutil eject /dev/diskN and remove your flash media when the command completes

Wednesday, 12 September 2012

Arp packet sender ring.c

Long time ago there was Mojodo. Mojodo was a team made by young nerd boys with it-security passion.
For mojodo i coded some tools and one of them was published on packetstorm.com, Today in a lag time i googled my nickname  and this link appeared. It sounds so strange for me... it was 2-9-2002! Ten years ago, amazing.
By the way, this tool is already useful, it's a normal arp packet forger (for sure in a famous tools like ettercap you can find something like this coded in a better way), and you can customize all arp,eth+ip packet, from the eth header to the ip packet, You can do all arp attack, with this tool and with a little bit of fantasy. Cheers.

Tuesday, 11 September 2012

Button inside a ListView

In my projects i often used the listview android element. When you fill the elements inside your adapter i found a little but for me (expecially sometimes) problem.
I had to fill up the elements with some descriptions and put inside the child of the list a clickable button.
ListView stole the focus to the buttons with the result you couldn't  to click on them.
The solution is to set up the button not focusable on the .xml layout or extend the Button Element as the follow : 
 
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;

public class ListButton extends Button {

    public ListButton(Context context) {
        super(context);
        this.setFocusable(false);
    }

    public ListButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.setFocusable(false);
    }
  @Override
    public void setPressed(boolean pressed) {
         if (pressed && ((View) getParent()).isPressed()) { return; }
         super.setPressed(pressed);
    }
}

And you can use the ListButton on your .xml layout.

Wednesday, 22 August 2012

ListView inside a ScrollView

There are some problems when you put a ListView inside a scrollview, in detail you can't really scroll the listview becouse of the Scrollview so if you add an element in your list array and you try to notify this fact to your adapter the listview will be not resize, so you have to resize by hand every time you notify the data set changed (an item removed or an item add).
I found this code in the net which could help you:
 

public class SetListViewHeightBasedOnChildren {

 public static void ModifyHeight(ListView listView) {
  ListAdapter listAdapter = listView.getAdapter();
  if (listAdapter == null) {
   // pre-condition
   return;
  }
  int totalHeight = 0;
  int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
  for (int i = 0; i < listAdapter.getCount(); i++) {
   View listItem = listAdapter.getView(i, null, listView);
   listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
   totalHeight += listItem.getMeasuredHeight();
  }

  ViewGroup.LayoutParams params = listView.getLayoutParams();
  params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
  listView.setLayoutParams(params);
  listView.requestLayout();
 }
}

Tuesday, 15 May 2012

Start a method in background with alarm manager,broadcast receiver and notification center.

In this post we will see how to start something (in this case a method plus a notification), and wake up it regular after a fixed time.
The first thing we need is a receiver who will be able to listen in broadcast some event.
We need to declare also the receiver and the type of event inside the AndroidManifest.xml.


 
//Broadcast_r.java
public class replicator_br extends BroadcastReceiver {
 Context _context;
 static Notification notification;
 static NotificationManager notificationManager;

 @Override
 public void onReceive(Context context, Intent intent) {
  _context = context;
  String action = intent.getAction();
  if ("it.evenet.WAKEUP".equals(action)) {
   createNotification(context, "Wakeup", "Start_event", 666);
   start_event(context);
  }

 }

 public void start_event(Context context) {

  try {
   ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
   NetworkInfo ni = cm.getActiveNetworkInfo();
   if (ni != null && ni.isConnected()) {
    // here we can put all method,we need to start in background
   } else {
    notification_Update("  I can't start", 666);
   }

  } catch (Exception e) {
   notification_Update(e.getMessage(), 666);

  }

 }

 public static void createNotification(Context context, String Title, String payload, int id) {
  Intent intent = new Intent();
  final PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
  // here i'm setting up a notify plus a progress bar.
                notification = new Notification(R.drawable.icon, Title, System.currentTimeMillis());
  notification.flags = notification.flags | Notification.FLAG_AUTO_CANCEL;
  notification.contentView = new RemoteViews(context.getPackageName(), R.layout.notification);
  notification.contentIntent = pendingIntent;
  notification.contentView.setImageViewResource(R.id.status_icona, R.drawable.icon);
  notification.contentView.setTextViewText(R.id.status_text_log, payload);
  // notification.contentView.setProgressBar(R.id.status_progress, j, i,
  // false);
  notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
  notificationManager.notify(id, notification);

 }

 public static void notification_Update(String string, int id) {
  notification.contentView.setTextViewText(R.id.status_text_log, string);
  notificationManager.notify(id, notification);

 }

 

}

After we will need something to start the event : it.evenet.WAKEUP and repeat it every 30 seconds, sending a notify in broadcast:
 
//snippet public void send_br() {
  final long REPEAT_TIME = 1000 * 30;
  AlarmManager service = (AlarmManager) this.getSystemService(this.ALARM_SERVICE);
  Intent intent = new Intent("it.evenet.WAKEUP");
  PendingIntent pending = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

  Calendar cal = Calendar.getInstance();
  cal.add(Calendar.SECOND, 40);
  
  service.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), REPEAT_TIME, pending);

  this.sendBroadcast(intent);
 }


And in the end our manifest.xml :
 

[snippet]