dashlt

Dashlt

Introduction

Dashlt is an Android application which the user can use to create verifiable video evidence using decentralized trusted timestamping. This way in case of an accident or collision, if the application recorded the event, the video can be used as valid evidence to prove the fact and it can be accepted by the Juridicial System or an insurance company. In case of an accident/collision the video will be recorded and a hash will be generated and sent to the ‘Originstamp’ for timestamping and the user can use the video as verifiable evidence.

Starting point

Most present technologies which record accidents cannot be used as legal proof because of the methods used in recording and also because they cannot prove an exact time of accident. The videos provided by Dash Cams can be modified and the metadata such as time and date can also be altered by the user, making them not a valid proof in case of an event. Another problem which occurs is that trusted timestamping methods are not easily accessible because of costs and they can also be tampered with.

Workshop implementation solutions

1. Intel Edison + GoPro (WebCam, Kinect) + Sensors (Accelerometer, GPS, Gyroscope)

     •	Intel Edison – For sending video over internet in case of accident
     •	GoPro – To record the video
     •	Sensors – To detect accident/collision
     

2. Smartphone

     •	Smartphone sensors to detect accident/collision
     •	Smartphone camera to record the video
     •	Mobile Data to connect to internet

Technology

During the workshop session multiple design solutions were proposed like PhoneGap or Cordova, but due to hardware and software limitations we switched to Android which can access all the features of a phone that are needed by the application and offers the possibility to run an application in the background. For hashing the video we used OriginStamp.org as the trusted timestamping method.

Design concepts

The application can be used by any person that owns an Android device with internet connection to access the application and send the hash of the evidence video, a camera that records the accident and an accelerometer which uses sensors to detect the movement in case of collision. A video will be recorded at every certain point in time and only the important length of the video will be hashed and sent for timestamping. In this case the user will be notified about the process and he will be able to access his events in a history panel along with verification details, so he can use the system for legal purposes.

The user turns on the application and starts recording then locks the application in Task Manager and the phone does the rest of the work. When an accident/collision occurs, the video is hashed and sent to OriginStamp and the user receives the confirmation of the timestamping. In the History Screen the user can see his accident(s) /collision(s) history with date, time and hashing value so that he can use it in Judicial Systems.

System

Workflow

• Week 1:

    o	Design system and choose technologies
    

• Week 2:

    o	Iterating the design for improvements, finalizing the design
    

• Week 3:

    o	System Implementation
    

• Week 4:

    o	System Implementation
    

• Week 5:

    o	System Implementation
    

• Week 6:

    o	Testing the system
    o	Presentation, Wiki Article, Demo Video
    

OriginStamp

OriginStamp is a non-commercial free of charge trusted timestamping REST API that can be used to prove that a person was the originator of a piece of information at a certain point in time. The advantage of OriginStamp compared to other trusted timestamping methods is that it is free of charge and allows the user to create anonymous timestamps in a secure and valid manner that uses the cryptographic blockchain of virtual bitcoins.

Implementation

OriginStamp access

OriginStamp is called by a HTTP request to the API. For the API to authorize access a parameter Token token=„{YOUR_API_KEY}“ needs to be provided in the Authorization field.

Example request:

POST http://www.originstamp.org/api/stamps
Authorization: Token token="{YOUR_API_KEY}"
Content-Type: application/json
{
  "hash_sha256" : "6b4a1673b225e8bf5f093b91be8c864427df32ca41b17cc0b82112b8f0185e41"
}

Generate Hash:

public void generateHash(){
        int[] orderOfVideo = new int[3];
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        if(accidentOnVideoIndex == 2){
            orderOfVideo[0] = 1;
            orderOfVideo[1] = 2;
            orderOfVideo[2] = 3;
        }else{
            orderOfVideo[0] = 2;
            orderOfVideo[1] = 1;
            orderOfVideo[2] = 3;
        }
        for(int i=0;i<3;i++){
            File file = new File("/sdcard/dashit"+orderOfVideo[i]+".mp4");
            if(file.exists() && !file.isDirectory()){
                byte[] byteArray = new byte[(int)file.length()];
                FileInputStream fileInputStream;
                try {
                    fileInputStream = new FileInputStream(file);
                    fileInputStream.read(byteArray);
                    System.out.println("File length::"+byteArray.length);
                    outputStream.write(byteArray);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        byte[] finalByte = outputStream.toByteArray();
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            md.update(finalByte);
            byte[] mdBytes = md.digest();
            StringBuffer hexString = new StringBuffer();
            for (int i=0;i<mdBytes.length;i++) {
                hexString.append(Integer.toHexString(0xFF & mdBytes[i]));
            }
            System.out.println("Hex format : " + hexString.toString());
            sendHashToServer(hexString.toString());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

Send hash to server:

public void sendHashToServer(String hashString){
        String url = "http://www.originstamp.org/api/stamps";
        String postData = "{\"hash_sha256\" : \""+hashString+"\"}";
        try {
            URL obj = new URL(url);
            HttpURLConnection con = (HttpURLConnection) obj.openConnection();
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type", "application/json");
            con.setRequestProperty("Authorization", "Token token=\"a876e0bbb8894e8c8eadc5b3a19adff7\"");
            con.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
            con.setRequestProperty("Accept","*/*");
            DataOutputStream dos = new DataOutputStream(con.getOutputStream());
            dos.writeBytes(postData);
            dos.flush();
            dos.close();
            String line;
            BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            reader.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    public static class MyBroadcastReceiver extends BroadcastReceiver {
 
        @Override
        public void onReceive(Context context, Intent intent) {
            System.out.println("Accident!!");
            accidentStatus = true;
        }
    }
}

Android Services

Accelerometer (Sensors) access:

public class SensorService extends Service implements SensorEventListener {
    private SensorManager manager = null;
    private Sensor sensor = null;
    private long lastUpdate = 0;
    private float last_x, last_y, last_z;
    ResultReceiver resultReceiver;
 
    public int onStartCommand(Intent intent, int flags, int startId){
        resultReceiver = intent.getParcelableExtra("receiver");
 
        manager = (SensorManager)getSystemService(SENSOR_SERVICE);
        sensor = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        boolean sensorAvailable = manager.registerListener(this,sensor,SensorManager.SENSOR_DELAY_FASTEST);
        if(sensorAvailable){
            System.out.println("Sensor available");
        }else{
            System.out.println("Some problem when retrieving the sensor.");
        }
 
        return START_STICKY;
    }
 
 
 
    @Override 
        public void onSensorChanged(SensorEvent event) {
 
        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];
 
        long curTime = System.currentTimeMillis();
 
        if ((curTime - lastUpdate) > 100) {
            long diffTime = (curTime - lastUpdate);
            lastUpdate = curTime;
 
            float speed = Math.abs(x + y + z - last_x - last_y - last_z)/ diffTime * 10000;
 
 
            if(Math.abs(x-last_x) > 8 || Math.abs(y-last_y) > 8 || Math.abs(z-last_z) > 8){
                Bundle bundle  = new Bundle();
                bundle.putString("state","Accident!!!");
                resultReceiver.send(100,bundle);
 
                Intent intent = new Intent();
                intent.setAction("com.example.Broadcast");
                intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
                sendBroadcast(intent);
            }else{
                Bundle bundle  = new Bundle();
                bundle.putString("state","You are good!!!");
                resultReceiver.send(100,bundle);
            }
 
            last_x = x;
            last_y = y;
            last_z = z;
        }
        new SensorEventLoggerTask().execute(event);
        stopSelf();
 
    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
 
    }
 
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
 
    public class SensorEventLoggerTask extends AsyncTask<SensorEvent, Void, Void> {
        @Override
        public Void doInBackground(SensorEvent... events) {
            for(int i=0;i<events.length;i++){
                SensorEvent event = events[i];
                for(int j=0;j<event.values.length;j++){
                    //System.out.println("Sensor Data::"+event.values[i]);
                }
            }
            return null;
        }
    }
}

Video recording:

public boolean startRecording(String fileName){
        try {
            //Toast.makeText(getBaseContext(), "Recording Started", Toast.LENGTH_SHORT).show();
            mRecordingStatus = true;
            mServiceCamera = Camera.open();
            Camera.Parameters params = mServiceCamera.getParameters();
            mServiceCamera.setParameters(params);
            Camera.Parameters p = mServiceCamera.getParameters();
 
            final List<Camera.Size> listSize = p.getSupportedPreviewSizes();
            Camera.Size mPreviewSize = listSize.get(2);
            Log.v(TAG, "use: width = " + mPreviewSize.width
                    + " height = " + mPreviewSize.height);
            p.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
            p.setPreviewFormat(PixelFormat.YCbCr_420_SP);
            mServiceCamera.setParameters(p);
            mServiceCamera.setDisplayOrientation(90);
            try {
                mServiceCamera.setPreviewDisplay(mSurfaceHolder);
                mServiceCamera.startPreview();
            }
            catch (IOException e) {
                Log.e(TAG, e.getMessage());
                e.printStackTrace();
            }
 
            mServiceCamera.unlock();
 
            mMediaRecorder = new MediaRecorder();
            mMediaRecorder.setCamera(mServiceCamera);
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
            mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
            mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_480P));
            //mMediaRecorder.setMaxDuration(10000);
            mMediaRecorder.setOutputFile("/sdcard/" + fileName + ".mp4");
 
            mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
 
            mMediaRecorder.prepare();
            mMediaRecorder.start();
 
            return true;
        } catch (IllegalStateException e) {
            Log.d(TAG, e.getMessage());
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            Log.d(TAG, e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

Limitations

  • The phone needs to be placed in a fix spot when recording
  • The entire journey is not recorded
  • It consumes a lot of battery power, but if phone plugged then the application will run without this problem at stake

Future work

  • Make the detection of accidents/collision more reliable
  • Use more sensors for a better detection of an accident/collision
  • Notify user and update the log when transaction seed is generated
  • Notify emergency services in case of an accident/collision and use the maps service to send the location of the car
  • Improve UI by making it more intuitive
dashlt.txt · Zuletzt geändert: 2018/12/03 09:43 (Externe Bearbeitung)