# Direct Upload via Street View

Version 2.1

## Background

In earlier versions of the API, an OSC compliant camera would create a Wi-Fi
access point that the Google Street View iOS and Android apps could connect to.
The app would both direct the OSC camera to capture photos and also download the
captured content from the camera to then publish it to Google Street View. To
expedite the publication of content, we have introduced a new optional workflow
that allows OSC cameras to upload content to the Street View server directly.
This eliminates the lengthy double transfer of content first from the
camera to the app and then from the app to the Street View server. **This was
added in API level 2.1 and is only relevant to OSC cameras that can both provide
a Wi-Fi access point and also connect to an infrastructure Wi-Fi access point
with access to the Internet.**

## Overview

The new upload workflow requires cameras to provide a way (e.g. a dedicated
physical button or a combination of existing buttons) to allow users to switch
between two Wi-Fi modes:

- **Direct mode:** In this mode, the camera acts as an access point which allows a mobile device to connect to it. In this mode, mobile devices can control the camera to perform tasks such as capturing photos. Mobile devices can also provide the camera with Wi-Fi access point credentials that the camera can then use to switch to **Internet mode**.
- **Internet mode:** In this mode, the camera connects to a Wi-Fi access point with Internet access. It will use the access point identifier and password that was provided to it from the app when the camera was previously in **Direct mode**. Mobile devices can initiate uploads from the camera directly to the Street View server in this mode. They can also continue to control the camera to perform tasks such as capturing photos.

The camera mode should persist across the camera being turned off and being
turned back on again. Also, it is highly recommended that the camera offer a
signal (e.g. light, sound or indicator on a screen) to inform users of the
current Wi-Fi mode.

The camera should also have discovery protocols
(see [Discovery](https://developers.google.com/streetview/open-spherical-camera/guides/direct-upload#discovery))
implemented to handle communication while the camera is in **Internet mode**.

## Internet Mode Setup

1. The user turns on the camera. It starts in **Direct mode** since **Internet mode** is not yet set up.
2. The mobile device connects to camera's Wi-Fi.
3. The app generates a self-signed certificate.
4. The app sends the [`switchWifi`](https://developers.google.com/streetview/open-spherical-camera/reference/camera/switchwifi) command to the camera with the **SSID** of the infrastructure Wi-Fi access point the camera will need to connect to, the **password** for that access point, and its **self-signed certificate** that the camera uses to authenticate the app later.
   - Please note that the camera should store both the Wi-Fi credential and the app's self-signed certificate securely.
   - It is recommended that the camera store multiple Wi-Fi credentials since the camera may need to connect to different infrastructure Wi-Fi access points. The minimum requirement is for the camera to store the most recent Wi-Fi credential.
5. The camera responds with its self-signed certificate that the app uses to authenticate the camera later.
6. The user can now switch between **Direct mode** and **Internet mode** directly from the camera, e.g. with a physical toggle button.

## Discovery

Discovery for OSC cameras is a zeroconf based protocol. The camera MUST
implement IPv4 Link-Local Addressing and MUST comply with the mDNS (Multicast
DNS) and DNS-SD (DNS-Based Service Discovery) specifications:

- [IPv4 Link-local](http://www.rfc-editor.org/rfc/rfc3927.txt)
- [mDNS](http://www.rfc-editor.org/rfc/rfc6762.txt)
- [DNS-SD](http://www.rfc-editor.org/rfc/rfc6763.txt)

### Service Instance Names

For the `<Service>` portion of the Service Instance Name, OSC cameras should use
`_osc._tcp`. For the `<Domain>` portion of the Service Instance Name, OSC
cameras should use `local.`. Note that there is a trailing `.` after `local`.

### TXT record

We require the camera to send the following key/value pairs in the TXT record:
`txtvers`, `ty`, and `id`.

#### txtvers

To allow for updates to the TXT version in the future, use the key/value pair
`txtvers=1`.

#### ty

Provides a user-readable name of the camera, e.g.
`ty=Google Street View Optimized Spherical Camera Model XYZ`.

#### id

Provides a unique id of the camera, e.g.
`id=A unique id of the camera`. The value for `id` MUST be the same as the
`cameraId` in
[`/osc/info`](https://developers.google.com/streetview/open-spherical-camera/guides/osc/info#output) output.

### Announcements

On camera startup or shutdown, the camera MUST perform the announcement step as
described in the mDNS specification. It SHOULD send the corresponding
announcement at least twice with at least a one-second interval between them.

#### Startup

On camera startup it MUST perform probing and announcing steps as described in
the mDNS specification. SRV, PTR and TXT records should be sent in this case. It
is recommended to group all records into one DNS response if possible. If not,
the following order is recommended: SRV, PTR, TXT records.

#### Shutdown

On camera shutdown it SHOULD try to notify all interested parties by
sending a "goodbye packet" with `TTL=0` as described in section 10.1 of the
mDNS documentation.

## Self-signed certificate

The app and the camera can use the self-signed certificates shared during the
**Internet mode setup** to authenticate each other and build a secure channel to protect
exchanged data, using SSL mutual authentication.

During the **Internet mode**, the app would act as a SSL server and the camera as a
client. The camera would check that the server's certificate matches the app's
self-signed certificate, and the app would check that the client's certificate
matches the camera's.

Any SSL library supporting mutual authentication (e.g. OpenSSL) can be used to
establish SSL connection between the app and the camera during the **Internet mode**.

## New Upload Flow

1. If the camera is not in **Internet mode** , the user switches it to **Internet mode**. The camera connects to the infrastructure Wi-Fi using stored credentials.
2. The mobile device also connects to the infrastructure Wi-Fi and discovers the camera.
   - This requires the camera to implement a local discovery protocol mDNS/DNS-SD (see [Discovery](https://developers.google.com/streetview/open-spherical-camera/guides/direct-upload#discovery)).
   - There is no specific requirement on how it is implemented ([mDNSResponder](https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/NetServices/Articles/faq.html) is a good reference).
   - Both the app and the camera generate and share self-signed certificates during the **Internet mode setup** . During **Internet mode**, both the app and the camera authenticate each other through mutual SSL authentication.
   - After the camera has been discovered, client communication is enabled with it directly over the local network based on HTTP 1.1. Data formats are JSON based. Requests may be GET or POST requests.
3. The app queries the camera for a list of files with the [`listFiles`](https://developers.google.com/streetview/open-spherical-camera/reference/camera/listfiles) command.
4. The app initiates upload with the [`uploadFile`](https://developers.google.com/streetview/open-spherical-camera/reference/camera/uploadfile) command to upload an image or video directly from the camera to the Street View server.
5. The app polls the camera periodically for upload progress with the [`status`](https://developers.google.com/streetview/open-spherical-camera/guides/osc/commands/status) command.