Thursday, March 2, 2017

Predictive Analytics using R and Java

Ever wondered how Star Sports is able to show the prediction of cricket match winner? You must have seen some fancy analysis like "India wins the match batting second 80% of the time when Virat Kohli scores 30+ runs in first 10 overs". Recently I delivered a webinar on Predictive Analytics using R and Java on Techgig which has an answer to these questions.

Predictive analytics is about predicting future outcomes based on currently available or historical data using several machine learning algorithms and statistical techniques.

R - a language and environment for statistical computing, makes it really easy to quickly try out several algorithms like Decision Trees, Random Forests, Neural Networks etc. on top of your existing datasets. R packages, like Rattle, can quickly allow you to interactively create machine learning models which can be trained and exported to a PMML file format.

The Predictive Model Markup Language (PMML) is a platform agnostic, XML-based predictive model interchange format which can be used to exchange the trained machine learning models across different technology platforms. Any machine learning model exported in PMML can be imported in your Java program by using libraries like JPPML and can be used to predict future outcomes based on the existing data.

As part of this webinar, you will understand how to quickly create trained machine learning model based on an existing dataset, export it to a PMML file and import into a Java Project.

You will learn about
  1. Basics of Predictive Analytics, brief explanation of Decision Trees, Random Forests and Neural Networks.
  2. How to use R and Rattle to create machine learning models which can be used to predict outcomes based on existing data.
  3. How to train, validate and test machine learning models in R using Rattle.
  4. How to export a trained machine learning model in PMML format using R.
  5. How to use the exported model in PMML format in your Java Program using JPMML

You can find the webinar recording below.


Code Samples related to this webinar can be found below
  1. https://github.com/abhilshit/CricIndiaWinPredictor
  2. https://github.com/abhilshit/CricIndiaWinPredictorService
  3. https://github.com/abhilshit/CricSheetYamlParser


Wednesday, March 1, 2017

Developing Garmin SmartWatch Apps with ConnectIQ Platform-Part 3

In this third and last part of this tutorial we shall see how to pass the meeting information from the Android app to the SmartWatch app/widget that we developed in part 2 of this tutorial. This part of the tutorial requires some prior knowledge on Android development. If you are in need of a quick android tutorial then you can find it here.

ConnectIQ platform comes with following pre-built mobile SDKs.
  1. Android BLE - (actually connects Android app to Smartwatch Apps over BLE)
  2. iOS BLE - (connects an iOS mobile app to Smartwatch App over BLE)
  3. Android ADB - (used to simulate BLE connection over ADB)
These SDK's  are set of libraries  required to communicate over BLE or to simulate a BLE like connection over ADB (the Android debug bridge). In this part of the tutorial we will look at that Android ADB SDK so that we can simulate the BLE like connection using the emulator in our development environment.

You can select and download the Android ADB SDK from the Mobile SDK download page from the link given below.


The SDK file would be a zip file named like connectiq-mobile-sdk-android-1.3.zip. Unzip this file and you should see a JAR file inside and a sample app. That JAR file is your SDK library which has everything you need to communicate with your Garmin Smartwatch app. The sample project in the zip file shows and example of how to use this SDK.  There should be an additional file called MobileSDK.html, I would recommend going through it to understand the lifecycle events of the ConnectIQ Mobile SDK.

Import the sample project present in the zip file into Android Studio. You should see a structure like this.

You can see the libs folder containing the connectiq.jar and under /src you should see a few classes like MainActivity.java etc. I would recommend you to connect your android device and deploy this sample app as is and see what happens.

You can see that the method onSDKReady() in MainActivity.java is called after the SDK is initialized, which invokes method called loadDevices() that looks like below
 
 public void loadDevices() {
        // Retrieve the list of known devices
        try {
            List devices = mConnectIQ.getKnownDevices();

            if (devices != null) {
                mAdapter.setDevices(devices);

                // Let's register for device status updates.  By doing so we will
                // automatically get a status update for each device so we do not
                // need to call getStatus()
                for (IQDevice device : devices) {
                    mConnectIQ.registerForDeviceEvents(device, mDeviceEventListener);
                }
            }

        } catch (InvalidStateException e) {
            // This generally means you forgot to call initialize(), but since
            // we are in the callback for initialize(), this should never happen
        } catch (ServiceUnavailableException e) {
            // This will happen if for some reason your app was not able to connect
            // to the ConnectIQ service running within Garmin Connect Mobile.  This
            // could be because Garmin Connect Mobile is not installed or needs to
            // be upgraded.
            if( null != mEmptyView )
                mEmptyView.setText(R.string.service_unavailable);
        }
    }

To get the list of connected devices do the following changes in MainActivity.java onCreate() method.

  1. Obtain the ConnectIQ object instance using the following method 
  2. mConnectIQ = ConnectIQ.getInstance(IQCommProtocol.ADB_SIMULATOR);
    
  3. Connect and deploy the app to your phone.
  4. Execute following command on the command-line 
    1.  adb forward tcp:7381 tcp:7381
The last command would forward the TCP port to the Android device in a terminal or console allowing the simulator to communicate over ADB simulating a BLE connection.

Doing this should display the list of connected devices in the sample app after deploying it on your android mobile.

The other class DeviceActivity.java implements a View.OnClickListener interface which implements an onListItemClick() method. You can see that the mobile app tries to send a text message to the smart watch connected device by calling 
mConnectIQ.sendMessage(mDevice, mMyApp, message, new IQSendMessageListener() {

         @Override
         public void onMessageStatus(IQDevice device, IQApp app, IQMessageStatus status) {
               Toast.makeText(DeviceActivity.this, status.name(), Toast.LENGTH_SHORT).show();
             }

         });
We can replace these set of lines to pass a set of text messages that contains comma separated calendar events by calling the syncCalendarMessages() method as described below.


private void syncCalendarMessages() {
        HashMap&ltString, List&ltCalendarEvent&gt&gt eventMap = CalendarService.readCalendar(getApplicationContext(), 2, 0);
        List&ltMap&gt eventDataList = new ArrayList&lt&gt();
        HashMap&ltInteger, String&gt eventDataMap ;
        for(Map.Entry&ltString, List&ltCalendarEvent&gt&gt e:eventMap.entrySet())
        {
            for(CalendarEvent event:e.getValue())
            {
                    eventDataMap = new HashMap();
                    StringBuilder eventBuilder = new StringBuilder();

                    eventDataMap.put(1, "1223");
                    //eventDataMap.put(2, event.getBegin().toGMTString());
                    String title= event.getTitle().replaceAll(":", " ").replaceAll(",", "");
                    String location = event.getLocation().replaceAll(":", " ").replaceAll(",",  "");
                    eventBuilder.append(new SimpleDateFormat("HHmm").format(event.getBegin()));
                    eventBuilder.append(",");
                    eventBuilder.append(title);
                    eventBuilder.append(",");
                    eventBuilder.append(location);
                    eventBuilder.append(",");
                    eventBuilder.append(SIMPLE_DATE_FORMAT.format(event.getBegin()));

                Log.i("Event Map", eventBuilder.toString());
                IQMessageStatus status = null;
                try {

                    status = mConnectIQ.sendMessage(mDevice, mApp, eventBuilder.toString());
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                if (status != IQMessageStatus.SUCCESS) {
                    //displayMessage(String.format(getString(R.string.message_send_error_format), status.name()));
                } else {
                   // displayMessage(getString(R.string.message_sent));
                   // mMessageInput.setText("");
                }
                    eventDataList.add(eventDataMap);

               // } catch (JSONException e1) {
//                    e1.printStackTrace();
//                }
            }
        }
        Log.i("CalenderEvents", eventDataList.toString());
        

    }

The CalendarService Class uses Android utility class android.provider.CalendarContract to read calendar events from the Google Calendar App.


package com.garmin.android.apps.connectiq.sample;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.CalendarContract;
import android.text.format.DateUtils;



public class CalendarService {

    // Default constructor
    public static void readCalendar(Context context) {
        readCalendar(context, 1, 0);
    }

    // Use to specify specific the time span
    public static HashMap&ltString, List&ltCalendarEvent&gt&gt readCalendar(Context context, int days, int hours) {

        ContentResolver contentResolver = context.getContentResolver();

        // Create a cursor and read from the calendar (for Android API below 4.0)
//        final Cursor cursor = contentResolver.query(Uri.parse("content://com.android.calendar/calendars"),
//                (new String[] { "_id", "displayName", "selected" }), null, null, null);

   Cursor cursor = contentResolver.query(Uri.parse("content://com.android.calendar/events"),
   new String[]{ "calendar_id", "title", "description", "dtstart", "dtend", "eventLocation" },
   null, null, null);

        // Create a set containing all of the calendar IDs available on the phone
        HashSet&ltString&gt calendarIds = getCalenderIds(cursor);

        // Create a hash map of calendar ids and the events of each id
        HashMap&ltString, List&ltCalendarEvent&gt&gt eventMap = new HashMap&ltString, List&ltCalendarEvent&gt&gt();

        // Loop over all of the calendars
        for (String id : calendarIds) {

            // Create a builder to define the time span
            Uri.Builder builder = Uri.parse("content://com.android.calendar/instances/when").buildUpon();
            long now = new Date().getTime();

            // create the time span based on the inputs
            ContentUris.appendId(builder, now - (DateUtils.DAY_IN_MILLIS * days) - (DateUtils.HOUR_IN_MILLIS * hours));
            ContentUris.appendId(builder, now + (DateUtils.DAY_IN_MILLIS * days) + (DateUtils.HOUR_IN_MILLIS * hours));

            // Create an event cursor to find all events in the calendar
            Cursor eventCursor = contentResolver.query(builder.build(),
                    new String[]  { "title", "begin", "end", "allDay", "eventLocation"},  CalendarContract.Instances.CALENDAR_ID+"=" + id,
                    null, "startDay ASC, startMinute ASC");

            System.out.println("eventCursor count="+eventCursor.getCount());

            // If there are actual events in the current calendar, the count will exceed zero
            if(eventCursor.getCount()>0)
            {

                // Create a list of calendar events for the specific calendar
                List eventList = new ArrayList();

                // Move to the first object
                eventCursor.moveToFirst();

                // Create an object of CalendarEvent which contains the title, when the event begins and ends,
                // and if it is a full day event or not
                CalendarEvent ce = loadEvent(eventCursor);

                // Adds the first object to the list of events
                eventList.add(ce);

                System.out.println(ce.toString());

                // While there are more events in the current calendar, move to the next instance
                while (eventCursor.moveToNext())
                {

                    // Adds the object to the list of events
                    ce = loadEvent(eventCursor);
                    eventList.add(ce);

                    System.out.println(ce.toString());

                }

                Collections.sort(eventList);
                eventMap.put(id, eventList);

                System.out.println(eventMap.keySet().size() + " " + eventMap.values());

            }
        }
        return eventMap;
    }

    // Returns a new instance of the calendar object
    private static CalendarEvent loadEvent(Cursor csr) {
        return new CalendarEvent(csr.getString(0),
                new Date(csr.getLong(1)),
                new Date(csr.getLong(2)),
                !csr.getString(3).equals("0"),csr.getString(4));
    }

    // Creates the list of calendar ids and returns it in a set
    private static HashSet&ltString&gt getCalenderIds(Cursor cursor) {

        HashSet&ltString&gt calendarIds = new HashSet&ltString&gt();

        try
        {

            // If there are more than 0 calendars, continue
            if(cursor.getCount() > 0)
            {

                // Loop to set the id for all of the calendars
                while (cursor.moveToNext()) {

                    String _id = cursor.getString(0);
                    String displayName = cursor.getString(1);
                    Boolean selected = !cursor.getString(2).equals("0");

                    System.out.println("Id: " + _id + " Display Name: " + displayName + " Selected: " + selected);
                    calendarIds.add(_id);
                }
            }
        }

        catch(AssertionError ex)
        {
            ex.printStackTrace();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

        return calendarIds;

    }
}
The CalendarEvent class is a POJO that defines fields of a calendar event and it looks like
package com.garmin.android.apps.connectiq.sample;

/**
 * Created by asoni on 22-07-2015.
 */
import java.util.Date;

public class CalendarEvent implements Comparable&ltCalendarEvent&gt{

    private String title, location;
    private Date begin, end;
    private boolean allDay;

    public CalendarEvent() {

    }

    public CalendarEvent(String title, Date begin, Date end, boolean allDay, String location) {
        setTitle(title);
        setBegin(begin);
        setEnd(end);
        setAllDay(allDay);
        setLocation(location);
    }

    public String getLocation() {
        return title;
    }

    public void setLocation(String location) {
        this.location = location;
    }
    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Date getBegin() {
        return begin;
    }

    public void setBegin(Date begin) {
        this.begin = begin;
    }

    public Date getEnd() {
        return end;
    }

    public void setEnd(Date end) {
        this.end = end;
    }

    public boolean isAllDay() {
        return allDay;
    }

    public void setAllDay(boolean allDay) {
        this.allDay = allDay;
    }

    @Override
    public String toString(){
        return getTitle() + " " + getBegin() + " " + getEnd() + " " + isAllDay();
    }

    @Override
    public int compareTo(CalendarEvent other) {
        // -1 = less, 0 = equal, 1 = greater
        return getBegin().compareTo(other.begin);
    }

}

That is all you need once you have these classes in place then redeploy your sample application, select appropriate smartwatch device from the list and your smartwatch app should receive the calendar events and start alerting you about it.

 P.S: If you restart the ADB while redeploying then you would need to fire the following command again on your terminal/command-line in order to start communicating over ADB simulating the BLE

                                  adb forward tcp:7381 tcp:7381

For making you application production ready you would want to test the communication on real BLE  instead of simulated BLE over ADB. To do that just change back the way you obtain the ConnectIQ object instance to

mConnectIQ = ConnectIQ.getInstance(this, IQConnectType.WIRELESS);

in MainActivity.java onCreate() method and test it after deploying without being in debug mode.

Wednesday, October 19, 2016

Developing Garmin SmartWatch Apps with ConnectIQ Platform-Part 2

This is part 2 of blog series that covers a tutorial on developing Wearables App for Garmin SmartWatches. In this part of the tutorial we will write the logic to display Meeting Alerts in the watch widget that we created in part-1 of this tutorial.

Lets create a Monkey-C class called MeetingAlert.mc in the CalendarAlerts ConnectIQ Eclipse Project. MeetingAlert class will represent a single MeetingAlert record that we will receive from the Android Device over BLE.

using Toybox.System as Sys;
class MeetingAlert {

  //mTime - meeting time
  //mDate - meeting date
  //mSubject - meeting subject
  //mLocation -meeting location
 hidden var mTime, mDate, mSubject, mLocation;

 
 function getMeetingTime() {
  return mTime;
 }
 
 function getMeetingDate() {
  return mDate;
 }
 
 function getMeetingSubject() {
  return mSubject;
 }
 
 function getMeetingLocation() {
  return mLocation;
 }
 
 
}

We can assume that the calendar event details are received from Android Device whenever the watch synchronizes with phone over bluetooth. As mentioned in part-1 of this blog we will use comma separated string values to exchange data. Hence we are assuming that the Android Device will send us the calendar events in the following CSV format

           mTime, mSubject, mLocation, mDate

Where
    mTime - is the meeting time
    mDate - is the meeting date
    mSubject - is the meeting subject
    mLocation - is the meeting location

When we receive a message containing the above mentioned CSV string we will parse it and create a MeetingAlert Object. So to parse it we will add a method called initialize() in MeetingAlerts which will accept a CSV string of meeting record and populate the mTime, mDate, mSubject and mLoaction variables in the MeetingAlert Class.

function initialize(eventData) {
     var i=eventData.find(",");
        
      mTime = eventData.substring(0, i);
      var leftOver = eventData.substring(i+1, eventData.length());
      i=leftOver.find(",");
      mSubject =leftOver.substring(0, i);
      
      leftOver = leftOver.substring(i+1, leftOver.length());
      i=leftOver.find(",");
      mLocation =leftOver.substring(0, i);
     
      leftOver = leftOver.substring(i+1, leftOver.length());
      mDate =leftOver;
      Sys.println("mTime" + mTime +" mDate "+ mDate + " mSubject "+ mSubject+" mLocation "+mLocation);
   
 }

In the above method we are trying to parse the comma separated calendar event record String (eventData) and assign the comma separated first value to mTime, second value to mSubject, third value to mLocation and fourth value to mDate variable.

Now lets expand the folder named "resources" in our CalendarAlerts project. You can see that it has an "images" folder and a "layouts" folder. The images folder is the place where you keep all your
 the images that you would like to use in your app. and the layouts folder has a file called layout.xml which defines the layout of the UI components that you will use in your app. The project structure at this point would look as in the screenshot on the left.
Now if you open the layouts.xml you can see a bitmap tag which has a file name as shown below.

bitmap filename="../images/monkey.png

This bitmap tag is responsible to render the image of monkey in the center of the default view that you see when the app is launched(check by launching in simulator). Since we don't need it for our app we can remove it. 
Now open the CalendarAlertsApp.mc class. This is our main application class which extends Toybox::Application::AppBase and is the entry point of our application. Notice that ToyBox.Application is aliased as App in the first statement using Toybox.Application as App; This is very similar to import statements that you use to import Classes/Packages in other languages like Java. See class definition below.

using Toybox.Application as App;

class CalendarAlertsApp extends App.AppBase {

    //! onStart() is called on application start up
    function onStart() {
    }

    //! onStop() is called when your application is exiting
    function onStop() {
    }

    //! Return the initial view of your application here
    function getInitialView() {
        return [ new CalendarAlertsView() ];
    }

}

As mentioned in the code comments you can do operation that you want to do on startup of the app in the onStart() method. If you want to perform an operation on exiting the application, that needs to be written in the onStop() method.  The function getInitialView returns the first view to be shown to the app user, in our case it is the CalendarAlertsView.

Now lets create CalendarAlertsView and add something to it. The basic structure of CalendarAlertsView.mc will look like this
using Toybox.WatchUi as Ui;
using Toybox.WatchUi as Ui;
using Toybox.Graphics as Gfx;
using Toybox.System as Sys;
using Toybox.Communications as Comm;
using Toybox.Attention as Attention;
using Toybox.Timer as Timer;
using Toybox.Lang as Lan;
using Toybox.Application as App;
using Toybox.Time as Time;
using Toybox.Time.Gregorian as Calendar;
 
class CalendarAlertsView extends Ui.View {
 
     //a string message to be shown on the screen
       var displayString ="None in next 15 mins";
    
   //! Load your resources here
    function onLayout(dc) {
        setLayout(Rez.Layouts.MainLayout(dc));
    }
 
    //! Called when this View is brought to the foreground. Restore
    //! the state of this View and prepare it to be shown. This includes
    //! loading resources into memory.
    function onShow() {
    }
 
    //! Update the view
    function onUpdate(dc) {
        // Call the parent onUpdate function to redraw the layout
              View.onUpdate(dc);
             
         //Set the foreground and background color of graphics    
              dc.setColor( Gfx.COLOR_WHITE, Gfx.COLOR_TRANSPARENT );
         //Set text that we want to draw at a given top,left location on the screen
  dc.drawText(10, 20,  Gfx.FONT_MEDIUM, "Upcoming Meetings:", Gfx.TEXT_JUSTIFY_LEFT);
dc.drawText(10, 50,  Gfx.FONT_MEDIUM, displayString, Gfx.TEXT_JUSTIFY_LEFT);
       
         //Refresh the UI with changes that we did above
             Ui.requestUpdate();
    }
 
    //! Called when this View is removed from the screen. Save the
    //! state of this View here. This includes freeing resources from
    //! memory.
    function onHide() {
    }
 
}

This should display an output like as shown in the image below.
I am assuming that the comments in the source code are self explanatory. As you can see that in the onUpdate() method we are trying to draw texts on the UI using dc.drawText(). Here the object dc represent the Device Context of the wearable device and is an object of Class: Toybox::Graphics::Dc. This class has few more methods to draw different kind of graphical shapes or text. In the end of this method we requested a UI update by calling UI.requestUpdate() which indirectly request the UI update from the current View by calling onUpdate(). At this point we are left with receiving the calendar data from mobile and displaying it 15 mins prior to the meeting time in our watch. Now lets set up the infrastructure to receive messages from the mobile app and setting up a timer which checks for a meeting occurrence at regular intervals. If you refer to the documentation of Class: Toybox::WatchUi::View there is a method called initialize() which acts as a constructor. Which means we can add a method called initialize in CalendarAlertsView class which can initialize the basic stuff like setting up the communication infrastructure and initializing the timer to scan upcoming meetings. So lets add this initialize() method to CalendarAlertsView.mc.
       var count=0;
       var meetingsArray= new [100] ;
       var timer;
       var app;

   function initialize() {
              // when a message is received over Bluetooth LE it would be received by the onMail method described below
              Comm.setMailboxListener( method(:onMail) );
              Comm.emptyMailbox();
              app=App.getApp();
              
              //this method is described below
              checkForUpcomingMeetings();
              timer = new Timer.Timer();
              //the method checkForUpcomingMeetings will be called at an interval of every 30 seconds
              timer.start( method(:checkForUpcomingMeetings), 1000*30, true );
       }


  function checkForUpcomingMeetings() {
          Sys.println("Checking for meetings");
       }

  function onMail(mailIter)
    {
         var  mail = mailIter.next();
        while( mail != null )
        {
             count++;
            
           //the variable 'mail' would contain a comma separated information about each meeting, create a MeetingAlert object out of it
            var meetingAlert = new MeetingAlert(mail);
            
           // store the meeting alerts for next 3 days stored in an in-memory array of MeetingAlerts
            meetingsArray[count]=meetingAlert;
            mail = mailIter.next();
        }
        Comm.emptyMailbox();
        return true;
    }
   
The method initialize() registers onMail() method as a mail box listener by calling Comm.setMailBoxListener. Mail box is a virtual place where messages sent over Bluetooth LE will arrive and on receipt of the same it invokes the listener method - in our case the onMail() method. Then we create a Timer which executes a method checkForUpcomingMeetings at a regular interval of 30 seconds. The Timer works in a similar way as setInterval method in Javascript or a TimerTask in Java. Right now the method checkForUpcomingMeetings just prints a single statement "Checking for meetings" on the console. However if you try to run this, your app wont start because you need to grant the necessary permission to the app for communicating over Bluetooth LE which can be done by adding following lines in your manifest.xml file.
        
            
        
 
If you run your application now it should show the watch app with a message "Upcoming Meetings - None in next 15 mins" and should print "Checking for upcoming meetings" every 30 seconds.
In next part of this tutorial we will setup our Android app to pass on the meeting information over Bluetooth LE to our watch widget.

Thursday, June 30, 2016

Developing Garmin SmartWatch Apps with ConnectIQ Platform-Part 1

Recently I was involved in developing apps for Gramin Wearables. Being new to the wearables world I found it relatively easier to develop apps for Garmin Wearables then what I had thought earlier. Hence I would like to share my experience via this blog series. I will take you through the step by step process of developing a simple watch widget that synchronizes with an Android phone's Google Calendar to send out meeting alerts and reminders on your Garmin Watch.

Apps for Garmin Wearables are developed using the Garmin ConnectIQ SDK  and are programmed using Monkey C language . You are already familiar with Monkey C if you are familiar with languages like Java or Objective C. Introduction to Monkey C language  highlights the basic difference between other languages and Monkey C. Its a short and precise tutorial, I would suggest to give a quick read in case you are planning to develop apps for Garmin.

The Problem Statement
Lets say you own an Android Phone and you have configured your Google Calendar to show meetings,events or reminders from your Google Account or may be MS Outlook using exchange services. The watch widget that we will develop will be responsible to send out alerts for these calendar events 15 minutes prior the event time, on your Garmin Watch.

The Basics
Before we proceed further, you need to know a few things that are applicable to the Wearables world.

  1. Most of the wearables does not have direct access to internet. Especially those which don't come with a SIM card slot. Same is applicable to Garmin Wearables.
  2. Communication with a web service over internet is only possible if a communication channel is established with a SmartPhone (Android or iOS) over Bluetooth LE protocol.
  3. Garmin comes with Android and iOS Mobile SDK's that helps you communicate with your mobile device easily.  These SDK's can be used to exchange data over Bluetooth Low Energy(BLE) with your phone easily and watch vice-versa.  The Android SDK is just a  JAR file to be included as part of your Android Project, which contains a bunch of Classes that helps you send and receive data over BLE.
  4. If you are capturing activity data using wearables then you need to store it into a temporary store until the user sync's the wearable device with a smartphone that can establish an internet communication to upload data over to web service. The storage space on wearable device is limited so you need to take care that the format of stored data is as precise as possible. Storing in XML is not a preferred way as the format is too verbose. JSON is still okay only if required. I would prefer comma separated string values or enums. 
  5. Same concept applies while transferring data from a Mobile phone to a watch. Bluetooth Low Energy is relatively slower, the amount of time taken to transfer a bigger chunk of data will take long. I would prefer comma separated strings over other formats here as well.
  6. Using Garmin SDK you can create different type of apps viz. a watch widget, a watch face, a data field or a watch app. Watch faces are the ones which are responsible to show time, you can choose to develop a customized watch face which is more graphically attractive however a watch face doesn't have access to communication API's to communicate over BLE or to access sensor data recorded by inbuilt sensors of a watch. A watch widget is like a card that resides on your main watch carousel it has ability to communicate over BLE with your smartphone and process data in background, it also has access to sensor data. Watch Apps are accessed on request basis and have much wider permissions as compared to a watch face and a widget, it can read data from ANT+ sensors. Data fields are basically apps that present captured activity data of a user in a creative way.
 As part of this blog series I am gonna create a watch widget to show calendar alerts which beeps and flashes the meeting/event details 15 minutes prior to the event time.
Setting up the environment
I am using Eclipse IDE with the ConnectIQ Plugin to develop the Garmin Watch App/Widget and Android Studio for developing the corresponding Android App. The ConnectIQ Eclipse plugin can be installed using the Eclipse update site http://developer.garmin.com/downloads/connect-iq/eclipse/. For more details see http://developer.garmin.com/connect-iq/getting-started/.

Jumping Right In
 Assuming that you are done setting up the environment. 
  1. Create a new ConnectIQ Project in Eclipse as shown in the screenshot below and lets name it CalendarAlerts.

  2. Choose the Project type as "Widget" and select appropriate target platforms.
  3. Select the default project template and click next.
  4. Select the supported languages for your app/widget.
  5. Click Finish to see the project created in the project explorer in Eclipse.
  6. To verify, run the project by Right Click->Run As-> Connect IQ App
  7. Choose Appropriate Device to Simulate
  8. You should see a widget displaying image of a monkey in the ConnectIQ Device Simulator.
At this point you should be done setting up everything that is required to start working on the actual app. In the next part of this blog series, we will modify this app that we just created to do what we described in the problem statement above.

Monday, May 2, 2016

Building Secure RESTful Webservices

Recently I delivered a webinar on "Building Secure RESTFul Webservices" on Techgig which received a very good feedback based on the Techgig survey. The webinar column was published on Gizmodo India as well.

Here is a list of key takeaways from the webinar

  • How HTTPS work in detail and how to implement HTTP BASIC Authentication.
  • What is Mutual SSL Authentication and how to implement it.
  • What kind of damage can be done with security attacks like Man in the Middle and Replay Attack. 
  • Authenticating user without passing credentials over the wire
  • Preventing Man in the Middle attacks using Signature verification
  • Preventing Replay Attacks using timestamp and cryptographic nonce
  • What are OAuth 1a and OAuth 2

The code samples (written in Java) related to this webinar can be found at 


I am embedding the webinar recording for quick access below.


Building Secure RESTful Web Services from Techgig on Vimeo.


Saturday, November 1, 2014

Web Service Security and Native Mobile App User Authentication

In this article I am going to throw some light around web service security,  user Authentication  for native mobile applications and how both the topics are connected. Me along with my cool team members at Zycus were working on the same off lately. The idea is to highlight the fact that it is ideal to implement web service security by being agnostic to the type of web service clients (like mobile apps) but these decisions may impact the mobile app user authentication process.

If you are working on a mobile application that requires user authentication and fetching data from a server side application then it is highly likely that you are exposing certain functionality of your server side application via web services that can be accessed over the web by your mobile application.

While developing such applications you will usually encounter following challenges.
  1.  How to secure the web service endpoints?
  2.  How to authenticate users from the mobile app in secure way?
  3.  How to ensure that mobile app does not bundle or store any sensitive information which can result into illegal access to server side data by compromising access to web services.
How to secure the web service endpoints?

If I have to forget about the Mobile Application for a second and just answer this question from web services security perspective, then I would answer it in following way. Discussing each security method in detail is out of the scope of this article hence I have provided hyperlinks to references that I used while taking such decisions..

Public-ally hosted Web Services, if not properly secured, are mostly vulnerable to Man in the Middle, DoS, and Replay Attacks.

As data passing over HTTP is not encrypted and can be sniffed and modified by someone in middle, plain HTTP based web services are vulnerable to Man in the Middle attacks. To tackle this, you need to make sure that web services are exposed only over HTTPS and they are not accessible via HTTP.

To harden the endpoints further you can choose to implement Mutual SSL Authentication. Mutual SSL Authentication ensures that the web service client knows that server is trusted and the server knows that the client is trusted by verifying each others certificates during the SSL Handshake.

Tackling DoS or Distributed DoS is not that easy as well. If you are using a web server like Apache then you can enable Mod_Security and Mod_Evasive rules to deal with DoS and DDoS or implement your IT infrastructure monitoring using Nagios.

Simplest way to tackle Replay attacks is by asking for a timestamp and a cryptographic nonce value as part of the HTTP request header. For simplicity timestamp can be enforced to be passed in UTC timezone. Server can verify the timestamp and check whether the request was initiated by the client not before a threshold value of say 5 minutes. Server can also verify a given nonce value and store it for certain amount of time so that any given request with same nonce should not be served again and should be discarded by the server.


How to authenticate users from the mobile app in secure way?

There are multiple solutions available and documented on the web. Each of them are best in their own way. I have seen many applications use the following approaches.
  1. OAuth2: Authorization Code Flow
  2. OAuth2: The Resource Owner Password Flow 
  3. Custom Implementation
OAuth2: Authorization Code Flow  

This could be one of the best ways out there but I am not so much in favor of using this approach. The reason is simple, it requires your app to do the OAuth Dance. Which will require opening up an embedded browser like WebView or UIWebView and take the user to the actual web application where the user can key in the credentials and is returned back with an access token once he authorizes the mobile application on his behalf to access the resource via web service calls. Mobile App can use the access token till the time it expires and carry on with accessing the user's data on behalf of the user. This model fits in well when the Mobile Application is using services provided by a third party web application., like you creating your own mobile Twitter App. In that case the end user using your version of Twitter App should authorize your App by indicating Twitter to allow your App to access resources on user's behalf.

If you our your company are the owners of both the web application and the official mobile application then this approach does not fit well.

OAuth2: The Resource Owner Password Flow 

This approach fits in well in a scenario where you or your company are the owner of the web application (or the API's exposed) and you or your company is planning to implement an official Mobile App for the corresponding web based application.

Actually OAuth was primarily created for a different purpose. Let me point out that "OAuth provides client applications a 'secure delegated access' to server resources on behalf of a resource owner". Hence it is not a way to secure your web services but rather a way to authorize 3rd party web service clients like
  1. a mobile app developed by someone else (not by you or your company)  but using your web services
  2. or a 3rd party developed Web 2.0 widget embedded in a 3rd party web application accessing resource provided by your application.
  3. or a 3rd party web application accessing resources provided by your application
The Resource Owner Password Flow  of OAuth was just specifically created to provide a solution to handle this scenario.

It is advisable to go with this approach if you have enough time to implement an OAuth Provider which adheres to the specification.

Custom Implementations
I was actually searching on internet for quite some time to find out an easily understandable and well documented open source library which could help us implement an OAuth Provider which adheres to resource manager password flow specification. Although there are many libraries out there but either proper documentation was lacking or it was getting a bit difficult to understand.


I found a very good resource here which mentions about doing a custom implementation some what similar to OAuth resource manager password flow specification and it helped me to get started.

All right, so here I am going to explain the approach that we decided to go with.

So first of all, lets break down the problem statement into smaller problems.

We need to take care of following things
1) Secure the Web Services from Man in the Middle, Replay attacks and DoS attacks
2) Provide a secure way to authenticate users for my mobile app

Securing the Web Services from Man in the Middle attacks, Replay attacks and DoS attacks

To prevent man in middle attacks we decided to expose the RESTful web services over HTTPS so that the data transferred is encrypted.

However we wanted to harden the  web service endpoints further. The option we had was to use Mutual SSL Authentication. But wait, Mutual SSL Authentication requires Client Certificates (including the private keys) to be shipped along with the web service clients like mobile app.

Here is the mantra "any private keys you store in your mobile app is accessible to an attacker. " Each web service client (like a mobile app) should have it's own certificate and key pair, to prevent security being compromised.

Your server should also enforce protections, ensuring a compromised client can't just request anything. I am sure that there will be mobile applications which stores private keys and the corresponding server invalidates the compromised keys.

We didn't wanted to get into the certificate distribution problem and then decided to go with the digital signature verification. So here is how the digital signature verification works.

Tackling Man in the Middle attacks
  1. The client sends a request to the server over HTTPS
  2. In the request a custom HTTP header is passed with header name as x-signature
  3. The x-signature header value is a message digest of a concatenated string prepared by concatenating the request URL+HTTP Method+alphabetically sorted request headers and their values in lower case+Data within the message body
  4. We used HMAC SHA1 algorithm to create this message digest
  5. Once the request is received by the server the server generates another HMAC SHA1 signature based on message digest of the concatenated string prepared by concatenating the request URL+HTTP Method+alphabetically sorted request headers  and their values in lower case+Data within the message body
  6. Server then verifies the generated signature with the one passed by the web service client
  7. If both the signatures are equal then it means that request was not modified by anyone in the middle.
Tackling Replay Attacks
  1.  We introduced 2 additional headers custom headers x-nonce and x-timestamp which are to be passed by any web service client
  2.  x-nonce request header needs to have unique value generated by the web service client preferably a  secure random, server would then store this secure random for a limited time for a month or so and choose not to serve any other request having the same nonce value.
  3. x-timestamp request header contains value of a UTC time stamp of the time when the web service client initiated the request. The server cross checks passed time stamp with the server time and determines whether the request was not initiated by the web service client prior to a threshold value of 5 minutes. If the request was initiated prior to 5 minutes from the current server time then server would discard the request.
  4. Server can optionally choose to block those IP's from which replay requests are detected.
Tackling the DoS Attacks
Our web servers were fronted by Apache web server and we already had the Mod_Security and Mod_Evasive rules implemented along with infrastructure monitoring using Nagios in place. Hence we were not much worried about this.

So by this point we had a straight forward web application acting as an REST API Resource server with services secured using the above mentioned approaches. However we were left with mobile user authentication.

Mobile User Authentication

First of all we decided to maintain a registry of the web service clients who are authorized to consume the web services. If customers of our product are willing to consume our REST API's then they are required to register their web service clients with us which is possible only if they are licensed to use our products. On completion of registration form an application id is issued to user which can be used as part of the authentication process.

We decided to setup a new web application which will act as a REST API Authentication Server for authenticating the users willing to consume the REST API Resources from the Resource Server.

We decided to implement the authentication process in such a way that the consumer of the REST Resources from the Resource Server is supposed to obtain an access token from the Authentication Server prior to accessing any resources from the resource server. This access token should be passed in the x-access_token request header while issuing any calls to the Resource server. The validity of  access token issued by the Authentication server is for next 8 hours, which on expiry should be obtained again by going through the authentication process again. Here is how the user authentication was implemented.

  1. The web service client needs to pass the Application id (issued after application registration) in the x-application_id header with user id in the x-userId header along with x-signature, x-nonce and x-timestamp headers.
  2.  Auth Server validates the Application id and the User id with the user management module of our application. It checks whether the user is active and it exists in our database at this point. If the user exists and is active then a challenge is generated by the Auth Server and the value of this challenge is sent back as part of the x-challenge response header. The challenge generation process is mentioned below.
    1. First of all generate a secure random  (which will be the answer of our challenge).
    2. The generated secure random should then be AES Encrypted using the user's password as a key
    3. The encrypted value of the secure random is our challenge which the client needs to decrypt using the user's password and send back for verification.
  3. Client receives the challenge as part of the x-challenge response header and is supposed to AES decrypt it using the user's password.
  4. After decrypting it the client is supposed to issue another request to Auth Server with x-challenge_answer that contains the challenge answer (the actual secure random value) along with x-application_id, x-signature, x-nonce and x-timestamp.
  5. The server then verifies whether the answer of that challenge matches with the original secure random value or not. If yes then an access token is returned as part of the x-access_token response header.
  6. After receiving the x-access_token response header the web service client can use the token value along with x-signature, x-nonce, x-timestamp and x-application_id to access the resources for next 8 hours.
  7. On expiry of the access token the web service client is required to issue another call to Auth server

Hence the Mobile App User Authentication would look as depicted in the diagram below.




Also it is good Implement Certificate Pinning in your mobile application that accesses the web services.  This ensures that your mobile app trusts only the server that it is supposed to connect to by using the hard coded server certificate and ignoring the device's default trust store.

Hope this article would help others trying to do similar kind of implementation. Your comments and suggestions are welcome.

Update:
Recently I delivered a webinar on Building Secure RESTful WebServices on Techgig. The Webinar recording can be found here. It also has link to code samples of the custom implementation of securing web services described above.

Wednesday, May 26, 2010

Yet another JavaFX App !

This application has won the RIA Exemplar Challenge Award organized by Java Champion Jim Weaver, Stephen Chin and Jasper Potts check the winner announcement here and here

Being a Java EE developer,I am always attracted towards the "grass on the other side" :P . I have been working on a JavaFX app, which tries to solve a typical engineering problem of loading cargo containers to a BeechCraft 1900C cargo airplane. Although the aircraft data and equations are taken from the authentic FAA weight and balance handbook (see Chapter 7 , page 60) , this application is not intended to be used for realtime cargo loading as it is just for JavaFX demo purposes and does not guarantee the accuracy of data and calculations. I must say again, being a newbie to the language its fun to learn JavaFX. Although I still regret not visiting Amy Fowlers blog post during the early stages of this app . Shown below is the screen-shot of the work done till date. Shown on the upper left side of the screen-shot are cargo containers which are supposed to be loaded on the horizontal cross section of Beechcraft main deck shown on the center-top. The parallel red blocks denotes left and right position of sections where cargo containers can be placed. Just below the red blocks is a scale which shows the section names and their distance in inches from a reference point referred as 'Datum' which in our case is aircraft's nose. So starting from Nose at 0 inches from datum , the tail of the aircraft is at 533 inches. The cargo containers are of different weights which can be seen by a mouse-hover tool-tip. User can drag these containers and place it on the aircraft's deck , which recalculates the center of gravity of the aircraft. The line chart on the lower right is Weight vs CG chart.It is actually combination or 3 overlapped line charts, One is in which the polygons are drawn, 2nd is with no data , but with X and Y axis on opposite sides, and the 3rd one contains just one yellow dot. The polygons drawn inside these charts are operational center of gravity limits defined by aircraft manufacturer. The yellow dot in the chart denotes the current center of gravity of the aircraft which gets updated when you place a container on the deck, The yellow dot(CG) should fall within these polygons (operational limits), otherwise the aircraft is either nose heavy or tail heavy. The data grid in the center is the XTableView control from JFXtras library (they have some nice controls and utilities for JavaFX). Parameters in this table are dynamically updated when the container is placed on the deck . The pie-chart on the lower left shows the total traffic weight of an aircraft by showing weight covered by each section of the deck. You can also click on these charts to get a larger view. Double click the dropped container to revert it back from the deck to the container panel. Just below the Main Deck is a JavaFx Toolbar component which contains normal and toogle buttons styled using an external CSS file. A user can revert back all the placed containers by clicking on the "Reset Containers" button. The animation on drag-drop can be toggled using the "Disable Animation" button on the toolbar. By default weight of each cargo containers can bee seen on the tool-tip displayed by the mouse-hover, optionally one can choose to quick view/hide weights on the containers by toggling the "View Weights" . Do check out the help and about buttons for more information about the application.



I am improving this application when ever I get free time and I will be updating the source code to JFxtras repository to ensure its compatibility with future releases of JavaFx Please let me know your valuable feedback.