Skip to content
Let a citizen send a picture to the 112 / 911 / 999 PSAPs, on invitation from the dispatcher
PHP HTML JavaScript
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
config
docker/nginx
html
php
src
.gitignore
.htaccess
LICENSE
README.md
docker-compose.yml
includes.php
screenshot.png

README.md

showme

Let a citizen send a live video or a picture to a 112 / 911 public safety answering point (PSAP), on invitation from the dispatcher - Lightweight solution

Kinda photowall, for emergency services.

Ask for a demo via https://showme.my-poppy.eu

Proof of concept, quick and dirty (really...), with a bit of security

  1. The dispatcher connects to the interface of its organization
  2. The dispatcher sends a link by SMS to the citizen.

either: live streaming

  1. The citizen turns mobile data on, clicks on the link and allows for cam and mic use
  2. The P2P stream is sent to the dispatching
  3. The server validates the remote peerid and answers the call
  4. The stream is displayed in the browser

or: sending a picture

  1. The citizen turns mobile data on, clicks on the link and takes a picture
  2. The picture is sent to the server
  3. The server validates the data received (image and key)
  4. The dispatcher sees the picture in reverse chronolocical order after a couple of seconds.

If you are looking for a geolocation solution, a project like Geoloc18_112 (Twitter: @geoloc18_112) might be worth trying.

Installation

Structure

  • /html : html5 apps for the PSAP & the citizen
  • /php : user facing scripts
  • /config : php config
  • /src : php libraries

Configuration

  • in html/params.js:

    • client_path: should be set to the path of the upload API (normally, ending with /php/)
    • peerjs_url: fully qualified domain name of your PeerJS server without preceding https and without trailing '/' (eg : mypeerjs-server.example.com, but not https://mypeerjs-server.example.com/)
  • in config/params.php:

    • TWILIO_SID & TWILIO_APIKEY are the Twilio credentials to het the STUN (free) and TURN (paying) servers, and optionally to access their SMS API if chosen below
    • TWILIO_FROM is the originating SMS number
    • SMS_API = {'TWILIO'|'CLICKATELL'}: which API to choose
    • BASE_URL should be set to the page the citizen will see (https://.../html/showme.html)
    • $params contains the userids, usernames, secrets and API key for the SMS API -> in the future, this might move to a database
    • BASE_FOLDER points to the folder where the received images will be collected. This folder will be created automatically at runtime
    • USAGE_FOLDER points to the folder where the usage & credit data will be stored. This folder will be created automatically at runtime
    • INITIAL_TOPUP defines how many free credits someone receives when using the service the first time
    • the $params array contains an array of [USERID => ['secret'=> SECRETTKEY, 'name'=> USERNAME, 'sms_apikey' => CLICKATELL_APIKEY],

Troubleshooting

  • P2P webRTC connexions might be unstable. See eg: https://peerjs.com/docs/#api
  • It may fail behind a firewall (a TURN server is configured, but port blocking / adress blocking might still be an issue)
  • According to the cases, one SMS provider might be more reliant / performant than the other. We have good experiences with Twilio.

How does the security part works

  • Each organization gets a userid

  • The user opens https://***/html/index.html?userid=USERID

  • This queries the API (query.php), which returns a key

  • This key is composed of a timestamp, a random hash and a validation hash

  • The validation hash takes into account the timestamp, the random hash and a user-related secret

  • When someone uploads a picture (upload.php), it must send the key

  • The key is validated against the secret

  • The image can only be uploaded if the key is less than 6 hours old

  • Ideally, the secret should change periodically, so that if an attacker finds it, it would not be useful for a long time

We could also think to a password, but this would be to the detriment of the UX, is it worth here ?

Note

  • the capture API is still used as the capture from the stream is not (yet?) available eg. on iOS. For it to work, when a user clicks on the camera button, the stream is interrupted. It is resumed when the user clicks on the video, or automatically after the sending of the picture

Handling of stability issues

  • If the remote peer cannot connect after 5 seconds, the stream is destroyed and the citizen can still send a picture
  • should elaborate more cases

Libraries used

You can’t perform that action at this time.